module.exports = [ "[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const { format } = __turbopack_context__.r("[externals]/util [external] (util, cjs)"); class OPError extends Error { constructor({ error_description, error, error_uri, session_state, state, scope }, response){ super(!error_description ? error : `${error} (${error_description})`); Object.assign(this, { error }, error_description && { error_description }, error_uri && { error_uri }, state && { state }, scope && { scope }, session_state && { session_state }); if (response) { Object.defineProperty(this, 'response', { value: response }); } this.name = this.constructor.name; Error.captureStackTrace(this, this.constructor); } } class RPError extends Error { constructor(...args){ if (typeof args[0] === 'string') { super(format(...args)); } else { const { message, printf, response, ...rest } = args[0]; if (printf) { super(format(...printf)); } else { super(message); } Object.assign(this, rest); if (response) { Object.defineProperty(this, 'response', { value: response }); } } this.name = this.constructor.name; Error.captureStackTrace(this, this.constructor); } } module.exports = { OPError, RPError }; }), "[project]/node_modules/openid-client/lib/helpers/is_key_object.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const util = __turbopack_context__.r("[externals]/util [external] (util, cjs)"); const crypto = __turbopack_context__.r("[externals]/crypto [external] (crypto, cjs)"); module.exports = util.types.isKeyObject || ((obj)=>obj && obj instanceof crypto.KeyObject); }), "[project]/node_modules/openid-client/lib/helpers/base64url.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { let encode; if (Buffer.isEncoding('base64url')) { encode = (input, encoding = 'utf8')=>Buffer.from(input, encoding).toString('base64url'); } else { const fromBase64 = (base64)=>base64.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); encode = (input, encoding = 'utf8')=>fromBase64(Buffer.from(input, encoding).toString('base64')); } const decode = (input)=>Buffer.from(input, 'base64'); module.exports.decode = decode; module.exports.encode = encode; }), "[project]/node_modules/openid-client/lib/helpers/decode_jwt.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const base64url = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/base64url.js [app-route] (ecmascript)"); module.exports = (token)=>{ if (typeof token !== 'string' || !token) { throw new TypeError('JWT must be a string'); } const { 0: header, 1: payload, 2: signature, length } = token.split('.'); if (length === 5) { throw new TypeError('encrypted JWTs cannot be decoded'); } if (length !== 3) { throw new Error('JWTs must have three components'); } try { return { header: JSON.parse(base64url.decode(header)), payload: JSON.parse(base64url.decode(payload)), signature }; } catch (err) { throw new Error('JWT is malformed'); } }; }), "[project]/node_modules/openid-client/lib/helpers/is_plain_object.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { module.exports = (a)=>!!a && a.constructor === Object; }), "[project]/node_modules/openid-client/lib/helpers/defaults.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const isPlainObject = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/is_plain_object.js [app-route] (ecmascript)"); function defaults(deep, target, ...sources) { for (const source of sources){ if (!isPlainObject(source)) { continue; } for (const [key, value] of Object.entries(source)){ /* istanbul ignore if */ if (key === '__proto__' || key === 'constructor') { continue; } if (typeof target[key] === 'undefined' && typeof value !== 'undefined') { target[key] = value; } if (deep && isPlainObject(target[key]) && isPlainObject(value)) { defaults(true, target[key], value); } } } return target; } module.exports = defaults.bind(undefined, false); module.exports.deep = defaults.bind(undefined, true); }), "[project]/node_modules/openid-client/lib/helpers/www_authenticate_parser.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const REGEXP = /(\w+)=("[^"]*")/g; module.exports = (wwwAuthenticate)=>{ const params = {}; try { while(REGEXP.exec(wwwAuthenticate) !== null){ if (RegExp.$1 && RegExp.$2) { params[RegExp.$1] = RegExp.$2.slice(1, -1); } } } catch (err) {} return params; }; }), "[project]/node_modules/openid-client/lib/helpers/assert.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { function assertSigningAlgValuesSupport(endpoint, issuer, properties) { if (!issuer[`${endpoint}_endpoint`]) return; const eam = `${endpoint}_endpoint_auth_method`; const easa = `${endpoint}_endpoint_auth_signing_alg`; const easavs = `${endpoint}_endpoint_auth_signing_alg_values_supported`; if (properties[eam] && properties[eam].endsWith('_jwt') && !properties[easa] && !issuer[easavs]) { throw new TypeError(`${easavs} must be configured on the issuer if ${easa} is not defined on a client`); } } function assertIssuerConfiguration(issuer, endpoint) { if (!issuer[endpoint]) { throw new TypeError(`${endpoint} must be configured on the issuer`); } } module.exports = { assertSigningAlgValuesSupport, assertIssuerConfiguration }; }), "[project]/node_modules/openid-client/lib/helpers/pick.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { module.exports = function pick(object, ...paths) { const obj = {}; for (const path of paths){ if (object[path] !== undefined) { obj[path] = object[path]; } } return obj; }; }), "[project]/node_modules/openid-client/lib/helpers/process_response.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const { STATUS_CODES } = __turbopack_context__.r("[externals]/http [external] (http, cjs)"); const { format } = __turbopack_context__.r("[externals]/util [external] (util, cjs)"); const { OPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const parseWwwAuthenticate = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/www_authenticate_parser.js [app-route] (ecmascript)"); const throwAuthenticateErrors = (response)=>{ const params = parseWwwAuthenticate(response.headers['www-authenticate']); if (params.error) { throw new OPError(params, response); } }; const isStandardBodyError = (response)=>{ let result = false; try { let jsonbody; if (typeof response.body !== 'object' || Buffer.isBuffer(response.body)) { jsonbody = JSON.parse(response.body); } else { jsonbody = response.body; } result = typeof jsonbody.error === 'string' && jsonbody.error.length; if (result) Object.defineProperty(response, 'body', { value: jsonbody, configurable: true }); } catch (err) {} return result; }; function processResponse(response, { statusCode = 200, body = true, bearer = false } = {}) { if (response.statusCode !== statusCode) { if (bearer) { throwAuthenticateErrors(response); } if (isStandardBodyError(response)) { throw new OPError(response.body, response); } throw new OPError({ error: format('expected %i %s, got: %i %s', statusCode, STATUS_CODES[statusCode], response.statusCode, STATUS_CODES[response.statusCode]) }, response); } if (body && !response.body) { throw new OPError({ error: format('expected %i %s with body but no body was returned', statusCode, STATUS_CODES[statusCode]) }, response); } return response.body; } module.exports = processResponse; }), "[project]/node_modules/openid-client/lib/helpers/unix_timestamp.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { module.exports = ()=>Math.floor(Date.now() / 1000); }), "[project]/node_modules/openid-client/lib/token_set.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const base64url = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/base64url.js [app-route] (ecmascript)"); const now = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/unix_timestamp.js [app-route] (ecmascript)"); class TokenSet { constructor(values){ Object.assign(this, values); const { constructor, ...properties } = Object.getOwnPropertyDescriptors(this.constructor.prototype); Object.defineProperties(this, properties); } set expires_in(value) { this.expires_at = now() + Number(value); } get expires_in() { return Math.max.apply(null, [ this.expires_at - now(), 0 ]); } expired() { return this.expires_in === 0; } claims() { if (!this.id_token) { throw new TypeError('id_token not present in TokenSet'); } return JSON.parse(base64url.decode(this.id_token.split('.')[1])); } } module.exports = TokenSet; }), "[project]/node_modules/openid-client/lib/helpers/generators.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const { createHash, randomBytes } = __turbopack_context__.r("[externals]/crypto [external] (crypto, cjs)"); const base64url = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/base64url.js [app-route] (ecmascript)"); const random = (bytes = 32)=>base64url.encode(randomBytes(bytes)); module.exports = { random, state: random, nonce: random, codeVerifier: random, codeChallenge: (codeVerifier)=>base64url.encode(createHash('sha256').update(codeVerifier).digest()) }; }), "[project]/node_modules/openid-client/package.json.[json].cjs [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { module.exports = { "name": "openid-client", "version": "5.7.1", "description": "OpenID Connect Relying Party (RP, Client) implementation for Node.js runtime, supports passportjs", "keywords": [ "auth", "authentication", "basic", "certified", "client", "connect", "dynamic", "electron", "hybrid", "identity", "implicit", "oauth", "oauth2", "oidc", "openid", "passport", "relying party", "strategy" ], "homepage": "https://github.com/panva/openid-client", "repository": "panva/openid-client", "funding": { "url": "https://github.com/sponsors/panva" }, "license": "MIT", "author": "Filip Skokan ", "exports": { "types": "./types/index.d.ts", "import": "./lib/index.mjs", "require": "./lib/index.js" }, "main": "./lib/index.js", "types": "./types/index.d.ts", "files": [ "lib", "types/index.d.ts" ], "scripts": { "format": "npx prettier --loglevel silent --write ./lib ./test ./certification ./types", "test": "mocha test/**/*.test.js" }, "dependencies": { "jose": "^4.15.9", "lru-cache": "^6.0.0", "object-hash": "^2.2.0", "oidc-token-hash": "^5.0.3" }, "devDependencies": { "@types/node": "^16.18.106", "@types/passport": "^1.0.16", "base64url": "^3.0.1", "chai": "^4.5.0", "mocha": "^10.7.3", "nock": "^13.5.5", "prettier": "^2.8.8", "readable-mock-req": "^0.2.2", "sinon": "^9.2.4", "timekeeper": "^2.3.1" }, "standard-version": { "scripts": { "postchangelog": "sed -i '' -e 's/### \\[/## [/g' CHANGELOG.md" }, "types": [ { "type": "feat", "section": "Features" }, { "type": "fix", "section": "Fixes" }, { "type": "chore", "hidden": true }, { "type": "docs", "hidden": true }, { "type": "style", "hidden": true }, { "type": "refactor", "section": "Refactor", "hidden": false }, { "type": "perf", "section": "Performance", "hidden": false }, { "type": "test", "hidden": true } ] } }; }), "[project]/node_modules/openid-client/lib/helpers/consts.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const HTTP_OPTIONS = Symbol(); const CLOCK_TOLERANCE = Symbol(); module.exports = { CLOCK_TOLERANCE, HTTP_OPTIONS }; }), "[project]/node_modules/openid-client/lib/helpers/request.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const assert = __turbopack_context__.r("[externals]/assert [external] (assert, cjs)"); const querystring = __turbopack_context__.r("[externals]/querystring [external] (querystring, cjs)"); const http = __turbopack_context__.r("[externals]/http [external] (http, cjs)"); const https = __turbopack_context__.r("[externals]/https [external] (https, cjs)"); const { once } = __turbopack_context__.r("[externals]/events [external] (events, cjs)"); const { URL } = __turbopack_context__.r("[externals]/url [external] (url, cjs)"); const LRU = __turbopack_context__.r("[project]/node_modules/openid-client/node_modules/lru-cache/index.js [app-route] (ecmascript)"); const pkg = __turbopack_context__.r("[project]/node_modules/openid-client/package.json.[json].cjs [app-route] (ecmascript)"); const { RPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const pick = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/pick.js [app-route] (ecmascript)"); const { deep: defaultsDeep } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/defaults.js [app-route] (ecmascript)"); const { HTTP_OPTIONS } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/consts.js [app-route] (ecmascript)"); let DEFAULT_HTTP_OPTIONS; const NQCHAR = /^[\x21\x23-\x5B\x5D-\x7E]+$/; const allowed = [ 'agent', 'ca', 'cert', 'crl', 'headers', 'key', 'lookup', 'passphrase', 'pfx', 'timeout' ]; const setDefaults = (props, options)=>{ DEFAULT_HTTP_OPTIONS = defaultsDeep({}, props.length ? pick(options, ...props) : options, DEFAULT_HTTP_OPTIONS); }; setDefaults([], { headers: { 'User-Agent': `${pkg.name}/${pkg.version} (${pkg.homepage})`, 'Accept-Encoding': 'identity' }, timeout: 3500 }); function send(req, body, contentType) { if (contentType) { req.removeHeader('content-type'); req.setHeader('content-type', contentType); } if (body) { req.removeHeader('content-length'); req.setHeader('content-length', Buffer.byteLength(body)); req.write(body); } req.end(); } const nonces = new LRU({ max: 100 }); module.exports = async function request(options, { accessToken, mTLS = false, DPoP } = {}) { let url; try { url = new URL(options.url); delete options.url; assert(/^(https?:)$/.test(url.protocol)); } catch (err) { throw new TypeError('only valid absolute URLs can be requested'); } const optsFn = this[HTTP_OPTIONS]; let opts = options; const nonceKey = `${url.origin}${url.pathname}`; if (DPoP && 'dpopProof' in this) { opts.headers = opts.headers || {}; opts.headers.DPoP = await this.dpopProof({ htu: `${url.origin}${url.pathname}`, htm: options.method || 'GET', nonce: nonces.get(nonceKey) }, DPoP, accessToken); } let userOptions; if (optsFn) { userOptions = pick(optsFn.call(this, url, defaultsDeep({}, opts, DEFAULT_HTTP_OPTIONS)), ...allowed); } opts = defaultsDeep({}, userOptions, opts, DEFAULT_HTTP_OPTIONS); if (mTLS && !opts.pfx && !(opts.key && opts.cert)) { throw new TypeError('mutual-TLS certificate and key not set'); } if (opts.searchParams) { for (const [key, value] of Object.entries(opts.searchParams)){ url.searchParams.delete(key); url.searchParams.set(key, value); } } let responseType; let form; let json; let body; ({ form, responseType, json, body, ...opts } = opts); for (const [key, value] of Object.entries(opts.headers || {})){ if (value === undefined) { delete opts.headers[key]; } } let response; const req = (url.protocol === 'https:' ? https.request : http.request)(url.href, opts); return (async ()=>{ if (json) { send(req, JSON.stringify(json), 'application/json'); } else if (form) { send(req, querystring.stringify(form), 'application/x-www-form-urlencoded'); } else if (body) { send(req, body); } else { send(req); } [response] = await Promise.race([ once(req, 'response'), once(req, 'timeout') ]); // timeout reached if (!response) { req.destroy(); throw new RPError(`outgoing request timed out after ${opts.timeout}ms`); } const parts = []; for await (const part of response){ parts.push(part); } if (parts.length) { switch(responseType){ case 'json': { Object.defineProperty(response, 'body', { get () { let value = Buffer.concat(parts); try { value = JSON.parse(value); } catch (err) { Object.defineProperty(err, 'response', { value: response }); throw err; } finally{ Object.defineProperty(response, 'body', { value, configurable: true }); } return value; }, configurable: true }); break; } case undefined: case 'buffer': { Object.defineProperty(response, 'body', { get () { const value = Buffer.concat(parts); Object.defineProperty(response, 'body', { value, configurable: true }); return value; }, configurable: true }); break; } default: throw new TypeError('unsupported responseType request option'); } } return response; })().catch((err)=>{ if (response) Object.defineProperty(err, 'response', { value: response }); throw err; }).finally(()=>{ const dpopNonce = response && response.headers['dpop-nonce']; if (dpopNonce && NQCHAR.test(dpopNonce)) { nonces.set(nonceKey, dpopNonce); } }); }; module.exports.setDefaults = setDefaults.bind(undefined, allowed); }), "[project]/node_modules/openid-client/lib/helpers/weak_cache.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { module.exports.keystores = new WeakMap(); }), "[project]/node_modules/openid-client/lib/helpers/deep_clone.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { module.exports = globalThis.structuredClone || ((obj)=>JSON.parse(JSON.stringify(obj))); }), "[project]/node_modules/openid-client/lib/helpers/keystore.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const jose = __turbopack_context__.r("[project]/node_modules/jose/dist/node/cjs/index.js [app-route] (ecmascript)"); const clone = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/deep_clone.js [app-route] (ecmascript)"); const isPlainObject = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/is_plain_object.js [app-route] (ecmascript)"); const internal = Symbol(); const keyscore = (key, { alg, use })=>{ let score = 0; if (alg && key.alg) { score++; } if (use && key.use) { score++; } return score; }; function getKtyFromAlg(alg) { switch(typeof alg === 'string' && alg.slice(0, 2)){ case 'RS': case 'PS': return 'RSA'; case 'ES': return 'EC'; case 'Ed': return 'OKP'; default: return undefined; } } function getAlgorithms(use, alg, kty, crv) { // Ed25519, Ed448, and secp256k1 always have "alg" // OKP always has "use" if (alg) { return new Set([ alg ]); } switch(kty){ case 'EC': { let algs = []; if (use === 'enc' || use === undefined) { algs = algs.concat([ 'ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW' ]); } if (use === 'sig' || use === undefined) { switch(crv){ case 'P-256': case 'P-384': algs = algs.concat([ `ES${crv.slice(-3)}` ]); break; case 'P-521': algs = algs.concat([ 'ES512' ]); break; case 'secp256k1': if (jose.cryptoRuntime === 'node:crypto') { algs = algs.concat([ 'ES256K' ]); } break; } } return new Set(algs); } case 'OKP': { return new Set([ 'ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW' ]); } case 'RSA': { let algs = []; if (use === 'enc' || use === undefined) { algs = algs.concat([ 'RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512' ]); if (jose.cryptoRuntime === 'node:crypto') { algs = algs.concat([ 'RSA1_5' ]); } } if (use === 'sig' || use === undefined) { algs = algs.concat([ 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512' ]); } return new Set(algs); } default: throw new Error('unreachable'); } } module.exports = class KeyStore { #keys; constructor(i, keys){ if (i !== internal) throw new Error('invalid constructor call'); this.#keys = keys; } toJWKS() { return { keys: this.map(({ jwk: { d, p, q, dp, dq, qi, ...jwk } })=>jwk) }; } all({ alg, kid, use } = {}) { if (!use || !alg) { throw new Error(); } const kty = getKtyFromAlg(alg); const search = { alg, use }; return this.filter((key)=>{ let candidate = true; if (candidate && kty !== undefined && key.jwk.kty !== kty) { candidate = false; } if (candidate && kid !== undefined && key.jwk.kid !== kid) { candidate = false; } if (candidate && use !== undefined && key.jwk.use !== undefined && key.jwk.use !== use) { candidate = false; } if (candidate && key.jwk.alg && key.jwk.alg !== alg) { candidate = false; } else if (!key.algorithms.has(alg)) { candidate = false; } return candidate; }).sort((first, second)=>keyscore(second, search) - keyscore(first, search)); } get(...args) { return this.all(...args)[0]; } static async fromJWKS(jwks, { onlyPublic = false, onlyPrivate = false } = {}) { if (!isPlainObject(jwks) || !Array.isArray(jwks.keys) || jwks.keys.some((k)=>!isPlainObject(k) || !('kty' in k))) { throw new TypeError('jwks must be a JSON Web Key Set formatted object'); } const keys = []; for (let jwk of jwks.keys){ jwk = clone(jwk); const { kty, kid, crv } = jwk; let { alg, use } = jwk; if (typeof kty !== 'string' || !kty) { continue; } if (use !== undefined && use !== 'sig' && use !== 'enc') { continue; } if (typeof alg !== 'string' && alg !== undefined) { continue; } if (typeof kid !== 'string' && kid !== undefined) { continue; } if (kty === 'EC' && use === 'sig') { switch(crv){ case 'P-256': alg = 'ES256'; break; case 'P-384': alg = 'ES384'; break; case 'P-521': alg = 'ES512'; break; default: break; } } if (crv === 'secp256k1') { use = 'sig'; alg = 'ES256K'; } if (kty === 'OKP') { switch(crv){ case 'Ed25519': case 'Ed448': use = 'sig'; alg = 'EdDSA'; break; case 'X25519': case 'X448': use = 'enc'; break; default: break; } } if (alg && !use) { switch(true){ case alg.startsWith('ECDH'): use = 'enc'; break; case alg.startsWith('RSA'): use = 'enc'; break; default: break; } } if (onlyPrivate && (jwk.kty === 'oct' || !jwk.d)) { throw new Error('jwks must only contain private keys'); } if (onlyPublic && (jwk.d || jwk.k)) { continue; } keys.push({ jwk: { ...jwk, alg, use }, async keyObject (alg) { if (this[alg]) { return this[alg]; } const keyObject = await jose.importJWK(this.jwk, alg); this[alg] = keyObject; return keyObject; }, get algorithms () { Object.defineProperty(this, 'algorithms', { value: getAlgorithms(this.jwk.use, this.jwk.alg, this.jwk.kty, this.jwk.crv), enumerable: true, configurable: false }); return this.algorithms; } }); } return new this(internal, keys); } filter(...args) { return this.#keys.filter(...args); } find(...args) { return this.#keys.find(...args); } every(...args) { return this.#keys.every(...args); } some(...args) { return this.#keys.some(...args); } map(...args) { return this.#keys.map(...args); } forEach(...args) { return this.#keys.forEach(...args); } reduce(...args) { return this.#keys.reduce(...args); } sort(...args) { return this.#keys.sort(...args); } *[Symbol.iterator]() { for (const key of this.#keys){ yield key; } } }; }), "[project]/node_modules/openid-client/lib/helpers/merge.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const isPlainObject = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/is_plain_object.js [app-route] (ecmascript)"); function merge(target, ...sources) { for (const source of sources){ if (!isPlainObject(source)) { continue; } for (const [key, value] of Object.entries(source)){ /* istanbul ignore if */ if (key === '__proto__' || key === 'constructor') { continue; } if (isPlainObject(target[key]) && isPlainObject(value)) { target[key] = merge(target[key], value); } else if (typeof value !== 'undefined') { target[key] = value; } } } return target; } module.exports = merge; }), "[project]/node_modules/openid-client/lib/helpers/client.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const jose = __turbopack_context__.r("[project]/node_modules/jose/dist/node/cjs/index.js [app-route] (ecmascript)"); const { RPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const { assertIssuerConfiguration } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/assert.js [app-route] (ecmascript)"); const { random } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/generators.js [app-route] (ecmascript)"); const now = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/unix_timestamp.js [app-route] (ecmascript)"); const request = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/request.js [app-route] (ecmascript)"); const { keystores } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/weak_cache.js [app-route] (ecmascript)"); const merge = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/merge.js [app-route] (ecmascript)"); // TODO: in v6.x additionally encode the `- _ . ! ~ * ' ( )` characters // https://github.com/panva/node-openid-client/commit/5a2ea80ef5e59ec0c03dbd97d82f551e24a9d348 const formUrlEncode = (value)=>encodeURIComponent(value).replace(/%20/g, '+'); async function clientAssertion(endpoint, payload) { let alg = this[`${endpoint}_endpoint_auth_signing_alg`]; if (!alg) { assertIssuerConfiguration(this.issuer, `${endpoint}_endpoint_auth_signing_alg_values_supported`); } if (this[`${endpoint}_endpoint_auth_method`] === 'client_secret_jwt') { if (!alg) { const supported = this.issuer[`${endpoint}_endpoint_auth_signing_alg_values_supported`]; alg = Array.isArray(supported) && supported.find((signAlg)=>/^HS(?:256|384|512)/.test(signAlg)); } if (!alg) { throw new RPError(`failed to determine a JWS Algorithm to use for ${this[`${endpoint}_endpoint_auth_method`]} Client Assertion`); } return new jose.CompactSign(Buffer.from(JSON.stringify(payload))).setProtectedHeader({ alg }).sign(this.secretForAlg(alg)); } const keystore = await keystores.get(this); if (!keystore) { throw new TypeError('no client jwks provided for signing a client assertion with'); } if (!alg) { const supported = this.issuer[`${endpoint}_endpoint_auth_signing_alg_values_supported`]; alg = Array.isArray(supported) && supported.find((signAlg)=>keystore.get({ alg: signAlg, use: 'sig' })); } if (!alg) { throw new RPError(`failed to determine a JWS Algorithm to use for ${this[`${endpoint}_endpoint_auth_method`]} Client Assertion`); } const key = keystore.get({ alg, use: 'sig' }); if (!key) { throw new RPError(`no key found in client jwks to sign a client assertion with using alg ${alg}`); } return new jose.CompactSign(Buffer.from(JSON.stringify(payload))).setProtectedHeader({ alg, kid: key.jwk && key.jwk.kid }).sign(await key.keyObject(alg)); } async function authFor(endpoint, { clientAssertionPayload } = {}) { const authMethod = this[`${endpoint}_endpoint_auth_method`]; switch(authMethod){ case 'self_signed_tls_client_auth': case 'tls_client_auth': case 'none': return { form: { client_id: this.client_id } }; case 'client_secret_post': if (typeof this.client_secret !== 'string') { throw new TypeError('client_secret_post client authentication method requires a client_secret'); } return { form: { client_id: this.client_id, client_secret: this.client_secret } }; case 'private_key_jwt': case 'client_secret_jwt': { const timestamp = now(); const assertion = await clientAssertion.call(this, endpoint, { iat: timestamp, exp: timestamp + 60, jti: random(), iss: this.client_id, sub: this.client_id, aud: this.issuer.issuer, ...clientAssertionPayload }); return { form: { client_id: this.client_id, client_assertion: assertion, client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer' } }; } case 'client_secret_basic': { // This is correct behaviour, see https://tools.ietf.org/html/rfc6749#section-2.3.1 and the // related appendix. (also https://github.com/panva/node-openid-client/pull/91) // > The client identifier is encoded using the // > "application/x-www-form-urlencoded" encoding algorithm per // > Appendix B, and the encoded value is used as the username; the client // > password is encoded using the same algorithm and used as the // > password. if (typeof this.client_secret !== 'string') { throw new TypeError('client_secret_basic client authentication method requires a client_secret'); } const encoded = `${formUrlEncode(this.client_id)}:${formUrlEncode(this.client_secret)}`; const value = Buffer.from(encoded).toString('base64'); return { headers: { Authorization: `Basic ${value}` } }; } default: { throw new TypeError(`missing, or unsupported, ${endpoint}_endpoint_auth_method`); } } } function resolveResponseType() { const { length, 0: value } = this.response_types; if (length === 1) { return value; } return undefined; } function resolveRedirectUri() { const { length, 0: value } = this.redirect_uris || []; if (length === 1) { return value; } return undefined; } async function authenticatedPost(endpoint, opts, { clientAssertionPayload, endpointAuthMethod = endpoint, DPoP } = {}) { const auth = await authFor.call(this, endpointAuthMethod, { clientAssertionPayload }); const requestOpts = merge(opts, auth); const mTLS = this[`${endpointAuthMethod}_endpoint_auth_method`].includes('tls_client_auth') || endpoint === 'token' && this.tls_client_certificate_bound_access_tokens; let targetUrl; if (mTLS && this.issuer.mtls_endpoint_aliases) { targetUrl = this.issuer.mtls_endpoint_aliases[`${endpoint}_endpoint`]; } targetUrl = targetUrl || this.issuer[`${endpoint}_endpoint`]; if ('form' in requestOpts) { for (const [key, value] of Object.entries(requestOpts.form)){ if (typeof value === 'undefined') { delete requestOpts.form[key]; } } } return request.call(this, { ...requestOpts, method: 'POST', url: targetUrl, headers: { ...endpoint !== 'revocation' ? { Accept: 'application/json' } : undefined, ...requestOpts.headers } }, { mTLS, DPoP }); } module.exports = { resolveResponseType, resolveRedirectUri, authFor, authenticatedPost }; }), "[project]/node_modules/openid-client/lib/helpers/issuer.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const objectHash = __turbopack_context__.r("[project]/node_modules/object-hash/index.js [app-route] (ecmascript)"); const LRU = __turbopack_context__.r("[project]/node_modules/openid-client/node_modules/lru-cache/index.js [app-route] (ecmascript)"); const { RPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const { assertIssuerConfiguration } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/assert.js [app-route] (ecmascript)"); const KeyStore = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/keystore.js [app-route] (ecmascript)"); const { keystores } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/weak_cache.js [app-route] (ecmascript)"); const processResponse = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/process_response.js [app-route] (ecmascript)"); const request = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/request.js [app-route] (ecmascript)"); const inFlight = new WeakMap(); const caches = new WeakMap(); const lrus = (ctx)=>{ if (!caches.has(ctx)) { caches.set(ctx, new LRU({ max: 100 })); } return caches.get(ctx); }; async function getKeyStore(reload = false) { assertIssuerConfiguration(this, 'jwks_uri'); const keystore = keystores.get(this); const cache = lrus(this); if (reload || !keystore) { if (inFlight.has(this)) { return inFlight.get(this); } cache.reset(); inFlight.set(this, (async ()=>{ const response = await request.call(this, { method: 'GET', responseType: 'json', url: this.jwks_uri, headers: { Accept: 'application/json, application/jwk-set+json' } }).finally(()=>{ inFlight.delete(this); }); const jwks = processResponse(response); const joseKeyStore = KeyStore.fromJWKS(jwks, { onlyPublic: true }); cache.set('throttle', true, 60 * 1000); keystores.set(this, joseKeyStore); return joseKeyStore; })()); return inFlight.get(this); } return keystore; } async function queryKeyStore({ kid, kty, alg, use }, { allowMulti = false } = {}) { const cache = lrus(this); const def = { kid, kty, alg, use }; const defHash = objectHash(def, { algorithm: 'sha256', ignoreUnknown: true, unorderedArrays: true, unorderedSets: true, respectType: false }); // refresh keystore on every unknown key but also only upto once every minute const freshJwksUri = cache.get(defHash) || cache.get('throttle'); const keystore = await getKeyStore.call(this, !freshJwksUri); const keys = keystore.all(def); delete def.use; if (keys.length === 0) { throw new RPError({ printf: [ "no valid key found in issuer's jwks_uri for key parameters %j", def ], jwks: keystore }); } if (!allowMulti && keys.length > 1 && !kid) { throw new RPError({ printf: [ "multiple matching keys found in issuer's jwks_uri for key parameters %j, kid must be provided in this case", def ], jwks: keystore }); } cache.set(defHash, true); return keys; } module.exports.queryKeyStore = queryKeyStore; module.exports.keystore = getKeyStore; }), "[project]/node_modules/openid-client/lib/device_flow_handle.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const { inspect } = __turbopack_context__.r("[externals]/util [external] (util, cjs)"); const { RPError, OPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const now = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/unix_timestamp.js [app-route] (ecmascript)"); class DeviceFlowHandle { #aborted; #client; #clientAssertionPayload; #DPoP; #exchangeBody; #expires_at; #interval; #maxAge; #response; constructor({ client, exchangeBody, clientAssertionPayload, response, maxAge, DPoP }){ [ 'verification_uri', 'user_code', 'device_code' ].forEach((prop)=>{ if (typeof response[prop] !== 'string' || !response[prop]) { throw new RPError(`expected ${prop} string to be returned by Device Authorization Response, got %j`, response[prop]); } }); if (!Number.isSafeInteger(response.expires_in)) { throw new RPError('expected expires_in number to be returned by Device Authorization Response, got %j', response.expires_in); } this.#expires_at = now() + response.expires_in; this.#client = client; this.#DPoP = DPoP; this.#maxAge = maxAge; this.#exchangeBody = exchangeBody; this.#clientAssertionPayload = clientAssertionPayload; this.#response = response; this.#interval = response.interval * 1000 || 5000; } abort() { this.#aborted = true; } async poll({ signal } = {}) { if (signal && signal.aborted || this.#aborted) { throw new RPError('polling aborted'); } if (this.expired()) { throw new RPError('the device code %j has expired and the device authorization session has concluded', this.device_code); } await new Promise((resolve)=>setTimeout(resolve, this.#interval)); let tokenset; try { tokenset = await this.#client.grant({ ...this.#exchangeBody, grant_type: 'urn:ietf:params:oauth:grant-type:device_code', device_code: this.device_code }, { clientAssertionPayload: this.#clientAssertionPayload, DPoP: this.#DPoP }); } catch (err) { switch(err instanceof OPError && err.error){ case 'slow_down': this.#interval += 5000; case 'authorization_pending': return this.poll({ signal }); default: throw err; } } if ('id_token' in tokenset) { await this.#client.decryptIdToken(tokenset); await this.#client.validateIdToken(tokenset, undefined, 'token', this.#maxAge); } return tokenset; } get device_code() { return this.#response.device_code; } get user_code() { return this.#response.user_code; } get verification_uri() { return this.#response.verification_uri; } get verification_uri_complete() { return this.#response.verification_uri_complete; } get expires_in() { return Math.max.apply(null, [ this.#expires_at - now(), 0 ]); } expired() { return this.expires_in === 0; } /* istanbul ignore next */ [inspect.custom]() { return `${this.constructor.name} ${inspect(this.#response, { depth: Infinity, colors: process.stdout.isTTY, compact: false, sorted: true })}`; } } module.exports = DeviceFlowHandle; }), "[project]/node_modules/openid-client/lib/client.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const { inspect } = __turbopack_context__.r("[externals]/util [external] (util, cjs)"); const stdhttp = __turbopack_context__.r("[externals]/http [external] (http, cjs)"); const crypto = __turbopack_context__.r("[externals]/crypto [external] (crypto, cjs)"); const { strict: assert } = __turbopack_context__.r("[externals]/assert [external] (assert, cjs)"); const querystring = __turbopack_context__.r("[externals]/querystring [external] (querystring, cjs)"); const url = __turbopack_context__.r("[externals]/url [external] (url, cjs)"); const { URL, URLSearchParams } = __turbopack_context__.r("[externals]/url [external] (url, cjs)"); const jose = __turbopack_context__.r("[project]/node_modules/jose/dist/node/cjs/index.js [app-route] (ecmascript)"); const tokenHash = __turbopack_context__.r("[project]/node_modules/oidc-token-hash/lib/index.js [app-route] (ecmascript)"); const isKeyObject = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/is_key_object.js [app-route] (ecmascript)"); const decodeJWT = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/decode_jwt.js [app-route] (ecmascript)"); const base64url = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/base64url.js [app-route] (ecmascript)"); const defaults = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/defaults.js [app-route] (ecmascript)"); const parseWwwAuthenticate = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/www_authenticate_parser.js [app-route] (ecmascript)"); const { assertSigningAlgValuesSupport, assertIssuerConfiguration } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/assert.js [app-route] (ecmascript)"); const pick = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/pick.js [app-route] (ecmascript)"); const isPlainObject = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/is_plain_object.js [app-route] (ecmascript)"); const processResponse = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/process_response.js [app-route] (ecmascript)"); const TokenSet = __turbopack_context__.r("[project]/node_modules/openid-client/lib/token_set.js [app-route] (ecmascript)"); const { OPError, RPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const now = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/unix_timestamp.js [app-route] (ecmascript)"); const { random } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/generators.js [app-route] (ecmascript)"); const request = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/request.js [app-route] (ecmascript)"); const { CLOCK_TOLERANCE } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/consts.js [app-route] (ecmascript)"); const { keystores } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/weak_cache.js [app-route] (ecmascript)"); const KeyStore = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/keystore.js [app-route] (ecmascript)"); const clone = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/deep_clone.js [app-route] (ecmascript)"); const { authenticatedPost, resolveResponseType, resolveRedirectUri } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/client.js [app-route] (ecmascript)"); const { queryKeyStore } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/issuer.js [app-route] (ecmascript)"); const DeviceFlowHandle = __turbopack_context__.r("[project]/node_modules/openid-client/lib/device_flow_handle.js [app-route] (ecmascript)"); const [major, minor] = process.version.slice(1).split('.').map((str)=>parseInt(str, 10)); const rsaPssParams = major >= 17 || major === 16 && minor >= 9; const retryAttempt = Symbol(); const skipNonceCheck = Symbol(); const skipMaxAgeCheck = Symbol(); function pickCb(input) { return pick(input, 'access_token', 'code', 'error_description', 'error_uri', 'error', 'expires_in', 'id_token', 'iss', 'response', 'session_state', 'state', 'token_type'); } function authorizationHeaderValue(token, tokenType = 'Bearer') { return `${tokenType} ${token}`; } function getSearchParams(input) { const parsed = url.parse(input); if (!parsed.search) return {}; return querystring.parse(parsed.search.substring(1)); } function verifyPresence(payload, jwt, prop) { if (payload[prop] === undefined) { throw new RPError({ message: `missing required JWT property ${prop}`, jwt }); } } function authorizationParams(params) { const authParams = { client_id: this.client_id, scope: 'openid', response_type: resolveResponseType.call(this), redirect_uri: resolveRedirectUri.call(this), ...params }; Object.entries(authParams).forEach(([key, value])=>{ if (value === null || value === undefined) { delete authParams[key]; } else if (key === 'claims' && typeof value === 'object') { authParams[key] = JSON.stringify(value); } else if (key === 'resource' && Array.isArray(value)) { authParams[key] = value; } else if (typeof value !== 'string') { authParams[key] = String(value); } }); return authParams; } function getKeystore(jwks) { if (!isPlainObject(jwks) || !Array.isArray(jwks.keys) || jwks.keys.some((k)=>!isPlainObject(k) || !('kty' in k))) { throw new TypeError('jwks must be a JSON Web Key Set formatted object'); } return KeyStore.fromJWKS(jwks, { onlyPrivate: true }); } // if an OP doesnt support client_secret_basic but supports client_secret_post, use it instead // this is in place to take care of most common pitfalls when first using discovered Issuers without // the support for default values defined by Discovery 1.0 function checkBasicSupport(client, properties) { try { const supported = client.issuer.token_endpoint_auth_methods_supported; if (!supported.includes(properties.token_endpoint_auth_method)) { if (supported.includes('client_secret_post')) { properties.token_endpoint_auth_method = 'client_secret_post'; } } } catch (err) {} } function handleCommonMistakes(client, metadata, properties) { if (!metadata.token_endpoint_auth_method) { // if no explicit value was provided checkBasicSupport(client, properties); } // :fp: c'mon people... RTFM if (metadata.redirect_uri) { if (metadata.redirect_uris) { throw new TypeError('provide a redirect_uri or redirect_uris, not both'); } properties.redirect_uris = [ metadata.redirect_uri ]; delete properties.redirect_uri; } if (metadata.response_type) { if (metadata.response_types) { throw new TypeError('provide a response_type or response_types, not both'); } properties.response_types = [ metadata.response_type ]; delete properties.response_type; } } function getDefaultsForEndpoint(endpoint, issuer, properties) { if (!issuer[`${endpoint}_endpoint`]) return; const tokenEndpointAuthMethod = properties.token_endpoint_auth_method; const tokenEndpointAuthSigningAlg = properties.token_endpoint_auth_signing_alg; const eam = `${endpoint}_endpoint_auth_method`; const easa = `${endpoint}_endpoint_auth_signing_alg`; if (properties[eam] === undefined && properties[easa] === undefined) { if (tokenEndpointAuthMethod !== undefined) { properties[eam] = tokenEndpointAuthMethod; } if (tokenEndpointAuthSigningAlg !== undefined) { properties[easa] = tokenEndpointAuthSigningAlg; } } } class BaseClient { #metadata; #issuer; #aadIssValidation; #additionalAuthorizedParties; constructor(issuer, aadIssValidation, metadata = {}, jwks, options){ this.#metadata = new Map(); this.#issuer = issuer; this.#aadIssValidation = aadIssValidation; if (typeof metadata.client_id !== 'string' || !metadata.client_id) { throw new TypeError('client_id is required'); } const properties = { grant_types: [ 'authorization_code' ], id_token_signed_response_alg: 'RS256', authorization_signed_response_alg: 'RS256', response_types: [ 'code' ], token_endpoint_auth_method: 'client_secret_basic', ...this.fapi1() ? { grant_types: [ 'authorization_code', 'implicit' ], id_token_signed_response_alg: 'PS256', authorization_signed_response_alg: 'PS256', response_types: [ 'code id_token' ], tls_client_certificate_bound_access_tokens: true, token_endpoint_auth_method: undefined } : undefined, ...this.fapi2() ? { id_token_signed_response_alg: 'PS256', authorization_signed_response_alg: 'PS256', token_endpoint_auth_method: undefined } : undefined, ...metadata }; if (this.fapi()) { switch(properties.token_endpoint_auth_method){ case 'self_signed_tls_client_auth': case 'tls_client_auth': break; case 'private_key_jwt': if (!jwks) { throw new TypeError('jwks is required'); } break; case undefined: throw new TypeError('token_endpoint_auth_method is required'); default: throw new TypeError('invalid or unsupported token_endpoint_auth_method'); } } if (this.fapi2()) { if (properties.tls_client_certificate_bound_access_tokens && properties.dpop_bound_access_tokens) { throw new TypeError('either tls_client_certificate_bound_access_tokens or dpop_bound_access_tokens must be set to true'); } if (!properties.tls_client_certificate_bound_access_tokens && !properties.dpop_bound_access_tokens) { throw new TypeError('either tls_client_certificate_bound_access_tokens or dpop_bound_access_tokens must be set to true'); } } handleCommonMistakes(this, metadata, properties); assertSigningAlgValuesSupport('token', this.issuer, properties); [ 'introspection', 'revocation' ].forEach((endpoint)=>{ getDefaultsForEndpoint(endpoint, this.issuer, properties); assertSigningAlgValuesSupport(endpoint, this.issuer, properties); }); Object.entries(properties).forEach(([key, value])=>{ this.#metadata.set(key, value); if (!this[key]) { Object.defineProperty(this, key, { get () { return this.#metadata.get(key); }, enumerable: true }); } }); if (jwks !== undefined) { const keystore = getKeystore.call(this, jwks); keystores.set(this, keystore); } if (options != null && options.additionalAuthorizedParties) { this.#additionalAuthorizedParties = clone(options.additionalAuthorizedParties); } this[CLOCK_TOLERANCE] = 0; } authorizationUrl(params = {}) { if (!isPlainObject(params)) { throw new TypeError('params must be a plain object'); } assertIssuerConfiguration(this.issuer, 'authorization_endpoint'); const target = new URL(this.issuer.authorization_endpoint); for (const [name, value] of Object.entries(authorizationParams.call(this, params))){ if (Array.isArray(value)) { target.searchParams.delete(name); for (const member of value){ target.searchParams.append(name, member); } } else { target.searchParams.set(name, value); } } // TODO: is the replace needed? return target.href.replace(/\+/g, '%20'); } authorizationPost(params = {}) { if (!isPlainObject(params)) { throw new TypeError('params must be a plain object'); } const inputs = authorizationParams.call(this, params); const formInputs = Object.keys(inputs).map((name)=>``).join('\n'); return ` Requesting Authorization
${formInputs}
`; } endSessionUrl(params = {}) { assertIssuerConfiguration(this.issuer, 'end_session_endpoint'); const { 0: postLogout, length } = this.post_logout_redirect_uris || []; const { post_logout_redirect_uri = length === 1 ? postLogout : undefined } = params; let id_token_hint; ({ id_token_hint, ...params } = params); if (id_token_hint instanceof TokenSet) { if (!id_token_hint.id_token) { throw new TypeError('id_token not present in TokenSet'); } id_token_hint = id_token_hint.id_token; } const target = url.parse(this.issuer.end_session_endpoint); const query = defaults(getSearchParams(this.issuer.end_session_endpoint), params, { post_logout_redirect_uri, client_id: this.client_id }, { id_token_hint }); Object.entries(query).forEach(([key, value])=>{ if (value === null || value === undefined) { delete query[key]; } }); target.search = null; target.query = query; return url.format(target); } callbackParams(input) { const isIncomingMessage = input instanceof stdhttp.IncomingMessage || input && input.method && input.url; const isString = typeof input === 'string'; if (!isString && !isIncomingMessage) { throw new TypeError('#callbackParams only accepts string urls, http.IncomingMessage or a lookalike'); } if (isIncomingMessage) { switch(input.method){ case 'GET': return pickCb(getSearchParams(input.url)); case 'POST': if (input.body === undefined) { throw new TypeError('incoming message body missing, include a body parser prior to this method call'); } switch(typeof input.body){ case 'object': case 'string': if (Buffer.isBuffer(input.body)) { return pickCb(querystring.parse(input.body.toString('utf-8'))); } if (typeof input.body === 'string') { return pickCb(querystring.parse(input.body)); } return pickCb(input.body); default: throw new TypeError('invalid IncomingMessage body object'); } default: throw new TypeError('invalid IncomingMessage method'); } } else { return pickCb(getSearchParams(input)); } } async callback(redirectUri, parameters, checks = {}, { exchangeBody, clientAssertionPayload, DPoP } = {}) { let params = pickCb(parameters); if (checks.jarm && !('response' in parameters)) { throw new RPError({ message: 'expected a JARM response', checks, params }); } else if ('response' in parameters) { const decrypted = await this.decryptJARM(params.response); params = await this.validateJARM(decrypted); } if (this.default_max_age && !checks.max_age) { checks.max_age = this.default_max_age; } if (params.state && !checks.state) { throw new TypeError('checks.state argument is missing'); } if (!params.state && checks.state) { throw new RPError({ message: 'state missing from the response', checks, params }); } if (checks.state !== params.state) { throw new RPError({ printf: [ 'state mismatch, expected %s, got: %s', checks.state, params.state ], checks, params }); } if ('iss' in params) { assertIssuerConfiguration(this.issuer, 'issuer'); if (params.iss !== this.issuer.issuer) { throw new RPError({ printf: [ 'iss mismatch, expected %s, got: %s', this.issuer.issuer, params.iss ], params }); } } else if (this.issuer.authorization_response_iss_parameter_supported && !('id_token' in params) && !('response' in parameters)) { throw new RPError({ message: 'iss missing from the response', params }); } if (params.error) { throw new OPError(params); } const RESPONSE_TYPE_REQUIRED_PARAMS = { code: [ 'code' ], id_token: [ 'id_token' ], token: [ 'access_token', 'token_type' ] }; if (checks.response_type) { for (const type of checks.response_type.split(' ')){ if (type === 'none') { if (params.code || params.id_token || params.access_token) { throw new RPError({ message: 'unexpected params encountered for "none" response', checks, params }); } } else { for (const param of RESPONSE_TYPE_REQUIRED_PARAMS[type]){ if (!params[param]) { throw new RPError({ message: `${param} missing from response`, checks, params }); } } } } } if (params.id_token) { const tokenset = new TokenSet(params); await this.decryptIdToken(tokenset); await this.validateIdToken(tokenset, checks.nonce, 'authorization', checks.max_age, checks.state); if (!params.code) { return tokenset; } } if (params.code) { const tokenset = await this.grant({ ...exchangeBody, grant_type: 'authorization_code', code: params.code, redirect_uri: redirectUri, code_verifier: checks.code_verifier }, { clientAssertionPayload, DPoP }); await this.decryptIdToken(tokenset); await this.validateIdToken(tokenset, checks.nonce, 'token', checks.max_age); if (params.session_state) { tokenset.session_state = params.session_state; } return tokenset; } return new TokenSet(params); } async oauthCallback(redirectUri, parameters, checks = {}, { exchangeBody, clientAssertionPayload, DPoP } = {}) { let params = pickCb(parameters); if (checks.jarm && !('response' in parameters)) { throw new RPError({ message: 'expected a JARM response', checks, params }); } else if ('response' in parameters) { const decrypted = await this.decryptJARM(params.response); params = await this.validateJARM(decrypted); } if (params.state && !checks.state) { throw new TypeError('checks.state argument is missing'); } if (!params.state && checks.state) { throw new RPError({ message: 'state missing from the response', checks, params }); } if (checks.state !== params.state) { throw new RPError({ printf: [ 'state mismatch, expected %s, got: %s', checks.state, params.state ], checks, params }); } if ('iss' in params) { assertIssuerConfiguration(this.issuer, 'issuer'); if (params.iss !== this.issuer.issuer) { throw new RPError({ printf: [ 'iss mismatch, expected %s, got: %s', this.issuer.issuer, params.iss ], params }); } } else if (this.issuer.authorization_response_iss_parameter_supported && !('id_token' in params) && !('response' in parameters)) { throw new RPError({ message: 'iss missing from the response', params }); } if (params.error) { throw new OPError(params); } if (typeof params.id_token === 'string' && params.id_token.length) { throw new RPError({ message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()', params }); } delete params.id_token; const RESPONSE_TYPE_REQUIRED_PARAMS = { code: [ 'code' ], token: [ 'access_token', 'token_type' ] }; if (checks.response_type) { for (const type of checks.response_type.split(' ')){ if (type === 'none') { if (params.code || params.id_token || params.access_token) { throw new RPError({ message: 'unexpected params encountered for "none" response', checks, params }); } } if (RESPONSE_TYPE_REQUIRED_PARAMS[type]) { for (const param of RESPONSE_TYPE_REQUIRED_PARAMS[type]){ if (!params[param]) { throw new RPError({ message: `${param} missing from response`, checks, params }); } } } } } if (params.code) { const tokenset = await this.grant({ ...exchangeBody, grant_type: 'authorization_code', code: params.code, redirect_uri: redirectUri, code_verifier: checks.code_verifier }, { clientAssertionPayload, DPoP }); if (typeof tokenset.id_token === 'string' && tokenset.id_token.length) { throw new RPError({ message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()', params }); } delete tokenset.id_token; return tokenset; } return new TokenSet(params); } async decryptIdToken(token) { if (!this.id_token_encrypted_response_alg) { return token; } let idToken = token; if (idToken instanceof TokenSet) { if (!idToken.id_token) { throw new TypeError('id_token not present in TokenSet'); } idToken = idToken.id_token; } const expectedAlg = this.id_token_encrypted_response_alg; const expectedEnc = this.id_token_encrypted_response_enc; const result = await this.decryptJWE(idToken, expectedAlg, expectedEnc); if (token instanceof TokenSet) { token.id_token = result; return token; } return result; } async validateJWTUserinfo(body) { const expectedAlg = this.userinfo_signed_response_alg; return this.validateJWT(body, expectedAlg, []); } async decryptJARM(response) { if (!this.authorization_encrypted_response_alg) { return response; } const expectedAlg = this.authorization_encrypted_response_alg; const expectedEnc = this.authorization_encrypted_response_enc; return this.decryptJWE(response, expectedAlg, expectedEnc); } async decryptJWTUserinfo(body) { if (!this.userinfo_encrypted_response_alg) { return body; } const expectedAlg = this.userinfo_encrypted_response_alg; const expectedEnc = this.userinfo_encrypted_response_enc; return this.decryptJWE(body, expectedAlg, expectedEnc); } async decryptJWE(jwe, expectedAlg, expectedEnc = 'A128CBC-HS256') { const header = JSON.parse(base64url.decode(jwe.split('.')[0])); if (header.alg !== expectedAlg) { throw new RPError({ printf: [ 'unexpected JWE alg received, expected %s, got: %s', expectedAlg, header.alg ], jwt: jwe }); } if (header.enc !== expectedEnc) { throw new RPError({ printf: [ 'unexpected JWE enc received, expected %s, got: %s', expectedEnc, header.enc ], jwt: jwe }); } const getPlaintext = (result)=>new TextDecoder().decode(result.plaintext); let plaintext; if (expectedAlg.match(/^(?:RSA|ECDH)/)) { const keystore = await keystores.get(this); const protectedHeader = jose.decodeProtectedHeader(jwe); for (const key of keystore.all({ ...protectedHeader, use: 'enc' })){ plaintext = await jose.compactDecrypt(jwe, await key.keyObject(protectedHeader.alg)).then(getPlaintext, ()=>{}); if (plaintext) break; } } else { plaintext = await jose.compactDecrypt(jwe, this.secretForAlg(expectedAlg === 'dir' ? expectedEnc : expectedAlg)).then(getPlaintext, ()=>{}); } if (!plaintext) { throw new RPError({ message: 'failed to decrypt JWE', jwt: jwe }); } return plaintext; } async validateIdToken(tokenSet, nonce, returnedBy, maxAge, state) { let idToken = tokenSet; const expectedAlg = this.id_token_signed_response_alg; const isTokenSet = idToken instanceof TokenSet; if (isTokenSet) { if (!idToken.id_token) { throw new TypeError('id_token not present in TokenSet'); } idToken = idToken.id_token; } idToken = String(idToken); const timestamp = now(); const { protected: header, payload, key } = await this.validateJWT(idToken, expectedAlg); if (typeof maxAge === 'number' || maxAge !== skipMaxAgeCheck && this.require_auth_time) { if (!payload.auth_time) { throw new RPError({ message: 'missing required JWT property auth_time', jwt: idToken }); } if (typeof payload.auth_time !== 'number') { throw new RPError({ message: 'JWT auth_time claim must be a JSON numeric value', jwt: idToken }); } } if (typeof maxAge === 'number' && payload.auth_time + maxAge < timestamp - this[CLOCK_TOLERANCE]) { throw new RPError({ printf: [ 'too much time has elapsed since the last End-User authentication, max_age %i, auth_time: %i, now %i', maxAge, payload.auth_time, timestamp - this[CLOCK_TOLERANCE] ], now: timestamp, tolerance: this[CLOCK_TOLERANCE], auth_time: payload.auth_time, jwt: idToken }); } if (nonce !== skipNonceCheck && (payload.nonce || nonce !== undefined) && payload.nonce !== nonce) { throw new RPError({ printf: [ 'nonce mismatch, expected %s, got: %s', nonce, payload.nonce ], jwt: idToken }); } if (returnedBy === 'authorization') { if (!payload.at_hash && tokenSet.access_token) { throw new RPError({ message: 'missing required property at_hash', jwt: idToken }); } if (!payload.c_hash && tokenSet.code) { throw new RPError({ message: 'missing required property c_hash', jwt: idToken }); } if (this.fapi1()) { if (!payload.s_hash && (tokenSet.state || state)) { throw new RPError({ message: 'missing required property s_hash', jwt: idToken }); } } if (payload.s_hash) { if (!state) { throw new TypeError('cannot verify s_hash, "checks.state" property not provided'); } try { tokenHash.validate({ claim: 's_hash', source: 'state' }, payload.s_hash, state, header.alg, key.jwk && key.jwk.crv); } catch (err) { throw new RPError({ message: err.message, jwt: idToken }); } } } if (this.fapi() && payload.iat < timestamp - 3600) { throw new RPError({ printf: [ 'JWT issued too far in the past, now %i, iat %i', timestamp, payload.iat ], now: timestamp, tolerance: this[CLOCK_TOLERANCE], iat: payload.iat, jwt: idToken }); } if (tokenSet.access_token && payload.at_hash !== undefined) { try { tokenHash.validate({ claim: 'at_hash', source: 'access_token' }, payload.at_hash, tokenSet.access_token, header.alg, key.jwk && key.jwk.crv); } catch (err) { throw new RPError({ message: err.message, jwt: idToken }); } } if (tokenSet.code && payload.c_hash !== undefined) { try { tokenHash.validate({ claim: 'c_hash', source: 'code' }, payload.c_hash, tokenSet.code, header.alg, key.jwk && key.jwk.crv); } catch (err) { throw new RPError({ message: err.message, jwt: idToken }); } } return tokenSet; } async validateJWT(jwt, expectedAlg, required = [ 'iss', 'sub', 'aud', 'exp', 'iat' ]) { const isSelfIssued = this.issuer.issuer === 'https://self-issued.me'; const timestamp = now(); let header; let payload; try { ({ header, payload } = decodeJWT(jwt, { complete: true })); } catch (err) { throw new RPError({ printf: [ 'failed to decode JWT (%s: %s)', err.name, err.message ], jwt }); } if (header.alg !== expectedAlg) { throw new RPError({ printf: [ 'unexpected JWT alg received, expected %s, got: %s', expectedAlg, header.alg ], jwt }); } if (isSelfIssued) { required = [ ...required, 'sub_jwk' ]; } required.forEach(verifyPresence.bind(undefined, payload, jwt)); if (payload.iss !== undefined) { let expectedIss = this.issuer.issuer; if (this.#aadIssValidation) { expectedIss = this.issuer.issuer.replace('{tenantid}', payload.tid); } if (payload.iss !== expectedIss) { throw new RPError({ printf: [ 'unexpected iss value, expected %s, got: %s', expectedIss, payload.iss ], jwt }); } } if (payload.iat !== undefined) { if (typeof payload.iat !== 'number') { throw new RPError({ message: 'JWT iat claim must be a JSON numeric value', jwt }); } } if (payload.nbf !== undefined) { if (typeof payload.nbf !== 'number') { throw new RPError({ message: 'JWT nbf claim must be a JSON numeric value', jwt }); } if (payload.nbf > timestamp + this[CLOCK_TOLERANCE]) { throw new RPError({ printf: [ 'JWT not active yet, now %i, nbf %i', timestamp + this[CLOCK_TOLERANCE], payload.nbf ], now: timestamp, tolerance: this[CLOCK_TOLERANCE], nbf: payload.nbf, jwt }); } } if (payload.exp !== undefined) { if (typeof payload.exp !== 'number') { throw new RPError({ message: 'JWT exp claim must be a JSON numeric value', jwt }); } if (timestamp - this[CLOCK_TOLERANCE] >= payload.exp) { throw new RPError({ printf: [ 'JWT expired, now %i, exp %i', timestamp - this[CLOCK_TOLERANCE], payload.exp ], now: timestamp, tolerance: this[CLOCK_TOLERANCE], exp: payload.exp, jwt }); } } if (payload.aud !== undefined) { if (Array.isArray(payload.aud)) { if (payload.aud.length > 1 && !payload.azp) { throw new RPError({ message: 'missing required JWT property azp', jwt }); } if (!payload.aud.includes(this.client_id)) { throw new RPError({ printf: [ 'aud is missing the client_id, expected %s to be included in %j', this.client_id, payload.aud ], jwt }); } } else if (payload.aud !== this.client_id) { throw new RPError({ printf: [ 'aud mismatch, expected %s, got: %s', this.client_id, payload.aud ], jwt }); } } if (payload.azp !== undefined) { let additionalAuthorizedParties = this.#additionalAuthorizedParties; if (typeof additionalAuthorizedParties === 'string') { additionalAuthorizedParties = [ this.client_id, additionalAuthorizedParties ]; } else if (Array.isArray(additionalAuthorizedParties)) { additionalAuthorizedParties = [ this.client_id, ...additionalAuthorizedParties ]; } else { additionalAuthorizedParties = [ this.client_id ]; } if (!additionalAuthorizedParties.includes(payload.azp)) { throw new RPError({ printf: [ 'azp mismatch, got: %s', payload.azp ], jwt }); } } let keys; if (isSelfIssued) { try { assert(isPlainObject(payload.sub_jwk)); const key = await jose.importJWK(payload.sub_jwk, header.alg); assert.equal(key.type, 'public'); keys = [ { keyObject () { return key; } } ]; } catch (err) { throw new RPError({ message: 'failed to use sub_jwk claim as an asymmetric JSON Web Key', jwt }); } if (await jose.calculateJwkThumbprint(payload.sub_jwk) !== payload.sub) { throw new RPError({ message: 'failed to match the subject with sub_jwk', jwt }); } } else if (header.alg.startsWith('HS')) { keys = [ this.secretForAlg(header.alg) ]; } else if (header.alg !== 'none') { keys = await queryKeyStore.call(this.issuer, { ...header, use: 'sig' }); } if (!keys && header.alg === 'none') { return { protected: header, payload }; } for (const key of keys){ const verified = await jose.compactVerify(jwt, key instanceof Uint8Array ? key : await key.keyObject(header.alg)).catch(()=>{}); if (verified) { return { payload, protected: verified.protectedHeader, key }; } } throw new RPError({ message: 'failed to validate JWT signature', jwt }); } async refresh(refreshToken, { exchangeBody, clientAssertionPayload, DPoP } = {}) { let token = refreshToken; if (token instanceof TokenSet) { if (!token.refresh_token) { throw new TypeError('refresh_token not present in TokenSet'); } token = token.refresh_token; } const tokenset = await this.grant({ ...exchangeBody, grant_type: 'refresh_token', refresh_token: String(token) }, { clientAssertionPayload, DPoP }); if (tokenset.id_token) { await this.decryptIdToken(tokenset); await this.validateIdToken(tokenset, skipNonceCheck, 'token', skipMaxAgeCheck); if (refreshToken instanceof TokenSet && refreshToken.id_token) { const expectedSub = refreshToken.claims().sub; const actualSub = tokenset.claims().sub; if (actualSub !== expectedSub) { throw new RPError({ printf: [ 'sub mismatch, expected %s, got: %s', expectedSub, actualSub ], jwt: tokenset.id_token }); } } } return tokenset; } async requestResource(resourceUrl, accessToken, { method, headers, body, DPoP, tokenType = DPoP ? 'DPoP' : accessToken instanceof TokenSet ? accessToken.token_type : 'Bearer' } = {}, retry) { if (accessToken instanceof TokenSet) { if (!accessToken.access_token) { throw new TypeError('access_token not present in TokenSet'); } accessToken = accessToken.access_token; } if (!accessToken) { throw new TypeError('no access token provided'); } else if (typeof accessToken !== 'string') { throw new TypeError('invalid access token provided'); } const requestOpts = { headers: { Authorization: authorizationHeaderValue(accessToken, tokenType), ...headers }, body }; const mTLS = !!this.tls_client_certificate_bound_access_tokens; const response = await request.call(this, { ...requestOpts, responseType: 'buffer', method, url: resourceUrl }, { accessToken, mTLS, DPoP }); const wwwAuthenticate = response.headers['www-authenticate']; if (retry !== retryAttempt && wwwAuthenticate && wwwAuthenticate.toLowerCase().startsWith('dpop ') && parseWwwAuthenticate(wwwAuthenticate).error === 'use_dpop_nonce') { return this.requestResource(resourceUrl, accessToken, { method, headers, body, DPoP, tokenType }); } return response; } async userinfo(accessToken, { method = 'GET', via = 'header', tokenType, params, DPoP } = {}) { assertIssuerConfiguration(this.issuer, 'userinfo_endpoint'); const options = { tokenType, method: String(method).toUpperCase(), DPoP }; if (options.method !== 'GET' && options.method !== 'POST') { throw new TypeError('#userinfo() method can only be POST or a GET'); } if (via === 'body' && options.method !== 'POST') { throw new TypeError('can only send body on POST'); } const jwt = !!(this.userinfo_signed_response_alg || this.userinfo_encrypted_response_alg); if (jwt) { options.headers = { Accept: 'application/jwt' }; } else { options.headers = { Accept: 'application/json' }; } const mTLS = !!this.tls_client_certificate_bound_access_tokens; let targetUrl; if (mTLS && this.issuer.mtls_endpoint_aliases) { targetUrl = this.issuer.mtls_endpoint_aliases.userinfo_endpoint; } targetUrl = new URL(targetUrl || this.issuer.userinfo_endpoint); if (via === 'body') { options.headers.Authorization = undefined; options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; options.body = new URLSearchParams(); options.body.append('access_token', accessToken instanceof TokenSet ? accessToken.access_token : accessToken); } // handle additional parameters, GET via querystring, POST via urlencoded body if (params) { if (options.method === 'GET') { Object.entries(params).forEach(([key, value])=>{ targetUrl.searchParams.append(key, value); }); } else if (options.body) { // POST && via body Object.entries(params).forEach(([key, value])=>{ options.body.append(key, value); }); } else { // POST && via header options.body = new URLSearchParams(); options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; Object.entries(params).forEach(([key, value])=>{ options.body.append(key, value); }); } } if (options.body) { options.body = options.body.toString(); } const response = await this.requestResource(targetUrl, accessToken, options); let parsed = processResponse(response, { bearer: true }); if (jwt) { if (!/^application\/jwt/.test(response.headers['content-type'])) { throw new RPError({ message: 'expected application/jwt response from the userinfo_endpoint', response }); } const body = response.body.toString(); const userinfo = await this.decryptJWTUserinfo(body); if (!this.userinfo_signed_response_alg) { try { parsed = JSON.parse(userinfo); assert(isPlainObject(parsed)); } catch (err) { throw new RPError({ message: 'failed to parse userinfo JWE payload as JSON', jwt: userinfo }); } } else { ({ payload: parsed } = await this.validateJWTUserinfo(userinfo)); } } else { try { parsed = JSON.parse(response.body); } catch (err) { Object.defineProperty(err, 'response', { value: response }); throw err; } } if (accessToken instanceof TokenSet && accessToken.id_token) { const expectedSub = accessToken.claims().sub; if (parsed.sub !== expectedSub) { throw new RPError({ printf: [ 'userinfo sub mismatch, expected %s, got: %s', expectedSub, parsed.sub ], body: parsed, jwt: accessToken.id_token }); } } return parsed; } encryptionSecret(len) { const hash = len <= 256 ? 'sha256' : len <= 384 ? 'sha384' : len <= 512 ? 'sha512' : false; if (!hash) { throw new Error('unsupported symmetric encryption key derivation'); } return crypto.createHash(hash).update(this.client_secret).digest().slice(0, len / 8); } secretForAlg(alg) { if (!this.client_secret) { throw new TypeError('client_secret is required'); } if (/^A(\d{3})(?:GCM)?KW$/.test(alg)) { return this.encryptionSecret(parseInt(RegExp.$1, 10)); } if (/^A(\d{3})(?:GCM|CBC-HS(\d{3}))$/.test(alg)) { return this.encryptionSecret(parseInt(RegExp.$2 || RegExp.$1, 10)); } return new TextEncoder().encode(this.client_secret); } async grant(body, { clientAssertionPayload, DPoP } = {}, retry) { assertIssuerConfiguration(this.issuer, 'token_endpoint'); const response = await authenticatedPost.call(this, 'token', { form: body, responseType: 'json' }, { clientAssertionPayload, DPoP }); let responseBody; try { responseBody = processResponse(response); } catch (err) { if (retry !== retryAttempt && err instanceof OPError && err.error === 'use_dpop_nonce') { return this.grant(body, { clientAssertionPayload, DPoP }, retryAttempt); } throw err; } return new TokenSet(responseBody); } async deviceAuthorization(params = {}, { exchangeBody, clientAssertionPayload, DPoP } = {}) { assertIssuerConfiguration(this.issuer, 'device_authorization_endpoint'); assertIssuerConfiguration(this.issuer, 'token_endpoint'); const body = authorizationParams.call(this, { client_id: this.client_id, redirect_uri: null, response_type: null, ...params }); const response = await authenticatedPost.call(this, 'device_authorization', { responseType: 'json', form: body }, { clientAssertionPayload, endpointAuthMethod: 'token' }); const responseBody = processResponse(response); return new DeviceFlowHandle({ client: this, exchangeBody, clientAssertionPayload, response: responseBody, maxAge: params.max_age, DPoP }); } async revoke(token, hint, { revokeBody, clientAssertionPayload } = {}) { assertIssuerConfiguration(this.issuer, 'revocation_endpoint'); if (hint !== undefined && typeof hint !== 'string') { throw new TypeError('hint must be a string'); } const form = { ...revokeBody, token }; if (hint) { form.token_type_hint = hint; } const response = await authenticatedPost.call(this, 'revocation', { form }, { clientAssertionPayload }); processResponse(response, { body: false }); } async introspect(token, hint, { introspectBody, clientAssertionPayload } = {}) { assertIssuerConfiguration(this.issuer, 'introspection_endpoint'); if (hint !== undefined && typeof hint !== 'string') { throw new TypeError('hint must be a string'); } const form = { ...introspectBody, token }; if (hint) { form.token_type_hint = hint; } const response = await authenticatedPost.call(this, 'introspection', { form, responseType: 'json' }, { clientAssertionPayload }); const responseBody = processResponse(response); return responseBody; } static async register(metadata, options = {}) { const { initialAccessToken, jwks, ...clientOptions } = options; assertIssuerConfiguration(this.issuer, 'registration_endpoint'); if (jwks !== undefined && !(metadata.jwks || metadata.jwks_uri)) { const keystore = await getKeystore.call(this, jwks); metadata.jwks = keystore.toJWKS(); } const response = await request.call(this, { headers: { Accept: 'application/json', ...initialAccessToken ? { Authorization: authorizationHeaderValue(initialAccessToken) } : undefined }, responseType: 'json', json: metadata, url: this.issuer.registration_endpoint, method: 'POST' }); const responseBody = processResponse(response, { statusCode: 201, bearer: true }); return new this(responseBody, jwks, clientOptions); } get metadata() { return clone(Object.fromEntries(this.#metadata.entries())); } static async fromUri(registrationClientUri, registrationAccessToken, jwks, clientOptions) { const response = await request.call(this, { method: 'GET', url: registrationClientUri, responseType: 'json', headers: { Authorization: authorizationHeaderValue(registrationAccessToken), Accept: 'application/json' } }); const responseBody = processResponse(response, { bearer: true }); return new this(responseBody, jwks, clientOptions); } async requestObject(requestObject = {}, { sign: signingAlgorithm = this.request_object_signing_alg || 'none', encrypt: { alg: eKeyManagement = this.request_object_encryption_alg, enc: eContentEncryption = this.request_object_encryption_enc || 'A128CBC-HS256' } = {} } = {}) { if (!isPlainObject(requestObject)) { throw new TypeError('requestObject must be a plain object'); } let signed; let key; const unix = now(); const header = { alg: signingAlgorithm, typ: 'oauth-authz-req+jwt' }; const payload = JSON.stringify(defaults({}, requestObject, { iss: this.client_id, aud: this.issuer.issuer, client_id: this.client_id, jti: random(), iat: unix, exp: unix + 300, ...this.fapi() ? { nbf: unix } : undefined })); if (signingAlgorithm === 'none') { signed = [ base64url.encode(JSON.stringify(header)), base64url.encode(payload), '' ].join('.'); } else { const symmetric = signingAlgorithm.startsWith('HS'); if (symmetric) { key = this.secretForAlg(signingAlgorithm); } else { const keystore = await keystores.get(this); if (!keystore) { throw new TypeError(`no keystore present for client, cannot sign using alg ${signingAlgorithm}`); } key = keystore.get({ alg: signingAlgorithm, use: 'sig' }); if (!key) { throw new TypeError(`no key to sign with found for alg ${signingAlgorithm}`); } } signed = await new jose.CompactSign(new TextEncoder().encode(payload)).setProtectedHeader({ ...header, kid: symmetric ? undefined : key.jwk.kid }).sign(symmetric ? key : await key.keyObject(signingAlgorithm)); } if (!eKeyManagement) { return signed; } const fields = { alg: eKeyManagement, enc: eContentEncryption, cty: 'oauth-authz-req+jwt' }; if (fields.alg.match(/^(RSA|ECDH)/)) { [key] = await queryKeyStore.call(this.issuer, { alg: fields.alg, use: 'enc' }, { allowMulti: true }); } else { key = this.secretForAlg(fields.alg === 'dir' ? fields.enc : fields.alg); } return new jose.CompactEncrypt(new TextEncoder().encode(signed)).setProtectedHeader({ ...fields, kid: key instanceof Uint8Array ? undefined : key.jwk.kid }).encrypt(key instanceof Uint8Array ? key : await key.keyObject(fields.alg)); } async pushedAuthorizationRequest(params = {}, { clientAssertionPayload } = {}) { assertIssuerConfiguration(this.issuer, 'pushed_authorization_request_endpoint'); const body = { ...'request' in params ? params : authorizationParams.call(this, params), client_id: this.client_id }; const response = await authenticatedPost.call(this, 'pushed_authorization_request', { responseType: 'json', form: body }, { clientAssertionPayload, endpointAuthMethod: 'token' }); const responseBody = processResponse(response, { statusCode: 201 }); if (!('expires_in' in responseBody)) { throw new RPError({ message: 'expected expires_in in Pushed Authorization Successful Response', response }); } if (typeof responseBody.expires_in !== 'number') { throw new RPError({ message: 'invalid expires_in value in Pushed Authorization Successful Response', response }); } if (!('request_uri' in responseBody)) { throw new RPError({ message: 'expected request_uri in Pushed Authorization Successful Response', response }); } if (typeof responseBody.request_uri !== 'string') { throw new RPError({ message: 'invalid request_uri value in Pushed Authorization Successful Response', response }); } return responseBody; } get issuer() { return this.#issuer; } /* istanbul ignore next */ [inspect.custom]() { return `${this.constructor.name} ${inspect(this.metadata, { depth: Infinity, colors: process.stdout.isTTY, compact: false, sorted: true })}`; } fapi() { return this.fapi1() || this.fapi2(); } fapi1() { return this.constructor.name === 'FAPI1Client'; } fapi2() { return this.constructor.name === 'FAPI2Client'; } async validateJARM(response) { const expectedAlg = this.authorization_signed_response_alg; const { payload } = await this.validateJWT(response, expectedAlg, [ 'iss', 'exp', 'aud' ]); return pickCb(payload); } /** * @name dpopProof * @api private */ async dpopProof(payload, privateKeyInput, accessToken) { if (!isPlainObject(payload)) { throw new TypeError('payload must be a plain object'); } let privateKey; if (isKeyObject(privateKeyInput)) { privateKey = privateKeyInput; } else if (privateKeyInput[Symbol.toStringTag] === 'CryptoKey') { privateKey = privateKeyInput; } else if (jose.cryptoRuntime === 'node:crypto') { privateKey = crypto.createPrivateKey(privateKeyInput); } else { throw new TypeError('unrecognized crypto runtime'); } if (privateKey.type !== 'private') { throw new TypeError('"DPoP" option must be a private key'); } let alg = determineDPoPAlgorithm.call(this, privateKey, privateKeyInput); if (!alg) { throw new TypeError('could not determine DPoP JWS Algorithm'); } return new jose.SignJWT({ ath: accessToken ? base64url.encode(crypto.createHash('sha256').update(accessToken).digest()) : undefined, ...payload }).setProtectedHeader({ alg, typ: 'dpop+jwt', jwk: await getJwk(privateKey, privateKeyInput) }).setIssuedAt().setJti(random()).sign(privateKey); } } function determineDPoPAlgorithmFromCryptoKey(cryptoKey) { switch(cryptoKey.algorithm.name){ case 'Ed25519': case 'Ed448': return 'EdDSA'; case 'ECDSA': { switch(cryptoKey.algorithm.namedCurve){ case 'P-256': return 'ES256'; case 'P-384': return 'ES384'; case 'P-521': return 'ES512'; default: break; } break; } case 'RSASSA-PKCS1-v1_5': return `RS${cryptoKey.algorithm.hash.name.slice(4)}`; case 'RSA-PSS': return `PS${cryptoKey.algorithm.hash.name.slice(4)}`; default: throw new TypeError('unsupported DPoP private key'); } } let determineDPoPAlgorithm; if (jose.cryptoRuntime === 'node:crypto') { determineDPoPAlgorithm = function(privateKey, privateKeyInput) { if (privateKeyInput[Symbol.toStringTag] === 'CryptoKey') { return determineDPoPAlgorithmFromCryptoKey(privateKey); } switch(privateKey.asymmetricKeyType){ case 'ed25519': case 'ed448': return 'EdDSA'; case 'ec': return determineEcAlgorithm(privateKey, privateKeyInput); case 'rsa': case rsaPssParams && 'rsa-pss': return determineRsaAlgorithm(privateKey, privateKeyInput, this.issuer.dpop_signing_alg_values_supported); default: throw new TypeError('unsupported DPoP private key'); } }; const RSPS = /^(?:RS|PS)(?:256|384|512)$/; function determineRsaAlgorithm(privateKey, privateKeyInput, valuesSupported) { if (typeof privateKeyInput === 'object' && privateKeyInput.format === 'jwk' && privateKeyInput.key && privateKeyInput.key.alg) { return privateKeyInput.key.alg; } if (Array.isArray(valuesSupported)) { let candidates = valuesSupported.filter(RegExp.prototype.test.bind(RSPS)); if (privateKey.asymmetricKeyType === 'rsa-pss') { candidates = candidates.filter((value)=>value.startsWith('PS')); } return [ 'PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS384' ].find((preferred)=>candidates.includes(preferred)); } return 'PS256'; } const p256 = Buffer.from([ 42, 134, 72, 206, 61, 3, 1, 7 ]); const p384 = Buffer.from([ 43, 129, 4, 0, 34 ]); const p521 = Buffer.from([ 43, 129, 4, 0, 35 ]); const secp256k1 = Buffer.from([ 43, 129, 4, 0, 10 ]); function determineEcAlgorithm(privateKey, privateKeyInput) { // If input was a JWK switch(typeof privateKeyInput === 'object' && typeof privateKeyInput.key === 'object' && privateKeyInput.key.crv){ case 'P-256': return 'ES256'; case 'secp256k1': return 'ES256K'; case 'P-384': return 'ES384'; case 'P-512': return 'ES512'; default: break; } const buf = privateKey.export({ format: 'der', type: 'pkcs8' }); const i = buf[1] < 128 ? 17 : 18; const len = buf[i]; const curveOid = buf.slice(i + 1, i + 1 + len); if (curveOid.equals(p256)) { return 'ES256'; } if (curveOid.equals(p384)) { return 'ES384'; } if (curveOid.equals(p521)) { return 'ES512'; } if (curveOid.equals(secp256k1)) { return 'ES256K'; } throw new TypeError('unsupported DPoP private key curve'); } } else { determineDPoPAlgorithm = determineDPoPAlgorithmFromCryptoKey; } const jwkCache = new WeakMap(); async function getJwk(keyObject, privateKeyInput) { if (jose.cryptoRuntime === 'node:crypto' && typeof privateKeyInput === 'object' && typeof privateKeyInput.key === 'object' && privateKeyInput.format === 'jwk') { return pick(privateKeyInput.key, 'kty', 'crv', 'x', 'y', 'e', 'n'); } if (jwkCache.has(privateKeyInput)) { return jwkCache.get(privateKeyInput); } const jwk = pick(await jose.exportJWK(keyObject), 'kty', 'crv', 'x', 'y', 'e', 'n'); if (isKeyObject(privateKeyInput) || jose.cryptoRuntime === 'WebCryptoAPI') { jwkCache.set(privateKeyInput, jwk); } return jwk; } module.exports = (issuer, aadIssValidation = false)=>class Client extends BaseClient { constructor(...args){ super(issuer, aadIssValidation, ...args); } static get issuer() { return issuer; } }; module.exports.BaseClient = BaseClient; }), "[project]/node_modules/openid-client/lib/issuer_registry.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const LRU = __turbopack_context__.r("[project]/node_modules/openid-client/node_modules/lru-cache/index.js [app-route] (ecmascript)"); module.exports = new LRU({ max: 100 }); }), "[project]/node_modules/openid-client/lib/helpers/webfinger_normalize.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { // Credit: https://github.com/rohe/pyoidc/blob/master/src/oic/utils/webfinger.py // -- Normalization -- // A string of any other type is interpreted as a URI either the form of scheme // "://" authority path-abempty [ "?" query ] [ "#" fragment ] or authority // path-abempty [ "?" query ] [ "#" fragment ] per RFC 3986 [RFC3986] and is // normalized according to the following rules: // // If the user input Identifier does not have an RFC 3986 [RFC3986] scheme // portion, the string is interpreted as [userinfo "@"] host [":" port] // path-abempty [ "?" query ] [ "#" fragment ] per RFC 3986 [RFC3986]. // If the userinfo component is present and all of the path component, query // component, and port component are empty, the acct scheme is assumed. In this // case, the normalized URI is formed by prefixing acct: to the string as the // scheme. Per the 'acct' URI Scheme [I‑D.ietf‑appsawg‑acct‑uri], if there is an // at-sign character ('@') in the userinfo component, it needs to be // percent-encoded as described in RFC 3986 [RFC3986]. // For all other inputs without a scheme portion, the https scheme is assumed, // and the normalized URI is formed by prefixing https:// to the string as the // scheme. // If the resulting URI contains a fragment portion, it MUST be stripped off // together with the fragment delimiter character "#". // The WebFinger [I‑D.ietf‑appsawg‑webfinger] Resource in this case is the // resulting URI, and the WebFinger Host is the authority component. // // Note: Since the definition of authority in RFC 3986 [RFC3986] is // [ userinfo "@" ] host [ ":" port ], it is legal to have a user input // identifier like userinfo@host:port, e.g., alice@example.com:8080. const PORT = /^\d+$/; function hasScheme(input) { if (input.includes('://')) return true; const authority = input.replace(/(\/|\?)/g, '#').split('#')[0]; if (authority.includes(':')) { const index = authority.indexOf(':'); const hostOrPort = authority.slice(index + 1); if (!PORT.test(hostOrPort)) { return true; } } return false; } function acctSchemeAssumed(input) { if (!input.includes('@')) return false; const parts = input.split('@'); const host = parts[parts.length - 1]; return !(host.includes(':') || host.includes('/') || host.includes('?')); } function normalize(input) { if (typeof input !== 'string') { throw new TypeError('input must be a string'); } let output; if (hasScheme(input)) { output = input; } else if (acctSchemeAssumed(input)) { output = `acct:${input}`; } else { output = `https://${input}`; } return output.split('#')[0]; } module.exports = normalize; }), "[project]/node_modules/openid-client/lib/issuer.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const { inspect } = __turbopack_context__.r("[externals]/util [external] (util, cjs)"); const url = __turbopack_context__.r("[externals]/url [external] (url, cjs)"); const { RPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const getClient = __turbopack_context__.r("[project]/node_modules/openid-client/lib/client.js [app-route] (ecmascript)"); const registry = __turbopack_context__.r("[project]/node_modules/openid-client/lib/issuer_registry.js [app-route] (ecmascript)"); const processResponse = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/process_response.js [app-route] (ecmascript)"); const webfingerNormalize = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/webfinger_normalize.js [app-route] (ecmascript)"); const request = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/request.js [app-route] (ecmascript)"); const clone = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/deep_clone.js [app-route] (ecmascript)"); const { keystore } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/issuer.js [app-route] (ecmascript)"); const AAD_MULTITENANT_DISCOVERY = [ 'https://login.microsoftonline.com/common/.well-known/openid-configuration', 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration', 'https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration', 'https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration' ]; const AAD_MULTITENANT = Symbol(); const ISSUER_DEFAULTS = { claim_types_supported: [ 'normal' ], claims_parameter_supported: false, grant_types_supported: [ 'authorization_code', 'implicit' ], request_parameter_supported: false, request_uri_parameter_supported: true, require_request_uri_registration: false, response_modes_supported: [ 'query', 'fragment' ], token_endpoint_auth_methods_supported: [ 'client_secret_basic' ] }; class Issuer { #metadata; constructor(meta = {}){ const aadIssValidation = meta[AAD_MULTITENANT]; delete meta[AAD_MULTITENANT]; [ 'introspection', 'revocation' ].forEach((endpoint)=>{ // if intro/revocation endpoint auth specific meta is missing use the token ones if they // are defined if (meta[`${endpoint}_endpoint`] && meta[`${endpoint}_endpoint_auth_methods_supported`] === undefined && meta[`${endpoint}_endpoint_auth_signing_alg_values_supported`] === undefined) { if (meta.token_endpoint_auth_methods_supported) { meta[`${endpoint}_endpoint_auth_methods_supported`] = meta.token_endpoint_auth_methods_supported; } if (meta.token_endpoint_auth_signing_alg_values_supported) { meta[`${endpoint}_endpoint_auth_signing_alg_values_supported`] = meta.token_endpoint_auth_signing_alg_values_supported; } } }); this.#metadata = new Map(); Object.entries(meta).forEach(([key, value])=>{ this.#metadata.set(key, value); if (!this[key]) { Object.defineProperty(this, key, { get () { return this.#metadata.get(key); }, enumerable: true }); } }); registry.set(this.issuer, this); const Client = getClient(this, aadIssValidation); Object.defineProperties(this, { Client: { value: Client, enumerable: true }, FAPI1Client: { value: class FAPI1Client extends Client { }, enumerable: true }, FAPI2Client: { value: class FAPI2Client extends Client { }, enumerable: true } }); } get metadata() { return clone(Object.fromEntries(this.#metadata.entries())); } static async webfinger(input) { const resource = webfingerNormalize(input); const { host } = url.parse(resource); const webfingerUrl = `https://${host}/.well-known/webfinger`; const response = await request.call(this, { method: 'GET', url: webfingerUrl, responseType: 'json', searchParams: { resource, rel: 'http://openid.net/specs/connect/1.0/issuer' }, headers: { Accept: 'application/json' } }); const body = processResponse(response); const location = Array.isArray(body.links) && body.links.find((link)=>typeof link === 'object' && link.rel === 'http://openid.net/specs/connect/1.0/issuer' && link.href); if (!location) { throw new RPError({ message: 'no issuer found in webfinger response', body }); } if (typeof location.href !== 'string' || !location.href.startsWith('https://')) { throw new RPError({ printf: [ 'invalid issuer location %s', location.href ], body }); } const expectedIssuer = location.href; if (registry.has(expectedIssuer)) { return registry.get(expectedIssuer); } const issuer = await this.discover(expectedIssuer); if (issuer.issuer !== expectedIssuer) { registry.del(issuer.issuer); throw new RPError('discovered issuer mismatch, expected %s, got: %s', expectedIssuer, issuer.issuer); } return issuer; } static async discover(uri) { const wellKnownUri = resolveWellKnownUri(uri); const response = await request.call(this, { method: 'GET', responseType: 'json', url: wellKnownUri, headers: { Accept: 'application/json' } }); const body = processResponse(response); return new Issuer({ ...ISSUER_DEFAULTS, ...body, [AAD_MULTITENANT]: !!AAD_MULTITENANT_DISCOVERY.find((discoveryURL)=>wellKnownUri.startsWith(discoveryURL)) }); } async reloadJwksUri() { await keystore.call(this, true); } /* istanbul ignore next */ [inspect.custom]() { return `${this.constructor.name} ${inspect(this.metadata, { depth: Infinity, colors: process.stdout.isTTY, compact: false, sorted: true })}`; } } function resolveWellKnownUri(uri) { const parsed = url.parse(uri); if (parsed.pathname.includes('/.well-known/')) { return uri; } else { let pathname; if (parsed.pathname.endsWith('/')) { pathname = `${parsed.pathname}.well-known/openid-configuration`; } else { pathname = `${parsed.pathname}/.well-known/openid-configuration`; } return url.format({ ...parsed, pathname }); } } module.exports = Issuer; }), "[project]/node_modules/openid-client/lib/passport_strategy.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const url = __turbopack_context__.r("[externals]/url [external] (url, cjs)"); const { format } = __turbopack_context__.r("[externals]/util [external] (util, cjs)"); const cloneDeep = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/deep_clone.js [app-route] (ecmascript)"); const { RPError, OPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const { BaseClient } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/client.js [app-route] (ecmascript)"); const { random, codeChallenge } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/generators.js [app-route] (ecmascript)"); const pick = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/pick.js [app-route] (ecmascript)"); const { resolveResponseType, resolveRedirectUri } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/client.js [app-route] (ecmascript)"); function verified(err, user, info = {}) { if (err) { this.error(err); } else if (!user) { this.fail(info); } else { this.success(user, info); } } function OpenIDConnectStrategy({ client, params = {}, passReqToCallback = false, sessionKey, usePKCE = true, extras = {} } = {}, verify) { if (!(client instanceof BaseClient)) { throw new TypeError('client must be an instance of openid-client Client'); } if (typeof verify !== 'function') { throw new TypeError('verify callback must be a function'); } if (!client.issuer || !client.issuer.issuer) { throw new TypeError('client must have an issuer with an identifier'); } this._client = client; this._issuer = client.issuer; this._verify = verify; this._passReqToCallback = passReqToCallback; this._usePKCE = usePKCE; this._key = sessionKey || `oidc:${url.parse(this._issuer.issuer).hostname}`; this._params = cloneDeep(params); // state and nonce are handled in authenticate() delete this._params.state; delete this._params.nonce; this._extras = cloneDeep(extras); if (!this._params.response_type) this._params.response_type = resolveResponseType.call(client); if (!this._params.redirect_uri) this._params.redirect_uri = resolveRedirectUri.call(client); if (!this._params.scope) this._params.scope = 'openid'; if (this._usePKCE === true) { const supportedMethods = Array.isArray(this._issuer.code_challenge_methods_supported) ? this._issuer.code_challenge_methods_supported : false; if (supportedMethods && supportedMethods.includes('S256')) { this._usePKCE = 'S256'; } else if (supportedMethods && supportedMethods.includes('plain')) { this._usePKCE = 'plain'; } else if (supportedMethods) { throw new TypeError('neither code_challenge_method supported by the client is supported by the issuer'); } else { this._usePKCE = 'S256'; } } else if (typeof this._usePKCE === 'string' && ![ 'plain', 'S256' ].includes(this._usePKCE)) { throw new TypeError(`${this._usePKCE} is not valid/implemented PKCE code_challenge_method`); } this.name = url.parse(client.issuer.issuer).hostname; } OpenIDConnectStrategy.prototype.authenticate = function authenticate(req, options) { (async ()=>{ const client = this._client; if (!req.session) { throw new TypeError('authentication requires session support'); } const reqParams = client.callbackParams(req); const sessionKey = this._key; const { 0: parameter, length } = Object.keys(reqParams); /** * Start authentication request if this has no authorization response parameters or * this might a login initiated from a third party as per * https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin. */ if (length === 0 || length === 1 && parameter === 'iss') { // provide options object with extra authentication parameters const params = { state: random(), ...this._params, ...options }; if (!params.nonce && params.response_type.includes('id_token')) { params.nonce = random(); } req.session[sessionKey] = pick(params, 'nonce', 'state', 'max_age', 'response_type'); if (this._usePKCE && params.response_type.includes('code')) { const verifier = random(); req.session[sessionKey].code_verifier = verifier; switch(this._usePKCE){ case 'S256': params.code_challenge = codeChallenge(verifier); params.code_challenge_method = 'S256'; break; case 'plain': params.code_challenge = verifier; break; } } this.redirect(client.authorizationUrl(params)); return; } /* end authentication request */ /* start authentication response */ const session = req.session[sessionKey]; if (Object.keys(session || {}).length === 0) { throw new Error(format('did not find expected authorization request details in session, req.session["%s"] is %j', sessionKey, session)); } const { state, nonce, max_age: maxAge, code_verifier: codeVerifier, response_type: responseType } = session; try { delete req.session[sessionKey]; } catch (err) {} const opts = { redirect_uri: this._params.redirect_uri, ...options }; const checks = { state, nonce, max_age: maxAge, code_verifier: codeVerifier, response_type: responseType }; const tokenset = await client.callback(opts.redirect_uri, reqParams, checks, this._extras); const passReq = this._passReqToCallback; const loadUserinfo = this._verify.length > (passReq ? 3 : 2) && client.issuer.userinfo_endpoint; const args = [ tokenset, verified.bind(this) ]; if (loadUserinfo) { if (!tokenset.access_token) { throw new RPError({ message: 'expected access_token to be returned when asking for userinfo in verify callback', tokenset }); } const userinfo = await client.userinfo(tokenset); args.splice(1, 0, userinfo); } if (passReq) { args.unshift(req); } this._verify(...args); /* end authentication response */ })().catch((error)=>{ if (error instanceof OPError && error.error !== 'server_error' && !error.error.startsWith('invalid') || error instanceof RPError) { this.fail(error); } else { this.error(error); } }); }; module.exports = OpenIDConnectStrategy; }), "[project]/node_modules/openid-client/lib/index.js [app-route] (ecmascript)", ((__turbopack_context__, module, exports) => { const Issuer = __turbopack_context__.r("[project]/node_modules/openid-client/lib/issuer.js [app-route] (ecmascript)"); const { OPError, RPError } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/errors.js [app-route] (ecmascript)"); const Strategy = __turbopack_context__.r("[project]/node_modules/openid-client/lib/passport_strategy.js [app-route] (ecmascript)"); const TokenSet = __turbopack_context__.r("[project]/node_modules/openid-client/lib/token_set.js [app-route] (ecmascript)"); const { CLOCK_TOLERANCE, HTTP_OPTIONS } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/consts.js [app-route] (ecmascript)"); const generators = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/generators.js [app-route] (ecmascript)"); const { setDefaults } = __turbopack_context__.r("[project]/node_modules/openid-client/lib/helpers/request.js [app-route] (ecmascript)"); module.exports = { Issuer, Strategy, TokenSet, errors: { OPError, RPError }, custom: { setHttpOptionsDefaults: setDefaults, http_options: HTTP_OPTIONS, clock_tolerance: CLOCK_TOLERANCE }, generators }; }), ]; //# sourceMappingURL=node_modules_openid-client_0681y5w._.js.map