@shipfox/api-auth 5.0.0 → 6.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 (154) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +52 -0
  3. package/README.md +71 -37
  4. package/dist/config.d.ts +0 -12
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +0 -62
  7. package/dist/config.js.map +1 -1
  8. package/dist/core/auth.d.ts +21 -2
  9. package/dist/core/auth.d.ts.map +1 -1
  10. package/dist/core/auth.js +109 -77
  11. package/dist/core/auth.js.map +1 -1
  12. package/dist/core/email-owner.d.ts +12 -0
  13. package/dist/core/email-owner.d.ts.map +1 -0
  14. package/dist/core/email-owner.js +20 -0
  15. package/dist/core/email-owner.js.map +1 -0
  16. package/dist/core/job-lease-token.d.ts.map +1 -1
  17. package/dist/core/job-lease-token.js +3 -2
  18. package/dist/core/job-lease-token.js.map +1 -1
  19. package/dist/core/jwt.d.ts +2 -2
  20. package/dist/core/jwt.d.ts.map +1 -1
  21. package/dist/core/jwt.js.map +1 -1
  22. package/dist/core/rate-limit.d.ts.map +1 -1
  23. package/dist/core/rate-limit.js +2 -7
  24. package/dist/core/rate-limit.js.map +1 -1
  25. package/dist/core/runner-session-token.d.ts.map +1 -1
  26. package/dist/core/runner-session-token.js +3 -2
  27. package/dist/core/runner-session-token.js.map +1 -1
  28. package/dist/db/db.d.ts +0 -218
  29. package/dist/db/db.d.ts.map +1 -1
  30. package/dist/db/db.js +0 -2
  31. package/dist/db/db.js.map +1 -1
  32. package/dist/db/users.d.ts +3 -0
  33. package/dist/db/users.d.ts.map +1 -1
  34. package/dist/db/users.js +28 -10
  35. package/dist/db/users.js.map +1 -1
  36. package/dist/index.d.ts +5 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +40 -34
  39. package/dist/index.js.map +1 -1
  40. package/dist/presentation/auth/jwt-auth.d.ts.map +1 -1
  41. package/dist/presentation/auth/jwt-auth.js +2 -2
  42. package/dist/presentation/auth/jwt-auth.js.map +1 -1
  43. package/dist/presentation/e2eRoutes/create-session.d.ts +2 -1
  44. package/dist/presentation/e2eRoutes/create-session.d.ts.map +1 -1
  45. package/dist/presentation/e2eRoutes/create-session.js +42 -39
  46. package/dist/presentation/e2eRoutes/create-session.js.map +1 -1
  47. package/dist/presentation/e2eRoutes/index.d.ts +2 -1
  48. package/dist/presentation/e2eRoutes/index.d.ts.map +1 -1
  49. package/dist/presentation/e2eRoutes/index.js +12 -10
  50. package/dist/presentation/e2eRoutes/index.js.map +1 -1
  51. package/dist/presentation/inter-module.d.ts +4 -0
  52. package/dist/presentation/inter-module.d.ts.map +1 -0
  53. package/dist/presentation/inter-module.js +16 -0
  54. package/dist/presentation/inter-module.js.map +1 -0
  55. package/dist/presentation/routes/email-verification/verify-email-confirm.d.ts +2 -1
  56. package/dist/presentation/routes/email-verification/verify-email-confirm.d.ts.map +1 -1
  57. package/dist/presentation/routes/email-verification/verify-email-confirm.js +36 -25
  58. package/dist/presentation/routes/email-verification/verify-email-confirm.js.map +1 -1
  59. package/dist/presentation/routes/email-verification/verify-email-resend.d.ts.map +1 -1
  60. package/dist/presentation/routes/email-verification/verify-email-resend.js +20 -4
  61. package/dist/presentation/routes/email-verification/verify-email-resend.js.map +1 -1
  62. package/dist/presentation/routes/index.d.ts +2 -2
  63. package/dist/presentation/routes/index.d.ts.map +1 -1
  64. package/dist/presentation/routes/index.js +11 -13
  65. package/dist/presentation/routes/index.js.map +1 -1
  66. package/dist/presentation/routes/password/password-reset-confirm.d.ts +2 -1
  67. package/dist/presentation/routes/password/password-reset-confirm.d.ts.map +1 -1
  68. package/dist/presentation/routes/password/password-reset-confirm.js +29 -26
  69. package/dist/presentation/routes/password/password-reset-confirm.js.map +1 -1
  70. package/dist/presentation/routes/registration/signup.d.ts +2 -1
  71. package/dist/presentation/routes/registration/signup.d.ts.map +1 -1
  72. package/dist/presentation/routes/registration/signup.js +86 -68
  73. package/dist/presentation/routes/registration/signup.js.map +1 -1
  74. package/dist/presentation/routes/session/login.d.ts +2 -1
  75. package/dist/presentation/routes/session/login.d.ts.map +1 -1
  76. package/dist/presentation/routes/session/login.js +40 -37
  77. package/dist/presentation/routes/session/login.js.map +1 -1
  78. package/dist/presentation/routes/session/refresh.d.ts +2 -1
  79. package/dist/presentation/routes/session/refresh.d.ts.map +1 -1
  80. package/dist/presentation/routes/session/refresh.js +42 -39
  81. package/dist/presentation/routes/session/refresh.js.map +1 -1
  82. package/dist/presentation/subscribers/index.d.ts +0 -1
  83. package/dist/presentation/subscribers/index.d.ts.map +1 -1
  84. package/dist/presentation/subscribers/index.js +0 -1
  85. package/dist/presentation/subscribers/index.js.map +1 -1
  86. package/dist/presentation/subscribers/on-password-reset-send-requested.js +1 -1
  87. package/dist/presentation/subscribers/on-password-reset-send-requested.js.map +1 -1
  88. package/dist/tsconfig.test.tsbuildinfo +1 -1
  89. package/drizzle/0000_initial.sql +1 -13
  90. package/drizzle/meta/0000_snapshot.json +0 -92
  91. package/package.json +17 -13
  92. package/src/config.ts +0 -56
  93. package/src/core/auth.test.ts +106 -187
  94. package/src/core/auth.ts +131 -87
  95. package/src/core/email-owner.test.ts +86 -0
  96. package/src/core/email-owner.ts +23 -0
  97. package/src/core/job-lease-token.test.ts +2 -1
  98. package/src/core/job-lease-token.ts +3 -2
  99. package/src/core/jwt.ts +2 -2
  100. package/src/core/rate-limit.test.ts +11 -28
  101. package/src/core/rate-limit.ts +3 -11
  102. package/src/core/runner-session-token.test.ts +2 -1
  103. package/src/core/runner-session-token.ts +3 -2
  104. package/src/db/db.ts +0 -2
  105. package/src/db/users.ts +32 -14
  106. package/src/index.test.ts +15 -11
  107. package/src/index.ts +23 -20
  108. package/src/presentation/auth/jwt-auth.test.ts +2 -1
  109. package/src/presentation/auth/jwt-auth.ts +2 -2
  110. package/src/presentation/e2eRoutes/create-session.ts +34 -30
  111. package/src/presentation/e2eRoutes/index.test.ts +9 -6
  112. package/src/presentation/e2eRoutes/index.ts +8 -5
  113. package/src/presentation/inter-module.ts +13 -0
  114. package/src/presentation/routes/email-verification/verify-email-confirm.ts +42 -24
  115. package/src/presentation/routes/email-verification/verify-email-resend.ts +18 -4
  116. package/src/presentation/routes/index.test.ts +10 -3
  117. package/src/presentation/routes/index.ts +22 -12
  118. package/src/presentation/routes/password/password-reset-confirm.ts +25 -22
  119. package/src/presentation/routes/password/password-reset-request.test.ts +1 -0
  120. package/src/presentation/routes/rate-limit.test.ts +2 -2
  121. package/src/presentation/routes/registration/signup.test.ts +39 -74
  122. package/src/presentation/routes/registration/signup.ts +89 -70
  123. package/src/presentation/routes/session/login.ts +38 -35
  124. package/src/presentation/routes/session/refresh.ts +43 -40
  125. package/src/presentation/subscribers/email-send-requested.test.ts +2 -30
  126. package/src/presentation/subscribers/index.ts +0 -1
  127. package/src/presentation/subscribers/on-password-reset-send-requested.ts +1 -1
  128. package/test/env.ts +1 -3
  129. package/test/globalSetup.ts +10 -1
  130. package/test/routes.ts +51 -84
  131. package/tsconfig.build.tsbuildinfo +1 -1
  132. package/dist/core/entities/email-verification.d.ts +0 -9
  133. package/dist/core/entities/email-verification.d.ts.map +0 -1
  134. package/dist/core/entities/email-verification.js +0 -3
  135. package/dist/core/entities/email-verification.js.map +0 -1
  136. package/dist/db/email-verifications.d.ts +0 -39
  137. package/dist/db/email-verifications.d.ts.map +0 -1
  138. package/dist/db/email-verifications.js +0 -95
  139. package/dist/db/email-verifications.js.map +0 -1
  140. package/dist/db/schema/email-verifications.d.ts +0 -114
  141. package/dist/db/schema/email-verifications.d.ts.map +0 -1
  142. package/dist/db/schema/email-verifications.js +0 -35
  143. package/dist/db/schema/email-verifications.js.map +0 -1
  144. package/dist/presentation/subscribers/on-email-verification-send-requested.d.ts +0 -3
  145. package/dist/presentation/subscribers/on-email-verification-send-requested.d.ts.map +0 -1
  146. package/dist/presentation/subscribers/on-email-verification-send-requested.js +0 -13
  147. package/dist/presentation/subscribers/on-email-verification-send-requested.js.map +0 -1
  148. package/src/core/entities/email-verification.ts +0 -8
  149. package/src/db/email-verifications.test.ts +0 -61
  150. package/src/db/email-verifications.ts +0 -160
  151. package/src/db/schema/email-verifications.ts +0 -37
  152. package/src/presentation/routes/email-verification/verify-email-confirm.test.ts +0 -66
  153. package/src/presentation/routes/email-verification/verify-email-resend.test.ts +0 -100
  154. package/src/presentation/subscribers/on-email-verification-send-requested.ts +0 -10
