@m1212e/oidc 0.0.0-stage → 0.1.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/LICENSE +201 -0
- package/README.md +164 -2
- package/out/index.cjs +1017 -0
- package/out/index.cjs.map +1 -0
- package/out/index.d.cts +298 -0
- package/out/index.d.cts.map +1 -0
- package/out/index.d.mts +298 -0
- package/out/index.d.mts.map +1 -0
- package/out/index.mjs +975 -0
- package/out/index.mjs.map +1 -0
- package/package.json +47 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["clockTolerance","clockToleranceOption"],"sources":["../lib/errors.ts","../lib/audience.ts","../lib/discovery.ts","../lib/logger.ts","../lib/returnTo.ts","../lib/tokenType.ts","../lib/core/logout.ts","../lib/tokenValidation.ts","../lib/types.ts","../lib/core/grant.ts","../lib/core/processTokens.ts","../lib/core/refresh.ts","../lib/core/signin.ts","../lib/core/userInfo.ts","../lib/core/index.ts"],"sourcesContent":["import type {\n TokenEndpointResponse,\n TokenEndpointResponseHelpers,\n} from \"openid-client\";\n\nexport type TokenKind = \"access\" | \"id\";\n\nexport type RefreshedTokenSet = TokenEndpointResponse &\n TokenEndpointResponseHelpers;\n\nexport class OidcError extends Error {\n refreshedTokens?: RefreshedTokenSet;\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OidcError\";\n }\n}\n\nexport class OidcInputError extends OidcError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OidcInputError\";\n }\n}\n\nexport class OidcTokenError extends OidcError {\n readonly tokenKind: TokenKind;\n readonly claim: string;\n\n constructor(tokenKind: TokenKind, claim: string, message: string) {\n super(message);\n this.name = \"OidcTokenError\";\n this.tokenKind = tokenKind;\n this.claim = claim;\n }\n}\n\nexport type TokenValidationFailure = {\n tokenKind: TokenKind;\n stage: string;\n error: unknown;\n};\n\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport class OidcTokenValidationError extends OidcError {\n readonly tokenKinds: readonly TokenKind[];\n readonly failures: readonly TokenValidationFailure[];\n\n constructor(\n tokenKinds: readonly TokenKind[],\n failures: readonly TokenValidationFailure[],\n ) {\n const relevant = failures.filter((failure) =>\n tokenKinds.includes(failure.tokenKind),\n );\n const detail = relevant.length\n ? relevant\n .map(\n (failure) =>\n `${failure.tokenKind} token ${failure.stage} failed (${describe(failure.error)})`,\n )\n .join(\"; \")\n : \"no validation strategy was available for it\";\n\n super(\n `could not validate the ${tokenKinds.join(\" and \")} token${tokenKinds.length > 1 ? \"s\" : \"\"}: ${detail}`,\n { cause: relevant[0]?.error },\n );\n this.name = \"OidcTokenValidationError\";\n this.tokenKinds = tokenKinds;\n this.failures = relevant;\n }\n}\n\nexport class OidcSubjectError extends OidcError {\n readonly expected: string;\n readonly actual: string;\n\n constructor(message: string, expected: string, actual: string) {\n super(message);\n this.name = \"OidcSubjectError\";\n this.expected = expected;\n this.actual = actual;\n }\n}\n\nexport class OidcGrantError extends OidcError {\n readonly grant: \"authorization_code\" | \"refresh_token\";\n\n constructor(\n grant: \"authorization_code\" | \"refresh_token\",\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"OidcGrantError\";\n this.grant = grant;\n }\n}\n\nexport class OidcStateError extends OidcError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OidcStateError\";\n }\n}\n\nexport class OidcClaimsError extends OidcError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OidcClaimsError\";\n }\n}\n\nexport class OidcUserInfoError extends OidcError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OidcUserInfoError\";\n }\n}\n\nexport class OidcLogoutError extends OidcError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OidcLogoutError\";\n }\n}\n\nexport function attachRefreshedTokens<E>(\n error: E,\n refreshedTokens?: RefreshedTokenSet,\n): E {\n if (\n refreshedTokens &&\n error instanceof OidcError &&\n // Tokens for a different subject must not be handed back for the caller to store.\n !(error instanceof OidcSubjectError)\n ) {\n error.refreshedTokens = refreshedTokens;\n }\n return error;\n}\n","import { OidcTokenError, type TokenKind } from \"./errors\";\n\nexport type { TokenKind } from \"./errors\";\n\nexport const DEFAULT_AUTHORIZED_PARTY_CLAIMS: readonly string[] = [\n \"azp\",\n \"client_id\",\n \"cid\",\n \"appid\",\n];\n\nexport type AudienceClaims = Readonly<Record<string, unknown>>;\n\nexport type AudiencePolicy = {\n clientId: string;\n expectedAudience?: string[];\n authorizedPartyClaims: readonly string[];\n verifyAudience?: (claims: AudienceClaims, tokenKind: TokenKind) => boolean;\n};\n\nexport class OidcAudienceError extends OidcTokenError {\n constructor(tokenKind: TokenKind, claim: string, message: string) {\n super(tokenKind, claim, message);\n this.name = \"OidcAudienceError\";\n }\n}\n\nfunction toAudienceList(aud: unknown): string[] {\n if (typeof aud === \"string\") return [aud];\n if (Array.isArray(aud))\n return aud.filter((entry): entry is string => typeof entry === \"string\");\n return [];\n}\n\nfunction findAuthorizedParty(\n claims: AudienceClaims,\n claimNames: readonly string[],\n): { claim: string; value: unknown } | undefined {\n for (const claim of claimNames) {\n const value = claims[claim];\n if (value === undefined || value === null) continue;\n return { claim, value };\n }\n return undefined;\n}\n\nexport function audienceVerifyOption(\n policy: AudiencePolicy,\n tokenKind: TokenKind,\n): string | string[] | undefined {\n if (policy.verifyAudience) return undefined;\n return tokenKind === \"id\" ? policy.clientId : policy.expectedAudience;\n}\n\nexport function assertAudienceClaim(\n claims: AudienceClaims,\n tokenKind: TokenKind,\n policy: AudiencePolicy,\n): void {\n const expected =\n tokenKind === \"id\" ? [policy.clientId] : policy.expectedAudience;\n if (!expected?.length) return;\n\n const aud = toAudienceList(claims.aud);\n if (!aud.some((entry) => expected.includes(entry))) {\n throw new OidcAudienceError(\n tokenKind,\n \"aud\",\n `${tokenKind} token \"aud\" (${aud.length ? aud.join(\", \") : \"absent\"}) does not include any expected audience (${expected.join(\", \")})`,\n );\n }\n}\n\nexport function assertAuthorizedParty(\n claims: AudienceClaims,\n tokenKind: TokenKind,\n policy: AudiencePolicy,\n): void {\n const { clientId, expectedAudience, authorizedPartyClaims } = policy;\n\n if (tokenKind === \"id\") {\n const azp = claims.azp;\n if (azp !== undefined && azp !== null) {\n if (azp !== clientId) {\n throw new OidcAudienceError(\n \"id\",\n \"azp\",\n `id token \"azp\" (${String(azp)}) is not this client id (${clientId})`,\n );\n }\n return;\n }\n const aud = toAudienceList(claims.aud);\n if (aud.length > 1) {\n throw new OidcAudienceError(\n \"id\",\n \"azp\",\n `id token \"aud\" names multiple parties (${aud.join(\", \")}) but carries no \"azp\" claim identifying the authorized one`,\n );\n }\n return;\n }\n\n if (expectedAudience?.length) {\n assertAudienceClaim(claims, \"access\", policy);\n return;\n }\n\n const party = findAuthorizedParty(claims, authorizedPartyClaims);\n if (party) {\n if (typeof party.value !== \"string\" || party.value !== clientId) {\n throw new OidcAudienceError(\n \"access\",\n party.claim,\n `access token \"${party.claim}\" (${\n typeof party.value === \"string\"\n ? party.value\n : JSON.stringify(party.value)\n }) is not this client id (${clientId})`,\n );\n }\n return;\n }\n throw new OidcAudienceError(\n \"access\",\n \"aud\",\n `access token cannot be bound to this client: it carries none of the authorized-party claims (${authorizedPartyClaims.join(\", \")}) and no \"expectedAudience\" is configured. Set \"expectedAudience\" to the value this resource server expects in \"aud\", extend \"authorizedPartyClaims\" with the claim your provider uses, or supply \"verifyAudience\".`,\n );\n}\n\nexport function assertAudienceAfterJwtVerify(\n claims: AudienceClaims,\n tokenKind: TokenKind,\n policy: AudiencePolicy,\n): void {\n if (policy.verifyAudience) {\n if (!policy.verifyAudience(claims, tokenKind)) {\n throw new OidcAudienceError(\n tokenKind,\n \"aud\",\n `verifyAudience rejected the ${tokenKind} token`,\n );\n }\n return;\n }\n assertAuthorizedParty(claims, tokenKind, policy);\n}\n\n// For claims that did not pass through jose's `audience` option (introspection, grant responses).\nexport function assertTokenAudience(\n claims: AudienceClaims,\n tokenKind: TokenKind,\n policy: AudiencePolicy,\n): void {\n if (!policy.verifyAudience) assertAudienceClaim(claims, tokenKind, policy);\n assertAudienceAfterJwtVerify(claims, tokenKind, policy);\n}\n\nexport function assertIntrospectedIdTokenAudience(\n claims: AudienceClaims,\n policy: AudiencePolicy,\n): void {\n if (policy.verifyAudience) {\n if (!policy.verifyAudience(claims, \"id\")) {\n throw new OidcAudienceError(\n \"id\",\n \"aud\",\n \"verifyAudience rejected the id token\",\n );\n }\n return;\n }\n\n const aud = toAudienceList(claims.aud);\n if (aud.length && !aud.includes(policy.clientId)) {\n throw new OidcAudienceError(\n \"id\",\n \"aud\",\n `id token introspection response reports \"aud\" (${aud.join(\", \")}), which does not include this client id (${policy.clientId})`,\n );\n }\n\n const claimNames = policy.authorizedPartyClaims.includes(\"azp\")\n ? policy.authorizedPartyClaims\n : [\"azp\", ...policy.authorizedPartyClaims];\n\n const party = findAuthorizedParty(claims, claimNames);\n if (party) {\n if (typeof party.value !== \"string\" || party.value !== policy.clientId) {\n throw new OidcAudienceError(\n \"id\",\n party.claim,\n `id token introspection response reports \"${party.claim}\" (${\n typeof party.value === \"string\"\n ? party.value\n : JSON.stringify(party.value)\n }), which is not this client id (${policy.clientId})`,\n );\n }\n return;\n }\n\n if (aud.length > 1) {\n throw new OidcAudienceError(\n \"id\",\n \"azp\",\n `id token introspection response reports an \"aud\" naming multiple parties (${aud.join(\", \")}) but nothing identifying the authorized one`,\n );\n }\n if (aud.length) return;\n\n throw new OidcAudienceError(\n \"id\",\n \"aud\",\n `id token introspection response cannot be bound to this client: it reports no \"aud\" and carries none of the authorized-party claims (${claimNames.join(\", \")}). Extend \"authorizedPartyClaims\" with the claim your provider reports, or supply \"verifyAudience\".`,\n );\n}\n\nexport function buildAudiencePolicy(opts: {\n clientId: string;\n expectedAudience?: string | string[];\n authorizedPartyClaims?: readonly string[];\n verifyAudience?: (claims: AudienceClaims, tokenKind: TokenKind) => boolean;\n}): AudiencePolicy {\n const supplied =\n typeof opts.expectedAudience === \"string\"\n ? [opts.expectedAudience]\n : (opts.expectedAudience ?? []);\n\n const invalid = supplied.filter(\n (entry) => typeof entry !== \"string\" || entry.length === 0,\n );\n if (invalid.length) {\n throw new TypeError(\n `invalid expectedAudience: every entry must be a non-empty string, and ${invalid.length} of ${supplied.length} ${invalid.length === 1 ? \"is\" : \"are\"} not. An empty audience matches nothing, so it cannot be dropped without silently replacing the resource-audience binding with the authorized-party one. Omit \"expectedAudience\" entirely to use that binding on purpose.`,\n );\n }\n const expected = supplied;\n\n return {\n clientId: opts.clientId,\n expectedAudience: expected.length ? expected : undefined,\n authorizedPartyClaims:\n opts.authorizedPartyClaims ?? DEFAULT_AUTHORIZED_PARTY_CLAIMS,\n verifyAudience: opts.verifyAudience,\n };\n}\n","import type { Configuration } from \"openid-client\";\nimport type { Logger } from \"./logger\";\n\nexport function resolveDevelopment(development?: boolean): boolean {\n if (development !== undefined) return development;\n if (typeof process === \"undefined\") return false;\n return process.env?.NODE_ENV === \"development\";\n}\n\nexport const DEFAULT_SIGNING_ALGORITHMS: readonly string[] = [\n \"RS256\",\n \"RS384\",\n \"RS512\",\n \"PS256\",\n \"PS384\",\n \"PS512\",\n \"ES256\",\n \"ES256K\",\n \"ES384\",\n \"ES512\",\n \"EdDSA\",\n \"Ed25519\",\n];\n\n// HS* keys are never published in a JWKS, so advertising them would only widen what is accepted.\nexport function isAsymmetricAlgorithm(alg: string): boolean {\n return /^(RS|PS|ES|Ed)/.test(alg);\n}\n\nexport function resolveJwksUri(jwksUri: string, development: boolean): URL {\n let url: URL;\n try {\n url = new URL(jwksUri);\n } catch {\n throw new TypeError(\n `the issuer advertises a jwks_uri that is not a URL (\"${jwksUri}\")`,\n );\n }\n if (url.protocol === \"https:\") return url;\n if (development && url.protocol === \"http:\") return url;\n throw new TypeError(\n `refusing the issuer's jwks_uri (\"${jwksUri}\"): signing keys must be fetched over https, and this is ${url.protocol.replace(\":\", \"\")}. Every token signature is checked against those keys, so anyone on the network could substitute their own and mint tokens for any user. Set \"development: true\" only if this is a local IdP.`,\n );\n}\n\n// Multi-tenant Microsoft endpoints publish a templated issuer (\"{tenantid}\") that never equals the request URL.\nfunction issuerMatchExempt(url: URL): boolean {\n return (\n url.origin === \"https://login.microsoftonline.com\" ||\n url.hostname.endsWith(\".b2clogin.com\")\n );\n}\n\nconst WELL_KNOWN = \"/.well-known/\";\nconst withoutTrailingSlash = (value: string) => value.replace(/\\/+$/, \"\");\n\nexport function assertDiscoveredIssuer(\n configured: string,\n discovered: string,\n): void {\n let configuredUrl: URL;\n try {\n configuredUrl = new URL(configured);\n } catch {\n return;\n }\n\n const path = configuredUrl.origin + configuredUrl.pathname;\n const wellKnownAt = path.indexOf(WELL_KNOWN);\n if (wellKnownAt === -1) return;\n\n const suffix = withoutTrailingSlash(\n path.slice(wellKnownAt + WELL_KNOWN.length),\n );\n // A single-segment suffix means the well-known path was appended to the issuer, so the issuer must equal the prefix.\n const appended = !suffix.includes(\"/\") && !issuerMatchExempt(configuredUrl);\n\n if (appended) {\n const expected = withoutTrailingSlash(path.slice(0, wellKnownAt));\n if (withoutTrailingSlash(discovered) === expected) return;\n throw new TypeError(\n `the metadata document at \"${configured}\" names a different issuer (\"${discovered}\") than the \"${expected}\" it was fetched for. Every token is verified against the issuer the document declares, and its keys and endpoints come from the same document, so this is not a mismatch that can be accepted. Configure \"issuer\" as the issuer identifier itself rather than its .well-known URL, or point it at the provider that really serves \"${discovered}\".`,\n );\n }\n\n let discoveredUrl: URL;\n try {\n discoveredUrl = new URL(discovered);\n } catch {\n throw new TypeError(\n `the metadata document at \"${configured}\" names an issuer that is not a URL (\"${discovered}\"), so it cannot be checked against the provider it was fetched from. Every token is verified against the issuer the document declares, and its keys and endpoints come from the same document, so an issuer that cannot be compared cannot be accepted. Configure \"issuer\" as the issuer identifier itself rather than its .well-known URL.`,\n );\n }\n\n if (discoveredUrl.origin === configuredUrl.origin) return;\n throw new TypeError(\n `the metadata document at \"${configured}\" names an issuer on a different origin (\"${discovered}\"). Every token is verified against the issuer the document declares, and its keys and endpoints come from the same document, so a document that hands off to another host cannot be accepted. Configure \"issuer\" as the issuer identifier itself rather than its .well-known URL.`,\n );\n}\n\nexport function assertPkceSupported(\n methods: string[] | undefined,\n clientSecret: string | undefined,\n log: Logger,\n): void {\n if (methods?.includes(\"S256\")) return;\n if (methods?.length) {\n throw new TypeError(\n `the issuer does not support the S256 PKCE challenge method (it advertises: ${methods.join(\", \")}). This library sends S256 on every authorization request, and without it an authorization code isn't bound to the login that requested it. An issuer that ignores it would leave the code redeemable by anyone who obtained it.`,\n );\n }\n log.warn(\n `[oidc] the issuer advertises no \"code_challenge_methods_supported\", so it cannot be confirmed that the PKCE challenge this library sends is honoured${\n clientSecret\n ? \"\"\n : \". This is a public client, where PKCE is the only thing protecting the token endpoint\"\n }. Verify that PKCE is enforced for this client at the IdP.`,\n );\n}\n\nconst DURATION_MULTIPLIERS: Record<string, number> = {\n s: 1,\n m: 60,\n h: 3600,\n d: 86400,\n w: 604800,\n y: 31557600,\n};\nconst DURATION =\n /^(\\d+|\\d+\\.\\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)$/i;\n\nexport function resolveClockTolerance(\n clockTolerance?: string | number,\n): number {\n if (clockTolerance === undefined) return 30;\n\n if (typeof clockTolerance === \"number\") {\n if (!Number.isFinite(clockTolerance) || clockTolerance < 0) {\n throw new TypeError(\n `invalid clockTolerance (${clockTolerance}): expected a non-negative number of seconds`,\n );\n }\n return clockTolerance;\n }\n\n const matched = DURATION.exec(clockTolerance.trim());\n if (!matched) {\n throw new TypeError(\n `invalid clockTolerance (\"${clockTolerance}\"): expected seconds as a number, or a duration such as \"30 seconds\" or \"5m\"`,\n );\n }\n const unit = (matched[2] as string)[0]?.toLowerCase() as string;\n return Math.round(\n Number.parseFloat(matched[1] as string) *\n (DURATION_MULTIPLIERS[unit] as number),\n );\n}\n\nexport function resolveSigningAlgorithms(\n config: Configuration,\n signingAlgorithms: string[] | undefined,\n log: Logger,\n): string[] {\n const advertised =\n config.serverMetadata().id_token_signing_alg_values_supported ?? [];\n const advertisedAlgorithms = advertised.filter(isAsymmetricAlgorithm);\n if (advertised.length !== advertisedAlgorithms.length) {\n log.debug(\n `[oidc] ignoring advertised signing algorithms that no JWKS key can verify: ${advertised\n .filter((alg) => !isAsymmetricAlgorithm(alg))\n .join(\", \")}`,\n );\n }\n return (\n signingAlgorithms ??\n (advertisedAlgorithms.length\n ? advertisedAlgorithms\n : [...DEFAULT_SIGNING_ALGORITHMS])\n );\n}\n","export type LogLevel = \"silent\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nexport type Logger = {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n};\n\nconst LEVELS: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst noop = () => {};\n\nexport function buildLogger(logger?: Logger, logLevel?: LogLevel): Logger {\n if (logger) return logger;\n const threshold = LEVELS[logLevel ?? \"warn\"];\n return {\n error:\n threshold >= LEVELS.error ? (...args) => console.error(...args) : noop,\n warn: threshold >= LEVELS.warn ? (...args) => console.warn(...args) : noop,\n info: threshold >= LEVELS.info ? (...args) => console.info(...args) : noop,\n debug:\n threshold >= LEVELS.debug ? (...args) => console.debug(...args) : noop,\n };\n}\n","import { OidcError } from \"./errors\";\n\n// Resolving against a dummy origin reveals relative-looking values such as \"//evil.com\" that leave the site.\nconst PROBE_ORIGIN = \"https://return-to.invalid\";\n\n// biome-ignore lint/suspicious/noControlCharactersInRegex: catching them is the point\nconst FORBIDDEN_CHARACTERS = /[\\u0000-\\u0020\\u007f\\\\]/;\n\nexport class OidcReturnToError extends OidcError {\n readonly returnTo: string;\n\n constructor(returnTo: string, message: string) {\n super(message);\n this.name = \"OidcReturnToError\";\n this.returnTo = returnTo;\n }\n}\n\nexport type ReturnToPolicy = {\n allowedOrigins: readonly string[];\n};\n\nexport function buildReturnToPolicy(opts: {\n allowedReturnToOrigins?: readonly string[];\n}): ReturnToPolicy {\n const origins = (opts.allowedReturnToOrigins ?? []).map((entry) => {\n let origin: string;\n try {\n origin = new URL(entry).origin;\n } catch {\n throw new TypeError(\n `invalid allowedReturnToOrigins entry (\"${entry}\"): expected an absolute URL such as \"https://app.example.com\"`,\n );\n }\n if (origin === \"null\") {\n throw new TypeError(\n `invalid allowedReturnToOrigins entry (\"${entry}\"): this URL has no origin to compare against`,\n );\n }\n return origin;\n });\n return { allowedOrigins: origins };\n}\n\nfunction assertNoForbiddenCharacters(value: string): void {\n const forbidden = FORBIDDEN_CHARACTERS.exec(value);\n if (!forbidden) return;\n throw new OidcReturnToError(\n value,\n `invalid returnTo (\"${value}\"): contains ${\n forbidden[0] === \"\\\\\"\n ? \"a backslash, which a URL parser reads as a slash\"\n : `the character U+${value.codePointAt(forbidden.index)?.toString(16).padStart(4, \"0\").toUpperCase()}, which a browser would strip or refuse`\n }`,\n );\n}\n\nfunction assertSafeRelativeReturnTo(returnTo: string): void {\n let resolved: URL;\n try {\n resolved = new URL(returnTo, PROBE_ORIGIN);\n } catch {\n throw new OidcReturnToError(\n returnTo,\n `invalid returnTo (\"${returnTo}\"): not a usable path`,\n );\n }\n if (resolved.origin !== PROBE_ORIGIN) {\n throw new OidcReturnToError(\n returnTo,\n `refusing returnTo (\"${returnTo}\"): it looks relative but navigates to ${resolved.origin}. Only same-site paths are allowed unless the origin is listed in \"allowedReturnToOrigins\".`,\n );\n }\n}\n\nfunction assertSafeAbsoluteReturnTo(\n returnTo: string,\n policy: ReturnToPolicy,\n): void {\n let absolute: URL;\n try {\n absolute = new URL(returnTo);\n } catch {\n throw new OidcReturnToError(\n returnTo,\n `invalid returnTo (\"${returnTo}\"): expected a path beginning with \"/\", or an absolute URL on an allowed origin`,\n );\n }\n\n if (absolute.protocol !== \"https:\" && absolute.protocol !== \"http:\") {\n throw new OidcReturnToError(\n returnTo,\n `refusing returnTo (\"${returnTo}\"): only http and https URLs may be redirected to`,\n );\n }\n\n if (!policy.allowedOrigins.includes(absolute.origin)) {\n throw new OidcReturnToError(\n returnTo,\n policy.allowedOrigins.length\n ? `refusing returnTo (\"${returnTo}\"): ${absolute.origin} is not one of the allowed origins (${policy.allowedOrigins.join(\", \")})`\n : `refusing returnTo (\"${returnTo}\"): absolute redirect targets need their origin listed in \"allowedReturnToOrigins\". A same-site path such as \"/dashboard\" needs no configuration.`,\n );\n }\n\n if (absolute.username || absolute.password) {\n throw new OidcReturnToError(\n returnTo,\n `refusing returnTo (\"${returnTo}\"): it embeds credentials, which disguise the origin it actually points at (${absolute.origin})`,\n );\n }\n}\n\nexport function assertSafeReturnTo(\n returnTo: string,\n policy: ReturnToPolicy,\n): string {\n if (typeof returnTo !== \"string\" || returnTo.length === 0) {\n throw new OidcReturnToError(\n String(returnTo),\n 'invalid returnTo: expected a non-empty path such as \"/dashboard\"',\n );\n }\n\n assertNoForbiddenCharacters(returnTo);\n\n if (returnTo.startsWith(\"/\")) {\n assertSafeRelativeReturnTo(returnTo);\n return returnTo;\n }\n\n assertSafeAbsoluteReturnTo(returnTo, policy);\n return returnTo;\n}\n\nexport function assertSafeRedirectUri(uri: string, label: string): string {\n if (typeof uri !== \"string\" || uri.length === 0) {\n throw new OidcReturnToError(\n String(uri),\n `invalid ${label}: expected an absolute URL such as \"https://app.example.com/callback\"`,\n );\n }\n\n if (FORBIDDEN_CHARACTERS.test(uri)) {\n throw new OidcReturnToError(\n uri,\n `invalid ${label} (\"${uri}\"): contains a control character, a space or a backslash`,\n );\n }\n\n let parsed: URL;\n try {\n parsed = new URL(uri);\n } catch {\n throw new OidcReturnToError(\n uri,\n `invalid ${label} (\"${uri}\"): expected an absolute URL such as \"https://app.example.com/callback\"`,\n );\n }\n\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n throw new OidcReturnToError(\n uri,\n `refusing ${label} (\"${uri}\"): only http and https URLs may be redirected to`,\n );\n }\n\n if (parsed.username || parsed.password) {\n throw new OidcReturnToError(\n uri,\n `refusing ${label} (\"${uri}\"): it embeds credentials, which disguise the origin it actually points at (${parsed.origin})`,\n );\n }\n\n return uri;\n}\n","import type { AudienceClaims } from \"./audience\";\nimport { OidcTokenError, type TokenKind } from \"./errors\";\n\nexport const DEFAULT_ID_TOKEN_ONLY_CLAIMS: readonly string[] = [\n \"nonce\",\n \"at_hash\",\n \"c_hash\",\n \"s_hash\",\n];\n\nconst ACCESS_TOKEN_TYP = \"application/at+jwt\";\n\nconst NAMED_TOKEN_KINDS = new Map<string, TokenKind | \"other\">([\n [\"access\", \"access\"],\n [\"access_token\", \"access\"],\n [\"bearer\", \"access\"],\n [\"dpop\", \"access\"],\n [\"mac\", \"access\"],\n [\"n_a\", \"access\"],\n [\"at+jwt\", \"access\"],\n [\"id\", \"id\"],\n [\"id_token\", \"id\"],\n [\"id+jwt\", \"id\"],\n [\"logout\", \"other\"],\n [\"logout+jwt\", \"other\"],\n [\"offline\", \"other\"],\n [\"refresh\", \"other\"],\n [\"refresh_token\", \"other\"],\n [\"refresh+jwt\", \"other\"],\n [\"secevent+jwt\", \"other\"],\n [\"serialized-id\", \"other\"],\n]);\n\nfunction namedKind(value: unknown): TokenKind | \"other\" | undefined {\n if (typeof value !== \"string\" || value.length === 0) return undefined;\n const bare = value\n .trim()\n .toLowerCase()\n .replace(/^application\\//, \"\");\n return NAMED_TOKEN_KINDS.get(bare);\n}\n\nfunction normalizeTyp(typ: unknown): string | undefined {\n if (typeof typ !== \"string\" || typ.length === 0) return undefined;\n const lower = typ.toLowerCase();\n return lower.includes(\"/\") ? lower : `application/${lower}`;\n}\n\nexport class OidcTokenTypeError extends OidcTokenError {\n constructor(tokenKind: TokenKind, claim: string, message: string) {\n super(tokenKind, claim, message);\n this.name = \"OidcTokenTypeError\";\n }\n}\n\nexport type TokenTypePolicy = {\n idTokenOnlyClaims: readonly string[];\n accessTokenTyp?: string;\n requireIntrospectedTokenType: boolean;\n};\n\nexport function buildTokenTypePolicy(opts: {\n idTokenOnlyClaims?: readonly string[];\n accessTokenTyp?: string;\n requireIntrospectedTokenType?: boolean;\n}): TokenTypePolicy {\n return {\n idTokenOnlyClaims: opts.idTokenOnlyClaims ?? DEFAULT_ID_TOKEN_ONLY_CLAIMS,\n accessTokenTyp: normalizeTyp(opts.accessTokenTyp),\n requireIntrospectedTokenType: opts.requireIntrospectedTokenType ?? true,\n };\n}\n\nexport function assertTokenTypeFromClaims(\n claims: AudienceClaims,\n tokenKind: TokenKind,\n policy: TokenTypePolicy,\n): void {\n if (tokenKind === \"access\") {\n for (const claim of policy.idTokenOnlyClaims) {\n if (claims[claim] === undefined) continue;\n throw new OidcTokenTypeError(\n \"access\",\n claim,\n `access token carries \"${claim}\", a claim defined for ID tokens only. An ID token must never be accepted as an access token.`,\n );\n }\n }\n\n for (const claim of [\"token_use\", \"typ\", \"token_type\"] as const) {\n const kind = namedKind(claims[claim]);\n if (kind === undefined || kind === tokenKind) continue;\n throw new OidcTokenTypeError(\n tokenKind,\n claim,\n `${tokenKind} token has \"${claim}\" (${String(claims[claim])}), naming ${\n kind === \"other\"\n ? \"neither an access token nor an ID token\"\n : `an ${kind} token`\n }. A token must be the kind it was presented as.`,\n );\n }\n\n if (claims.events !== undefined) {\n throw new OidcTokenTypeError(\n tokenKind,\n \"events\",\n `${tokenKind} token carries \"events\", making it a back-channel logout token rather than ${\n tokenKind === \"id\" ? \"an ID\" : \"an access\"\n } token`,\n );\n }\n}\n\nexport function assertTokenTypeAfterJwtVerify(\n claims: AudienceClaims,\n header: { typ?: string },\n tokenKind: TokenKind,\n policy: TokenTypePolicy,\n): void {\n assertTokenTypeFromClaims(claims, tokenKind, policy);\n const typ = normalizeTyp(header.typ);\n\n if (tokenKind === \"access\" && policy.accessTokenTyp) {\n if (typ !== policy.accessTokenTyp) {\n throw new OidcTokenTypeError(\n \"access\",\n \"typ\",\n `access token \"typ\" header (${typ ?? \"absent\"}) is not the required ${policy.accessTokenTyp}`,\n );\n }\n return;\n }\n\n const named = namedKind(header.typ);\n if (named !== undefined && named !== tokenKind) {\n throw new OidcTokenTypeError(\n tokenKind,\n \"typ\",\n `${tokenKind} token \"typ\" header (${typ}) names ${\n named === \"other\"\n ? \"neither an access token nor an ID token\"\n : `an ${named} token`\n }${\n typ === ACCESS_TOKEN_TYP ? \" (the RFC 9068 access token type)\" : \"\"\n }. A token must be the kind it was presented as.`,\n );\n }\n}\n\nexport function assertIntrospectedAccessToken(\n claims: AudienceClaims,\n policy: TokenTypePolicy,\n): void {\n assertTokenTypeFromClaims(claims, \"access\", policy);\n\n if (introspectedKind(claims) === \"access\") return;\n if (!policy.requireIntrospectedTokenType) return;\n\n throw new OidcTokenTypeError(\n \"access\",\n \"token_type\",\n `introspection response does not name an access token: it carries no recognized \"token_type\", \"typ\" or \"token_use\". RFC 7662 reports a \"token_type\" only for tokens that have one, so a response without it is as consistent with a refresh token as with an access token, and a refresh token must never be accepted as one. Set \"requireIntrospectedTokenType: false\" only if your provider omits the type on genuine access tokens.`,\n );\n}\n\nexport function assertIntrospectedIdToken(\n claims: AudienceClaims,\n policy: TokenTypePolicy,\n): void {\n assertTokenTypeFromClaims(claims, \"id\", policy);\n\n if (introspectedKind(claims) === \"id\") return;\n if (!policy.requireIntrospectedTokenType) return;\n\n throw new OidcTokenTypeError(\n \"id\",\n \"token_type\",\n `introspection response does not name an ID token: it carries no recognized \"token_type\", \"typ\" or \"token_use\". One introspection endpoint answers for every token type an AS issues, so a response that does not say what it describes is as consistent with an access or refresh token as with an ID token, and neither may be accepted as one. Set \"requireIntrospectedTokenType: false\" only if your provider omits the type on genuine ID tokens.`,\n );\n}\n\nfunction introspectedKind(\n claims: AudienceClaims,\n): TokenKind | \"other\" | undefined {\n return [\"token_type\", \"typ\", \"token_use\"]\n .map((claim) => namedKind(claims[claim]))\n .find((kind) => kind !== undefined);\n}\n","import { buildEndSessionUrl } from \"openid-client\";\nimport { OidcLogoutError } from \"../errors\";\nimport { assertSafeRedirectUri } from \"../returnTo\";\nimport type { CoreContext } from \"./context\";\n\nexport function createLogout(ctx: CoreContext) {\n /**\n * Builds the provider's RP-initiated logout URL.\n * @example const url = await oidc.getLogoutUrl({ postLogoutRedirectUri: \"https://app.example.com/\", idTokenHint: id_token });\n */\n return async function getLogoutUrl({\n postLogoutRedirectUri,\n idTokenHint,\n state,\n }: {\n postLogoutRedirectUri: string;\n idTokenHint?: string;\n state?: string;\n }): Promise<URL> {\n assertSafeRedirectUri(postLogoutRedirectUri, \"postLogoutRedirectUri\");\n try {\n return buildEndSessionUrl(ctx.config, {\n post_logout_redirect_uri: postLogoutRedirectUri,\n ...(idTokenHint ? { id_token_hint: idTokenHint } : {}),\n ...(state ? { state } : {}),\n });\n } catch (err) {\n throw new OidcLogoutError(\n `could not build a logout URL for ${ctx.issuer}: ${\n err instanceof Error ? err.message : String(err)\n }. If the issuer advertises no \"end_session_endpoint\" it does not support RP-initiated logout, so you need its own logout URL instead. Destroying your session locally is all this library can do for you.`,\n { cause: err },\n );\n }\n };\n}\n","import {\n decodeJwt,\n decodeProtectedHeader,\n errors,\n type JWTVerifyOptions,\n jwtVerify,\n} from \"jose\";\nimport type { Configuration } from \"openid-client\";\nimport { tokenIntrospection } from \"openid-client\";\nimport {\n type AudienceClaims,\n type AudiencePolicy,\n assertAudienceAfterJwtVerify,\n assertIntrospectedIdTokenAudience,\n assertTokenAudience,\n OidcAudienceError,\n} from \"./audience\";\nimport {\n OidcTokenError,\n type TokenKind,\n type TokenValidationFailure,\n} from \"./errors\";\nimport type { Logger } from \"./logger\";\nimport {\n assertIntrospectedAccessToken,\n assertIntrospectedIdToken,\n assertTokenTypeAfterJwtVerify,\n type TokenTypePolicy,\n} from \"./tokenType\";\nimport type { AccessTokenClaims, IdTokenClaims } from \"./types\";\n\nconst JWS_COMPACT = /^[\\w-]+\\.[\\w-]*\\.[\\w-]+$/;\n\nexport function looksLikeJwt(token: string): boolean {\n if (!JWS_COMPACT.test(token)) return false;\n try {\n return typeof decodeProtectedHeader(token).alg === \"string\";\n } catch {\n return false;\n }\n}\n\nexport function subjectOf(claims: unknown): string | undefined {\n const sub = (claims as { sub?: unknown } | undefined)?.sub;\n return typeof sub === \"string\" && sub.length > 0 ? sub : undefined;\n}\n\nexport function unverifiedSubject(token?: string): string | undefined {\n if (!token || !looksLikeJwt(token)) return undefined;\n try {\n return subjectOf(decodeJwt(token));\n } catch {\n return undefined;\n }\n}\n\nclass StrategyOutcome {\n accessTokenValue: AccessTokenClaims;\n idTokenValue: IdTokenClaims;\n failures: TokenValidationFailure[] = [];\n expired = false;\n fatal: OidcTokenError | undefined;\n\n constructor(private log: Logger) {}\n\n onError(kind: TokenKind, stage: string) {\n return (err: unknown) => {\n if (err instanceof OidcTokenError) {\n this.fatal ??= err;\n return;\n }\n if (\n err instanceof errors.JWTClaimValidationFailed &&\n err.claim === \"aud\"\n ) {\n this.fatal ??= new OidcAudienceError(kind, \"aud\", err.message);\n return;\n }\n if (err instanceof errors.JWTExpired) this.expired = true;\n this.failures.push({ tokenKind: kind, stage, error: err });\n this.log.debug(\n `[oidc] ${kind} token ${stage} failed:`,\n (err as Error).message,\n );\n };\n }\n}\n\nexport async function verifyTokensLocally(\n jwks: Parameters<typeof jwtVerify>[1],\n tokens: { access?: string; id?: string },\n jwtVerifyOptionsFor: (tokenKind: TokenKind) => JWTVerifyOptions,\n tokenTypePolicy: TokenTypePolicy,\n audiencePolicy: AudiencePolicy,\n log: Logger,\n): Promise<StrategyOutcome> {\n const outcome = new StrategyOutcome(log);\n const promises: Promise<void>[] = [];\n\n if (tokens.access) {\n promises.push(\n jwtVerify(tokens.access, jwks, jwtVerifyOptionsFor(\"access\"))\n .then((result) => {\n assertTokenTypeAfterJwtVerify(\n result.payload as AudienceClaims,\n result.protectedHeader,\n \"access\",\n tokenTypePolicy,\n );\n assertAudienceAfterJwtVerify(\n result.payload as AudienceClaims,\n \"access\",\n audiencePolicy,\n );\n outcome.accessTokenValue = result.payload;\n })\n .catch(outcome.onError(\"access\", \"JWT verification\")),\n );\n }\n if (tokens.id) {\n promises.push(\n jwtVerify(tokens.id, jwks, jwtVerifyOptionsFor(\"id\"))\n .then((result) => {\n assertTokenTypeAfterJwtVerify(\n result.payload as AudienceClaims,\n result.protectedHeader,\n \"id\",\n tokenTypePolicy,\n );\n assertAudienceAfterJwtVerify(\n result.payload as AudienceClaims,\n \"id\",\n audiencePolicy,\n );\n outcome.idTokenValue = result.payload;\n })\n .catch(outcome.onError(\"id\", \"JWT verification\")),\n );\n }\n\n await Promise.allSettled(promises);\n if (outcome.fatal) throw outcome.fatal;\n return outcome;\n}\n\nexport async function introspectTokens(\n config: Configuration,\n tokens: { access?: string; id?: string },\n which: { access: boolean; id: boolean },\n tokenTypePolicy: TokenTypePolicy,\n audiencePolicy: AudiencePolicy,\n log: Logger,\n): Promise<StrategyOutcome> {\n const outcome = new StrategyOutcome(log);\n const promises: Promise<void>[] = [];\n\n if (which.access && tokens.access) {\n promises.push(\n tokenIntrospection(config, tokens.access)\n .then((result) => {\n if (!result.active) throw new Error(\"access token is not active\");\n assertIntrospectedAccessToken(\n result as AudienceClaims,\n tokenTypePolicy,\n );\n assertTokenAudience(\n result as AudienceClaims,\n \"access\",\n audiencePolicy,\n );\n outcome.accessTokenValue = result;\n })\n .catch(outcome.onError(\"access\", \"introspection\")),\n );\n }\n if (which.id && tokens.id) {\n promises.push(\n tokenIntrospection(config, tokens.id)\n .then((result) => {\n if (!result.active) throw new Error(\"id token is not active\");\n assertIntrospectedIdToken(result as AudienceClaims, tokenTypePolicy);\n assertIntrospectedIdTokenAudience(\n result as AudienceClaims,\n audiencePolicy,\n );\n outcome.idTokenValue = result;\n })\n .catch(outcome.onError(\"id\", \"introspection\")),\n );\n }\n\n await Promise.allSettled(promises);\n if (outcome.fatal) throw outcome.fatal;\n return outcome;\n}\n\nexport type { StrategyOutcome };\n","import type { JWTPayload } from \"jose\";\nimport type { IntrospectionResponse, UserInfoResponse } from \"openid-client\";\nimport { Decode, type Static, type TSchema, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\nimport { Value } from \"typebox/value\";\nimport { OidcClaimsError, OidcStateError } from \"./errors\";\n\nconst nullable = <T extends TSchema>(t: T) =>\n Type.Optional(Type.Union([Type.Null(), t]));\n\nconst LowercaseEmail = Decode(Type.String(), (s) => s.toLowerCase());\n\n// Some providers (e.g. Cognito) send verification flags as \"true\"/\"false\" strings or 0/1.\nconst VerifiedFlag = Decode(\n Type.Union([Type.Boolean(), Type.String(), Type.Number()]),\n (value): boolean => {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"number\") return value === 1;\n return value.trim().toLowerCase() === \"true\";\n },\n);\n\nconst OIDCUserSchema = Type.Object({\n iss: Type.Optional(Type.String({ minLength: 1 })),\n sub: Type.String({ minLength: 1 }),\n email: nullable(LowercaseEmail),\n email_verified: nullable(VerifiedFlag),\n name: nullable(Type.String()),\n given_name: nullable(Type.String()),\n family_name: nullable(Type.String()),\n middle_name: nullable(Type.String()),\n nickname: nullable(Type.String()),\n preferred_username: nullable(Type.String()),\n profile: nullable(Type.String()),\n picture: nullable(Type.String()),\n website: nullable(Type.String()),\n gender: nullable(Type.String()),\n birthdate: nullable(Type.String()),\n zoneinfo: nullable(Type.String()),\n locale: nullable(Type.String()),\n phone_number: nullable(Type.String()),\n phone_number_verified: nullable(VerifiedFlag),\n address: nullable(\n Type.Object({\n formatted: Type.Optional(Type.String()),\n street_address: Type.Optional(Type.String()),\n locality: Type.Optional(Type.String()),\n region: Type.Optional(Type.String()),\n postal_code: Type.Optional(Type.String()),\n country: Type.Optional(Type.String()),\n }),\n ),\n updated_at: nullable(Type.Number()),\n});\nexport type OIDCUser = Static<typeof OIDCUserSchema>;\nconst CompiledOIDCUser = Compile(OIDCUserSchema);\nconst USER_CLAIM_SCHEMAS = OIDCUserSchema.properties as Record<string, TSchema>;\nconst OPTIONAL_USER_CLAIMS = Object.keys(USER_CLAIM_SCHEMAS).filter(\n (claim) => claim !== \"sub\",\n);\n\nexport function parseOIDCUser(value: unknown): OIDCUser {\n const claims: Record<string, unknown> =\n typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)\n : {};\n\n const candidate: Record<string, unknown> = { sub: claims.sub };\n for (const claim of OPTIONAL_USER_CLAIMS) {\n const supplied = claims[claim];\n if (supplied === undefined) continue;\n const schema = USER_CLAIM_SCHEMAS[claim] as TSchema;\n // A malformed optional claim is dropped rather than failing the whole login.\n if (Value.Check(schema, supplied)) candidate[claim] = supplied;\n }\n\n if (!CompiledOIDCUser.Check(candidate)) {\n const [first] = [...CompiledOIDCUser.Errors(candidate)];\n throw new OidcClaimsError(\n `could not read the validated claims as a user: ${\n first\n ? `${first.instancePath || \"/\"} ${first.message}`\n : \"unknown claim shape\"\n }`,\n );\n }\n return CompiledOIDCUser.Decode(candidate);\n}\n\nconst OIDCFlowStateSchema = Type.Object({\n visitedUrl: Type.String(),\n random: Type.String(),\n nonce: Type.Optional(Type.String()),\n});\nexport type OIDCFlowState = Static<typeof OIDCFlowStateSchema>;\nconst CompiledOIDCFlowState = Compile(OIDCFlowStateSchema);\n\nexport function parseOIDCFlowState(value: string): OIDCFlowState {\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch (err) {\n throw new OidcStateError(\n \"could not read the stored OAuth state: it is not the value startSignin returned. Hand it back exactly as it was stored, unmodified.\",\n { cause: err },\n );\n }\n try {\n return CompiledOIDCFlowState.Decode(CompiledOIDCFlowState.Clean(parsed));\n } catch (err) {\n const [first] = [...CompiledOIDCFlowState.Errors(parsed)];\n throw new OidcStateError(\n `the stored OAuth state is not the shape startSignin produces: ${\n first\n ? `${first.instancePath || \"/\"} ${first.message}`\n : \"unknown state shape\"\n }`,\n { cause: err },\n );\n }\n}\n\nexport type AccessTokenClaims = JWTPayload | IntrospectionResponse | undefined;\nexport type IdTokenClaims =\n | JWTPayload\n | IntrospectionResponse\n | UserInfoResponse\n | undefined;\n\nexport type ValidationResult = {\n user: OIDCUser;\n accessTokenClaims: AccessTokenClaims;\n idTokenClaims: IdTokenClaims;\n};\n\n// A verification flag is only meaningful from the token that supplied its value, so it is never mixed across tokens.\nconst VOUCHED_CLAIMS = [\n [\"email\", \"email_verified\"],\n [\"phone_number\", \"phone_number_verified\"],\n] as const;\n\nexport function mergeTokenClaims(\n accessTokenClaims: Record<string, unknown> | undefined,\n idTokenClaims: Record<string, unknown> | undefined,\n onConflict?: (claim: string) => void,\n): Record<string, unknown> {\n const access = accessTokenClaims ?? {};\n const id = idTokenClaims ?? {};\n const merged: Record<string, unknown> = { ...access, ...id };\n\n for (const [value, flag] of VOUCHED_CLAIMS) {\n if (\n onConflict &&\n access[value] !== undefined &&\n id[value] !== undefined &&\n access[value] !== id[value]\n ) {\n onConflict(value);\n }\n\n const source =\n id[value] !== undefined\n ? id\n : access[value] !== undefined\n ? access\n : undefined;\n\n if (source?.[flag] === undefined) delete merged[flag];\n else merged[flag] = source[flag];\n }\n\n return merged;\n}\n","import type { JWTVerifyOptions } from \"jose\";\nimport type {\n TokenEndpointResponse,\n TokenEndpointResponseHelpers,\n} from \"openid-client\";\nimport {\n type AudienceClaims,\n assertTokenAudience,\n audienceVerifyOption,\n} from \"../audience\";\nimport type { TokenKind } from \"../errors\";\nimport type { CoreContext } from \"./context\";\n\nexport function jwtVerifyOptions(\n ctx: CoreContext,\n tokenKind: TokenKind,\n): JWTVerifyOptions {\n return {\n issuer: ctx.issuer,\n audience: audienceVerifyOption(ctx.audiencePolicy, tokenKind),\n clockTolerance: ctx.clockTolerance,\n algorithms: ctx.signingAlgorithms,\n requiredClaims:\n tokenKind === \"id\"\n ? [\"iss\", \"sub\", \"aud\", \"exp\", \"iat\"]\n : [\"iss\", \"sub\", \"exp\"],\n };\n}\n\nexport function assertGrantedIdToken(\n ctx: CoreContext,\n tokens: TokenEndpointResponse & TokenEndpointResponseHelpers,\n): void {\n const claims = tokens.claims();\n if (claims) {\n assertTokenAudience(claims as AudienceClaims, \"id\", ctx.audiencePolicy);\n }\n}\n","import {\n attachRefreshedTokens,\n OidcInputError,\n OidcSubjectError,\n OidcTokenValidationError,\n type RefreshedTokenSet,\n type TokenKind,\n type TokenValidationFailure,\n} from \"../errors\";\nimport type { Logger } from \"../logger\";\nimport {\n introspectTokens,\n looksLikeJwt,\n subjectOf,\n unverifiedSubject,\n verifyTokensLocally,\n} from \"../tokenValidation\";\nimport {\n type AccessTokenClaims,\n type IdTokenClaims,\n mergeTokenClaims,\n parseOIDCUser,\n} from \"../types\";\nimport type { CoreContext } from \"./context\";\nimport { jwtVerifyOptions } from \"./grant\";\nimport type { ProcessTokensInput, ProcessTokensResult } from \"./options\";\n\nfunction assertOptionalToken(\n value: string | null | undefined,\n label: string,\n): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== \"string\" || value.length === 0) {\n throw new OidcInputError(\n `processTokens was given a malformed \\`${label}\\`: expected a non-empty string, or \\`undefined\\` to omit it, got ${\n value === null ? \"null\" : JSON.stringify(value)\n }. Pass \\`undefined\\`, not \\`null\\`/\\`\"\"\\`, when you don't have this token.`,\n );\n }\n return value;\n}\n\nfunction createSenderConstrainedWarning(log: Logger) {\n let warned = false;\n return (claims: AccessTokenClaims): void => {\n if (warned) return;\n const cnf = (claims as Record<string, unknown> | undefined)?.cnf;\n if (cnf === undefined || cnf === null) return;\n warned = true;\n log.warn(\n '[oidc] this access token carries a \"cnf\" claim: the issuer bound it to a key (DPoP or mTLS), and that binding is not being checked. Validating it needs the proof that travels with the HTTP request, which this library never sees. The token is accepted as an ordinary bearer token, so a stolen one is usable by anyone. Verify the proof at your edge if you accept tokens from callers you do not control.',\n );\n };\n}\n\nexport function createProcessTokens(\n ctx: CoreContext,\n refresh: (args: { refreshToken: string }) => Promise<RefreshedTokenSet>,\n) {\n const warnIfSenderConstrained = createSenderConstrainedWarning(ctx.log);\n\n function worthIntrospecting(token: string): boolean {\n return (\n ctx.introspectionMode !== \"never\" &&\n (ctx.introspectionMode === \"auto\" || !ctx.jwks || !looksLikeJwt(token))\n );\n }\n\n /**\n * Validates the tokens and returns the user, refreshing once if a `refresh_token` is given and validation fails.\n * @example const { user, refreshed, refreshedTokens } = await oidc.processTokens({ access_token, id_token, refresh_token });\n */\n return async function processTokens(\n input: ProcessTokensInput,\n ): Promise<ProcessTokensResult> {\n const access_token = assertOptionalToken(\n input.access_token,\n \"access_token\",\n );\n const id_token = assertOptionalToken(input.id_token, \"id_token\");\n const refresh_token = assertOptionalToken(\n input.refresh_token,\n \"refresh_token\",\n );\n const { subject } = input;\n\n if (!access_token && !id_token) {\n throw new OidcInputError(\n \"processTokens needs an access token, an id token, or both. Validating neither is meaningless\",\n );\n }\n if (subject !== undefined && (typeof subject !== \"string\" || !subject)) {\n throw new OidcInputError(\n \"processTokens was given a `subject` that is not a non-empty string\",\n );\n }\n\n let currentAccessToken = access_token;\n let currentIdToken = id_token;\n let newTokens: RefreshedTokenSet | undefined;\n let accessTokenValue: AccessTokenClaims;\n let idTokenValue: IdTokenClaims;\n let failures: TokenValidationFailure[] = [];\n let boundSubject =\n subject ?? unverifiedSubject(id_token) ?? unverifiedSubject(access_token);\n\n try {\n for (let attempt = 0; attempt < 2; attempt++) {\n accessTokenValue = undefined;\n idTokenValue = undefined;\n failures = [];\n let expired = false;\n\n if (ctx.jwks) {\n const local = await verifyTokensLocally(\n ctx.jwks,\n { access: currentAccessToken, id: currentIdToken },\n (tokenKind) => jwtVerifyOptions(ctx, tokenKind),\n ctx.tokenTypePolicy,\n ctx.audiencePolicy,\n ctx.log,\n );\n accessTokenValue = local.accessTokenValue;\n idTokenValue = local.idTokenValue;\n failures = local.failures;\n expired = local.expired;\n }\n\n const shortcutToRefresh = expired && !!refresh_token;\n\n if (!shortcutToRefresh) {\n const introspectAccess =\n !accessTokenValue &&\n !!currentAccessToken &&\n worthIntrospecting(currentAccessToken);\n const introspectId =\n !idTokenValue &&\n !!currentIdToken &&\n worthIntrospecting(currentIdToken);\n\n if (introspectAccess || introspectId) {\n ctx.log.debug(\n \"[oidc] could not verify tokens locally, trying introspection...\",\n );\n const introspected = await introspectTokens(\n ctx.config,\n { access: currentAccessToken, id: currentIdToken },\n { access: introspectAccess, id: introspectId },\n ctx.tokenTypePolicy,\n ctx.audiencePolicy,\n ctx.log,\n );\n accessTokenValue ??= introspected.accessTokenValue;\n idTokenValue ??= introspected.idTokenValue;\n failures = failures.concat(introspected.failures);\n }\n }\n\n if (!newTokens && !subject) {\n boundSubject =\n subjectOf(accessTokenValue) ??\n subjectOf(idTokenValue) ??\n boundSubject;\n }\n\n const allValidated =\n (!currentAccessToken || !!accessTokenValue) &&\n (!currentIdToken || !!idTokenValue);\n const shouldRefresh = !newTokens && !!refresh_token && !allValidated;\n if (!shouldRefresh) break;\n\n ctx.log.debug(\n expired\n ? \"[oidc] token expired, refreshing directly...\"\n : \"[oidc] a token could not be validated, refreshing as a last resort...\",\n );\n newTokens = await refresh({ refreshToken: refresh_token as string });\n currentAccessToken = newTokens.access_token;\n currentIdToken = newTokens.id_token;\n }\n\n return finalizeProcessTokens({\n currentAccessToken,\n currentIdToken,\n accessTokenValue,\n idTokenValue,\n failures,\n newTokens,\n boundSubject,\n subject,\n issuer: ctx.issuer,\n log: ctx.log,\n warnIfSenderConstrained,\n });\n } catch (err) {\n throw attachRefreshedTokens(err, newTokens);\n }\n };\n}\n\nfunction finalizeProcessTokens({\n currentAccessToken,\n currentIdToken,\n accessTokenValue,\n idTokenValue,\n failures,\n newTokens,\n boundSubject,\n subject,\n issuer,\n log,\n warnIfSenderConstrained,\n}: {\n currentAccessToken: string | undefined;\n currentIdToken: string | undefined;\n accessTokenValue: AccessTokenClaims;\n idTokenValue: IdTokenClaims;\n failures: TokenValidationFailure[];\n newTokens: RefreshedTokenSet | undefined;\n boundSubject: string | undefined;\n subject: string | undefined;\n issuer: string;\n log: Logger;\n warnIfSenderConstrained: (claims: AccessTokenClaims) => void;\n}): ProcessTokensResult {\n const unvalidated: TokenKind[] = [];\n if (currentAccessToken && !accessTokenValue) unvalidated.push(\"access\");\n if (currentIdToken && !idTokenValue) unvalidated.push(\"id\");\n if (unvalidated.length) {\n throw new OidcTokenValidationError(unvalidated, failures);\n }\n\n const accessSub = subjectOf(accessTokenValue);\n const idSub = subjectOf(idTokenValue);\n if (accessSub && idSub && accessSub !== idSub) {\n throw new OidcSubjectError(\n `subject in access token and id token do not match (${accessSub} vs ${idSub})`,\n accessSub,\n idSub,\n );\n }\n\n const finalSubject = accessSub ?? idSub;\n if (\n newTokens &&\n boundSubject &&\n finalSubject &&\n finalSubject !== boundSubject\n ) {\n throw new OidcSubjectError(\n `refresh returned a token set for a different subject (${finalSubject}) than the tokens it replaced (${boundSubject}). The refresh token does not belong to this session`,\n boundSubject,\n finalSubject,\n );\n }\n\n if (subject && finalSubject && finalSubject !== subject) {\n throw new OidcSubjectError(\n `the tokens describe subject ${finalSubject}, not the ${subject} they were presented for`,\n subject,\n finalSubject,\n );\n }\n\n if (newTokens && !boundSubject) {\n log.warn(\n \"[oidc] refreshed a token set whose original subject could not be determined. The supplied tokens were opaque or unreadable, so the refreshed set could not be checked against them. Pass `subject` to processTokens to enforce it.\",\n );\n }\n\n warnIfSenderConstrained(accessTokenValue);\n\n const base = {\n user: parseOIDCUser({\n ...mergeTokenClaims(\n accessTokenValue as Record<string, unknown> | undefined,\n idTokenValue as Record<string, unknown> | undefined,\n (claim) =>\n log.warn(\n `[oidc] the access token and the id token disagree on \"${claim}\" for subject ${finalSubject ?? \"(unknown)\"}. Using the id token's value, and dropping any verification flag that did not come with it. One of the two is stale.`,\n ),\n ),\n iss: issuer,\n }),\n accessTokenClaims: accessTokenValue,\n idTokenClaims: idTokenValue,\n };\n\n if (newTokens) {\n return { ...base, refreshed: true, refreshedTokens: newTokens };\n }\n return { ...base, refreshed: false };\n}\n","import { refreshTokenGrant } from \"openid-client\";\nimport {\n OidcGrantError,\n OidcInputError,\n OidcSubjectError,\n type RefreshedTokenSet,\n} from \"../errors\";\nimport { subjectOf } from \"../tokenValidation\";\nimport type { CoreContext } from \"./context\";\nimport { assertGrantedIdToken } from \"./grant\";\n\nexport function createRefresh(ctx: CoreContext) {\n /**\n * Exchanges a refresh token for a new token set.\n * @example const tokens = await oidc.refresh({ refreshToken, expectedSubject: user.sub });\n */\n return async function refresh({\n refreshToken,\n expectedSubject,\n }: {\n refreshToken: string;\n expectedSubject?: string;\n }): Promise<RefreshedTokenSet> {\n if (\n expectedSubject !== undefined &&\n (typeof expectedSubject !== \"string\" || !expectedSubject)\n ) {\n throw new OidcInputError(\n \"refresh was given an `expectedSubject` that is not a non-empty string\",\n );\n }\n\n let tokens: RefreshedTokenSet;\n try {\n tokens = await refreshTokenGrant(ctx.config, refreshToken);\n } catch (err) {\n throw new OidcGrantError(\n \"refresh_token\",\n `could not exchange the refresh token: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n assertGrantedIdToken(ctx, tokens);\n\n if (expectedSubject) {\n const actual = subjectOf(tokens.claims());\n if (!actual) {\n ctx.log.warn(\n \"[oidc] refresh could not be checked against the expected subject: the provider returned no id token to read one from. The new token set is returned unchecked.\",\n );\n } else if (actual !== expectedSubject) {\n throw new OidcSubjectError(\n `refresh returned a token set for a different subject (${actual}) than the ${expectedSubject} it was asked for. The refresh token does not belong to this session`,\n expectedSubject,\n actual,\n );\n }\n }\n\n return tokens;\n };\n}\n","import {\n authorizationCodeGrant,\n buildAuthorizationUrl,\n calculatePKCECodeChallenge,\n randomNonce,\n randomPKCECodeVerifier,\n randomState,\n} from \"openid-client\";\nimport {\n OidcGrantError,\n OidcInputError,\n type RefreshedTokenSet,\n} from \"../errors\";\nimport { assertSafeRedirectUri, assertSafeReturnTo } from \"../returnTo\";\nimport { parseOIDCFlowState } from \"../types\";\nimport type { CoreContext } from \"./context\";\nimport { assertGrantedIdToken } from \"./grant\";\nimport type { ResolveSigninResult, StartSigninResult } from \"./options\";\n\nexport function createSignin(ctx: CoreContext) {\n /**\n * Builds the authorization URL. Store `codeVerifier` and `state` until the callback.\n * @example const { authorizationUrl, codeVerifier, state } = await oidc.startSignin({ redirectUri, returnTo: \"/\" });\n */\n async function startSignin({\n redirectUri,\n returnTo,\n scope = \"openid profile email offline_access\",\n }: {\n redirectUri: string;\n returnTo: string;\n scope?: string;\n }): Promise<StartSigninResult> {\n assertSafeReturnTo(returnTo, ctx.returnToPolicy);\n assertSafeRedirectUri(redirectUri, \"redirectUri\");\n\n if (!scope.split(/\\s+/).includes(\"openid\")) {\n throw new OidcInputError(\n `invalid scope (\"${scope}\"): it must include \"openid\"`,\n );\n }\n\n const codeVerifier = randomPKCECodeVerifier();\n const codeChallenge = await calculatePKCECodeChallenge(codeVerifier);\n const nonce = randomNonce();\n const state = JSON.stringify({\n visitedUrl: returnTo,\n random: randomState(),\n nonce,\n });\n\n const authorizationUrl = buildAuthorizationUrl(ctx.config, {\n redirect_uri: redirectUri,\n scope,\n code_challenge: codeChallenge,\n code_challenge_method: \"S256\",\n state,\n nonce,\n });\n\n return { codeVerifier, authorizationUrl, state };\n }\n\n /**\n * Exchanges the callback's code for tokens and returns the `returnTo` passed to `startSignin`.\n * @example const { tokens, returnTo } = await oidc.resolveSignin({ callbackUrl: new URL(req.url), codeVerifier, expectedState: state });\n */\n async function resolveSignin({\n callbackUrl,\n codeVerifier,\n expectedState,\n }: {\n callbackUrl: URL;\n codeVerifier: string;\n expectedState: string;\n }): Promise<ResolveSigninResult> {\n if (typeof codeVerifier !== \"string\" || codeVerifier.length === 0) {\n throw new OidcInputError(\n \"resolveSignin was given no PKCE code verifier. Pass the `codeVerifier` startSignin returned, exactly as it was stored.\",\n );\n }\n const parsedState = parseOIDCFlowState(expectedState);\n const returnTo = assertSafeReturnTo(\n parsedState.visitedUrl,\n ctx.returnToPolicy,\n );\n\n let tokens: RefreshedTokenSet;\n try {\n tokens = await authorizationCodeGrant(ctx.config, callbackUrl, {\n pkceCodeVerifier: codeVerifier,\n expectedState,\n expectedNonce: parsedState.nonce,\n idTokenExpected: true,\n });\n } catch (err) {\n throw new OidcGrantError(\n \"authorization_code\",\n `could not complete the login: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n assertGrantedIdToken(ctx, tokens);\n return { tokens, returnTo };\n }\n\n return { startSignin, resolveSignin };\n}\n","import { fetchUserInfo } from \"openid-client\";\nimport { OidcInputError, OidcUserInfoError } from \"../errors\";\nimport type { CoreContext } from \"./context\";\n\nexport function createUserInfoFetcher(ctx: CoreContext) {\n /**\n * Fetches the UserInfo endpoint, checking the response is for `expectedSubject`.\n * @example const info = await oidc.fetchUserInfoFromIssuer({ accessToken, expectedSubject: user.sub });\n */\n return async function fetchUserInfoFromIssuer({\n accessToken,\n expectedSubject,\n }: {\n accessToken: string;\n expectedSubject: string;\n }) {\n if (typeof expectedSubject !== \"string\" || !expectedSubject) {\n throw new OidcInputError(\n \"fetchUserInfoFromIssuer needs the `sub` this token set was validated for, as a non-empty string. The response is only meaningful once it is known to describe that subject\",\n );\n }\n try {\n return await fetchUserInfo(ctx.config, accessToken, expectedSubject);\n } catch (err) {\n throw new OidcUserInfoError(\n `could not fetch UserInfo claims for subject ${expectedSubject}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err },\n );\n }\n };\n}\n","import { createRemoteJWKSet } from \"jose\";\nimport {\n allowInsecureRequests,\n clockTolerance as clockToleranceOption,\n discovery,\n} from \"openid-client\";\nimport { buildAudiencePolicy } from \"../audience\";\nimport {\n assertDiscoveredIssuer,\n assertPkceSupported,\n resolveClockTolerance,\n resolveDevelopment,\n resolveJwksUri,\n resolveSigningAlgorithms,\n} from \"../discovery\";\nimport { buildLogger } from \"../logger\";\nimport { buildReturnToPolicy } from \"../returnTo\";\nimport { buildTokenTypePolicy } from \"../tokenType\";\nimport type { CoreContext } from \"./context\";\nimport { createLogout } from \"./logout\";\nimport { createProcessTokens } from \"./processTokens\";\nimport { createRefresh } from \"./refresh\";\nimport { createSignin } from \"./signin\";\nimport { createUserInfoFetcher } from \"./userInfo\";\n\nexport {\n assertDiscoveredIssuer,\n assertPkceSupported,\n DEFAULT_SIGNING_ALGORITHMS,\n resolveClockTolerance,\n resolveDevelopment,\n resolveJwksUri,\n} from \"../discovery\";\nexport type {\n OidcCoreOptions,\n ProcessTokensInput,\n ProcessTokensResult,\n ResolveSigninResult,\n StartSigninResult,\n} from \"./options\";\n\nimport type { OidcCoreOptions } from \"./options\";\n\n/**\n * Discovers the issuer and returns the sign-in, validation, refresh and logout functions.\n * @example const oidc = await createOidcCore({ issuer: \"https://auth.example.com\", clientId: \"my-app\" });\n */\nexport async function createOidcCore(opts: OidcCoreOptions) {\n const log = buildLogger(opts.logger, opts.logLevel);\n const development = resolveDevelopment(opts.development);\n\n if (development) {\n log.warn(\n \"[oidc] development mode is on: plain-HTTP requests to the IdP are allowed. Never enable this in production.\",\n );\n }\n\n if (typeof opts.clientId !== \"string\" || opts.clientId.length === 0) {\n throw new TypeError(\n \"invalid clientId: expected a non-empty string. It is what every token is bound to, so there is nothing this library could check without it.\",\n );\n }\n\n if (opts.verifyAudience && opts.expectedAudience !== undefined) {\n log.warn(\n '[oidc] both \"verifyAudience\" and \"expectedAudience\" are set. \"verifyAudience\" replaces the audience policy entirely, so \"expectedAudience\" is not checked at all. Assert it inside your callback, or drop one of the two.',\n );\n }\n\n const clockTolerance = resolveClockTolerance(opts.clockTolerance);\n\n const config = await discovery(\n new URL(opts.issuer),\n opts.clientId,\n {\n client_secret: opts.clientSecret,\n token_endpoint_auth_method: opts.clientSecret ? undefined : \"none\",\n [clockToleranceOption]: clockTolerance,\n },\n undefined,\n { execute: development ? [allowInsecureRequests] : [] },\n );\n\n assertDiscoveredIssuer(opts.issuer, config.serverMetadata().issuer);\n\n assertPkceSupported(\n config.serverMetadata().code_challenge_methods_supported,\n opts.clientSecret,\n log,\n );\n\n const jwksUri = config.serverMetadata().jwks_uri;\n const jwks = jwksUri\n ? createRemoteJWKSet(resolveJwksUri(jwksUri, development))\n : undefined;\n const issuer = config.serverMetadata().issuer;\n\n if (!jwksUri) {\n log.warn(\n `[oidc] the issuer advertises no \"jwks_uri\", so no token can be verified offline. Every validation will fall back to remote introspection${\n (opts.introspection ?? \"opaque-only\") === \"never\"\n ? \", which \\\"introspection: 'never'\\\" has switched off, so no token will validate at all\"\n : \", one round trip to the IdP per request\"\n }.`,\n );\n }\n\n const audiencePolicy = buildAudiencePolicy(opts);\n const ctx: CoreContext = {\n config,\n log,\n issuer,\n jwks,\n audiencePolicy,\n tokenTypePolicy: buildTokenTypePolicy(opts),\n returnToPolicy: buildReturnToPolicy(opts),\n introspectionMode: opts.introspection ?? \"opaque-only\",\n clockTolerance,\n signingAlgorithms: resolveSigningAlgorithms(\n config,\n opts.signingAlgorithms,\n log,\n ),\n };\n\n const { startSignin, resolveSignin } = createSignin(ctx);\n const refresh = createRefresh(ctx);\n const processTokens = createProcessTokens(ctx, refresh);\n const getLogoutUrl = createLogout(ctx);\n const fetchUserInfoFromIssuer = createUserInfoFetcher(ctx);\n\n return {\n configuration: config,\n startSignin,\n resolveSignin,\n processTokens,\n refresh,\n getLogoutUrl,\n fetchUserInfoFromIssuer,\n };\n}\n\nexport type OidcCore = Awaited<ReturnType<typeof createOidcCore>>;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m1212e/oidc",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"module": "./out/index.mjs",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": "https://github.com/m1212e/oidc",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.12.0"
|
|
9
|
+
},
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"files": [
|
|
12
|
+
"out"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"format": "bun run lint",
|
|
16
|
+
"lint": "bunx biome check --write .",
|
|
17
|
+
"build": "tsdown",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"test:types": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@biomejs/biome": "^2.6.3",
|
|
23
|
+
"@types/bun": "^1.4.4",
|
|
24
|
+
"@types/node": "^26.6.5",
|
|
25
|
+
"@types/oidc-provider": "^9.12.1",
|
|
26
|
+
"lefthook": "^2.2.2",
|
|
27
|
+
"oidc-provider": "9.13.0",
|
|
28
|
+
"rolldown-plugin-dts": "^0.28.8",
|
|
29
|
+
"tsdown": "^0.22.14",
|
|
30
|
+
"typescript": "^7.0.2"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"jose": "^6.2.13",
|
|
34
|
+
"openid-client": "^6.8.8",
|
|
35
|
+
"typebox": "^1.4.3"
|
|
36
|
+
},
|
|
37
|
+
"main": "./out/index.cjs",
|
|
38
|
+
"types": "./out/index.d.cts",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"import": "./out/index.mjs",
|
|
42
|
+
"require": "./out/index.cjs"
|
|
43
|
+
},
|
|
44
|
+
"./package.json": "./package.json"
|
|
45
|
+
},
|
|
46
|
+
"inlinedDependencies": {
|
|
47
|
+
"oauth4webapi": "3.8.8"
|
|
48
|
+
}
|
|
49
|
+
}
|