Fix issues described in #25551

Signed-off-by: Olivier Liechti <olivier.liechti@wasabi-tech.com>
This commit is contained in:
Olivier Liechti
2024-07-09 09:55:58 +02:00
parent 78c9adcc61
commit b9832aee3d
4 changed files with 83 additions and 9 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend-module-atlassian-provider': patch
---
Fix several issues with the Atlassian auth provider (type definition, profile url, profile transformation, scopes)
@@ -0,0 +1,40 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Strategy from 'passport-atlassian-oauth2';
describe('Strategy', () => {
it('should be an instance of', () => {
try {
console.log(Strategy);
const strategy = new Strategy(
{
authorizationURL: 'https://auth.atlassian.com/authorize',
tokenURL: 'https://auth.atlassian.com/oauth/token',
clientID: 'my-client-id',
clientSecret: 'my-client-secret',
scope: ['offline_access', 'read:jira-work', 'read:jira-user'],
},
() => {},
);
console.log(strategy.name);
expect(strategy).toBeInstanceOf(Strategy);
expect((strategy as any).name).toBe('atlassian');
} catch (e) {
console.error(e);
}
});
});
@@ -20,14 +20,35 @@ import {
PassportOAuthDoneCallback,
PassportProfile,
} from '@backstage/plugin-auth-node';
import { Strategy as AtlassianStrategy } from 'passport-atlassian-oauth2';
import AtlassianStrategy from 'passport-atlassian-oauth2';
export type AtlassianPassportProfile = {
id: string;
displayName: string;
email: string;
photo: string;
provider: string;
_json: any;
};
/** @public */
export const atlassianAuthenticator = createOAuthAuthenticator({
defaultProfileTransform:
PassportOAuthAuthenticatorHelper.defaultProfileTransform,
export const atlassianAuthenticator = createOAuthAuthenticator<
any,
AtlassianPassportProfile
>({
defaultProfileTransform: async (input, context) => {
// const result = await PassportOAuthAuthenticatorHelper.defaultProfileTransform(input, context);
return {
profile: {
displayName: input.fullProfile.displayName,
email: input.fullProfile.email,
picture: input.fullProfile.photo,
},
};
},
scopes: {
required: ['offline_access', 'read:jira-work', 'read:jira-user'],
required: ['offline_access', 'read:me', 'read:jira-work', 'read:jira-user'],
},
initialize({ callbackUrl, config }) {
const clientId = config.getString('clientId');
@@ -49,18 +70,25 @@ export const atlassianAuthenticator = createOAuthAuthenticator({
baseURL: baseUrl,
authorizationURL: `${baseUrl}/authorize`,
tokenURL: `${baseUrl}/oauth/token`,
profileURL: `${baseUrl}/api/v4/user`,
// profileURL: `${baseUrl}/api/v4/user`,
profileURL: 'https://api.atlassian.com/me',
scope: config.getOptionalString('additionalScopes')?.split(' ') || [],
},
(
accessToken: string,
refreshToken: string,
params: any,
fullProfile: PassportProfile,
fullProfile: PassportProfile & { email: string; photo: string },
done: PassportOAuthDoneCallback,
) => {
const fullProfileWithEmails = {
...fullProfile,
// avatarUrl: fullProfile.photo,
// emails: [{ value: fullProfile.email }],
};
done(
undefined,
{ fullProfile, params, accessToken },
{ fullProfile: fullProfileWithEmails, params, accessToken },
{ refreshToken },
);
},
@@ -18,8 +18,9 @@ declare module 'passport-atlassian-oauth2' {
import { Request } from 'express';
import { StrategyCreated } from 'passport';
export class Strategy {
export default class Strategy {
constructor(options: any, verify: any);
name?: string;
authenticate(this: StrategyCreated<this>, req: Request, options?: any): any;
}
}