@@ -1,66 +0,0 @@
1
- import {AUTH_EMAIL_VERIFICATION_SEND_REQUESTED} from '@shipfox/api-auth-dto';
2
- import type {FastifyInstance} from 'fastify';
3
- import {
4
- cookieHeader,
5
- createAuthTestApp,
6
- extractToken,
7
- getSetCookie,
8
- latestEmailLinkTo,
9
- resetCapturedMail,
10
- signup,
11
- uniqueEmail,
12
- } from '#test/routes.js';
13
-
14
- describe('POST /auth/verify-email/confirm', () => {
15
- let app: FastifyInstance;
16
-
17
- beforeAll(async () => {
18
- app = await createAuthTestApp();
19
- });
20
-
21
- beforeEach(() => {
22
- resetCapturedMail();
23
- });
24
-
25
- afterAll(async () => {
26
- await app.close();
27
- });
28
-
29
- test('verifies a user email with a valid token and starts a session', async () => {
30
- const email = uniqueEmail('verify-confirm');
31
- const password = 'correct horse battery staple';
32
- await signup(app, {email, password});
33
- const token = extractToken(
34
- await latestEmailLinkTo(email, AUTH_EMAIL_VERIFICATION_SEND_REQUESTED),
35
- );
36
-
37
- const confirm = await app.inject({
38
- method: 'POST',
39
- url: '/auth/verify-email/confirm',
40
- payload: {token},
41
- });
42
- const refreshCookie = getSetCookie(confirm);
43
- const refresh = await app.inject({
44
- method: 'POST',
45
- url: '/auth/refresh',
46
- headers: {cookie: cookieHeader(refreshCookie)},
47
- });
48
-
49
- expect(confirm.statusCode).toBe(200);
50
- expect(confirm.json().token).toEqual(expect.any(String));
51
- expect(confirm.json().user.email).toBe(email);
52
- expect(refreshCookie).toContain('shipfox_refresh_token=');
53
- expect(refresh.statusCode).toBe(200);
54
- });
55
-
56
- test('transforms invalid token into 410', async () => {
57
- const res = await app.inject({
58
- method: 'POST',
59
- url: '/auth/verify-email/confirm',
60
- payload: {token: 'bad-token'},
61
- });
62
-
63
- expect(res.statusCode).toBe(410);
64
- expect(res.json().code).toBe('token-invalid');
65
- });
66
- });
@@ -1,100 +0,0 @@
1
- import {
2
- AUTH_EMAIL_VERIFICATION_SEND_REQUESTED,
3
- EMAIL_VERIFICATION_RESEND_COOLDOWN_SECONDS,
4
- } from '@shipfox/api-auth-dto';
5
- import {eq} from 'drizzle-orm';
6
- import type {FastifyInstance} from 'fastify';
7
- import {db} from '#db/db.js';
8
- import {emailVerifications} from '#db/schema/email-verifications.js';
9
- import {
10
- createAuthTestApp,
11
- outboxEventsTo,
12
- resetCapturedMail,
13
- signup,
14
- uniqueEmail,
15
- verifyEmail,
16
- } from '#test/routes.js';
17
-
18
- describe('POST /auth/verify-email/resend', () => {
19
- let app: FastifyInstance;
20
-
21
- beforeAll(async () => {
22
- app = await createAuthTestApp();
23
- });
24
-
25
- beforeEach(() => {
26
- resetCapturedMail();
27
- });
28
-
29
- afterAll(async () => {
30
- await app.close();
31
- });
32
-
33
- test('returns 200 without sending during cooldown for an unverified account', async () => {
34
- const email = uniqueEmail('verify-resend');
35
- await signup(app, {email, password: 'correct horse battery staple'});
36
-
37
- const res = await app.inject({
38
- method: 'POST',
39
- url: '/auth/verify-email/resend',
40
- payload: {email: email.toUpperCase()},
41
- });
42
-
43
- expect(res.statusCode).toBe(200);
44
- expect(res.json().next_resend_available_at).toEqual(expect.any(String));
45
- expect(await outboxEventsTo(email, AUTH_EMAIL_VERIFICATION_SEND_REQUESTED)).toHaveLength(1);
46
- });
47
-
48
- test('returns 200 and sends a new token after cooldown', async () => {
49
- const email = uniqueEmail('verify-resend-ready');
50
- const signupRes = await signup(app, {email, password: 'correct horse battery staple'});
51
- const staleCreatedAt = new Date(
52
- Date.now() - (EMAIL_VERIFICATION_RESEND_COOLDOWN_SECONDS + 1) * 1000,
53
- );
54
- await db()
55
- .update(emailVerifications)
56
- .set({createdAt: staleCreatedAt})
57
- .where(eq(emailVerifications.userId, signupRes.json().user.id));
58
-
59
- const res = await app.inject({
60
- method: 'POST',
61
- url: '/auth/verify-email/resend',
62
- payload: {email},
63
- });
64
-
65
- expect(res.statusCode).toBe(200);
66
- expect(res.json().next_resend_available_at).toEqual(expect.any(String));
67
- expect(await outboxEventsTo(email, AUTH_EMAIL_VERIFICATION_SEND_REQUESTED)).toHaveLength(2);
68
- });
69
-
70
- test('returns 200 without sending mail for a verified account', async () => {
71
- const email = uniqueEmail('verify-resend-verified');
72
- await signup(app, {email, password: 'correct horse battery staple'});
73
- await verifyEmail(app, email);
74
- resetCapturedMail();
75
-
76
- const res = await app.inject({
77
- method: 'POST',
78
- url: '/auth/verify-email/resend',
79
- payload: {email},
80
- });
81
-
82
- expect(res.statusCode).toBe(200);
83
- expect(res.json().next_resend_available_at).toEqual(expect.any(String));
84
- expect(await outboxEventsTo(email, AUTH_EMAIL_VERIFICATION_SEND_REQUESTED)).toHaveLength(1);
85
- });
86
-
87
- test('returns the same response shape for a missing account', async () => {
88
- const email = uniqueEmail('verify-resend-missing');
89
-
90
- const res = await app.inject({
91
- method: 'POST',
92
- url: '/auth/verify-email/resend',
93
- payload: {email},
94
- });
95
-
96
- expect(res.statusCode).toBe(200);
97
- expect(res.json()).toEqual({next_resend_available_at: expect.any(String)});
98
- expect(await outboxEventsTo(email, AUTH_EMAIL_VERIFICATION_SEND_REQUESTED)).toHaveLength(0);
99
- });
100
- });
@@ -1,10 +0,0 @@
1
- import type {AuthEmailVerificationSendRequestedEvent} from '@shipfox/api-auth-dto';
2
- import {renderEmail} from '@shipfox/node-email';
3
- import {mailer} from '#config.js';
4
-
5
- export async function onEmailVerificationSendRequested(
6
- payload: AuthEmailVerificationSendRequestedEvent,
7
- ): Promise<void> {
8
- const email = await renderEmail('verify-email', {verifyLink: payload.verifyLink});
9
- await mailer.send({to: payload.email, ...email});
10
- }