@shipfox/api-auth 18.0.0 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +24 -9
  4. package/dist/core/administration.d.ts +15 -0
  5. package/dist/core/administration.d.ts.map +1 -1
  6. package/dist/core/administration.js +44 -2
  7. package/dist/core/administration.js.map +1 -1
  8. package/dist/core/auth.d.ts.map +1 -1
  9. package/dist/core/auth.js +5 -3
  10. package/dist/core/auth.js.map +1 -1
  11. package/dist/core/entities/agent-access.d.ts +75 -0
  12. package/dist/core/entities/agent-access.d.ts.map +1 -0
  13. package/dist/core/entities/agent-access.js +3 -0
  14. package/dist/core/entities/agent-access.js.map +1 -0
  15. package/dist/core/errors.d.ts +3 -0
  16. package/dist/core/errors.d.ts.map +1 -1
  17. package/dist/core/errors.js +6 -0
  18. package/dist/core/errors.js.map +1 -1
  19. package/dist/db/admin-user-moderation.d.ts.map +1 -1
  20. package/dist/db/admin-user-moderation.js +30 -26
  21. package/dist/db/admin-user-moderation.js.map +1 -1
  22. package/dist/db/admin-user-summary.d.ts +22 -0
  23. package/dist/db/admin-user-summary.d.ts.map +1 -1
  24. package/dist/db/admin-user-summary.js +75 -1
  25. package/dist/db/admin-user-summary.js.map +1 -1
  26. package/dist/db/admin-users.d.ts +11 -0
  27. package/dist/db/admin-users.d.ts.map +1 -1
  28. package/dist/db/admin-users.js +4 -1
  29. package/dist/db/admin-users.js.map +1 -1
  30. package/dist/db/agent-access.d.ts +159 -0
  31. package/dist/db/agent-access.d.ts.map +1 -0
  32. package/dist/db/agent-access.js +267 -0
  33. package/dist/db/agent-access.js.map +1 -0
  34. package/dist/db/db.d.ts +2604 -238
  35. package/dist/db/db.d.ts.map +1 -1
  36. package/dist/db/db.js +7 -0
  37. package/dist/db/db.js.map +1 -1
  38. package/dist/db/schema/agent-access.d.ts +1204 -0
  39. package/dist/db/schema/agent-access.d.ts.map +1 -0
  40. package/dist/db/schema/agent-access.js +267 -0
  41. package/dist/db/schema/agent-access.js.map +1 -0
  42. package/dist/db/schema/users.d.ts.map +1 -1
  43. package/dist/db/schema/users.js +8 -3
  44. package/dist/db/schema/users.js.map +1 -1
  45. package/dist/index.d.ts +3 -2
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +2 -2
  48. package/dist/index.js.map +1 -1
  49. package/dist/metrics/instance.d.ts +1 -1
  50. package/dist/metrics/instance.d.ts.map +1 -1
  51. package/dist/metrics/instance.js.map +1 -1
  52. package/dist/presentation/routes/administration.d.ts.map +1 -1
  53. package/dist/presentation/routes/administration.js +123 -20
  54. package/dist/presentation/routes/administration.js.map +1 -1
  55. package/dist/presentation/routes/email-verification/verify-email-resend.d.ts.map +1 -1
  56. package/dist/presentation/routes/email-verification/verify-email-resend.js +6 -1
  57. package/dist/presentation/routes/email-verification/verify-email-resend.js.map +1 -1
  58. package/dist/presentation/routes/rate-limit.d.ts.map +1 -1
  59. package/dist/presentation/routes/rate-limit.js +10 -0
  60. package/dist/presentation/routes/rate-limit.js.map +1 -1
  61. package/dist/presentation/routes/registration/signup.d.ts.map +1 -1
  62. package/dist/presentation/routes/registration/signup.js +59 -50
  63. package/dist/presentation/routes/registration/signup.js.map +1 -1
  64. package/dist/tsconfig.test.tsbuildinfo +1 -1
  65. package/drizzle/0003_brainy_luckman.sql +6 -0
  66. package/drizzle/0004_yummy_runaways.sql +110 -0
  67. package/drizzle/meta/0003_snapshot.json +844 -0
  68. package/drizzle/meta/0004_snapshot.json +1751 -0
  69. package/drizzle/meta/_journal.json +14 -0
  70. package/package.json +7 -7
  71. package/src/core/admin-role.test.ts +70 -0
  72. package/src/core/administration.ts +78 -1
  73. package/src/core/auth.ts +3 -5
  74. package/src/core/entities/agent-access.ts +80 -0
  75. package/src/core/errors.ts +7 -0
  76. package/src/db/admin-user-moderation.ts +53 -45
  77. package/src/db/admin-user-summary.test.ts +228 -0
  78. package/src/db/admin-user-summary.ts +143 -1
  79. package/src/db/admin-users.ts +21 -1
  80. package/src/db/agent-access.test.ts +370 -0
  81. package/src/db/agent-access.ts +629 -0
  82. package/src/db/db.ts +14 -0
  83. package/src/db/schema/agent-access.ts +273 -0
  84. package/src/db/schema/users.ts +9 -3
  85. package/src/index.ts +6 -0
  86. package/src/metrics/instance.ts +1 -0
  87. package/src/presentation/routes/administration.test.ts +359 -2
  88. package/src/presentation/routes/administration.ts +142 -20
  89. package/src/presentation/routes/email-verification/verify-email-resend.ts +7 -1
  90. package/src/presentation/routes/rate-limit.ts +4 -0
  91. package/src/presentation/routes/registration/signup.ts +52 -41
  92. package/test/globalSetup.ts +1 -1
  93. package/test/routes.ts +3 -1
  94. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 68 files with swc (397.31ms)
