diff --git a/.changeset/tricky-months-hug.md b/.changeset/tricky-months-hug.md new file mode 100644 index 0000000000..ae1bd85532 --- /dev/null +++ b/.changeset/tricky-months-hug.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-auth-backend-module-oauth2-proxy-provider': patch +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +'@backstage/plugin-auth-backend-module-gcp-iap-provider': patch +'@backstage/plugin-auth-node': patch +--- + +Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` diff --git a/plugins/auth-backend-module-aws-alb-provider/api-report.md b/plugins/auth-backend-module-aws-alb-provider/api-report.md index 76a366d2c9..c1f0c6f01b 100644 --- a/plugins/auth-backend-module-aws-alb-provider/api-report.md +++ b/plugins/auth-backend-module-aws-alb-provider/api-report.md @@ -21,7 +21,11 @@ export const awsAlbAuthenticator: ProxyAuthenticator< issuer: string; getKey: (header: JWTHeaderParameters) => Promise; }, - AwsAlbResult + AwsAlbResult, + { + accessToken: string; + expiresInSeconds: number; + } >; // @public diff --git a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts index 5f19d800a0..e4700d10dd 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts @@ -107,6 +107,10 @@ describe('AwsAlbProvider', () => { expiresInSeconds: mockClaims.exp, accessToken: mockAccessToken, }, + providerInfo: { + accessToken: mockAccessToken, + expiresInSeconds: mockClaims.exp, + }, }); }); }); diff --git a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts index d7ca79927f..e7e0a7d76d 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts @@ -81,8 +81,12 @@ export const awsAlbAuthenticator = createProxyAuthenticator({ return { result: { fullProfile, + accessToken: accessToken, + expiresInSeconds: claims.exp, + }, + providerInfo: { + accessToken: accessToken, expiresInSeconds: claims.exp, - accessToken, }, }; } catch (e) { diff --git a/plugins/auth-backend-module-gcp-iap-provider/api-report.md b/plugins/auth-backend-module-gcp-iap-provider/api-report.md index 821aa8e437..8d7c319a50 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/api-report.md +++ b/plugins/auth-backend-module-gcp-iap-provider/api-report.md @@ -18,6 +18,9 @@ export const gcpIapAuthenticator: ProxyAuthenticator< jwtHeader: string; tokenValidator: (token: string) => Promise; }, + { + iapToken: GcpIapTokenInfo; + }, { iapToken: GcpIapTokenInfo; } diff --git a/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts b/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts index 5f90d3a379..dfe08a7fe2 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.test.ts @@ -45,7 +45,10 @@ describe('GcpIapProvider', () => { }, ctx, ), - ).resolves.toEqual({ result: { iapToken: { sub: 's', email: 'e' } } }); + ).resolves.toEqual({ + result: { iapToken: { sub: 's', email: 'e' } }, + providerInfo: { iapToken: { sub: 's', email: 'e' } }, + }); }); it('should find custom JWT header', async () => { @@ -66,7 +69,10 @@ describe('GcpIapProvider', () => { }, ctx, ), - ).resolves.toEqual({ result: { iapToken: { sub: 's', email: 'e' } } }); + ).resolves.toEqual({ + result: { iapToken: { sub: 's', email: 'e' } }, + providerInfo: { iapToken: { sub: 's', email: 'e' } }, + }); }); it('should throw if header is missing', async () => { diff --git a/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.ts b/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.ts index 9bb68fcbb3..7bf4290e9a 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-gcp-iap-provider/src/authenticator.ts @@ -47,6 +47,9 @@ export const gcpIapAuthenticator = createProxyAuthenticator({ const iapToken = await tokenValidator(token); - return { result: { iapToken } }; + return { + result: { iapToken }, + providerInfo: { iapToken }, + }; }, }); diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/api-report.md b/plugins/auth-backend-module-oauth2-proxy-provider/api-report.md index 1a4c1ee6d6..2d464fbdb1 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/api-report.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/api-report.md @@ -18,8 +18,11 @@ export const OAUTH2_PROXY_JWT_HEADER = 'X-OAUTH2-PROXY-ID-TOKEN'; // @public (undocumented) export const oauth2ProxyAuthenticator: ProxyAuthenticator< - unknown, - OAuth2ProxyResult + Promise, + OAuth2ProxyResult, + { + accessToken: string; + } >; // @public diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts b/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts index a3da83791a..fb124fef30 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-oauth2-proxy-provider/src/authenticator.ts @@ -31,10 +31,7 @@ import { OAuth2ProxyResult } from './types'; export const OAUTH2_PROXY_JWT_HEADER = 'X-OAUTH2-PROXY-ID-TOKEN'; /** @public */ -export const oauth2ProxyAuthenticator = createProxyAuthenticator< - unknown, - OAuth2ProxyResult ->({ +export const oauth2ProxyAuthenticator = createProxyAuthenticator({ defaultProfileTransform: async (result: OAuth2ProxyResult) => { return { profile: { @@ -63,7 +60,13 @@ export const oauth2ProxyAuthenticator = createProxyAuthenticator< return req.get(name); }, }; - return { result }; + + return { + result, + providerInfo: { + accessToken: result.accessToken, + }, + }; } catch (e) { throw new AuthenticationError('Authentication failed', e); } diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index 4b1a8a1f27..5c8c547442 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -173,13 +173,13 @@ export function createOAuthRouteHandlers( ): AuthProviderRouteHandlers; // @public (undocumented) -export function createProxyAuthenticator( - authenticator: ProxyAuthenticator, -): ProxyAuthenticator; +export function createProxyAuthenticator( + authenticator: ProxyAuthenticator, +): ProxyAuthenticator; // @public (undocumented) export function createProxyAuthProviderFactory(options: { - authenticator: ProxyAuthenticator; + authenticator: ProxyAuthenticator; profileTransform?: ProfileTransform; signInResolver?: SignInResolver; signInResolverFactories?: Record< @@ -538,7 +538,11 @@ export type ProfileTransform = ( }>; // @public (undocumented) -export interface ProxyAuthenticator { +export interface ProxyAuthenticator< + TContext, + TResult, + TProviderInfo = undefined, +> { // (undocumented) authenticate( options: { @@ -547,6 +551,7 @@ export interface ProxyAuthenticator { ctx: TContext, ): Promise<{ result: TResult; + providerInfo?: TProviderInfo; }>; // (undocumented) defaultProfileTransform: ProfileTransform; @@ -557,7 +562,7 @@ export interface ProxyAuthenticator { // @public (undocumented) export interface ProxyAuthRouteHandlersOptions { // (undocumented) - authenticator: ProxyAuthenticator; + authenticator: ProxyAuthenticator; // (undocumented) config: Config; // (undocumented) diff --git a/plugins/auth-node/src/proxy/createProxyAuthProviderFactory.ts b/plugins/auth-node/src/proxy/createProxyAuthProviderFactory.ts index 8626c40b33..36e7b04e1e 100644 --- a/plugins/auth-node/src/proxy/createProxyAuthProviderFactory.ts +++ b/plugins/auth-node/src/proxy/createProxyAuthProviderFactory.ts @@ -28,7 +28,7 @@ import { ProxyAuthenticator } from './types'; /** @public */ export function createProxyAuthProviderFactory(options: { - authenticator: ProxyAuthenticator; + authenticator: ProxyAuthenticator; profileTransform?: ProfileTransform; signInResolver?: SignInResolver; signInResolverFactories?: Record< diff --git a/plugins/auth-node/src/proxy/createProxyRouteHandlers.ts b/plugins/auth-node/src/proxy/createProxyRouteHandlers.ts index 521fe39288..9aea9b27a7 100644 --- a/plugins/auth-node/src/proxy/createProxyRouteHandlers.ts +++ b/plugins/auth-node/src/proxy/createProxyRouteHandlers.ts @@ -29,7 +29,7 @@ import { NotImplementedError } from '@backstage/errors'; /** @public */ export interface ProxyAuthRouteHandlersOptions { - authenticator: ProxyAuthenticator; + authenticator: ProxyAuthenticator; config: Config; resolverContext: AuthResolverContext; signInResolver: SignInResolver; @@ -56,7 +56,7 @@ export function createProxyAuthRouteHandlers( }, async refresh(this: never, req: Request, res: Response): Promise { - const { result } = await authenticator.authenticate( + const { result, providerInfo } = await authenticator.authenticate( { req }, authenticatorCtx, ); @@ -68,9 +68,9 @@ export function createProxyAuthRouteHandlers( resolverContext, ); - const response: ClientAuthResponse<{}> = { + const response: ClientAuthResponse = { profile, - providerInfo: {}, + providerInfo, backstageIdentity: prepareBackstageIdentityResponse(identity), }; diff --git a/plugins/auth-node/src/proxy/types.ts b/plugins/auth-node/src/proxy/types.ts index 0f52feaac4..06f5a145fd 100644 --- a/plugins/auth-node/src/proxy/types.ts +++ b/plugins/auth-node/src/proxy/types.ts @@ -19,18 +19,22 @@ import { Request } from 'express'; import { ProfileTransform } from '../types'; /** @public */ -export interface ProxyAuthenticator { +export interface ProxyAuthenticator< + TContext, + TResult, + TProviderInfo = undefined, +> { defaultProfileTransform: ProfileTransform; initialize(ctx: { config: Config }): TContext; authenticate( options: { req: Request }, ctx: TContext, - ): Promise<{ result: TResult }>; + ): Promise<{ result: TResult; providerInfo?: TProviderInfo }>; } /** @public */ -export function createProxyAuthenticator( - authenticator: ProxyAuthenticator, -): ProxyAuthenticator { +export function createProxyAuthenticator( + authenticator: ProxyAuthenticator, +): ProxyAuthenticator { return authenticator; }