mirror of
https://github.com/hanzoai/openid-client.git
synced 2026-09-24 17:01:10 +00:00
chore(release): 6.3.3
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [6.3.3](https://github.com/panva/openid-client/compare/v6.3.2...v6.3.3) (2025-02-24)
|
||||
|
||||
## [6.3.2](https://github.com/panva/openid-client/compare/v6.3.1...v6.3.2) (2025-02-24)
|
||||
|
||||
|
||||
|
||||
Vendored
+2019
File diff suppressed because it is too large
Load Diff
+1069
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Vendored
+109
@@ -0,0 +1,109 @@
|
||||
import * as client from './index.js';
|
||||
import type { PrivateKey } from 'oauth4webapi';
|
||||
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;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* URL to which the authorization server will redirect the user after
|
||||
* obtaining authorization. This will be used as the `redirect_uri`
|
||||
* authorization request parameter unless specified elsewhere.
|
||||
*/
|
||||
callbackURL?: string;
|
||||
/**
|
||||
* Authorization Request Scope. This will be used as the `scope` authorization
|
||||
* request parameter unless specified elsewhere.
|
||||
*/
|
||||
scope?: 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 | PrivateKey | [client.CryptoKey | 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);
|
||||
/**
|
||||
* Return extra parameters to be included an authorization request.
|
||||
*/
|
||||
authorizationRequestParams<TOptions extends passport.AuthenticateOptions = passport.AuthenticateOptions>(req: express.Request, options: TOptions): URLSearchParams | Record<string, string> | undefined;
|
||||
/**
|
||||
* Return extra parameters to be included in the authorization code grant
|
||||
* token endpoint request.
|
||||
*/
|
||||
authorizationCodeGrantParameters<TOptions extends passport.AuthenticateOptions = passport.AuthenticateOptions>(req: express.Request, options: TOptions): URLSearchParams | Record<string, string> | undefined;
|
||||
/**
|
||||
* Return the current request URL.
|
||||
*
|
||||
* - Its `searchParams` are used as the authorization response parameters when
|
||||
* the response type used by the client is `code`
|
||||
* - Its value stripped of `searchParams` and `hash` is used as the
|
||||
* `redirect_uri` authorization code grant token endpoint parameter
|
||||
*
|
||||
* This function may need to be overridden by users if its return value does
|
||||
* not match the actual URL the authorization server redirected the user to.
|
||||
*/
|
||||
currentUrl(req: express.Request): URL;
|
||||
/**
|
||||
* Authenticate request.
|
||||
*/
|
||||
authenticate<TOptions extends passport.AuthenticateOptions = passport.AuthenticateOptions>(this: passport.StrategyCreated<Strategy, Strategy & passport.StrategyCreatedStatic>, req: express.Request, options: TOptions): void;
|
||||
}
|
||||
export {};
|
||||
@@ -0,0 +1,181 @@
|
||||
import * as client from './index.js';
|
||||
export class Strategy {
|
||||
name;
|
||||
_config;
|
||||
_verify;
|
||||
_callbackURL;
|
||||
_sessionKey;
|
||||
_passReqToCallback;
|
||||
_proxy;
|
||||
_usePAR;
|
||||
_useJAR;
|
||||
_DPoP;
|
||||
_scope;
|
||||
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;
|
||||
this._callbackURL = options.callbackURL;
|
||||
this._passReqToCallback = options.passReqToCallback;
|
||||
}
|
||||
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);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
authorizationCodeGrantParameters(req, options) {
|
||||
return {};
|
||||
}
|
||||
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());
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (this._scope && !redirectTo.searchParams.has('scope')) {
|
||||
redirectTo.searchParams.set('scope', this._scope);
|
||||
}
|
||||
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 stateData = req.session[sessionKey];
|
||||
if (!stateData?.code_verifier) {
|
||||
return this.fail({
|
||||
message: 'Unable to verify authorization request state',
|
||||
});
|
||||
}
|
||||
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}://${req.host}${req.originalUrl ?? req.url}`);
|
||||
}
|
||||
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 ((req.method === 'GET' && currentUrl.searchParams.size === 0) ||
|
||||
(currentUrl.searchParams.size === 1 && currentUrl.searchParams.has('iss'))) {
|
||||
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",
|
||||
"name": "@panva/openid-client",
|
||||
"version": "6.3.2",
|
||||
"version": "6.3.3",
|
||||
"exports": "./src/index.ts",
|
||||
"publish": {
|
||||
"include": [
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "openid-client",
|
||||
"version": "6.3.2",
|
||||
"version": "6.3.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "openid-client",
|
||||
"version": "6.3.2",
|
||||
"version": "6.3.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jose": "^6.0.6",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openid-client",
|
||||
"version": "6.3.2",
|
||||
"version": "6.3.3",
|
||||
"description": "OAuth 2 / OpenID Connect Client API for JavaScript Runtimes",
|
||||
"keywords": [
|
||||
"access token",
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ if (
|
||||
typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ') // prettier-ignore
|
||||
) {
|
||||
const NAME = 'openid-client'
|
||||
const VERSION = 'v6.3.2'
|
||||
const VERSION = 'v6.3.3'
|
||||
USER_AGENT = `${NAME}/${VERSION}`
|
||||
headers = { 'user-agent': USER_AGENT }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user