@shipfox/api-auth 2.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 +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +116 -0
- package/LICENSE +21 -0
- package/README.md +336 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +95 -0
- package/dist/config.js.map +1 -0
- package/dist/core/auth.d.ts +108 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +476 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/entities/email-verification.d.ts +9 -0
- package/dist/core/entities/email-verification.d.ts.map +1 -0
- package/dist/core/entities/email-verification.js +3 -0
- package/dist/core/entities/email-verification.js.map +1 -0
- package/dist/core/entities/password-reset.d.ts +9 -0
- package/dist/core/entities/password-reset.d.ts.map +1 -0
- package/dist/core/entities/password-reset.js +3 -0
- package/dist/core/entities/password-reset.js.map +1 -0
- package/dist/core/entities/refresh-token.d.ts +12 -0
- package/dist/core/entities/refresh-token.d.ts.map +1 -0
- package/dist/core/entities/refresh-token.js +3 -0
- package/dist/core/entities/refresh-token.js.map +1 -0
- package/dist/core/entities/user.d.ts +12 -0
- package/dist/core/entities/user.d.ts.map +1 -0
- package/dist/core/entities/user.js +3 -0
- package/dist/core/entities/user.js.map +1 -0
- package/dist/core/errors.d.ts +54 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +106 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/job-lease-token.d.ts +12 -0
- package/dist/core/job-lease-token.d.ts.map +1 -0
- package/dist/core/job-lease-token.js +58 -0
- package/dist/core/job-lease-token.js.map +1 -0
- package/dist/core/jwt.d.ts +37 -0
- package/dist/core/jwt.d.ts.map +1 -0
- package/dist/core/jwt.js +46 -0
- package/dist/core/jwt.js.map +1 -0
- package/dist/core/password.d.ts +10 -0
- package/dist/core/password.d.ts.map +1 -0
- package/dist/core/password.js +13 -0
- package/dist/core/password.js.map +1 -0
- package/dist/core/rate-limit.d.ts +34 -0
- package/dist/core/rate-limit.d.ts.map +1 -0
- package/dist/core/rate-limit.js +76 -0
- package/dist/core/rate-limit.js.map +1 -0
- package/dist/core/runner-session-token.d.ts +6 -0
- package/dist/core/runner-session-token.d.ts.map +1 -0
- package/dist/core/runner-session-token.js +37 -0
- package/dist/core/runner-session-token.js.map +1 -0
- package/dist/db/db.d.ts +1723 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +28 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/email-verifications.d.ts +39 -0
- package/dist/db/email-verifications.d.ts.map +1 -0
- package/dist/db/email-verifications.js +95 -0
- package/dist/db/email-verifications.js.map +1 -0
- package/dist/db/migrations.d.ts +2 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +5 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/password-resets.d.ts +23 -0
- package/dist/db/password-resets.d.ts.map +1 -0
- package/dist/db/password-resets.js +37 -0
- package/dist/db/password-resets.js.map +1 -0
- package/dist/db/rate-limits.d.ts +18 -0
- package/dist/db/rate-limits.d.ts.map +1 -0
- package/dist/db/rate-limits.js +44 -0
- package/dist/db/rate-limits.js.map +1 -0
- package/dist/db/refresh-tokens.d.ts +44 -0
- package/dist/db/refresh-tokens.d.ts.map +1 -0
- package/dist/db/refresh-tokens.js +71 -0
- package/dist/db/refresh-tokens.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/email-verifications.d.ts +114 -0
- package/dist/db/schema/email-verifications.d.ts.map +1 -0
- package/dist/db/schema/email-verifications.js +35 -0
- package/dist/db/schema/email-verifications.js.map +1 -0
- package/dist/db/schema/outbox.d.ts +195 -0
- package/dist/db/schema/outbox.d.ts.map +1 -0
- package/dist/db/schema/outbox.js +5 -0
- package/dist/db/schema/outbox.js.map +1 -0
- package/dist/db/schema/password-resets.d.ts +114 -0
- package/dist/db/schema/password-resets.d.ts.map +1 -0
- package/dist/db/schema/password-resets.js +35 -0
- package/dist/db/schema/password-resets.js.map +1 -0
- package/dist/db/schema/rate-limits.d.ts +145 -0
- package/dist/db/schema/rate-limits.d.ts.map +1 -0
- package/dist/db/schema/rate-limits.js +25 -0
- package/dist/db/schema/rate-limits.js.map +1 -0
- package/dist/db/schema/refresh-tokens.d.ts +165 -0
- package/dist/db/schema/refresh-tokens.d.ts.map +1 -0
- package/dist/db/schema/refresh-tokens.js +47 -0
- package/dist/db/schema/refresh-tokens.js.map +1 -0
- package/dist/db/schema/users.d.ts +149 -0
- package/dist/db/schema/users.d.ts.map +1 -0
- package/dist/db/schema/users.js +40 -0
- package/dist/db/schema/users.js.map +1 -0
- package/dist/db/users.d.ts +28 -0
- package/dist/db/users.d.ts.map +1 -0
- package/dist/db/users.js +83 -0
- package/dist/db/users.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +3 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instance.d.ts +16 -0
- package/dist/metrics/instance.d.ts.map +1 -0
- package/dist/metrics/instance.js +52 -0
- package/dist/metrics/instance.js.map +1 -0
- package/dist/presentation/auth/bearer-token-auth.d.ts +15 -0
- package/dist/presentation/auth/bearer-token-auth.d.ts.map +1 -0
- package/dist/presentation/auth/bearer-token-auth.js +31 -0
- package/dist/presentation/auth/bearer-token-auth.js.map +1 -0
- package/dist/presentation/auth/jwt-auth.d.ts +10 -0
- package/dist/presentation/auth/jwt-auth.d.ts.map +1 -0
- package/dist/presentation/auth/jwt-auth.js +31 -0
- package/dist/presentation/auth/jwt-auth.js.map +1 -0
- package/dist/presentation/auth/lease-token-auth.d.ts +15 -0
- package/dist/presentation/auth/lease-token-auth.d.ts.map +1 -0
- package/dist/presentation/auth/lease-token-auth.js +27 -0
- package/dist/presentation/auth/lease-token-auth.js.map +1 -0
- package/dist/presentation/auth/refresh-cookie.d.ts +7 -0
- package/dist/presentation/auth/refresh-cookie.d.ts.map +1 -0
- package/dist/presentation/auth/refresh-cookie.js +29 -0
- package/dist/presentation/auth/refresh-cookie.js.map +1 -0
- package/dist/presentation/auth/runner-session-auth.d.ts +3 -0
- package/dist/presentation/auth/runner-session-auth.d.ts.map +1 -0
- package/dist/presentation/auth/runner-session-auth.js +16 -0
- package/dist/presentation/auth/runner-session-auth.js.map +1 -0
- package/dist/presentation/dto/user.d.ts +8 -0
- package/dist/presentation/dto/user.d.ts.map +1 -0
- package/dist/presentation/dto/user.js +19 -0
- package/dist/presentation/dto/user.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-session.d.ts +2 -0
- package/dist/presentation/e2eRoutes/create-session.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-session.js +49 -0
- package/dist/presentation/e2eRoutes/create-session.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-user.d.ts +2 -0
- package/dist/presentation/e2eRoutes/create-user.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-user.js +42 -0
- package/dist/presentation/e2eRoutes/create-user.js.map +1 -0
- package/dist/presentation/e2eRoutes/index.d.ts +3 -0
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/index.js +15 -0
- package/dist/presentation/e2eRoutes/index.js.map +1 -0
- package/dist/presentation/routes/email-verification/verify-email-confirm.d.ts +2 -0
- package/dist/presentation/routes/email-verification/verify-email-confirm.d.ts.map +1 -0
- package/dist/presentation/routes/email-verification/verify-email-confirm.js +35 -0
- package/dist/presentation/routes/email-verification/verify-email-confirm.js.map +1 -0
- package/dist/presentation/routes/email-verification/verify-email-resend.d.ts +2 -0
- package/dist/presentation/routes/email-verification/verify-email-resend.d.ts.map +1 -0
- package/dist/presentation/routes/email-verification/verify-email-resend.js +27 -0
- package/dist/presentation/routes/email-verification/verify-email-resend.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +3 -0
- package/dist/presentation/routes/index.d.ts.map +1 -0
- package/dist/presentation/routes/index.js +31 -0
- package/dist/presentation/routes/index.js.map +1 -0
- package/dist/presentation/routes/password/change-password.d.ts +2 -0
- package/dist/presentation/routes/password/change-password.d.ts.map +1 -0
- package/dist/presentation/routes/password/change-password.js +50 -0
- package/dist/presentation/routes/password/change-password.js.map +1 -0
- package/dist/presentation/routes/password/password-reset-confirm.d.ts +2 -0
- package/dist/presentation/routes/password/password-reset-confirm.d.ts.map +1 -0
- package/dist/presentation/routes/password/password-reset-confirm.js +36 -0
- package/dist/presentation/routes/password/password-reset-confirm.js.map +1 -0
- package/dist/presentation/routes/password/password-reset-request.d.ts +2 -0
- package/dist/presentation/routes/password/password-reset-request.d.ts.map +1 -0
- package/dist/presentation/routes/password/password-reset-request.js +26 -0
- package/dist/presentation/routes/password/password-reset-request.js.map +1 -0
- package/dist/presentation/routes/rate-limit.d.ts +10 -0
- package/dist/presentation/routes/rate-limit.d.ts.map +1 -0
- package/dist/presentation/routes/rate-limit.js +101 -0
- package/dist/presentation/routes/rate-limit.js.map +1 -0
- package/dist/presentation/routes/registration/signup.d.ts +2 -0
- package/dist/presentation/routes/registration/signup.d.ts.map +1 -0
- package/dist/presentation/routes/registration/signup.js +82 -0
- package/dist/presentation/routes/registration/signup.js.map +1 -0
- package/dist/presentation/routes/session/login.d.ts +2 -0
- package/dist/presentation/routes/session/login.d.ts.map +1 -0
- package/dist/presentation/routes/session/login.js +48 -0
- package/dist/presentation/routes/session/login.js.map +1 -0
- package/dist/presentation/routes/session/logout.d.ts +2 -0
- package/dist/presentation/routes/session/logout.d.ts.map +1 -0
- package/dist/presentation/routes/session/logout.js +25 -0
- package/dist/presentation/routes/session/logout.js.map +1 -0
- package/dist/presentation/routes/session/me.d.ts +2 -0
- package/dist/presentation/routes/session/me.d.ts.map +1 -0
- package/dist/presentation/routes/session/me.js +42 -0
- package/dist/presentation/routes/session/me.js.map +1 -0
- package/dist/presentation/routes/session/refresh.d.ts +2 -0
- package/dist/presentation/routes/session/refresh.d.ts.map +1 -0
- package/dist/presentation/routes/session/refresh.js +49 -0
- package/dist/presentation/routes/session/refresh.js.map +1 -0
- package/dist/presentation/subscribers/index.d.ts +3 -0
- package/dist/presentation/subscribers/index.d.ts.map +1 -0
- package/dist/presentation/subscribers/index.js +4 -0
- package/dist/presentation/subscribers/index.js.map +1 -0
- package/dist/presentation/subscribers/on-email-verification-send-requested.d.ts +3 -0
- package/dist/presentation/subscribers/on-email-verification-send-requested.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-email-verification-send-requested.js +13 -0
- package/dist/presentation/subscribers/on-email-verification-send-requested.js.map +1 -0
- package/dist/presentation/subscribers/on-password-reset-send-requested.d.ts +3 -0
- package/dist/presentation/subscribers/on-password-reset-send-requested.d.ts.map +1 -0
- package/dist/presentation/subscribers/on-password-reset-send-requested.js +14 -0
- package/dist/presentation/subscribers/on-password-reset-send-requested.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +81 -0
- package/drizzle/meta/0000_snapshot.json +643 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/package.json +88 -0
- package/src/config.ts +88 -0
- package/src/core/auth.test.ts +675 -0
- package/src/core/auth.ts +560 -0
- package/src/core/entities/email-verification.ts +8 -0
- package/src/core/entities/password-reset.ts +8 -0
- package/src/core/entities/refresh-token.ts +11 -0
- package/src/core/entities/user.ts +12 -0
- package/src/core/errors.ts +123 -0
- package/src/core/job-lease-token.test.ts +201 -0
- package/src/core/job-lease-token.ts +83 -0
- package/src/core/jwt.test.ts +180 -0
- package/src/core/jwt.ts +66 -0
- package/src/core/password.test.ts +28 -0
- package/src/core/password.ts +21 -0
- package/src/core/rate-limit.test.ts +462 -0
- package/src/core/rate-limit.ts +130 -0
- package/src/core/runner-session-token.test.ts +126 -0
- package/src/core/runner-session-token.ts +49 -0
- package/src/db/db.ts +28 -0
- package/src/db/email-verifications.test.ts +61 -0
- package/src/db/email-verifications.ts +160 -0
- package/src/db/migrations.ts +4 -0
- package/src/db/password-resets.test.ts +61 -0
- package/src/db/password-resets.ts +69 -0
- package/src/db/rate-limits.ts +69 -0
- package/src/db/refresh-tokens.test.ts +164 -0
- package/src/db/refresh-tokens.ts +149 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/email-verifications.ts +37 -0
- package/src/db/schema/outbox.ts +4 -0
- package/src/db/schema/password-resets.ts +37 -0
- package/src/db/schema/rate-limits.ts +27 -0
- package/src/db/schema/refresh-tokens.ts +43 -0
- package/src/db/schema/users.ts +37 -0
- package/src/db/users.test.ts +75 -0
- package/src/db/users.ts +121 -0
- package/src/index.test.ts +39 -0
- package/src/index.ts +69 -0
- package/src/metrics/index.ts +13 -0
- package/src/metrics/instance.test.ts +69 -0
- package/src/metrics/instance.ts +77 -0
- package/src/presentation/auth/bearer-token-auth.test.ts +99 -0
- package/src/presentation/auth/bearer-token-auth.ts +51 -0
- package/src/presentation/auth/jwt-auth.test.ts +136 -0
- package/src/presentation/auth/jwt-auth.ts +39 -0
- package/src/presentation/auth/lease-token-auth.test.ts +56 -0
- package/src/presentation/auth/lease-token-auth.ts +25 -0
- package/src/presentation/auth/refresh-cookie.test.ts +39 -0
- package/src/presentation/auth/refresh-cookie.ts +34 -0
- package/src/presentation/auth/runner-session-auth.test.ts +54 -0
- package/src/presentation/auth/runner-session-auth.ts +13 -0
- package/src/presentation/dto/user.ts +21 -0
- package/src/presentation/e2eRoutes/create-session.ts +39 -0
- package/src/presentation/e2eRoutes/create-user.ts +38 -0
- package/src/presentation/e2eRoutes/index.test.ts +102 -0
- package/src/presentation/e2eRoutes/index.ts +10 -0
- package/src/presentation/routes/email-verification/verify-email-confirm.test.ts +66 -0
- package/src/presentation/routes/email-verification/verify-email-confirm.ts +37 -0
- package/src/presentation/routes/email-verification/verify-email-resend.test.ts +100 -0
- package/src/presentation/routes/email-verification/verify-email-resend.ts +26 -0
- package/src/presentation/routes/index.ts +29 -0
- package/src/presentation/routes/password/change-password.test.ts +106 -0
- package/src/presentation/routes/password/change-password.ts +45 -0
- package/src/presentation/routes/password/password-reset-confirm.test.ts +63 -0
- package/src/presentation/routes/password/password-reset-confirm.ts +35 -0
- package/src/presentation/routes/password/password-reset-request.test.ts +56 -0
- package/src/presentation/routes/password/password-reset-request.ts +25 -0
- package/src/presentation/routes/rate-limit.test.ts +341 -0
- package/src/presentation/routes/rate-limit.ts +119 -0
- package/src/presentation/routes/registration/signup.test.ts +284 -0
- package/src/presentation/routes/registration/signup.ts +81 -0
- package/src/presentation/routes/session/login.test.ts +77 -0
- package/src/presentation/routes/session/login.ts +50 -0
- package/src/presentation/routes/session/logout.test.ts +55 -0
- package/src/presentation/routes/session/logout.ts +23 -0
- package/src/presentation/routes/session/me.test.ts +56 -0
- package/src/presentation/routes/session/me.ts +35 -0
- package/src/presentation/routes/session/refresh.test.ts +89 -0
- package/src/presentation/routes/session/refresh.ts +54 -0
- package/src/presentation/subscribers/email-send-requested.test.ts +77 -0
- package/src/presentation/subscribers/index.ts +2 -0
- package/src/presentation/subscribers/on-email-verification-send-requested.ts +10 -0
- package/src/presentation/subscribers/on-password-reset-send-requested.ts +13 -0
- package/test/env.ts +10 -0
- package/test/factories/index.ts +1 -0
- package/test/factories/user.ts +36 -0
- package/test/globalSetup.ts +18 -0
- package/test/index.ts +1 -0
- package/test/routes.ts +275 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +4 -0
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +11 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AUTH_EMAIL_VERIFICATION_SEND_REQUESTED, AUTH_PASSWORD_RESET_SEND_REQUESTED, authEventSchemas } from '@shipfox/api-auth-dto';
|
|
2
|
+
import { subscriberFactory } from '@shipfox/node-module';
|
|
3
|
+
import { db } from '#db/db.js';
|
|
4
|
+
import { migrationsPath } from '#db/migrations.js';
|
|
5
|
+
import { authOutbox } from '#db/schema/outbox.js';
|
|
6
|
+
import { createJwtAuthMethod } from '#presentation/auth/jwt-auth.js';
|
|
7
|
+
import { createLeaseTokenAuthMethod } from '#presentation/auth/lease-token-auth.js';
|
|
8
|
+
import { createRunnerSessionAuthMethod } from '#presentation/auth/runner-session-auth.js';
|
|
9
|
+
import { authE2eRoutes } from '#presentation/e2eRoutes/index.js';
|
|
10
|
+
import { authRoutes } from '#presentation/routes/index.js';
|
|
11
|
+
import { onEmailVerificationSendRequested, onPasswordResetSendRequested } from '#presentation/subscribers/index.js';
|
|
12
|
+
export { createSessionForUser, provisionUser } from '#core/auth.js';
|
|
13
|
+
export { AuthDependencyUnavailableError, EmailNotVerifiedError, InvalidCredentialsError, UserNotFoundError } from '#core/errors.js';
|
|
14
|
+
export { issueJobLeaseToken, jobLeaseParamsFrom, verifyJobLeaseToken } from '#core/job-lease-token.js';
|
|
15
|
+
export { issueRunnerSessionToken, verifyRunnerSessionToken } from '#core/runner-session-token.js';
|
|
16
|
+
export { createJwtAuthMethod } from '#presentation/auth/jwt-auth.js';
|
|
17
|
+
export { createLeaseTokenAuthMethod } from '#presentation/auth/lease-token-auth.js';
|
|
18
|
+
export { authCookiePlugin, clearRefreshTokenCookie, getRefreshTokenCookie, setRefreshTokenCookie } from '#presentation/auth/refresh-cookie.js';
|
|
19
|
+
export { createRunnerSessionAuthMethod } from '#presentation/auth/runner-session-auth.js';
|
|
20
|
+
const subscriber = subscriberFactory();
|
|
21
|
+
export const authModule = {
|
|
22
|
+
name: 'auth',
|
|
23
|
+
database: {
|
|
24
|
+
db,
|
|
25
|
+
migrationsPath
|
|
26
|
+
},
|
|
27
|
+
auth: [
|
|
28
|
+
createJwtAuthMethod(),
|
|
29
|
+
createLeaseTokenAuthMethod(),
|
|
30
|
+
createRunnerSessionAuthMethod()
|
|
31
|
+
],
|
|
32
|
+
routes: [
|
|
33
|
+
authRoutes
|
|
34
|
+
],
|
|
35
|
+
e2eRoutes: [
|
|
36
|
+
authE2eRoutes
|
|
37
|
+
],
|
|
38
|
+
publishers: [
|
|
39
|
+
{
|
|
40
|
+
name: 'auth',
|
|
41
|
+
table: authOutbox,
|
|
42
|
+
db,
|
|
43
|
+
eventSchemas: authEventSchemas
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
subscribers: [
|
|
47
|
+
subscriber(AUTH_EMAIL_VERIFICATION_SEND_REQUESTED, onEmailVerificationSendRequested),
|
|
48
|
+
subscriber(AUTH_PASSWORD_RESET_SEND_REQUESTED, onPasswordResetSendRequested)
|
|
49
|
+
]
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n AUTH_EMAIL_VERIFICATION_SEND_REQUESTED,\n AUTH_PASSWORD_RESET_SEND_REQUESTED,\n type AuthEventMap,\n authEventSchemas,\n} from '@shipfox/api-auth-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {subscriberFactory} from '@shipfox/node-module';\nimport {db} from '#db/db.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {authOutbox} from '#db/schema/outbox.js';\nimport {createJwtAuthMethod} from '#presentation/auth/jwt-auth.js';\nimport {createLeaseTokenAuthMethod} from '#presentation/auth/lease-token-auth.js';\nimport {createRunnerSessionAuthMethod} from '#presentation/auth/runner-session-auth.js';\nimport {authE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {authRoutes} from '#presentation/routes/index.js';\nimport {\n onEmailVerificationSendRequested,\n onPasswordResetSendRequested,\n} from '#presentation/subscribers/index.js';\n\nexport type {JobLeaseTokenClaims, RunnerSessionTokenClaims} from '@shipfox/api-auth-dto';\nexport type {\n CreateSessionForUserError,\n CreateSessionForUserParams,\n CreateSessionForUserResult,\n ProvisionUserParams,\n} from '#core/auth.js';\nexport {createSessionForUser, provisionUser} from '#core/auth.js';\nexport type {User, UserStatus} from '#core/entities/user.js';\nexport {\n AuthDependencyUnavailableError,\n EmailNotVerifiedError,\n InvalidCredentialsError,\n UserNotFoundError,\n} from '#core/errors.js';\nexport {\n issueJobLeaseToken,\n jobLeaseParamsFrom,\n verifyJobLeaseToken,\n} from '#core/job-lease-token.js';\nexport {\n issueRunnerSessionToken,\n verifyRunnerSessionToken,\n} from '#core/runner-session-token.js';\nexport {createJwtAuthMethod} from '#presentation/auth/jwt-auth.js';\nexport {createLeaseTokenAuthMethod} from '#presentation/auth/lease-token-auth.js';\nexport {\n authCookiePlugin,\n clearRefreshTokenCookie,\n getRefreshTokenCookie,\n setRefreshTokenCookie,\n} from '#presentation/auth/refresh-cookie.js';\nexport {createRunnerSessionAuthMethod} from '#presentation/auth/runner-session-auth.js';\n\nconst subscriber = subscriberFactory<AuthEventMap>();\n\nexport const authModule: ShipfoxModule = {\n name: 'auth',\n database: {db, migrationsPath},\n auth: [createJwtAuthMethod(), createLeaseTokenAuthMethod(), createRunnerSessionAuthMethod()],\n routes: [authRoutes],\n e2eRoutes: [authE2eRoutes],\n publishers: [{name: 'auth', table: authOutbox, db, eventSchemas: authEventSchemas}],\n subscribers: [\n subscriber(AUTH_EMAIL_VERIFICATION_SEND_REQUESTED, onEmailVerificationSendRequested),\n subscriber(AUTH_PASSWORD_RESET_SEND_REQUESTED, onPasswordResetSendRequested),\n ],\n};\n"],"names":["AUTH_EMAIL_VERIFICATION_SEND_REQUESTED","AUTH_PASSWORD_RESET_SEND_REQUESTED","authEventSchemas","subscriberFactory","db","migrationsPath","authOutbox","createJwtAuthMethod","createLeaseTokenAuthMethod","createRunnerSessionAuthMethod","authE2eRoutes","authRoutes","onEmailVerificationSendRequested","onPasswordResetSendRequested","createSessionForUser","provisionUser","AuthDependencyUnavailableError","EmailNotVerifiedError","InvalidCredentialsError","UserNotFoundError","issueJobLeaseToken","jobLeaseParamsFrom","verifyJobLeaseToken","issueRunnerSessionToken","verifyRunnerSessionToken","authCookiePlugin","clearRefreshTokenCookie","getRefreshTokenCookie","setRefreshTokenCookie","subscriber","authModule","name","database","auth","routes","e2eRoutes","publishers","table","eventSchemas","subscribers"],"mappings":"AAAA,SACEA,sCAAsC,EACtCC,kCAAkC,EAElCC,gBAAgB,QACX,wBAAwB;AAE/B,SAAQC,iBAAiB,QAAO,uBAAuB;AACvD,SAAQC,EAAE,QAAO,YAAY;AAC7B,SAAQC,cAAc,QAAO,oBAAoB;AACjD,SAAQC,UAAU,QAAO,uBAAuB;AAChD,SAAQC,mBAAmB,QAAO,iCAAiC;AACnE,SAAQC,0BAA0B,QAAO,yCAAyC;AAClF,SAAQC,6BAA6B,QAAO,4CAA4C;AACxF,SAAQC,aAAa,QAAO,mCAAmC;AAC/D,SAAQC,UAAU,QAAO,gCAAgC;AACzD,SACEC,gCAAgC,EAChCC,4BAA4B,QACvB,qCAAqC;AAS5C,SAAQC,oBAAoB,EAAEC,aAAa,QAAO,gBAAgB;AAElE,SACEC,8BAA8B,EAC9BC,qBAAqB,EACrBC,uBAAuB,EACvBC,iBAAiB,QACZ,kBAAkB;AACzB,SACEC,kBAAkB,EAClBC,kBAAkB,EAClBC,mBAAmB,QACd,2BAA2B;AAClC,SACEC,uBAAuB,EACvBC,wBAAwB,QACnB,gCAAgC;AACvC,SAAQjB,mBAAmB,QAAO,iCAAiC;AACnE,SAAQC,0BAA0B,QAAO,yCAAyC;AAClF,SACEiB,gBAAgB,EAChBC,uBAAuB,EACvBC,qBAAqB,EACrBC,qBAAqB,QAChB,uCAAuC;AAC9C,SAAQnB,6BAA6B,QAAO,4CAA4C;AAExF,MAAMoB,aAAa1B;AAEnB,OAAO,MAAM2B,aAA4B;IACvCC,MAAM;IACNC,UAAU;QAAC5B;QAAIC;IAAc;IAC7B4B,MAAM;QAAC1B;QAAuBC;QAA8BC;KAAgC;IAC5FyB,QAAQ;QAACvB;KAAW;IACpBwB,WAAW;QAACzB;KAAc;IAC1B0B,YAAY;QAAC;YAACL,MAAM;YAAQM,OAAO/B;YAAYF;YAAIkC,cAAcpC;QAAgB;KAAE;IACnFqC,aAAa;QACXV,WAAW7B,wCAAwCY;QACnDiB,WAAW5B,oCAAoCY;KAChD;AACH,EAAE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { type AuthRateLimitAction, type AuthRateLimitOutcome, type AuthRateLimitScope, type AuthTokenRefreshOutcome, type AuthTokenType, type AuthTokenVerificationOutcome, recordAuthRateLimitCheck, recordAuthRateLimitPruneFailure, recordTokenIssued, recordTokenRefreshed, recordTokenVerified, } from './instance.js';
|
|
2
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,4BAA4B,EACjC,wBAAwB,EACxB,+BAA+B,EAC/B,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/metrics/index.ts"],"sourcesContent":["export {\n type AuthRateLimitAction,\n type AuthRateLimitOutcome,\n type AuthRateLimitScope,\n type AuthTokenRefreshOutcome,\n type AuthTokenType,\n type AuthTokenVerificationOutcome,\n recordAuthRateLimitCheck,\n recordAuthRateLimitPruneFailure,\n recordTokenIssued,\n recordTokenRefreshed,\n recordTokenVerified,\n} from './instance.js';\n"],"names":["recordAuthRateLimitCheck","recordAuthRateLimitPruneFailure","recordTokenIssued","recordTokenRefreshed","recordTokenVerified"],"mappings":"AAAA,SAOEA,wBAAwB,EACxBC,+BAA+B,EAC/BC,iBAAiB,EACjBC,oBAAoB,EACpBC,mBAAmB,QACd,gBAAgB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type AuthTokenType = 'session' | 'job_lease' | 'runner_session';
|
|
2
|
+
export type AuthTokenVerificationOutcome = 'ok' | 'rejected';
|
|
3
|
+
export type AuthTokenRefreshOutcome = 'rotated' | 'grace' | 'rejected';
|
|
4
|
+
export type AuthRateLimitAction = 'login' | 'email-send';
|
|
5
|
+
export type AuthRateLimitScope = 'ip' | 'email';
|
|
6
|
+
export type AuthRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';
|
|
7
|
+
export declare function recordTokenIssued(tokenType: AuthTokenType): void;
|
|
8
|
+
export declare function recordTokenVerified(tokenType: AuthTokenType, outcome: AuthTokenVerificationOutcome): void;
|
|
9
|
+
export declare function recordTokenRefreshed(outcome: AuthTokenRefreshOutcome): void;
|
|
10
|
+
export declare function recordAuthRateLimitCheck(params: {
|
|
11
|
+
action: AuthRateLimitAction;
|
|
12
|
+
scope: AuthRateLimitScope;
|
|
13
|
+
outcome: AuthRateLimitOutcome;
|
|
14
|
+
}): void;
|
|
15
|
+
export declare function recordAuthRateLimitPruneFailure(): void;
|
|
16
|
+
//# sourceMappingURL=instance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/metrics/instance.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,gBAAgB,CAAC;AACvE,MAAM,MAAM,4BAA4B,GAAG,IAAI,GAAG,UAAU,CAAC;AAC7D,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AACvE,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,YAAY,CAAC;AACzD,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC;AAChD,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAsCzE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAEhE;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,4BAA4B,GACpC,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAE3E;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,OAAO,EAAE,oBAAoB,CAAC;CAC/B,GAAG,IAAI,CAQP;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { instanceMetrics } from '@shipfox/node-opentelemetry';
|
|
2
|
+
const meter = instanceMetrics.getMeter('auth');
|
|
3
|
+
const tokenIssuedCount = meter.createCounter('auth_token_issued', {
|
|
4
|
+
description: 'Tokens issued by token type'
|
|
5
|
+
});
|
|
6
|
+
const tokenVerifiedCount = meter.createCounter('auth_token_verified', {
|
|
7
|
+
description: 'Token verification attempts by token type and outcome'
|
|
8
|
+
});
|
|
9
|
+
const tokenRefreshedCount = meter.createCounter('auth_token_refreshed', {
|
|
10
|
+
description: 'Refresh-token exchanges by outcome'
|
|
11
|
+
});
|
|
12
|
+
const rateLimitCheckCount = meter.createCounter('auth_rate_limit_checks', {
|
|
13
|
+
description: 'Authentication rate limit checks by action, scope, and outcome'
|
|
14
|
+
});
|
|
15
|
+
const rateLimitPruneFailureCount = meter.createCounter('auth_rate_limit_prune_failures', {
|
|
16
|
+
description: 'Authentication rate limit prune failures'
|
|
17
|
+
});
|
|
18
|
+
function recordMetric(record) {
|
|
19
|
+
try {
|
|
20
|
+
record();
|
|
21
|
+
} catch {
|
|
22
|
+
// Metrics must not affect authentication outcomes.
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function recordTokenIssued(tokenType) {
|
|
26
|
+
recordMetric(()=>tokenIssuedCount.add(1, {
|
|
27
|
+
token_type: tokenType
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
export function recordTokenVerified(tokenType, outcome) {
|
|
31
|
+
recordMetric(()=>tokenVerifiedCount.add(1, {
|
|
32
|
+
token_type: tokenType,
|
|
33
|
+
outcome
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
export function recordTokenRefreshed(outcome) {
|
|
37
|
+
recordMetric(()=>tokenRefreshedCount.add(1, {
|
|
38
|
+
outcome
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
export function recordAuthRateLimitCheck(params) {
|
|
42
|
+
recordMetric(()=>rateLimitCheckCount.add(1, {
|
|
43
|
+
action: params.action,
|
|
44
|
+
scope: params.scope,
|
|
45
|
+
outcome: params.outcome
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
export function recordAuthRateLimitPruneFailure() {
|
|
49
|
+
recordMetric(()=>rateLimitPruneFailureCount.add(1));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=instance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/metrics/instance.ts"],"sourcesContent":["import {instanceMetrics} from '@shipfox/node-opentelemetry';\n\nexport type AuthTokenType = 'session' | 'job_lease' | 'runner_session';\nexport type AuthTokenVerificationOutcome = 'ok' | 'rejected';\nexport type AuthTokenRefreshOutcome = 'rotated' | 'grace' | 'rejected';\nexport type AuthRateLimitAction = 'login' | 'email-send';\nexport type AuthRateLimitScope = 'ip' | 'email';\nexport type AuthRateLimitOutcome = 'allowed' | 'blocked' | 'unavailable';\n\nconst meter = instanceMetrics.getMeter('auth');\n\nconst tokenIssuedCount = meter.createCounter<{token_type: AuthTokenType}>('auth_token_issued', {\n description: 'Tokens issued by token type',\n});\n\nconst tokenVerifiedCount = meter.createCounter<{\n token_type: AuthTokenType;\n outcome: AuthTokenVerificationOutcome;\n}>('auth_token_verified', {description: 'Token verification attempts by token type and outcome'});\n\nconst tokenRefreshedCount = meter.createCounter<{outcome: AuthTokenRefreshOutcome}>(\n 'auth_token_refreshed',\n {description: 'Refresh-token exchanges by outcome'},\n);\n\nconst rateLimitCheckCount = meter.createCounter<{\n action: AuthRateLimitAction;\n scope: AuthRateLimitScope;\n outcome: AuthRateLimitOutcome;\n}>('auth_rate_limit_checks', {\n description: 'Authentication rate limit checks by action, scope, and outcome',\n});\n\nconst rateLimitPruneFailureCount = meter.createCounter('auth_rate_limit_prune_failures', {\n description: 'Authentication rate limit prune failures',\n});\n\nfunction recordMetric(record: () => void): void {\n try {\n record();\n } catch {\n // Metrics must not affect authentication outcomes.\n }\n}\n\nexport function recordTokenIssued(tokenType: AuthTokenType): void {\n recordMetric(() => tokenIssuedCount.add(1, {token_type: tokenType}));\n}\n\nexport function recordTokenVerified(\n tokenType: AuthTokenType,\n outcome: AuthTokenVerificationOutcome,\n): void {\n recordMetric(() => tokenVerifiedCount.add(1, {token_type: tokenType, outcome}));\n}\n\nexport function recordTokenRefreshed(outcome: AuthTokenRefreshOutcome): void {\n recordMetric(() => tokenRefreshedCount.add(1, {outcome}));\n}\n\nexport function recordAuthRateLimitCheck(params: {\n action: AuthRateLimitAction;\n scope: AuthRateLimitScope;\n outcome: AuthRateLimitOutcome;\n}): void {\n recordMetric(() =>\n rateLimitCheckCount.add(1, {\n action: params.action,\n scope: params.scope,\n outcome: params.outcome,\n }),\n );\n}\n\nexport function recordAuthRateLimitPruneFailure(): void {\n recordMetric(() => rateLimitPruneFailureCount.add(1));\n}\n"],"names":["instanceMetrics","meter","getMeter","tokenIssuedCount","createCounter","description","tokenVerifiedCount","tokenRefreshedCount","rateLimitCheckCount","rateLimitPruneFailureCount","recordMetric","record","recordTokenIssued","tokenType","add","token_type","recordTokenVerified","outcome","recordTokenRefreshed","recordAuthRateLimitCheck","params","action","scope","recordAuthRateLimitPruneFailure"],"mappings":"AAAA,SAAQA,eAAe,QAAO,8BAA8B;AAS5D,MAAMC,QAAQD,gBAAgBE,QAAQ,CAAC;AAEvC,MAAMC,mBAAmBF,MAAMG,aAAa,CAA8B,qBAAqB;IAC7FC,aAAa;AACf;AAEA,MAAMC,qBAAqBL,MAAMG,aAAa,CAG3C,uBAAuB;IAACC,aAAa;AAAuD;AAE/F,MAAME,sBAAsBN,MAAMG,aAAa,CAC7C,wBACA;IAACC,aAAa;AAAoC;AAGpD,MAAMG,sBAAsBP,MAAMG,aAAa,CAI5C,0BAA0B;IAC3BC,aAAa;AACf;AAEA,MAAMI,6BAA6BR,MAAMG,aAAa,CAAC,kCAAkC;IACvFC,aAAa;AACf;AAEA,SAASK,aAAaC,MAAkB;IACtC,IAAI;QACFA;IACF,EAAE,OAAM;IACN,mDAAmD;IACrD;AACF;AAEA,OAAO,SAASC,kBAAkBC,SAAwB;IACxDH,aAAa,IAAMP,iBAAiBW,GAAG,CAAC,GAAG;YAACC,YAAYF;QAAS;AACnE;AAEA,OAAO,SAASG,oBACdH,SAAwB,EACxBI,OAAqC;IAErCP,aAAa,IAAMJ,mBAAmBQ,GAAG,CAAC,GAAG;YAACC,YAAYF;YAAWI;QAAO;AAC9E;AAEA,OAAO,SAASC,qBAAqBD,OAAgC;IACnEP,aAAa,IAAMH,oBAAoBO,GAAG,CAAC,GAAG;YAACG;QAAO;AACxD;AAEA,OAAO,SAASE,yBAAyBC,MAIxC;IACCV,aAAa,IACXF,oBAAoBM,GAAG,CAAC,GAAG;YACzBO,QAAQD,OAAOC,MAAM;YACrBC,OAAOF,OAAOE,KAAK;YACnBL,SAASG,OAAOH,OAAO;QACzB;AAEJ;AAEA,OAAO,SAASM;IACdb,aAAa,IAAMD,2BAA2BK,GAAG,CAAC;AACpD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type AuthMethod } from '@shipfox/node-fastify';
|
|
2
|
+
import type { FastifyRequest } from 'fastify';
|
|
3
|
+
interface UnauthorizedErrorParams {
|
|
4
|
+
message: string;
|
|
5
|
+
code: string;
|
|
6
|
+
}
|
|
7
|
+
interface BearerTokenAuthMethodOptions<TClaims> {
|
|
8
|
+
name: string;
|
|
9
|
+
verifyToken: (token: string) => Promise<TClaims | null>;
|
|
10
|
+
invalidTokenError: UnauthorizedErrorParams;
|
|
11
|
+
setContext: (request: FastifyRequest, claims: TClaims) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function createBearerTokenAuthMethod<TClaims>(options: BearerTokenAuthMethodOptions<TClaims>): AuthMethod;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=bearer-token-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bearer-token-auth.d.ts","sourceRoot":"","sources":["../../../src/presentation/auth/bearer-token-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,UAAU,EAAkC,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAE5C,UAAU,uBAAuB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,4BAA4B,CAAC,OAAO;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACxD,iBAAiB,EAAE,uBAAuB,CAAC;IAC3C,UAAU,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CAChE;AAOD,wBAAgB,2BAA2B,CAAC,OAAO,EACjD,OAAO,EAAE,4BAA4B,CAAC,OAAO,CAAC,GAC7C,UAAU,CAaZ"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ClientError, extractBearerToken } from '@shipfox/node-fastify';
|
|
2
|
+
const missingBearerError = {
|
|
3
|
+
message: 'Missing or invalid Authorization header',
|
|
4
|
+
code: 'unauthorized'
|
|
5
|
+
};
|
|
6
|
+
export function createBearerTokenAuthMethod(options) {
|
|
7
|
+
return {
|
|
8
|
+
name: options.name,
|
|
9
|
+
authenticate: async (request)=>{
|
|
10
|
+
const token = extractBearerToken(request.headers.authorization);
|
|
11
|
+
if (!token) throwUnauthorized(missingBearerError);
|
|
12
|
+
const claims = await verifyBearerToken(token, options.verifyToken);
|
|
13
|
+
if (!claims) throwUnauthorized(options.invalidTokenError);
|
|
14
|
+
options.setContext(request, claims);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
async function verifyBearerToken(token, verifyToken) {
|
|
19
|
+
try {
|
|
20
|
+
return await verifyToken(token);
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function throwUnauthorized(error) {
|
|
26
|
+
throw new ClientError(error.message, error.code, {
|
|
27
|
+
status: 401
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=bearer-token-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/auth/bearer-token-auth.ts"],"sourcesContent":["import {type AuthMethod, ClientError, extractBearerToken} from '@shipfox/node-fastify';\nimport type {FastifyRequest} from 'fastify';\n\ninterface UnauthorizedErrorParams {\n message: string;\n code: string;\n}\n\ninterface BearerTokenAuthMethodOptions<TClaims> {\n name: string;\n verifyToken: (token: string) => Promise<TClaims | null>;\n invalidTokenError: UnauthorizedErrorParams;\n setContext: (request: FastifyRequest, claims: TClaims) => void;\n}\n\nconst missingBearerError: UnauthorizedErrorParams = {\n message: 'Missing or invalid Authorization header',\n code: 'unauthorized',\n};\n\nexport function createBearerTokenAuthMethod<TClaims>(\n options: BearerTokenAuthMethodOptions<TClaims>,\n): AuthMethod {\n return {\n name: options.name,\n authenticate: async (request) => {\n const token = extractBearerToken(request.headers.authorization);\n if (!token) throwUnauthorized(missingBearerError);\n\n const claims = await verifyBearerToken(token, options.verifyToken);\n if (!claims) throwUnauthorized(options.invalidTokenError);\n\n options.setContext(request, claims);\n },\n };\n}\n\nasync function verifyBearerToken<TClaims>(\n token: string,\n verifyToken: (token: string) => Promise<TClaims | null>,\n): Promise<TClaims | null> {\n try {\n return await verifyToken(token);\n } catch {\n return null;\n }\n}\n\nfunction throwUnauthorized(error: UnauthorizedErrorParams): never {\n throw new ClientError(error.message, error.code, {status: 401});\n}\n"],"names":["ClientError","extractBearerToken","missingBearerError","message","code","createBearerTokenAuthMethod","options","name","authenticate","request","token","headers","authorization","throwUnauthorized","claims","verifyBearerToken","verifyToken","invalidTokenError","setContext","error","status"],"mappings":"AAAA,SAAyBA,WAAW,EAAEC,kBAAkB,QAAO,wBAAwB;AAevF,MAAMC,qBAA8C;IAClDC,SAAS;IACTC,MAAM;AACR;AAEA,OAAO,SAASC,4BACdC,OAA8C;IAE9C,OAAO;QACLC,MAAMD,QAAQC,IAAI;QAClBC,cAAc,OAAOC;YACnB,MAAMC,QAAQT,mBAAmBQ,QAAQE,OAAO,CAACC,aAAa;YAC9D,IAAI,CAACF,OAAOG,kBAAkBX;YAE9B,MAAMY,SAAS,MAAMC,kBAAkBL,OAAOJ,QAAQU,WAAW;YACjE,IAAI,CAACF,QAAQD,kBAAkBP,QAAQW,iBAAiB;YAExDX,QAAQY,UAAU,CAACT,SAASK;QAC9B;IACF;AACF;AAEA,eAAeC,kBACbL,KAAa,EACbM,WAAuD;IAEvD,IAAI;QACF,OAAO,MAAMA,YAAYN;IAC3B,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,SAASG,kBAAkBM,KAA8B;IACvD,MAAM,IAAInB,YAAYmB,MAAMhB,OAAO,EAAEgB,MAAMf,IAAI,EAAE;QAACgB,QAAQ;IAAG;AAC/D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type UserContext } from '@shipfox/api-auth-context';
|
|
2
|
+
import type { AuthMethod } from '@shipfox/node-fastify';
|
|
3
|
+
import type { FastifyRequest } from 'fastify';
|
|
4
|
+
export type ClientContext = UserContext;
|
|
5
|
+
export interface CreateJwtAuthMethodOptions {
|
|
6
|
+
secret: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function getClientContext(request: FastifyRequest): ClientContext | null;
|
|
9
|
+
export declare function createJwtAuthMethod(): AuthMethod;
|
|
10
|
+
//# sourceMappingURL=jwt-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-auth.d.ts","sourceRoot":"","sources":["../../../src/presentation/auth/jwt-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAK5C,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC;AAExC,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,GAAG,IAAI,CAE9E;AAED,wBAAgB,mBAAmB,IAAI,UAAU,CAehD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AUTH_USER, buildUserContext, getUserContext, setUserContext } from '@shipfox/api-auth-context';
|
|
2
|
+
import { config } from '#config.js';
|
|
3
|
+
import { verifyUserToken } from '#core/jwt.js';
|
|
4
|
+
import { createBearerTokenAuthMethod } from './bearer-token-auth.js';
|
|
5
|
+
export function getClientContext(request) {
|
|
6
|
+
return getUserContext(request);
|
|
7
|
+
}
|
|
8
|
+
export function createJwtAuthMethod() {
|
|
9
|
+
return createBearerTokenAuthMethod({
|
|
10
|
+
name: AUTH_USER,
|
|
11
|
+
verifyToken: (token)=>verifyUserToken({
|
|
12
|
+
token,
|
|
13
|
+
secret: config.AUTH_JWT_SECRET
|
|
14
|
+
}),
|
|
15
|
+
invalidTokenError: {
|
|
16
|
+
message: 'Invalid or expired token',
|
|
17
|
+
code: 'unauthorized'
|
|
18
|
+
},
|
|
19
|
+
setContext: (request, claims)=>{
|
|
20
|
+
const clientContext = buildUserContext({
|
|
21
|
+
userId: claims.sub,
|
|
22
|
+
email: claims.email,
|
|
23
|
+
name: claims.name ?? null,
|
|
24
|
+
memberships: claims.memberships
|
|
25
|
+
});
|
|
26
|
+
setUserContext(request, clientContext);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=jwt-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/auth/jwt-auth.ts"],"sourcesContent":["import {\n AUTH_USER,\n buildUserContext,\n getUserContext,\n setUserContext,\n type UserContext,\n} from '@shipfox/api-auth-context';\nimport type {AuthMethod} from '@shipfox/node-fastify';\nimport type {FastifyRequest} from 'fastify';\nimport {config} from '#config.js';\nimport {verifyUserToken} from '#core/jwt.js';\nimport {createBearerTokenAuthMethod} from './bearer-token-auth.js';\n\nexport type ClientContext = UserContext;\n\nexport interface CreateJwtAuthMethodOptions {\n secret: string;\n}\n\nexport function getClientContext(request: FastifyRequest): ClientContext | null {\n return getUserContext(request);\n}\n\nexport function createJwtAuthMethod(): AuthMethod {\n return createBearerTokenAuthMethod({\n name: AUTH_USER,\n verifyToken: (token) => verifyUserToken({token, secret: config.AUTH_JWT_SECRET}),\n invalidTokenError: {message: 'Invalid or expired token', code: 'unauthorized'},\n setContext: (request, claims) => {\n const clientContext: ClientContext = buildUserContext({\n userId: claims.sub,\n email: claims.email,\n name: claims.name ?? null,\n memberships: claims.memberships,\n });\n setUserContext(request, clientContext);\n },\n });\n}\n"],"names":["AUTH_USER","buildUserContext","getUserContext","setUserContext","config","verifyUserToken","createBearerTokenAuthMethod","getClientContext","request","createJwtAuthMethod","name","verifyToken","token","secret","AUTH_JWT_SECRET","invalidTokenError","message","code","setContext","claims","clientContext","userId","sub","email","memberships"],"mappings":"AAAA,SACEA,SAAS,EACTC,gBAAgB,EAChBC,cAAc,EACdC,cAAc,QAET,4BAA4B;AAGnC,SAAQC,MAAM,QAAO,aAAa;AAClC,SAAQC,eAAe,QAAO,eAAe;AAC7C,SAAQC,2BAA2B,QAAO,yBAAyB;AAQnE,OAAO,SAASC,iBAAiBC,OAAuB;IACtD,OAAON,eAAeM;AACxB;AAEA,OAAO,SAASC;IACd,OAAOH,4BAA4B;QACjCI,MAAMV;QACNW,aAAa,CAACC,QAAUP,gBAAgB;gBAACO;gBAAOC,QAAQT,OAAOU,eAAe;YAAA;QAC9EC,mBAAmB;YAACC,SAAS;YAA4BC,MAAM;QAAc;QAC7EC,YAAY,CAACV,SAASW;YACpB,MAAMC,gBAA+BnB,iBAAiB;gBACpDoB,QAAQF,OAAOG,GAAG;gBAClBC,OAAOJ,OAAOI,KAAK;gBACnBb,MAAMS,OAAOT,IAAI,IAAI;gBACrBc,aAAaL,OAAOK,WAAW;YACjC;YACArB,eAAeK,SAASY;QAC1B;IACF;AACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AuthMethod } from '@shipfox/node-fastify';
|
|
2
|
+
/**
|
|
3
|
+
* Trust boundary: the signed token is the sole authority — `claims.jobId` scopes
|
|
4
|
+
* every runner request to exactly one job. `workflowRunId`/`workflowRunAttemptId`/`workspaceId`
|
|
5
|
+
* are carried for consumers but are NOT verified against the database here.
|
|
6
|
+
*
|
|
7
|
+
* Revocation tradeoff: `runnerSessionId` is carried in the claims but is not checked
|
|
8
|
+
* against runner-session storage, so a lease minted before its registration token is
|
|
9
|
+
* revoked stays usable until it expires (`AUTH_JOB_LEASE_TOKEN_EXPIRES_IN`, 90m).
|
|
10
|
+
* Accepted deliberately for a short-lived, job-scoped capability token; tightening
|
|
11
|
+
* this would mean a per-request DB lookup on the hot status-reporting path. See the
|
|
12
|
+
* "Security model" section in the package README for the full rationale.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createLeaseTokenAuthMethod(): AuthMethod;
|
|
15
|
+
//# sourceMappingURL=lease-token-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease-token-auth.d.ts","sourceRoot":"","sources":["../../../src/presentation/auth/lease-token-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAItD;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,IAAI,UAAU,CAOvD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AUTH_LEASED_JOB, setLeasedJobContext } from '@shipfox/api-auth-context';
|
|
2
|
+
import { verifyJobLeaseToken } from '#core/job-lease-token.js';
|
|
3
|
+
import { createBearerTokenAuthMethod } from './bearer-token-auth.js';
|
|
4
|
+
/**
|
|
5
|
+
* Trust boundary: the signed token is the sole authority — `claims.jobId` scopes
|
|
6
|
+
* every runner request to exactly one job. `workflowRunId`/`workflowRunAttemptId`/`workspaceId`
|
|
7
|
+
* are carried for consumers but are NOT verified against the database here.
|
|
8
|
+
*
|
|
9
|
+
* Revocation tradeoff: `runnerSessionId` is carried in the claims but is not checked
|
|
10
|
+
* against runner-session storage, so a lease minted before its registration token is
|
|
11
|
+
* revoked stays usable until it expires (`AUTH_JOB_LEASE_TOKEN_EXPIRES_IN`, 90m).
|
|
12
|
+
* Accepted deliberately for a short-lived, job-scoped capability token; tightening
|
|
13
|
+
* this would mean a per-request DB lookup on the hot status-reporting path. See the
|
|
14
|
+
* "Security model" section in the package README for the full rationale.
|
|
15
|
+
*/ export function createLeaseTokenAuthMethod() {
|
|
16
|
+
return createBearerTokenAuthMethod({
|
|
17
|
+
name: AUTH_LEASED_JOB,
|
|
18
|
+
verifyToken: verifyJobLeaseToken,
|
|
19
|
+
invalidTokenError: {
|
|
20
|
+
message: 'Invalid or expired job lease token',
|
|
21
|
+
code: 'unauthorized'
|
|
22
|
+
},
|
|
23
|
+
setContext: setLeasedJobContext
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=lease-token-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/auth/lease-token-auth.ts"],"sourcesContent":["import {AUTH_LEASED_JOB, setLeasedJobContext} from '@shipfox/api-auth-context';\nimport type {AuthMethod} from '@shipfox/node-fastify';\nimport {verifyJobLeaseToken} from '#core/job-lease-token.js';\nimport {createBearerTokenAuthMethod} from './bearer-token-auth.js';\n\n/**\n * Trust boundary: the signed token is the sole authority — `claims.jobId` scopes\n * every runner request to exactly one job. `workflowRunId`/`workflowRunAttemptId`/`workspaceId`\n * are carried for consumers but are NOT verified against the database here.\n *\n * Revocation tradeoff: `runnerSessionId` is carried in the claims but is not checked\n * against runner-session storage, so a lease minted before its registration token is\n * revoked stays usable until it expires (`AUTH_JOB_LEASE_TOKEN_EXPIRES_IN`, 90m).\n * Accepted deliberately for a short-lived, job-scoped capability token; tightening\n * this would mean a per-request DB lookup on the hot status-reporting path. See the\n * \"Security model\" section in the package README for the full rationale.\n */\nexport function createLeaseTokenAuthMethod(): AuthMethod {\n return createBearerTokenAuthMethod({\n name: AUTH_LEASED_JOB,\n verifyToken: verifyJobLeaseToken,\n invalidTokenError: {message: 'Invalid or expired job lease token', code: 'unauthorized'},\n setContext: setLeasedJobContext,\n });\n}\n"],"names":["AUTH_LEASED_JOB","setLeasedJobContext","verifyJobLeaseToken","createBearerTokenAuthMethod","createLeaseTokenAuthMethod","name","verifyToken","invalidTokenError","message","code","setContext"],"mappings":"AAAA,SAAQA,eAAe,EAAEC,mBAAmB,QAAO,4BAA4B;AAE/E,SAAQC,mBAAmB,QAAO,2BAA2B;AAC7D,SAAQC,2BAA2B,QAAO,yBAAyB;AAEnE;;;;;;;;;;;CAWC,GACD,OAAO,SAASC;IACd,OAAOD,4BAA4B;QACjCE,MAAML;QACNM,aAAaJ;QACbK,mBAAmB;YAACC,SAAS;YAAsCC,MAAM;QAAc;QACvFC,YAAYT;IACd;AACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import cookie from '@fastify/cookie';
|
|
2
|
+
import type { FastifyReply, FastifyRequest } from 'fastify';
|
|
3
|
+
export declare const authCookiePlugin: typeof cookie;
|
|
4
|
+
export declare function getRefreshTokenCookie(request: FastifyRequest): string | undefined;
|
|
5
|
+
export declare function setRefreshTokenCookie(reply: FastifyReply, refreshToken: string): void;
|
|
6
|
+
export declare function clearRefreshTokenCookie(reply: FastifyReply): void;
|
|
7
|
+
//# sourceMappingURL=refresh-cookie.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-cookie.d.ts","sourceRoot":"","sources":["../../../src/presentation/auth/refresh-cookie.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,KAAK,EAAC,YAAY,EAAE,cAAc,EAAC,MAAM,SAAS,CAAC;AAK1D,eAAO,MAAM,gBAAgB,eAAS,CAAC;AAMvC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAEjF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAQrF;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAOjE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import cookie from '@fastify/cookie';
|
|
2
|
+
import { config } from '#config.js';
|
|
3
|
+
const REFRESH_COOKIE_PATH = '/auth';
|
|
4
|
+
export const authCookiePlugin = cookie;
|
|
5
|
+
function refreshCookieMaxAgeSeconds() {
|
|
6
|
+
return config.AUTH_REFRESH_TOKEN_EXPIRES_IN_DAYS * 24 * 60 * 60;
|
|
7
|
+
}
|
|
8
|
+
export function getRefreshTokenCookie(request) {
|
|
9
|
+
return request.cookies[config.AUTH_REFRESH_COOKIE_NAME];
|
|
10
|
+
}
|
|
11
|
+
export function setRefreshTokenCookie(reply, refreshToken) {
|
|
12
|
+
reply.setCookie(config.AUTH_REFRESH_COOKIE_NAME, refreshToken, {
|
|
13
|
+
httpOnly: true,
|
|
14
|
+
secure: true,
|
|
15
|
+
sameSite: 'lax',
|
|
16
|
+
path: REFRESH_COOKIE_PATH,
|
|
17
|
+
maxAge: refreshCookieMaxAgeSeconds()
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export function clearRefreshTokenCookie(reply) {
|
|
21
|
+
reply.clearCookie(config.AUTH_REFRESH_COOKIE_NAME, {
|
|
22
|
+
httpOnly: true,
|
|
23
|
+
secure: true,
|
|
24
|
+
sameSite: 'lax',
|
|
25
|
+
path: REFRESH_COOKIE_PATH
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=refresh-cookie.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/auth/refresh-cookie.ts"],"sourcesContent":["import cookie from '@fastify/cookie';\nimport type {FastifyReply, FastifyRequest} from 'fastify';\nimport {config} from '#config.js';\n\nconst REFRESH_COOKIE_PATH = '/auth';\n\nexport const authCookiePlugin = cookie;\n\nfunction refreshCookieMaxAgeSeconds(): number {\n return config.AUTH_REFRESH_TOKEN_EXPIRES_IN_DAYS * 24 * 60 * 60;\n}\n\nexport function getRefreshTokenCookie(request: FastifyRequest): string | undefined {\n return request.cookies[config.AUTH_REFRESH_COOKIE_NAME];\n}\n\nexport function setRefreshTokenCookie(reply: FastifyReply, refreshToken: string): void {\n reply.setCookie(config.AUTH_REFRESH_COOKIE_NAME, refreshToken, {\n httpOnly: true,\n secure: true,\n sameSite: 'lax',\n path: REFRESH_COOKIE_PATH,\n maxAge: refreshCookieMaxAgeSeconds(),\n });\n}\n\nexport function clearRefreshTokenCookie(reply: FastifyReply): void {\n reply.clearCookie(config.AUTH_REFRESH_COOKIE_NAME, {\n httpOnly: true,\n secure: true,\n sameSite: 'lax',\n path: REFRESH_COOKIE_PATH,\n });\n}\n"],"names":["cookie","config","REFRESH_COOKIE_PATH","authCookiePlugin","refreshCookieMaxAgeSeconds","AUTH_REFRESH_TOKEN_EXPIRES_IN_DAYS","getRefreshTokenCookie","request","cookies","AUTH_REFRESH_COOKIE_NAME","setRefreshTokenCookie","reply","refreshToken","setCookie","httpOnly","secure","sameSite","path","maxAge","clearRefreshTokenCookie","clearCookie"],"mappings":"AAAA,OAAOA,YAAY,kBAAkB;AAErC,SAAQC,MAAM,QAAO,aAAa;AAElC,MAAMC,sBAAsB;AAE5B,OAAO,MAAMC,mBAAmBH,OAAO;AAEvC,SAASI;IACP,OAAOH,OAAOI,kCAAkC,GAAG,KAAK,KAAK;AAC/D;AAEA,OAAO,SAASC,sBAAsBC,OAAuB;IAC3D,OAAOA,QAAQC,OAAO,CAACP,OAAOQ,wBAAwB,CAAC;AACzD;AAEA,OAAO,SAASC,sBAAsBC,KAAmB,EAAEC,YAAoB;IAC7ED,MAAME,SAAS,CAACZ,OAAOQ,wBAAwB,EAAEG,cAAc;QAC7DE,UAAU;QACVC,QAAQ;QACRC,UAAU;QACVC,MAAMf;QACNgB,QAAQd;IACV;AACF;AAEA,OAAO,SAASe,wBAAwBR,KAAmB;IACzDA,MAAMS,WAAW,CAACnB,OAAOQ,wBAAwB,EAAE;QACjDK,UAAU;QACVC,QAAQ;QACRC,UAAU;QACVC,MAAMf;IACR;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-session-auth.d.ts","sourceRoot":"","sources":["../../../src/presentation/auth/runner-session-auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAItD,wBAAgB,6BAA6B,IAAI,UAAU,CAO1D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AUTH_RUNNER_SESSION, setRunnerSessionContext } from '@shipfox/api-auth-context';
|
|
2
|
+
import { verifyRunnerSessionToken } from '#core/runner-session-token.js';
|
|
3
|
+
import { createBearerTokenAuthMethod } from './bearer-token-auth.js';
|
|
4
|
+
export function createRunnerSessionAuthMethod() {
|
|
5
|
+
return createBearerTokenAuthMethod({
|
|
6
|
+
name: AUTH_RUNNER_SESSION,
|
|
7
|
+
verifyToken: verifyRunnerSessionToken,
|
|
8
|
+
invalidTokenError: {
|
|
9
|
+
message: 'Invalid or expired runner session token',
|
|
10
|
+
code: 'unauthorized'
|
|
11
|
+
},
|
|
12
|
+
setContext: setRunnerSessionContext
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=runner-session-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/auth/runner-session-auth.ts"],"sourcesContent":["import {AUTH_RUNNER_SESSION, setRunnerSessionContext} from '@shipfox/api-auth-context';\nimport type {AuthMethod} from '@shipfox/node-fastify';\nimport {verifyRunnerSessionToken} from '#core/runner-session-token.js';\nimport {createBearerTokenAuthMethod} from './bearer-token-auth.js';\n\nexport function createRunnerSessionAuthMethod(): AuthMethod {\n return createBearerTokenAuthMethod({\n name: AUTH_RUNNER_SESSION,\n verifyToken: verifyRunnerSessionToken,\n invalidTokenError: {message: 'Invalid or expired runner session token', code: 'unauthorized'},\n setContext: setRunnerSessionContext,\n });\n}\n"],"names":["AUTH_RUNNER_SESSION","setRunnerSessionContext","verifyRunnerSessionToken","createBearerTokenAuthMethod","createRunnerSessionAuthMethod","name","verifyToken","invalidTokenError","message","code","setContext"],"mappings":"AAAA,SAAQA,mBAAmB,EAAEC,uBAAuB,QAAO,4BAA4B;AAEvF,SAAQC,wBAAwB,QAAO,gCAAgC;AACvE,SAAQC,2BAA2B,QAAO,yBAAyB;AAEnE,OAAO,SAASC;IACd,OAAOD,4BAA4B;QACjCE,MAAML;QACNM,aAAaJ;QACbK,mBAAmB;YAACC,SAAS;YAA2CC,MAAM;QAAc;QAC5FC,YAAYT;IACd;AACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LoginResponseDto, UserDto } from '@shipfox/api-auth-dto';
|
|
2
|
+
import type { User } from '#core/entities/user.js';
|
|
3
|
+
export declare function toUserDto(user: User): UserDto;
|
|
4
|
+
export declare function toAuthSessionDto(result: {
|
|
5
|
+
token: string;
|
|
6
|
+
user: User;
|
|
7
|
+
}): LoginResponseDto;
|
|
8
|
+
//# sourceMappingURL=user.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAE,OAAO,EAAC,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAU7C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC,GAAG,gBAAgB,CAKtF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function toUserDto(user) {
|
|
2
|
+
return {
|
|
3
|
+
id: user.id,
|
|
4
|
+
email: user.email,
|
|
5
|
+
name: user.name,
|
|
6
|
+
email_verified_at: user.emailVerifiedAt ? user.emailVerifiedAt.toISOString() : null,
|
|
7
|
+
status: user.status,
|
|
8
|
+
created_at: user.createdAt.toISOString(),
|
|
9
|
+
updated_at: user.updatedAt.toISOString()
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function toAuthSessionDto(result) {
|
|
13
|
+
return {
|
|
14
|
+
token: result.token,
|
|
15
|
+
user: toUserDto(result.user)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/dto/user.ts"],"sourcesContent":["import type {LoginResponseDto, UserDto} from '@shipfox/api-auth-dto';\nimport type {User} from '#core/entities/user.js';\n\nexport function toUserDto(user: User): UserDto {\n return {\n id: user.id,\n email: user.email,\n name: user.name,\n email_verified_at: user.emailVerifiedAt ? user.emailVerifiedAt.toISOString() : null,\n status: user.status,\n created_at: user.createdAt.toISOString(),\n updated_at: user.updatedAt.toISOString(),\n };\n}\n\nexport function toAuthSessionDto(result: {token: string; user: User}): LoginResponseDto {\n return {\n token: result.token,\n user: toUserDto(result.user),\n };\n}\n"],"names":["toUserDto","user","id","email","name","email_verified_at","emailVerifiedAt","toISOString","status","created_at","createdAt","updated_at","updatedAt","toAuthSessionDto","result","token"],"mappings":"AAGA,OAAO,SAASA,UAAUC,IAAU;IAClC,OAAO;QACLC,IAAID,KAAKC,EAAE;QACXC,OAAOF,KAAKE,KAAK;QACjBC,MAAMH,KAAKG,IAAI;QACfC,mBAAmBJ,KAAKK,eAAe,GAAGL,KAAKK,eAAe,CAACC,WAAW,KAAK;QAC/EC,QAAQP,KAAKO,MAAM;QACnBC,YAAYR,KAAKS,SAAS,CAACH,WAAW;QACtCI,YAAYV,KAAKW,SAAS,CAACL,WAAW;IACxC;AACF;AAEA,OAAO,SAASM,iBAAiBC,MAAmC;IAClE,OAAO;QACLC,OAAOD,OAAOC,KAAK;QACnBd,MAAMD,UAAUc,OAAOb,IAAI;IAC7B;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-session.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/create-session.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,qBAAqB,iDA+BhC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { e2eCreateSessionBodySchema, e2eCreateSessionResponseSchema } from '@shipfox/api-auth-dto';
|
|
2
|
+
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
3
|
+
import { createSessionForUser } from '#core/auth.js';
|
|
4
|
+
import { EmailNotVerifiedError, InvalidCredentialsError, UserNotFoundError } from '#core/errors.js';
|
|
5
|
+
import { setRefreshTokenCookie } from '#presentation/auth/refresh-cookie.js';
|
|
6
|
+
import { toAuthSessionDto } from '#presentation/dto/user.js';
|
|
7
|
+
export const createE2eSessionRoute = defineRoute({
|
|
8
|
+
method: 'POST',
|
|
9
|
+
path: '/sessions',
|
|
10
|
+
description: 'Create an authenticated browser session for E2E tests.',
|
|
11
|
+
schema: {
|
|
12
|
+
body: e2eCreateSessionBodySchema,
|
|
13
|
+
response: {
|
|
14
|
+
200: e2eCreateSessionResponseSchema
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
errorHandler: (error)=>{
|
|
18
|
+
if (error instanceof UserNotFoundError) {
|
|
19
|
+
throw new ClientError('User not found', 'user-not-found', {
|
|
20
|
+
status: 404
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (error instanceof EmailNotVerifiedError) {
|
|
24
|
+
throw new ClientError('Email not verified', 'email-not-verified', {
|
|
25
|
+
status: 403
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (error instanceof InvalidCredentialsError) {
|
|
29
|
+
throw new ClientError('User is not active', 'user-inactive', {
|
|
30
|
+
status: 409
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
throw error;
|
|
34
|
+
},
|
|
35
|
+
handler: async (request, reply)=>{
|
|
36
|
+
const result = await createSessionForUser({
|
|
37
|
+
...request.body.user_id ? {
|
|
38
|
+
userId: request.body.user_id
|
|
39
|
+
} : {},
|
|
40
|
+
...request.body.email ? {
|
|
41
|
+
email: request.body.email
|
|
42
|
+
} : {}
|
|
43
|
+
});
|
|
44
|
+
setRefreshTokenCookie(reply, result.refreshToken);
|
|
45
|
+
return toAuthSessionDto(result);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=create-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/e2eRoutes/create-session.ts"],"sourcesContent":["import {e2eCreateSessionBodySchema, e2eCreateSessionResponseSchema} from '@shipfox/api-auth-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {createSessionForUser} from '#core/auth.js';\nimport {EmailNotVerifiedError, InvalidCredentialsError, UserNotFoundError} from '#core/errors.js';\nimport {setRefreshTokenCookie} from '#presentation/auth/refresh-cookie.js';\nimport {toAuthSessionDto} from '#presentation/dto/user.js';\n\nexport const createE2eSessionRoute = defineRoute({\n method: 'POST',\n path: '/sessions',\n description: 'Create an authenticated browser session for E2E tests.',\n schema: {\n body: e2eCreateSessionBodySchema,\n response: {\n 200: e2eCreateSessionResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof UserNotFoundError) {\n throw new ClientError('User not found', 'user-not-found', {status: 404});\n }\n if (error instanceof EmailNotVerifiedError) {\n throw new ClientError('Email not verified', 'email-not-verified', {status: 403});\n }\n if (error instanceof InvalidCredentialsError) {\n throw new ClientError('User is not active', 'user-inactive', {status: 409});\n }\n throw error;\n },\n handler: async (request, reply) => {\n const result = await createSessionForUser({\n ...(request.body.user_id ? {userId: request.body.user_id} : {}),\n ...(request.body.email ? {email: request.body.email} : {}),\n });\n\n setRefreshTokenCookie(reply, result.refreshToken);\n return toAuthSessionDto(result);\n },\n});\n"],"names":["e2eCreateSessionBodySchema","e2eCreateSessionResponseSchema","ClientError","defineRoute","createSessionForUser","EmailNotVerifiedError","InvalidCredentialsError","UserNotFoundError","setRefreshTokenCookie","toAuthSessionDto","createE2eSessionRoute","method","path","description","schema","body","response","errorHandler","error","status","handler","request","reply","result","user_id","userId","email","refreshToken"],"mappings":"AAAA,SAAQA,0BAA0B,EAAEC,8BAA8B,QAAO,wBAAwB;AACjG,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,oBAAoB,QAAO,gBAAgB;AACnD,SAAQC,qBAAqB,EAAEC,uBAAuB,EAAEC,iBAAiB,QAAO,kBAAkB;AAClG,SAAQC,qBAAqB,QAAO,uCAAuC;AAC3E,SAAQC,gBAAgB,QAAO,4BAA4B;AAE3D,OAAO,MAAMC,wBAAwBP,YAAY;IAC/CQ,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,MAAMf;QACNgB,UAAU;YACR,KAAKf;QACP;IACF;IACAgB,cAAc,CAACC;QACb,IAAIA,iBAAiBX,mBAAmB;YACtC,MAAM,IAAIL,YAAY,kBAAkB,kBAAkB;gBAACiB,QAAQ;YAAG;QACxE;QACA,IAAID,iBAAiBb,uBAAuB;YAC1C,MAAM,IAAIH,YAAY,sBAAsB,sBAAsB;gBAACiB,QAAQ;YAAG;QAChF;QACA,IAAID,iBAAiBZ,yBAAyB;YAC5C,MAAM,IAAIJ,YAAY,sBAAsB,iBAAiB;gBAACiB,QAAQ;YAAG;QAC3E;QACA,MAAMD;IACR;IACAE,SAAS,OAAOC,SAASC;QACvB,MAAMC,SAAS,MAAMnB,qBAAqB;YACxC,GAAIiB,QAAQN,IAAI,CAACS,OAAO,GAAG;gBAACC,QAAQJ,QAAQN,IAAI,CAACS,OAAO;YAAA,IAAI,CAAC,CAAC;YAC9D,GAAIH,QAAQN,IAAI,CAACW,KAAK,GAAG;gBAACA,OAAOL,QAAQN,IAAI,CAACW,KAAK;YAAA,IAAI,CAAC,CAAC;QAC3D;QAEAlB,sBAAsBc,OAAOC,OAAOI,YAAY;QAChD,OAAOlB,iBAAiBc;IAC1B;AACF,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-user.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/create-user.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,kBAAkB,iDA+B7B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { e2eCreateUserBodySchema, e2eCreateUserResponseSchema } from '@shipfox/api-auth-dto';
|
|
2
|
+
import { ClientError, defineRoute } from '@shipfox/node-fastify';
|
|
3
|
+
import { createUser } from '#core/auth.js';
|
|
4
|
+
import { EmailTakenError } from '#core/errors.js';
|
|
5
|
+
import { toUserDto } from '#presentation/dto/user.js';
|
|
6
|
+
export const createE2eUserRoute = defineRoute({
|
|
7
|
+
method: 'POST',
|
|
8
|
+
path: '/users',
|
|
9
|
+
description: 'Create a user for E2E tests.',
|
|
10
|
+
schema: {
|
|
11
|
+
body: e2eCreateUserBodySchema,
|
|
12
|
+
response: {
|
|
13
|
+
201: e2eCreateUserResponseSchema
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
errorHandler: (error)=>{
|
|
17
|
+
if (error instanceof EmailTakenError) {
|
|
18
|
+
throw new ClientError('Email already registered', 'email-taken', {
|
|
19
|
+
status: 409
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
},
|
|
24
|
+
handler: async (request, reply)=>{
|
|
25
|
+
const user = await createUser({
|
|
26
|
+
email: request.body.email,
|
|
27
|
+
password: request.body.password,
|
|
28
|
+
verified: request.body.verified,
|
|
29
|
+
...request.body.name ? {
|
|
30
|
+
name: request.body.name
|
|
31
|
+
} : {}
|
|
32
|
+
});
|
|
33
|
+
reply.code(201);
|
|
34
|
+
return {
|
|
35
|
+
user: toUserDto(user),
|
|
36
|
+
email: user.email,
|
|
37
|
+
password: request.body.password
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=create-user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/e2eRoutes/create-user.ts"],"sourcesContent":["import {e2eCreateUserBodySchema, e2eCreateUserResponseSchema} from '@shipfox/api-auth-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {createUser} from '#core/auth.js';\nimport {EmailTakenError} from '#core/errors.js';\nimport {toUserDto} from '#presentation/dto/user.js';\n\nexport const createE2eUserRoute = defineRoute({\n method: 'POST',\n path: '/users',\n description: 'Create a user for E2E tests.',\n schema: {\n body: e2eCreateUserBodySchema,\n response: {\n 201: e2eCreateUserResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof EmailTakenError) {\n throw new ClientError('Email already registered', 'email-taken', {status: 409});\n }\n throw error;\n },\n handler: async (request, reply) => {\n const user = await createUser({\n email: request.body.email,\n password: request.body.password,\n verified: request.body.verified,\n ...(request.body.name ? {name: request.body.name} : {}),\n });\n\n reply.code(201);\n return {\n user: toUserDto(user),\n email: user.email,\n password: request.body.password,\n };\n },\n});\n"],"names":["e2eCreateUserBodySchema","e2eCreateUserResponseSchema","ClientError","defineRoute","createUser","EmailTakenError","toUserDto","createE2eUserRoute","method","path","description","schema","body","response","errorHandler","error","status","handler","request","reply","user","email","password","verified","name","code"],"mappings":"AAAA,SAAQA,uBAAuB,EAAEC,2BAA2B,QAAO,wBAAwB;AAC3F,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,UAAU,QAAO,gBAAgB;AACzC,SAAQC,eAAe,QAAO,kBAAkB;AAChD,SAAQC,SAAS,QAAO,4BAA4B;AAEpD,OAAO,MAAMC,qBAAqBJ,YAAY;IAC5CK,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,MAAMZ;QACNa,UAAU;YACR,KAAKZ;QACP;IACF;IACAa,cAAc,CAACC;QACb,IAAIA,iBAAiBV,iBAAiB;YACpC,MAAM,IAAIH,YAAY,4BAA4B,eAAe;gBAACc,QAAQ;YAAG;QAC/E;QACA,MAAMD;IACR;IACAE,SAAS,OAAOC,SAASC;QACvB,MAAMC,OAAO,MAAMhB,WAAW;YAC5BiB,OAAOH,QAAQN,IAAI,CAACS,KAAK;YACzBC,UAAUJ,QAAQN,IAAI,CAACU,QAAQ;YAC/BC,UAAUL,QAAQN,IAAI,CAACW,QAAQ;YAC/B,GAAIL,QAAQN,IAAI,CAACY,IAAI,GAAG;gBAACA,MAAMN,QAAQN,IAAI,CAACY,IAAI;YAAA,IAAI,CAAC,CAAC;QACxD;QAEAL,MAAMM,IAAI,CAAC;QACX,OAAO;YACLL,MAAMd,UAAUc;YAChBC,OAAOD,KAAKC,KAAK;YACjBC,UAAUJ,QAAQN,IAAI,CAACU,QAAQ;QACjC;IACF;AACF,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAItD,eAAO,MAAM,aAAa,EAAE,UAI3B,CAAC"}
|