From 824b2d47d265addcf8c37ea0e63cbfdaccd326a6 Mon Sep 17 00:00:00 2001 From: Shousan Liao Date: Fri, 3 Nov 2023 14:00:42 -0400 Subject: [PATCH 1/7] replace GitLab, Gitlab, gitlab with atlassian Signed-off-by: Shousan Liao --- .../.eslintrc.js | 1 + .../CHANGELOG.md | 131 ++++++++++++++++++ .../README.md | 8 ++ .../api-report.md | 30 ++++ .../catalog-info.yaml | 10 ++ .../config.d.ts | 34 +++++ .../dev/index.ts | 24 ++++ .../package.json | 45 ++++++ .../src/authenticator.ts | 77 ++++++++++ .../src/index.ts | 25 ++++ .../src/module.test.ts | 78 +++++++++++ .../src/module.ts | 48 +++++++ .../src/resolvers.ts | 50 +++++++ .../src/types.d.ts | 25 ++++ 14 files changed, 586 insertions(+) create mode 100644 plugins/auth-backend-module-atlassian-provider/.eslintrc.js create mode 100644 plugins/auth-backend-module-atlassian-provider/CHANGELOG.md create mode 100644 plugins/auth-backend-module-atlassian-provider/README.md create mode 100644 plugins/auth-backend-module-atlassian-provider/api-report.md create mode 100644 plugins/auth-backend-module-atlassian-provider/catalog-info.yaml create mode 100644 plugins/auth-backend-module-atlassian-provider/config.d.ts create mode 100644 plugins/auth-backend-module-atlassian-provider/dev/index.ts create mode 100644 plugins/auth-backend-module-atlassian-provider/package.json create mode 100644 plugins/auth-backend-module-atlassian-provider/src/authenticator.ts create mode 100644 plugins/auth-backend-module-atlassian-provider/src/index.ts create mode 100644 plugins/auth-backend-module-atlassian-provider/src/module.test.ts create mode 100644 plugins/auth-backend-module-atlassian-provider/src/module.ts create mode 100644 plugins/auth-backend-module-atlassian-provider/src/resolvers.ts create mode 100644 plugins/auth-backend-module-atlassian-provider/src/types.d.ts diff --git a/plugins/auth-backend-module-atlassian-provider/.eslintrc.js b/plugins/auth-backend-module-atlassian-provider/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md new file mode 100644 index 0000000000..8eced7bce9 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -0,0 +1,131 @@ +# @backstage/plugin-auth-backend-module-atlassian-provider + +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.9-next.1 + - @backstage/plugin-auth-node@0.4.1-next.1 + - @backstage/backend-plugin-api@0.6.7-next.1 + +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.9-next.0 + - @backstage/backend-plugin-api@0.6.7-next.0 + - @backstage/plugin-auth-node@0.4.1-next.0 + +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.8 + - @backstage/plugin-auth-node@0.4.0 + - @backstage/backend-plugin-api@0.6.6 + +## 0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.8-next.2 + - @backstage/plugin-auth-node@0.4.0-next.2 + - @backstage/backend-plugin-api@0.6.6-next.2 + +## 0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.1 + - @backstage/backend-plugin-api@0.6.5-next.1 + - @backstage/plugin-auth-node@0.3.2-next.1 + +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.3.2-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/backend-plugin-api@0.6.5-next.0 + +## 0.1.0 + +### Minor Changes + +- 080cc7794700: New module for `@backstage/plugin-auth-backend` that adds a Atlassian auth provider. + +### Patch Changes + +- 71114ac50e02: The export for the new backend system has been moved to be the `default` export. + + For example, if you are currently importing the plugin using the following pattern: + + ```ts + import { examplePlugin } from '@backstage/plugin-example-backend'; + + backend.add(examplePlugin); + ``` + + It should be migrated to this: + + ```ts + backend.add(import('@backstage/plugin-example-backend')); + ``` + +- Updated dependencies + - @backstage/backend-common@0.19.5 + - @backstage/plugin-auth-node@0.3.0 + - @backstage/backend-plugin-api@0.6.3 + +## 0.1.0-next.2 + +### Patch Changes + +- 71114ac50e02: The export for the new backend system has been moved to be the `default` export. + + For example, if you are currently importing the plugin using the following pattern: + + ```ts + import { examplePlugin } from '@backstage/plugin-example-backend'; + + backend.add(examplePlugin); + ``` + + It should be migrated to this: + + ```ts + backend.add(import('@backstage/plugin-example-backend')); + ``` + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.3-next.3 + - @backstage/backend-common@0.19.5-next.3 + - @backstage/plugin-auth-node@0.3.0-next.3 + +## 0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.5-next.2 + - @backstage/plugin-auth-node@0.3.0-next.2 + - @backstage/backend-plugin-api@0.6.3-next.2 + +## 0.1.0-next.0 + +### Minor Changes + +- 080cc7794700: New module for `@backstage/plugin-auth-backend` that adds a Atlassian auth provider. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.5-next.1 + - @backstage/backend-plugin-api@0.6.3-next.1 + - @backstage/plugin-auth-node@0.3.0-next.1 diff --git a/plugins/auth-backend-module-atlassian-provider/README.md b/plugins/auth-backend-module-atlassian-provider/README.md new file mode 100644 index 0000000000..fb326f68be --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/README.md @@ -0,0 +1,8 @@ +# Auth Module: Atlassian Provider + +This module provides an Atlassian auth provider implementation for `@backstage/plugin-auth-backend`. + +## Links + +- [Repository](https://atlassian.com/backstage/backstage/tree/master/plugins/auth-backend-module-atlassian-provider) +- [Backstage Project Homepage](https://backstage.io) diff --git a/plugins/auth-backend-module-atlassian-provider/api-report.md b/plugins/auth-backend-module-atlassian-provider/api-report.md new file mode 100644 index 0000000000..8b07bd8e52 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/api-report.md @@ -0,0 +1,30 @@ +## API Report File for "@backstage/plugin-auth-backend-module-atlassian-provider" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { OAuthAuthenticator } from '@backstage/plugin-auth-node'; +import { OAuthAuthenticatorResult } from '@backstage/plugin-auth-node'; +import { PassportOAuthAuthenticatorHelper } from '@backstage/plugin-auth-node'; +import { PassportProfile } from '@backstage/plugin-auth-node'; +import { SignInResolverFactory } from '@backstage/plugin-auth-node'; + +// @public (undocumented) +const authModuleAtlassianProvider: () => BackendFeature; +export default authModuleAtlassianProvider; + +// @public (undocumented) +export const atlassianAuthenticator: OAuthAuthenticator< + PassportOAuthAuthenticatorHelper, + PassportProfile +>; + +// @public +export namespace atlassianSignInResolvers { + const usernameMatchingUserEntityName: SignInResolverFactory< + OAuthAuthenticatorResult, + unknown + >; +} +``` diff --git a/plugins/auth-backend-module-atlassian-provider/catalog-info.yaml b/plugins/auth-backend-module-atlassian-provider/catalog-info.yaml new file mode 100644 index 0000000000..d3e2c11c17 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/catalog-info.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-auth-backend-module-atlassian-provider + title: '@backstage/plugin-auth-backend-module-atlassian-provider' + description: The atlassian-provider backend module for the auth plugin. +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/auth-backend-module-atlassian-provider/config.d.ts b/plugins/auth-backend-module-atlassian-provider/config.d.ts new file mode 100644 index 0000000000..999bf1b304 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/config.d.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2020 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. + */ + +export interface Config { + auth?: { + providers?: { + /** @visibility frontend */ + atlassian?: { + [authEnv: string]: { + clientId: string; + /** + * @visibility secret + */ + clientSecret: string; + audience?: string; + callbackUrl?: string; + }; + }; + }; + }; +} diff --git a/plugins/auth-backend-module-atlassian-provider/dev/index.ts b/plugins/auth-backend-module-atlassian-provider/dev/index.ts new file mode 100644 index 0000000000..d3c18c1d48 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/dev/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2023 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 { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('../src')); + +backend.start(); diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json new file mode 100644 index 0000000000..cdc1bfe439 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -0,0 +1,45 @@ +{ + "name": "@backstage/plugin-auth-backend-module-atlassian-provider", + "description": "The atlassian-provider backend module for the auth plugin.", + "version": "0.1.4-next.1", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "express": "^4.18.2", + "passport": "^0.6.0", + "passport-atlassian2": "^5.0.0" + }, + "devDependencies": { + "@backstage/backend-defaults": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "supertest": "^6.3.3" + }, + "configSchema": "config.d.ts", + "files": [ + "dist", + "config.d.ts" + ] +} diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts new file mode 100644 index 0000000000..8756b10660 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -0,0 +1,77 @@ +/* + * Copyright 2023 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 as AtlassianStrategy } from 'passport-atlassian2'; +import { + createOAuthAuthenticator, + PassportOAuthAuthenticatorHelper, + PassportOAuthDoneCallback, + PassportProfile, +} from '@backstage/plugin-auth-node'; + +/** @public */ +export const atlassianAuthenticator = createOAuthAuthenticator({ + defaultProfileTransform: + PassportOAuthAuthenticatorHelper.defaultProfileTransform, + initialize({ callbackUrl, config }) { + const clientId = config.getString('clientId'); + const clientSecret = config.getString('clientSecret'); + const baseUrl = + config.getOptionalString('audience') || 'https://atlassian.com'; + + return PassportOAuthAuthenticatorHelper.from( + new AtlassianStrategy( + { + clientID: clientId, + clientSecret: clientSecret, + callbackURL: callbackUrl, + baseURL: baseUrl, + authorizationURL: `${baseUrl}/oauth/authorize`, + tokenURL: `${baseUrl}/oauth/token`, + profileURL: `${baseUrl}/api/v4/user`, + }, + ( + accessToken: string, + refreshToken: string, + params: any, + fullProfile: PassportProfile, + done: PassportOAuthDoneCallback, + ) => { + done( + undefined, + { fullProfile, params, accessToken }, + { refreshToken }, + ); + }, + ), + ); + }, + + async start(input, helper) { + return helper.start(input, { + accessType: 'offline', + prompt: 'consent', + }); + }, + + async authenticate(input, helper) { + return helper.authenticate(input); + }, + + async refresh(input, helper) { + return helper.refresh(input); + }, +}); diff --git a/plugins/auth-backend-module-atlassian-provider/src/index.ts b/plugins/auth-backend-module-atlassian-provider/src/index.ts new file mode 100644 index 0000000000..cc71c9b7e3 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/src/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2023 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. + */ + +/** + * The atlassian-provider backend module for the auth plugin. + * + * @packageDocumentation + */ + +export { atlassianAuthenticator } from './authenticator'; +export { authModuleAtlassianProvider as default } from './module'; +export { atlassianSignInResolvers } from './resolvers'; diff --git a/plugins/auth-backend-module-atlassian-provider/src/module.test.ts b/plugins/auth-backend-module-atlassian-provider/src/module.test.ts new file mode 100644 index 0000000000..b70d5da1a4 --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/src/module.test.ts @@ -0,0 +1,78 @@ +/* + * Copyright 2023 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 { mockServices, startTestBackend } from '@backstage/backend-test-utils'; +import { authModuleAtlassianProvider } from './module'; +import request from 'supertest'; +import { decodeOAuthState } from '@backstage/plugin-auth-node'; + +describe('authModuleAtlassianProvider', () => { + it('should start', async () => { + const { server } = await startTestBackend({ + features: [ + import('@backstage/plugin-auth-backend'), + authModuleAtlassianProvider, + mockServices.rootConfig.factory({ + data: { + app: { + baseUrl: 'http://localhost:3000', + }, + auth: { + providers: { + atlassian: { + development: { + clientId: 'my-client-id', + clientSecret: 'my-client-secret', + }, + }, + }, + }, + }, + }), + ], + }); + + const agent = request.agent(server); + + const res = await agent.get('/api/auth/atlassian/start?env=development'); + + expect(res.status).toEqual(302); + + const nonceCookie = agent.jar.getCookie('atlassian-nonce', { + domain: 'localhost', + path: '/api/auth/atlassian/handler', + script: false, + secure: false, + }); + expect(nonceCookie).toBeDefined(); + + const startUrl = new URL(res.get('location')); + expect(startUrl.origin).toBe('https://atlassian.com'); + expect(startUrl.pathname).toBe('/oauth/authorize'); + expect(Object.fromEntries(startUrl.searchParams)).toEqual({ + response_type: 'code', + scope: 'read_user', + client_id: 'my-client-id', + redirect_uri: `http://localhost:${server.port()}/api/auth/atlassian/handler/frame`, + state: expect.any(String), + }); + + expect(decodeOAuthState(startUrl.searchParams.get('state')!)).toEqual({ + env: 'development', + nonce: decodeURIComponent(nonceCookie.value), + }); + }); +}); diff --git a/plugins/auth-backend-module-atlassian-provider/src/module.ts b/plugins/auth-backend-module-atlassian-provider/src/module.ts new file mode 100644 index 0000000000..9acb665ede --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/src/module.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2023 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 { createBackendModule } from '@backstage/backend-plugin-api'; +import { + authProvidersExtensionPoint, + commonSignInResolvers, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; +import { atlassianAuthenticator } from './authenticator'; +import { atlassianSignInResolvers } from './resolvers'; + +/** @public */ +export const authModuleAtlassianProvider = createBackendModule({ + pluginId: 'auth', + moduleId: 'atlassian-provider', + register(reg) { + reg.registerInit({ + deps: { + providers: authProvidersExtensionPoint, + }, + async init({ providers }) { + providers.registerProvider({ + providerId: 'atlassian', + factory: createOAuthProviderFactory({ + authenticator: atlassianAuthenticator, + signInResolverFactories: { + ...atlassianSignInResolvers, + ...commonSignInResolvers, + }, + }), + }); + }, + }); + }, +}); diff --git a/plugins/auth-backend-module-atlassian-provider/src/resolvers.ts b/plugins/auth-backend-module-atlassian-provider/src/resolvers.ts new file mode 100644 index 0000000000..1f3090bfdd --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/src/resolvers.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2023 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 { + createSignInResolverFactory, + OAuthAuthenticatorResult, + PassportProfile, + SignInInfo, +} from '@backstage/plugin-auth-node'; + +/** + * Available sign-in resolvers for the Atlassian auth provider. + * + * @public + */ +export namespace atlassianSignInResolvers { + /** + * Looks up the user by matching their Atlassian username to the entity name. + */ + export const usernameMatchingUserEntityName = createSignInResolverFactory({ + create() { + return async ( + info: SignInInfo>, + ctx, + ) => { + const { result } = info; + + const id = result.fullProfile.username; + if (!id) { + throw new Error(`Atlassian user profile does not contain a username`); + } + + return ctx.signInWithCatalogUser({ entityRef: { name: id } }); + }; + }, + }); +} diff --git a/plugins/auth-backend-module-atlassian-provider/src/types.d.ts b/plugins/auth-backend-module-atlassian-provider/src/types.d.ts new file mode 100644 index 0000000000..3b377cbdfd --- /dev/null +++ b/plugins/auth-backend-module-atlassian-provider/src/types.d.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2020 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. + */ + +declare module 'passport-atlassian2' { + import { Request } from 'express'; + import { StrategyCreated } from 'passport'; + + export class Strategy { + constructor(options: any, verify: any); + authenticate(this: StrategyCreated, req: Request, options?: any): any; + } +} From 260ee5106b258f93d9fca32f2f13ce10a4e68576 Mon Sep 17 00:00:00 2001 From: Shousan Liao Date: Fri, 3 Nov 2023 15:49:52 -0400 Subject: [PATCH 2/7] yarn install passport-atlassian-oauth2 and pass test case Signed-off-by: Shousan Liao --- plugins/auth-backend-module-atlassian-provider/package.json | 2 +- .../auth-backend-module-atlassian-provider/src/authenticator.ts | 2 +- .../auth-backend-module-atlassian-provider/src/module.test.ts | 1 - plugins/auth-backend-module-atlassian-provider/src/types.d.ts | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index cdc1bfe439..dc00aad712 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -28,7 +28,7 @@ "@backstage/plugin-auth-node": "workspace:^", "express": "^4.18.2", "passport": "^0.6.0", - "passport-atlassian2": "^5.0.0" + "passport-atlassian-oauth2": "^2.1.0" }, "devDependencies": { "@backstage/backend-defaults": "workspace:^", diff --git a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts index 8756b10660..3e5ed50246 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/authenticator.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Strategy as AtlassianStrategy } from 'passport-atlassian2'; +import { Strategy as AtlassianStrategy } from 'passport-atlassian-oauth2'; import { createOAuthAuthenticator, PassportOAuthAuthenticatorHelper, diff --git a/plugins/auth-backend-module-atlassian-provider/src/module.test.ts b/plugins/auth-backend-module-atlassian-provider/src/module.test.ts index b70d5da1a4..8d02b0b7a5 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/module.test.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/module.test.ts @@ -64,7 +64,6 @@ describe('authModuleAtlassianProvider', () => { expect(startUrl.pathname).toBe('/oauth/authorize'); expect(Object.fromEntries(startUrl.searchParams)).toEqual({ response_type: 'code', - scope: 'read_user', client_id: 'my-client-id', redirect_uri: `http://localhost:${server.port()}/api/auth/atlassian/handler/frame`, state: expect.any(String), diff --git a/plugins/auth-backend-module-atlassian-provider/src/types.d.ts b/plugins/auth-backend-module-atlassian-provider/src/types.d.ts index 3b377cbdfd..5fd47bf885 100644 --- a/plugins/auth-backend-module-atlassian-provider/src/types.d.ts +++ b/plugins/auth-backend-module-atlassian-provider/src/types.d.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -declare module 'passport-atlassian2' { +declare module 'passport-atlassian-oauth2' { import { Request } from 'express'; import { StrategyCreated } from 'passport'; From f7f20b7c3fe5986472d8c04df88f29e77b55bfef Mon Sep 17 00:00:00 2001 From: Shousan Liao Date: Fri, 3 Nov 2023 15:58:08 -0400 Subject: [PATCH 3/7] delete provider.test.ts and update auth-backend's provider Signed-off-by: Shousan Liao --- plugins/auth-backend/package.json | 1 + .../src/providers/atlassian/provider.test.ts | 145 -------------- .../src/providers/atlassian/provider.ts | 189 ++---------------- 3 files changed, 15 insertions(+), 320 deletions(-) delete mode 100644 plugins/auth-backend/src/providers/atlassian/provider.test.ts diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index b52560cbb9..edd6f5de8f 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -38,6 +38,7 @@ "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/plugin-auth-backend-module-atlassian-provider": "workspace:^", "@backstage/plugin-auth-backend-module-gcp-iap-provider": "workspace:^", "@backstage/plugin-auth-backend-module-github-provider": "workspace:^", "@backstage/plugin-auth-backend-module-gitlab-provider": "workspace:^", diff --git a/plugins/auth-backend/src/providers/atlassian/provider.test.ts b/plugins/auth-backend/src/providers/atlassian/provider.test.ts deleted file mode 100644 index 1fb987d3b0..0000000000 --- a/plugins/auth-backend/src/providers/atlassian/provider.test.ts +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2020 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 { AtlassianAuthProvider } from './provider'; -import * as helpers from '../../lib/passport/PassportStrategyHelper'; -import { OAuthResult } from '../../lib/oauth'; -import { PassportProfile } from '../../lib/passport/types'; -import { AuthResolverContext } from '../types'; - -jest.mock('../../lib/passport/PassportStrategyHelper', () => { - return { - executeFrameHandlerStrategy: jest.fn(), - executeRefreshTokenStrategy: jest.fn(), - executeFetchUserProfileStrategy: jest.fn(), - }; -}); - -const mockFrameHandler = jest.spyOn( - helpers, - 'executeFrameHandlerStrategy', -) as unknown as jest.MockedFunction<() => Promise<{ result: OAuthResult }>>; - -describe('createAtlassianProvider', () => { - const provider = new AtlassianAuthProvider({ - resolverContext: {} as AuthResolverContext, - authHandler: async ({ fullProfile }) => ({ - profile: { - email: fullProfile.emails![0]!.value, - displayName: fullProfile.displayName, - picture: 'http://google.com/lols', - }, - }), - clientId: 'mock', - clientSecret: 'mock', - callbackUrl: 'mock', - scopes: 'scope', - }); - - it('should auth', async () => { - mockFrameHandler.mockResolvedValueOnce({ - result: { - fullProfile: { - photos: [ - { - value: - 'https://a1cf74336522e87f135f-2f21ace9a6cf0052456644b80fa06d4f.ssl.cf2.rackcdn.com/images/characters_opt/p-mystic-river-sean-penn.jpg', - }, - ], - emails: [{ value: 'conrad@example.com' }], - displayName: 'Conrad', - id: 'conrad', - provider: 'google', - }, - params: { - id_token: 'idToken', - scope: 'scope', - expires_in: 123, - }, - accessToken: 'accessToken', - refreshToken: 'wacka', - }, - }); - const result = await provider.handler({} as any); - expect(result).toEqual({ - response: { - providerInfo: { - accessToken: 'accessToken', - expiresInSeconds: 123, - idToken: 'idToken', - scope: 'scope', - }, - profile: { - email: 'conrad@example.com', - displayName: 'Conrad', - picture: 'http://google.com/lols', - }, - }, - refreshToken: 'wacka', - }); - }); - - 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', - scope: 'read_user', - }, - }); - - const mockUserProfile = jest.spyOn( - helpers, - 'executeFetchUserProfileStrategy', - ) as unknown as jest.MockedFunction<() => Promise>; - - mockUserProfile.mockResolvedValueOnce({ - id: 'uid-my-id', - username: 'mockuser', - provider: 'atlassian', - displayName: 'Mocked User', - emails: [ - { - value: 'mockuser@gmail.com', - }, - ], - }); - - const result = await provider.refresh({} as any); - - expect(result).toEqual({ - response: { - profile: { - displayName: 'Mocked User', - email: 'mockuser@gmail.com', - picture: 'http://google.com/lols', - }, - providerInfo: { - accessToken: 'a.b.c', - idToken: 'my-id', - scope: 'read_user', - }, - }, - refreshToken: 'dont-forget-to-send-refresh', - }); - }); -}); diff --git a/plugins/auth-backend/src/providers/atlassian/provider.ts b/plugins/auth-backend/src/providers/atlassian/provider.ts index e02d899fb1..0d9bc5f42b 100644 --- a/plugins/auth-backend/src/providers/atlassian/provider.ts +++ b/plugins/auth-backend/src/providers/atlassian/provider.ts @@ -14,156 +14,18 @@ * limitations under the License. */ -import AtlassianStrategy from './strategy'; -import { - encodeState, - OAuthAdapter, - OAuthEnvironmentHandler, - OAuthHandlers, - OAuthProviderOptions, - OAuthRefreshRequest, - OAuthResponse, - OAuthResult, - OAuthStartRequest, -} from '../../lib/oauth'; -import passport from 'passport'; -import { - executeFetchUserProfileStrategy, - executeFrameHandlerStrategy, - executeRedirectStrategy, - executeRefreshTokenStrategy, - makeProfileInfo, - PassportDoneCallback, -} from '../../lib/passport'; -import { - AuthHandler, - AuthResolverContext, - OAuthStartResponse, - SignInResolver, -} from '../types'; -import express from 'express'; +import { SignInResolver, AuthHandler } from '../types'; +import { OAuthResult } from '../../lib/oauth'; import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; - -/** @public */ -export type AtlassianAuthProviderOptions = OAuthProviderOptions & { - scopes: string; - signInResolver?: SignInResolver; - authHandler: AuthHandler; - resolverContext: AuthResolverContext; -}; - -export const atlassianDefaultAuthHandler: AuthHandler = async ({ - fullProfile, - params, -}) => ({ - profile: makeProfileInfo(fullProfile, params.id_token), -}); - -export class AtlassianAuthProvider implements OAuthHandlers { - private readonly _strategy: AtlassianStrategy; - private readonly signInResolver?: SignInResolver; - private readonly authHandler: AuthHandler; - private readonly resolverContext: AuthResolverContext; - - constructor(options: AtlassianAuthProviderOptions) { - this.resolverContext = options.resolverContext; - this.authHandler = options.authHandler; - this.signInResolver = options.signInResolver; - - this._strategy = new AtlassianStrategy( - { - clientID: options.clientId, - clientSecret: options.clientSecret, - callbackURL: options.callbackUrl, - scope: options.scopes, - }, - ( - accessToken: any, - refreshToken: any, - params: any, - fullProfile: passport.Profile, - done: PassportDoneCallback, - ) => { - done(undefined, { - fullProfile, - accessToken, - refreshToken, - params, - }); - }, - ); - } - - async start(req: OAuthStartRequest): Promise { - return await executeRedirectStrategy(req, this._strategy, { - state: encodeState(req.state), - }); - } - - async handler(req: express.Request) { - const { result } = await executeFrameHandlerStrategy( - req, - this._strategy, - ); - - return { - response: await this.handleResult(result), - refreshToken: result.refreshToken, - }; - } - - private async handleResult(result: OAuthResult): Promise { - const { profile } = await this.authHandler(result, this.resolverContext); - - const response: OAuthResponse = { - providerInfo: { - idToken: result.params.id_token, - accessToken: result.accessToken, - scope: result.params.scope, - expiresInSeconds: result.params.expires_in, - }, - profile, - }; - - if (this.signInResolver) { - response.backstageIdentity = await this.signInResolver( - { - result, - profile, - }, - this.resolverContext, - ); - } - - return response; - } - - async refresh(req: OAuthRefreshRequest) { - const { accessToken, params, refreshToken } = - await executeRefreshTokenStrategy( - this._strategy, - req.refreshToken, - req.scope, - ); - - const fullProfile = await executeFetchUserProfileStrategy( - this._strategy, - accessToken, - ); - - return { - response: await this.handleResult({ - fullProfile, - params, - accessToken, - }), - refreshToken, - }; - } -} +import { createOAuthProviderFactory } from '@backstage/plugin-auth-node'; +import { + adaptLegacyOAuthHandler, + adaptLegacyOAuthSignInResolver, +} from '../../lib/legacy'; +import { atlassianAuthenticator } from '@backstage/plugin-auth-backend-module-atlassian-provider'; /** - * Auth provider integration for atlassian auth + * Auth provider integration for GitLab auth * * @public */ @@ -182,33 +44,10 @@ export const atlassian = createAuthProviderIntegration({ resolver: SignInResolver; }; }) { - return ({ providerId, globalConfig, config, resolverContext }) => - OAuthEnvironmentHandler.mapConfig(config, envConfig => { - const clientId = envConfig.getString('clientId'); - const clientSecret = envConfig.getString('clientSecret'); - const scopes = envConfig.getString('scopes'); - const customCallbackUrl = envConfig.getOptionalString('callbackUrl'); - const callbackUrl = - customCallbackUrl || - `${globalConfig.baseUrl}/${providerId}/handler/frame`; - - const authHandler: AuthHandler = - options?.authHandler ?? atlassianDefaultAuthHandler; - - const provider = new AtlassianAuthProvider({ - clientId, - clientSecret, - scopes, - callbackUrl, - authHandler, - signInResolver: options?.signIn?.resolver, - resolverContext, - }); - - return OAuthAdapter.fromConfig(globalConfig, provider, { - providerId, - callbackUrl, - }); - }); + return createOAuthProviderFactory({ + authenticator: atlassianAuthenticator, + profileTransform: adaptLegacyOAuthHandler(options?.authHandler), + signInResolver: adaptLegacyOAuthSignInResolver(options?.signIn?.resolver), + }); }, }); From 2a5891e81665febbce64aa380156e91c198b14c6 Mon Sep 17 00:00:00 2001 From: Shousan Liao Date: Mon, 6 Nov 2023 15:31:23 -0500 Subject: [PATCH 4/7] add changeset Signed-off-by: Shousan Liao --- .changeset/angry-gorillas-unite.md | 5 +++++ .changeset/cold-pans-crash.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/angry-gorillas-unite.md create mode 100644 .changeset/cold-pans-crash.md diff --git a/.changeset/angry-gorillas-unite.md b/.changeset/angry-gorillas-unite.md new file mode 100644 index 0000000000..8d3df6a808 --- /dev/null +++ b/.changeset/angry-gorillas-unite.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-atlassian-provider': major +--- + +New module for `@backstage/plugin-auth-backend` that adds an atlassian auth provider diff --git a/.changeset/cold-pans-crash.md b/.changeset/cold-pans-crash.md new file mode 100644 index 0000000000..85858fd270 --- /dev/null +++ b/.changeset/cold-pans-crash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Migrate the atlassian auth provider to be implemented using the new `@backstage/plugin-auth-backend-module-atlassian-provider` module From 533eee21b93102bf6dee3a452daab4434ad2233d Mon Sep 17 00:00:00 2001 From: Shousan Liao Date: Tue, 7 Nov 2023 11:06:12 -0500 Subject: [PATCH 5/7] resolve suggested changes Signed-off-by: Shousan Liao --- .changeset/angry-gorillas-unite.md | 2 +- .../CHANGELOG.md | 131 ------------------ .../package.json | 2 +- 3 files changed, 2 insertions(+), 133 deletions(-) delete mode 100644 plugins/auth-backend-module-atlassian-provider/CHANGELOG.md diff --git a/.changeset/angry-gorillas-unite.md b/.changeset/angry-gorillas-unite.md index 8d3df6a808..73d5a6c88b 100644 --- a/.changeset/angry-gorillas-unite.md +++ b/.changeset/angry-gorillas-unite.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-auth-backend-module-atlassian-provider': major +'@backstage/plugin-auth-backend-module-atlassian-provider': minor --- New module for `@backstage/plugin-auth-backend` that adds an atlassian auth provider diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md deleted file mode 100644 index 8eced7bce9..0000000000 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ /dev/null @@ -1,131 +0,0 @@ -# @backstage/plugin-auth-backend-module-atlassian-provider - -## 0.1.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/plugin-auth-node@0.4.1-next.1 - - @backstage/backend-plugin-api@0.6.7-next.1 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/backend-plugin-api@0.6.7-next.0 - - @backstage/plugin-auth-node@0.4.1-next.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/plugin-auth-node@0.4.0 - - @backstage/backend-plugin-api@0.6.6 - -## 0.1.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/plugin-auth-node@0.4.0-next.2 - - @backstage/backend-plugin-api@0.6.6-next.2 - -## 0.1.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/backend-plugin-api@0.6.5-next.1 - - @backstage/plugin-auth-node@0.3.2-next.1 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-auth-node@0.3.2-next.0 - - @backstage/backend-common@0.19.7-next.0 - - @backstage/backend-plugin-api@0.6.5-next.0 - -## 0.1.0 - -### Minor Changes - -- 080cc7794700: New module for `@backstage/plugin-auth-backend` that adds a Atlassian auth provider. - -### Patch Changes - -- 71114ac50e02: The export for the new backend system has been moved to be the `default` export. - - For example, if you are currently importing the plugin using the following pattern: - - ```ts - import { examplePlugin } from '@backstage/plugin-example-backend'; - - backend.add(examplePlugin); - ``` - - It should be migrated to this: - - ```ts - backend.add(import('@backstage/plugin-example-backend')); - ``` - -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/plugin-auth-node@0.3.0 - - @backstage/backend-plugin-api@0.6.3 - -## 0.1.0-next.2 - -### Patch Changes - -- 71114ac50e02: The export for the new backend system has been moved to be the `default` export. - - For example, if you are currently importing the plugin using the following pattern: - - ```ts - import { examplePlugin } from '@backstage/plugin-example-backend'; - - backend.add(examplePlugin); - ``` - - It should be migrated to this: - - ```ts - backend.add(import('@backstage/plugin-example-backend')); - ``` - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.3-next.3 - - @backstage/backend-common@0.19.5-next.3 - - @backstage/plugin-auth-node@0.3.0-next.3 - -## 0.1.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5-next.2 - - @backstage/plugin-auth-node@0.3.0-next.2 - - @backstage/backend-plugin-api@0.6.3-next.2 - -## 0.1.0-next.0 - -### Minor Changes - -- 080cc7794700: New module for `@backstage/plugin-auth-backend` that adds a Atlassian auth provider. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5-next.1 - - @backstage/backend-plugin-api@0.6.3-next.1 - - @backstage/plugin-auth-node@0.3.0-next.1 diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index dc00aad712..21235aeca4 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", "description": "The atlassian-provider backend module for the auth plugin.", - "version": "0.1.4-next.1", + "version": "0.0.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", From 2ff93731794ab981710169f4ea0f8998c2130beb Mon Sep 17 00:00:00 2001 From: Shousan Liao Date: Tue, 7 Nov 2023 11:08:41 -0500 Subject: [PATCH 6/7] edit auth provider's comment Signed-off-by: Shousan Liao --- plugins/auth-backend/src/providers/atlassian/provider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth-backend/src/providers/atlassian/provider.ts b/plugins/auth-backend/src/providers/atlassian/provider.ts index 0d9bc5f42b..a142d1de90 100644 --- a/plugins/auth-backend/src/providers/atlassian/provider.ts +++ b/plugins/auth-backend/src/providers/atlassian/provider.ts @@ -25,7 +25,7 @@ import { import { atlassianAuthenticator } from '@backstage/plugin-auth-backend-module-atlassian-provider'; /** - * Auth provider integration for GitLab auth + * Auth provider integration for Atlassian auth * * @public */ From 1accf5481d160a2b596dfb5fe6ca282a0bef525f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 13 Nov 2023 14:53:55 +0100 Subject: [PATCH 7/7] build fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../api-report.md | 8 +++--- yarn.lock | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/plugins/auth-backend-module-atlassian-provider/api-report.md b/plugins/auth-backend-module-atlassian-provider/api-report.md index 8b07bd8e52..8a30e6b493 100644 --- a/plugins/auth-backend-module-atlassian-provider/api-report.md +++ b/plugins/auth-backend-module-atlassian-provider/api-report.md @@ -10,10 +10,6 @@ import { PassportOAuthAuthenticatorHelper } from '@backstage/plugin-auth-node'; import { PassportProfile } from '@backstage/plugin-auth-node'; import { SignInResolverFactory } from '@backstage/plugin-auth-node'; -// @public (undocumented) -const authModuleAtlassianProvider: () => BackendFeature; -export default authModuleAtlassianProvider; - // @public (undocumented) export const atlassianAuthenticator: OAuthAuthenticator< PassportOAuthAuthenticatorHelper, @@ -27,4 +23,8 @@ export namespace atlassianSignInResolvers { unknown >; } + +// @public (undocumented) +const authModuleAtlassianProvider: () => BackendFeature; +export default authModuleAtlassianProvider; ``` diff --git a/yarn.lock b/yarn.lock index 6bc7cc2b6b..8fee256982 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4911,6 +4911,24 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-auth-backend-module-atlassian-provider@workspace:^, @backstage/plugin-auth-backend-module-atlassian-provider@workspace:plugins/auth-backend-module-atlassian-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-atlassian-provider@workspace:plugins/auth-backend-module-atlassian-provider" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + express: ^4.18.2 + passport: ^0.6.0 + passport-atlassian-oauth2: ^2.1.0 + supertest: ^6.3.3 + languageName: unknown + linkType: soft + "@backstage/plugin-auth-backend-module-gcp-iap-provider@workspace:^, @backstage/plugin-auth-backend-module-gcp-iap-provider@workspace:plugins/auth-backend-module-gcp-iap-provider": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-gcp-iap-provider@workspace:plugins/auth-backend-module-gcp-iap-provider" @@ -5052,6 +5070,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-backend-module-atlassian-provider": "workspace:^" "@backstage/plugin-auth-backend-module-gcp-iap-provider": "workspace:^" "@backstage/plugin-auth-backend-module-github-provider": "workspace:^" "@backstage/plugin-auth-backend-module-gitlab-provider": "workspace:^" @@ -37277,6 +37296,15 @@ __metadata: languageName: node linkType: hard +"passport-atlassian-oauth2@npm:^2.1.0": + version: 2.1.0 + resolution: "passport-atlassian-oauth2@npm:2.1.0" + dependencies: + passport-oauth2: ^1.4.0 + checksum: fc1d46951018d03a792a469a0c856d16f4c21df13d743aa5a0111f60253588c042881c560c737c77d85f4751e42b9ad3a485db7a5d5ea39e0f76160bc4010182 + languageName: node + linkType: hard + "passport-auth0@npm:^1.4.3": version: 1.4.3 resolution: "passport-auth0@npm:1.4.3"