UNPKG

oidc-client-rx

Version:

ReactiveX enhanced OIDC and OAuth2 protocol support for browser-based JavaScript applications

128 lines (127 loc) 5.62 kB
import { Injectable, inject } from "injection-js"; import { Subject } from "rxjs"; import { DOCUMENT } from "../../dom/index.js"; import { LoggerService } from "../../logging/logger.service.js"; import { StoragePersistenceService } from "../../storage/storage-persistence.service.js"; function _ts_decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc); else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } class PopUpService { get result$() { return this.resultInternal$.asObservable(); } get windowInternal() { return this.document.defaultView; } isCurrentlyInPopup(config) { if (this.canAccessSessionStorage()) { const popup = this.storagePersistenceService.read(this.STORAGE_IDENTIFIER, config); const windowIdentifier = this.windowInternal; if (!windowIdentifier) return false; return Boolean(windowIdentifier.opener) && windowIdentifier.opener !== windowIdentifier && Boolean(popup); } return false; } openPopUp(url, popupOptions, config) { const optionsToPass = this.getOptions(popupOptions); this.storagePersistenceService.write(this.STORAGE_IDENTIFIER, "true", config); const windowIdentifier = this.windowInternal; if (!windowIdentifier) return; if (!url) return void this.loggerService.logError(config, "Could not open popup, url is empty"); this.popUp = windowIdentifier.open(url, "_blank", optionsToPass); if (!this.popUp) { this.storagePersistenceService.remove(this.STORAGE_IDENTIFIER, config); this.loggerService.logError(config, "Could not open popup"); return; } this.loggerService.logDebug(config, `Opened popup with url ${url}`); const listener = (event)=>{ if (!event?.data || "string" != typeof event.data) { if (config.disableCleaningPopupOnInvalidMessage) return; this.cleanUp(listener, config); return; } this.loggerService.logDebug(config, `Received message from popup with url ${event.data}`); this.resultInternal$.next({ userClosed: false, receivedUrl: event.data }); this.cleanUp(listener, config); }; windowIdentifier.addEventListener("message", listener, false); this.handle = windowIdentifier.setInterval(()=>{ if (this.popUp?.closed) { this.resultInternal$.next({ userClosed: true, receivedUrl: "" }); this.cleanUp(listener, config); } }, 200); } sendMessageToMainWindow(url, config) { const windowIdentifier = this.windowInternal; if (!windowIdentifier) return; if (windowIdentifier.opener) { const href = windowIdentifier.location.href; this.sendMessage(url, href, config); } } cleanUp(listener, config) { const windowIdentifier = this.windowInternal; if (!windowIdentifier) return; windowIdentifier.removeEventListener("message", listener, false); windowIdentifier.clearInterval(this.handle); if (this.popUp) { this.storagePersistenceService.remove(this.STORAGE_IDENTIFIER, config); this.popUp.close(); this.popUp = null; } } sendMessage(url, href, config) { const windowIdentifier = this.windowInternal; if (!windowIdentifier) return; if (!url) return void this.loggerService.logDebug(config, `Can not send message to parent, no url: '${url}'`); windowIdentifier.opener.postMessage(url, href); } getOptions(popupOptions) { const popupDefaultOptions = { width: 500, height: 500, left: 50, top: 50 }; const options = { ...popupDefaultOptions, ...popupOptions || {} }; const windowIdentifier = this.windowInternal; if (!windowIdentifier) return ""; const width = options.width || popupDefaultOptions.width; const height = options.height || popupDefaultOptions.height; const left = windowIdentifier.screenLeft + (windowIdentifier.outerWidth - width) / 2; const top = windowIdentifier.screenTop + (windowIdentifier.outerHeight - height) / 2; options.left = left; options.top = top; return Object.entries(options).map(([key, value])=>`${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join(","); } canAccessSessionStorage() { return "u" > typeof navigator && navigator.cookieEnabled && "u" > typeof Storage; } constructor(){ this.loggerService = inject(LoggerService); this.storagePersistenceService = inject(StoragePersistenceService); this.document = inject(DOCUMENT); this.STORAGE_IDENTIFIER = "popupauth"; this.popUp = null; this.handle = -1; this.resultInternal$ = new Subject(); } } PopUpService = _ts_decorate([ Injectable() ], PopUpService); export { PopUpService };