Admin — Humans
The Humans page is the tenant user directory. It lists every person who has access to the tenant, their role, their membership status, and their Cognito credential state. Operators use this surface to create access without email, send invitation email, resend pending invitations, and manage user roles.
Route: /settings/users
File: apps/web/src/components/settings/SettingsUsers.tsx
The list
Section titled “The list”A searchable table with columns:
| Column | Notes |
|---|---|
| User | Avatar initials plus display name or email |
| Cognito sign-in email | |
| Role | Tenant role badge |
| Status | Membership status |
| Cognito | Credential/setup state from Cognito where available |
| Added | Relative creation time |
The action area exposes two distinct setup paths:
- Add user creates tenant access without sending or claiming to send email.
- Send invite creates or links the user and asks Cognito to deliver an invitation email.
Three roles cover the current tenant-access model:
- Owner — full access, including owner creation and sensitive tenant administration.
- Admin — can manage members and tenant settings, but cannot create or promote another owner.
- Member — regular tenant access without user-management authority.
Role checks are enforced server-side. Add, invite, resend, role assignment, and removal all require an owner/admin membership before any Cognito or email side effect runs.
Add User
Section titled “Add User”Choose Add user when an operator needs the person to exist in the tenant but does not want ThinkWork to send setup email.
The dialog captures:
- Email — the user’s Cognito sign-in email.
- Display name — optional.
- Role — owner, admin, or member, constrained by the caller’s role.
Submitting the dialog calls the GraphQL addManualUser mutation. The backend:
- Authorizes the caller as a tenant admin or owner.
- Rejects duplicate active membership before replaying idempotent results.
- Creates or repairs the Cognito user with
MessageAction=SUPPRESS. - Sets a generated permanent hidden password that is never returned or logged.
- Inserts the tenant membership only after Cognito is reset-capable.
The operator never creates, views, copies, or distributes a password. The user sets their real password from the login page’s Reset password path.
Send Invite
Section titled “Send Invite”Choose Send invite when the operator wants ThinkWork to attempt email delivery immediately.
Submitting the dialog calls the GraphQL inviteMember mutation with a fresh
per-submit idempotency key. Success means Cognito accepted a new create/send
attempt. Delivery, configuration, sandbox, and Cognito failures remain visible
instead of being converted into invitation-success copy.
Resend Invite
Section titled “Resend Invite”User detail pages expose Resend invite only for pending/resendable Cognito
states. Resend uses the dedicated resendMemberInvite GraphQL mutation keyed by
tenant member ID. Each human click uses a fresh operation attempt and calls
Cognito with MessageAction=RESEND; it does not replay an older
inviteMember result as delivery success.
Confirmed or non-pending users are not treated as successfully resent. Operators should direct password-capable users who need credentials to the login Reset password path.
Reset Password
Section titled “Reset Password”The public /sign-in page exposes Reset password whenever email/password
sign-in is configured. The user enters their email, receives a Cognito reset
code when the account is eligible, confirms the code with a new password, and
returns to sign-in.
The request-code step uses neutral copy so the page does not casually enumerate accounts. Configuration, delivery, rate-limit, invalid/expired code, and password-policy failures remain visible and actionable.
CLI and Legacy REST Parity
Section titled “CLI and Legacy REST Parity”THNK-29 changes the web GraphQL Settings and login surfaces. Existing operator-oriented CLI/REST utilities were audited:
thinkwork user invitecontinues to be an email-delivery path backed by/api/tenants/:slug/invites.thinkwork user reset-passwordremains an admin-initiated Cognitoadmin-reset-user-passwordhelper for operators./api/tenants/:slug/invitesremains CLI-facing invite behavior and does not become the web manual-add path.
Use Settings -> Users Add user for no-email manual setup in the web product surface. Use Settings -> Users Send invite or Resend invite when the desired side effect is email delivery.
GraphQL
Section titled “GraphQL”| Query / Mutation | Purpose |
|---|---|
tenantMembers(tenantId) | List tenant members and Cognito setup state |
addManualUser(tenantId, input) | Create access without invitation email |
inviteMember(tenantId, input) | Create/link a member and attempt invitation email |
resendMemberInvite(memberId, input) | Attempt fresh Cognito resend for a pending member |
updateTenantMemberRole(memberId, input) | Change a member’s role |
removeTenantMember(memberId) | Remove a member from the tenant |
Known Limits
Section titled “Known Limits”- No bulk import, SCIM, or external directory sync in v1.
- No operator-visible password assignment.
- No “add now, send setup email later” manual-user action in v1. Use Send invite when email delivery is desired at setup time.
- SES sandbox or sender misconfiguration can block live email delivery even when account creation succeeds.
Related Pages
Section titled “Related Pages”- Authentication & Tenancy — Cognito sign-in and login reset behavior
- Agent Invites — BYOB service-account registration
- Deploy Configuration — Cognito and SES deployment configuration