From 82a29469f705c0b2f36a792b6553e8b594d7db61 Mon Sep 17 00:00:00 2001 From: Badisi Date: Wed, 1 Mar 2023 16:10:15 +0100 Subject: [PATCH] feat(mobile): allow window customizations (toolbar color, presentation style, width and height) --- projects/auth-js/oidc/index.ts | 1 + .../auth-js/oidc/mobile/mobile-navigator.ts | 13 ++---- projects/auth-js/oidc/mobile/mobile-window.ts | 12 ++--- .../oidc/models/mobile-window-params.model.ts | 26 ++++++++++- .../oidc/models/oidc-auth-settings.model.ts | 3 +- projects/auth-js/oidc/oidc-auth-manager.ts | 9 ++-- .../{user-manager.ts => oidc-user-manager.ts} | 44 ++++++++++++++++--- 7 files changed, 80 insertions(+), 28 deletions(-) rename projects/auth-js/oidc/{user-manager.ts => oidc-user-manager.ts} (60%) diff --git a/projects/auth-js/oidc/index.ts b/projects/auth-js/oidc/index.ts index 5013f93..8584797 100644 --- a/projects/auth-js/oidc/index.ts +++ b/projects/auth-js/oidc/index.ts @@ -11,6 +11,7 @@ export type { UserProfile } from 'oidc-client-ts'; export type { Optional, AuthSubscriber, AuthSubscription } from '../core'; export type { AccessToken } from './models/access-token.model'; export type { IdToken } from './models/id-token.model'; +export type { MobileWindowParams } from './models/mobile-window-params.model'; export * from '../core'; export * from './models/oidc-auth-settings.model'; diff --git a/projects/auth-js/oidc/mobile/mobile-navigator.ts b/projects/auth-js/oidc/mobile/mobile-navigator.ts index f33b9d4..96039ab 100644 --- a/projects/auth-js/oidc/mobile/mobile-navigator.ts +++ b/projects/auth-js/oidc/mobile/mobile-navigator.ts @@ -1,4 +1,4 @@ -import { Logger, UserManagerSettingsStore } from 'oidc-client-ts'; +import { Logger } from 'oidc-client-ts'; import { MobileWindowParams } from '../models/mobile-window-params.model'; import { MobileWindow } from './mobile-window'; @@ -6,15 +6,8 @@ import { MobileWindow } from './mobile-window'; export class MobileNavigator { private readonly _logger = new Logger('MobileNavigator'); - constructor( - public settings: UserManagerSettingsStore - ) { - // TODO: manage settings - } - - public prepare(params: MobileWindowParams, redirectUrl: string): MobileWindow { - // TODO: manage params + public prepare(redirectUrl: string, params: MobileWindowParams): MobileWindow { this._logger.create('prepare'); - return new MobileWindow(params, redirectUrl); + return new MobileWindow(redirectUrl, params); } } diff --git a/projects/auth-js/oidc/mobile/mobile-window.ts b/projects/auth-js/oidc/mobile/mobile-window.ts index b3b9e47..4c75c87 100644 --- a/projects/auth-js/oidc/mobile/mobile-window.ts +++ b/projects/auth-js/oidc/mobile/mobile-window.ts @@ -24,8 +24,8 @@ export class MobileWindow implements IWindow { private _reject?: (reason?: unknown) => void; constructor( - public options: MobileWindowParams, - public redirectUrl: string + public redirectUrl: string, + public params: MobileWindowParams ) { if (!AuthUtils.isCapacitor() && !AuthUtils.isCordova()) { let message = '[@badisi/auth-js] Required core dependency not found.\n\n'; @@ -39,8 +39,7 @@ export class MobileWindow implements IWindow { console.error(message); } - // TODO: - /* if (!BROWSER_TAB && CAPACITOR_BROWSER) { + /* TODO: if (!BROWSER_TAB && CAPACITOR_BROWSER) { let message = '[@badisi/auth-js] This application is currently using a non recommended browser plugin.\n\n'; message += 'ⓘ Please follow the recommended guide and use `@badisi/capacitor-browsertab` instead.'; console.warn(message); @@ -112,7 +111,10 @@ export class MobileWindow implements IWindow { await CAPACITOR_BROWSER?.open({ url: params.url, - presentationStyle: 'popover' + toolbarColor: this.params.mobileWindowToolbarColor, + presentationStyle: this.params.mobileWindowPresentationStyle, + width: this.params.mobileWindowWidth, + height: this.params.mobileWindowWidth }); } diff --git a/projects/auth-js/oidc/models/mobile-window-params.model.ts b/projects/auth-js/oidc/models/mobile-window-params.model.ts index 7430f51..a8d685a 100644 --- a/projects/auth-js/oidc/models/mobile-window-params.model.ts +++ b/projects/auth-js/oidc/models/mobile-window-params.model.ts @@ -1,3 +1,27 @@ export interface MobileWindowParams { - mobileWindowName?: string; + /** + * A hex color to which the toolbar color is set. + */ + mobileWindowToolbarColor?: string; + + /** + * iOS only: The presentation style of the browser. Defaults to fullscreen. + * + * Ignored on other platforms. + */ + mobileWindowPresentationStyle?: 'fullscreen' | 'popover'; + + /** + * iOS only: The width the browser when using presentationStyle 'popover' on iPads. + * + * Ignored on other platforms. + */ + mobileWindowWidth?: number; + + /** + * iOS only: The height the browser when using presentationStyle 'popover' on iPads. + * + * Ignored on other platforms. + */ + mobileWindowHeight?: number; } diff --git a/projects/auth-js/oidc/models/oidc-auth-settings.model.ts b/projects/auth-js/oidc/models/oidc-auth-settings.model.ts index e626d42..e545414 100644 --- a/projects/auth-js/oidc/models/oidc-auth-settings.model.ts +++ b/projects/auth-js/oidc/models/oidc-auth-settings.model.ts @@ -1,6 +1,7 @@ import { Log, UserManagerSettings } from 'oidc-client-ts'; import { AuthSettings as CoreAuthSettings } from '../../core'; +import { MobileWindowParams } from './mobile-window-params.model'; export enum DesktopNavigation { REDIRECT = 'REDIRECT', @@ -17,5 +18,5 @@ export interface OIDCAuthSettings extends CoreAuthSettings, Pick>; + internal?: Partial> & MobileWindowParams; } diff --git a/projects/auth-js/oidc/oidc-auth-manager.ts b/projects/auth-js/oidc/oidc-auth-manager.ts index 69e98c9..cebf394 100644 --- a/projects/auth-js/oidc/oidc-auth-manager.ts +++ b/projects/auth-js/oidc/oidc-auth-manager.ts @@ -13,7 +13,7 @@ import { IdToken } from './models/id-token.model'; import { MobileWindowParams } from './models/mobile-window-params.model'; import { DesktopNavigation, OIDCAuthSettings } from './models/oidc-auth-settings.model'; import { UserSession } from './models/user-session.model'; -import { UserManager } from './user-manager'; +import { OidcUserManager } from './oidc-user-manager'; const REDIRECT_URL_KEY = 'auth-js:oidc_manager:redirect_url'; @@ -31,7 +31,8 @@ const DEFAULT_SETTINGS: Optional post_logout_redirect_uri: '?oidc-callback=logout', popup_redirect_uri: 'oidc/callback/popup_redirect.html', popup_post_logout_redirect_uri: 'oidc/callback/popup_redirect.html', - silent_redirect_uri: 'oidc/callback/silent_redirect.html' + silent_redirect_uri: 'oidc/callback/silent_redirect.html', + mobileWindowPresentationStyle: 'popover' } }; @@ -64,7 +65,7 @@ export class OIDCAuthManager extends AuthManager { private _isAuthenticated = false; private _isRenewing = false; - private userManager?: UserManager; + private userManager?: OidcUserManager; private settings = DEFAULT_SETTINGS as OIDCAuthSettings; private _user?: User | null; @@ -117,7 +118,7 @@ export class OIDCAuthManager extends AuthManager { this.patchAuth0Logout(); // Configure the user manager - this.userManager = new UserManager(this.settings); + this.userManager = new OidcUserManager(this.settings); // Listen for events this.userManagerSubs.push( diff --git a/projects/auth-js/oidc/user-manager.ts b/projects/auth-js/oidc/oidc-user-manager.ts similarity index 60% rename from projects/auth-js/oidc/user-manager.ts rename to projects/auth-js/oidc/oidc-user-manager.ts index 953d6e3..6d90de0 100644 --- a/projects/auth-js/oidc/user-manager.ts +++ b/projects/auth-js/oidc/oidc-user-manager.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention, camelcase */ import { - ExtraSigninRequestArgs, ExtraSignoutRequestArgs, UserManager as OidcClientUserManager, UserManagerSettings + ExtraSigninRequestArgs, ExtraSignoutRequestArgs, UserManager, UserManagerSettings } from 'oidc-client-ts'; import { MobileNavigator } from './mobile/mobile-navigator'; @@ -16,7 +16,7 @@ export type SignoutMobileArgs = MobileWindowParams & ExtraSignoutRequestArgs; * Extended UserManager class that adds helpers and mobile capabilities * (ex: signinMobile, signoutMobile, MobileNavigator, MobileWindow) */ -export class UserManager extends OidcClientUserManager { +export class OidcUserManager extends UserManager { private _mobileNavigator!: MobileNavigator; constructor( @@ -31,7 +31,7 @@ export class UserManager extends OidcClientUserManager { ...libSettings.internal } as UserManagerSettings); - this._mobileNavigator = new MobileNavigator(this.settings); + this._mobileNavigator = new MobileNavigator(); } /* public async readRequestTypeFromState(url = location.href): Promise { @@ -50,8 +50,23 @@ export class UserManager extends OidcClientUserManager { public async signoutMobile(args: SignoutMobileArgs = {}): Promise { const logger = this._logger.create('signout'); - const { mobileWindowName, ...requestArgs } = args; - const handle = this._mobileNavigator.prepare({ mobileWindowName }, this.settings.post_logout_redirect_uri as string); + + const { + mobileWindowToolbarColor, + mobileWindowPresentationStyle, + mobileWindowWidth, + mobileWindowHeight, + ...requestArgs + } = args; + + const params = { + mobileWindowToolbarColor: mobileWindowToolbarColor ?? this.libSettings.internal?.mobileWindowToolbarColor, + mobileWindowPresentationStyle: mobileWindowPresentationStyle ?? this.libSettings.internal?.mobileWindowPresentationStyle, + mobileWindowWidth: mobileWindowWidth ?? this.libSettings.internal?.mobileWindowWidth, + mobileWindowHeight: mobileWindowHeight ?? this.libSettings.internal?.mobileWindowHeight + }; + + const handle = this._mobileNavigator.prepare(this.settings.post_logout_redirect_uri as string, params); await this._signout({ request_type: 'so:m', @@ -64,8 +79,23 @@ export class UserManager extends OidcClientUserManager { public async signinMobile(args: SigninMobileArgs = {}): Promise { const logger = this._logger.create('signin'); - const { mobileWindowName, ...requestArgs } = args; - const handle = this._mobileNavigator.prepare({ mobileWindowName }, this.settings.redirect_uri); + + const { + mobileWindowToolbarColor, + mobileWindowPresentationStyle, + mobileWindowWidth, + mobileWindowHeight, + ...requestArgs + } = args; + + const params = { + mobileWindowToolbarColor: mobileWindowToolbarColor ?? this.libSettings.internal?.mobileWindowToolbarColor, + mobileWindowPresentationStyle: mobileWindowPresentationStyle ?? this.libSettings.internal?.mobileWindowPresentationStyle, + mobileWindowWidth: mobileWindowWidth ?? this.libSettings.internal?.mobileWindowWidth, + mobileWindowHeight: mobileWindowHeight ?? this.libSettings.internal?.mobileWindowHeight + }; + + const handle = this._mobileNavigator.prepare(this.settings.redirect_uri, params); const user = await this._signin({ request_type: 'si:m',