@velion-la/onboarding-sdk-web 1.0.0-beta.21 → 1.0.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/velion-sdk.es.js +1 -1
- package/dist/velion-sdk.umd.js +1 -1
- package/package.json +1 -1
package/dist/velion-sdk.es.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=/* @__PURE__ */(e=>(e.PERMISSION_DENIED="CAMERA_PERMISSION_DENIED",e.DEVICE_NOT_FOUND="CAMERA_DEVICE_NOT_FOUND",e.DEVICE_NOT_READABLE="CAMERA_DEVICE_NOT_READABLE",e.INSECURE_CONTEXT="CAMERA_INSECURE_CONTEXT",e.POLICY_BLOCKED="CAMERA_POLICY_BLOCKED",e.NOT_SUPPORTED="CAMERA_NOT_SUPPORTED",e.WEBVIEW_BLOCKED="CAMERA_WEBVIEW_BLOCKED",e.CONSTRAINT_ERROR="CAMERA_CONSTRAINT_ERROR",e.UNKNOWN="CAMERA_UNKNOWN_ERROR",e))(e||{}),t=/* @__PURE__ */(e=>(e.SESSION_INVALID="SESSION_INVALID",e.SESSION_EXPIRED="SESSION_EXPIRED",e.SESSION_FETCH_FAILED="SESSION_FETCH_FAILED",e.SESSION_DECLINED="SESSION_DECLINED",e.FINGERPRINT_FAILED="FINGERPRINT_FAILED",e.DOCUMENT_UPLOAD_FAILED="DOCUMENT_UPLOAD_FAILED",e.LIVENESS_FAILED="LIVENESS_FAILED",e.LIVENESS_INIT_FAILED="LIVENESS_INIT_FAILED",e.LIVENESS_VIDEO_UPLOAD_FAILED="LIVENESS_VIDEO_UPLOAD_FAILED",e.CAMERA_ERROR="CAMERA_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.API_ERROR="API_ERROR",e.CONTAINER_NOT_FOUND="CONTAINER_NOT_FOUND",e.ALREADY_STARTED="ALREADY_STARTED",e.INSTANCE_DESTROYED="INSTANCE_DESTROYED",e.INSECURE_EMBED="INSECURE_EMBED",e.INTEGRITY_FAILED="INTEGRITY_FAILED",e.RUNTIME_LOAD_FAILED="RUNTIME_LOAD_FAILED",e.UNKNOWN="UNKNOWN",e))(t||{});const i="VELION_INIT",n="VELION_READY",s="VELION_SUCCESS",r="VELION_ERROR",a="VELION_STEP_CHANGE",o="VELION_STEP_COMPLETE",c="VELION_TOKEN_EXPIRED",E="VELION_EXIT",l="VELION_LIVENESS_VIDEO_UPLOADED",d="VELION_TOKEN",h="lpqLG4Ta0YyBn/+lQh95tFl4CuTIHWapeeq7+xnPH+U=";function I(e){const t=atob(e),i=new ArrayBuffer(t.length),n=new Uint8Array(i);for(let s=0;s<t.length;s++)n[s]=t.charCodeAt(s);return i}async function u(e,t=h){let i,n,s,r,a,o;try{const t=await fetch(`${e}/manifest.json`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(404===t.status)return{ok:!1,reason:"unavailable"};if(!t.ok)return{ok:!1,reason:"unavailable",detail:`HTTP ${t.status}`};i=await t.arrayBuffer(),n=(new TextDecoder).decode(i)}catch(c){return{ok:!1,reason:"unavailable",detail:c.message}}try{if(s=JSON.parse(n),"string"!=typeof s.version||"string"!=typeof s.entry||"string"!=typeof s.buildTime)return{ok:!1,reason:"malformed"}}catch(c){return{ok:!1,reason:"malformed",detail:c.message}}if(!t)return{ok:!0,manifest:s,signed:!1};try{const t=await fetch(`${e}/manifest.sig`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(!t.ok)return{ok:!1,reason:"invalid_signature",detail:`sig HTTP ${t.status}`};r=I((await t.text()).trim())}catch(c){return{ok:!1,reason:"invalid_signature",detail:c.message}}try{a=await async function(e){const t=I(e);return crypto.subtle.importKey("raw",t,{name:"Ed25519"},!1,["verify"])}(t)}catch(c){return{ok:!1,reason:"invalid_signature",detail:`pubkey import failed: ${c.message}`}}try{o=await async function(e,t,i){return crypto.subtle.verify({name:"Ed25519"},e,t,i)}(a,r,i)}catch(c){return{ok:!1,reason:"invalid_signature",detail:c.message}}return o?{ok:!0,manifest:s,signed:!0}:{ok:!1,reason:"invalid_signature"}}const f="https://static.velion.la/sdk/onboarding/v1";function R(e){try{const i=new URL(e);return"https:"===i.protocol||"http:"===i.protocol&&("localhost"===(t=i.hostname)||"127.0.0.1"===t||"::1"===t||t.endsWith(".local"))}catch{return!1}var t}const N=["containerId","sessionId","sessionToken","apiUrl","expiresAt","theme","colorMode","locale","allowEmbedded","livenessShowIntro","livenessShowBackButton","fingerprintEndpoint","debug","googleMapsApiKey","showFinalResultScreen","showProgressBar","finalResultScreenTexts"];class m{constructor(e){this.status="IDLE",this.iframe=null,this.container=null,this.messageHandler=null,this.containerResizeObserver=null,this.iframeHeightWindowResizeHandler=null,this.cdnOrigin="",this.readyTimer=null,this.config=Object.freeze({...e})}clearReadyTimer(){null!==this.readyTimer&&(clearTimeout(this.readyTimer),this.readyTimer=null)}armReadyTimer(e){this.clearReadyTimer();const i=this.config.runtimeReadyTimeoutMs??3e4;i>0&&(this.readyTimer=setTimeout(()=>{this.readyTimer=null,"RUNNING"===this.status&&(this.status="ERROR",this.config.onError?.({code:t.RUNTIME_LOAD_FAILED,message:`The onboarding runtime at ${e} did not become ready within ${i} ms. Check that the CDN serves the assets referenced by its index.html and that the host page's Content-Security-Policy allows the runtime scripts.`}))},i))}async start(){if("DESTROYED"===this.status)return void this.config.onError?.({code:t.INSTANCE_DESTROYED,message:"This VelionOnboarding instance has been destroyed. Create a new instance to retry."});if("IDLE"!==this.status)return void this.config.onError?.({code:t.ALREADY_STARTED,message:"start() was called on an already-running SDK instance. Call destroy() before re-starting."});const e=document.getElementById(this.config.containerId);if(!e)return void this.config.onError?.({code:t.CONTAINER_NOT_FOUND,message:`No DOM element found with id="${this.config.containerId}". Ensure the element exists before calling start().`});const h=(this.config.cdnUrl??f).replace(/\/$/,"");if(!R(h))return void this.config.onError?.({code:t.UNKNOWN,message:`Insecure cdnUrl: "${h}". Must be https:// (http:// is allowed only for localhost).`});if(this.config.apiUrl&&!R(this.config.apiUrl))return void this.config.onError?.({code:t.UNKNOWN,message:`Insecure apiUrl: "${this.config.apiUrl}". Must be https:// (http:// is allowed only for localhost).`});if(this.cdnOrigin=function(e){try{return new URL(e).origin}catch{return""}}(h),!this.cdnOrigin)return void this.config.onError?.({code:t.UNKNOWN,message:`Invalid cdnUrl: ${h}. Must be a valid absolute URL.`});this.container=e,this.status="INITIALIZING";const I=document.createElement("iframe");I.setAttribute("title","Velion Onboarding"),I.setAttribute("allow","camera"),I.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-modals"),I.setAttribute("referrerpolicy","no-referrer"),I.style.width="100%",I.style.border="none",I.style.display="block";const u=e=>{if(e.origin!==this.cdnOrigin)return;if(e.source!==this.iframe?.contentWindow)return;const i=e.data;if(i&&"string"==typeof i.type)switch(i.type){case n:this.clearReadyTimer(),this.status="RUNNING";break;case s:this.status="COMPLETED",this.config.onSuccess?.(i.payload);break;case r:this.status="ERROR",this.config.onError?.(i.payload);break;case a:{const e=i.payload;this.config.onStepChange?.(e.step,e.stepIndex);break}case o:{const e=i.payload;this.config.onStepComplete?.(e.step);break}case E:this.status="EXITED",this.config.onExit?.(i.payload);break;case l:this.config.onLivenessVideoUploaded?.(i.payload);break;case c:{const e=this.config.onTokenExpired;e?e().then(e=>this.sendToIframe({type:d,payload:e}),()=>{this.config.onError?.({code:t.SESSION_EXPIRED,message:"Token refresh failed."})}):this.config.onError?.({code:t.SESSION_EXPIRED,message:"Session token expired. Provide onTokenExpired in config to refresh."});break}}};window.addEventListener("message",u),this.messageHandler=u,this.iframe=I,e.replaceChildren(I),this.attachIframeHeightSync(e,I);const m=await this.resolveManifest(h);if(!m)return;const g=m.entry.startsWith("/")?m.entry:`/${m.entry}`;return new Promise(e=>{I.onload=()=>{if(!this.iframe?.contentWindow)return this.status="ERROR",this.config.onError?.({code:t.UNKNOWN,message:"Iframe failed to load."}),void e();const n=function(e){const t={containerId:"velion-sdk-root",allowEmbedded:!0};for(const i of N){if("containerId"===i||"allowEmbedded"===i)continue;const n=e[i];void 0!==n&&"function"!=typeof n&&(t[i]=n)}return t}(this.config);let s;try{s=JSON.parse(JSON.stringify(n))}catch{s=n}this.sendToIframe({type:i,payload:s}),this.status="RUNNING",this.armReadyTimer(h),e()},I.onerror=()=>{this.status="ERROR",this.config.onError?.({code:t.UNKNOWN,message:`Failed to load onboarding app from ${h}. Check cdnUrl and network.`}),e()},I.src=`${h}${g}`})}async resolveManifest(e){let i;try{i=await u(e)}catch(n){return this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:`Manifest verification crashed unexpectedly: ${n.message}`}),null}if(i.ok)return!i.signed&&h?(this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:"Internal: manifest reported as unsigned despite pubkey being set."}),null):i.manifest;if("unavailable"===i.reason){return!0!==this.config.allowUnverifiedCdn?(this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:`CDN at "${e}" did not expose /manifest.json. The loader is configured to require a signed manifest. If the CDN is migrating, set \`allowUnverifiedCdn: true\` on the loader config — but only as a temporary measure.`}),null):{version:"legacy",buildTime:/* @__PURE__ */(new Date).toISOString(),entry:"/index.html"}}return this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:`CDN manifest at "${e}/manifest.json" failed integrity check (${i.reason}). Refusing to load the iframe to protect the user. `+("detail"in i&&i.detail?`Detail: ${i.detail}`:"")}),null}attachIframeHeightSync(e,t){const i=()=>{if(this.iframe!==t||this.container!==e)return;const i=e.clientHeight;i>0?(t.style.height=`${i}px`,t.style.minHeight=""):(t.style.height="min(85vh, 880px)",t.style.minHeight="")};i(),requestAnimationFrame(i),requestAnimationFrame(()=>{requestAnimationFrame(i)}),"undefined"!=typeof ResizeObserver?(this.containerResizeObserver=new ResizeObserver(i),this.containerResizeObserver.observe(e)):(this.iframeHeightWindowResizeHandler=i,window.addEventListener("resize",i))}detachIframeHeightSync(){this.containerResizeObserver&&(this.containerResizeObserver.disconnect(),this.containerResizeObserver=null),this.iframeHeightWindowResizeHandler&&(window.removeEventListener("resize",this.iframeHeightWindowResizeHandler),this.iframeHeightWindowResizeHandler=null)}sendToIframe(e){this.iframe?.contentWindow&&this.iframe.contentWindow.postMessage(e,this.cdnOrigin)}getStatus(){return this.status}static getVersion(){return"1.0.0-beta.21"}destroy(){"DESTROYED"!==this.status&&(this.clearReadyTimer(),this.detachIframeHeightSync(),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.iframe&&this.container&&(this.iframe.remove(),this.container.replaceChildren()),this.iframe=null,this.container=null,this.status="DESTROYED")}}function g(e){}export{e as CameraErrorCode,f as DEFAULT_CDN_URL,t as SdkErrorCode,r as VELION_MSG_ERROR,E as VELION_MSG_EXIT,i as VELION_MSG_INIT,l as VELION_MSG_LIVENESS_VIDEO_UPLOADED,n as VELION_MSG_READY,a as VELION_MSG_STEP_CHANGE,o as VELION_MSG_STEP_COMPLETE,s as VELION_MSG_SUCCESS,d as VELION_MSG_TOKEN,c as VELION_MSG_TOKEN_EXPIRED,m as VelionOnboarding,g as setOpenCVBaseUrl};
|
|
1
|
+
var e=/* @__PURE__ */(e=>(e.PERMISSION_DENIED="CAMERA_PERMISSION_DENIED",e.DEVICE_NOT_FOUND="CAMERA_DEVICE_NOT_FOUND",e.DEVICE_NOT_READABLE="CAMERA_DEVICE_NOT_READABLE",e.INSECURE_CONTEXT="CAMERA_INSECURE_CONTEXT",e.POLICY_BLOCKED="CAMERA_POLICY_BLOCKED",e.NOT_SUPPORTED="CAMERA_NOT_SUPPORTED",e.WEBVIEW_BLOCKED="CAMERA_WEBVIEW_BLOCKED",e.CONSTRAINT_ERROR="CAMERA_CONSTRAINT_ERROR",e.UNKNOWN="CAMERA_UNKNOWN_ERROR",e))(e||{}),t=/* @__PURE__ */(e=>(e.SESSION_INVALID="SESSION_INVALID",e.SESSION_EXPIRED="SESSION_EXPIRED",e.SESSION_FETCH_FAILED="SESSION_FETCH_FAILED",e.SESSION_DECLINED="SESSION_DECLINED",e.FINGERPRINT_FAILED="FINGERPRINT_FAILED",e.DOCUMENT_UPLOAD_FAILED="DOCUMENT_UPLOAD_FAILED",e.LIVENESS_FAILED="LIVENESS_FAILED",e.LIVENESS_INIT_FAILED="LIVENESS_INIT_FAILED",e.LIVENESS_VIDEO_UPLOAD_FAILED="LIVENESS_VIDEO_UPLOAD_FAILED",e.CAMERA_ERROR="CAMERA_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.API_ERROR="API_ERROR",e.CONTAINER_NOT_FOUND="CONTAINER_NOT_FOUND",e.ALREADY_STARTED="ALREADY_STARTED",e.INSTANCE_DESTROYED="INSTANCE_DESTROYED",e.INSECURE_EMBED="INSECURE_EMBED",e.INTEGRITY_FAILED="INTEGRITY_FAILED",e.RUNTIME_LOAD_FAILED="RUNTIME_LOAD_FAILED",e.UNKNOWN="UNKNOWN",e))(t||{});const i="VELION_INIT",n="VELION_READY",s="VELION_SUCCESS",r="VELION_ERROR",a="VELION_STEP_CHANGE",o="VELION_STEP_COMPLETE",c="VELION_TOKEN_EXPIRED",E="VELION_EXIT",l="VELION_LIVENESS_VIDEO_UPLOADED",d="VELION_TOKEN",h="lpqLG4Ta0YyBn/+lQh95tFl4CuTIHWapeeq7+xnPH+U=";function I(e){const t=atob(e),i=new ArrayBuffer(t.length),n=new Uint8Array(i);for(let s=0;s<t.length;s++)n[s]=t.charCodeAt(s);return i}async function u(e,t=h){let i,n,s,r,a,o;try{const t=await fetch(`${e}/manifest.json`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(404===t.status)return{ok:!1,reason:"unavailable"};if(!t.ok)return{ok:!1,reason:"unavailable",detail:`HTTP ${t.status}`};i=await t.arrayBuffer(),n=(new TextDecoder).decode(i)}catch(c){return{ok:!1,reason:"unavailable",detail:c.message}}try{if(s=JSON.parse(n),"string"!=typeof s.version||"string"!=typeof s.entry||"string"!=typeof s.buildTime)return{ok:!1,reason:"malformed"}}catch(c){return{ok:!1,reason:"malformed",detail:c.message}}if(!t)return{ok:!0,manifest:s,signed:!1};try{const t=await fetch(`${e}/manifest.sig`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(!t.ok)return{ok:!1,reason:"invalid_signature",detail:`sig HTTP ${t.status}`};r=I((await t.text()).trim())}catch(c){return{ok:!1,reason:"invalid_signature",detail:c.message}}try{a=await async function(e){const t=I(e);return crypto.subtle.importKey("raw",t,{name:"Ed25519"},!1,["verify"])}(t)}catch(c){return{ok:!1,reason:"invalid_signature",detail:`pubkey import failed: ${c.message}`}}try{o=await async function(e,t,i){return crypto.subtle.verify({name:"Ed25519"},e,t,i)}(a,r,i)}catch(c){return{ok:!1,reason:"invalid_signature",detail:c.message}}return o?{ok:!0,manifest:s,signed:!0}:{ok:!1,reason:"invalid_signature"}}const f="https://static.velion.la/sdk/onboarding/v1";function R(e){try{const i=new URL(e);return"https:"===i.protocol||"http:"===i.protocol&&("localhost"===(t=i.hostname)||"127.0.0.1"===t||"::1"===t||t.endsWith(".local"))}catch{return!1}var t}const N=["containerId","sessionId","sessionToken","apiUrl","expiresAt","theme","colorMode","locale","allowEmbedded","livenessShowIntro","livenessShowBackButton","fingerprintEndpoint","debug","googleMapsApiKey","showFinalResultScreen","showProgressBar","finalResultScreenTexts"];class m{constructor(e){this.status="IDLE",this.iframe=null,this.container=null,this.messageHandler=null,this.containerResizeObserver=null,this.iframeHeightWindowResizeHandler=null,this.cdnOrigin="",this.readyTimer=null,this.config=Object.freeze({...e})}clearReadyTimer(){null!==this.readyTimer&&(clearTimeout(this.readyTimer),this.readyTimer=null)}armReadyTimer(e){this.clearReadyTimer();const i=this.config.runtimeReadyTimeoutMs??3e4;i>0&&(this.readyTimer=setTimeout(()=>{this.readyTimer=null,"RUNNING"===this.status&&(this.status="ERROR",this.config.onError?.({code:t.RUNTIME_LOAD_FAILED,message:`The onboarding runtime at ${e} did not become ready within ${i} ms. Check that the CDN serves the assets referenced by its index.html and that the host page's Content-Security-Policy allows the runtime scripts.`}))},i))}async start(){if("DESTROYED"===this.status)return void this.config.onError?.({code:t.INSTANCE_DESTROYED,message:"This VelionOnboarding instance has been destroyed. Create a new instance to retry."});if("IDLE"!==this.status)return void this.config.onError?.({code:t.ALREADY_STARTED,message:"start() was called on an already-running SDK instance. Call destroy() before re-starting."});const e=document.getElementById(this.config.containerId);if(!e)return void this.config.onError?.({code:t.CONTAINER_NOT_FOUND,message:`No DOM element found with id="${this.config.containerId}". Ensure the element exists before calling start().`});const h=(this.config.cdnUrl??f).replace(/\/$/,"");if(!R(h))return void this.config.onError?.({code:t.UNKNOWN,message:`Insecure cdnUrl: "${h}". Must be https:// (http:// is allowed only for localhost).`});if(this.config.apiUrl&&!R(this.config.apiUrl))return void this.config.onError?.({code:t.UNKNOWN,message:`Insecure apiUrl: "${this.config.apiUrl}". Must be https:// (http:// is allowed only for localhost).`});if(this.cdnOrigin=function(e){try{return new URL(e).origin}catch{return""}}(h),!this.cdnOrigin)return void this.config.onError?.({code:t.UNKNOWN,message:`Invalid cdnUrl: ${h}. Must be a valid absolute URL.`});this.container=e,this.status="INITIALIZING";const I=document.createElement("iframe");I.setAttribute("title","Velion Onboarding"),I.setAttribute("allow","camera"),I.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-modals"),I.setAttribute("referrerpolicy","no-referrer"),I.style.width="100%",I.style.border="none",I.style.display="block";const u=e=>{if(e.origin!==this.cdnOrigin)return;if(e.source!==this.iframe?.contentWindow)return;const i=e.data;if(i&&"string"==typeof i.type)switch(i.type){case n:this.clearReadyTimer(),this.status="RUNNING";break;case s:this.status="COMPLETED",this.config.onSuccess?.(i.payload);break;case r:this.status="ERROR",this.config.onError?.(i.payload);break;case a:{const e=i.payload;this.config.onStepChange?.(e.step,e.stepIndex);break}case o:{const e=i.payload;this.config.onStepComplete?.(e.step);break}case E:this.status="EXITED",this.config.onExit?.(i.payload);break;case l:this.config.onLivenessVideoUploaded?.(i.payload);break;case c:{const e=this.config.onTokenExpired;e?e().then(e=>this.sendToIframe({type:d,payload:e}),()=>{this.config.onError?.({code:t.SESSION_EXPIRED,message:"Token refresh failed."})}):this.config.onError?.({code:t.SESSION_EXPIRED,message:"Session token expired. Provide onTokenExpired in config to refresh."});break}}};window.addEventListener("message",u),this.messageHandler=u,this.iframe=I,e.replaceChildren(I),this.attachIframeHeightSync(e,I);const m=await this.resolveManifest(h);if(!m)return;const g=m.entry.startsWith("/")?m.entry:`/${m.entry}`;return new Promise(e=>{I.onload=()=>{if(!this.iframe?.contentWindow)return this.status="ERROR",this.config.onError?.({code:t.UNKNOWN,message:"Iframe failed to load."}),void e();const n=function(e){const t={containerId:"velion-sdk-root",allowEmbedded:!0};for(const i of N){if("containerId"===i||"allowEmbedded"===i)continue;const n=e[i];void 0!==n&&"function"!=typeof n&&(t[i]=n)}return t}(this.config);let s;try{s=JSON.parse(JSON.stringify(n))}catch{s=n}this.sendToIframe({type:i,payload:s}),this.status="RUNNING",this.armReadyTimer(h),e()},I.onerror=()=>{this.status="ERROR",this.config.onError?.({code:t.UNKNOWN,message:`Failed to load onboarding app from ${h}. Check cdnUrl and network.`}),e()},I.src=`${h}${g}`})}async resolveManifest(e){let i;try{i=await u(e)}catch(n){return this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:`Manifest verification crashed unexpectedly: ${n.message}`}),null}if(i.ok)return!i.signed&&h?(this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:"Internal: manifest reported as unsigned despite pubkey being set."}),null):i.manifest;if("unavailable"===i.reason){return!0!==this.config.allowUnverifiedCdn?(this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:`CDN at "${e}" did not expose /manifest.json. The loader is configured to require a signed manifest. If the CDN is migrating, set \`allowUnverifiedCdn: true\` on the loader config — but only as a temporary measure.`}),null):{version:"legacy",buildTime:/* @__PURE__ */(new Date).toISOString(),entry:"/index.html"}}return this.status="ERROR",this.config.onError?.({code:t.INTEGRITY_FAILED,message:`CDN manifest at "${e}/manifest.json" failed integrity check (${i.reason}). Refusing to load the iframe to protect the user. `+("detail"in i&&i.detail?`Detail: ${i.detail}`:"")}),null}attachIframeHeightSync(e,t){const i=()=>{if(this.iframe!==t||this.container!==e)return;const i=e.clientHeight;i>0?(t.style.height=`${i}px`,t.style.minHeight=""):(t.style.height="min(85vh, 880px)",t.style.minHeight="")};i(),requestAnimationFrame(i),requestAnimationFrame(()=>{requestAnimationFrame(i)}),"undefined"!=typeof ResizeObserver?(this.containerResizeObserver=new ResizeObserver(i),this.containerResizeObserver.observe(e)):(this.iframeHeightWindowResizeHandler=i,window.addEventListener("resize",i))}detachIframeHeightSync(){this.containerResizeObserver&&(this.containerResizeObserver.disconnect(),this.containerResizeObserver=null),this.iframeHeightWindowResizeHandler&&(window.removeEventListener("resize",this.iframeHeightWindowResizeHandler),this.iframeHeightWindowResizeHandler=null)}sendToIframe(e){this.iframe?.contentWindow&&this.iframe.contentWindow.postMessage(e,this.cdnOrigin)}getStatus(){return this.status}static getVersion(){return"1.0.0-beta.23"}destroy(){"DESTROYED"!==this.status&&(this.clearReadyTimer(),this.detachIframeHeightSync(),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.iframe&&this.container&&(this.iframe.remove(),this.container.replaceChildren()),this.iframe=null,this.container=null,this.status="DESTROYED")}}function g(e){}export{e as CameraErrorCode,f as DEFAULT_CDN_URL,t as SdkErrorCode,r as VELION_MSG_ERROR,E as VELION_MSG_EXIT,i as VELION_MSG_INIT,l as VELION_MSG_LIVENESS_VIDEO_UPLOADED,n as VELION_MSG_READY,a as VELION_MSG_STEP_CHANGE,o as VELION_MSG_STEP_COMPLETE,s as VELION_MSG_SUCCESS,d as VELION_MSG_TOKEN,c as VELION_MSG_TOKEN_EXPIRED,m as VelionOnboarding,g as setOpenCVBaseUrl};
|
|
2
2
|
//# sourceMappingURL=velion-sdk.es.js.map
|
package/dist/velion-sdk.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VelionSDK={})}(this,function(e){"use strict";var t=(e=>(e.PERMISSION_DENIED="CAMERA_PERMISSION_DENIED",e.DEVICE_NOT_FOUND="CAMERA_DEVICE_NOT_FOUND",e.DEVICE_NOT_READABLE="CAMERA_DEVICE_NOT_READABLE",e.INSECURE_CONTEXT="CAMERA_INSECURE_CONTEXT",e.POLICY_BLOCKED="CAMERA_POLICY_BLOCKED",e.NOT_SUPPORTED="CAMERA_NOT_SUPPORTED",e.WEBVIEW_BLOCKED="CAMERA_WEBVIEW_BLOCKED",e.CONSTRAINT_ERROR="CAMERA_CONSTRAINT_ERROR",e.UNKNOWN="CAMERA_UNKNOWN_ERROR",e))(t||{}),i=(e=>(e.SESSION_INVALID="SESSION_INVALID",e.SESSION_EXPIRED="SESSION_EXPIRED",e.SESSION_FETCH_FAILED="SESSION_FETCH_FAILED",e.SESSION_DECLINED="SESSION_DECLINED",e.FINGERPRINT_FAILED="FINGERPRINT_FAILED",e.DOCUMENT_UPLOAD_FAILED="DOCUMENT_UPLOAD_FAILED",e.LIVENESS_FAILED="LIVENESS_FAILED",e.LIVENESS_INIT_FAILED="LIVENESS_INIT_FAILED",e.LIVENESS_VIDEO_UPLOAD_FAILED="LIVENESS_VIDEO_UPLOAD_FAILED",e.CAMERA_ERROR="CAMERA_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.API_ERROR="API_ERROR",e.CONTAINER_NOT_FOUND="CONTAINER_NOT_FOUND",e.ALREADY_STARTED="ALREADY_STARTED",e.INSTANCE_DESTROYED="INSTANCE_DESTROYED",e.INSECURE_EMBED="INSECURE_EMBED",e.INTEGRITY_FAILED="INTEGRITY_FAILED",e.RUNTIME_LOAD_FAILED="RUNTIME_LOAD_FAILED",e.UNKNOWN="UNKNOWN",e))(i||{});const n="VELION_INIT",s="VELION_READY",r="VELION_SUCCESS",o="VELION_ERROR",a="VELION_STEP_CHANGE",E="VELION_STEP_COMPLETE",c="VELION_TOKEN_EXPIRED",l="VELION_EXIT",d="VELION_LIVENESS_VIDEO_UPLOADED",h="VELION_TOKEN",I="lpqLG4Ta0YyBn/+lQh95tFl4CuTIHWapeeq7+xnPH+U=";function f(e){const t=atob(e),i=new ArrayBuffer(t.length),n=new Uint8Array(i);for(let s=0;s<t.length;s++)n[s]=t.charCodeAt(s);return i}async function u(e,t=I){let i,n,s,r,o,a;try{const t=await fetch(`${e}/manifest.json`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(404===t.status)return{ok:!1,reason:"unavailable"};if(!t.ok)return{ok:!1,reason:"unavailable",detail:`HTTP ${t.status}`};i=await t.arrayBuffer(),n=(new TextDecoder).decode(i)}catch(E){return{ok:!1,reason:"unavailable",detail:E.message}}try{if(s=JSON.parse(n),"string"!=typeof s.version||"string"!=typeof s.entry||"string"!=typeof s.buildTime)return{ok:!1,reason:"malformed"}}catch(E){return{ok:!1,reason:"malformed",detail:E.message}}if(!t)return{ok:!0,manifest:s,signed:!1};try{const t=await fetch(`${e}/manifest.sig`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(!t.ok)return{ok:!1,reason:"invalid_signature",detail:`sig HTTP ${t.status}`};r=f((await t.text()).trim())}catch(E){return{ok:!1,reason:"invalid_signature",detail:E.message}}try{o=await async function(e){const t=f(e);return crypto.subtle.importKey("raw",t,{name:"Ed25519"},!1,["verify"])}(t)}catch(E){return{ok:!1,reason:"invalid_signature",detail:`pubkey import failed: ${E.message}`}}try{a=await async function(e,t,i){return crypto.subtle.verify({name:"Ed25519"},e,t,i)}(o,r,i)}catch(E){return{ok:!1,reason:"invalid_signature",detail:E.message}}return a?{ok:!0,manifest:s,signed:!0}:{ok:!1,reason:"invalid_signature"}}const N="https://static.velion.la/sdk/onboarding/v1";function R(e){try{const i=new URL(e);return"https:"===i.protocol||"http:"===i.protocol&&("localhost"===(t=i.hostname)||"127.0.0.1"===t||"::1"===t||t.endsWith(".local"))}catch{return!1}var t}const O=["containerId","sessionId","sessionToken","apiUrl","expiresAt","theme","colorMode","locale","allowEmbedded","livenessShowIntro","livenessShowBackButton","fingerprintEndpoint","debug","googleMapsApiKey","showFinalResultScreen","showProgressBar","finalResultScreenTexts"];e.CameraErrorCode=t,e.DEFAULT_CDN_URL=N,e.SdkErrorCode=i,e.VELION_MSG_ERROR=o,e.VELION_MSG_EXIT=l,e.VELION_MSG_INIT=n,e.VELION_MSG_LIVENESS_VIDEO_UPLOADED=d,e.VELION_MSG_READY=s,e.VELION_MSG_STEP_CHANGE=a,e.VELION_MSG_STEP_COMPLETE=E,e.VELION_MSG_SUCCESS=r,e.VELION_MSG_TOKEN=h,e.VELION_MSG_TOKEN_EXPIRED=c,e.VelionOnboarding=class{constructor(e){this.status="IDLE",this.iframe=null,this.container=null,this.messageHandler=null,this.containerResizeObserver=null,this.iframeHeightWindowResizeHandler=null,this.cdnOrigin="",this.readyTimer=null,this.config=Object.freeze({...e})}clearReadyTimer(){null!==this.readyTimer&&(clearTimeout(this.readyTimer),this.readyTimer=null)}armReadyTimer(e){this.clearReadyTimer();const t=this.config.runtimeReadyTimeoutMs??3e4;t>0&&(this.readyTimer=setTimeout(()=>{this.readyTimer=null,"RUNNING"===this.status&&(this.status="ERROR",this.config.onError?.({code:i.RUNTIME_LOAD_FAILED,message:`The onboarding runtime at ${e} did not become ready within ${t} ms. Check that the CDN serves the assets referenced by its index.html and that the host page's Content-Security-Policy allows the runtime scripts.`}))},t))}async start(){if("DESTROYED"===this.status)return void this.config.onError?.({code:i.INSTANCE_DESTROYED,message:"This VelionOnboarding instance has been destroyed. Create a new instance to retry."});if("IDLE"!==this.status)return void this.config.onError?.({code:i.ALREADY_STARTED,message:"start() was called on an already-running SDK instance. Call destroy() before re-starting."});const e=document.getElementById(this.config.containerId);if(!e)return void this.config.onError?.({code:i.CONTAINER_NOT_FOUND,message:`No DOM element found with id="${this.config.containerId}". Ensure the element exists before calling start().`});const t=(this.config.cdnUrl??N).replace(/\/$/,"");if(!R(t))return void this.config.onError?.({code:i.UNKNOWN,message:`Insecure cdnUrl: "${t}". Must be https:// (http:// is allowed only for localhost).`});if(this.config.apiUrl&&!R(this.config.apiUrl))return void this.config.onError?.({code:i.UNKNOWN,message:`Insecure apiUrl: "${this.config.apiUrl}". Must be https:// (http:// is allowed only for localhost).`});if(this.cdnOrigin=function(e){try{return new URL(e).origin}catch{return""}}(t),!this.cdnOrigin)return void this.config.onError?.({code:i.UNKNOWN,message:`Invalid cdnUrl: ${t}. Must be a valid absolute URL.`});this.container=e,this.status="INITIALIZING";const I=document.createElement("iframe");I.setAttribute("title","Velion Onboarding"),I.setAttribute("allow","camera"),I.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-modals"),I.setAttribute("referrerpolicy","no-referrer"),I.style.width="100%",I.style.border="none",I.style.display="block";const f=e=>{if(e.origin!==this.cdnOrigin)return;if(e.source!==this.iframe?.contentWindow)return;const t=e.data;if(t&&"string"==typeof t.type)switch(t.type){case s:this.clearReadyTimer(),this.status="RUNNING";break;case r:this.status="COMPLETED",this.config.onSuccess?.(t.payload);break;case o:this.status="ERROR",this.config.onError?.(t.payload);break;case a:{const e=t.payload;this.config.onStepChange?.(e.step,e.stepIndex);break}case E:{const e=t.payload;this.config.onStepComplete?.(e.step);break}case l:this.status="EXITED",this.config.onExit?.(t.payload);break;case d:this.config.onLivenessVideoUploaded?.(t.payload);break;case c:{const e=this.config.onTokenExpired;e?e().then(e=>this.sendToIframe({type:h,payload:e}),()=>{this.config.onError?.({code:i.SESSION_EXPIRED,message:"Token refresh failed."})}):this.config.onError?.({code:i.SESSION_EXPIRED,message:"Session token expired. Provide onTokenExpired in config to refresh."});break}}};window.addEventListener("message",f),this.messageHandler=f,this.iframe=I,e.replaceChildren(I),this.attachIframeHeightSync(e,I);const u=await this.resolveManifest(t);if(!u)return;const _=u.entry.startsWith("/")?u.entry:`/${u.entry}`;return new Promise(e=>{I.onload=()=>{if(!this.iframe?.contentWindow)return this.status="ERROR",this.config.onError?.({code:i.UNKNOWN,message:"Iframe failed to load."}),void e();const s=function(e){const t={containerId:"velion-sdk-root",allowEmbedded:!0};for(const i of O){if("containerId"===i||"allowEmbedded"===i)continue;const n=e[i];void 0!==n&&"function"!=typeof n&&(t[i]=n)}return t}(this.config);let r;try{r=JSON.parse(JSON.stringify(s))}catch{r=s}this.sendToIframe({type:n,payload:r}),this.status="RUNNING",this.armReadyTimer(t),e()},I.onerror=()=>{this.status="ERROR",this.config.onError?.({code:i.UNKNOWN,message:`Failed to load onboarding app from ${t}. Check cdnUrl and network.`}),e()},I.src=`${t}${_}`})}async resolveManifest(e){let t;try{t=await u(e)}catch(n){return this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:`Manifest verification crashed unexpectedly: ${n.message}`}),null}if(t.ok)return!t.signed&&I?(this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:"Internal: manifest reported as unsigned despite pubkey being set."}),null):t.manifest;if("unavailable"===t.reason){return!0!==this.config.allowUnverifiedCdn?(this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:`CDN at "${e}" did not expose /manifest.json. The loader is configured to require a signed manifest. If the CDN is migrating, set \`allowUnverifiedCdn: true\` on the loader config — but only as a temporary measure.`}),null):{version:"legacy",buildTime:(new Date).toISOString(),entry:"/index.html"}}return this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:`CDN manifest at "${e}/manifest.json" failed integrity check (${t.reason}). Refusing to load the iframe to protect the user. `+("detail"in t&&t.detail?`Detail: ${t.detail}`:"")}),null}attachIframeHeightSync(e,t){const i=()=>{if(this.iframe!==t||this.container!==e)return;const i=e.clientHeight;i>0?(t.style.height=`${i}px`,t.style.minHeight=""):(t.style.height="min(85vh, 880px)",t.style.minHeight="")};i(),requestAnimationFrame(i),requestAnimationFrame(()=>{requestAnimationFrame(i)}),"undefined"!=typeof ResizeObserver?(this.containerResizeObserver=new ResizeObserver(i),this.containerResizeObserver.observe(e)):(this.iframeHeightWindowResizeHandler=i,window.addEventListener("resize",i))}detachIframeHeightSync(){this.containerResizeObserver&&(this.containerResizeObserver.disconnect(),this.containerResizeObserver=null),this.iframeHeightWindowResizeHandler&&(window.removeEventListener("resize",this.iframeHeightWindowResizeHandler),this.iframeHeightWindowResizeHandler=null)}sendToIframe(e){this.iframe?.contentWindow&&this.iframe.contentWindow.postMessage(e,this.cdnOrigin)}getStatus(){return this.status}static getVersion(){return"1.0.0-beta.21"}destroy(){"DESTROYED"!==this.status&&(this.clearReadyTimer(),this.detachIframeHeightSync(),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.iframe&&this.container&&(this.iframe.remove(),this.container.replaceChildren()),this.iframe=null,this.container=null,this.status="DESTROYED")}},e.setOpenCVBaseUrl=function(e){},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VelionSDK={})}(this,function(e){"use strict";var t=(e=>(e.PERMISSION_DENIED="CAMERA_PERMISSION_DENIED",e.DEVICE_NOT_FOUND="CAMERA_DEVICE_NOT_FOUND",e.DEVICE_NOT_READABLE="CAMERA_DEVICE_NOT_READABLE",e.INSECURE_CONTEXT="CAMERA_INSECURE_CONTEXT",e.POLICY_BLOCKED="CAMERA_POLICY_BLOCKED",e.NOT_SUPPORTED="CAMERA_NOT_SUPPORTED",e.WEBVIEW_BLOCKED="CAMERA_WEBVIEW_BLOCKED",e.CONSTRAINT_ERROR="CAMERA_CONSTRAINT_ERROR",e.UNKNOWN="CAMERA_UNKNOWN_ERROR",e))(t||{}),i=(e=>(e.SESSION_INVALID="SESSION_INVALID",e.SESSION_EXPIRED="SESSION_EXPIRED",e.SESSION_FETCH_FAILED="SESSION_FETCH_FAILED",e.SESSION_DECLINED="SESSION_DECLINED",e.FINGERPRINT_FAILED="FINGERPRINT_FAILED",e.DOCUMENT_UPLOAD_FAILED="DOCUMENT_UPLOAD_FAILED",e.LIVENESS_FAILED="LIVENESS_FAILED",e.LIVENESS_INIT_FAILED="LIVENESS_INIT_FAILED",e.LIVENESS_VIDEO_UPLOAD_FAILED="LIVENESS_VIDEO_UPLOAD_FAILED",e.CAMERA_ERROR="CAMERA_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.API_ERROR="API_ERROR",e.CONTAINER_NOT_FOUND="CONTAINER_NOT_FOUND",e.ALREADY_STARTED="ALREADY_STARTED",e.INSTANCE_DESTROYED="INSTANCE_DESTROYED",e.INSECURE_EMBED="INSECURE_EMBED",e.INTEGRITY_FAILED="INTEGRITY_FAILED",e.RUNTIME_LOAD_FAILED="RUNTIME_LOAD_FAILED",e.UNKNOWN="UNKNOWN",e))(i||{});const n="VELION_INIT",s="VELION_READY",r="VELION_SUCCESS",o="VELION_ERROR",a="VELION_STEP_CHANGE",E="VELION_STEP_COMPLETE",c="VELION_TOKEN_EXPIRED",l="VELION_EXIT",d="VELION_LIVENESS_VIDEO_UPLOADED",h="VELION_TOKEN",I="lpqLG4Ta0YyBn/+lQh95tFl4CuTIHWapeeq7+xnPH+U=";function f(e){const t=atob(e),i=new ArrayBuffer(t.length),n=new Uint8Array(i);for(let s=0;s<t.length;s++)n[s]=t.charCodeAt(s);return i}async function u(e,t=I){let i,n,s,r,o,a;try{const t=await fetch(`${e}/manifest.json`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(404===t.status)return{ok:!1,reason:"unavailable"};if(!t.ok)return{ok:!1,reason:"unavailable",detail:`HTTP ${t.status}`};i=await t.arrayBuffer(),n=(new TextDecoder).decode(i)}catch(E){return{ok:!1,reason:"unavailable",detail:E.message}}try{if(s=JSON.parse(n),"string"!=typeof s.version||"string"!=typeof s.entry||"string"!=typeof s.buildTime)return{ok:!1,reason:"malformed"}}catch(E){return{ok:!1,reason:"malformed",detail:E.message}}if(!t)return{ok:!0,manifest:s,signed:!1};try{const t=await fetch(`${e}/manifest.sig`,{credentials:"omit",cache:"no-cache",redirect:"error"});if(!t.ok)return{ok:!1,reason:"invalid_signature",detail:`sig HTTP ${t.status}`};r=f((await t.text()).trim())}catch(E){return{ok:!1,reason:"invalid_signature",detail:E.message}}try{o=await async function(e){const t=f(e);return crypto.subtle.importKey("raw",t,{name:"Ed25519"},!1,["verify"])}(t)}catch(E){return{ok:!1,reason:"invalid_signature",detail:`pubkey import failed: ${E.message}`}}try{a=await async function(e,t,i){return crypto.subtle.verify({name:"Ed25519"},e,t,i)}(o,r,i)}catch(E){return{ok:!1,reason:"invalid_signature",detail:E.message}}return a?{ok:!0,manifest:s,signed:!0}:{ok:!1,reason:"invalid_signature"}}const N="https://static.velion.la/sdk/onboarding/v1";function R(e){try{const i=new URL(e);return"https:"===i.protocol||"http:"===i.protocol&&("localhost"===(t=i.hostname)||"127.0.0.1"===t||"::1"===t||t.endsWith(".local"))}catch{return!1}var t}const O=["containerId","sessionId","sessionToken","apiUrl","expiresAt","theme","colorMode","locale","allowEmbedded","livenessShowIntro","livenessShowBackButton","fingerprintEndpoint","debug","googleMapsApiKey","showFinalResultScreen","showProgressBar","finalResultScreenTexts"];e.CameraErrorCode=t,e.DEFAULT_CDN_URL=N,e.SdkErrorCode=i,e.VELION_MSG_ERROR=o,e.VELION_MSG_EXIT=l,e.VELION_MSG_INIT=n,e.VELION_MSG_LIVENESS_VIDEO_UPLOADED=d,e.VELION_MSG_READY=s,e.VELION_MSG_STEP_CHANGE=a,e.VELION_MSG_STEP_COMPLETE=E,e.VELION_MSG_SUCCESS=r,e.VELION_MSG_TOKEN=h,e.VELION_MSG_TOKEN_EXPIRED=c,e.VelionOnboarding=class{constructor(e){this.status="IDLE",this.iframe=null,this.container=null,this.messageHandler=null,this.containerResizeObserver=null,this.iframeHeightWindowResizeHandler=null,this.cdnOrigin="",this.readyTimer=null,this.config=Object.freeze({...e})}clearReadyTimer(){null!==this.readyTimer&&(clearTimeout(this.readyTimer),this.readyTimer=null)}armReadyTimer(e){this.clearReadyTimer();const t=this.config.runtimeReadyTimeoutMs??3e4;t>0&&(this.readyTimer=setTimeout(()=>{this.readyTimer=null,"RUNNING"===this.status&&(this.status="ERROR",this.config.onError?.({code:i.RUNTIME_LOAD_FAILED,message:`The onboarding runtime at ${e} did not become ready within ${t} ms. Check that the CDN serves the assets referenced by its index.html and that the host page's Content-Security-Policy allows the runtime scripts.`}))},t))}async start(){if("DESTROYED"===this.status)return void this.config.onError?.({code:i.INSTANCE_DESTROYED,message:"This VelionOnboarding instance has been destroyed. Create a new instance to retry."});if("IDLE"!==this.status)return void this.config.onError?.({code:i.ALREADY_STARTED,message:"start() was called on an already-running SDK instance. Call destroy() before re-starting."});const e=document.getElementById(this.config.containerId);if(!e)return void this.config.onError?.({code:i.CONTAINER_NOT_FOUND,message:`No DOM element found with id="${this.config.containerId}". Ensure the element exists before calling start().`});const t=(this.config.cdnUrl??N).replace(/\/$/,"");if(!R(t))return void this.config.onError?.({code:i.UNKNOWN,message:`Insecure cdnUrl: "${t}". Must be https:// (http:// is allowed only for localhost).`});if(this.config.apiUrl&&!R(this.config.apiUrl))return void this.config.onError?.({code:i.UNKNOWN,message:`Insecure apiUrl: "${this.config.apiUrl}". Must be https:// (http:// is allowed only for localhost).`});if(this.cdnOrigin=function(e){try{return new URL(e).origin}catch{return""}}(t),!this.cdnOrigin)return void this.config.onError?.({code:i.UNKNOWN,message:`Invalid cdnUrl: ${t}. Must be a valid absolute URL.`});this.container=e,this.status="INITIALIZING";const I=document.createElement("iframe");I.setAttribute("title","Velion Onboarding"),I.setAttribute("allow","camera"),I.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups allow-modals"),I.setAttribute("referrerpolicy","no-referrer"),I.style.width="100%",I.style.border="none",I.style.display="block";const f=e=>{if(e.origin!==this.cdnOrigin)return;if(e.source!==this.iframe?.contentWindow)return;const t=e.data;if(t&&"string"==typeof t.type)switch(t.type){case s:this.clearReadyTimer(),this.status="RUNNING";break;case r:this.status="COMPLETED",this.config.onSuccess?.(t.payload);break;case o:this.status="ERROR",this.config.onError?.(t.payload);break;case a:{const e=t.payload;this.config.onStepChange?.(e.step,e.stepIndex);break}case E:{const e=t.payload;this.config.onStepComplete?.(e.step);break}case l:this.status="EXITED",this.config.onExit?.(t.payload);break;case d:this.config.onLivenessVideoUploaded?.(t.payload);break;case c:{const e=this.config.onTokenExpired;e?e().then(e=>this.sendToIframe({type:h,payload:e}),()=>{this.config.onError?.({code:i.SESSION_EXPIRED,message:"Token refresh failed."})}):this.config.onError?.({code:i.SESSION_EXPIRED,message:"Session token expired. Provide onTokenExpired in config to refresh."});break}}};window.addEventListener("message",f),this.messageHandler=f,this.iframe=I,e.replaceChildren(I),this.attachIframeHeightSync(e,I);const u=await this.resolveManifest(t);if(!u)return;const _=u.entry.startsWith("/")?u.entry:`/${u.entry}`;return new Promise(e=>{I.onload=()=>{if(!this.iframe?.contentWindow)return this.status="ERROR",this.config.onError?.({code:i.UNKNOWN,message:"Iframe failed to load."}),void e();const s=function(e){const t={containerId:"velion-sdk-root",allowEmbedded:!0};for(const i of O){if("containerId"===i||"allowEmbedded"===i)continue;const n=e[i];void 0!==n&&"function"!=typeof n&&(t[i]=n)}return t}(this.config);let r;try{r=JSON.parse(JSON.stringify(s))}catch{r=s}this.sendToIframe({type:n,payload:r}),this.status="RUNNING",this.armReadyTimer(t),e()},I.onerror=()=>{this.status="ERROR",this.config.onError?.({code:i.UNKNOWN,message:`Failed to load onboarding app from ${t}. Check cdnUrl and network.`}),e()},I.src=`${t}${_}`})}async resolveManifest(e){let t;try{t=await u(e)}catch(n){return this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:`Manifest verification crashed unexpectedly: ${n.message}`}),null}if(t.ok)return!t.signed&&I?(this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:"Internal: manifest reported as unsigned despite pubkey being set."}),null):t.manifest;if("unavailable"===t.reason){return!0!==this.config.allowUnverifiedCdn?(this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:`CDN at "${e}" did not expose /manifest.json. The loader is configured to require a signed manifest. If the CDN is migrating, set \`allowUnverifiedCdn: true\` on the loader config — but only as a temporary measure.`}),null):{version:"legacy",buildTime:(new Date).toISOString(),entry:"/index.html"}}return this.status="ERROR",this.config.onError?.({code:i.INTEGRITY_FAILED,message:`CDN manifest at "${e}/manifest.json" failed integrity check (${t.reason}). Refusing to load the iframe to protect the user. `+("detail"in t&&t.detail?`Detail: ${t.detail}`:"")}),null}attachIframeHeightSync(e,t){const i=()=>{if(this.iframe!==t||this.container!==e)return;const i=e.clientHeight;i>0?(t.style.height=`${i}px`,t.style.minHeight=""):(t.style.height="min(85vh, 880px)",t.style.minHeight="")};i(),requestAnimationFrame(i),requestAnimationFrame(()=>{requestAnimationFrame(i)}),"undefined"!=typeof ResizeObserver?(this.containerResizeObserver=new ResizeObserver(i),this.containerResizeObserver.observe(e)):(this.iframeHeightWindowResizeHandler=i,window.addEventListener("resize",i))}detachIframeHeightSync(){this.containerResizeObserver&&(this.containerResizeObserver.disconnect(),this.containerResizeObserver=null),this.iframeHeightWindowResizeHandler&&(window.removeEventListener("resize",this.iframeHeightWindowResizeHandler),this.iframeHeightWindowResizeHandler=null)}sendToIframe(e){this.iframe?.contentWindow&&this.iframe.contentWindow.postMessage(e,this.cdnOrigin)}getStatus(){return this.status}static getVersion(){return"1.0.0-beta.23"}destroy(){"DESTROYED"!==this.status&&(this.clearReadyTimer(),this.detachIframeHeightSync(),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.iframe&&this.container&&(this.iframe.remove(),this.container.replaceChildren()),this.iframe=null,this.container=null,this.status="DESTROYED")}},e.setOpenCVBaseUrl=function(e){},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
|
|
2
2
|
//# sourceMappingURL=velion-sdk.umd.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velion-la/onboarding-sdk-web",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.23",
|
|
4
4
|
"description": "Web SDK for the Velion Onboarding (KYC) flow. Thin client that boots the full verification experience (ID document OCR, passive + active liveness, device fingerprint, OTP verification, address picker, and personal / legal information forms) inside an embedded iframe served from the Velion CDN.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/velion-sdk.umd.js",
|