2
+ Successfully compiled: 71 files with swc (374.15ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @shipfox/api-auth
2
2
 
3
+ ## 19.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 570f67d: Adds the administrator user directory operation and route while preserving the existing rows result field.
8
+ - b654054: Adds the administrator user directory query for browsing users.
9
+ - 627eda2: Add agent-access authorization storage and personal access token primitives.
10
+
11
+ ### Patch Changes
12
+
13
+ - b416c4c: Preserves existing package behavior while simplifying internal control flow.
14
+ - Updated dependencies [b416c4c]
15
+ - Updated dependencies [627eda2]
16
+ - Updated dependencies [621108c]
17
+ - @shipfox/api-auth-context@19.0.0
18
+ - @shipfox/api-email-challenges@1.1.12
19
+ - @shipfox/node-module@1.0.8
20
+ - @shipfox/node-outbox@0.2.7
21
+ - @shipfox/node-tokens@1.1.0
22
+ - @shipfox/api-auth-dto@19.0.0
23
+ - @shipfox/api-common-dto@15.0.0
24
+ - @shipfox/api-workspaces-dto@15.0.0
25
+ - @shipfox/config@1.2.4
26
+ - @shipfox/inter-module@0.2.3
27
+ - @shipfox/node-auth-root-key@0.2.3
28
+ - @shipfox/node-drizzle@0.3.5
29
+ - @shipfox/node-email@0.3.5
30
+ - @shipfox/node-fastify@0.4.3
31
+ - @shipfox/node-jwt@0.4.0
32
+ - @shipfox/node-mailer@0.2.6
33
+ - @shipfox/node-opentelemetry@0.6.5
34
+ - @shipfox/node-postgres@0.5.1
35
+ - @shipfox/node-rate-limit@0.4.0
36
+
3
37
  ## 18.0.0
4
38
 
5
39
  ### Patch Changes
package/README.md CHANGED
@@ -314,16 +314,17 @@ Bootstrap remains closed only while an active `admin-owner` exists. An owner is
314
314
 
315
315
  The public auth endpoints include an application-layer abuse baseline for open source installs:
316
316
 
317
- | Route | IP bucket | Email bucket |
318
- | --- | --- | --- |
319
- | `POST /auth/login` | 60 attempts per 5 minutes | 10 attempts per 15 minutes |
320
- | `POST /auth/password-reset` | 30 email-send attempts per hour | 3 email-send attempts per hour |
321
- | `POST /auth/verify-email/resend` | Shared with password reset | Shared with password reset |
322
- | `POST /admin/auth/admin-grants/bootstrap` | 5 attempts per 15 minutes | n/a |
323
- | `GET /admin/auth/users` | 60 attempts per 5 minutes | n/a |
324
- | `POST /admin/auth/users/:userId/impersonate` | 20 attempts per 15 minutes | n/a |
317
+ | Route | IP bucket | Actor bucket | Email bucket |
318
+ | --- | --- | --- | --- |
319
+ | `POST /auth/login` | 60 attempts per 5 minutes | n/a | 10 attempts per 15 minutes |
320
+ | `POST /auth/password-reset` | 30 email-send attempts per hour | n/a | 3 email-send attempts per hour |
321
+ | `POST /auth/verify-email/resend` | Shared with password reset | n/a | Shared with password reset |
322
+ | `POST /admin/auth/admin-grants/bootstrap` | 5 attempts per 15 minutes | n/a | n/a |
323
+ | `GET /admin/auth/users` | 60 attempts per 5 minutes | n/a | n/a |
324
+ | `GET /admin/auth/users/directory` | 60 attempts per 5 minutes | 60 attempts per 5 minutes | n/a |
325
+ | `POST /admin/auth/users/:userId/impersonate` | 20 attempts per 15 minutes | 20 attempts per 15 minutes | n/a |
325
326
 
326
- Counters are stored in PostgreSQL as fixed windows in `auth_rate_limits`. IP addresses and email addresses are HMAC-SHA256 values before storage; raw identifiers are not persisted. The identifier key is derived from `AUTH_ROOT_KEY` separately from every token key.
327
+ Counters are stored in PostgreSQL as fixed windows in `auth_rate_limits`. IP addresses, actor IDs, and email addresses are HMAC-SHA256 values before storage; raw identifiers are not persisted. The identifier key is derived from `AUTH_ROOT_KEY` separately from every token key.
327
328
 
328
329
  The limiter uses `request.ip`, so production deployments behind a reverse proxy must configure the API app's `API_TRUST_PROXY` setting. Keep the default `false` when clients connect directly. Use a positive hop count such as `1`, or a trusted proxy IP/CIDR such as `10.0.0.0/8`, when proxy headers are controlled by infrastructure you operate.
329
330
 
@@ -333,6 +334,8 @@ This app-layer limiter protects semantic auth work such as Argon2 verification a
333
334
 
334
335
  `GET /admin/auth/users` requires `admin-observer` and accepts exactly one checked query filter: `id`, `user_id`, or normalized `email`. The response is a bounded `AdministratorUserSummary` containing only the stable user identity, verified-email timestamp, display name, account status, creation timestamp, and current administrator role.
335
336
 
337
+ `GET /admin/auth/users/directory` requires `admin-observer` and returns at most 100 safe user summaries per page. It accepts optional `search`, `status`, `impersonation_eligible`, `limit`, and opaque `cursor` filters. Empty pages return `200` with an empty `users` array and a null `next_cursor`. Directory reads do not create administration action events. Structured security logs include the actor ID, required role, target type, request ID, result, and bounded directory metadata.
338
+
336
339
  `GET /admin/auth/admin-grants` also requires `admin-observer`. It returns at most 100 newest-first `AdministratorGrantSummary` rows per page, with an opaque cursor and a safe embedded user identity. It does not return credentials, sessions, provider payloads, OAuth tokens, refresh tokens, or raw authentication metadata.
337
340
 
338
341
  ### Administrator user moderation
@@ -379,6 +382,7 @@ It also exports lower-level pieces for tests and advanced integration:
379
382
  - `createImpersonatedSessionToken({targetUserId, impersonatorId, workspaces})`: mints an access-token-only impersonated session (capped TTL, `impersonatorId` claim, no refresh material). The `impersonateUser` administration command owns the authorization ladder, idempotency, and audit flow.
380
383
  - `getAuthenticatedSessionContext(request)`: reads the user ID and required refresh-session ID from verified access-token claims. It does not check whether the refresh session is still active.
381
384
  - `findUserByEmail({email})`: read-only lookup of the current owner of a normalized email; see below.
385
+ - `listAdministratorUsers({actorId, limit, cursor?, search?, status?, eligible?})`: returns `{users, rows, nextCursor}` after requiring an active observer role. `rows` remains as a compatibility alias. Search accepts at most 10 whitespace-separated terms. Each term can contain at most 100 characters.
382
386
  - Entity types: `User`, `UserStatus`, `RefreshToken`, `PasswordReset`, and `EmailOwner`.
383
387
 
384
388
  ### External identity callbacks
@@ -497,6 +501,17 @@ The module creates tables with the `auth_` prefix:
497
501
  - `auth_rate_limits`
498
502
  - `auth_admin_grants`
499
503
  - `auth_admin_command_results`
504
+ - `auth_agent_clients`
505
+ - `auth_agent_authorization_requests`
506
+ - `auth_agent_grants`
507
+ - `auth_agent_authorization_codes`
508
+ - `auth_agent_refresh_tokens`
509
+ - `auth_agent_pats`
510
+
511
+ Agent-access credentials are stored as hashes. Client identities retain only
512
+ validated redirect metadata, display names, and lifecycle timestamps.
513
+
514
+ The directory ordering index uses a transactional migration. PostgreSQL holds a `ShareLock` on `auth_users` for the full index build, so writes wait during that period. The build time depends on the table size; schedule the migration when writes can wait.
500
515
 
501
516
  Passwords use Argon2id. Password reset tokens and refresh tokens are opaque tokens stored as hashes. Email verification uses the shared email-challenges module.
502
517
 
@@ -29,6 +29,21 @@ export declare function findAdministratorUserSummary(params: {
29
29
  email: string;
30
30
  id?: never;
31
31
  })): Promise<AdministratorUserSummary | undefined>;
