From 6f8716bd8ce11b929aa29f7ba0717630d7438ef0 Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Fri, 9 Dec 2022 17:15:50 +0530 Subject: [PATCH 01/10] Adding option to pass additional headers in ProxiedSignInPage Signed-off-by: Abhinav Rastogi --- .../src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts | 4 +++- .../src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts index 7633fc43c3..c8b4d66837 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts @@ -51,6 +51,7 @@ export function tokenToExpiry(jwtToken: string | undefined): Date { type ProxiedSignInIdentityOptions = { provider: string; discoveryApi: typeof discoveryApiRef.T; + getHeaders?: () => Promise; }; type State = @@ -192,6 +193,7 @@ export class ProxiedSignInIdentity implements IdentityApi { async fetchSession(): Promise { const baseUrl = await this.options.discoveryApi.getBaseUrl('auth'); + const headers = await this.options.getHeaders?.(); // Note that we do not use the fetchApi here, since this all happens before // sign-in completes so there can be no automatic token injection and @@ -200,7 +202,7 @@ export class ProxiedSignInIdentity implements IdentityApi { `${baseUrl}/${this.options.provider}/refresh`, { signal: this.abortController.signal, - headers: { 'x-requested-with': 'XMLHttpRequest' }, + headers: { ...headers, 'x-requested-with': 'XMLHttpRequest' }, credentials: 'include', }, ); diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx index 965c603004..78ca5a8e84 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx @@ -36,6 +36,12 @@ export type ProxiedSignInPageProps = SignInPageProps & { * a properly configured auth provider ID in the auth backend. */ provider: string; + + /** + * An optional function which returns a promise resolving with any headers + * that need to be added to the call made to /refresh endpoint. + */ + getHeaders?: () => Promise; }; /** @@ -60,6 +66,7 @@ export const ProxiedSignInPage = (props: ProxiedSignInPageProps) => { const identity = new ProxiedSignInIdentity({ provider: props.provider, discoveryApi, + getHeaders: props.getHeaders, }); await identity.start(); From a5a2d12298b169768c5702ca20e1e9feeefbe986 Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Fri, 9 Dec 2022 17:18:47 +0530 Subject: [PATCH 02/10] Added changeset Signed-off-by: Abhinav Rastogi --- .changeset/violet-dots-relate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/violet-dots-relate.md diff --git a/.changeset/violet-dots-relate.md b/.changeset/violet-dots-relate.md new file mode 100644 index 0000000000..3b63129337 --- /dev/null +++ b/.changeset/violet-dots-relate.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': minor +--- + +Added option to pass additional headers in ProxiedSignInPage From f7749ae07fe13479bf92c48c4dbbfe5d3a63c82f Mon Sep 17 00:00:00 2001 From: Himanshu Mishra Date: Mon, 12 Dec 2022 11:38:23 +0530 Subject: [PATCH 03/10] update changeset with example and change minor to patch (#7) Signed-off-by: Himanshu Mishra Signed-off-by: Himanshu Mishra --- .changeset/violet-dots-relate.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.changeset/violet-dots-relate.md b/.changeset/violet-dots-relate.md index 3b63129337..bc6b75caf9 100644 --- a/.changeset/violet-dots-relate.md +++ b/.changeset/violet-dots-relate.md @@ -1,5 +1,30 @@ --- -'@backstage/core-components': minor +'@backstage/core-components': patch --- -Added option to pass additional headers in ProxiedSignInPage +Added option to pass additional headers to `` + +The supports signing into Backstage with a Sign Page coming from an external provider e.g. Google IAP, AWS ALB, etc. The component makes requests to a single endpoint `/refresh` on the auth backend to fetch the logged in user session. + +If the provider in auth backend expects additional headers such as `x-provider-token`, there is now a way to configure that in `ProxiedSignInPage` using the optional `getHeaders` prop. + +Example - + +```tsx +const app = createApp({ + // ... + components: { + SignInPage: props => ( + { + const someValue = await someFn(); + return { 'x-some-key': someValue }; + }} + /> + ), + }, + // ... +}); +``` From bf6efe3a73fcc8d76e84a14600b46b11a51c8fd0 Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Mon, 12 Dec 2022 11:50:41 +0530 Subject: [PATCH 04/10] Tests for headers (#8) * Adds tests for ProxiedSignInPage * working test for headers * code formatting Signed-off-by: Abhinav Rastogi --- .../ProxiedSignInIdentity.test.ts | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts index 3a40f5bb4b..17a1287052 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts @@ -103,7 +103,6 @@ describe('ProxiedSignInIdentity', () => { }, }; } - worker.events.on('request:match', serverCalled); worker.use( rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) => @@ -164,5 +163,57 @@ describe('ProxiedSignInIdentity', () => { await identity.getSessionAsync(); // now the expiry has passed expect(serverCalled).toHaveBeenCalledTimes(2); }); + + it('handles optional headers correctly', async () => { + let req1: Request; + const getBaseUrl = jest.fn(); + const serverCalled = jest.fn().mockImplementation(req => { + req1 = req; + }); + + worker.events.on('request:match', serverCalled); + worker.use( + rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + // dummy response as we are only testing the request in this test + ctx.json({ + providerInfo: {}, + profile: {}, + backstageIdentity: { + token: '', + identity: { + ownershipEntityRefs: [''], + userEntityRef: '', + type: 'user', + }, + }, + }), + ), + ), + ); + + const getHeaders = jest.fn().mockResolvedValue({ 'x-foo': 'bars' }); + const identity = new ProxiedSignInIdentity({ + provider: 'foo', + discoveryApi: { getBaseUrl }, + getHeaders: getHeaders, + }); + + getBaseUrl.mockResolvedValue('http://example.com/api/auth'); + + await identity.start(); // should not throw + expect(getBaseUrl).toHaveBeenCalledTimes(1); + expect(getBaseUrl).toHaveBeenLastCalledWith('auth'); + expect(getHeaders).toHaveBeenCalledTimes(1); + expect(serverCalled).toHaveBeenCalledTimes(1); + + expect(req1).not.toBeUndefined(); + // required header should be present + expect(req1!.headers.get('x-requested-with')).toEqual('XMLHttpRequest'); + // optional header should be present when passed + expect(req1!.headers.get('x-foo')).toEqual('bars'); + }); }); }); From 681f6a63c1f9bc957a1b70babdf839e8908b953c Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Mon, 12 Dec 2022 12:20:16 +0530 Subject: [PATCH 05/10] handle undefined check Signed-off-by: Abhinav Rastogi --- .../src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts index 17a1287052..ed3a1d73a9 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts @@ -209,7 +209,7 @@ describe('ProxiedSignInIdentity', () => { expect(getHeaders).toHaveBeenCalledTimes(1); expect(serverCalled).toHaveBeenCalledTimes(1); - expect(req1).not.toBeUndefined(); + expect(req1!).not.toBeUndefined(); // required header should be present expect(req1!.headers.get('x-requested-with')).toEqual('XMLHttpRequest'); // optional header should be present when passed From 6c9fbd19570d5920fa89892c532206ec0664d33c Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Mon, 12 Dec 2022 12:59:55 +0530 Subject: [PATCH 06/10] add api-report Signed-off-by: Abhinav Rastogi --- packages/core-components/api-report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index d8ea9d2bbe..1c3717f1ee 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -807,6 +807,7 @@ export const ProxiedSignInPage: ( // @public export type ProxiedSignInPageProps = SignInPageProps & { provider: string; + getHeaders?: () => Promise; }; // Warning: (ae-missing-release-tag) "Ranker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) From 0548ef8ed82d689e5b514ee29f555a106aa1ff55 Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Mon, 12 Dec 2022 16:29:35 +0530 Subject: [PATCH 07/10] accept objects, functions and promises for headers Signed-off-by: Abhinav Rastogi --- .changeset/violet-dots-relate.md | 27 +---- .../ProxiedSignInIdentity.test.ts | 110 +++++++++++++++--- .../ProxiedSignInIdentity.ts | 17 ++- .../ProxiedSignInPage/ProxiedSignInPage.tsx | 10 +- 4 files changed, 115 insertions(+), 49 deletions(-) diff --git a/.changeset/violet-dots-relate.md b/.changeset/violet-dots-relate.md index bc6b75caf9..3e22cdd1c7 100644 --- a/.changeset/violet-dots-relate.md +++ b/.changeset/violet-dots-relate.md @@ -2,29 +2,4 @@ '@backstage/core-components': patch --- -Added option to pass additional headers to `` - -The supports signing into Backstage with a Sign Page coming from an external provider e.g. Google IAP, AWS ALB, etc. The component makes requests to a single endpoint `/refresh` on the auth backend to fetch the logged in user session. - -If the provider in auth backend expects additional headers such as `x-provider-token`, there is now a way to configure that in `ProxiedSignInPage` using the optional `getHeaders` prop. - -Example - - -```tsx -const app = createApp({ - // ... - components: { - SignInPage: props => ( - { - const someValue = await someFn(); - return { 'x-some-key': someValue }; - }} - /> - ), - }, - // ... -}); -``` +Added option to pass additional headers to ``, which are passed along with the request to the underlying provider diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts index ed3a1d73a9..b8c2b84085 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.test.ts @@ -164,7 +164,21 @@ describe('ProxiedSignInIdentity', () => { expect(serverCalled).toHaveBeenCalledTimes(2); }); - it('handles optional headers correctly', async () => { + // dummy response for tests which are only testing the request behaviour + const dummySessionResponse = { + providerInfo: {}, + profile: {}, + backstageIdentity: { + token: '', + identity: { + ownershipEntityRefs: [''], + userEntityRef: '', + type: 'user', + }, + }, + }; + + it('handles headers passed as a promise', async () => { let req1: Request; const getBaseUrl = jest.fn(); const serverCalled = jest.fn().mockImplementation(req => { @@ -177,19 +191,7 @@ describe('ProxiedSignInIdentity', () => { res( ctx.status(200), ctx.set('Content-Type', 'application/json'), - // dummy response as we are only testing the request in this test - ctx.json({ - providerInfo: {}, - profile: {}, - backstageIdentity: { - token: '', - identity: { - ownershipEntityRefs: [''], - userEntityRef: '', - type: 'user', - }, - }, - }), + ctx.json(dummySessionResponse), ), ), ); @@ -198,7 +200,85 @@ describe('ProxiedSignInIdentity', () => { const identity = new ProxiedSignInIdentity({ provider: 'foo', discoveryApi: { getBaseUrl }, - getHeaders: getHeaders, + headers: getHeaders, + }); + + getBaseUrl.mockResolvedValue('http://example.com/api/auth'); + + await identity.start(); // should not throw + expect(getBaseUrl).toHaveBeenCalledTimes(1); + expect(getBaseUrl).toHaveBeenLastCalledWith('auth'); + expect(getHeaders).toHaveBeenCalledTimes(1); + expect(serverCalled).toHaveBeenCalledTimes(1); + + expect(req1!).not.toBeUndefined(); + // required header should be present + expect(req1!.headers.get('x-requested-with')).toEqual('XMLHttpRequest'); + // optional header should be present when passed + expect(req1!.headers.get('x-foo')).toEqual('bars'); + }); + + it('handles headers passed as an object', async () => { + let req1: Request; + const getBaseUrl = jest.fn(); + const serverCalled = jest.fn().mockImplementation(req => { + req1 = req; + }); + + worker.events.on('request:match', serverCalled); + worker.use( + rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(dummySessionResponse), + ), + ), + ); + + const identity = new ProxiedSignInIdentity({ + provider: 'foo', + discoveryApi: { getBaseUrl }, + headers: { 'x-foo': 'bars' }, + }); + + getBaseUrl.mockResolvedValue('http://example.com/api/auth'); + + await identity.start(); // should not throw + expect(getBaseUrl).toHaveBeenCalledTimes(1); + expect(getBaseUrl).toHaveBeenLastCalledWith('auth'); + expect(serverCalled).toHaveBeenCalledTimes(1); + + expect(req1!).not.toBeUndefined(); + // required header should be present + expect(req1!.headers.get('x-requested-with')).toEqual('XMLHttpRequest'); + // optional header should be present when passed + expect(req1!.headers.get('x-foo')).toEqual('bars'); + }); + + it('handles headers passed as a function', async () => { + let req1: Request; + const getBaseUrl = jest.fn(); + const serverCalled = jest.fn().mockImplementation(req => { + req1 = req; + }); + + worker.events.on('request:match', serverCalled); + worker.use( + rest.get('http://example.com/api/auth/foo/refresh', (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(dummySessionResponse), + ), + ), + ); + + const getHeaders = jest.fn().mockReturnValue({ 'x-foo': 'bars' }); + const identity = new ProxiedSignInIdentity({ + provider: 'foo', + discoveryApi: { getBaseUrl }, + headers: getHeaders, }); getBaseUrl.mockResolvedValue('http://example.com/api/auth'); diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts index c8b4d66837..828e9ab1a0 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts @@ -48,10 +48,15 @@ export function tokenToExpiry(jwtToken: string | undefined): Date { return new Date(payload.exp * 1000 - DEFAULTS.tokenExpiryMarginMillis); } +export type RefreshHeaders = + | HeadersInit + | (() => HeadersInit) + | (() => Promise); + type ProxiedSignInIdentityOptions = { provider: string; discoveryApi: typeof discoveryApiRef.T; - getHeaders?: () => Promise; + headers?: RefreshHeaders; }; type State = @@ -193,7 +198,13 @@ export class ProxiedSignInIdentity implements IdentityApi { async fetchSession(): Promise { const baseUrl = await this.options.discoveryApi.getBaseUrl('auth'); - const headers = await this.options.getHeaders?.(); + + const headers = + typeof this.options.headers === 'function' + ? await this.options.headers() + : this.options.headers; + const mergedHeaders = new Headers(headers); + mergedHeaders.set('X-Requested-With', 'XMLHttpRequest'); // Note that we do not use the fetchApi here, since this all happens before // sign-in completes so there can be no automatic token injection and @@ -202,7 +213,7 @@ export class ProxiedSignInIdentity implements IdentityApi { `${baseUrl}/${this.options.provider}/refresh`, { signal: this.abortController.signal, - headers: { ...headers, 'x-requested-with': 'XMLHttpRequest' }, + headers: mergedHeaders, credentials: 'include', }, ); diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx index 78ca5a8e84..9d91a31462 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx @@ -23,7 +23,7 @@ import React from 'react'; import { useAsync, useMountEffect } from '@react-hookz/web'; import { ErrorPanel } from '../../components/ErrorPanel'; import { Progress } from '../../components/Progress'; -import { ProxiedSignInIdentity } from './ProxiedSignInIdentity'; +import { ProxiedSignInIdentity, RefreshHeaders } from './ProxiedSignInIdentity'; /** * Props for {@link ProxiedSignInPage}. @@ -38,10 +38,10 @@ export type ProxiedSignInPageProps = SignInPageProps & { provider: string; /** - * An optional function which returns a promise resolving with any headers - * that need to be added to the call made to /refresh endpoint. + * Optional headers which are passed along with the request to the + * underlying provider */ - getHeaders?: () => Promise; + headers?: RefreshHeaders; }; /** @@ -66,7 +66,7 @@ export const ProxiedSignInPage = (props: ProxiedSignInPageProps) => { const identity = new ProxiedSignInIdentity({ provider: props.provider, discoveryApi, - getHeaders: props.getHeaders, + headers: props.headers, }); await identity.start(); From 35db4c669adbcf702d955d2e895329e888e22093 Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Mon, 12 Dec 2022 16:42:03 +0530 Subject: [PATCH 08/10] update docs for ProxiedSignInPage Signed-off-by: Abhinav Rastogi --- docs/auth/index.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/auth/index.md b/docs/auth/index.md index 5702e96cee..fa185c0c23 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -150,6 +150,31 @@ const app = createApp({ }); ``` +If the provider in auth backend expects additional headers such as `x-provider-token`, there is now a way to configure that in `ProxiedSignInPage` using the optional `headers` prop. + +Example: + +```tsx + +``` + +Headers can also be returned in an async manner: + +```tsx + { + const someValue = await someFn(); + return { 'x-some-key': someValue }; + }} +/> +``` + A downside of this method is that it can be cumbersome to set up for local development. As a workaround for this, it's possible to dynamically select the sign-in page based on what environment the app is running in, and then use a different sign-in method for local From fae040888aba06646b5a363fa80cfc5fc0a3915e Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Mon, 12 Dec 2022 16:44:04 +0530 Subject: [PATCH 09/10] update api-report.md Signed-off-by: Abhinav Rastogi --- packages/core-components/api-report.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 1c3717f1ee..82d75fba96 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -807,7 +807,7 @@ export const ProxiedSignInPage: ( // @public export type ProxiedSignInPageProps = SignInPageProps & { provider: string; - getHeaders?: () => Promise; + headers?: RefreshHeaders; }; // Warning: (ae-missing-release-tag) "Ranker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1533,4 +1533,5 @@ export type WarningPanelClassKey = // src/components/TabbedLayout/RoutedTabs.d.ts:9:5 - (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts // src/components/Table/Table.d.ts:20:5 - (ae-forgotten-export) The symbol "SelectedFilters" needs to be exported by the entry point index.d.ts // src/layout/ErrorBoundary/ErrorBoundary.d.ts:8:5 - (ae-forgotten-export) The symbol "SlackChannel" needs to be exported by the entry point index.d.ts +// src/layout/ProxiedSignInPage/ProxiedSignInPage.d.ts:19:5 - (ae-forgotten-export) The symbol "RefreshHeaders" needs to be exported by the entry point index.d.ts ``` From b5c65ca6e9ec7f192ddbf59afc20f1096e8c724e Mon Sep 17 00:00:00 2001 From: Abhinav Rastogi Date: Mon, 12 Dec 2022 17:56:41 +0530 Subject: [PATCH 10/10] remove intermediate type for headers Signed-off-by: Abhinav Rastogi --- packages/core-components/api-report.md | 3 +-- .../src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts | 7 +------ .../src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx | 4 ++-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 82d75fba96..c46b3637cb 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -807,7 +807,7 @@ export const ProxiedSignInPage: ( // @public export type ProxiedSignInPageProps = SignInPageProps & { provider: string; - headers?: RefreshHeaders; + headers?: HeadersInit | (() => HeadersInit) | (() => Promise); }; // Warning: (ae-missing-release-tag) "Ranker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1533,5 +1533,4 @@ export type WarningPanelClassKey = // src/components/TabbedLayout/RoutedTabs.d.ts:9:5 - (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts // src/components/Table/Table.d.ts:20:5 - (ae-forgotten-export) The symbol "SelectedFilters" needs to be exported by the entry point index.d.ts // src/layout/ErrorBoundary/ErrorBoundary.d.ts:8:5 - (ae-forgotten-export) The symbol "SlackChannel" needs to be exported by the entry point index.d.ts -// src/layout/ProxiedSignInPage/ProxiedSignInPage.d.ts:19:5 - (ae-forgotten-export) The symbol "RefreshHeaders" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts index 828e9ab1a0..bd1fc1bf39 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInIdentity.ts @@ -48,15 +48,10 @@ export function tokenToExpiry(jwtToken: string | undefined): Date { return new Date(payload.exp * 1000 - DEFAULTS.tokenExpiryMarginMillis); } -export type RefreshHeaders = - | HeadersInit - | (() => HeadersInit) - | (() => Promise); - type ProxiedSignInIdentityOptions = { provider: string; discoveryApi: typeof discoveryApiRef.T; - headers?: RefreshHeaders; + headers?: HeadersInit | (() => HeadersInit) | (() => Promise); }; type State = diff --git a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx index 9d91a31462..ea095cd8ab 100644 --- a/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx +++ b/packages/core-components/src/layout/ProxiedSignInPage/ProxiedSignInPage.tsx @@ -23,7 +23,7 @@ import React from 'react'; import { useAsync, useMountEffect } from '@react-hookz/web'; import { ErrorPanel } from '../../components/ErrorPanel'; import { Progress } from '../../components/Progress'; -import { ProxiedSignInIdentity, RefreshHeaders } from './ProxiedSignInIdentity'; +import { ProxiedSignInIdentity } from './ProxiedSignInIdentity'; /** * Props for {@link ProxiedSignInPage}. @@ -41,7 +41,7 @@ export type ProxiedSignInPageProps = SignInPageProps & { * Optional headers which are passed along with the request to the * underlying provider */ - headers?: RefreshHeaders; + headers?: HeadersInit | (() => HeadersInit) | (() => Promise); }; /**