UNPKG

scrivito

Version:

Scrivito is a professional, yet easy to use SaaS Enterprise Content Management Service, built for digital agencies and medium to large businesses. It is completely maintenance-free, cost-effective, and has unprecedented performance and security.

90 lines (75 loc) 2.5 kB
import { AuthorizationProvider } from 'scrivito_sdk/client'; import { VisitorSession, cmsRestApi } from 'scrivito_sdk/client/cms_rest_api'; import { PublicAuthentication } from 'scrivito_sdk/client/public_authentication'; import { Deferred, ScrivitoError, randomId, throwNextTick, } from 'scrivito_sdk/common'; /** * The VisitorAuthenticationProvider is responsible to provide the visitor * session to authenticate backend requests for a Scrivito configured with * visitor authentication. * * The visitor session is retrieved from backend using the id token that * the provider has received. Backend requests are delayed until the first * session response arrives. * * Responses of visitor session authenticated backend requests are monitored * if they indicate an expired session, and retried either with a fresh * visitor session or without authentication. */ export class VisitorAuthenticationProvider implements AuthorizationProvider { private readonly sessionId = randomId(); private idToken = new Deferred<string>(); private sessionRequest: Promise<VisitorSession>; private state = 'waiting for token'; constructor() { this.sessionRequest = this.fetchSession(); } setToken(token: string) { if (!this.idToken.isPending()) { this.idToken = new Deferred(); this.renewSession(); } this.idToken.resolve(token); this.state = `active - token: ${token.substr(0, 3)}...`; } currentState(): string { return this.state; } async authorize( request: (authorization: string | undefined) => Promise<Response> ): Promise<Response> { const sessionRequest = this.sessionRequest; let session: VisitorSession; try { session = await sessionRequest; } catch { return PublicAuthentication.authorize(request); } const response = await request(`Session ${session.token}`); if (response.status === 401) { if (this.sessionRequest === sessionRequest) this.renewSession(); return this.authorize(request); } return response; } private renewSession() { this.sessionRequest = this.fetchSession(); } private async fetchSession() { try { const token = await this.idToken; return await cmsRestApi.requestVisitorSession(this.sessionId, token); } catch (error) { throwNextTick( new ScrivitoError( `Failed to establish visitor session: ${(error as Error).message}` ) ); throw error; } } }