32
+ export interface ListAdministratorUsersParams {
33
+ actorId: string;
34
+ limit: number;
35
+ cursor?: TimestampIdCursor | undefined;
36
+ search?: string | undefined;
37
+ status?: AdministratorUserSummary['status'] | undefined;
38
+ eligible?: boolean | undefined;
39
+ }
40
+ export interface ListAdministratorUsersResult {
41
+ /** Retained for compatibility with the original database-shaped result. */
42
+ rows: AdministratorUserSummary[];
43
+ users: AdministratorUserSummary[];
44
+ nextCursor: TimestampIdCursor | null;
45
+ }
46
+ export declare function listAdministratorUsers(params: ListAdministratorUsersParams): Promise<ListAdministratorUsersResult>;
32
47
  export declare function listAdministratorGrantSummaries(params: {
33
48
  actorId: string;
34
49
  limit: number;
@@ -1 +1 @@
1
- {"version":3,"file":"administration.d.ts","sourceRoot":"","sources":["../../src/core/administration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"administration.d.ts","sourceRoot":"","sources":["../../src/core/administration.ts"],"names":[],"mappings":"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"}
@@ -4,14 +4,18 @@ import { hashOpaqueToken } from '@shipfox/node-tokens';
4
4
  import { config } from '#config.js';
5
5
  import { bootstrapFirstAdminOwner as bootstrapFirstAdminOwnerInDb, grantAdminRoleWithAudit, hasActiveAdminOwner, listAdminGrantSummaries, revokeAdminGrantWithAudit } from '#db/admin-grants.js';
6
6
  import { reactivateUserWithAudit, revokeUserSessionsWithAudit, suspendUserWithAudit } from '#db/admin-user-moderation.js';
7
- import { findAdministratorUser as findAdministratorUserInDb } from '#db/admin-users.js';
7
+ import { findAdministratorUser as findAdministratorUserInDb, listAdministratorUsers as listAdministratorUsersInDb } from '#db/admin-users.js';
8
8
  import { impersonateUserWithAudit, impersonationSucceededEventExists, publishImpersonationFailure } from '#db/impersonation.js';
9
9
  import { recordImpersonationOutcome } from '#metrics/index.js';
10
10
  import { getCurrentAdminRole, requireAdminRole } from './admin-role.js';
11
- import { AdminBootstrapClosedError, AdminGrantAlreadyExistsError, AdminGrantNotFoundError, AdminIdempotencyKeyReuseError, AdminRoleRequiredError, CannotImpersonateAdministratorError, CannotImpersonateSelfError, EmailNotVerifiedError, ImpersonationDisabledError, ImpersonationExpiredError, ImpersonationTargetNotActiveError, InvalidAdminBootstrapTokenError, InvalidCredentialsError, LastAdminOwnerError, UserNotFoundError } from './errors.js';
11
+ import { AdminBootstrapClosedError, AdminGrantAlreadyExistsError, AdminGrantNotFoundError, AdminIdempotencyKeyReuseError, AdminRoleRequiredError, CannotImpersonateAdministratorError, CannotImpersonateSelfError, EmailNotVerifiedError, ImpersonationDisabledError, ImpersonationExpiredError, ImpersonationTargetNotActiveError, InvalidAdminBootstrapTokenError, InvalidAdministratorUserDirectoryFilterError, InvalidCredentialsError, LastAdminOwnerError, UserNotFoundError } from './errors.js';
12
12
  const ADMIN_OWNER_ROLE = 'admin-owner';
13
13
  const ADMIN_OBSERVER_ROLE = 'admin-observer';
14
14
  const ADMIN_OPERATOR_ROLE = 'admin-operator';
15
+ const ADMINISTRATOR_DIRECTORY_MAX_PAGE_SIZE = 100;
16
+ const ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERMS = 10;
17
+ const ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERM_LENGTH = 100;
18
+ const ADMINISTRATOR_DIRECTORY_SEARCH_TERM_SEPARATOR = /\s+/g;
15
19
  const BOOTSTRAP_COMMAND = 'auth.admin_grant.bootstrap';
16
20
  const GRANT_COMMAND = 'auth.admin_grant.grant';
17
21
  const REVOKE_COMMAND = 'auth.admin_grant.revoke';
@@ -104,6 +108,44 @@ export async function findAdministratorUserSummary(params) {
104
108
  if (!user) return undefined;
105
109
  return user;
106
110
  }
111
+ function normalizeAdministratorUserDirectorySearch(search) {
112
+ const normalizedSearch = search?.trim().replace(ADMINISTRATOR_DIRECTORY_SEARCH_TERM_SEPARATOR, ' ');
113
+ if (!normalizedSearch) return;
114
+ const terms = normalizedSearch.split(' ');
115
+ if (terms.length > ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERMS) {
116
+ throw new InvalidAdministratorUserDirectoryFilterError(`Administrator user directory search accepts at most ${ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERMS} terms`);
117
+ }
118
+ if (terms.some((term)=>term.length > ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERM_LENGTH)) {
119
+ throw new InvalidAdministratorUserDirectoryFilterError(`Administrator user directory search terms must be at most ${ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERM_LENGTH} characters`);
120
+ }
121
+ return normalizedSearch;
122
+ }
123
+ function validateAdministratorUserDirectoryFilters(params) {
124
+ const normalizedSearch = normalizeAdministratorUserDirectorySearch(params.search);
125
+ if (params.eligible === true && params.status && params.status !== 'active') {
126
+ throw new InvalidAdministratorUserDirectoryFilterError('eligible users must have active status');
127
+ }
128
+ return normalizedSearch;
129
+ }
130
+ export async function listAdministratorUsers(params) {
131
+ await requireAdminRole({
132
+ userId: params.actorId,
133
+ minimumRole: ADMIN_OBSERVER_ROLE
134
+ });
135
+ const normalizedSearch = validateAdministratorUserDirectoryFilters(params);
136
+ const result = await listAdministratorUsersInDb({
137
+ ...params,
138
+ limit: Math.min(params.limit, ADMINISTRATOR_DIRECTORY_MAX_PAGE_SIZE),
139
+ search: normalizedSearch
140
+ });
141
+ return {
142
+ rows: result.rows,
143
+ // Keep the original `rows` result while exposing the domain-named field
144
+ // used by the directory route.
145
+ users: result.rows,
146
+ nextCursor: result.nextCursor
147
+ };
148
+ }
107
149
  export async function listAdministratorGrantSummaries(params) {
108
150
  await requireAdminRole({
109
151
  userId: params.actorId,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/administration.ts"],"sourcesContent":["import {timingSafeEqual} from 'node:crypto';\nimport type {AdminRole} from '@shipfox/api-auth-dto';\nimport {createAdministrationActionEvent} from '@shipfox/api-common-dto';\nimport type {WorkspacesInterModuleClient} from '@shipfox/api-workspaces-dto/inter-module';\nimport type {TimestampIdCursor} from '@shipfox/node-drizzle';\nimport {hashOpaqueToken} from '@shipfox/node-tokens';\nimport {config} from '#config.js';\nimport {\n bootstrapFirstAdminOwner as bootstrapFirstAdminOwnerInDb,\n grantAdminRoleWithAudit,\n hasActiveAdminOwner,\n listAdminGrantSummaries,\n revokeAdminGrantWithAudit,\n} from '#db/admin-grants.js';\nimport {\n reactivateUserWithAudit,\n revokeUserSessionsWithAudit,\n suspendUserWithAudit,\n type UserModerationResult,\n} from '#db/admin-user-moderation.js';\nimport {findAdministratorUser as findAdministratorUserInDb} from '#db/admin-users.js';\nimport {\n type ImpersonationResult,\n impersonateUserWithAudit,\n impersonationSucceededEventExists,\n publishImpersonationFailure,\n} from '#db/impersonation.js';\nimport {recordImpersonationOutcome} from '#metrics/index.js';\nimport {getCurrentAdminRole, requireAdminRole} from './admin-role.js';\nimport type {AdminGrant} from './entities/admin-grant.js';\nimport type {\n AdministratorGrantSummary,\n AdministratorUserSummary,\n} from './entities/administrator-read-model.js';\nimport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n AdminRoleRequiredError,\n CannotImpersonateAdministratorError,\n CannotImpersonateSelfError,\n EmailNotVerifiedError,\n ImpersonationDisabledError,\n ImpersonationExpiredError,\n ImpersonationTargetNotActiveError,\n InvalidAdminBootstrapTokenError,\n InvalidCredentialsError,\n LastAdminOwnerError,\n UserNotFoundError,\n} from './errors.js';\n\nconst ADMIN_OWNER_ROLE: AdminRole = 'admin-owner';\nconst ADMIN_OBSERVER_ROLE: AdminRole = 'admin-observer';\nconst ADMIN_OPERATOR_ROLE: AdminRole = 'admin-operator';\nconst BOOTSTRAP_COMMAND = 'auth.admin_grant.bootstrap';\nconst GRANT_COMMAND = 'auth.admin_grant.grant';\nconst REVOKE_COMMAND = 'auth.admin_grant.revoke';\nconst SUSPEND_USER_COMMAND = 'auth.user.suspend';\nconst REACTIVATE_USER_COMMAND = 'auth.user.reactivate';\nconst REVOKE_USER_SESSIONS_COMMAND = 'auth.user.revoke-sessions';\nconst IMPERSONATE_COMMAND = 'auth.user.impersonate';\n\n/**\n * Client-contract errors are reported to the caller, not the denial stream: a\n * 404 for an unknown target or a 409 for a reused key is a request mistake,\n * and auditing each retry would drown the `failed` event stream under durable\n * rows that a security review cannot distinguish from genuine denials.\n */\nfunction isImpersonationClientContractError(error: unknown): boolean {\n return error instanceof AdminIdempotencyKeyReuseError || error instanceof UserNotFoundError;\n}\n\n/**\n * Deterministic authorization and eligibility denials. They are raised before\n * the command transaction writes anything, so the transaction is known to have\n * rolled back and the failure event is an unambiguous audit of the denial.\n */\nfunction isImpersonationDenial(error: unknown): boolean {\n return (\n error instanceof ImpersonationDisabledError ||\n error instanceof AdminRoleRequiredError ||\n error instanceof CannotImpersonateSelfError ||\n error instanceof CannotImpersonateAdministratorError ||\n error instanceof ImpersonationTargetNotActiveError ||\n error instanceof ImpersonationExpiredError ||\n error instanceof EmailNotVerifiedError ||\n error instanceof InvalidCredentialsError\n );\n}\n\nexport function administrationCommandFingerprint(command: string, input: unknown): string {\n return hashOpaqueToken(`${command}:${JSON.stringify(input)}`);\n}\n\nfunction bootstrapTokenMatches(candidate: string, expected: string | undefined): boolean {\n if (!expected) return false;\n const candidateHash = Buffer.from(hashOpaqueToken(candidate), 'hex');\n const expectedHash = Buffer.from(hashOpaqueToken(expected), 'hex');\n return timingSafeEqual(candidateHash, expectedHash);\n}\n\nfunction administrationEvent(params: {\n actorId: string;\n actorRole: AdminRole;\n command: string;\n targetType: string;\n targetId: string;\n reason: string;\n requiredRole?: AdminRole;\n correlationId: string;\n idempotencyKeyFingerprint: string;\n}) {\n return createAdministrationActionEvent({\n actorId: params.actorId,\n actorRole: params.actorRole,\n requiredRole: params.requiredRole ?? ADMIN_OWNER_ROLE,\n command: params.command,\n targetType: params.targetType,\n targetId: params.targetId,\n reason: params.reason,\n result: 'succeeded',\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: params.idempotencyKeyFingerprint,\n occurredAt: new Date().toISOString(),\n });\n}\n\nexport interface AdministrationMutationContext {\n actorId: string;\n idempotencyKey: string;\n correlationId: string;\n}\n\nexport interface AdministratorUserMutationResult {\n user: AdministratorUserSummary;\n correlationId: string;\n sessionsRevoked: number;\n}\n\nfunction toAdministratorUserMutationResult(\n result: UserModerationResult,\n): AdministratorUserMutationResult {\n return {\n user: result.user,\n correlationId: result.correlationId,\n sessionsRevoked: result.sessionsRevoked,\n };\n}\n\nexport async function bootstrapFirstAdminOwner(\n params: AdministrationMutationContext & {bootstrapToken: string},\n): Promise<AdminGrant> {\n if (!bootstrapTokenMatches(params.bootstrapToken, config.ADMIN_BOOTSTRAP_TOKEN)) {\n throw new InvalidAdminBootstrapTokenError();\n }\n\n return await bootstrapFirstAdminOwnerInDb({\n userId: params.actorId,\n actorId: params.actorId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n requestFingerprint: administrationCommandFingerprint(BOOTSTRAP_COMMAND, {\n actorId: params.actorId,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole: ADMIN_OWNER_ROLE,\n command: BOOTSTRAP_COMMAND,\n targetType: 'user',\n targetId: params.actorId,\n reason: 'Initial administrator owner bootstrap',\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n }),\n });\n}\n\nexport async function getAdminBootstrapState(): Promise<'available' | 'closed'> {\n return (await hasActiveAdminOwner()) ? 'closed' : 'available';\n}\n\nexport async function findAdministratorUserSummary(\n params: {actorId: string} & ({id: string; email?: never} | {email: string; id?: never}),\n): Promise<AdministratorUserSummary | undefined> {\n await requireAdminRole({userId: params.actorId, minimumRole: ADMIN_OBSERVER_ROLE});\n\n const user = await findAdministratorUserInDb(\n 'id' in params ? {id: params.id} : {email: params.email},\n );\n if (!user) return undefined;\n\n return user;\n}\n\nexport async function listAdministratorGrantSummaries(params: {\n actorId: string;\n limit: number;\n cursor?: TimestampIdCursor;\n}): Promise<{\n grants: AdministratorGrantSummary[];\n nextCursor: TimestampIdCursor | null;\n}> {\n await requireAdminRole({userId: params.actorId, minimumRole: ADMIN_OBSERVER_ROLE});\n\n const result = await listAdminGrantSummaries({\n limit: params.limit,\n ...(params.cursor ? {cursor: params.cursor} : {}),\n });\n return {\n grants: result.rows.map((row) => ({\n grantId: row.id,\n role: row.role,\n createdAt: row.createdAt,\n revokedAt: row.revokedAt,\n user: row.user,\n })),\n nextCursor: result.nextCursor,\n };\n}\n\nexport async function grantAdministratorRole(\n params: AdministrationMutationContext & {userId: string; role: AdminRole; reason: string},\n): Promise<AdminGrant> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OWNER_ROLE,\n });\n return await grantAdminRoleWithAudit({\n userId: params.userId,\n role: params.role,\n actorId: params.actorId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n requestFingerprint: administrationCommandFingerprint(GRANT_COMMAND, {\n userId: params.userId,\n role: params.role,\n reason: params.reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n command: GRANT_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n }),\n });\n}\n\nexport async function revokeAdministratorGrant(\n params: AdministrationMutationContext & {grantId: string; reason: string},\n): Promise<AdminGrant> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OWNER_ROLE,\n });\n return await revokeAdminGrantWithAudit({\n grantId: params.grantId,\n actorId: params.actorId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n requestFingerprint: administrationCommandFingerprint(REVOKE_COMMAND, {\n grantId: params.grantId,\n reason: params.reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n command: REVOKE_COMMAND,\n targetType: 'admin-grant',\n targetId: params.grantId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n }),\n });\n}\n\nexport async function suspendAdministratorUser(\n params: AdministrationMutationContext & {userId: string; reason: string},\n): Promise<AdministratorUserMutationResult> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n return toAdministratorUserMutationResult(\n await suspendUserWithAudit({\n actorId: params.actorId,\n userId: params.userId,\n idempotencyKeyFingerprint,\n requestFingerprint: administrationCommandFingerprint(SUSPEND_USER_COMMAND, {\n userId: params.userId,\n reason: params.reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n requiredRole: ADMIN_OPERATOR_ROLE,\n command: SUSPEND_USER_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n }),\n );\n}\n\nexport async function reactivateAdministratorUser(\n params: AdministrationMutationContext & {userId: string; reason?: string},\n): Promise<AdministratorUserMutationResult> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const reason = params.reason ?? 'User reactivation requested by an administrator';\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n return toAdministratorUserMutationResult(\n await reactivateUserWithAudit({\n actorId: params.actorId,\n userId: params.userId,\n idempotencyKeyFingerprint,\n requestFingerprint: administrationCommandFingerprint(REACTIVATE_USER_COMMAND, {\n userId: params.userId,\n reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n requiredRole: ADMIN_OPERATOR_ROLE,\n command: REACTIVATE_USER_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n }),\n );\n}\n\nexport async function revokeAdministratorUserSessions(\n params: AdministrationMutationContext & {userId: string; reason?: string},\n): Promise<AdministratorUserMutationResult> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const reason = params.reason ?? 'All active user sessions revoked by an administrator';\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n return toAdministratorUserMutationResult(\n await revokeUserSessionsWithAudit({\n actorId: params.actorId,\n userId: params.userId,\n idempotencyKeyFingerprint,\n requestFingerprint: administrationCommandFingerprint(REVOKE_USER_SESSIONS_COMMAND, {\n userId: params.userId,\n reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n requiredRole: ADMIN_OPERATOR_ROLE,\n command: REVOKE_USER_SESSIONS_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n }),\n );\n}\n\nexport interface ImpersonateUserParams extends AdministrationMutationContext {\n targetUserId: string;\n reason: string;\n /**\n * The actor's own session mark, from the verified request context. The\n * positional `/admin` guard rejects an impersonated actor before this\n * command runs; the command refuses the same mark defensively.\n */\n actorImpersonatorId?: string | undefined;\n workspaces: WorkspacesInterModuleClient;\n}\n\n/**\n * Mints a short-lived, marked, audited impersonated session for a target\n * user. Enforces the authorization and eligibility ladder (rules 1-6), the\n * fingerprint-only idempotency flow (replay re-runs the ladder and re-signs\n * with the original expiry), and the audit event contract: success and replay\n * events commit atomically with the command result, and failure events commit\n * in their own transaction after the rollback.\n */\nexport async function impersonateUser(params: ImpersonateUserParams): Promise<ImpersonationResult> {\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n const requestFingerprint = administrationCommandFingerprint(IMPERSONATE_COMMAND, {\n targetUserId: params.targetUserId,\n reason: params.reason,\n });\n try {\n // Rule 1: the capability is an explicit opt-in; the flag is a kill switch\n // and must hold on the replay path as well as the initial mint.\n if (!config.AUTH_IMPERSONATION_ENABLED) throw new ImpersonationDisabledError();\n // Rule 3: an impersonated actor cannot impersonate (nested impersonation).\n if (params.actorImpersonatorId !== undefined) {\n throw new AdminRoleRequiredError(ADMIN_OPERATOR_ROLE);\n }\n // Rule 2: minimum admin-operator, the same bar as suspension and session\n // revocation. Re-checked inside the transaction on every path, replay\n // included, so a revocation mid-window ends the capability immediately.\n await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const result = await impersonateUserWithAudit({\n actorId: params.actorId,\n targetUserId: params.targetUserId,\n reason: params.reason,\n idempotencyKeyFingerprint,\n requestFingerprint,\n correlationId: params.correlationId,\n workspaces: params.workspaces,\n });\n recordImpersonationOutcome('succeeded');\n return result;\n } catch (error) {\n // The command did not hand out a token, so the attempt is a failed outcome\n // regardless of why: mint-volume and denial-spike alerts key off this.\n recordImpersonationOutcome('failed');\n // Client-contract errors (unknown target, reused key) are reported to the\n // caller and never enter the denial stream.\n if (isImpersonationClientContractError(error)) throw error;\n // Deterministic denials always audit: their transaction rolled back with\n // nothing written, so the `failed` event is unambiguous even when a\n // previous mint under the same key left a committed result row.\n if (isImpersonationDenial(error)) {\n await publishImpersonationFailureForActor(params, {\n idempotencyKeyFingerprint,\n correlationId: params.correlationId,\n });\n throw error;\n }\n // An unexpected error may be an ambiguous COMMIT: the mint transaction\n // committed (result row and `succeeded` event are durable) but the driver\n // raised on the acknowledgement. Publishing a `failed` event then would\n // contradict the committed trail, so reconcile against the committed\n // `succeeded` event for THIS invocation before writing anything: the event\n // is written atomically with the result row, and its correlationId is\n // unique per request, so a result row committed by an earlier mint or\n // replay under the same key is never mistaken for this invocation's\n // commit. The reconcile is best-effort: never mask the original error.\n let committed = false;\n try {\n committed = await impersonationSucceededEventExists({\n actorId: params.actorId,\n idempotencyKeyFingerprint,\n correlationId: params.correlationId,\n });\n } catch {\n // Fall through: publish the failure event rather than losing the denial.\n }\n if (!committed) {\n await publishImpersonationFailureForActor(params, {\n idempotencyKeyFingerprint,\n correlationId: params.correlationId,\n });\n }\n throw error;\n }\n}\n\nasync function publishImpersonationFailureForActor(\n params: ImpersonateUserParams,\n audit: {idempotencyKeyFingerprint: string; correlationId: string},\n): Promise<void> {\n // Failures publish from a separate committed transaction after the rollback:\n // the main transaction is gone, so an event written inside it would\n // disappear, and the role check runs before it even opens.\n let actorRole: AdminRole | null = null;\n try {\n actorRole = await getCurrentAdminRole({userId: params.actorId});\n } catch {\n // The failure event is best-effort; never mask the original error.\n }\n await publishImpersonationFailure({\n actorId: params.actorId,\n targetUserId: params.targetUserId,\n reason: params.reason,\n actorRole,\n idempotencyKeyFingerprint: audit.idempotencyKeyFingerprint,\n correlationId: audit.correlationId,\n });\n}\n\nexport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n CannotImpersonateAdministratorError,\n CannotImpersonateSelfError,\n ImpersonationDisabledError,\n ImpersonationExpiredError,\n ImpersonationTargetNotActiveError,\n InvalidAdminBootstrapTokenError,\n LastAdminOwnerError,\n UserNotFoundError,\n};\n"],"names":["timingSafeEqual","createAdministrationActionEvent","hashOpaqueToken","config","bootstrapFirstAdminOwner","bootstrapFirstAdminOwnerInDb","grantAdminRoleWithAudit","hasActiveAdminOwner","listAdminGrantSummaries","revokeAdminGrantWithAudit","reactivateUserWithAudit","revokeUserSessionsWithAudit","suspendUserWithAudit","findAdministratorUser","findAdministratorUserInDb","impersonateUserWithAudit","impersonationSucceededEventExists","publishImpersonationFailure","recordImpersonationOutcome","getCurrentAdminRole","requireAdminRole","AdminBootstrapClosedError","AdminGrantAlreadyExistsError","AdminGrantNotFoundError","AdminIdempotencyKeyReuseError","AdminRoleRequiredError","CannotImpersonateAdministratorError","CannotImpersonateSelfError","EmailNotVerifiedError","ImpersonationDisabledError","ImpersonationExpiredError","ImpersonationTargetNotActiveError","InvalidAdminBootstrapTokenError","InvalidCredentialsError","LastAdminOwnerError","UserNotFoundError","ADMIN_OWNER_ROLE","ADMIN_OBSERVER_ROLE","ADMIN_OPERATOR_ROLE","BOOTSTRAP_COMMAND","GRANT_COMMAND","REVOKE_COMMAND","SUSPEND_USER_COMMAND","REACTIVATE_USER_COMMAND","REVOKE_USER_SESSIONS_COMMAND","IMPERSONATE_COMMAND","isImpersonationClientContractError","error","isImpersonationDenial","administrationCommandFingerprint","command","input","JSON","stringify","bootstrapTokenMatches","candidate","expected","candidateHash","Buffer","from","expectedHash","administrationEvent","params","actorId","actorRole","requiredRole","targetType","targetId","reason","result","correlationId","idempotencyKeyFingerprint","occurredAt","Date","toISOString","toAdministratorUserMutationResult","user","sessionsRevoked","bootstrapToken","ADMIN_BOOTSTRAP_TOKEN","userId","idempotencyKey","requestFingerprint","event","getAdminBootstrapState","findAdministratorUserSummary","minimumRole","id","email","undefined","listAdministratorGrantSummaries","limit","cursor","grants","rows","map","row","grantId","role","createdAt","revokedAt","nextCursor","grantAdministratorRole","revokeAdministratorGrant","suspendAdministratorUser","reactivateAdministratorUser","revokeAdministratorUserSessions","impersonateUser","targetUserId","AUTH_IMPERSONATION_ENABLED","actorImpersonatorId","workspaces","publishImpersonationFailureForActor","committed","audit"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/administration.ts"],"sourcesContent":["import {timingSafeEqual} from 'node:crypto';\nimport type {AdminRole} from '@shipfox/api-auth-dto';\nimport {createAdministrationActionEvent} from '@shipfox/api-common-dto';\nimport type {WorkspacesInterModuleClient} from '@shipfox/api-workspaces-dto/inter-module';\nimport type {TimestampIdCursor} from '@shipfox/node-drizzle';\nimport {hashOpaqueToken} from '@shipfox/node-tokens';\nimport {config} from '#config.js';\nimport {\n bootstrapFirstAdminOwner as bootstrapFirstAdminOwnerInDb,\n grantAdminRoleWithAudit,\n hasActiveAdminOwner,\n listAdminGrantSummaries,\n revokeAdminGrantWithAudit,\n} from '#db/admin-grants.js';\nimport {\n reactivateUserWithAudit,\n revokeUserSessionsWithAudit,\n suspendUserWithAudit,\n type UserModerationResult,\n} from '#db/admin-user-moderation.js';\nimport {\n findAdministratorUser as findAdministratorUserInDb,\n listAdministratorUsers as listAdministratorUsersInDb,\n} from '#db/admin-users.js';\nimport {\n type ImpersonationResult,\n impersonateUserWithAudit,\n impersonationSucceededEventExists,\n publishImpersonationFailure,\n} from '#db/impersonation.js';\nimport {recordImpersonationOutcome} from '#metrics/index.js';\nimport {getCurrentAdminRole, requireAdminRole} from './admin-role.js';\nimport type {AdminGrant} from './entities/admin-grant.js';\nimport type {\n AdministratorGrantSummary,\n AdministratorUserSummary,\n} from './entities/administrator-read-model.js';\nimport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n AdminRoleRequiredError,\n CannotImpersonateAdministratorError,\n CannotImpersonateSelfError,\n EmailNotVerifiedError,\n ImpersonationDisabledError,\n ImpersonationExpiredError,\n ImpersonationTargetNotActiveError,\n InvalidAdminBootstrapTokenError,\n InvalidAdministratorUserDirectoryFilterError,\n InvalidCredentialsError,\n LastAdminOwnerError,\n UserNotFoundError,\n} from './errors.js';\n\nconst ADMIN_OWNER_ROLE: AdminRole = 'admin-owner';\nconst ADMIN_OBSERVER_ROLE: AdminRole = 'admin-observer';\nconst ADMIN_OPERATOR_ROLE: AdminRole = 'admin-operator';\nconst ADMINISTRATOR_DIRECTORY_MAX_PAGE_SIZE = 100;\nconst ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERMS = 10;\nconst ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERM_LENGTH = 100;\nconst ADMINISTRATOR_DIRECTORY_SEARCH_TERM_SEPARATOR = /\\s+/g;\nconst BOOTSTRAP_COMMAND = 'auth.admin_grant.bootstrap';\nconst GRANT_COMMAND = 'auth.admin_grant.grant';\nconst REVOKE_COMMAND = 'auth.admin_grant.revoke';\nconst SUSPEND_USER_COMMAND = 'auth.user.suspend';\nconst REACTIVATE_USER_COMMAND = 'auth.user.reactivate';\nconst REVOKE_USER_SESSIONS_COMMAND = 'auth.user.revoke-sessions';\nconst IMPERSONATE_COMMAND = 'auth.user.impersonate';\n\n/**\n * Client-contract errors are reported to the caller, not the denial stream: a\n * 404 for an unknown target or a 409 for a reused key is a request mistake,\n * and auditing each retry would drown the `failed` event stream under durable\n * rows that a security review cannot distinguish from genuine denials.\n */\nfunction isImpersonationClientContractError(error: unknown): boolean {\n return error instanceof AdminIdempotencyKeyReuseError || error instanceof UserNotFoundError;\n}\n\n/**\n * Deterministic authorization and eligibility denials. They are raised before\n * the command transaction writes anything, so the transaction is known to have\n * rolled back and the failure event is an unambiguous audit of the denial.\n */\nfunction isImpersonationDenial(error: unknown): boolean {\n return (\n error instanceof ImpersonationDisabledError ||\n error instanceof AdminRoleRequiredError ||\n error instanceof CannotImpersonateSelfError ||\n error instanceof CannotImpersonateAdministratorError ||\n error instanceof ImpersonationTargetNotActiveError ||\n error instanceof ImpersonationExpiredError ||\n error instanceof EmailNotVerifiedError ||\n error instanceof InvalidCredentialsError\n );\n}\n\nexport function administrationCommandFingerprint(command: string, input: unknown): string {\n return hashOpaqueToken(`${command}:${JSON.stringify(input)}`);\n}\n\nfunction bootstrapTokenMatches(candidate: string, expected: string | undefined): boolean {\n if (!expected) return false;\n const candidateHash = Buffer.from(hashOpaqueToken(candidate), 'hex');\n const expectedHash = Buffer.from(hashOpaqueToken(expected), 'hex');\n return timingSafeEqual(candidateHash, expectedHash);\n}\n\nfunction administrationEvent(params: {\n actorId: string;\n actorRole: AdminRole;\n command: string;\n targetType: string;\n targetId: string;\n reason: string;\n requiredRole?: AdminRole;\n correlationId: string;\n idempotencyKeyFingerprint: string;\n}) {\n return createAdministrationActionEvent({\n actorId: params.actorId,\n actorRole: params.actorRole,\n requiredRole: params.requiredRole ?? ADMIN_OWNER_ROLE,\n command: params.command,\n targetType: params.targetType,\n targetId: params.targetId,\n reason: params.reason,\n result: 'succeeded',\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: params.idempotencyKeyFingerprint,\n occurredAt: new Date().toISOString(),\n });\n}\n\nexport interface AdministrationMutationContext {\n actorId: string;\n idempotencyKey: string;\n correlationId: string;\n}\n\nexport interface AdministratorUserMutationResult {\n user: AdministratorUserSummary;\n correlationId: string;\n sessionsRevoked: number;\n}\n\nfunction toAdministratorUserMutationResult(\n result: UserModerationResult,\n): AdministratorUserMutationResult {\n return {\n user: result.user,\n correlationId: result.correlationId,\n sessionsRevoked: result.sessionsRevoked,\n };\n}\n\nexport async function bootstrapFirstAdminOwner(\n params: AdministrationMutationContext & {bootstrapToken: string},\n): Promise<AdminGrant> {\n if (!bootstrapTokenMatches(params.bootstrapToken, config.ADMIN_BOOTSTRAP_TOKEN)) {\n throw new InvalidAdminBootstrapTokenError();\n }\n\n return await bootstrapFirstAdminOwnerInDb({\n userId: params.actorId,\n actorId: params.actorId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n requestFingerprint: administrationCommandFingerprint(BOOTSTRAP_COMMAND, {\n actorId: params.actorId,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole: ADMIN_OWNER_ROLE,\n command: BOOTSTRAP_COMMAND,\n targetType: 'user',\n targetId: params.actorId,\n reason: 'Initial administrator owner bootstrap',\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n }),\n });\n}\n\nexport async function getAdminBootstrapState(): Promise<'available' | 'closed'> {\n return (await hasActiveAdminOwner()) ? 'closed' : 'available';\n}\n\nexport async function findAdministratorUserSummary(\n params: {actorId: string} & ({id: string; email?: never} | {email: string; id?: never}),\n): Promise<AdministratorUserSummary | undefined> {\n await requireAdminRole({userId: params.actorId, minimumRole: ADMIN_OBSERVER_ROLE});\n\n const user = await findAdministratorUserInDb(\n 'id' in params ? {id: params.id} : {email: params.email},\n );\n if (!user) return undefined;\n\n return user;\n}\n\nexport interface ListAdministratorUsersParams {\n actorId: string;\n limit: number;\n cursor?: TimestampIdCursor | undefined;\n search?: string | undefined;\n status?: AdministratorUserSummary['status'] | undefined;\n eligible?: boolean | undefined;\n}\n\nexport interface ListAdministratorUsersResult {\n /** Retained for compatibility with the original database-shaped result. */\n rows: AdministratorUserSummary[];\n users: AdministratorUserSummary[];\n nextCursor: TimestampIdCursor | null;\n}\n\nfunction normalizeAdministratorUserDirectorySearch(search: string | undefined): string | undefined {\n const normalizedSearch = search\n ?.trim()\n .replace(ADMINISTRATOR_DIRECTORY_SEARCH_TERM_SEPARATOR, ' ');\n if (!normalizedSearch) return;\n\n const terms = normalizedSearch.split(' ');\n if (terms.length > ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERMS) {\n throw new InvalidAdministratorUserDirectoryFilterError(\n `Administrator user directory search accepts at most ${ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERMS} terms`,\n );\n }\n\n if (terms.some((term) => term.length > ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERM_LENGTH)) {\n throw new InvalidAdministratorUserDirectoryFilterError(\n `Administrator user directory search terms must be at most ${ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERM_LENGTH} characters`,\n );\n }\n\n return normalizedSearch;\n}\n\nfunction validateAdministratorUserDirectoryFilters(\n params: ListAdministratorUsersParams,\n): string | undefined {\n const normalizedSearch = normalizeAdministratorUserDirectorySearch(params.search);\n if (params.eligible === true && params.status && params.status !== 'active') {\n throw new InvalidAdministratorUserDirectoryFilterError(\n 'eligible users must have active status',\n );\n }\n return normalizedSearch;\n}\n\nexport async function listAdministratorUsers(\n params: ListAdministratorUsersParams,\n): Promise<ListAdministratorUsersResult> {\n await requireAdminRole({userId: params.actorId, minimumRole: ADMIN_OBSERVER_ROLE});\n const normalizedSearch = validateAdministratorUserDirectoryFilters(params);\n const result = await listAdministratorUsersInDb({\n ...params,\n limit: Math.min(params.limit, ADMINISTRATOR_DIRECTORY_MAX_PAGE_SIZE),\n search: normalizedSearch,\n });\n return {\n rows: result.rows,\n // Keep the original `rows` result while exposing the domain-named field\n // used by the directory route.\n users: result.rows,\n nextCursor: result.nextCursor,\n };\n}\n\nexport async function listAdministratorGrantSummaries(params: {\n actorId: string;\n limit: number;\n cursor?: TimestampIdCursor;\n}): Promise<{\n grants: AdministratorGrantSummary[];\n nextCursor: TimestampIdCursor | null;\n}> {\n await requireAdminRole({userId: params.actorId, minimumRole: ADMIN_OBSERVER_ROLE});\n\n const result = await listAdminGrantSummaries({\n limit: params.limit,\n ...(params.cursor ? {cursor: params.cursor} : {}),\n });\n return {\n grants: result.rows.map((row) => ({\n grantId: row.id,\n role: row.role,\n createdAt: row.createdAt,\n revokedAt: row.revokedAt,\n user: row.user,\n })),\n nextCursor: result.nextCursor,\n };\n}\n\nexport async function grantAdministratorRole(\n params: AdministrationMutationContext & {userId: string; role: AdminRole; reason: string},\n): Promise<AdminGrant> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OWNER_ROLE,\n });\n return await grantAdminRoleWithAudit({\n userId: params.userId,\n role: params.role,\n actorId: params.actorId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n requestFingerprint: administrationCommandFingerprint(GRANT_COMMAND, {\n userId: params.userId,\n role: params.role,\n reason: params.reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n command: GRANT_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n }),\n });\n}\n\nexport async function revokeAdministratorGrant(\n params: AdministrationMutationContext & {grantId: string; reason: string},\n): Promise<AdminGrant> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OWNER_ROLE,\n });\n return await revokeAdminGrantWithAudit({\n grantId: params.grantId,\n actorId: params.actorId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n requestFingerprint: administrationCommandFingerprint(REVOKE_COMMAND, {\n grantId: params.grantId,\n reason: params.reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n command: REVOKE_COMMAND,\n targetType: 'admin-grant',\n targetId: params.grantId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: hashOpaqueToken(params.idempotencyKey),\n }),\n });\n}\n\nexport async function suspendAdministratorUser(\n params: AdministrationMutationContext & {userId: string; reason: string},\n): Promise<AdministratorUserMutationResult> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n return toAdministratorUserMutationResult(\n await suspendUserWithAudit({\n actorId: params.actorId,\n userId: params.userId,\n idempotencyKeyFingerprint,\n requestFingerprint: administrationCommandFingerprint(SUSPEND_USER_COMMAND, {\n userId: params.userId,\n reason: params.reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n requiredRole: ADMIN_OPERATOR_ROLE,\n command: SUSPEND_USER_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n }),\n );\n}\n\nexport async function reactivateAdministratorUser(\n params: AdministrationMutationContext & {userId: string; reason?: string},\n): Promise<AdministratorUserMutationResult> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const reason = params.reason ?? 'User reactivation requested by an administrator';\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n return toAdministratorUserMutationResult(\n await reactivateUserWithAudit({\n actorId: params.actorId,\n userId: params.userId,\n idempotencyKeyFingerprint,\n requestFingerprint: administrationCommandFingerprint(REACTIVATE_USER_COMMAND, {\n userId: params.userId,\n reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n requiredRole: ADMIN_OPERATOR_ROLE,\n command: REACTIVATE_USER_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n }),\n );\n}\n\nexport async function revokeAdministratorUserSessions(\n params: AdministrationMutationContext & {userId: string; reason?: string},\n): Promise<AdministratorUserMutationResult> {\n const actorRole = await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const reason = params.reason ?? 'All active user sessions revoked by an administrator';\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n return toAdministratorUserMutationResult(\n await revokeUserSessionsWithAudit({\n actorId: params.actorId,\n userId: params.userId,\n idempotencyKeyFingerprint,\n requestFingerprint: administrationCommandFingerprint(REVOKE_USER_SESSIONS_COMMAND, {\n userId: params.userId,\n reason,\n }),\n event: administrationEvent({\n actorId: params.actorId,\n actorRole,\n requiredRole: ADMIN_OPERATOR_ROLE,\n command: REVOKE_USER_SESSIONS_COMMAND,\n targetType: 'user',\n targetId: params.userId,\n reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n }),\n );\n}\n\nexport interface ImpersonateUserParams extends AdministrationMutationContext {\n targetUserId: string;\n reason: string;\n /**\n * The actor's own session mark, from the verified request context. The\n * positional `/admin` guard rejects an impersonated actor before this\n * command runs; the command refuses the same mark defensively.\n */\n actorImpersonatorId?: string | undefined;\n workspaces: WorkspacesInterModuleClient;\n}\n\n/**\n * Mints a short-lived, marked, audited impersonated session for a target\n * user. Enforces the authorization and eligibility ladder (rules 1-6), the\n * fingerprint-only idempotency flow (replay re-runs the ladder and re-signs\n * with the original expiry), and the audit event contract: success and replay\n * events commit atomically with the command result, and failure events commit\n * in their own transaction after the rollback.\n */\nexport async function impersonateUser(params: ImpersonateUserParams): Promise<ImpersonationResult> {\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n const requestFingerprint = administrationCommandFingerprint(IMPERSONATE_COMMAND, {\n targetUserId: params.targetUserId,\n reason: params.reason,\n });\n try {\n // Rule 1: the capability is an explicit opt-in; the flag is a kill switch\n // and must hold on the replay path as well as the initial mint.\n if (!config.AUTH_IMPERSONATION_ENABLED) throw new ImpersonationDisabledError();\n // Rule 3: an impersonated actor cannot impersonate (nested impersonation).\n if (params.actorImpersonatorId !== undefined) {\n throw new AdminRoleRequiredError(ADMIN_OPERATOR_ROLE);\n }\n // Rule 2: minimum admin-operator, the same bar as suspension and session\n // revocation. Re-checked inside the transaction on every path, replay\n // included, so a revocation mid-window ends the capability immediately.\n await requireAdminRole({\n userId: params.actorId,\n minimumRole: ADMIN_OPERATOR_ROLE,\n });\n const result = await impersonateUserWithAudit({\n actorId: params.actorId,\n targetUserId: params.targetUserId,\n reason: params.reason,\n idempotencyKeyFingerprint,\n requestFingerprint,\n correlationId: params.correlationId,\n workspaces: params.workspaces,\n });\n recordImpersonationOutcome('succeeded');\n return result;\n } catch (error) {\n // The command did not hand out a token, so the attempt is a failed outcome\n // regardless of why: mint-volume and denial-spike alerts key off this.\n recordImpersonationOutcome('failed');\n // Client-contract errors (unknown target, reused key) are reported to the\n // caller and never enter the denial stream.\n if (isImpersonationClientContractError(error)) throw error;\n // Deterministic denials always audit: their transaction rolled back with\n // nothing written, so the `failed` event is unambiguous even when a\n // previous mint under the same key left a committed result row.\n if (isImpersonationDenial(error)) {\n await publishImpersonationFailureForActor(params, {\n idempotencyKeyFingerprint,\n correlationId: params.correlationId,\n });\n throw error;\n }\n // An unexpected error may be an ambiguous COMMIT: the mint transaction\n // committed (result row and `succeeded` event are durable) but the driver\n // raised on the acknowledgement. Publishing a `failed` event then would\n // contradict the committed trail, so reconcile against the committed\n // `succeeded` event for THIS invocation before writing anything: the event\n // is written atomically with the result row, and its correlationId is\n // unique per request, so a result row committed by an earlier mint or\n // replay under the same key is never mistaken for this invocation's\n // commit. The reconcile is best-effort: never mask the original error.\n let committed = false;\n try {\n committed = await impersonationSucceededEventExists({\n actorId: params.actorId,\n idempotencyKeyFingerprint,\n correlationId: params.correlationId,\n });\n } catch {\n // Fall through: publish the failure event rather than losing the denial.\n }\n if (!committed) {\n await publishImpersonationFailureForActor(params, {\n idempotencyKeyFingerprint,\n correlationId: params.correlationId,\n });\n }\n throw error;\n }\n}\n\nasync function publishImpersonationFailureForActor(\n params: ImpersonateUserParams,\n audit: {idempotencyKeyFingerprint: string; correlationId: string},\n): Promise<void> {\n // Failures publish from a separate committed transaction after the rollback:\n // the main transaction is gone, so an event written inside it would\n // disappear, and the role check runs before it even opens.\n let actorRole: AdminRole | null = null;\n try {\n actorRole = await getCurrentAdminRole({userId: params.actorId});\n } catch {\n // The failure event is best-effort; never mask the original error.\n }\n await publishImpersonationFailure({\n actorId: params.actorId,\n targetUserId: params.targetUserId,\n reason: params.reason,\n actorRole,\n idempotencyKeyFingerprint: audit.idempotencyKeyFingerprint,\n correlationId: audit.correlationId,\n });\n}\n\nexport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n CannotImpersonateAdministratorError,\n CannotImpersonateSelfError,\n ImpersonationDisabledError,\n ImpersonationExpiredError,\n ImpersonationTargetNotActiveError,\n InvalidAdminBootstrapTokenError,\n LastAdminOwnerError,\n UserNotFoundError,\n};\n"],"names":["timingSafeEqual","createAdministrationActionEvent","hashOpaqueToken","config","bootstrapFirstAdminOwner","bootstrapFirstAdminOwnerInDb","grantAdminRoleWithAudit","hasActiveAdminOwner","listAdminGrantSummaries","revokeAdminGrantWithAudit","reactivateUserWithAudit","revokeUserSessionsWithAudit","suspendUserWithAudit","findAdministratorUser","findAdministratorUserInDb","listAdministratorUsers","listAdministratorUsersInDb","impersonateUserWithAudit","impersonationSucceededEventExists","publishImpersonationFailure","recordImpersonationOutcome","getCurrentAdminRole","requireAdminRole","AdminBootstrapClosedError","AdminGrantAlreadyExistsError","AdminGrantNotFoundError","AdminIdempotencyKeyReuseError","AdminRoleRequiredError","CannotImpersonateAdministratorError","CannotImpersonateSelfError","EmailNotVerifiedError","ImpersonationDisabledError","ImpersonationExpiredError","ImpersonationTargetNotActiveError","InvalidAdminBootstrapTokenError","InvalidAdministratorUserDirectoryFilterError","InvalidCredentialsError","LastAdminOwnerError","UserNotFoundError","ADMIN_OWNER_ROLE","ADMIN_OBSERVER_ROLE","ADMIN_OPERATOR_ROLE","ADMINISTRATOR_DIRECTORY_MAX_PAGE_SIZE","ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERMS","ADMINISTRATOR_DIRECTORY_MAX_SEARCH_TERM_LENGTH","ADMINISTRATOR_DIRECTORY_SEARCH_TERM_SEPARATOR","BOOTSTRAP_COMMAND","GRANT_COMMAND","REVOKE_COMMAND","SUSPEND_USER_COMMAND","REACTIVATE_USER_COMMAND","REVOKE_USER_SESSIONS_COMMAND","IMPERSONATE_COMMAND","isImpersonationClientContractError","error","isImpersonationDenial","administrationCommandFingerprint","command","input","JSON","stringify","bootstrapTokenMatches","candidate","expected","candidateHash","Buffer","from","expectedHash","administrationEvent","params","actorId","actorRole","requiredRole","targetType","targetId","reason","result","correlationId","idempotencyKeyFingerprint","occurredAt","Date","toISOString","toAdministratorUserMutationResult","user","sessionsRevoked","bootstrapToken","ADMIN_BOOTSTRAP_TOKEN","userId","idempotencyKey","requestFingerprint","event","getAdminBootstrapState","findAdministratorUserSummary","minimumRole","id","email","undefined","normalizeAdministratorUserDirectorySearch","search","normalizedSearch","trim","replace","terms","split","length","some","term","validateAdministratorUserDirectoryFilters","eligible","status","limit","Math","min","rows","users","nextCursor","listAdministratorGrantSummaries","cursor","grants","map","row","grantId","role","createdAt","revokedAt","grantAdministratorRole","revokeAdministratorGrant","suspendAdministratorUser","reactivateAdministratorUser","revokeAdministratorUserSessions","impersonateUser","targetUserId","AUTH_IMPERSONATION_ENABLED","actorImpersonatorId","workspaces","publishImpersonationFailureForActor","committed","audit"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"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"}
package/dist/core/auth.js CHANGED
@@ -323,11 +323,13 @@ export async function login(params) {
323
323
  };
324
324
  }
325
325
  export async function createSessionForUser(params) {
326
- const user = params.userId ? await findUserById({
326
+ let user;
327
+ if (params.userId) user = await findUserById({
327
328
  id: params.userId
328
- }) : params.email ? await findUserByEmail({
329
+ });
330
+ else if (params.email) user = await findUserByEmail({
329
331
  email: emailSchema.parse(params.email)
330
- }) : undefined;
332
+ });
331
333
  if (!user) {
332
334
  throw new UserNotFoundError(params.userId ?? params.email ?? 'unknown');
333
335
  }