@curity/identityserver-haapi-web-driver
Version:
Curity Identity Server HAAPI Web driver
2 lines • 9.09 kB
JavaScript
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.HaapiDriver=t():e.HaapiDriver=t()}(this,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{InitializationError:()=>r,TimeoutError:()=>n,createHaapiFetch:()=>R});class i{constructor(){this.promise=new Promise(((e,t)=>{this.resolve=e,this.reject=t}))}completeWith(e){if(!this.resolve||!this.reject)throw new Error("Deferred promise already used");const t=this.resolve,i=this.reject;this.resolve=this.reject=void 0,(()=>{var n,r,s,o;n=this,r=void 0,o=function*(){try{t(yield e())}catch(e){i(e)}},new((s=void 0)||(s=Promise))((function(e,t){function i(e){try{d(o.next(e))}catch(e){t(e)}}function a(e){try{d(o.throw(e))}catch(e){t(e)}}function d(t){var n;t.done?e(t.value):(n=t.value,n instanceof s?n:new s((function(e){e(n)}))).then(i,a)}d((o=o.apply(n,r||[])).next())}))})()}}class n extends Error{constructor(e){super(e),this.name="TimeoutError"}}class r extends Error{constructor(e){super(e.message),this.name="InitializationError"}}class s extends DOMException{constructor(){super("Cancelled","AbortError")}}var o=function(e,t,i,n){return new(i||(i=Promise))((function(r,s){function o(e){try{d(n.next(e))}catch(e){s(e)}}function a(e){try{d(n.throw(e))}catch(e){s(e)}}function d(e){var t;e.done?r(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,a)}d((n=n.apply(e,t||[])).next())}))};class a{get whenReady(){if(this.ready instanceof Promise)return this.ready;throw new Error("Called whenReady() but setup is not ongoing")}get pendingResponsesCount(){return this.pendingResponses.size}constructor(e,t,i){this.iframeFactory=e,this.timeout=t,this.logger=i,this.handleProtocolMessage=()=>{},this.pendingReload=void 0,this.pendingResponses=new Map,this.ready=this.setup(),this.iframe=this.createIframeMessenger(),this.configuration=e.configuration}fetch(e,t,i){return o(this,void 0,void 0,(function*(){return yield this.ensureReady(),yield this.sendReceive("api-request",{href:e,init:t()},"api-response",i)}))}init(){return this.ensureReady()}dispose(){this.iframe.dispose(),this.pendingResponses.forEach((e=>e.cancel())),this.ready=()=>Promise.reject(new Error("Already disposed"))}createIframeMessenger(){return this.iframeFactory.create((e=>{this.logger.debug("Received message",e),this.handleProtocolMessage(e)}))}ensureReady(){return this.ready instanceof Function&&(this.ready=this.ready()),this.ready}setup(){return o(this,void 0,void 0,(function*(){const e=new Date;try{yield new Promise(((e,t)=>{const i=new d("loaded",(()=>{this.handleProtocolMessage=e=>this.handlePendingResponse(e),e()}),(e=>{this.handleProtocolMessage=()=>this.logger.error("Previous setup has failed",e),t(e)}),this.timeout,null,this.logger);this.handleProtocolMessage=e=>i.handle(e)}));const t=new Date;this.logger.debug("Loading took %s ms",t.getTime()-e.getTime()),yield this.sendReceive("setup",{startedLoadingAt:e,finishedLoadingAt:t,timeout:this.timeout,deviceIdentifier:this.configuration.deviceIdentifier},"ready",null),this.logger.debug("Setup took %s ms",Date.now()-t.getTime())}catch(e){if(e instanceof s)throw e;throw this.iframe.dispose(),this.ready=()=>{const e=this.setup();return this.iframe=this.createIframeMessenger(),e},new r(e)}}))}reload(){return o(this,void 0,void 0,(function*(){this.logger.debug("Reloading CAT iframe"),this.send("reload"),yield this.setup()}))}tryReload(){0===this.pendingResponses.size?this.ready=this.reload():(this.logger.debug("Delaying reload because there are pending responses"),this.pendingReload=new i,this.ready=this.pendingReload.promise)}tryScheduledReload(){this.pendingReload&&0===this.pendingResponses.size&&(this.pendingReload.completeWith((()=>this.reload())),this.pendingReload=void 0)}handlePendingResponse(e){if("reload"===e.type)return this.tryReload();if(e.traceId){const t=this.pendingResponses.get(e.traceId);if(t)return t.handle(e)}this.logger.debug("Received outdated message",e)}send(e,t,i){const n={type:e,data:t,traceId:i};this.logger.debug("Sending message",n),this.iframe.send(n)}sendReceive(e,t,i,n){const r=Math.random();return this.send(e,t,r),new Promise(((e,t)=>{var o;const a=()=>{this.pendingResponses.delete(r),this.tryScheduledReload()},c=e=>{a(),t(e)};(null==n?void 0:n.aborted)&&c(null!==(o=n.reason)&&void 0!==o?o:new s);const h=new d(i,(t=>{a(),e(t)}),c,this.timeout,n,this.logger);this.pendingResponses.set(r,h)}))}}class d{constructor(e,t,i,r,o,a){this.type=e,this.success=t,this.error=i,this.logger=a;const d=setTimeout((()=>{this.cleanup(),this.error(new n(`Timeout while waiting for message '${e}'`))}),r),c=()=>{var t;this.cleanup(),this.logger.debug(`Cancelled while waiting for message of type '${e}'`),this.error(null!==(t=null==o?void 0:o.reason)&&void 0!==t?t:new s)};null==o||o.addEventListener("abort",c),this.cleanup=()=>{clearTimeout(d),null==o||o.removeEventListener("abort",c)}}handle(e){this.cleanup(),"error"===e.type?this.error(new Error(e.data.toString())):e.type!==this.type?(this.logger.error(`Expected message with type '${this.type}' but received '${e.type}'`,e),this.error(new Error("Received message with unexpected type"))):this.success(e.data)}cancel(){this.cleanup(),this.error(new s)}}class c{constructor(e,t){this.configuration=e,this.logger=t}create(e){return new h(this.configuration,e,this.logger)}}class h{constructor(e,t,i){this.logger=i,this.iframeSource=new URL("cat",function(e){const t=new URL(e);return t.pathname.endsWith("/")||(t.pathname+="/"),t}(e.tokenEndpoint)),this.iframeSource.searchParams.append("client_id",e.clientId),this.iframe=window.document.createElement("iframe"),this.iframe.src=this.iframeSource.href,this.iframe.style.display="none",this.iframe.id=Math.random().toString(),this.logger.debug("Initializing CAT iframe %s",this.iframe.id),this.eventHandler=e=>this.handleMessageEvent(e,t),window.addEventListener("message",this.eventHandler),document.body.append(this.iframe)}dispose(){this.logger.debug("Removing CAT iframe %s",this.iframe.id),window.removeEventListener("message",this.eventHandler),this.iframe.remove()}send(e){if(!this.iframe.parentElement)throw new Error("Already disposed");this.iframe.contentWindow.postMessage(e,this.iframeSource.origin)}handleMessageEvent(e,t){e.source===this.iframe.contentWindow?e.origin===this.iframeSource.origin?"object"==typeof e.data&&"string"==typeof e.data.type?t(e.data):this.logger.error("Received malformed message",e.data):this.logger.error("Received message from unexpected origin",e.origin):this.logger.debug("Received message from unexpected source",e.source)}}function l(e){throw new Error(`config: missing or invalid ${e}`)}const u=2,g=128;function f(e){if(void 0===e)return e;if(e.length<u)throw new Error(`deviceIdentifier length below required minimum of '${u}'`);if(e.length>g)throw new Error(`deviceIdentifier length above required maximum of '${g}'`);return e}function p(e){const t={};for(var i of e)t[i[0]]=i[1];return t}const m={debug:console.log,error:console.error},y={debug:()=>{},error:()=>{}},v=e=>e["se:curity:web-cat:debug"]?m:y;var w=function(e,t,i,n){return new(i||(i=Promise))((function(r,s){function o(e){try{d(n.next(e))}catch(e){s(e)}}function a(e){try{d(n.throw(e))}catch(e){s(e)}}function d(e){var t;e.done?r(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,a)}d((n=n.apply(e,t||[])).next())}))};let b=null;function R(e){const t=v(window),i=function(e){return e.clientId||l("clientId"),e.tokenEndpoint||l("tokenEndpoint"),Object.assign(Object.assign({},e),{baseUrl:e.baseUrl||new URL(e.tokenEndpoint).origin,timeout:e.timeout||5,deviceIdentifier:f(e.deviceIdentifier)})}(e);b&&(b.dispose(),b=null);const n=new a(new c(i,t),1e3*i.timeout,t);let r=null;const s=(e,s)=>w(this,void 0,void 0,(function*(){s=s||{};const o=new URL(e,i.baseUrl),a=s.method||"GET",d=s.credentials||"same-origin",c=new Headers(s.headers);let h;c.set("Accept","application/vnd.auth+json"),s.body&&(h=function(e){if(e instanceof URLSearchParams||"string"==typeof e)return e;if("object"==typeof e){const t=new URLSearchParams;return Object.entries(e).forEach((e=>t.append(e[0],e[1]))),t}throw new Error("Unsupported body type")}(s.body),h instanceof URLSearchParams&&c.set("Content-Type","application/x-www-form-urlencoded"));const l=yield n.fetch(o.href,(()=>function(e,t,i,n){return r&&t.set("Session-Id",r),{method:e,headers:p(t),body:null==i?void 0:i.toString(),credentials:n}}(a,c,h,d)),s.signal),u=new Response(l.body,l.init),g=u.headers.get("Set-Session-Id");return g&&(t.debug(`Setting session ID to ${g}`),r=g),u}));return s.init=()=>w(this,void 0,void 0,(function*(){return yield n.init(),s})),s.close=()=>{n.dispose()},b=n,s}return t})()));
//# sourceMappingURL=index.js.map