Fixed the OIDC token refresh
This commit is contained in:
@@ -33,10 +33,8 @@ import {
|
||||
OAuthRefreshRequest,
|
||||
} from '../../lib/oauth';
|
||||
import {
|
||||
executeFetchUserProfileStrategy,
|
||||
executeFrameHandlerStrategy,
|
||||
executeRedirectStrategy,
|
||||
executeRefreshTokenStrategy,
|
||||
PassportDoneCallback,
|
||||
} from '../../lib/passport';
|
||||
import { RedirectInfo, AuthProviderFactory, ProfileInfo } from '../types';
|
||||
@@ -45,20 +43,25 @@ type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
};
|
||||
|
||||
type OidcImpl = {
|
||||
strategy: OidcStrategy<UserinfoResponse, Client>;
|
||||
client: Client;
|
||||
};
|
||||
|
||||
export type OidcAuthProviderOptions = OAuthProviderOptions & {
|
||||
metadataUrl: string;
|
||||
tokenSignedResponseAlg?: string;
|
||||
};
|
||||
|
||||
export class OidcAuthProvider implements OAuthHandlers {
|
||||
readonly _strategy: Promise<OidcStrategy<UserinfoResponse, Client>>;
|
||||
readonly _implementation: Promise<OidcImpl>;
|
||||
|
||||
constructor(options: OidcAuthProviderOptions) {
|
||||
this._strategy = this.setupStrategy(options);
|
||||
this._implementation = this.setupStrategy(options);
|
||||
}
|
||||
|
||||
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
|
||||
const strategy = await this._strategy;
|
||||
const { strategy } = await this._implementation;
|
||||
return await executeRedirectStrategy(req, strategy, {
|
||||
accessType: 'offline',
|
||||
prompt: 'none',
|
||||
@@ -70,7 +73,7 @@ export class OidcAuthProvider implements OAuthHandlers {
|
||||
async handler(
|
||||
req: express.Request,
|
||||
): Promise<{ response: OAuthResponse; refreshToken: string }> {
|
||||
const strategy = await this._strategy;
|
||||
const { strategy } = await this._implementation;
|
||||
const { response, privateInfo } = await executeFrameHandlerStrategy<
|
||||
OAuthResponse,
|
||||
PrivateInfo
|
||||
@@ -83,31 +86,19 @@ export class OidcAuthProvider implements OAuthHandlers {
|
||||
}
|
||||
|
||||
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
|
||||
const strategy = await this._strategy;
|
||||
const refreshTokenResponse = await executeRefreshTokenStrategy(
|
||||
strategy,
|
||||
req.refreshToken,
|
||||
req.scope,
|
||||
);
|
||||
const {
|
||||
accessToken,
|
||||
params,
|
||||
refreshToken: updatedRefreshToken,
|
||||
} = refreshTokenResponse;
|
||||
|
||||
const profile = await executeFetchUserProfileStrategy(
|
||||
strategy,
|
||||
accessToken,
|
||||
params.id_token,
|
||||
);
|
||||
const { client } = await this._implementation;
|
||||
const tokenset = await client.refresh(req.refreshToken);
|
||||
if (!tokenset.access_token) {
|
||||
throw new Error('Refresh failed');
|
||||
}
|
||||
const profile = await client.userinfo(tokenset.access_token);
|
||||
|
||||
return this.populateIdentity({
|
||||
providerInfo: {
|
||||
accessToken,
|
||||
refreshToken: updatedRefreshToken,
|
||||
idToken: params.id_token,
|
||||
expiresInSeconds: params.expires_in,
|
||||
scope: params.scope,
|
||||
accessToken: tokenset.access_token,
|
||||
refreshToken: tokenset.refresh_token,
|
||||
expiresInSeconds: tokenset.expires_at,
|
||||
scope: tokenset.scope || '',
|
||||
},
|
||||
profile,
|
||||
});
|
||||
@@ -115,7 +106,7 @@ export class OidcAuthProvider implements OAuthHandlers {
|
||||
|
||||
private async setupStrategy(
|
||||
options: OidcAuthProviderOptions,
|
||||
): Promise<OidcStrategy<UserinfoResponse, Client>> {
|
||||
): Promise<OidcImpl> {
|
||||
const issuer = await Issuer.discover(options.metadataUrl);
|
||||
const client = new issuer.Client({
|
||||
client_id: options.clientId,
|
||||
@@ -159,7 +150,7 @@ export class OidcAuthProvider implements OAuthHandlers {
|
||||
},
|
||||
);
|
||||
strategy.error = console.error;
|
||||
return strategy;
|
||||
return { strategy, client };
|
||||
}
|
||||
|
||||
// Use this function to grab the user profile info from the token
|
||||
|
||||
Reference in New Issue
Block a user