mirror of
https://github.com/hanzoai/openid-client.git
synced 2026-09-24 17:01:10 +00:00
chore(release): 6.8.4
This commit is contained in:
@@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||||
|
|
||||||
|
## [6.8.4](https://github.com/panva/openid-client/compare/v6.8.3...v6.8.4) (2026-04-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* apply optional non-repudiation on generic grant ID Tokens ([6202888](https://github.com/panva/openid-client/commit/62028884943a1987eb1ddedc9efc01953189a14f))
|
||||||
|
* filter jwe decryption keys by algorithm ([34e2ffd](https://github.com/panva/openid-client/commit/34e2ffdea5b3b5afffeff55208aaad1d3b42d0fb))
|
||||||
|
* preserve poll abort signals on requests ([96a2d17](https://github.com/panva/openid-client/commit/96a2d176b982196f432990ef1f64978cb7cb881c))
|
||||||
|
* retry dpop nonce errors for generic grants ([498c4d9](https://github.com/panva/openid-client/commit/498c4d9c098340ad2f8b9dbb91bfe7f1166a3fd4))
|
||||||
|
|
||||||
## [6.8.3](https://github.com/panva/openid-client/compare/v6.8.2...v6.8.3) (2026-04-13)
|
## [6.8.3](https://github.com/panva/openid-client/compare/v6.8.2...v6.8.3) (2026-04-13)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Vendored
+2256
File diff suppressed because it is too large
Load Diff
+1357
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Vendored
+247
@@ -0,0 +1,247 @@
|
|||||||
|
import * as client from './index.js';
|
||||||
|
import type * as express from 'express';
|
||||||
|
import type passport from 'passport';
|
||||||
|
export type VerifyFunction = (
|
||||||
|
/**
|
||||||
|
* Parsed Token Endpoint Response returned by the authorization server with
|
||||||
|
* attached helpers.
|
||||||
|
*/
|
||||||
|
tokens: client.TokenEndpointResponse & client.TokenEndpointResponseHelpers, verified: passport.AuthenticateCallback) => void;
|
||||||
|
export type VerifyFunctionWithRequest = (req: express.Request,
|
||||||
|
/**
|
||||||
|
* Parsed Token Endpoint Response returned by the authorization server with
|
||||||
|
* attached helpers.
|
||||||
|
*/
|
||||||
|
tokens: client.TokenEndpointResponse & client.TokenEndpointResponseHelpers, verified: passport.AuthenticateCallback) => void;
|
||||||
|
export interface AuthenticateOptions extends passport.AuthenticateOptions {
|
||||||
|
/**
|
||||||
|
* OAuth 2.0 Resource Indicator(s) to use for the request either for the
|
||||||
|
* authorization request or token endpoint request, depending on whether it's
|
||||||
|
* part of {@link Strategy.authenticate} options during the initial redirect or
|
||||||
|
* callback phase.
|
||||||
|
*
|
||||||
|
* This is a request-specific override for {@link StrategyOptions.resource}.
|
||||||
|
*/
|
||||||
|
resource?: string | string[];
|
||||||
|
/**
|
||||||
|
* Login Hint to use for the authorization request. It is ignored for token
|
||||||
|
* endpoint requests.
|
||||||
|
*/
|
||||||
|
loginHint?: string;
|
||||||
|
/**
|
||||||
|
* ID Token Hint to use for the authorization request. It is ignored for token
|
||||||
|
* endpoint requests.
|
||||||
|
*/
|
||||||
|
idTokenHint?: string;
|
||||||
|
/**
|
||||||
|
* OAuth 2.0 Rich Authorization Requests to use for the authorization request.
|
||||||
|
* It is ignored for token endpoint requests.
|
||||||
|
*
|
||||||
|
* This is a request-specific override for
|
||||||
|
* {@link StrategyOptions.authorizationDetails}.
|
||||||
|
*/
|
||||||
|
authorizationDetails?: client.AuthorizationDetails | client.AuthorizationDetails[];
|
||||||
|
/**
|
||||||
|
* OpenID Connect prompt. This will be used as the `prompt` authorization
|
||||||
|
* request parameter unless specified through other means.
|
||||||
|
*/
|
||||||
|
prompt?: string;
|
||||||
|
/**
|
||||||
|
* OAuth 2.0 scope to use for the authorization request. It is ignored for
|
||||||
|
* token endpoint requests.
|
||||||
|
*
|
||||||
|
* This is a request-specific override for {@link StrategyOptions.scope}.
|
||||||
|
*/
|
||||||
|
scope?: string | string[];
|
||||||
|
/**
|
||||||
|
* The state option is ignored by this strategy.
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
state?: never;
|
||||||
|
/**
|
||||||
|
* OAuth 2.0 redirect_uri to use for the request either for the authorization
|
||||||
|
* request or token endpoint request, depending on whether it's part of
|
||||||
|
* {@link Strategy.authenticate} options during the initial redirect or
|
||||||
|
* callback phase.
|
||||||
|
*
|
||||||
|
* This is a request-specific override for {@link StrategyOptions.callbackURL}.
|
||||||
|
*
|
||||||
|
* Note: The option is called "callbackURL" to keep some continuity and
|
||||||
|
* familiarity with other oauth-based strategies in the passport ecosystem,
|
||||||
|
* namely "passport-oauth2".
|
||||||
|
*/
|
||||||
|
callbackURL?: URL | string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Retrieve an openid-client DPoPHandle for a given request.
|
||||||
|
*/
|
||||||
|
export type getDPoPHandle = (req: express.Request) => Promise<client.DPoPHandle | undefined> | client.DPoPHandle | undefined;
|
||||||
|
interface StrategyOptionsBase {
|
||||||
|
/**
|
||||||
|
* Openid-client Configuration instance.
|
||||||
|
*/
|
||||||
|
config: client.Configuration;
|
||||||
|
/**
|
||||||
|
* Name of the strategy, default is the host component of the authorization
|
||||||
|
* server's issuer identifier.
|
||||||
|
*/
|
||||||
|
name?: string;
|
||||||
|
/**
|
||||||
|
* Property in the session to use for storing the authorization request state,
|
||||||
|
* default is the host component of the authorization server's issuer
|
||||||
|
* identifier.
|
||||||
|
*/
|
||||||
|
sessionKey?: string;
|
||||||
|
/**
|
||||||
|
* Function used to retrieve an openid-client DPoPHandle for a given request,
|
||||||
|
* when provided the strategy will use DPoP where applicable.
|
||||||
|
*/
|
||||||
|
DPoP?: getDPoPHandle;
|
||||||
|
/**
|
||||||
|
* An absolute URL to which the authorization server will redirect the user
|
||||||
|
* after obtaining authorization. The {@link !URL} instance's `href` will be
|
||||||
|
* used as the `redirect_uri` authorization request and token endpoint request
|
||||||
|
* parameters. When string is provided it will be internally casted to a
|
||||||
|
* {@link URL} instance.
|
||||||
|
*/
|
||||||
|
callbackURL?: URL | string;
|
||||||
|
/**
|
||||||
|
* OAuth 2.0 Authorization Request Scope. This will be used as the `scope`
|
||||||
|
* authorization request parameter unless specified through other means.
|
||||||
|
*/
|
||||||
|
scope?: string;
|
||||||
|
/**
|
||||||
|
* OAuth 2.0 Rich Authorization Request(s). This will be used as the
|
||||||
|
* `authorization_details` authorization request parameter unless specified
|
||||||
|
* through other means.
|
||||||
|
*/
|
||||||
|
authorizationDetails?: client.AuthorizationDetails | client.AuthorizationDetails[];
|
||||||
|
/**
|
||||||
|
* OAuth 2.0 Resource Indicator(s). This will be used as the `resource`
|
||||||
|
* authorization request parameter unless specified through other means.
|
||||||
|
*/
|
||||||
|
resource?: string | string[];
|
||||||
|
/**
|
||||||
|
* Whether the strategy will use PAR. Default is `false`.
|
||||||
|
*/
|
||||||
|
usePAR?: boolean;
|
||||||
|
/**
|
||||||
|
* Whether the strategy will use JAR. Its value can be a private key to sign
|
||||||
|
* with or an array with the private key and a modify assertion function that
|
||||||
|
* will be used to modify the request object before it is signed. Default is
|
||||||
|
* `false`.
|
||||||
|
*/
|
||||||
|
useJAR?: false | client.CryptoKey | client.PrivateKey | [client.CryptoKey | client.PrivateKey, client.ModifyAssertionFunction];
|
||||||
|
/**
|
||||||
|
* Whether the verify function should get the `req` as first argument instead.
|
||||||
|
* Default is `false`.
|
||||||
|
*/
|
||||||
|
passReqToCallback?: boolean;
|
||||||
|
}
|
||||||
|
export interface StrategyOptions extends StrategyOptionsBase {
|
||||||
|
passReqToCallback?: false;
|
||||||
|
}
|
||||||
|
export interface StrategyOptionsWithRequest extends StrategyOptionsBase {
|
||||||
|
passReqToCallback: true;
|
||||||
|
}
|
||||||
|
export declare class Strategy implements passport.Strategy {
|
||||||
|
/**
|
||||||
|
* Name of the strategy
|
||||||
|
*/
|
||||||
|
readonly name: string;
|
||||||
|
constructor(options: StrategyOptions, verify: VerifyFunction);
|
||||||
|
constructor(options: StrategyOptionsWithRequest, verify: VerifyFunctionWithRequest);
|
||||||
|
/**
|
||||||
|
* [Strategy method] Return additional authorization request parameters.
|
||||||
|
*
|
||||||
|
* This method is intended to be overloaded if additional parameters need to
|
||||||
|
* be included an authorization request are needed.
|
||||||
|
*
|
||||||
|
* By default this method takes care of adding the corresponding authorization
|
||||||
|
* endpoint parameters when
|
||||||
|
* {@link AuthenticateOptions.authorizationDetails authorizationDetails},
|
||||||
|
* {@link AuthenticateOptions.idTokenHint idTokenHint},
|
||||||
|
* {@link AuthenticateOptions.loginHint loginHint},
|
||||||
|
* {@link AuthenticateOptions.prompt prompt},
|
||||||
|
* {@link AuthenticateOptions.resource resource}, or
|
||||||
|
* {@link AuthenticateOptions.scope scope} properties of
|
||||||
|
* {@link AuthenticateOptions} are used.
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param options This is the value originally passed to
|
||||||
|
* `passport.authenticate()` as its `options` argument.
|
||||||
|
*/
|
||||||
|
authorizationRequestParams<TOptions extends AuthenticateOptions>(req: express.Request, options: TOptions): URLSearchParams | Record<string, string> | undefined;
|
||||||
|
/**
|
||||||
|
* [Strategy method] Return additional token endpoint request parameters.
|
||||||
|
*
|
||||||
|
* This method is intended to be overloaded if additional parameters to be
|
||||||
|
* included in the authorization code grant token endpoint request are
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* By default this method takes care of adding the `resource` token endpoint
|
||||||
|
* parameters when {@link AuthenticateOptions.resource} is used.
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param options This is the value originally passed to
|
||||||
|
* `passport.authenticate()` as its `options` argument.
|
||||||
|
*/
|
||||||
|
authorizationCodeGrantParameters<TOptions extends AuthenticateOptions>(req: express.Request, options: TOptions): URLSearchParams | Record<string, string> | undefined;
|
||||||
|
/**
|
||||||
|
* [Strategy method] Return the current request URL.
|
||||||
|
*
|
||||||
|
* This method is intended to be overloaded if its return value does not match
|
||||||
|
* the actual URL the authorization server redirected the user to.
|
||||||
|
*
|
||||||
|
* - Its `searchParams` are used as the authorization response parameters when
|
||||||
|
* the authorization response request is a GET.
|
||||||
|
* - Its resulting `href` value (after stripping its `searchParams` and `hash`)
|
||||||
|
* is used as the `redirect_uri` authorization code grant token endpoint
|
||||||
|
* parameter unless {@link AuthenticateOptions.callbackURL}, or
|
||||||
|
* {@link StrategyOptionsBase.callbackURL} are used in which case those are
|
||||||
|
* used as the `redirect_uri` parameter instead.
|
||||||
|
*
|
||||||
|
* Default is
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* function currentUrl(req: express.Request): URL {
|
||||||
|
* return new URL(
|
||||||
|
* `${req.protocol}://${req.host}${req.originalUrl ?? req.url}`,
|
||||||
|
* )
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* When behind a reverse proxy it assumes common proxy headers are in use and
|
||||||
|
* that
|
||||||
|
* {@link https://expressjs.com/en/guide/behind-proxies.html Express (behind proxies docs)},
|
||||||
|
* or
|
||||||
|
* {@link https://fastify.dev/docs/latest/Reference/Server/#trustproxy Fastify (trustProxy docs)}
|
||||||
|
* are properly configured to trust them.
|
||||||
|
*/
|
||||||
|
currentUrl(req: express.Request): URL;
|
||||||
|
/**
|
||||||
|
* [Strategy method] Determine whether to initiate an authorization request.
|
||||||
|
*
|
||||||
|
* This method is intended to be overloaded if custom logic for determining
|
||||||
|
* whether to initiate an authorization request or process an authorization
|
||||||
|
* response.
|
||||||
|
*
|
||||||
|
* By default, this method returns `true` when the request method is GET and
|
||||||
|
* the current URL does not contain `code`, `error`, or `response` query
|
||||||
|
* parameters, indicating that this is an initial authorization request rather
|
||||||
|
* than a callback from the authorization server.
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param currentUrl The current request URL as determined by
|
||||||
|
* {@link Strategy.currentUrl}
|
||||||
|
* @param options This is the value originally passed to
|
||||||
|
* `passport.authenticate()` as its `options` argument.
|
||||||
|
*/
|
||||||
|
shouldInitiateAuthRequest<TOptions extends AuthenticateOptions>(req: express.Request, currentUrl: URL, options: TOptions): boolean;
|
||||||
|
/**
|
||||||
|
* [Passport method] Authenticate the request.
|
||||||
|
*/
|
||||||
|
authenticate<TOptions extends AuthenticateOptions>(this: passport.StrategyCreated<Strategy, Strategy & passport.StrategyCreatedStatic>, req: express.Request, options: TOptions): void;
|
||||||
|
}
|
||||||
|
export {};
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
import * as client from './index.js';
|
||||||
|
function setResource(params, resource) {
|
||||||
|
if (Array.isArray(resource)) {
|
||||||
|
for (const value of resource) {
|
||||||
|
params.append('resource', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
params.set('resource', resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function setAuthorizationDetails(params, authorizationDetails) {
|
||||||
|
if (Array.isArray(authorizationDetails)) {
|
||||||
|
params.set('authorization_details', JSON.stringify(authorizationDetails));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
params.set('authorization_details', JSON.stringify([authorizationDetails]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function host(req) {
|
||||||
|
try {
|
||||||
|
const trust = req.app.get('trust proxy fn');
|
||||||
|
let val = req.get('x-forwarded-host');
|
||||||
|
if (!val || !trust(req.socket.remoteAddress, 0)) {
|
||||||
|
val = req.get('host');
|
||||||
|
}
|
||||||
|
else if (val.indexOf(',') !== -1) {
|
||||||
|
val = val.substring(0, val.indexOf(',')).trimEnd();
|
||||||
|
}
|
||||||
|
return val || undefined;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return req.host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class Strategy {
|
||||||
|
name;
|
||||||
|
_config;
|
||||||
|
_verify;
|
||||||
|
_callbackURL;
|
||||||
|
_sessionKey;
|
||||||
|
_passReqToCallback;
|
||||||
|
_usePAR;
|
||||||
|
_useJAR;
|
||||||
|
_DPoP;
|
||||||
|
_scope;
|
||||||
|
_resource;
|
||||||
|
_authorizationDetails;
|
||||||
|
constructor(options, verify) {
|
||||||
|
if (!(options?.config instanceof client.Configuration)) {
|
||||||
|
throw new TypeError();
|
||||||
|
}
|
||||||
|
if (typeof verify !== 'function') {
|
||||||
|
throw new TypeError();
|
||||||
|
}
|
||||||
|
const { host } = new URL(options.config.serverMetadata().issuer);
|
||||||
|
this.name = options.name ?? host;
|
||||||
|
this._sessionKey = options.sessionKey ?? host;
|
||||||
|
this._DPoP = options.DPoP;
|
||||||
|
this._config = options.config;
|
||||||
|
this._scope = options.scope;
|
||||||
|
this._useJAR = options.useJAR;
|
||||||
|
this._usePAR = options.usePAR;
|
||||||
|
this._verify = verify;
|
||||||
|
if (options.callbackURL) {
|
||||||
|
this._callbackURL = new URL(options.callbackURL);
|
||||||
|
}
|
||||||
|
this._passReqToCallback = options.passReqToCallback;
|
||||||
|
this._resource = options.resource;
|
||||||
|
this._authorizationDetails = options.authorizationDetails;
|
||||||
|
}
|
||||||
|
authorizationRequestParams(req, options) {
|
||||||
|
let params = new URLSearchParams();
|
||||||
|
if (options?.scope) {
|
||||||
|
if (Array.isArray(options.scope) && options.scope.length) {
|
||||||
|
params.set('scope', options.scope.join(' '));
|
||||||
|
}
|
||||||
|
else if (typeof options.scope === 'string' && options.scope.length) {
|
||||||
|
params.set('scope', options.scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options?.prompt) {
|
||||||
|
params.set('prompt', options.prompt);
|
||||||
|
}
|
||||||
|
if (options?.loginHint) {
|
||||||
|
params.set('login_hint', options.loginHint);
|
||||||
|
}
|
||||||
|
if (options?.idTokenHint) {
|
||||||
|
params.set('id_token_hint', options.idTokenHint);
|
||||||
|
}
|
||||||
|
if (options?.resource) {
|
||||||
|
setResource(params, options.resource);
|
||||||
|
}
|
||||||
|
if (options?.authorizationDetails) {
|
||||||
|
setAuthorizationDetails(params, options.authorizationDetails);
|
||||||
|
}
|
||||||
|
if (options?.callbackURL) {
|
||||||
|
params.set('redirect_uri', new URL(options.callbackURL).href);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
authorizationCodeGrantParameters(req, options) {
|
||||||
|
let params = new URLSearchParams();
|
||||||
|
if (options?.resource) {
|
||||||
|
setResource(params, options.resource);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
async authorizationRequest(req, options) {
|
||||||
|
try {
|
||||||
|
let redirectTo = client.buildAuthorizationUrl(this._config, new URLSearchParams(this.authorizationRequestParams(req, options)));
|
||||||
|
if (redirectTo.searchParams.get('response_type')?.includes('id_token')) {
|
||||||
|
redirectTo.searchParams.set('nonce', client.randomNonce());
|
||||||
|
if (!redirectTo.searchParams.has('response_mode')) {
|
||||||
|
redirectTo.searchParams.set('response_mode', 'form_post');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const codeVerifier = client.randomPKCECodeVerifier();
|
||||||
|
const code_challenge = await client.calculatePKCECodeChallenge(codeVerifier);
|
||||||
|
redirectTo.searchParams.set('code_challenge', code_challenge);
|
||||||
|
redirectTo.searchParams.set('code_challenge_method', 'S256');
|
||||||
|
if (!this._config.serverMetadata().supportsPKCE() &&
|
||||||
|
!redirectTo.searchParams.has('nonce')) {
|
||||||
|
redirectTo.searchParams.set('state', client.randomState());
|
||||||
|
}
|
||||||
|
if (this._callbackURL && !redirectTo.searchParams.has('redirect_uri')) {
|
||||||
|
redirectTo.searchParams.set('redirect_uri', this._callbackURL.href);
|
||||||
|
}
|
||||||
|
if (this._scope && !redirectTo.searchParams.has('scope')) {
|
||||||
|
redirectTo.searchParams.set('scope', this._scope);
|
||||||
|
}
|
||||||
|
if (this._resource && !redirectTo.searchParams.has('resource')) {
|
||||||
|
setResource(redirectTo.searchParams, this._resource);
|
||||||
|
}
|
||||||
|
if (this._authorizationDetails &&
|
||||||
|
!redirectTo.searchParams.has('authorization_details')) {
|
||||||
|
setAuthorizationDetails(redirectTo.searchParams, this._authorizationDetails);
|
||||||
|
}
|
||||||
|
const DPoP = await this._DPoP?.(req);
|
||||||
|
if (DPoP && !redirectTo.searchParams.has('dpop_jkt')) {
|
||||||
|
redirectTo.searchParams.set('dpop_jkt', await DPoP.calculateThumbprint());
|
||||||
|
}
|
||||||
|
const sessionKey = this._sessionKey;
|
||||||
|
const stateData = { code_verifier: codeVerifier };
|
||||||
|
let nonce;
|
||||||
|
if ((nonce = redirectTo.searchParams.get('nonce'))) {
|
||||||
|
stateData.nonce = nonce;
|
||||||
|
}
|
||||||
|
let state;
|
||||||
|
if ((state = redirectTo.searchParams.get('state'))) {
|
||||||
|
stateData.state = state;
|
||||||
|
}
|
||||||
|
let max_age;
|
||||||
|
if ((max_age = redirectTo.searchParams.get('max_age'))) {
|
||||||
|
stateData.max_age = parseInt(max_age, 10);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
req.session[sessionKey] = stateData;
|
||||||
|
if (this._useJAR) {
|
||||||
|
let key;
|
||||||
|
let modifyAssertion;
|
||||||
|
if (Array.isArray(this._useJAR)) {
|
||||||
|
;
|
||||||
|
[key, modifyAssertion] = this._useJAR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
key = this._useJAR;
|
||||||
|
}
|
||||||
|
redirectTo = await client.buildAuthorizationUrlWithJAR(this._config, redirectTo.searchParams, key, { [client.modifyAssertion]: modifyAssertion });
|
||||||
|
}
|
||||||
|
if (this._usePAR) {
|
||||||
|
redirectTo = await client.buildAuthorizationUrlWithPAR(this._config, redirectTo.searchParams, { DPoP });
|
||||||
|
}
|
||||||
|
return this.redirect(redirectTo.href);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
return this.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async authorizationCodeGrant(req, currentUrl, options) {
|
||||||
|
try {
|
||||||
|
const sessionKey = this._sessionKey;
|
||||||
|
const session = req
|
||||||
|
.session;
|
||||||
|
const stateData = session[sessionKey];
|
||||||
|
delete session[sessionKey];
|
||||||
|
if (!stateData?.code_verifier) {
|
||||||
|
return this.fail({
|
||||||
|
message: 'Unable to verify authorization request state',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.callbackURL || this._callbackURL) {
|
||||||
|
const _currentUrl = new URL(options.callbackURL || this._callbackURL);
|
||||||
|
for (const [k, v] of currentUrl.searchParams.entries()) {
|
||||||
|
_currentUrl.searchParams.append(k, v);
|
||||||
|
}
|
||||||
|
currentUrl = _currentUrl;
|
||||||
|
}
|
||||||
|
let input = currentUrl;
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
input = new Request(currentUrl.href, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: Object.entries(req.headersDistinct).reduce((acc, [key, values]) => {
|
||||||
|
for (const value of values) {
|
||||||
|
acc.append(key, value);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, new Headers()),
|
||||||
|
body: req,
|
||||||
|
duplex: 'half',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const tokens = await client.authorizationCodeGrant(this._config, input, {
|
||||||
|
pkceCodeVerifier: stateData.code_verifier,
|
||||||
|
expectedNonce: stateData.nonce,
|
||||||
|
expectedState: stateData.state,
|
||||||
|
maxAge: stateData.max_age,
|
||||||
|
}, this.authorizationCodeGrantParameters(req, options), { DPoP: await this._DPoP?.(req) });
|
||||||
|
const verified = (err, user, info) => {
|
||||||
|
if (err)
|
||||||
|
return this.error(err);
|
||||||
|
if (!user)
|
||||||
|
return this.fail(info);
|
||||||
|
return this.success(user);
|
||||||
|
};
|
||||||
|
if (options.passReqToCallback ?? this._passReqToCallback) {
|
||||||
|
return this._verify(req, tokens, verified);
|
||||||
|
}
|
||||||
|
return this._verify(tokens, verified);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (err instanceof client.AuthorizationResponseError &&
|
||||||
|
err.error === 'access_denied') {
|
||||||
|
return this.fail({
|
||||||
|
message: err.error_description || err.error,
|
||||||
|
...Object.fromEntries(err.cause.entries()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentUrl(req) {
|
||||||
|
return new URL(`${req.protocol}://${host(req)}${req.originalUrl ?? req.url}`);
|
||||||
|
}
|
||||||
|
shouldInitiateAuthRequest(req, currentUrl, options) {
|
||||||
|
return (req.method === 'GET' &&
|
||||||
|
!currentUrl.searchParams.has('code') &&
|
||||||
|
!currentUrl.searchParams.has('error') &&
|
||||||
|
!currentUrl.searchParams.has('response'));
|
||||||
|
}
|
||||||
|
authenticate(req, options) {
|
||||||
|
if (!req.session) {
|
||||||
|
return this.error(new Error('OAuth 2.0 authentication requires session support. Did you forget to use express-session middleware?'));
|
||||||
|
}
|
||||||
|
const currentUrl = this.currentUrl(req);
|
||||||
|
if (this.shouldInitiateAuthRequest(req, currentUrl, options)) {
|
||||||
|
Strategy.prototype.authorizationRequest.call(this, req, options);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Strategy.prototype.authorizationCodeGrant.call(this, req, currentUrl, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=passport.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://jsr.io/schema/config-file.v1.json",
|
"$schema": "https://jsr.io/schema/config-file.v1.json",
|
||||||
"name": "@panva/openid-client",
|
"name": "@panva/openid-client",
|
||||||
"version": "6.8.3",
|
"version": "6.8.4",
|
||||||
"exports": "./src/index.ts",
|
"exports": "./src/index.ts",
|
||||||
"publish": {
|
"publish": {
|
||||||
"include": [
|
"include": [
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "openid-client",
|
"name": "openid-client",
|
||||||
"version": "6.8.3",
|
"version": "6.8.4",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "openid-client",
|
"name": "openid-client",
|
||||||
"version": "6.8.3",
|
"version": "6.8.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jose": "^6.2.2",
|
"jose": "^6.2.2",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openid-client",
|
"name": "openid-client",
|
||||||
"version": "6.8.3",
|
"version": "6.8.4",
|
||||||
"description": "OAuth 2 / OpenID Connect Client API for JavaScript Runtimes",
|
"description": "OAuth 2 / OpenID Connect Client API for JavaScript Runtimes",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"access token",
|
"access token",
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ if (
|
|||||||
typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ') // prettier-ignore
|
typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ') // prettier-ignore
|
||||||
) {
|
) {
|
||||||
const NAME = 'openid-client'
|
const NAME = 'openid-client'
|
||||||
const VERSION = 'v6.8.3'
|
const VERSION = 'v6.8.4'
|
||||||
USER_AGENT = `${NAME}/${VERSION}`
|
USER_AGENT = `${NAME}/${VERSION}`
|
||||||
headers = { 'user-agent': USER_AGENT }
|
headers = { 'user-agent': USER_AGENT }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user