Update Refresh Token, if provided by the server in the refresh grant
The OAuth2 specifications specify that during the refresh grant, the server may provide an alternate refresh Token along with the access Token when performing a token refresh. The oauth2 provider in the `auth-backend` ignores the newer refresh token during the refresh grant. This commit will update the refresh token cookie at the end of the call to the /auth/oauth2/refresh endpoint if the server provides a new refresh token grant a
This commit is contained in:
@@ -258,6 +258,13 @@ export class OAuthProvider implements AuthProviderRouteHandlers {
|
||||
|
||||
await this.populateIdentity(response.backstageIdentity);
|
||||
|
||||
if (
|
||||
response.providerInfo.refreshToken &&
|
||||
response.providerInfo.refreshToken !== refreshToken
|
||||
) {
|
||||
this.setRefreshTokenCookie(res, response.providerInfo.refreshToken);
|
||||
}
|
||||
|
||||
res.send(response);
|
||||
} catch (error) {
|
||||
res.status(401).send(`${error.message}`);
|
||||
|
||||
@@ -45,7 +45,6 @@ export const makeProfileInfo = (
|
||||
if ((!email || !picture) && idToken) {
|
||||
try {
|
||||
const decoded: Record<string, string> = jwtDecoder(idToken);
|
||||
|
||||
if (!email && decoded.email) {
|
||||
email = decoded.email;
|
||||
}
|
||||
@@ -133,7 +132,7 @@ export const executeRefreshTokenStrategy = async (
|
||||
(
|
||||
err: Error | null,
|
||||
accessToken: string,
|
||||
_refreshToken: string,
|
||||
newRefreshToken: string,
|
||||
params: any,
|
||||
) => {
|
||||
if (err) {
|
||||
@@ -149,6 +148,7 @@ export const executeRefreshTokenStrategy = async (
|
||||
|
||||
resolve({
|
||||
accessToken,
|
||||
refreshToken: newRefreshToken,
|
||||
params,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -55,6 +55,7 @@ export class OAuth2AuthProvider implements OAuthProviderHandlers {
|
||||
done: PassportDoneCallback<OAuthResponse, PrivateInfo>,
|
||||
) => {
|
||||
const profile = makeProfileInfo(rawProfile, params.id_token);
|
||||
|
||||
done(
|
||||
undefined,
|
||||
{
|
||||
@@ -101,21 +102,24 @@ export class OAuth2AuthProvider implements OAuthProviderHandlers {
|
||||
}
|
||||
|
||||
async refresh(refreshToken: string, scope: string): Promise<OAuthResponse> {
|
||||
const { accessToken, params } = await executeRefreshTokenStrategy(
|
||||
const refreshTokenResponse = await executeRefreshTokenStrategy(
|
||||
this._strategy,
|
||||
refreshToken,
|
||||
scope,
|
||||
);
|
||||
const { accessToken, params } = refreshTokenResponse;
|
||||
const updatedRefreshToken = refreshTokenResponse.refreshToken;
|
||||
|
||||
const profile = await executeFetchUserProfileStrategy(
|
||||
this._strategy,
|
||||
accessToken,
|
||||
params.id_token,
|
||||
refreshTokenResponse.accessToken,
|
||||
refreshTokenResponse.params.id_token,
|
||||
);
|
||||
|
||||
return this.populateIdentity({
|
||||
providerInfo: {
|
||||
accessToken,
|
||||
refreshToken: updatedRefreshToken,
|
||||
idToken: params.id_token,
|
||||
expiresInSeconds: params.expires_in,
|
||||
scope: params.scope,
|
||||
@@ -134,7 +138,6 @@ export class OAuth2AuthProvider implements OAuthProviderHandlers {
|
||||
if (!profile.email) {
|
||||
throw new Error('Profile does not contain a profile');
|
||||
}
|
||||
|
||||
const id = profile.email.split('@')[0];
|
||||
|
||||
return { ...response, backstageIdentity: { id } };
|
||||
|
||||
@@ -259,6 +259,10 @@ export type OAuthProviderInfo = {
|
||||
* Scopes granted for the access token.
|
||||
*/
|
||||
scope: string;
|
||||
/**
|
||||
* A refresh token issued for the signed in user
|
||||
*/
|
||||
refreshToken?: string;
|
||||
};
|
||||
|
||||
export type OAuthPrivateInfo = {
|
||||
@@ -326,6 +330,10 @@ export type RefreshTokenResponse = {
|
||||
* An access token issued for the signed in user.
|
||||
*/
|
||||
accessToken: string;
|
||||
/**
|
||||
* Optionally, the server can issue a new Refresh Token for the user
|
||||
*/
|
||||
refreshToken?: string;
|
||||
params: any;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user