auth-backend-module-github-provider: reject refresh for sessions without granted scope
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend-module-github-provider': patch
|
||||
---
|
||||
|
||||
Fixed a bug where the requested scope was ignored when refreshing sessions for a GitHub OAuth App. This would lead to access tokens being returned that didn't have the requested scope, and in turn errors when trying to use these tokens.
|
||||
|
||||
As part of this fix all existing sessions are being revoked in order to ensure that they receive the correct scope.
|
||||
@@ -42,7 +42,7 @@ describe('githubAuthenticator', () => {
|
||||
accessToken: 'my-token',
|
||||
scope: 'user:read',
|
||||
tokenType: 'bearer',
|
||||
refreshToken: 'access-token.my-token',
|
||||
refreshToken: 'access-token-v2.my-token',
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -105,9 +105,10 @@ describe('githubAuthenticator', () => {
|
||||
await expect(
|
||||
githubAuthenticator.refresh(
|
||||
{
|
||||
refreshToken: 'access-token.my-token',
|
||||
refreshToken: 'access-token-v2.my-token',
|
||||
req: {} as any,
|
||||
scope: 'user:read',
|
||||
scopeAlreadyGranted: true,
|
||||
},
|
||||
{
|
||||
fetchProfile: async _input => ({ id: 'id' } as PassportProfile),
|
||||
@@ -119,11 +120,28 @@ describe('githubAuthenticator', () => {
|
||||
accessToken: 'my-token',
|
||||
scope: 'user:read',
|
||||
tokenType: 'bearer',
|
||||
refreshToken: 'access-token.my-token',
|
||||
refreshToken: 'access-token-v2.my-token',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail refresh if scope has not already been granted', async () => {
|
||||
await expect(
|
||||
githubAuthenticator.refresh(
|
||||
{
|
||||
refreshToken: 'access-token-v2.my-token',
|
||||
req: {} as any,
|
||||
scope: 'user:read',
|
||||
},
|
||||
{
|
||||
fetchProfile: async _input => ({ id: 'id' } as PassportProfile),
|
||||
} as PassportOAuthAuthenticatorHelper,
|
||||
),
|
||||
).rejects.toThrow(
|
||||
'Refresh failed, session has not been granted the requested scope',
|
||||
);
|
||||
});
|
||||
|
||||
it('should refresh with refresh token', async () => {
|
||||
const res = {};
|
||||
await expect(
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
PassportProfile,
|
||||
} from '@backstage/plugin-auth-node';
|
||||
|
||||
const ACCESS_TOKEN_PREFIX = 'access-token.';
|
||||
const ACCESS_TOKEN_PREFIX = 'access-token-v2.';
|
||||
|
||||
/** @public */
|
||||
export const githubAuthenticator = createOAuthAuthenticator({
|
||||
@@ -98,6 +98,11 @@ export const githubAuthenticator = createOAuthAuthenticator({
|
||||
// refresh token cookie. We use that token to fetch the user profile and
|
||||
// refresh the Backstage session when needed.
|
||||
if (input.refreshToken?.startsWith(ACCESS_TOKEN_PREFIX)) {
|
||||
if (!input.scopeAlreadyGranted) {
|
||||
throw new Error(
|
||||
'Refresh failed, session has not been granted the requested scope',
|
||||
);
|
||||
}
|
||||
const accessToken = input.refreshToken.slice(ACCESS_TOKEN_PREFIX.length);
|
||||
|
||||
const fullProfile = await helper
|
||||
|
||||
Reference in New Issue
Block a user