diff --git a/src/Oauth.ts b/src/Oauth.ts index b144eda..acbbaf0 100644 --- a/src/Oauth.ts +++ b/src/Oauth.ts @@ -48,7 +48,7 @@ export async function computeAuthorizationUrl(config: AuthConfiguration): Promis const sessionId: string | void = (await initializeOauthSession(config.domain)) || ''; return { - authorizationUrl: `https://${normalizeDomain(config.domain)}/api/oauth/authorize?${toUrlParameter({ + authorizationUrl: `https://${normalizeDomain(config.domain)}/oauth-authorize?${toUrlParameter({ response_type: AUTH_URL_RESPONSE_TYPE, client_id: config.clientId, scope: config.scopes.join('+'), diff --git a/src/Popup.ts b/src/Popup.ts index 8d69e7c..3077e11 100644 --- a/src/Popup.ts +++ b/src/Popup.ts @@ -39,8 +39,10 @@ export class Popup { private readonly unregisterEventListener: () => void; private static EVENT_NAME_CANCELLED = 'frontify-oauth-authorize-cancelled'; private static EVENT_NAME_SUCCESS = 'frontify-oauth-authorize-success'; + private static EVENT_NAME_EXPIRED = 'frontify-oauth-expired'; private static EVENT_METHOD_CANCELLED = 'cancelled'; private static EVENT_METHOD_SUCCESS = 'success'; + private static EVENT_METHOD_EXPIRED = 'expired'; private static EVENT_METHOD_DOMAIN = 'domain'; private static EVENT_METHOD_ABORTED = 'aborted'; public listeners: { [name: string]: () => void } = {}; @@ -69,6 +71,9 @@ export class Popup { case Popup.EVENT_NAME_SUCCESS: this.call(Popup.EVENT_METHOD_SUCCESS); break; + case Popup.EVENT_NAME_EXPIRED: + this.call(Popup.EVENT_METHOD_EXPIRED); + break; default: { const messageData = data as PopupMessageData; if (messageData.domain) { @@ -133,6 +138,10 @@ export class Popup { this.listeners.canceled = callback; } + public onExpired(callback: () => void): void { + this.listeners.expired = callback; + } + close(): void { this.listeners = {}; clearInterval(this.interval); diff --git a/src/index.ts b/src/index.ts index 0c511ab..8ef07ea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -187,6 +187,8 @@ function openAuthPopUp(url: string, popUp: Popup): Promise { }); return new Promise((resolve, reject) => { + // Must exceed the server-side OAuth session TTL (OauthSessionService::EXPIRES_IN_SECONDS, 10 min) + // so the popup is still open when the server renders is_expired=true and fires frontify-oauth-expired. authTimeout = setTimeout( () => { POPUP_STATE.open = false; @@ -196,7 +198,7 @@ function openAuthPopUp(url: string, popUp: Popup): Promise { message: 'Auth popup timed out.', }); }, - 5 * 60 * 1000, + 15 * 60 * 1000, ); popUp.onAborted(() => { @@ -223,6 +225,16 @@ function openAuthPopUp(url: string, popUp: Popup): Promise { popUp.close(); reject(new AuthenticatorError('ERR_AUTH_POPUP_CLOSED', 'Auth cancelled by client.')); }); + + popUp.onExpired(() => { + POPUP_STATE.open = false; + clearTimeout(authTimeout); + logMessage('warning', { + code: 'WARN_AUTH_EXPIRED', + message: 'Auth session expired.', + }); + reject(new AuthenticatorError('ERR_AUTH_EXPIRED', 'Auth session expired.')); + }); }); }