diff --git a/CHANGELOG.md b/CHANGELOG.md index 2565f6e6d..63fb1b3da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ * Support for "global" views. * New `SessionStorageService` and associated persistence provider provides support for saving tab local data across reloads. +* Added support for `AuthZeroClientConfig.audience` to support improved configuration of Auth0 OAuth + clients requesting access tokens, covering cases when third-party cookies are blocked. ### ⚙️ Technical diff --git a/security/authzero/AuthZeroClient.ts b/security/authzero/AuthZeroClient.ts index ce22c494c..e918058a3 100644 --- a/security/authzero/AuthZeroClient.ts +++ b/security/authzero/AuthZeroClient.ts @@ -4,7 +4,8 @@ * * Copyright © 2024 Extremely Heavy Industries Inc. */ -import {Auth0Client, Auth0ClientOptions} from '@auth0/auth0-spa-js'; +import type {Auth0ClientOptions} from '@auth0/auth0-spa-js'; +import {Auth0Client} from '@auth0/auth0-spa-js'; import {XH} from '@xh/hoist/core'; import {never, wait} from '@xh/hoist/promise'; import {Token, TokenMap} from '@xh/hoist/security/Token'; @@ -14,9 +15,23 @@ import {flatMap, union} from 'lodash'; import {BaseOAuthClient, BaseOAuthClientConfig} from '../BaseOAuthClient'; export interface AuthZeroClientConfig extends BaseOAuthClientConfig { - /** Domain of your app registered with Auth0 */ + /** Domain of your app registered with Auth0. */ domain: string; + /** + * Audience to pass to interactive login and ID token requests. + * + * If you are also requesting an *access* token for a single audience, pass that value here to + * ensure that the initial login/token request returns a ready-to-use access token (and refresh + * token) with a single request to the Auth0 API, instead of requiring two. + * + * This also avoids issues with browsers that block third party cookies when running on + * localhost or with an Auth0 domain that does not match the app's own domain. In those cases, + * Auth0 must use refresh tokens to obtain access tokens, and a single audience allows that + * exchange to work without extra user interaction that this class does not currently support. + */ + audience?: string; + /** * Additional options for the Auth0Client ctor. Will be deep merged with defaults, with options * supplied here taking precedence. Use with care, as overriding defaults may have unintended @@ -31,9 +46,7 @@ export interface AuthZeroTokenSpec { /** * Audience (i.e. API) identifier for AccessToken. Must be registered with Auth0. - * - * Note that this is required to ensure that issued token is a JWT and not - * an opaque string. + * Note that this is required to ensure that issued token is a JWT and not an opaque string. */ audience: string; } @@ -95,7 +108,9 @@ export class AuthZeroClient extends BaseOAuthClient { try { - await this.client.loginWithPopup({authorizationParams: {scope: this.loginScope}}); + await this.client.loginWithPopup({ + authorizationParams: {scope: this.loginScope} + }); await this.noteUserAuthenticatedAsync(); } catch (e) { const msg = e.message?.toLowerCase(); @@ -167,25 +182,27 @@ export class AuthZeroClient extends BaseOAuthClient