@shipfox/api-auth 12.2.0 → 15.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 (43) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +29 -0
  3. package/README.md +15 -2
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +5 -1
  6. package/dist/config.js.map +1 -1
  7. package/dist/core/auth.d.ts.map +1 -1
  8. package/dist/core/auth.js +1 -1
  9. package/dist/core/auth.js.map +1 -1
  10. package/dist/core/errors.d.ts +3 -1
  11. package/dist/core/errors.d.ts.map +1 -1
  12. package/dist/core/errors.js +2 -2
  13. package/dist/core/errors.js.map +1 -1
  14. package/dist/core/ports.d.ts +3 -0
  15. package/dist/core/ports.d.ts.map +1 -1
  16. package/dist/core/ports.js +1 -1
  17. package/dist/core/ports.js.map +1 -1
  18. package/dist/core/signup-policy.d.ts.map +1 -1
  19. package/dist/core/signup-policy.js +2 -1
  20. package/dist/core/signup-policy.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/presentation/routes/registration/signup.d.ts +1 -1
  25. package/dist/presentation/routes/registration/signup.d.ts.map +1 -1
  26. package/dist/presentation/routes/registration/signup.js +6 -3
  27. package/dist/presentation/routes/registration/signup.js.map +1 -1
  28. package/dist/tsconfig.test.tsbuildinfo +1 -1
  29. package/package.json +12 -12
  30. package/src/config.test.ts +12 -0
  31. package/src/config.ts +11 -1
  32. package/src/core/auth-default-signup-policy.test.ts +2 -0
  33. package/src/core/auth.test.ts +1 -0
  34. package/src/core/auth.ts +4 -1
  35. package/src/core/errors.ts +6 -1
  36. package/src/core/ports.ts +6 -1
  37. package/src/core/signup-policy.test.ts +10 -2
  38. package/src/core/signup-policy.ts +1 -0
  39. package/src/index.test.ts +1 -0
  40. package/src/index.ts +1 -1
  41. package/src/presentation/routes/registration/signup.test.ts +21 -0
  42. package/src/presentation/routes/registration/signup.ts +3 -5
  43. package/tsconfig.build.tsbuildinfo +1 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n AUTH_PASSWORD_RESET_SEND_REQUESTED,\n type AuthEventMap,\n authEventSchemas,\n} from '@shipfox/api-auth-dto';\nimport {administrationActionEventSchemas} from '@shipfox/api-common-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {subscriberFactory} from '@shipfox/node-module';\nimport {config} from '#config.js';\nimport type {SignupPolicy} from '#core/ports.js';\nimport {createEnvironmentSignupPolicy} from '#core/signup-policy.js';\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 {createAuthE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createAuthInterModulePresentation} from '#presentation/inter-module.js';\nimport {\n administrationBootstrapRoutes,\n administrationRoutes,\n administrationUserRoutes,\n} from '#presentation/routes/administration.js';\nimport {buildAuthRoutes} from '#presentation/routes/index.js';\nimport {onPasswordResetSendRequested} from '#presentation/subscribers/index.js';\nimport {passwordLoginMethods} from './login-methods.js';\n\nconst authPublisherEventSchemas = {...authEventSchemas, ...administrationActionEventSchemas};\n\nexport type {AdminRole, JobLeaseTokenClaims, RunnerSessionTokenClaims} from '@shipfox/api-auth-dto';\nexport {\n ADMIN_ROLES,\n getCurrentAdminRole,\n hasMinimumAdminRole,\n highestAdminRole,\n requireAdminRole,\n revokeAdminGrant,\n} from '#core/admin-role.js';\nexport {\n bootstrapFirstAdminOwner,\n grantAdministratorRole,\n reactivateAdministratorUser,\n revokeAdministratorGrant,\n revokeAdministratorUserSessions,\n suspendAdministratorUser,\n} from '#core/administration.js';\nexport type {\n CreateSessionForUserError,\n CreateSessionForUserParams,\n CreateSessionForUserResult,\n ProvisionUserParams,\n} from '#core/auth.js';\nexport {createSessionForUser, provisionUser} from '#core/auth.js';\nexport type {EmailOwner, FindUserByEmailParams} from '#core/email-owner.js';\nexport {findUserByEmail} from '#core/email-owner.js';\nexport type {AdminGrant} from '#core/entities/admin-grant.js';\nexport type {User, UserStatus} from '#core/entities/user.js';\nexport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n AdminRoleRequiredError,\n AuthDependencyUnavailableError,\n EmailNotVerifiedError,\n InvalidAdminBootstrapTokenError,\n InvalidCredentialsError,\n LastAdminOwnerError,\n SignupNotAllowedError,\n UserNotFoundError,\n} from '#core/errors.js';\nexport {\n issueJobLeaseToken,\n jobLeaseParamsFrom,\n verifyJobLeaseToken,\n} from '#core/job-lease-token.js';\nexport type {SignupPolicy} from '#core/ports.js';\nexport {\n issueRunnerSessionToken,\n verifyRunnerSessionToken,\n} from '#core/runner-session-token.js';\nexport {\n createEnvironmentSignupPolicy,\n DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE,\n} from '#core/signup-policy.js';\nexport {\n type AuthenticatedSessionContext,\n createJwtAuthMethod,\n getAuthenticatedSessionContext,\n type RefreshSessionId,\n type UserId,\n} 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 interface CreateAuthModuleOptions {\n workspaces: import('@shipfox/api-workspaces-dto/inter-module').WorkspacesInterModuleClient;\n signupPolicy?: SignupPolicy;\n}\n\nexport function createAuthModule({\n workspaces,\n signupPolicy = createEnvironmentSignupPolicy(),\n}: CreateAuthModuleOptions): ShipfoxModule {\n return {\n name: 'auth',\n database: {db, migrationsPath, databaseNamespace: 'auth'},\n auth: [createJwtAuthMethod(), createLeaseTokenAuthMethod(), createRunnerSessionAuthMethod()],\n loginMethods: passwordLoginMethods(config.AUTH_PASSWORD_ENABLED),\n routes: [\n buildAuthRoutes(config.AUTH_PASSWORD_ENABLED, workspaces, signupPolicy),\n administrationBootstrapRoutes,\n administrationRoutes,\n administrationUserRoutes,\n ],\n e2eRoutes: [createAuthE2eRoutes(workspaces)],\n publishers: [{name: 'auth', table: authOutbox, db, eventSchemas: authPublisherEventSchemas}],\n subscribers: [subscriber(AUTH_PASSWORD_RESET_SEND_REQUESTED, onPasswordResetSendRequested)],\n interModulePresentations: [createAuthInterModulePresentation()],\n };\n}\n"],"names":["AUTH_PASSWORD_RESET_SEND_REQUESTED","authEventSchemas","administrationActionEventSchemas","subscriberFactory","config","createEnvironmentSignupPolicy","db","migrationsPath","authOutbox","createJwtAuthMethod","createLeaseTokenAuthMethod","createRunnerSessionAuthMethod","createAuthE2eRoutes","createAuthInterModulePresentation","administrationBootstrapRoutes","administrationRoutes","administrationUserRoutes","buildAuthRoutes","onPasswordResetSendRequested","passwordLoginMethods","authPublisherEventSchemas","ADMIN_ROLES","getCurrentAdminRole","hasMinimumAdminRole","highestAdminRole","requireAdminRole","revokeAdminGrant","bootstrapFirstAdminOwner","grantAdministratorRole","reactivateAdministratorUser","revokeAdministratorGrant","revokeAdministratorUserSessions","suspendAdministratorUser","createSessionForUser","provisionUser","findUserByEmail","AdminBootstrapClosedError","AdminGrantAlreadyExistsError","AdminGrantNotFoundError","AdminIdempotencyKeyReuseError","AdminRoleRequiredError","AuthDependencyUnavailableError","EmailNotVerifiedError","InvalidAdminBootstrapTokenError","InvalidCredentialsError","LastAdminOwnerError","SignupNotAllowedError","UserNotFoundError","issueJobLeaseToken","jobLeaseParamsFrom","verifyJobLeaseToken","issueRunnerSessionToken","verifyRunnerSessionToken","DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE","getAuthenticatedSessionContext","authCookiePlugin","clearRefreshTokenCookie","getRefreshTokenCookie","setRefreshTokenCookie","subscriber","createAuthModule","workspaces","signupPolicy","name","database","databaseNamespace","auth","loginMethods","AUTH_PASSWORD_ENABLED","routes","e2eRoutes","publishers","table","eventSchemas","subscribers","interModulePresentations"],"mappings":"AAAA,SACEA,kCAAkC,EAElCC,gBAAgB,QACX,wBAAwB;AAC/B,SAAQC,gCAAgC,QAAO,0BAA0B;AAEzE,SAAQC,iBAAiB,QAAO,uBAAuB;AACvD,SAAQC,MAAM,QAAO,aAAa;AAElC,SAAQC,6BAA6B,QAAO,yBAAyB;AACrE,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,mBAAmB,QAAO,mCAAmC;AACrE,SAAQC,iCAAiC,QAAO,gCAAgC;AAChF,SACEC,6BAA6B,EAC7BC,oBAAoB,EACpBC,wBAAwB,QACnB,yCAAyC;AAChD,SAAQC,eAAe,QAAO,gCAAgC;AAC9D,SAAQC,4BAA4B,QAAO,qCAAqC;AAChF,SAAQC,oBAAoB,QAAO,qBAAqB;AAExD,MAAMC,4BAA4B;IAAC,GAAGnB,gBAAgB;IAAE,GAAGC,gCAAgC;AAAA;AAG3F,SACEmB,WAAW,EACXC,mBAAmB,EACnBC,mBAAmB,EACnBC,gBAAgB,EAChBC,gBAAgB,EAChBC,gBAAgB,QACX,sBAAsB;AAC7B,SACEC,wBAAwB,EACxBC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wBAAwB,EACxBC,+BAA+B,EAC/BC,wBAAwB,QACnB,0BAA0B;AAOjC,SAAQC,oBAAoB,EAAEC,aAAa,QAAO,gBAAgB;AAElE,SAAQC,eAAe,QAAO,uBAAuB;AAGrD,SACEC,yBAAyB,EACzBC,4BAA4B,EAC5BC,uBAAuB,EACvBC,6BAA6B,EAC7BC,sBAAsB,EACtBC,8BAA8B,EAC9BC,qBAAqB,EACrBC,+BAA+B,EAC/BC,uBAAuB,EACvBC,mBAAmB,EACnBC,qBAAqB,EACrBC,iBAAiB,QACZ,kBAAkB;AACzB,SACEC,kBAAkB,EAClBC,kBAAkB,EAClBC,mBAAmB,QACd,2BAA2B;AAElC,SACEC,uBAAuB,EACvBC,wBAAwB,QACnB,gCAAgC;AACvC,SACE/C,6BAA6B,EAC7BgD,kCAAkC,QAC7B,yBAAyB;AAChC,SAEE5C,mBAAmB,EACnB6C,8BAA8B,QAGzB,iCAAiC;AACxC,SAAQ5C,0BAA0B,QAAO,yCAAyC;AAClF,SACE6C,gBAAgB,EAChBC,uBAAuB,EACvBC,qBAAqB,EACrBC,qBAAqB,QAChB,uCAAuC;AAC9C,SAAQ/C,6BAA6B,QAAO,4CAA4C;AAExF,MAAMgD,aAAaxD;AAOnB,OAAO,SAASyD,iBAAiB,EAC/BC,UAAU,EACVC,eAAezD,+BAA+B,EACtB;IACxB,OAAO;QACL0D,MAAM;QACNC,UAAU;YAAC1D;YAAIC;YAAgB0D,mBAAmB;QAAM;QACxDC,MAAM;YAACzD;YAAuBC;YAA8BC;SAAgC;QAC5FwD,cAAchD,qBAAqBf,OAAOgE,qBAAqB;QAC/DC,QAAQ;YACNpD,gBAAgBb,OAAOgE,qBAAqB,EAAEP,YAAYC;YAC1DhD;YACAC;YACAC;SACD;QACDsD,WAAW;YAAC1D,oBAAoBiD;SAAY;QAC5CU,YAAY;YAAC;gBAACR,MAAM;gBAAQS,OAAOhE;gBAAYF;gBAAImE,cAAcrD;YAAyB;SAAE;QAC5FsD,aAAa;YAACf,WAAW3D,oCAAoCkB;SAA8B;QAC3FyD,0BAA0B;YAAC9D;SAAoC;IACjE;AACF"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n AUTH_PASSWORD_RESET_SEND_REQUESTED,\n type AuthEventMap,\n authEventSchemas,\n} from '@shipfox/api-auth-dto';\nimport {administrationActionEventSchemas} from '@shipfox/api-common-dto';\nimport type {ShipfoxModule} from '@shipfox/node-module';\nimport {subscriberFactory} from '@shipfox/node-module';\nimport {config} from '#config.js';\nimport type {SignupPolicy} from '#core/ports.js';\nimport {createEnvironmentSignupPolicy} from '#core/signup-policy.js';\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 {createAuthE2eRoutes} from '#presentation/e2eRoutes/index.js';\nimport {createAuthInterModulePresentation} from '#presentation/inter-module.js';\nimport {\n administrationBootstrapRoutes,\n administrationRoutes,\n administrationUserRoutes,\n} from '#presentation/routes/administration.js';\nimport {buildAuthRoutes} from '#presentation/routes/index.js';\nimport {onPasswordResetSendRequested} from '#presentation/subscribers/index.js';\nimport {passwordLoginMethods} from './login-methods.js';\n\nconst authPublisherEventSchemas = {...authEventSchemas, ...administrationActionEventSchemas};\n\nexport type {AdminRole, JobLeaseTokenClaims, RunnerSessionTokenClaims} from '@shipfox/api-auth-dto';\nexport {\n ADMIN_ROLES,\n getCurrentAdminRole,\n hasMinimumAdminRole,\n highestAdminRole,\n requireAdminRole,\n revokeAdminGrant,\n} from '#core/admin-role.js';\nexport {\n bootstrapFirstAdminOwner,\n grantAdministratorRole,\n reactivateAdministratorUser,\n revokeAdministratorGrant,\n revokeAdministratorUserSessions,\n suspendAdministratorUser,\n} from '#core/administration.js';\nexport type {\n CreateSessionForUserError,\n CreateSessionForUserParams,\n CreateSessionForUserResult,\n ProvisionUserParams,\n} from '#core/auth.js';\nexport {createSessionForUser, provisionUser} from '#core/auth.js';\nexport type {EmailOwner, FindUserByEmailParams} from '#core/email-owner.js';\nexport {findUserByEmail} from '#core/email-owner.js';\nexport type {AdminGrant} from '#core/entities/admin-grant.js';\nexport type {User, UserStatus} from '#core/entities/user.js';\nexport {\n AdminBootstrapClosedError,\n AdminGrantAlreadyExistsError,\n AdminGrantNotFoundError,\n AdminIdempotencyKeyReuseError,\n AdminRoleRequiredError,\n AuthDependencyUnavailableError,\n EmailNotVerifiedError,\n InvalidAdminBootstrapTokenError,\n InvalidCredentialsError,\n LastAdminOwnerError,\n SignupNotAllowedError,\n UserNotFoundError,\n} from '#core/errors.js';\nexport {\n issueJobLeaseToken,\n jobLeaseParamsFrom,\n verifyJobLeaseToken,\n} from '#core/job-lease-token.js';\nexport type {SignupDenialMessageFormat, SignupPolicy} from '#core/ports.js';\nexport {\n issueRunnerSessionToken,\n verifyRunnerSessionToken,\n} from '#core/runner-session-token.js';\nexport {\n createEnvironmentSignupPolicy,\n DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE,\n} from '#core/signup-policy.js';\nexport {\n type AuthenticatedSessionContext,\n createJwtAuthMethod,\n getAuthenticatedSessionContext,\n type RefreshSessionId,\n type UserId,\n} 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 interface CreateAuthModuleOptions {\n workspaces: import('@shipfox/api-workspaces-dto/inter-module').WorkspacesInterModuleClient;\n signupPolicy?: SignupPolicy;\n}\n\nexport function createAuthModule({\n workspaces,\n signupPolicy = createEnvironmentSignupPolicy(),\n}: CreateAuthModuleOptions): ShipfoxModule {\n return {\n name: 'auth',\n database: {db, migrationsPath, databaseNamespace: 'auth'},\n auth: [createJwtAuthMethod(), createLeaseTokenAuthMethod(), createRunnerSessionAuthMethod()],\n loginMethods: passwordLoginMethods(config.AUTH_PASSWORD_ENABLED),\n routes: [\n buildAuthRoutes(config.AUTH_PASSWORD_ENABLED, workspaces, signupPolicy),\n administrationBootstrapRoutes,\n administrationRoutes,\n administrationUserRoutes,\n ],\n e2eRoutes: [createAuthE2eRoutes(workspaces)],\n publishers: [{name: 'auth', table: authOutbox, db, eventSchemas: authPublisherEventSchemas}],\n subscribers: [subscriber(AUTH_PASSWORD_RESET_SEND_REQUESTED, onPasswordResetSendRequested)],\n interModulePresentations: [createAuthInterModulePresentation()],\n };\n}\n"],"names":["AUTH_PASSWORD_RESET_SEND_REQUESTED","authEventSchemas","administrationActionEventSchemas","subscriberFactory","config","createEnvironmentSignupPolicy","db","migrationsPath","authOutbox","createJwtAuthMethod","createLeaseTokenAuthMethod","createRunnerSessionAuthMethod","createAuthE2eRoutes","createAuthInterModulePresentation","administrationBootstrapRoutes","administrationRoutes","administrationUserRoutes","buildAuthRoutes","onPasswordResetSendRequested","passwordLoginMethods","authPublisherEventSchemas","ADMIN_ROLES","getCurrentAdminRole","hasMinimumAdminRole","highestAdminRole","requireAdminRole","revokeAdminGrant","bootstrapFirstAdminOwner","grantAdministratorRole","reactivateAdministratorUser","revokeAdministratorGrant","revokeAdministratorUserSessions","suspendAdministratorUser","createSessionForUser","provisionUser","findUserByEmail","AdminBootstrapClosedError","AdminGrantAlreadyExistsError","AdminGrantNotFoundError","AdminIdempotencyKeyReuseError","AdminRoleRequiredError","AuthDependencyUnavailableError","EmailNotVerifiedError","InvalidAdminBootstrapTokenError","InvalidCredentialsError","LastAdminOwnerError","SignupNotAllowedError","UserNotFoundError","issueJobLeaseToken","jobLeaseParamsFrom","verifyJobLeaseToken","issueRunnerSessionToken","verifyRunnerSessionToken","DEFAULT_SIGNUP_NOT_ALLOWED_MESSAGE","getAuthenticatedSessionContext","authCookiePlugin","clearRefreshTokenCookie","getRefreshTokenCookie","setRefreshTokenCookie","subscriber","createAuthModule","workspaces","signupPolicy","name","database","databaseNamespace","auth","loginMethods","AUTH_PASSWORD_ENABLED","routes","e2eRoutes","publishers","table","eventSchemas","subscribers","interModulePresentations"],"mappings":"AAAA,SACEA,kCAAkC,EAElCC,gBAAgB,QACX,wBAAwB;AAC/B,SAAQC,gCAAgC,QAAO,0BAA0B;AAEzE,SAAQC,iBAAiB,QAAO,uBAAuB;AACvD,SAAQC,MAAM,QAAO,aAAa;AAElC,SAAQC,6BAA6B,QAAO,yBAAyB;AACrE,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,mBAAmB,QAAO,mCAAmC;AACrE,SAAQC,iCAAiC,QAAO,gCAAgC;AAChF,SACEC,6BAA6B,EAC7BC,oBAAoB,EACpBC,wBAAwB,QACnB,yCAAyC;AAChD,SAAQC,eAAe,QAAO,gCAAgC;AAC9D,SAAQC,4BAA4B,QAAO,qCAAqC;AAChF,SAAQC,oBAAoB,QAAO,qBAAqB;AAExD,MAAMC,4BAA4B;IAAC,GAAGnB,gBAAgB;IAAE,GAAGC,gCAAgC;AAAA;AAG3F,SACEmB,WAAW,EACXC,mBAAmB,EACnBC,mBAAmB,EACnBC,gBAAgB,EAChBC,gBAAgB,EAChBC,gBAAgB,QACX,sBAAsB;AAC7B,SACEC,wBAAwB,EACxBC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wBAAwB,EACxBC,+BAA+B,EAC/BC,wBAAwB,QACnB,0BAA0B;AAOjC,SAAQC,oBAAoB,EAAEC,aAAa,QAAO,gBAAgB;AAElE,SAAQC,eAAe,QAAO,uBAAuB;AAGrD,SACEC,yBAAyB,EACzBC,4BAA4B,EAC5BC,uBAAuB,EACvBC,6BAA6B,EAC7BC,sBAAsB,EACtBC,8BAA8B,EAC9BC,qBAAqB,EACrBC,+BAA+B,EAC/BC,uBAAuB,EACvBC,mBAAmB,EACnBC,qBAAqB,EACrBC,iBAAiB,QACZ,kBAAkB;AACzB,SACEC,kBAAkB,EAClBC,kBAAkB,EAClBC,mBAAmB,QACd,2BAA2B;AAElC,SACEC,uBAAuB,EACvBC,wBAAwB,QACnB,gCAAgC;AACvC,SACE/C,6BAA6B,EAC7BgD,kCAAkC,QAC7B,yBAAyB;AAChC,SAEE5C,mBAAmB,EACnB6C,8BAA8B,QAGzB,iCAAiC;AACxC,SAAQ5C,0BAA0B,QAAO,yCAAyC;AAClF,SACE6C,gBAAgB,EAChBC,uBAAuB,EACvBC,qBAAqB,EACrBC,qBAAqB,QAChB,uCAAuC;AAC9C,SAAQ/C,6BAA6B,QAAO,4CAA4C;AAExF,MAAMgD,aAAaxD;AAOnB,OAAO,SAASyD,iBAAiB,EAC/BC,UAAU,EACVC,eAAezD,+BAA+B,EACtB;IACxB,OAAO;QACL0D,MAAM;QACNC,UAAU;YAAC1D;YAAIC;YAAgB0D,mBAAmB;QAAM;QACxDC,MAAM;YAACzD;YAAuBC;YAA8BC;SAAgC;QAC5FwD,cAAchD,qBAAqBf,OAAOgE,qBAAqB;QAC/DC,QAAQ;YACNpD,gBAAgBb,OAAOgE,qBAAqB,EAAEP,YAAYC;YAC1DhD;YACAC;YACAC;SACD;QACDsD,WAAW;YAAC1D,oBAAoBiD;SAAY;QAC5CU,YAAY;YAAC;gBAACR,MAAM;gBAAQS,OAAOhE;gBAAYF;gBAAImE,cAAcrD;YAAyB;SAAE;QAC5FsD,aAAa;YAACf,WAAW3D,oCAAoCkB;SAA8B;QAC3FyD,0BAA0B;YAAC9D;SAAoC;IACjE;AACF"}
