@shipfox/api-auth 17.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 (99) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +44 -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/core/runner-session-token.d.ts.map +1 -1
  20. package/dist/core/runner-session-token.js +2 -1
  21. package/dist/core/runner-session-token.js.map +1 -1
  22. package/dist/db/admin-user-moderation.d.ts.map +1 -1
  23. package/dist/db/admin-user-moderation.js +30 -26
  24. package/dist/db/admin-user-moderation.js.map +1 -1
  25. package/dist/db/admin-user-summary.d.ts +22 -0
  26. package/dist/db/admin-user-summary.d.ts.map +1 -1
  27. package/dist/db/admin-user-summary.js +75 -1
  28. package/dist/db/admin-user-summary.js.map +1 -1
  29. package/dist/db/admin-users.d.ts +11 -0
  30. package/dist/db/admin-users.d.ts.map +1 -1
  31. package/dist/db/admin-users.js +4 -1
  32. package/dist/db/admin-users.js.map +1 -1
  33. package/dist/db/agent-access.d.ts +159 -0
  34. package/dist/db/agent-access.d.ts.map +1 -0
  35. package/dist/db/agent-access.js +267 -0
  36. package/dist/db/agent-access.js.map +1 -0
  37. package/dist/db/db.d.ts +2604 -238
  38. package/dist/db/db.d.ts.map +1 -1
  39. package/dist/db/db.js +7 -0
  40. package/dist/db/db.js.map +1 -1
  41. package/dist/db/schema/agent-access.d.ts +1204 -0
  42. package/dist/db/schema/agent-access.d.ts.map +1 -0
  43. package/dist/db/schema/agent-access.js +267 -0
  44. package/dist/db/schema/agent-access.js.map +1 -0
  45. package/dist/db/schema/users.d.ts.map +1 -1
  46. package/dist/db/schema/users.js +8 -3
  47. package/dist/db/schema/users.js.map +1 -1
  48. package/dist/index.d.ts +3 -2
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +2 -2
  51. package/dist/index.js.map +1 -1
  52. package/dist/metrics/instance.d.ts +1 -1
  53. package/dist/metrics/instance.d.ts.map +1 -1
  54. package/dist/metrics/instance.js.map +1 -1
  55. package/dist/presentation/routes/administration.d.ts.map +1 -1
  56. package/dist/presentation/routes/administration.js +123 -20
  57. package/dist/presentation/routes/administration.js.map +1 -1
  58. package/dist/presentation/routes/email-verification/verify-email-resend.d.ts.map +1 -1
  59. package/dist/presentation/routes/email-verification/verify-email-resend.js +6 -1
  60. package/dist/presentation/routes/email-verification/verify-email-resend.js.map +1 -1
  61. package/dist/presentation/routes/rate-limit.d.ts.map +1 -1
  62. package/dist/presentation/routes/rate-limit.js +10 -0
  63. package/dist/presentation/routes/rate-limit.js.map +1 -1
  64. package/dist/presentation/routes/registration/signup.d.ts.map +1 -1
  65. package/dist/presentation/routes/registration/signup.js +59 -50
  66. package/dist/presentation/routes/registration/signup.js.map +1 -1
  67. package/dist/tsconfig.test.tsbuildinfo +1 -1
  68. package/drizzle/0003_brainy_luckman.sql +6 -0
  69. package/drizzle/0004_yummy_runaways.sql +110 -0
  70. package/drizzle/meta/0003_snapshot.json +844 -0
  71. package/drizzle/meta/0004_snapshot.json +1751 -0
  72. package/drizzle/meta/_journal.json +14 -0
  73. package/package.json +7 -7
  74. package/src/core/admin-role.test.ts +70 -0
  75. package/src/core/administration.ts +78 -1
  76. package/src/core/auth.ts +3 -5
  77. package/src/core/entities/agent-access.ts +80 -0
  78. package/src/core/errors.ts +7 -0
  79. package/src/core/runner-session-token.test.ts +2 -0
  80. package/src/core/runner-session-token.ts +1 -0
  81. package/src/db/admin-user-moderation.ts +53 -45
  82. package/src/db/admin-user-summary.test.ts +228 -0
  83. package/src/db/admin-user-summary.ts +143 -1
  84. package/src/db/admin-users.ts +21 -1
  85. package/src/db/agent-access.test.ts +370 -0
  86. package/src/db/agent-access.ts +629 -0
  87. package/src/db/db.ts +14 -0
  88. package/src/db/schema/agent-access.ts +273 -0
  89. package/src/db/schema/users.ts +9 -3
  90. package/src/index.ts +6 -0
  91. package/src/metrics/instance.ts +1 -0
  92. package/src/presentation/routes/administration.test.ts +359 -2
  93. package/src/presentation/routes/administration.ts +142 -20
  94. package/src/presentation/routes/email-verification/verify-email-resend.ts +7 -1
  95. package/src/presentation/routes/rate-limit.ts +4 -0
  96. package/src/presentation/routes/registration/signup.ts +52 -41
  97. package/test/globalSetup.ts +1 -1
  98. package/test/routes.ts +3 -1
  99. package/tsconfig.build.tsbuildinfo +1 -1
@@ -15,6 +15,57 @@ import {SIGNUP_DENIAL_MESSAGE_MAX_LENGTH, type SignupPolicy} from '#core/ports.j
15
15
  import {setRefreshTokenCookie} from '#presentation/auth/refresh-cookie.js';
16
16
  import {toUserDto} from '#presentation/dto/user.js';
17
17
 
