From abe404176c6dd987f785ddb2d3df2d26d3a230ea Mon Sep 17 00:00:00 2001 From: Odin Thomas Rochmann Date: Tue, 12 Mar 2024 14:31:52 +0100 Subject: [PATCH 1/4] feat(module-msal): add AuthBehavior parameter to AuthClient constructor --- .changeset/four-waves-joke.md | 15 +++++++++++++++ packages/modules/msal/src/client/client.ts | 8 ++++++-- .../modules/msal/src/client/create-auth-client.ts | 12 +++++++----- 3 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 .changeset/four-waves-joke.md diff --git a/.changeset/four-waves-joke.md b/.changeset/four-waves-joke.md new file mode 100644 index 000000000..8cea595f0 --- /dev/null +++ b/.changeset/four-waves-joke.md @@ -0,0 +1,15 @@ +--- +"@equinor/fusion-framework-module-msal": minor +--- + +Added functionality for setting default authentication behavior (`redirect` or `popup`) when creating authentication client. + +```ts +const client = new AuthClient( + "TENNANT_ID", + { + /** auth client options */ + }, + "redirect" || "popup", +); +``` diff --git a/packages/modules/msal/src/client/client.ts b/packages/modules/msal/src/client/client.ts index 2dda89eaf..18a061425 100644 --- a/packages/modules/msal/src/client/client.ts +++ b/packages/modules/msal/src/client/client.ts @@ -85,6 +85,8 @@ export class AuthClient extends PublicClientApplication { return this.browserStorage.getTemporaryCache('request.origin', true); } + #behavior: AuthBehavior; + /** * @param tenantId - tenant id for client domain * @param config - required [Configuration](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/src/config/Configuration.ts) @@ -92,8 +94,10 @@ export class AuthClient extends PublicClientApplication { constructor( readonly tenantId: string, config: Configuration, + behavior: AuthBehavior = defaultBehavior, ) { super(config); + this.#behavior = behavior; } /** @@ -109,7 +113,7 @@ export class AuthClient extends PublicClientApplication { */ async login( options?: AuthRequest, - behavior: AuthBehavior = defaultBehavior, + behavior: AuthBehavior = this.#behavior, silent = true, ): Promise { const loginHint = options?.loginHint || this.account?.username; @@ -153,7 +157,7 @@ export class AuthClient extends PublicClientApplication { */ public async acquireToken( options: AuthRequest = { scopes: [] }, - behavior: AuthBehavior = defaultBehavior, + behavior: AuthBehavior = this.#behavior, silent = true, ): Promise { const account = await this.account; diff --git a/packages/modules/msal/src/client/create-auth-client.ts b/packages/modules/msal/src/client/create-auth-client.ts index d509dfe33..1e26621c3 100644 --- a/packages/modules/msal/src/client/create-auth-client.ts +++ b/packages/modules/msal/src/client/create-auth-client.ts @@ -1,9 +1,11 @@ import { Configuration, IPublicClientApplication } from '@azure/msal-browser'; import { AuthClient } from './client'; import { normalizeUri } from './util/url'; +import { AuthBehavior } from './behavior'; -export type AuthClientConfig = Configuration & { - auth: Partial; +export type AuthClientConfig = Omit & { + auth?: Partial; + behavior?: AuthBehavior; }; /** @@ -31,7 +33,7 @@ export const createAuthClient = T, + ctor?: new (tenantId: string, config: Configuration, defaultBehavior?: AuthBehavior) => T, ): T => { const auth: Configuration['auth'] = { clientId, @@ -41,8 +43,8 @@ export const createAuthClient = Date: Tue, 12 Mar 2024 14:43:59 +0100 Subject: [PATCH 2/4] feat(module-msal): refactor handleRedirect to check handleRedirectPromise state and add login flag --- .changeset/real-houses-refuse.md | 10 ++++++++++ packages/modules/msal/src/provider.ts | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 .changeset/real-houses-refuse.md diff --git a/.changeset/real-houses-refuse.md b/.changeset/real-houses-refuse.md new file mode 100644 index 000000000..7c1a82d27 --- /dev/null +++ b/.changeset/real-houses-refuse.md @@ -0,0 +1,10 @@ +--- +"@equinor/fusion-framework-module-msal": minor +--- + +Changed `handleRedirect` to check the state of `handleRedirectPromise`, since login threw popup should not trigger redirect. + +Added flag in login state + +- `internal` [_default_] when login was triggered from same frame +- `external` login was triggered by a iframe diff --git a/packages/modules/msal/src/provider.ts b/packages/modules/msal/src/provider.ts index c3e6c42ac..d277035fb 100644 --- a/packages/modules/msal/src/provider.ts +++ b/packages/modules/msal/src/provider.ts @@ -98,13 +98,19 @@ export class AuthProvider implements IAuthProvider { const logger = client.getLogger(); const { requestOrigin } = client; - await client.handleRedirectPromise(); - if (requestOrigin === redirectUri) { + const res = await client.handleRedirectPromise(); + + // if not internal state, do not redirect (state will not be included when popup was created from iframe) + if (res?.state !== 'internal') { + return null; + } else if (requestOrigin === redirectUri) { + // prevent redirect loop logger.warning( `detected callback loop from url ${redirectUri}, redirecting to root`, ); window.location.replace('/'); } else { + // either redirect to origin or root window.location.replace(requestOrigin || '/'); } } @@ -121,6 +127,9 @@ export class AuthProvider implements IAuthProvider { } async login(): Promise { - await this.defaultClient.login(); + await this.defaultClient.login({ + state: window.parent === window ? 'internal' : 'external', + scopes: [], + }); } } From 660e2c556850f816841297aba92d3a3015c9d163 Mon Sep 17 00:00:00 2001 From: Odin Thomas Rochmann Date: Tue, 12 Mar 2024 15:14:37 +0100 Subject: [PATCH 3/4] feat(cli): update CLI config to allow embedding in iframe --- .changeset/afraid-countries-repeat.md | 5 +++++ packages/cli/src/bin/dev-portal/config.ts | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 .changeset/afraid-countries-repeat.md diff --git a/.changeset/afraid-countries-repeat.md b/.changeset/afraid-countries-repeat.md new file mode 100644 index 000000000..bf1737917 --- /dev/null +++ b/.changeset/afraid-countries-repeat.md @@ -0,0 +1,5 @@ +--- +"@equinor/fusion-framework-cli": patch +--- + +Updated CLI config to allow embedding in iframe diff --git a/packages/cli/src/bin/dev-portal/config.ts b/packages/cli/src/bin/dev-portal/config.ts index 90990b42b..8d3551477 100644 --- a/packages/cli/src/bin/dev-portal/config.ts +++ b/packages/cli/src/bin/dev-portal/config.ts @@ -25,6 +25,9 @@ export const configure = async (config: FrameworkConfigurator) => { tenantId: '3aa4a235-b6e2-48d5-9195-7fcf05b459b0', clientId: '9b707e3a-3e90-41ed-a47e-652a1e3b53d0', redirectUri: '/authentication/login-callback', + config: { + behavior: window.parent === window ? 'redirect' : 'popup', + }, }, { requiresAuth: true }, ); From a48dcfe523e40243313637b31b0dc70d1b1ddc47 Mon Sep 17 00:00:00 2001 From: Odin Thomas Rochmann Date: Tue, 12 Mar 2024 15:16:10 +0100 Subject: [PATCH 4/4] feat(cookbook-app-react): add sample of iframe --- .changeset/plenty-moose-smoke.md | 5 +++++ cookbooks/app-react/index.html | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 .changeset/plenty-moose-smoke.md create mode 100644 cookbooks/app-react/index.html diff --git a/.changeset/plenty-moose-smoke.md b/.changeset/plenty-moose-smoke.md new file mode 100644 index 000000000..bc94fb42f --- /dev/null +++ b/.changeset/plenty-moose-smoke.md @@ -0,0 +1,5 @@ +--- +"@equinor/fusion-framework-cookbook-app-react": patch +--- + +Added sample page for testing og iframe diff --git a/cookbooks/app-react/index.html b/cookbooks/app-react/index.html new file mode 100644 index 000000000..ebe16c7c2 --- /dev/null +++ b/cookbooks/app-react/index.html @@ -0,0 +1,10 @@ + + + + My Web Page + + +

Hello, world!

+ + +