@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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +52 -0
- package/README.md +71 -37
- package/dist/config.d.ts +0 -12
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -62
- package/dist/config.js.map +1 -1
- package/dist/core/auth.d.ts +21 -2
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +109 -77
- package/dist/core/auth.js.map +1 -1
- package/dist/core/email-owner.d.ts +12 -0
- package/dist/core/email-owner.d.ts.map +1 -0
- package/dist/core/email-owner.js +20 -0
- package/dist/core/email-owner.js.map +1 -0
- package/dist/core/job-lease-token.d.ts.map +1 -1
- package/dist/core/job-lease-token.js +3 -2
- package/dist/core/job-lease-token.js.map +1 -1
- package/dist/core/jwt.d.ts +2 -2
- package/dist/core/jwt.d.ts.map +1 -1
- package/dist/core/jwt.js.map +1 -1
- package/dist/core/rate-limit.d.ts.map +1 -1
- package/dist/core/rate-limit.js +2 -7
- package/dist/core/rate-limit.js.map +1 -1
- package/dist/core/runner-session-token.d.ts.map +1 -1
- package/dist/core/runner-session-token.js +3 -2
- package/dist/core/runner-session-token.js.map +1 -1
- package/dist/db/db.d.ts +0 -218
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +0 -2
- package/dist/db/db.js.map +1 -1
- package/dist/db/users.d.ts +3 -0
- package/dist/db/users.d.ts.map +1 -1
- package/dist/db/users.js +28 -10
- package/dist/db/users.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -34
- package/dist/index.js.map +1 -1
- package/dist/presentation/auth/jwt-auth.d.ts.map +1 -1
- package/dist/presentation/auth/jwt-auth.js +2 -2
- package/dist/presentation/auth/jwt-auth.js.map +1 -1
- package/dist/presentation/e2eRoutes/create-session.d.ts +2 -1
- package/dist/presentation/e2eRoutes/create-session.d.ts.map +1 -1
- package/dist/presentation/e2eRoutes/create-session.js +42 -39
- package/dist/presentation/e2eRoutes/create-session.js.map +1 -1
- package/dist/presentation/e2eRoutes/index.d.ts +2 -1
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -1
- package/dist/presentation/e2eRoutes/index.js +12 -10
- package/dist/presentation/e2eRoutes/index.js.map +1 -1
- package/dist/presentation/inter-module.d.ts +4 -0
- package/dist/presentation/inter-module.d.ts.map +1 -0
- package/dist/presentation/inter-module.js +16 -0
- package/dist/presentation/inter-module.js.map +1 -0
- package/dist/presentation/routes/email-verification/verify-email-confirm.d.ts +2 -1
- package/dist/presentation/routes/email-verification/verify-email-confirm.d.ts.map +1 -1
- package/dist/presentation/routes/email-verification/verify-email-confirm.js +36 -25
- package/dist/presentation/routes/email-verification/verify-email-confirm.js.map +1 -1
- package/dist/presentation/routes/email-verification/verify-email-resend.d.ts.map +1 -1
- package/dist/presentation/routes/email-verification/verify-email-resend.js +20 -4
- package/dist/presentation/routes/email-verification/verify-email-resend.js.map +1 -1
- package/dist/presentation/routes/index.d.ts +2 -2
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +11 -13
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/password/password-reset-confirm.d.ts +2 -1
- package/dist/presentation/routes/password/password-reset-confirm.d.ts.map +1 -1
- package/dist/presentation/routes/password/password-reset-confirm.js +29 -26
- package/dist/presentation/routes/password/password-reset-confirm.js.map +1 -1
- package/dist/presentation/routes/registration/signup.d.ts +2 -1
- package/dist/presentation/routes/registration/signup.d.ts.map +1 -1
- package/dist/presentation/routes/registration/signup.js +86 -68
- package/dist/presentation/routes/registration/signup.js.map +1 -1
- package/dist/presentation/routes/session/login.d.ts +2 -1
- package/dist/presentation/routes/session/login.d.ts.map +1 -1
- package/dist/presentation/routes/session/login.js +40 -37
- package/dist/presentation/routes/session/login.js.map +1 -1
- package/dist/presentation/routes/session/refresh.d.ts +2 -1
- package/dist/presentation/routes/session/refresh.d.ts.map +1 -1
- package/dist/presentation/routes/session/refresh.js +42 -39
- package/dist/presentation/routes/session/refresh.js.map +1 -1
- package/dist/presentation/subscribers/index.d.ts +0 -1
- package/dist/presentation/subscribers/index.d.ts.map +1 -1
- package/dist/presentation/subscribers/index.js +0 -1
- package/dist/presentation/subscribers/index.js.map +1 -1
- package/dist/presentation/subscribers/on-password-reset-send-requested.js +1 -1
- package/dist/presentation/subscribers/on-password-reset-send-requested.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_initial.sql +1 -13
- package/drizzle/meta/0000_snapshot.json +0 -92
- package/package.json +17 -13
- package/src/config.ts +0 -56
- package/src/core/auth.test.ts +106 -187
- package/src/core/auth.ts +131 -87
- package/src/core/email-owner.test.ts +86 -0
- package/src/core/email-owner.ts +23 -0
- package/src/core/job-lease-token.test.ts +2 -1
- package/src/core/job-lease-token.ts +3 -2
- package/src/core/jwt.ts +2 -2
- package/src/core/rate-limit.test.ts +11 -28
- package/src/core/rate-limit.ts +3 -11
- package/src/core/runner-session-token.test.ts +2 -1
- package/src/core/runner-session-token.ts +3 -2
- package/src/db/db.ts +0 -2
- package/src/db/users.ts +32 -14
- package/src/index.test.ts +15 -11
- package/src/index.ts +23 -20
- package/src/presentation/auth/jwt-auth.test.ts +2 -1
- package/src/presentation/auth/jwt-auth.ts +2 -2
- package/src/presentation/e2eRoutes/create-session.ts +34 -30
- package/src/presentation/e2eRoutes/index.test.ts +9 -6
- package/src/presentation/e2eRoutes/index.ts +8 -5
- package/src/presentation/inter-module.ts +13 -0
- package/src/presentation/routes/email-verification/verify-email-confirm.ts +42 -24
- package/src/presentation/routes/email-verification/verify-email-resend.ts +18 -4
- package/src/presentation/routes/index.test.ts +10 -3
- package/src/presentation/routes/index.ts +22 -12
- package/src/presentation/routes/password/password-reset-confirm.ts +25 -22
- package/src/presentation/routes/password/password-reset-request.test.ts +1 -0
- package/src/presentation/routes/rate-limit.test.ts +2 -2
- package/src/presentation/routes/registration/signup.test.ts +39 -74
- package/src/presentation/routes/registration/signup.ts +89 -70
- package/src/presentation/routes/session/login.ts +38 -35
- package/src/presentation/routes/session/refresh.ts +43 -40
- package/src/presentation/subscribers/email-send-requested.test.ts +2 -30
- package/src/presentation/subscribers/index.ts +0 -1
- package/src/presentation/subscribers/on-password-reset-send-requested.ts +1 -1
- package/test/env.ts +1 -3
- package/test/globalSetup.ts +10 -1
- package/test/routes.ts +51 -84
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/entities/email-verification.d.ts +0 -9
- package/dist/core/entities/email-verification.d.ts.map +0 -1
- package/dist/core/entities/email-verification.js +0 -3
- package/dist/core/entities/email-verification.js.map +0 -1
- package/dist/db/email-verifications.d.ts +0 -39
- package/dist/db/email-verifications.d.ts.map +0 -1
- package/dist/db/email-verifications.js +0 -95
- package/dist/db/email-verifications.js.map +0 -1
- package/dist/db/schema/email-verifications.d.ts +0 -114
- package/dist/db/schema/email-verifications.d.ts.map +0 -1
- package/dist/db/schema/email-verifications.js +0 -35
- package/dist/db/schema/email-verifications.js.map +0 -1
- package/dist/presentation/subscribers/on-email-verification-send-requested.d.ts +0 -3
- package/dist/presentation/subscribers/on-email-verification-send-requested.d.ts.map +0 -1
- package/dist/presentation/subscribers/on-email-verification-send-requested.js +0 -13
- package/dist/presentation/subscribers/on-email-verification-send-requested.js.map +0 -1
- package/src/core/entities/email-verification.ts +0 -8
- package/src/db/email-verifications.test.ts +0 -61
- package/src/db/email-verifications.ts +0 -160
- package/src/db/schema/email-verifications.ts +0 -37
- package/src/presentation/routes/email-verification/verify-email-confirm.test.ts +0 -66
- package/src/presentation/routes/email-verification/verify-email-resend.test.ts +0 -100
- 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
|
-
}
|