18
+ function handleEmailChallengeError(error: unknown): void {
19
+ if (!(error instanceof EmailChallengeError)) return;
20
+ throw new ClientError(error.message, `email-challenge-${error.code}`, {
21
+ status: error.code === 'limited' ? 429 : 400,
22
+ ...(error.retryAt ? {details: {retry_at: error.retryAt.toISOString()}} : {}),
23
+ });
24
+ }
25
+
26
+ function handleSignupPolicyError(error: unknown): void {
27
+ if (error instanceof EmailTakenError) {
28
+ throw new ClientError('Email already registered', 'email-taken', {status: 409});
29
+ }
30
+ if (error instanceof SignupNotAllowedError) {
31
+ const message = error.message.slice(0, SIGNUP_DENIAL_MESSAGE_MAX_LENGTH);
32
+ throw new ClientError(message, 'signup-not-allowed', {
33
+ status: 403,
34
+ details: {message, ...(error.format ? {format: error.format} : {})},
35
+ });
36
+ }
37
+ }
38
+
39
+ function handleInvitationError(error: unknown): void {
40
+ if (error instanceof TokenInvalidError) {
41
+ throw new ClientError('Invitation token is invalid', 'invitation-token-invalid', {status: 410});
42
+ }
43
+ if (error instanceof TokenAlreadyUsedError) {
44
+ throw new ClientError('Invitation has already been accepted', 'invitation-token-used', {
45
+ status: 410,
46
+ });
47
+ }
48
+ if (error instanceof TokenExpiredError) {
49
+ throw new ClientError('Invitation has expired', 'invitation-token-expired', {status: 410});
50
+ }
51
+ if (error instanceof InvitationEmailMismatchError) {
52
+ throw new ClientError(
53
+ 'Signup email does not match the invitation',
54
+ 'invitation-email-mismatch',
55
+ {
56
+ status: 403,
57
+ },
58
+ );
59
+ }
60
+ }
61
+
62
+ function handleSignupError(error: unknown): never {
63
+ handleEmailChallengeError(error);
64
+ handleSignupPolicyError(error);
65
+ handleInvitationError(error);
66
+ throw error;
67
+ }
68
+
18
69
  export function createSignupRoute(
19
70
  workspaces: WorkspacesInterModuleClient,
20
71
  signupPolicy?: SignupPolicy,
@@ -30,47 +81,7 @@ export function createSignupRoute(
30
81
  201: signupResponseSchema,
31
82
  },
32
83
  },
33
- errorHandler: (error) => {
34
- if (error instanceof EmailChallengeError) {
35
- throw new ClientError(error.message, `email-challenge-${error.code}`, {
36
- status: error.code === 'limited' ? 429 : 400,
37
- ...(error.retryAt ? {details: {retry_at: error.retryAt.toISOString()}} : {}),
38
- });
39
- }
40
- if (error instanceof EmailTakenError) {
41
- throw new ClientError('Email already registered', 'email-taken', {status: 409});
42
- }
43
- if (error instanceof SignupNotAllowedError) {
44
- const message = error.message.slice(0, SIGNUP_DENIAL_MESSAGE_MAX_LENGTH);
45
- throw new ClientError(message, 'signup-not-allowed', {
46
- status: 403,
47
- details: {message, ...(error.format ? {format: error.format} : {})},
48
- });
49
- }
50
- if (error instanceof TokenInvalidError) {
51
- throw new ClientError('Invitation token is invalid', 'invitation-token-invalid', {
52
- status: 410,
53
- });
54
- }
55
- if (error instanceof TokenAlreadyUsedError) {
56
- throw new ClientError('Invitation has already been accepted', 'invitation-token-used', {
57
- status: 410,
58
- });
59
- }
60
- if (error instanceof TokenExpiredError) {
61
- throw new ClientError('Invitation has expired', 'invitation-token-expired', {
62
- status: 410,
63
- });
64
- }
65
- if (error instanceof InvitationEmailMismatchError) {
66
- throw new ClientError(
67
- 'Signup email does not match the invitation',
68
- 'invitation-email-mismatch',
69
- {status: 403},
70
- );
71
- }
72
- throw error;
73
- },
84
+ errorHandler: handleSignupError,
74
85
  handler: async (request, reply) => {
75
86
  const {email, password, name, invitation_token} = request.body;
76
87
 
@@ -16,7 +16,7 @@ export async function setup() {
16
16
  await initializeEmailChallengesForTests();
17
17
  await resetEmailChallengesForTests();
18
18
  await db().execute(
19
- sql`TRUNCATE auth_admin_command_results, auth_admin_grants, auth_outbox, auth_password_resets, auth_rate_limits, auth_refresh_tokens, auth_users CASCADE`,
19
+ sql`TRUNCATE auth_agent_pats, auth_agent_refresh_tokens, auth_agent_authorization_codes, auth_agent_grants, auth_agent_authorization_requests, auth_agent_clients, auth_admin_command_results, auth_admin_grants, auth_outbox, auth_password_resets, auth_rate_limits, auth_refresh_tokens, auth_users CASCADE`,
20
20
  );
21
21
 
22
22
  closeDb();
package/test/routes.ts CHANGED
@@ -151,7 +151,9 @@ export function extractToken(url: string): string {
151
151
 
152
152
  export function getSetCookie(res: {headers: OutgoingHttpHeaders}): string {
153
153
  const header = res.headers['set-cookie'];
154
- const value = Array.isArray(header) ? header[0] : typeof header === 'string' ? header : undefined;
154
+ let value: string | undefined;
155
+ if (Array.isArray(header)) value = header[0];
156
+ else if (typeof header === 'string') value = header;
155
157
  expect(value).toBeDefined();
156
158
  return value ?? '';
157
159
  }