@@ -1,4 +1,4 @@
1
1
  import type { WorkspacesInterModuleClient } from '@shipfox/api-workspaces-dto/inter-module';
2
- import type { SignupPolicy } from '#core/ports.js';
2
+ import { type SignupPolicy } from '#core/ports.js';
3
3
  export declare function createSignupRoute(workspaces: WorkspacesInterModuleClient, signupPolicy?: SignupPolicy): import("@shipfox/node-fastify").RouteDefinition;
4
4
  //# sourceMappingURL=signup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signup.d.ts","sourceRoot":"","sources":["../../../../src/presentation/routes/registration/signup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,0CAA0C,CAAC;AAW1F,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAMjD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,2BAA2B,EACvC,YAAY,CAAC,EAAE,YAAY,mDAkG5B"}
1
+ {"version":3,"file":"signup.d.ts","sourceRoot":"","sources":["../../../../src/presentation/routes/registration/signup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,0CAA0C,CAAC;AAW1F,OAAO,EAAmC,KAAK,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAInF,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,2BAA2B,EACvC,YAAY,CAAC,EAAE,YAAY,mDAkG5B"}
@@ -3,9 +3,9 @@ import { EmailChallengeError } from '@shipfox/api-email-challenges';
3
3
  import { ClientError, defineRoute } from '@shipfox/node-fastify';
4
4
  import { signup, signupWithInvitation } from '#core/auth.js';
5
5
  import { EmailTakenError, InvitationEmailMismatchError, SignupNotAllowedError, TokenAlreadyUsedError, TokenExpiredError, TokenInvalidError } from '#core/errors.js';
6
+ import { SIGNUP_DENIAL_MESSAGE_MAX_LENGTH } from '#core/ports.js';
6
7
  import { setRefreshTokenCookie } from '#presentation/auth/refresh-cookie.js';
7
8
  import { toUserDto } from '#presentation/dto/user.js';
8
- const SIGNUP_NOT_ALLOWED_MESSAGE_MAX_LENGTH = 500;
9
9
  export function createSignupRoute(workspaces, signupPolicy) {
10
10
  return defineRoute({
11
11
  method: 'POST',
@@ -34,11 +34,14 @@ export function createSignupRoute(workspaces, signupPolicy) {
34
34
  });
35
35
  }
36
36
  if (error instanceof SignupNotAllowedError) {
37
- const message = error.message.slice(0, SIGNUP_NOT_ALLOWED_MESSAGE_MAX_LENGTH);
37
+ const message = error.message.slice(0, SIGNUP_DENIAL_MESSAGE_MAX_LENGTH);
38
38
  throw new ClientError(message, 'signup-not-allowed', {
39
39
  status: 403,
40
40
  details: {
41
- message
41
+ message,
42
+ ...error.format ? {
43
+ format: error.format
44
+ } : {}
42
45
  }
43
46
  });
44
47
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/presentation/routes/registration/signup.ts"],"sourcesContent":["import {signupBodySchema, signupResponseSchema} from '@shipfox/api-auth-dto';\nimport {EmailChallengeError} from '@shipfox/api-email-challenges';\nimport type {WorkspacesInterModuleClient} from '@shipfox/api-workspaces-dto/inter-module';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {signup, signupWithInvitation} from '#core/auth.js';\nimport {\n EmailTakenError,\n InvitationEmailMismatchError,\n SignupNotAllowedError,\n TokenAlreadyUsedError,\n TokenExpiredError,\n TokenInvalidError,\n} from '#core/errors.js';\nimport type {SignupPolicy} from '#core/ports.js';\nimport {setRefreshTokenCookie} from '#presentation/auth/refresh-cookie.js';\nimport {toUserDto} from '#presentation/dto/user.js';\n\nconst SIGNUP_NOT_ALLOWED_MESSAGE_MAX_LENGTH = 500;\n\nexport function createSignupRoute(\n workspaces: WorkspacesInterModuleClient,\n signupPolicy?: SignupPolicy,\n) {\n return defineRoute({\n method: 'POST',\n path: '/signup',\n description:\n 'Create a user account. Sends a verification email unless an invitation token is supplied.',\n schema: {\n body: signupBodySchema,\n response: {\n 201: signupResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof EmailChallengeError) {\n throw new ClientError(error.message, `email-challenge-${error.code}`, {\n status: error.code === 'limited' ? 429 : 400,\n ...(error.retryAt ? {details: {retry_at: error.retryAt.toISOString()}} : {}),\n });\n }\n if (error instanceof EmailTakenError) {\n throw new ClientError('Email already registered', 'email-taken', {status: 409});\n }\n if (error instanceof SignupNotAllowedError) {\n const message = error.message.slice(0, SIGNUP_NOT_ALLOWED_MESSAGE_MAX_LENGTH);\n throw new ClientError(message, 'signup-not-allowed', {\n status: 403,\n details: {message},\n });\n }\n if (error instanceof TokenInvalidError) {\n throw new ClientError('Invitation token is invalid', 'invitation-token-invalid', {\n status: 410,\n });\n }\n if (error instanceof TokenAlreadyUsedError) {\n throw new ClientError('Invitation has already been accepted', 'invitation-token-used', {\n status: 410,\n });\n }\n if (error instanceof TokenExpiredError) {\n throw new ClientError('Invitation has expired', 'invitation-token-expired', {\n status: 410,\n });\n }\n if (error instanceof InvitationEmailMismatchError) {\n throw new ClientError(\n 'Signup email does not match the invitation',\n 'invitation-email-mismatch',\n {status: 403},\n );\n }\n throw error;\n },\n handler: async (request, reply) => {\n const {email, password, name, invitation_token} = request.body;\n\n if (invitation_token === undefined) {\n const result = await signup({\n email,\n password,\n name,\n sourceIp: request.ip,\n signupPolicy,\n });\n reply.code(201);\n return {\n user: toUserDto(result),\n email_challenge: {\n id: result.emailChallenge.id,\n next_resend_available_at: result.emailChallenge.nextResendAvailableAt.toISOString(),\n },\n };\n }\n\n const result = await signupWithInvitation({\n email,\n password,\n name,\n invitationToken: invitation_token,\n workspaces,\n });\n setRefreshTokenCookie(reply, result.refreshToken);\n reply.code(201);\n return {\n user: toUserDto(result.user),\n token: result.token,\n membership: result.membership\n ? {\n id: result.membership.id,\n user_id: result.membership.userId,\n workspace_id: result.membership.workspaceId,\n }\n : null,\n ...(result.acceptError ? {accept_error: result.acceptError} : {}),\n };\n },\n });\n}\n"],"names":["signupBodySchema","signupResponseSchema","EmailChallengeError","ClientError","defineRoute","signup","signupWithInvitation","EmailTakenError","InvitationEmailMismatchError","SignupNotAllowedError","TokenAlreadyUsedError","TokenExpiredError","TokenInvalidError","setRefreshTokenCookie","toUserDto","SIGNUP_NOT_ALLOWED_MESSAGE_MAX_LENGTH","createSignupRoute","workspaces","signupPolicy","method","path","description","schema","body","response","errorHandler","error","message","code","status","retryAt","details","retry_at","toISOString","slice","handler","request","reply","email","password","name","invitation_token","undefined","result","sourceIp","ip","user","email_challenge","id","emailChallenge","next_resend_available_at","nextResendAvailableAt","invitationToken","refreshToken","token","membership","user_id","userId","workspace_id","workspaceId","acceptError","accept_error"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/presentation/routes/registration/signup.ts"],"sourcesContent":["import {signupBodySchema, signupResponseSchema} from '@shipfox/api-auth-dto';\nimport {EmailChallengeError} from '@shipfox/api-email-challenges';\nimport type {WorkspacesInterModuleClient} from '@shipfox/api-workspaces-dto/inter-module';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {signup, signupWithInvitation} from '#core/auth.js';\nimport {\n EmailTakenError,\n InvitationEmailMismatchError,\n SignupNotAllowedError,\n TokenAlreadyUsedError,\n TokenExpiredError,\n TokenInvalidError,\n} from '#core/errors.js';\nimport {SIGNUP_DENIAL_MESSAGE_MAX_LENGTH, type SignupPolicy} from '#core/ports.js';\nimport {setRefreshTokenCookie} from '#presentation/auth/refresh-cookie.js';\nimport {toUserDto} from '#presentation/dto/user.js';\n\nexport function createSignupRoute(\n workspaces: WorkspacesInterModuleClient,\n signupPolicy?: SignupPolicy,\n) {\n return defineRoute({\n method: 'POST',\n path: '/signup',\n description:\n 'Create a user account. Sends a verification email unless an invitation token is supplied.',\n schema: {\n body: signupBodySchema,\n response: {\n 201: signupResponseSchema,\n },\n },\n errorHandler: (error) => {\n if (error instanceof EmailChallengeError) {\n throw new ClientError(error.message, `email-challenge-${error.code}`, {\n status: error.code === 'limited' ? 429 : 400,\n ...(error.retryAt ? {details: {retry_at: error.retryAt.toISOString()}} : {}),\n });\n }\n if (error instanceof EmailTakenError) {\n throw new ClientError('Email already registered', 'email-taken', {status: 409});\n }\n if (error instanceof SignupNotAllowedError) {\n const message = error.message.slice(0, SIGNUP_DENIAL_MESSAGE_MAX_LENGTH);\n throw new ClientError(message, 'signup-not-allowed', {\n status: 403,\n details: {message, ...(error.format ? {format: error.format} : {})},\n });\n }\n if (error instanceof TokenInvalidError) {\n throw new ClientError('Invitation token is invalid', 'invitation-token-invalid', {\n status: 410,\n });\n }\n if (error instanceof TokenAlreadyUsedError) {\n throw new ClientError('Invitation has already been accepted', 'invitation-token-used', {\n status: 410,\n });\n }\n if (error instanceof TokenExpiredError) {\n throw new ClientError('Invitation has expired', 'invitation-token-expired', {\n status: 410,\n });\n }\n if (error instanceof InvitationEmailMismatchError) {\n throw new ClientError(\n 'Signup email does not match the invitation',\n 'invitation-email-mismatch',\n {status: 403},\n );\n }\n throw error;\n },\n handler: async (request, reply) => {\n const {email, password, name, invitation_token} = request.body;\n\n if (invitation_token === undefined) {\n const result = await signup({\n email,\n password,\n name,\n sourceIp: request.ip,\n signupPolicy,\n });\n reply.code(201);\n return {\n user: toUserDto(result),\n email_challenge: {\n id: result.emailChallenge.id,\n next_resend_available_at: result.emailChallenge.nextResendAvailableAt.toISOString(),\n },\n };\n }\n\n const result = await signupWithInvitation({\n email,\n password,\n name,\n invitationToken: invitation_token,\n workspaces,\n });\n setRefreshTokenCookie(reply, result.refreshToken);\n reply.code(201);\n return {\n user: toUserDto(result.user),\n token: result.token,\n membership: result.membership\n ? {\n id: result.membership.id,\n user_id: result.membership.userId,\n workspace_id: result.membership.workspaceId,\n }\n : null,\n ...(result.acceptError ? {accept_error: result.acceptError} : {}),\n };\n },\n });\n}\n"],"names":["signupBodySchema","signupResponseSchema","EmailChallengeError","ClientError","defineRoute","signup","signupWithInvitation","EmailTakenError","InvitationEmailMismatchError","SignupNotAllowedError","TokenAlreadyUsedError","TokenExpiredError","TokenInvalidError","SIGNUP_DENIAL_MESSAGE_MAX_LENGTH","setRefreshTokenCookie","toUserDto","createSignupRoute","workspaces","signupPolicy","method","path","description","schema","body","response","errorHandler","error","message","code","status","retryAt","details","retry_at","toISOString","slice","format","handler","request","reply","email","password","name","invitation_token","undefined","result","sourceIp","ip","user","email_challenge","id","emailChallenge","next_resend_available_at","nextResendAvailableAt","invitationToken","refreshToken","token","membership","user_id","userId","workspace_id","workspaceId","acceptError","accept_error"],"mappings":"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"}