@warlock.js/auth 5.30.0 → 5.32.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/CHANGELOG.md +18 -1
- package/esm/commands/auth-cleanup-command.d.mts +1 -2
- package/esm/commands/auth-cleanup-command.d.mts.map +1 -1
- package/esm/commands/auth-purge-never-expiring-command.d.mts +1 -2
- package/esm/commands/auth-purge-never-expiring-command.d.mts.map +1 -1
- package/esm/commands/auth-purge-never-expiring-command.mjs.map +1 -1
- package/esm/commands/jwt-secret-generator-command.d.mts +1 -2
- package/esm/commands/jwt-secret-generator-command.d.mts.map +1 -1
- package/esm/commands/jwt-secret-generator-command.mjs.map +1 -1
- package/esm/contracts/auth-contract.d.mts +1 -3
- package/esm/contracts/auth-contract.d.mts.map +1 -1
- package/esm/contracts/index.d.mts +2 -1
- package/esm/contracts/providers.d.mts +82 -50
- package/esm/contracts/providers.d.mts.map +1 -1
- package/esm/contracts/request-locals.d.mts +2 -3
- package/esm/contracts/request-locals.d.mts.map +1 -1
- package/esm/contracts/types.d.mts +59 -43
- package/esm/contracts/types.d.mts.map +1 -1
- package/esm/errors/auth-provider-sdk-missing.error.d.mts +1 -3
- package/esm/errors/auth-provider-sdk-missing.error.d.mts.map +1 -1
- package/esm/errors/email-not-verified.error.d.mts +1 -3
- package/esm/errors/email-not-verified.error.d.mts.map +1 -1
- package/esm/errors/index.d.mts +2 -1
- package/esm/errors/index.mjs +1 -1
- package/esm/errors/invalid-one-time-token.error.d.mts +1 -3
- package/esm/errors/invalid-one-time-token.error.d.mts.map +1 -1
- package/esm/errors/invalid-passkey.error.d.mts +1 -3
- package/esm/errors/invalid-passkey.error.d.mts.map +1 -1
- package/esm/errors/invalid-provider-callback.error.d.mts +1 -3
- package/esm/errors/invalid-provider-callback.error.d.mts.map +1 -1
- package/esm/errors/notifications-unavailable.error.d.mts +1 -3
- package/esm/errors/notifications-unavailable.error.d.mts.map +1 -1
- package/esm/errors/provider-email-not-verified.error.d.mts +1 -3
- package/esm/errors/provider-email-not-verified.error.d.mts.map +1 -1
- package/esm/index.d.mts +8 -0
- package/esm/localization/auth-default-translations.d.mts +1 -3
- package/esm/localization/auth-default-translations.d.mts.map +1 -1
- package/esm/localization/auth-translations.type.d.mts +11 -7
- package/esm/localization/auth-translations.type.d.mts.map +1 -1
- package/esm/localization/index.mjs +1 -1
- package/esm/localization/register-auth-translations.d.mts +1 -2
- package/esm/localization/register-auth-translations.d.mts.map +1 -1
- package/esm/middleware/auth.middleware.d.mts +10 -10
- package/esm/middleware/auth.middleware.d.mts.map +1 -1
- package/esm/middleware/auth.middleware.mjs +2 -2
- package/esm/middleware/auth.middleware.mjs.map +1 -1
- package/esm/middleware/csrf-origin-check.d.mts +4 -6
- package/esm/middleware/csrf-origin-check.d.mts.map +1 -1
- package/esm/middleware/csrf-origin-check.mjs +1 -1
- package/esm/middleware/csrf-origin-check.mjs.map +1 -1
- package/esm/middleware/index.d.mts +2 -1
- package/esm/middleware/index.mjs +1 -1
- package/esm/middleware/login-throttle.middleware.d.mts +4 -6
- package/esm/middleware/login-throttle.middleware.d.mts.map +1 -1
- package/esm/middleware/login-throttle.middleware.mjs +1 -1
- package/esm/middleware/login-throttle.middleware.mjs.map +1 -1
- package/esm/middleware/one-time-token-throttle.middleware.d.mts +2 -4
- package/esm/middleware/one-time-token-throttle.middleware.d.mts.map +1 -1
- package/esm/middleware/otp-throttle.middleware.d.mts +2 -4
- package/esm/middleware/otp-throttle.middleware.d.mts.map +1 -1
- package/esm/middleware/require-verified-email.middleware.d.mts +1 -3
- package/esm/middleware/require-verified-email.middleware.d.mts.map +1 -1
- package/esm/models/access-token/access-token.model.d.mts +6 -30
- package/esm/models/access-token/access-token.model.d.mts.map +1 -1
- package/esm/models/access-token/index.d.mts +2 -1
- package/esm/models/access-token/index.mjs +1 -1
- package/esm/models/auth-token-family/auth-token-family.model.d.mts +2 -28
- package/esm/models/auth-token-family/auth-token-family.model.d.mts.map +1 -1
- package/esm/models/auth-token-family/index.d.mts +2 -1
- package/esm/models/auth-token-family/index.mjs +1 -1
- package/esm/models/auth.model.d.mts +1 -3
- package/esm/models/auth.model.d.mts.map +1 -1
- package/esm/models/index.d.mts +8 -2
- package/esm/models/index.d.mts.map +1 -1
- package/esm/models/index.mjs +1 -1
- package/esm/models/one-time-token/index.d.mts +2 -1
- package/esm/models/one-time-token/index.mjs +1 -1
- package/esm/models/one-time-token/one-time-token.model.d.mts +3 -37
- package/esm/models/one-time-token/one-time-token.model.d.mts.map +1 -1
- package/esm/models/passkey-credential/index.d.mts +2 -1
- package/esm/models/passkey-credential/index.mjs +1 -1
- package/esm/models/passkey-credential/passkey-credential.model.d.mts +2 -32
- package/esm/models/passkey-credential/passkey-credential.model.d.mts.map +1 -1
- package/esm/models/provider-account/index.d.mts +2 -1
- package/esm/models/provider-account/index.mjs +1 -1
- package/esm/models/provider-account/provider-account.model.d.mts +2 -28
- package/esm/models/provider-account/provider-account.model.d.mts.map +1 -1
- package/esm/models/refresh-token/index.d.mts +2 -1
- package/esm/models/refresh-token/index.mjs +1 -1
- package/esm/models/refresh-token/refresh-token.model.d.mts +11 -55
- package/esm/models/refresh-token/refresh-token.model.d.mts.map +1 -1
- package/esm/otp/index.d.mts +2 -1
- package/esm/otp/index.mjs +1 -1
- package/esm/otp/otp.d.mts +2 -4
- package/esm/otp/otp.d.mts.map +1 -1
- package/esm/otp/otp.mjs +2 -1
- package/esm/otp/otp.mjs.map +1 -1
- package/esm/passkeys/index.d.mts +2 -1
- package/esm/passkeys/index.mjs +1 -1
- package/esm/passkeys/passkey-authentication.d.mts +2 -4
- package/esm/passkeys/passkey-authentication.d.mts.map +1 -1
- package/esm/passkeys/passkey-authentication.mjs +2 -1
- package/esm/passkeys/passkey-authentication.mjs.map +1 -1
- package/esm/passkeys/passkey-registration.d.mts +3 -4
- package/esm/passkeys/passkey-registration.d.mts.map +1 -1
- package/esm/passkeys/simplewebauthn.d.mts +2 -3
- package/esm/passkeys/simplewebauthn.d.mts.map +1 -1
- package/esm/passkeys/simplewebauthn.mjs +1 -1
- package/esm/providers/apple-provider.d.mts +5 -9
- package/esm/providers/apple-provider.d.mts.map +1 -1
- package/esm/providers/discord-provider.d.mts +2 -7
- package/esm/providers/discord-provider.d.mts.map +1 -1
- package/esm/providers/facebook-provider.d.mts +2 -7
- package/esm/providers/facebook-provider.d.mts.map +1 -1
- package/esm/providers/github-provider.d.mts +2 -7
- package/esm/providers/github-provider.d.mts.map +1 -1
- package/esm/providers/google-provider.d.mts +5 -10
- package/esm/providers/google-provider.d.mts.map +1 -1
- package/esm/providers/index.d.mts +2 -1
- package/esm/providers/index.mjs +1 -1
- package/esm/providers/linkedin-provider.d.mts +3 -8
- package/esm/providers/linkedin-provider.d.mts.map +1 -1
- package/esm/providers/provider-login.d.mts +3 -5
- package/esm/providers/provider-login.d.mts.map +1 -1
- package/esm/providers/provider-login.mjs +3 -2
- package/esm/providers/provider-login.mjs.map +1 -1
- package/esm/providers/provider-state-cookie.mjs +3 -2
- package/esm/providers/provider-state-cookie.mjs.map +1 -1
- package/esm/providers/x-provider.d.mts +2 -7
- package/esm/providers/x-provider.d.mts.map +1 -1
- package/esm/services/auth-events.d.mts +5 -6
- package/esm/services/auth-events.d.mts.map +1 -1
- package/esm/services/auth.service.d.mts +10 -9
- package/esm/services/auth.service.d.mts.map +1 -1
- package/esm/services/current-user.d.mts +1 -3
- package/esm/services/current-user.d.mts.map +1 -1
- package/esm/services/email-verification.d.mts +3 -5
- package/esm/services/email-verification.d.mts.map +1 -1
- package/esm/services/generate-jwt-secret.d.mts +1 -2
- package/esm/services/generate-jwt-secret.d.mts.map +1 -1
- package/esm/services/index.d.mts +2 -1
- package/esm/services/index.mjs +1 -1
- package/esm/services/jwt.d.mts +8 -29
- package/esm/services/jwt.d.mts.map +1 -1
- package/esm/services/jwt.mjs +2 -2
- package/esm/services/jwt.mjs.map +1 -1
- package/esm/services/one-time-tokens.d.mts +6 -6
- package/esm/services/one-time-tokens.d.mts.map +1 -1
- package/esm/services/password-reset.d.mts +2 -4
- package/esm/services/password-reset.d.mts.map +1 -1
- package/esm/services/resolve-request-user.d.mts +19 -14
- package/esm/services/resolve-request-user.d.mts.map +1 -1
- package/esm/services/resolve-request-user.mjs.map +1 -1
- package/esm/services/token-family-operation.mjs +1 -1
- package/esm/session/index.d.mts +2 -1
- package/esm/session/index.mjs +1 -1
- package/esm/session/page-session.d.mts +26 -18
- package/esm/session/page-session.d.mts.map +1 -1
- package/esm/utils/auth-error-codes.d.mts +11 -22
- package/esm/utils/auth-error-codes.d.mts.map +1 -1
- package/esm/utils/index.mjs +1 -1
- package/esm/utils/safe-equal.d.mts +1 -2
- package/esm/utils/safe-equal.d.mts.map +1 -1
- package/esm/utils/token-expiry.d.mts +3 -4
- package/esm/utils/token-expiry.d.mts.map +1 -1
- package/llms-full.txt +189 -111
- package/package.json +8 -8
- package/skills/auth-basics/SKILL.md +10 -13
- package/skills/customize-token-storage/SKILL.md +24 -19
- package/skills/customize-user-type/SKILL.md +3 -1
- package/skills/index.md +4 -1
- package/skills/login-with-providers/SKILL.md +54 -29
- package/skills/manage-tokens/SKILL.md +2 -2
- package/skills/overview/SKILL.md +10 -1
- package/skills/protect-routes/SKILL.md +23 -14
- package/skills/register-user/SKILL.md +4 -4
- package/skills/run-auth-commands/SKILL.md +1 -1
- package/skills/throttle-login-attempts/SKILL.md +51 -22
- package/skills/verify-email-and-reset-password/SKILL.md +7 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-request-user.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/services/resolve-request-user.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-request-user.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/services/resolve-request-user.ts"],"mappings":";;;YAgBY;;EAEV,YAAY;;EAEZ,oBAAoB;;EAEpB;;EAEA;;EAEA;;EAEA;;EAEA,eAAe;;;;;;YAOL;YAEA,mBAAmB;EACzB,MAAM;EAAO;;EACb;EAAY,SAAS;;;wBAoBX,eAAe,SAAS,SAAS,WAAW;;;;;;;;;;;;wBAqBtC,0BACpB,SAAS,SACT,UAAU,UACV,UAAS,4BACR,QAAQ;;;;;;;;wBAmHK,mBACd,SAAS,SACT,UAAU,UACV,UAAS,4BACR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-request-user.mjs","names":[],"sources":["../../../../../../../../packages/auth/src/services/resolve-request-user.ts"],"sourcesContent":["import { config, type Request, type Response } from \"@warlock.js/core\";\nimport { log } from \"@warlock.js/logger\";\nimport type { CookieDomainResolver, TokenFrom } from \"../contracts/types\";\nimport { AccessToken } from \"../models/access-token\";\nimport { authService } from \"./auth.service\";\nimport { isInvalidCredentialError, jwt } from \"./jwt\";\n\n/**\n * Decoded access-token claims the resolver reads. The full payload carries\n * more (`created_at`, `tokenType`, `iat`, `exp`) but only these drive routing.\n */\ntype DecodedAccessToken = {\n id: string | number;\n userType?: string;\n};\n\nexport type ResolveRequestUserOptions = {\n /** Where the access token is read from. Defaults to `\"header\"`. */\n tokenFrom?: TokenFrom;\n /** Refresh credential source; enables one automatic renewal per call. */\n refreshCredential?: TokenFrom;\n /** Refresh overlap window forwarded to `authService.renewAutomaticSession`. */\n overlapMs?: number;\n /** User types allowed to pass. Empty means any authenticated type. */\n allowedTypes?: string[];\n /** Absolute family lifetime in ms; rotation never extends a family past it. */\n maxAgeMs?: number;\n /** The single user type a renewal mints for. Required for renewal. */\n renewalUserType?: string;\n /** Select a request-scoped Domain for renewed cookies. */\n cookieDomain?: CookieDomainResolver;\n};\n\n/**\n * Why a request did not resolve to a user. The middleware maps each reason to\n * its own response; `resolveRequestUser` collapses them all to `null`.\n */\nexport type RequestUserFailure = \"missing\" | \"invalid\" | \"forbidden\" | \"unauthorized\";\n\nexport type RequestUserOutcome<TUser = any> =\n { user: TUser; failure?: undefined } | { user: null; failure: RequestUserFailure };\n\n/**\n * Whether the persisted row says the token is dead.\n *\n * The answer belongs to the model (`AccessToken.isExpired`), so a registered\n * override that renames or reshapes its expiry column stays authoritative. A\n * row that cannot answer at all — an override that dropped the getter — is\n * treated as **expired**: a check must never quietly answer \"fine\" when it has\n * nothing to check.\n *\n * This is independent of the `exp` claim required by `jwt.verify`: that guard\n * catches a token whose *claims* carry no deadline; this one catches a token\n * whose *row* says the deadline has passed.\n */\nfunction accessTokenRowIsExpired(accessToken: AccessToken): boolean {\n return typeof accessToken.isExpired === \"boolean\" ? accessToken.isExpired : true;\n}\n\n/** Read one credential (access or refresh) from the header or a cookie. */\nexport function readCredential(request: Request, tokenFrom: TokenFrom): string {\n if (tokenFrom === \"header\") {\n return request.authorizationValue;\n }\n\n const value = request.cookie(tokenFrom.slice(\"cookie:\".length));\n\n return value ? String(value) : \"\";\n}\n\n/**\n * Resolve a request's credential to a user, reporting WHY it failed.\n *\n * Side effects match what `authMiddleware` always did: `request.locals.user` is\n * cleared on every failure, `request.decodedAccessToken` is set once a token\n * verifies, and stale rows are destroyed. It does NOT set `request.locals.user`\n * on success — the caller decides that.\n *\n * At most one renewal is attempted per call. The renewed access token is\n * checked through the same path; no handler or unsafe request replay happens.\n */\nexport async function resolveRequestUserOutcome(\n request: Request,\n response: Response,\n options: ResolveRequestUserOptions = {},\n): Promise<RequestUserOutcome> {\n const tokenFrom = options.tokenFrom ?? \"header\";\n const allowedTypes = options.allowedTypes ?? [];\n const { refreshCredential } = options;\n let authorizationValue = readCredential(request, tokenFrom);\n let renewalAttempted = false;\n\n const renew = async (): Promise<boolean> => {\n if (!refreshCredential || renewalAttempted) return false;\n\n renewalAttempted = true;\n const refreshToken = readCredential(request, refreshCredential);\n if (!refreshToken) return false;\n\n const pair = await authService.renewAutomaticSession(refreshToken, options.renewalUserType!, {\n overlapMs: options.overlapMs,\n maxAgeMs: options.maxAgeMs,\n });\n if (!pair?.refreshToken) return false;\n\n authService.setAuthCookie(response, pair.accessToken, {\n name: tokenFrom.slice(\"cookie:\".length),\n domain: options.cookieDomain?.(request),\n });\n authService.setAuthCookie(response, pair.refreshToken, {\n name: refreshCredential.slice(\"cookie:\".length),\n domain: options.cookieDomain?.(request),\n });\n authorizationValue = pair.accessToken.token;\n\n return true;\n };\n\n const fail = (failure: RequestUserFailure): RequestUserOutcome => {\n request.locals.user = undefined;\n\n return { user: null, failure };\n };\n\n let decoded: DecodedAccessToken;\n let accessToken: AccessToken | null;\n\n while (true) {\n if (!authorizationValue) {\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"missing\");\n }\n\n try {\n decoded = await jwt.verify<DecodedAccessToken>(authorizationValue);\n } catch (error) {\n if (!isInvalidCredentialError(error)) throw error;\n log.error(\"http\", \"auth\", error);\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"invalid\");\n }\n\n request.decodedAccessToken = decoded;\n const AccessTokenModel = config.key(\"auth.accessToken.model\", AccessToken);\n accessToken = await AccessTokenModel.findByToken(authorizationValue);\n\n if (!accessToken) {\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"invalid\");\n }\n\n if (accessTokenRowIsExpired(accessToken)) {\n await accessToken.destroy();\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"invalid\");\n }\n\n break;\n }\n\n const userType = decoded.userType ?? accessToken.userType;\n\n if (allowedTypes.length && !allowedTypes.includes(userType)) {\n return { user: null, failure: \"forbidden\" };\n }\n\n const UserModel = config.key(`auth.userType.${userType}`);\n\n if (!UserModel) {\n // Configuration, not credentials. Throwing keeps a mis-registered app\n // loudly broken instead of quietly rejecting every request of this type.\n throw new Error(`User type ${userType} is unknown type.`);\n }\n\n const currentUser = await UserModel.find(decoded.id);\n\n if (!currentUser) {\n await accessToken.destroy();\n\n return fail(\"invalid\");\n }\n\n if (!(await authService.canAuthenticate(currentUser))) {\n return fail(\"unauthorized\");\n }\n\n return { user: currentUser };\n}\n\n/**\n * Resolve the request's credential to its user model, or `null` when there is\n * none (missing, invalid, expired, wrong type, or not allowed to authenticate).\n *\n * Includes the middleware's automatic renewal when `options.refreshCredential`\n * is set. Use `resolveRequestUserOutcome` when the failure reason matters.\n */\nexport function resolveRequestUser(\n request: Request,\n response: Response,\n options: ResolveRequestUserOptions = {},\n): Promise<any> {\n // Single-flight: the PROMISE is stored, so concurrent and repeat callers in\n // one request share one verify, one lookup and at most one renewal. The first\n // caller's options win for the rest of the request.\n if (!request.locals.session) {\n request.locals.session = resolveRequestUserOutcome(request, response, options).then(\n (outcome) => outcome.user,\n );\n }\n\n return request.locals.session;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolve-request-user.mjs","names":[],"sources":["../../../../../../../../packages/auth/src/services/resolve-request-user.ts"],"sourcesContent":["import { config, type Request, type Response } from \"@warlock.js/core\";\nimport { log } from \"@warlock.js/logger\";\nimport type { CookieDomainResolver, TokenFrom } from \"../contracts/types\";\nimport { AccessToken } from \"../models/access-token\";\nimport { authService } from \"./auth.service\";\nimport { isInvalidCredentialError, jwt } from \"./jwt\";\n\n/**\n * Decoded access-token claims the resolver reads. The full payload carries\n * more (`created_at`, `tokenType`, `iat`, `exp`) but only these drive routing.\n */\ntype DecodedAccessToken = {\n id: string | number;\n userType?: string;\n};\n\nexport type ResolveRequestUserOptions = {\n /** Where the access token is read from. Defaults to `\"header\"`. */\n tokenFrom?: TokenFrom;\n /** Refresh credential source; enables one automatic renewal per call. */\n refreshCredential?: TokenFrom;\n /** Refresh overlap window forwarded to `authService.renewAutomaticSession`. */\n overlapMs?: number;\n /** User types allowed to pass. Empty means any authenticated type. */\n allowedTypes?: string[];\n /** Absolute family lifetime in ms; rotation never extends a family past it. */\n maxAgeMs?: number;\n /** The single user type a renewal mints for. Required for renewal. */\n renewalUserType?: string;\n /** Select a request-scoped Domain for renewed cookies. */\n cookieDomain?: CookieDomainResolver;\n};\n\n/**\n * Why a request did not resolve to a user. The middleware maps each reason to\n * its own response; `resolveRequestUser` collapses them all to `null`.\n */\nexport type RequestUserFailure = \"missing\" | \"invalid\" | \"forbidden\" | \"unauthorized\";\n\nexport type RequestUserOutcome<TUser = any> =\n | { user: TUser; failure?: undefined }\n | { user: null; failure: RequestUserFailure };\n\n/**\n * Whether the persisted row says the token is dead.\n *\n * The answer belongs to the model (`AccessToken.isExpired`), so a registered\n * override that renames or reshapes its expiry column stays authoritative. A\n * row that cannot answer at all — an override that dropped the getter — is\n * treated as **expired**: a check must never quietly answer \"fine\" when it has\n * nothing to check.\n *\n * This is independent of the `exp` claim required by `jwt.verify`: that guard\n * catches a token whose *claims* carry no deadline; this one catches a token\n * whose *row* says the deadline has passed.\n */\nfunction accessTokenRowIsExpired(accessToken: AccessToken): boolean {\n return typeof accessToken.isExpired === \"boolean\" ? accessToken.isExpired : true;\n}\n\n/** Read one credential (access or refresh) from the header or a cookie. */\nexport function readCredential(request: Request, tokenFrom: TokenFrom): string {\n if (tokenFrom === \"header\") {\n return request.authorizationValue;\n }\n\n const value = request.cookie(tokenFrom.slice(\"cookie:\".length));\n\n return value ? String(value) : \"\";\n}\n\n/**\n * Resolve a request's credential to a user, reporting WHY it failed.\n *\n * Side effects match what `authMiddleware` always did: `request.locals.user` is\n * cleared on every failure, `request.decodedAccessToken` is set once a token\n * verifies, and stale rows are destroyed. It does NOT set `request.locals.user`\n * on success — the caller decides that.\n *\n * At most one renewal is attempted per call. The renewed access token is\n * checked through the same path; no handler or unsafe request replay happens.\n */\nexport async function resolveRequestUserOutcome(\n request: Request,\n response: Response,\n options: ResolveRequestUserOptions = {},\n): Promise<RequestUserOutcome> {\n const tokenFrom = options.tokenFrom ?? \"header\";\n const allowedTypes = options.allowedTypes ?? [];\n const { refreshCredential } = options;\n let authorizationValue = readCredential(request, tokenFrom);\n let renewalAttempted = false;\n\n const renew = async (): Promise<boolean> => {\n if (!refreshCredential || renewalAttempted) return false;\n\n renewalAttempted = true;\n const refreshToken = readCredential(request, refreshCredential);\n if (!refreshToken) return false;\n\n const pair = await authService.renewAutomaticSession(refreshToken, options.renewalUserType!, {\n overlapMs: options.overlapMs,\n maxAgeMs: options.maxAgeMs,\n });\n if (!pair?.refreshToken) return false;\n\n authService.setAuthCookie(response, pair.accessToken, {\n name: tokenFrom.slice(\"cookie:\".length),\n domain: options.cookieDomain?.(request),\n });\n authService.setAuthCookie(response, pair.refreshToken, {\n name: refreshCredential.slice(\"cookie:\".length),\n domain: options.cookieDomain?.(request),\n });\n authorizationValue = pair.accessToken.token;\n\n return true;\n };\n\n const fail = (failure: RequestUserFailure): RequestUserOutcome => {\n request.locals.user = undefined;\n\n return { user: null, failure };\n };\n\n let decoded: DecodedAccessToken;\n let accessToken: AccessToken | null;\n\n while (true) {\n if (!authorizationValue) {\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"missing\");\n }\n\n try {\n decoded = await jwt.verify<DecodedAccessToken>(authorizationValue);\n } catch (error) {\n if (!isInvalidCredentialError(error)) throw error;\n log.error(\"http\", \"auth\", error);\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"invalid\");\n }\n\n request.decodedAccessToken = decoded;\n const AccessTokenModel = config.key(\"auth.accessToken.model\", AccessToken);\n accessToken = await AccessTokenModel.findByToken(authorizationValue);\n\n if (!accessToken) {\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"invalid\");\n }\n\n if (accessTokenRowIsExpired(accessToken)) {\n await accessToken.destroy();\n request.locals.user = undefined;\n if (await renew()) continue;\n return fail(\"invalid\");\n }\n\n break;\n }\n\n const userType = decoded.userType ?? accessToken.userType;\n\n if (allowedTypes.length && !allowedTypes.includes(userType)) {\n return { user: null, failure: \"forbidden\" };\n }\n\n const UserModel = config.key(`auth.userType.${userType}`);\n\n if (!UserModel) {\n // Configuration, not credentials. Throwing keeps a mis-registered app\n // loudly broken instead of quietly rejecting every request of this type.\n throw new Error(`User type ${userType} is unknown type.`);\n }\n\n const currentUser = await UserModel.find(decoded.id);\n\n if (!currentUser) {\n await accessToken.destroy();\n\n return fail(\"invalid\");\n }\n\n if (!(await authService.canAuthenticate(currentUser))) {\n return fail(\"unauthorized\");\n }\n\n return { user: currentUser };\n}\n\n/**\n * Resolve the request's credential to its user model, or `null` when there is\n * none (missing, invalid, expired, wrong type, or not allowed to authenticate).\n *\n * Includes the middleware's automatic renewal when `options.refreshCredential`\n * is set. Use `resolveRequestUserOutcome` when the failure reason matters.\n */\nexport function resolveRequestUser(\n request: Request,\n response: Response,\n options: ResolveRequestUserOptions = {},\n): Promise<any> {\n // Single-flight: the PROMISE is stored, so concurrent and repeat callers in\n // one request share one verify, one lookup and at most one renewal. The first\n // caller's options win for the rest of the request.\n if (!request.locals.session) {\n request.locals.session = resolveRequestUserOutcome(request, response, options).then(\n (outcome) => outcome.user,\n );\n }\n\n return request.locals.session;\n}\n"],"mappings":"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"}
|
|
@@ -70,5 +70,5 @@ async function runTokenFamilyOperation(familyId, operation) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
//#endregion
|
|
73
|
-
export { TokenFamilyUnavailableError, afterTokenFamilyOperation, runTokenFamilyOperation };
|
|
73
|
+
export { TokenFamilyConflictError, TokenFamilyUnavailableError, afterTokenFamilyOperation, runTokenFamilyOperation };
|
|
74
74
|
//# sourceMappingURL=token-family-operation.mjs.map
|
package/esm/session/index.d.mts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import { PageSessionOptions, PageSessionResolver, SessionMiddlewareOptions, SessionResolverOptions, SessionSource, pageSession, sessionMiddleware } from "./page-session.mjs";
|
|
1
|
+
import { PageSessionOptions, PageSessionResolver, SessionMiddlewareOptions, SessionResolverOptions, SessionSource, pageSession, sessionMiddleware } from "./page-session.mjs";
|
|
2
|
+
export { PageSessionOptions, PageSessionResolver, SessionMiddlewareOptions, SessionResolverOptions, SessionSource, pageSession, sessionMiddleware };
|
package/esm/session/index.mjs
CHANGED
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
import { CookieDomainResolver } from "../contracts/types.mjs";
|
|
2
2
|
import { Middleware, Request, Response } from "@warlock.js/core";
|
|
3
|
-
|
|
4
3
|
//#region ../../packages/auth/src/session/page-session.d.ts
|
|
5
4
|
/** Credential sources a session can be read from. */
|
|
6
|
-
type SessionSource = "cookie" | "header";
|
|
5
|
+
export type SessionSource = "cookie" | "header";
|
|
7
6
|
/**
|
|
8
7
|
* The seam web consumes. Declared here, not imported: web and auth never
|
|
9
8
|
* depend on each other, and `pageSession()` satisfies web's `SessionResolver`
|
|
10
9
|
* structurally.
|
|
11
10
|
*/
|
|
12
|
-
type PageSessionResolver<TModel = unknown, TUser = unknown> = {
|
|
11
|
+
export type PageSessionResolver<TModel = unknown, TUser = unknown> = {
|
|
13
12
|
resolve(request: Request, response: Response): Promise<{
|
|
14
13
|
model: TModel;
|
|
15
14
|
user: TUser;
|
|
16
15
|
} | null>;
|
|
17
16
|
};
|
|
18
|
-
type SessionResolverOptions = {
|
|
19
|
-
/** Access cookie name. @default auth.cookie.name */
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
export type SessionResolverOptions = {
|
|
18
|
+
/** Access cookie name. @default auth.cookie.name */
|
|
19
|
+
cookie?: string;
|
|
20
|
+
/** Refresh cookie name. @default auth.cookie.refreshName */
|
|
21
|
+
refreshCookie?: string;
|
|
22
|
+
/** Credential sources. A present Authorization header always wins. @default ["cookie", "header"] */
|
|
23
|
+
sources?: SessionSource[];
|
|
24
|
+
/** Renew an expired access cookie from the refresh cookie. Cookie source only. @default true */
|
|
25
|
+
renew?: boolean;
|
|
26
|
+
/** Allowed user types. @default auth.defaultUserType */
|
|
27
|
+
userTypes?: string | string[];
|
|
28
|
+
/** Absolute family lifetime, an `ms` string or milliseconds. @default auth.session.maxAge, else "30d" */
|
|
29
|
+
maxAge?: string | number;
|
|
30
|
+
/** Refresh overlap window forwarded to renewal. */
|
|
31
|
+
overlapMs?: number;
|
|
32
|
+
/** Select a request-scoped Domain for renewed cookies; `undefined` keeps them host-only. */
|
|
26
33
|
cookieDomain?: CookieDomainResolver;
|
|
27
34
|
};
|
|
28
|
-
type PageSessionOptions<TModel, TUser> = SessionResolverOptions & {
|
|
29
|
-
/** Model → wire projection. Required: a model never crosses the wire by default. */
|
|
35
|
+
export type PageSessionOptions<TModel, TUser> = SessionResolverOptions & {
|
|
36
|
+
/** Model → wire projection. Required: a model never crosses the wire by default. */
|
|
37
|
+
project: (model: TModel) => TUser | Promise<TUser>;
|
|
30
38
|
};
|
|
31
|
-
type SessionMiddlewareOptions = SessionResolverOptions & {
|
|
32
|
-
/** Let guests through with no user instead of a 401. @default false */
|
|
39
|
+
export type SessionMiddlewareOptions = SessionResolverOptions & {
|
|
40
|
+
/** Let guests through with no user instead of a 401. @default false */
|
|
41
|
+
optional?: boolean;
|
|
33
42
|
};
|
|
34
43
|
/**
|
|
35
44
|
* Session resolver for pages: cookie-or-header credential, reactive renewal,
|
|
@@ -38,14 +47,13 @@ type SessionMiddlewareOptions = SessionResolverOptions & {
|
|
|
38
47
|
* @example
|
|
39
48
|
* export default { session: pageSession({ project: (user: User) => userResource(user) }) };
|
|
40
49
|
*/
|
|
41
|
-
declare function pageSession<TModel = any, TUser = unknown>(options: PageSessionOptions<TModel, TUser>): PageSessionResolver<TModel, TUser>;
|
|
50
|
+
export declare function pageSession<TModel = any, TUser = unknown>(options: PageSessionOptions<TModel, TUser>): PageSessionResolver<TModel, TUser>;
|
|
42
51
|
/**
|
|
43
52
|
* Middleware for cookie API routes over the same resolver as `pageSession`.
|
|
44
53
|
* A cookie-authenticated unsafe request must pass the Origin/Referer check
|
|
45
54
|
* (renewal can mint cookies, so it runs even when the access cookie is gone).
|
|
46
55
|
* Guests get a 401 unless `optional`. The user lands on `request.locals.user`.
|
|
47
56
|
*/
|
|
48
|
-
declare function sessionMiddleware(options?: SessionMiddlewareOptions): Middleware;
|
|
57
|
+
export declare function sessionMiddleware(options?: SessionMiddlewareOptions): Middleware;
|
|
49
58
|
//#endregion
|
|
50
|
-
export { PageSessionOptions, PageSessionResolver, SessionMiddlewareOptions, SessionResolverOptions, SessionSource, pageSession, sessionMiddleware };
|
|
51
59
|
//# sourceMappingURL=page-session.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-session.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/session/page-session.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"page-session.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/session/page-session.ts"],"mappings":";;;;YAcY;;;;;;YAUA,oBAAoB,kBAAkB;EAChD,QAAQ,SAAS,SAAS,UAAU,WAAW;IAAU,OAAO;IAAQ,MAAM;;;YAGpE;;EAEV;;EAEA;;EAEA,UAAU;;EAEV;;EAEA;;EAEA;;EAEA;;EAEA,eAAe;;YAGL,mBAAmB,QAAQ,SAAS;;EAE9C,UAAU,OAAO,WAAW,QAAQ,QAAQ;;YAGlC,2BAA2B;;EAErC;;;;;;;;;wBAgFc,YAAY,cAAc,iBACxC,SAAS,mBAAmB,QAAQ,SACnC,oBAAoB,QAAQ;;;;;;;wBAmCf,kBAAkB,UAAS,2BAAgC"}
|
|
@@ -1,30 +1,26 @@
|
|
|
1
1
|
//#region ../../packages/auth/src/utils/auth-error-codes.d.ts
|
|
2
|
-
declare enum AuthErrorCodes {
|
|
2
|
+
export declare enum AuthErrorCodes {
|
|
3
3
|
/**
|
|
4
4
|
* Missing Access Token Error Code EC001
|
|
5
5
|
* EC001 = Missing Access Token
|
|
6
6
|
*/
|
|
7
|
-
MissingAccessToken = "EC001",
|
|
8
|
-
// Error Code 001
|
|
7
|
+
MissingAccessToken = "EC001", // Error Code 001
|
|
9
8
|
/**
|
|
10
9
|
* Invalid Access Token Error Code EC002
|
|
11
10
|
* EC002 = Invalid Access Token
|
|
12
11
|
*/
|
|
13
|
-
InvalidAccessToken = "EC002",
|
|
14
|
-
// Error Code 002
|
|
12
|
+
InvalidAccessToken = "EC002", // Error Code 002
|
|
15
13
|
/**
|
|
16
14
|
* Unauthorized Error Code EC003
|
|
17
15
|
* EC003 = Unauthorized
|
|
18
16
|
*/
|
|
19
|
-
Unauthorized = "EC003",
|
|
20
|
-
// Error Code 003
|
|
17
|
+
Unauthorized = "EC003", // Error Code 003
|
|
21
18
|
/**
|
|
22
19
|
* Too Many Attempts Error Code EC004
|
|
23
20
|
* EC004 = Too Many Attempts — issued by the login-throttle middleware once
|
|
24
21
|
* a per-account or per-IP failure counter trips its threshold.
|
|
25
22
|
*/
|
|
26
|
-
TooManyAttempts = "EC004",
|
|
27
|
-
// Error Code 004
|
|
23
|
+
TooManyAttempts = "EC004", // Error Code 004
|
|
28
24
|
/**
|
|
29
25
|
* Invalid Token Type Error Code EC005
|
|
30
26
|
* EC005 = Invalid Token Type — the token's `tokenType` claim does not match
|
|
@@ -33,8 +29,7 @@ declare enum AuthErrorCodes {
|
|
|
33
29
|
* `Error` thrown by `assertTokenType` (`services/jwt.ts`) so callers can
|
|
34
30
|
* classify it as a credential failure without matching on the message.
|
|
35
31
|
*/
|
|
36
|
-
InvalidTokenType = "EC005",
|
|
37
|
-
// Error Code 005
|
|
32
|
+
InvalidTokenType = "EC005", // Error Code 005
|
|
38
33
|
/**
|
|
39
34
|
* CSRF Origin Mismatch Error Code EC006
|
|
40
35
|
* EC006 = a cookie-authenticated, unsafe-method (POST/PUT/PATCH/DELETE)
|
|
@@ -42,38 +37,33 @@ declare enum AuthErrorCodes {
|
|
|
42
37
|
* request's own origin or an entry in `auth.csrf.allowedOrigins`, or whose
|
|
43
38
|
* request carried neither header at all.
|
|
44
39
|
*/
|
|
45
|
-
CsrfOriginMismatch = "EC006",
|
|
46
|
-
// Error Code 006
|
|
40
|
+
CsrfOriginMismatch = "EC006", // Error Code 006
|
|
47
41
|
/**
|
|
48
42
|
* Email Not Verified Error Code EC007
|
|
49
43
|
* EC007 = the authenticated user has not verified their email address —
|
|
50
44
|
* thrown by `requireVerifiedEmail()` as `EmailNotVerifiedError` (403).
|
|
51
45
|
*/
|
|
52
|
-
EmailNotVerified = "EC007",
|
|
53
|
-
// Error Code 007
|
|
46
|
+
EmailNotVerified = "EC007", // Error Code 007
|
|
54
47
|
/**
|
|
55
48
|
* Invalid One-Time Token Error Code EC008
|
|
56
49
|
* EC008 = an email-verification or password-reset token that is unknown,
|
|
57
50
|
* issued for the other purpose, expired, or already used. One code for all
|
|
58
51
|
* four on purpose: the caller learns nothing about which it was.
|
|
59
52
|
*/
|
|
60
|
-
InvalidOneTimeToken = "EC008",
|
|
61
|
-
// Error Code 008
|
|
53
|
+
InvalidOneTimeToken = "EC008", // Error Code 008
|
|
62
54
|
/**
|
|
63
55
|
* Invalid Provider Callback Error Code EC009
|
|
64
56
|
* EC009 = a redirect-provider callback was rejected: missing, forged or
|
|
65
57
|
* expired state cookie, `state` mismatch, failed code exchange, or an
|
|
66
58
|
* id_token with a bad signature, issuer, audience, expiry or nonce.
|
|
67
59
|
*/
|
|
68
|
-
InvalidProviderCallback = "EC009",
|
|
69
|
-
// Error Code 009
|
|
60
|
+
InvalidProviderCallback = "EC009", // Error Code 009
|
|
70
61
|
/**
|
|
71
62
|
* Provider Email Not Verified Error Code EC010
|
|
72
63
|
* EC010 = the provider did not verify the email, so auth refused to link or
|
|
73
64
|
* create an account from it.
|
|
74
65
|
*/
|
|
75
|
-
ProviderEmailNotVerified = "EC010",
|
|
76
|
-
// Error Code 010
|
|
66
|
+
ProviderEmailNotVerified = "EC010", // Error Code 010
|
|
77
67
|
/**
|
|
78
68
|
* Invalid Passkey Error Code EC011
|
|
79
69
|
* EC011 = a passkey ceremony was rejected: unknown, expired or used
|
|
@@ -83,5 +73,4 @@ declare enum AuthErrorCodes {
|
|
|
83
73
|
InvalidPasskey = "EC011"
|
|
84
74
|
}
|
|
85
75
|
//#endregion
|
|
86
|
-
export { AuthErrorCodes };
|
|
87
76
|
//# sourceMappingURL=auth-error-codes.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-error-codes.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/utils/auth-error-codes.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"auth-error-codes.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/utils/auth-error-codes.ts"],"mappings":";oBAAY;;;;;EAKV;;;;;EAKA;;;;;EAKA;;;;;;EAMA;;;;;;;;;EASA;;;;;;;;EAQA;;;;;;EAMA;;;;;;;EAOA;;;;;;;EAOA;;;;;;EAMA;;;;;;;EAOA"}
|
package/esm/utils/index.mjs
CHANGED
|
@@ -2,4 +2,4 @@ import { AuthErrorCodes } from "./auth-error-codes.mjs";
|
|
|
2
2
|
import { isNeverExpiring, isUsableExpiry, tokenHasExpClaim } from "./token-expiry.mjs";
|
|
3
3
|
import { safeEqual } from "./safe-equal.mjs";
|
|
4
4
|
|
|
5
|
-
export {
|
|
5
|
+
export { AuthErrorCodes, isNeverExpiring, isUsableExpiry, safeEqual, tokenHasExpClaim };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
//#region ../../packages/auth/src/utils/safe-equal.d.ts
|
|
2
2
|
/** Constant-time string equality; strings of unequal length are simply unequal. */
|
|
3
|
-
declare function safeEqual(left: string, right: string): boolean;
|
|
3
|
+
export declare function safeEqual(left: string, right: string): boolean;
|
|
4
4
|
//#endregion
|
|
5
|
-
export { safeEqual };
|
|
6
5
|
//# sourceMappingURL=safe-equal.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-equal.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/utils/safe-equal.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"safe-equal.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/utils/safe-equal.ts"],"mappings":";;wBAGgB,UAAU,cAAc"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* nor `expires_at > now` (it never shows as an active session): it is outside
|
|
10
10
|
* the reach of every date predicate rather than merely wrong.
|
|
11
11
|
*/
|
|
12
|
-
declare function isUsableExpiry(value: unknown): boolean;
|
|
12
|
+
export declare function isUsableExpiry(value: unknown): boolean;
|
|
13
13
|
/**
|
|
14
14
|
* Whether the JWT carries a finite numeric `exp` claim.
|
|
15
15
|
*
|
|
@@ -19,7 +19,7 @@ declare function isUsableExpiry(value: unknown): boolean;
|
|
|
19
19
|
* answers `false` — it cannot be shown to expire, and a row whose token cannot
|
|
20
20
|
* even be parsed is unusable regardless.
|
|
21
21
|
*/
|
|
22
|
-
declare function tokenHasExpClaim(token: unknown): boolean;
|
|
22
|
+
export declare function tokenHasExpClaim(token: unknown): boolean;
|
|
23
23
|
/**
|
|
24
24
|
* Whether a token row can ever stop being accepted on its own.
|
|
25
25
|
*
|
|
@@ -29,7 +29,6 @@ declare function tokenHasExpClaim(token: unknown): boolean;
|
|
|
29
29
|
*
|
|
30
30
|
* This is the predicate the `auth.purge-never-expiring` remediation selects on.
|
|
31
31
|
*/
|
|
32
|
-
declare function isNeverExpiring(token: unknown, expiresAt: unknown): boolean;
|
|
32
|
+
export declare function isNeverExpiring(token: unknown, expiresAt: unknown): boolean;
|
|
33
33
|
//#endregion
|
|
34
|
-
export { isNeverExpiring, isUsableExpiry, tokenHasExpClaim };
|
|
35
34
|
//# sourceMappingURL=token-expiry.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-expiry.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/utils/token-expiry.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"token-expiry.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/utils/token-expiry.ts"],"mappings":";;;;;;;;;;;wBAqBgB,eAAe;;;;;;;;;;wBAef,iBAAiB;;;;;;;;;;wBAqBjB,gBAAgB,gBAAgB"}
|