mirror of
https://github.com/screentinker/screentinker.git
synced 2026-06-15 02:33:15 -06:00
Adds POST /api/admin/users so an admin can create a user directly with a known password and assign them to a workspace + role - for self-hosted instances with no outbound email, where invites never deliver. Server (routes/admin.js, mounted /api/admin with requireAuth + activityLogger): - Gated by canAdminWorkspace(db, req.user, targetWorkspace): 404 if the workspace is missing, 403 if not an admin of it. This scopes org_admins to their own org and excludes platform_operator (no user/role mgmt, #13). - Validates email (invite-create regex), role in WORKSPACE_ROLES, password min-8 (the /me rule). 409 on duplicate email - never overwrites. - One transaction: global users row (auth_provider 'local', bcrypt.hashSync(pw,10), must_change_password from the flag) + a workspace_members row written inline (same footprint as an accepted invite; accept-invite left untouched). - Explicit audit row admin_create_user; never logs the password; response excludes password/hash. - HOSTED_INSTANCE: never calls sendSignupEmails and stamps both welcome_email_sent_at / activation_nudge_sent_at, so an admin-created user gets no welcome email and never enters the activation-nudge sweep. must_change_password (frontend-first enforcement, per spec): - Migration adds users.must_change_password INTEGER NOT NULL DEFAULT 0; surfaced via requireAuth + /me + login responses. - route() in app.js forces users with the flag to a #/change-password screen (new force-password-change view, reuses PUT /api/auth/me) and blocks every other view until set. The /me update clears the flag. Frontend: "Add User" button beside "Invite member" in the members view (admin-only) opening a modal (email, name, password + generate, role, must-change checkbox); invite and Add User coexist. api.adminCreateUser; EN i18n only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| database.js | ||
| schema.sql | ||