Fix refresh reuse bug in Github provider

Currently when the Github provider refreshes an access token it doesn't forward
the new refresh token to the caller. As Github only allows refresh tokens to be
used once, the next refresh call will fail.

This change fixes the bug by returning the new refresh token upon refresh.

This change is similar to 25a613bdd7 (#7110) for
the GitLab provider.

Signed-off-by: Crevil <bjoern.soerensen@gmail.com>
This commit is contained in:
Crevil
2021-10-14 21:26:43 +02:00
parent 72be1cf988
commit de3e26aecc
3 changed files with 66 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Fix a bug preventing an access token to be refreshed a second time with the GitHub provider.
@@ -278,5 +278,59 @@ describe('GithubAuthProvider', () => {
refreshToken: 'refresh-me',
});
});
it('should forward a new refresh token on refresh', async () => {
const mockRefreshToken = jest.spyOn(
helpers,
'executeRefreshTokenStrategy',
) as unknown as jest.MockedFunction<() => Promise<{}>>;
mockRefreshToken.mockResolvedValueOnce({
accessToken: 'a.b.c',
refreshToken: 'dont-forget-to-send-refresh',
params: {
id_token: 'my-id',
expires_in: '123',
scope: 'read_user',
},
});
const mockUserProfile = jest.spyOn(
helpers,
'executeFetchUserProfileStrategy',
) as unknown as jest.MockedFunction<() => Promise<PassportProfile>>;
mockUserProfile.mockResolvedValueOnce({
id: 'mockid',
username: 'mockuser',
provider: 'github',
displayName: 'Mocked User',
emails: [
{
value: 'mockuser@gmail.com',
},
],
});
const response = await provider.refresh({} as any);
expect(response).toEqual({
backstageIdentity: {
id: 'mockuser',
token: 'token-for-mockuser',
},
profile: {
displayName: 'Mocked User',
email: 'mockuser@gmail.com',
picture: undefined,
},
providerInfo: {
accessToken: 'a.b.c',
refreshToken: 'dont-forget-to-send-refresh',
expiresInSeconds: 123,
scope: 'read_user',
},
});
});
});
});
@@ -126,7 +126,11 @@ export class GithubAuthProvider implements OAuthHandlers {
}
async refresh(req: OAuthRefreshRequest): Promise<OAuthResponse> {
const { accessToken, params } = await executeRefreshTokenStrategy(
const {
accessToken,
refreshToken: newRefreshToken,
params,
} = await executeRefreshTokenStrategy(
this._strategy,
req.refreshToken,
req.scope,
@@ -139,7 +143,7 @@ export class GithubAuthProvider implements OAuthHandlers {
fullProfile,
params,
accessToken,
refreshToken: req.refreshToken,
refreshToken: newRefreshToken,
});
}
@@ -150,6 +154,7 @@ export class GithubAuthProvider implements OAuthHandlers {
const response: OAuthResponse = {
providerInfo: {
accessToken: result.accessToken,
refreshToken: result.refreshToken, // GitHub expires the old refresh token when used
scope: result.params.scope,
expiresInSeconds:
expiresInStr === undefined ? undefined : Number(expiresInStr),