@checktiv/sdk-web 1.9.0 → 1.12.0
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/README.md +16 -1
- package/dist/agents/AGENTS.md +8 -0
- package/dist/agents/manifest.json +24 -0
- package/dist/capture-ui.d.ts +4 -4
- package/dist/capture-ui.js +7 -6
- package/dist/capture.d.ts +3 -3
- package/dist/capture.js +4 -3
- package/dist/challenge.js +2 -2
- package/dist/chunk-3KEVZCCZ.js +3 -0
- package/dist/chunk-4HIQN4KL.js +3 -0
- package/dist/chunk-C7GRMEYT.js +3 -0
- package/dist/chunk-CAI3JWWU.js +12 -0
- package/dist/chunk-EOTGVXW6.js +7 -0
- package/dist/{chunk-HV2QKVJX.js → chunk-FQSJUWRP.js} +1 -1
- package/dist/{chunk-FL2GCRSI.js → chunk-HWABVMID.js} +4 -4
- package/dist/{chunk-MCYAWMYQ.js → chunk-KYV5BPCD.js} +2 -2
- package/dist/chunk-MLQ2HMTS.js +3 -0
- package/dist/chunk-O3JECGW2.js +3 -0
- package/dist/chunk-PB2THQ3P.js +8 -0
- package/dist/chunk-TKK5CTVG.js +59 -0
- package/dist/chunk-UVTAPUGQ.js +3 -0
- package/dist/chunk-VMWTID63.js +3 -0
- package/dist/{chunk-WC6TLR42.js → chunk-WALPQ6TH.js} +2 -1
- package/dist/chunk-YE2LWN74.js +9 -0
- package/dist/{chunk-XSSM5ZB7.js → chunk-ZU4L3NDZ.js} +1 -1
- package/dist/collect-user-info.d.ts +4 -4
- package/dist/collect-user-info.js +5 -5
- package/dist/{controller-Ta5RgFZ4.d.ts → controller-Dh-rSrot.d.ts} +3 -2
- package/dist/{copy-CEILzVXc.d.ts → copy-Bsb1n1Wv.d.ts} +1 -1
- package/dist/credit-history.d.ts +4 -0
- package/dist/credit-history.js +12 -0
- package/dist/cross-device.js +2 -2
- package/dist/custom-form.css +1 -1
- package/dist/custom-form.d.ts +3 -3
- package/dist/custom-form.js +7 -8
- package/dist/esign/ceremony-runtime.js +7 -0
- package/dist/esign.d.ts +16 -0
- package/dist/esign.js +427 -0
- package/dist/fraud.d.ts +3 -3
- package/dist/fraud.js +5 -6
- package/dist/idv/cross-device.d.ts +7 -7
- package/dist/idv/cross-device.js +4 -5
- package/dist/idv.d.ts +3 -3
- package/dist/idv.js +13 -13
- package/dist/index-CGH7LlPH.d.ts +736 -0
- package/dist/{index-G5mVvjNZ.d.ts → index-CZt19Km4.d.ts} +5 -5
- package/dist/index.d.ts +6 -6
- package/dist/index.js +8 -8
- package/dist/{machine-BhPiYmOR.d.ts → machine-EePe2ERe.d.ts} +49 -2
- package/dist/react.d.ts +4 -4
- package/dist/react.js +11 -11
- package/dist/workspace.d.ts +3 -3
- package/dist/workspace.js +2 -1
- package/package.json +35 -9
- package/dist/api-BrQqQbGK.d.ts +0 -342
- package/dist/chunk-523TT3PD.js +0 -7
- package/dist/chunk-7GP5REM7.js +0 -3
- package/dist/chunk-BBO2X73Y.js +0 -9
- package/dist/chunk-GFHNOZVO.js +0 -3
- package/dist/chunk-NHNGQ5BB.js +0 -66
- package/dist/chunk-S2OOEDJS.js +0 -3
- package/dist/chunk-T4R5TTE5.js +0 -7
- package/dist/chunk-WPMO4FQ2.js +0 -13
- package/dist/chunk-XOGHMNBX.js +0 -3
package/dist/idv.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import { mount } from './chunk-HWABVMID.js';
|
|
2
|
+
import { IDV_ACQUISITION_WHEN_ABSENT, CURRENT_PROTOCOL_VERSION } from './chunk-PB2THQ3P.js';
|
|
3
|
+
import './chunk-TKK5CTVG.js';
|
|
4
|
+
import { createChecktivErrorEvent, mapStateToEvent, getCrossDeviceOpener } from './chunk-KYV5BPCD.js';
|
|
5
|
+
import './chunk-ZU4L3NDZ.js';
|
|
6
|
+
import './chunk-FQSJUWRP.js';
|
|
7
|
+
import './chunk-3KEVZCCZ.js';
|
|
8
|
+
import { resolveSession, warnWrongTokenPlane } from './chunk-EOTGVXW6.js';
|
|
9
|
+
import './chunk-IQKHRPJR.js';
|
|
5
10
|
import { assertNever } from './chunk-UBQTPS5J.js';
|
|
6
|
-
import {
|
|
11
|
+
import { resolveCaptureTheme } from './chunk-4HIQN4KL.js';
|
|
12
|
+
import { registerModule } from './chunk-VMWTID63.js';
|
|
13
|
+
import { createChecktivError, withTokenRetry, CREDENTIAL_UNVERIFIABLE_STATUS, mapHttpStatusToError } from './chunk-C7GRMEYT.js';
|
|
7
14
|
import { stepSubmitPath, dataPlaneHeaders, CAPTURE_TOKEN_MINT_PATH, isCanonicalOrigin } from './chunk-HFQJYEGZ.js';
|
|
8
|
-
import { mount } from './chunk-FL2GCRSI.js';
|
|
9
|
-
import './chunk-HV2QKVJX.js';
|
|
10
|
-
import './chunk-XOGHMNBX.js';
|
|
11
|
-
import { CURRENT_PROTOCOL_VERSION } from './chunk-T4R5TTE5.js';
|
|
12
|
-
import './chunk-NHNGQ5BB.js';
|
|
13
|
-
import './chunk-XSSM5ZB7.js';
|
|
14
|
-
import './chunk-IQKHRPJR.js';
|
|
15
15
|
import './chunk-QFA3K5ZV.js';
|
|
16
16
|
import './chunk-AIK7CDV6.js';
|
|
17
17
|
|
|
18
|
-
var PLATFORM_BRAND_DEFAULT={primaryColor:"#2563eb",secondaryColor:"#ff5e4d",colorMode:"auto"};var SURFACE={light:{bg:"#fafaf7",surface1:"#ffffff"},dark:{bg:"#0b0c0f",surface1:"#15171c"}};var WHITE="#ffffff";var NEAR_BLACK="#0b0c0f";var ACCENT_TARGET=3;var ADAPT_STEP=.04;var ADAPT_MAX_ITERS=24;var HOVER_DELTA=.08;var SECONDARY_HUE_SHIFT=150;var HEX_RE=/^#[0-9a-fA-F]{6}$/;function toHex(r,g,b){const ch=v=>Math.max(0,Math.min(255,Math.round(v))).toString(16).padStart(2,"0");return `#${ch(r)}${ch(g)}${ch(b)}`}function parseHex(hex){if(typeof hex!=="string"||!HEX_RE.test(hex))return null;const n=Number.parseInt(hex.slice(1),16);return {r:n>>16&255,g:n>>8&255,b:n&255}}function linearize(channel){const s=channel/255;return s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4)}function relativeLuminance(rgb){return .2126*linearize(rgb.r)+.7152*linearize(rgb.g)+.0722*linearize(rgb.b)}function assessContrast(fg,bg){const f=parseHex(fg);const b=parseHex(bg);if(!f||!b)return 1;const l1=relativeLuminance(f);const l2=relativeLuminance(b);const hi=Math.max(l1,l2);const lo=Math.min(l1,l2);return (hi+.05)/(lo+.05)}function rgbToHsl({r,g,b}){const rn=r/255;const gn=g/255;const bn=b/255;const max=Math.max(rn,gn,bn);const min=Math.min(rn,gn,bn);const l=(max+min)/2;let h=0;let s=0;if(max!==min){const d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case rn:h=(gn-bn)/d+(gn<bn?6:0);break;case gn:h=(bn-rn)/d+2;break;default:h=(rn-gn)/d+4;break}h/=6;}return {h:h*360,s,l}}function hueToRgb(p,q,tRaw){let t=tRaw;if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p}function hslToRgb({h,s,l}){const hn=(h%360+360)%360/360;let r;let g;let b;if(s===0){r=g=b=l;}else {const q=l<.5?l*(1+s):l+s-l*s;const p=2*l-q;r=hueToRgb(p,q,hn+1/3);g=hueToRgb(p,q,hn);b=hueToRgb(p,q,hn-1/3);}return {r:Math.round(r*255),g:Math.round(g*255),b:Math.round(b*255)}}function deriveSecondaryHue(hex){const rgb=parseHex(hex);if(!rgb)return PLATFORM_BRAND_DEFAULT.secondaryColor;const hsl=rgbToHsl(rgb);const out=hslToRgb({...hsl,h:(hsl.h+SECONDARY_HUE_SHIFT)%360});return toHex(out.r,out.g,out.b)}function shiftLightness(hex,delta){const rgb=parseHex(hex);if(!rgb)return toHex(0,0,0);const hsl=rgbToHsl(rgb);const out=hslToRgb({...hsl,l:Math.max(0,Math.min(1,hsl.l+delta))});return toHex(out.r,out.g,out.b)}function onColorFor(bg){const white=assessContrast(WHITE,bg);const dark=assessContrast(NEAR_BLACK,bg);return white>=dark?WHITE:NEAR_BLACK}function adaptAccent(hex,surface,target,warnings,field,mode){const rgb=parseHex(hex);if(!rgb){return toHex(0,0,0)}const hsl=rgbToHsl(rgb);const lighten=relativeLuminance(parseHex(surface)??{r:255,g:255,b:255})<.5;const rawRatio=assessContrast(hex,surface);let l=hsl.l;let out=toHex(rgb.r,rgb.g,rgb.b);for(let i=0;i<ADAPT_MAX_ITERS;i+=1){if(assessContrast(out,surface)>=target)break;l=Math.max(0,Math.min(1,l+(lighten?ADAPT_STEP:-ADAPT_STEP)));const o=hslToRgb({h:hsl.h,s:hsl.s,l});out=toHex(o.r,o.g,o.b);}const finalRatio=assessContrast(out,surface);if(rawRatio<target||finalRatio<target){warnings.push({field,mode,ratio:Number(rawRatio.toFixed(2))});}return out}function deriveMode(input,mode,warnings){const surf=SURFACE[mode];const primary=adaptAccent(input.primaryColor,surf.bg,ACCENT_TARGET,warnings,"primary",mode);const rawSecondary=input.secondaryColor??deriveSecondaryHue(input.primaryColor);const secondary=adaptAccent(rawSecondary,surf.bg,ACCENT_TARGET,warnings,"secondary",mode);const primaryHover=shiftLightness(primary,mode==="light"?-HOVER_DELTA:HOVER_DELTA);const onPrimary=onColorFor(primary);const onSecondary=onColorFor(secondary);const ring=primary;return {primary,primaryHover,onPrimary,secondary,onSecondary,ring}}function toSafeBrandColors(input){if(!input||parseHex(input.primaryColor)===null){return {primaryColor:PLATFORM_BRAND_DEFAULT.primaryColor,secondaryColor:PLATFORM_BRAND_DEFAULT.secondaryColor,colorMode:PLATFORM_BRAND_DEFAULT.colorMode}}const secondaryColor=typeof input.secondaryColor==="string"&&parseHex(input.secondaryColor)!==null?input.secondaryColor:null;const colorMode="auto";return {primaryColor:input.primaryColor,secondaryColor,colorMode}}function deriveBrandTokens(input){const safe=toSafeBrandColors(input);const warnings=[];return {light:deriveMode(safe,"light",warnings),dark:deriveMode(safe,"dark",warnings),warnings}}function defaultPrefersDark(){if(typeof window==="undefined"||typeof window.matchMedia!=="function"){return false}try{return window.matchMedia("(prefers-color-scheme: dark)").matches}catch{return false}}function defaultForcedMode(){if(typeof document==="undefined")return null;const dataTheme=document.documentElement.dataset.theme;return dataTheme==="light"||dataTheme==="dark"?dataTheme:null}function brandColorsFrom(primaryColor){return {primaryColor,secondaryColor:PLATFORM_BRAND_DEFAULT.secondaryColor,colorMode:"auto"}}function resolveCaptureTheme(ctxTheme,opts={}){const prefersDark=opts.prefersDark??defaultPrefersDark;const forcedMode=opts.forcedMode??defaultForcedMode;const colorMode=forcedMode()??(prefersDark()?"dark":"light");const primaryColor=ctxTheme?.primaryColor;if(typeof primaryColor!=="string"||primaryColor.length===0){return {colorMode,brandTokens:null}}const brandTokens=deriveBrandTokens(brandColorsFrom(primaryColor))[colorMode];return {colorMode,brandTokens}}var LEASE_STORAGE_KEY_PREFIX="checktiv.idv.lease.";function isRecord(v){return typeof v==="object"&&v!==null}function storageKey(sessionId){return LEASE_STORAGE_KEY_PREFIX+sessionId}function safeLocalStorage(){try{return globalThis.localStorage??null}catch{return null}}function generateHolderDeviceId(){const c=globalThis.crypto;if(c&&typeof c.randomUUID==="function"){return c.randomUUID()}const bytes=new Uint8Array(16);c.getRandomValues(bytes);let hex="";for(const b of bytes)hex+=b.toString(16).padStart(2,"0");return hex}function loadPersistedLease(sessionId){const ls=safeLocalStorage();if(ls===null)return null;let raw;try{raw=ls.getItem(storageKey(sessionId));}catch{return null}if(raw===null)return null;let parsed;try{parsed=JSON.parse(raw);}catch{return null}if(!isRecord(parsed))return null;const{holderDeviceId,leaseGeneration}=parsed;if(typeof holderDeviceId!=="string"||holderDeviceId.length===0)return null;const gen=typeof leaseGeneration==="number"&&Number.isInteger(leaseGeneration)&&leaseGeneration>=0?leaseGeneration:void 0;return gen===void 0?{holderDeviceId}:{holderDeviceId,leaseGeneration:gen}}function persistLease(sessionId,record){const ls=safeLocalStorage();if(ls===null)return;try{ls.setItem(storageKey(sessionId),JSON.stringify(record));}catch{}}function loadOrCreatePersistedLease(sessionId){const persisted=loadPersistedLease(sessionId);if(persisted!==null)return persisted;const record={holderDeviceId:generateHolderDeviceId()};persistLease(sessionId,record);return record}var MAX_REMINTS=3;function isRecord2(v){return typeof v==="object"&&v!==null}function asMode(value){return value==="live"||value==="test"?value:null}var TEST_HINTS=["pass","review","fail","doc_quality"];function asTestHint(value){return TEST_HINTS.find(hint=>hint===value)??null}function parseMintBody(body){if(!isRecord2(body)||!isRecord2(body.data))return null;const d=body.data;const captureToken=d.capture_token;const embedOrigin=d.embed_origin;const runIndex=d.run_index;const embedContextToken=d.embed_context_token;if(typeof captureToken!=="string"||captureToken.length===0)return null;if(!isCanonicalOrigin(embedOrigin))return null;if(typeof runIndex!=="number"||!Number.isInteger(runIndex)||runIndex<0)return null;if(typeof embedContextToken!=="string"||embedContextToken.length===0)return null;const mode=asMode(d.mode);const testHint=asTestHint(d.test_hint);return {captureToken,embedOrigin,runIndex,embedContextToken,...mode!==null?{mode}:{},...testHint!==null?{testHint}:{}}}function buildCaptureSubmitBody(input){return {runIndex:input.runIndex,r2Keys:input.r2Keys,holderDeviceId:input.holderDeviceId,...input.leaseGeneration!==void 0?{leaseGeneration:input.leaseGeneration}:{}}}function createIdvTransport(ctx,opts){const fetchImpl=opts.fetchImpl??fetch;const origin=ctx.apiBaseOrigin;let embedContextToken=null;let remintCount=0;const persistedLease=loadOrCreatePersistedLease(opts.sessionId);const holderDeviceId=persistedLease.holderDeviceId;const leaseGeneration=persistedLease.leaseGeneration;async function mintToken(){const res=await withTokenRetry(ctx.tokens,token=>fetchImpl(origin+CAPTURE_TOKEN_MINT_PATH,{method:"POST",headers:dataPlaneHeaders(ctx,token,{withJsonBody:true}),body:JSON.stringify({stepId:opts.stepId})}),result=>result?.status===401);if(!res.ok){throw createChecktivError(mapHttpStatusToError(res.status))}let body;try{body=await res.json();}catch{opts.onError?.(createChecktivErrorEvent("sdk_load_failed"));throw createChecktivError("sdk_load_failed")}const parsed=parseMintBody(body);if(parsed===null){opts.onError?.(createChecktivErrorEvent("sdk_load_failed"));throw createChecktivError("sdk_load_failed")}embedContextToken=parsed.embedContextToken;return {captureToken:parsed.captureToken,embedOrigin:parsed.embedOrigin,runIndex:parsed.runIndex,...parsed.mode!==void 0?{mode:parsed.mode}:{},...parsed.testHint!==void 0?{testHint:parsed.testHint}:{}}}function getEmbedSrc(embedOrigin){if(embedContextToken===null){opts.onError?.(createChecktivErrorEvent("sdk_load_failed"));throw createChecktivError("sdk_load_failed")}return `${embedOrigin}/idv/capture?ctx=${encodeURIComponent(embedContextToken)}`}async function submit(runIndex,r2Keys){let res;try{res=await withTokenRetry(ctx.tokens,token=>fetchImpl(origin+stepSubmitPath(opts.sessionId,opts.stepId??""),{method:"POST",headers:dataPlaneHeaders(ctx,token,{withJsonBody:true}),body:JSON.stringify(buildCaptureSubmitBody({runIndex,r2Keys,holderDeviceId,leaseGeneration}))}),result=>result?.status===401);}catch{return {ok:false,reason:"failed"}}if(res.ok)return {ok:true};if(res.status===401)return {ok:false,reason:"token_expired"};if(res.status===409)return {ok:false,reason:"capture_superseded"};if(res.status===503&&res.headers.has("Retry-After")){return {ok:false,reason:"signal_pending"}}return {ok:false,reason:"failed"}}function initPayload(){return {config:opts.config(),locale:ctx.locale,theme:resolveCaptureTheme(ctx.theme),protocolVersion:CURRENT_PROTOCOL_VERSION,...ctx.selfiePromptMap!==void 0?{selfiePromptMap:ctx.selfiePromptMap}:{},...ctx.selfieChromeCopy!==void 0?{selfieChromeCopy:ctx.selfieChromeCopy}:{}}}async function remint(){if(remintCount>=MAX_REMINTS){opts.onError?.(createChecktivErrorEvent("session_expired"));return null}remintCount+=1;try{return await mintToken()}catch{return null}}function failProtocolMismatch(){opts.onError?.(createChecktivErrorEvent("protocol_mismatch"));}return {mintToken,submit,getEmbedSrc,initPayload,remint,failProtocolMismatch}}function after(delayMs,fn){return setTimeout(fn,delayMs)}function createSyntheticIdv(opts,config,sessionId,script){const emit=e=>opts.onEvent?.(e);const delayMs=script?.stepDelayMs??0;const timers=[];let destroyed=false;function step(offsetMs,fn){timers.push(after(offsetMs,()=>{if(!destroyed)fn();}));}step(delayMs*0,()=>{emit({type:"checktiv.idv.ready",config});});if(script?.injectError!==void 0){const code=script.injectError;step(delayMs*1,()=>{emit(createChecktivErrorEvent(code));});}else {step(delayMs*1,()=>{emit({type:"checktiv.idv.phase",phase:"document_front"});});step(delayMs*2,()=>{emit({type:"checktiv.idv.submitted",sessionId});});}const destroy=()=>{if(destroyed)return;destroyed=true;for(const id of timers)clearTimeout(id);};return {destroy,unmount:destroy}}function resolveTarget(target){if(typeof target!=="string")return target;if(typeof document==="undefined")return null;return document.querySelector(target)}function toCaptureConfig(config){return {documentTypes:config.documentTypes,biometricMode:config.biometricMode,requireMrzMatch:false,requireExpiryValid:false,requireNameMatch:false,documentAuthenticity:false,...config.minAge!==void 0?{minAge:config.minAge}:{}}}var REMINT_READY_TIMEOUT_MS=15e3;function noopHandle(){return {destroy(){},unmount(){},openCrossDevice(){}}}function isCoarsePointerViewport(){return typeof window!=="undefined"&&typeof window.matchMedia==="function"&&window.matchMedia("(pointer: coarse)").matches}function createIdv(ctx,opts){const element=resolveTarget(opts.target);if(element===null){console.warn('[Checktiv] mount("idv"): no target element found. Pass an element or a selector that resolves.');return noopHandle()}const emit=e=>opts.onEvent?.(e);const fetchImpl=opts.fetchImpl??fetch;let teardown=null;let cancelled=false;let crossDeviceSession=null;let crossDeviceOverlay=null;const closeCrossDevice=()=>{if(crossDeviceOverlay!==null){crossDeviceOverlay.destroy();crossDeviceOverlay=null;}};const openCrossDevice=()=>{if(cancelled)return;if(crossDeviceOverlay!==null){if(crossDeviceOverlay.isCapped())crossDeviceOverlay.restartPoll();return}if(isCoarsePointerViewport()){console.warn('[Checktiv] mount("idv"): openCrossDevice() is a desktop affordance; ignoring the call on a touch device (the immersive capture layout already owns the phone).');return}const sess=crossDeviceSession;if(sess===null){console.warn('[Checktiv] mount("idv"): openCrossDevice() called before the session resolved.');return}const copy=opts.crossDeviceCopy;if(copy===void 0){console.warn('[Checktiv] mount("idv"): openCrossDevice() requires `crossDeviceCopy` (with `unavailableMessage`).');return}const openOverlay=getCrossDeviceOpener();if(openOverlay===null){console.warn(`[Checktiv] mount("idv"): cross-device is not enabled. Import '@checktiv/sdk-web/idv/cross-device' in your app.`);return}crossDeviceOverlay=openOverlay({ctx,fetchImpl,target:sess.element,stepId:sess.stepId,sessionId:sess.sessionId,copy,isMobile:isCoarsePointerViewport(),onOpenCrossDevice:opts.onOpenCrossDevice,emit,onClose:closeCrossDevice});};void(async()=>{try{await setupCapture(element);}catch(err){if(cancelled)return;console.warn('[Checktiv] mount("idv") setup failed.',err);emit(createChecktivErrorEvent("sdk_load_failed"));}})();async function setupCapture(element2){const resolution=await resolveSession(ctx,fetchImpl);if(cancelled)return;let session;switch(resolution.kind){case "ok":session=resolution.session;break;case "wrong_token":warnWrongTokenPlane();emit(createChecktivErrorEvent("wrong_token_type"));return;case "unresolved":emit(createChecktivErrorEvent("session_expired"));return;case "nothing_to_render":emit({type:"checktiv.idv.processing",reason:"no_renderable_step"});return;default:return assertNever(resolution)}const idvConfig=session.config;if(idvConfig===null){emit(createChecktivErrorEvent("session_expired"));return}const readyConfig={documentTypes:idvConfig.documentTypes,biometricMode:idvConfig.biometricMode};if(ctx.mode==="test"&&opts.synthetic!==void 0){const synthHandle=createSyntheticIdv(opts,readyConfig,session.sessionId,opts.synthetic);teardown=()=>synthHandle.destroy();return}const captureConfig=toCaptureConfig(idvConfig);crossDeviceSession={sessionId:session.sessionId,stepId:session.stepId,element:element2};const transport=createIdvTransport(ctx,{fetchImpl,sessionId:session.sessionId,stepId:session.stepId,config:()=>captureConfig,onError:emit});let pinnedOrigin=null;let everReady=false;const onState=state=>{if(state.kind==="ready"){pinnedOrigin=state.embedOrigin;everReady=true;}if(state.kind==="capture_error"&&state.errorKind==="protocol_mismatch"){transport.failProtocolMismatch();return}const event=mapStateToEvent(state,{config:readyConfig,sessionId:session.sessionId});if(event!==null)emit(event);};const onControllerEvent=event=>{if(event.type==="all-complete"){emit({type:"checktiv.idv.submitted",sessionId:session.sessionId});}};const handle=mount(element2,{mintToken:transport.mintToken,submit:transport.submit,getEmbedSrc:transport.getEmbedSrc,initPayload:transport.initPayload,copy:opts.copy??{},layout:opts.layout,maxWidth:opts.maxWidth,onBeforeSubmit:opts.onBeforeSubmit,onBehaviorSegment:opts.onBehaviorSegment,onState,onControllerEvent});let reminting=false;let awaitingRemintReady=false;let remintReadyTimeoutHandle=null;const clearRemintReadyTimeout=()=>{if(remintReadyTimeoutHandle!==null){clearTimeout(remintReadyTimeoutHandle);remintReadyTimeoutHandle=null;}};const armRemintReadyTimeout=()=>{clearRemintReadyTimeout();remintReadyTimeoutHandle=setTimeout(()=>{remintReadyTimeoutHandle=null;if(!awaitingRemintReady)return;if(cancelled)return;void(async()=>{const minted=await transport.remint();if(cancelled||minted===null){awaitingRemintReady=false;reminting=false;return}if(!awaitingRemintReady){reminting=false;return}const frame=element2.querySelector("iframe.idv-capture-frame");if(frame===null){awaitingRemintReady=false;reminting=false;return}armRemintReadyTimeout();frame.src=transport.getEmbedSrc(minted.embedOrigin);})();},REMINT_READY_TIMEOUT_MS);};const isCaptureReady=data=>typeof data==="object"&&data!==null&&"type"in data&&data.type==="capture:ready";const onReloadMessage=mev=>{if(pinnedOrigin===null||mev.origin!==pinnedOrigin)return;if(!everReady)return;if(!isCaptureReady(mev.data))return;const pinnedFrame=element2.querySelector("iframe.idv-capture-frame");if(pinnedFrame===null)return;if(mev.source!==null&&mev.source!==pinnedFrame.contentWindow)return;if(reminting){if(awaitingRemintReady){clearRemintReadyTimeout();awaitingRemintReady=false;reminting=false;}return}reminting=true;void(async()=>{const minted=await transport.remint();if(cancelled||minted===null){reminting=false;return}const frame=element2.querySelector("iframe.idv-capture-frame");if(frame===null){reminting=false;return}awaitingRemintReady=true;armRemintReadyTimeout();frame.src=transport.getEmbedSrc(minted.embedOrigin);})();};if(typeof window!=="undefined"){window.addEventListener("message",onReloadMessage);}teardown=()=>{clearRemintReadyTimeout();if(typeof window!=="undefined"){window.removeEventListener("message",onReloadMessage);}handle.destroy();};}const destroy=()=>{cancelled=true;closeCrossDevice();if(teardown!==null){teardown();teardown=null;}};return {destroy,unmount:destroy,openCrossDevice}}registerModule("idv",createIdv);
|
|
18
|
+
var LEASE_STORAGE_KEY_PREFIX="checktiv.idv.lease.";function isRecord(v){return typeof v==="object"&&v!==null}function storageKey(sessionId){return LEASE_STORAGE_KEY_PREFIX+sessionId}function safeLocalStorage(){try{return globalThis.localStorage??null}catch{return null}}function generateHolderDeviceId(){const c=globalThis.crypto;if(c&&typeof c.randomUUID==="function"){return c.randomUUID()}const bytes=new Uint8Array(16);c.getRandomValues(bytes);let hex="";for(const b of bytes)hex+=b.toString(16).padStart(2,"0");return hex}function loadPersistedLease(sessionId){const ls=safeLocalStorage();if(ls===null)return null;let raw;try{raw=ls.getItem(storageKey(sessionId));}catch{return null}if(raw===null)return null;let parsed;try{parsed=JSON.parse(raw);}catch{return null}if(!isRecord(parsed))return null;const{holderDeviceId,leaseGeneration}=parsed;if(typeof holderDeviceId!=="string"||holderDeviceId.length===0)return null;const gen=typeof leaseGeneration==="number"&&Number.isInteger(leaseGeneration)&&leaseGeneration>=0?leaseGeneration:void 0;return gen===void 0?{holderDeviceId}:{holderDeviceId,leaseGeneration:gen}}function persistLease(sessionId,record){const ls=safeLocalStorage();if(ls===null)return;try{ls.setItem(storageKey(sessionId),JSON.stringify(record));}catch{}}function loadOrCreatePersistedLease(sessionId){const persisted=loadPersistedLease(sessionId);if(persisted!==null)return persisted;const record={holderDeviceId:generateHolderDeviceId()};persistLease(sessionId,record);return record}var MAX_REMINTS=3;var CTX_FORWARDED_KEYS=["selfiePromptMap","selfieChromeCopy","beginScanCopy"];function pickDefined(source,keys){const out={};for(const key of keys){const value=source[key];if(value!==void 0)out[key]=value;}return out}function isRecord2(v){return typeof v==="object"&&v!==null}function asMode(value){return value==="live"||value==="test"?value:null}var TEST_HINTS=["pass","review","fail","doc_quality"];function asTestHint(value){return TEST_HINTS.find(hint=>hint===value)??null}function parseMintBody(body){if(!isRecord2(body)||!isRecord2(body.data))return null;const d=body.data;const captureToken=d.capture_token;const embedOrigin=d.embed_origin;const runIndex=d.run_index;const embedContextToken=d.embed_context_token;if(typeof captureToken!=="string"||captureToken.length===0)return null;if(!isCanonicalOrigin(embedOrigin))return null;if(typeof runIndex!=="number"||!Number.isInteger(runIndex)||runIndex<0)return null;if(typeof embedContextToken!=="string"||embedContextToken.length===0)return null;const mode=asMode(d.mode);const testHint=asTestHint(d.test_hint);return {captureToken,embedOrigin,runIndex,embedContextToken,...mode!==null?{mode}:{},...testHint!==null?{testHint}:{}}}function buildCaptureSubmitBody(input){return {runIndex:input.runIndex,r2Keys:input.r2Keys,...input.acquisition!==IDV_ACQUISITION_WHEN_ABSENT?{acquisition:input.acquisition}:{},holderDeviceId:input.holderDeviceId,...input.leaseGeneration!==void 0?{leaseGeneration:input.leaseGeneration}:{}}}function createIdvTransport(ctx,opts){const fetchImpl=opts.fetchImpl??fetch;const origin=ctx.apiBaseOrigin;let embedContextToken=null;let remintCount=0;const persistedLease=loadOrCreatePersistedLease(opts.sessionId);const holderDeviceId=persistedLease.holderDeviceId;const leaseGeneration=persistedLease.leaseGeneration;async function mintToken(){const res=await withTokenRetry(ctx.tokens,token=>fetchImpl(origin+CAPTURE_TOKEN_MINT_PATH,{method:"POST",headers:dataPlaneHeaders(ctx,token,{withJsonBody:true}),body:JSON.stringify({stepId:opts.stepId})}));if(!res.ok){throw createChecktivError(mapHttpStatusToError(res.status))}let body;try{body=await res.json();}catch{opts.onError?.(createChecktivErrorEvent("sdk_load_failed"));throw createChecktivError("sdk_load_failed")}const parsed=parseMintBody(body);if(parsed===null){opts.onError?.(createChecktivErrorEvent("sdk_load_failed"));throw createChecktivError("sdk_load_failed")}embedContextToken=parsed.embedContextToken;return {captureToken:parsed.captureToken,embedOrigin:parsed.embedOrigin,runIndex:parsed.runIndex,...parsed.mode!==void 0?{mode:parsed.mode}:{},...parsed.testHint!==void 0?{testHint:parsed.testHint}:{}}}function getEmbedSrc(embedOrigin){if(embedContextToken===null){opts.onError?.(createChecktivErrorEvent("sdk_load_failed"));throw createChecktivError("sdk_load_failed")}return `${embedOrigin}/idv/capture?ctx=${encodeURIComponent(embedContextToken)}`}async function submit(runIndex,r2Keys,acquisition=IDV_ACQUISITION_WHEN_ABSENT){let res;try{res=await withTokenRetry(ctx.tokens,token=>fetchImpl(origin+stepSubmitPath(opts.sessionId,opts.stepId??""),{method:"POST",headers:dataPlaneHeaders(ctx,token,{withJsonBody:true}),body:JSON.stringify(buildCaptureSubmitBody({runIndex,r2Keys,acquisition,holderDeviceId,leaseGeneration}))}));}catch{return {ok:false,reason:"failed"}}if(res.ok)return {ok:true};if(res.status===CREDENTIAL_UNVERIFIABLE_STATUS)return {ok:false,reason:"token_expired"};if(res.status===409)return {ok:false,reason:"capture_superseded"};if(res.status===503&&res.headers.has("Retry-After")){return {ok:false,reason:"signal_pending"}}return {ok:false,reason:"failed"}}function initPayload(){return {config:opts.config(),locale:ctx.locale,theme:resolveCaptureTheme(ctx.theme),protocolVersion:CURRENT_PROTOCOL_VERSION,...pickDefined(ctx,CTX_FORWARDED_KEYS)}}async function remint(){if(remintCount>=MAX_REMINTS){opts.onError?.(createChecktivErrorEvent("session_expired"));return null}remintCount+=1;try{return await mintToken()}catch{return null}}function failProtocolMismatch(){opts.onError?.(createChecktivErrorEvent("protocol_mismatch"));}return {mintToken,submit,getEmbedSrc,initPayload,remint,failProtocolMismatch}}function after(delayMs,fn){return setTimeout(fn,delayMs)}function createSyntheticIdv(opts,config,sessionId,script){const emit=e=>opts.onEvent?.(e);const delayMs=script?.stepDelayMs??0;const timers=[];let destroyed=false;function step(offsetMs,fn){timers.push(after(offsetMs,()=>{if(!destroyed)fn();}));}step(delayMs*0,()=>{emit({type:"checktiv.idv.ready",config});});if(script?.injectError!==void 0){const code=script.injectError;step(delayMs*1,()=>{emit(createChecktivErrorEvent(code));});}else {step(delayMs*1,()=>{emit({type:"checktiv.idv.phase",phase:"document_front"});});step(delayMs*2,()=>{emit({type:"checktiv.idv.submitted",sessionId});});}const destroy=()=>{if(destroyed)return;destroyed=true;for(const id of timers)clearTimeout(id);};return {destroy,unmount:destroy}}function resolveTarget(target){if(typeof target!=="string")return target;if(typeof document==="undefined")return null;return document.querySelector(target)}function toCaptureConfig(config){return {documentTypes:config.documentTypes,biometricMode:config.biometricMode,allowDocumentUpload:config.allowDocumentUpload,requireMrzMatch:false,requireExpiryValid:false,requireNameMatch:false,documentAuthenticity:false,...config.minAge!==void 0?{minAge:config.minAge}:{}}}function toReadyConfig(config){const{documentTypes,biometricMode,allowDocumentUpload}=config;return {documentTypes,biometricMode,allowDocumentUpload}}var REMINT_READY_TIMEOUT_MS=15e3;function noopHandle(){return {destroy(){},unmount(){},openCrossDevice(){}}}function isCoarsePointerViewport(){return typeof window!=="undefined"&&typeof window.matchMedia==="function"&&window.matchMedia("(pointer: coarse)").matches}function createIdv(ctx,opts){const element=resolveTarget(opts.target);if(element===null){console.warn('[Checktiv] mount("idv"): no target element found. Pass an element or a selector that resolves.');return noopHandle()}const emit=e=>opts.onEvent?.(e);const fetchImpl=opts.fetchImpl??fetch;let teardown=null;let cancelled=false;let crossDeviceSession=null;let crossDeviceOverlay=null;const closeCrossDevice=()=>{if(crossDeviceOverlay!==null){crossDeviceOverlay.destroy();crossDeviceOverlay=null;}};const openCrossDevice=()=>{if(cancelled)return;if(crossDeviceOverlay!==null){if(crossDeviceOverlay.isCapped())crossDeviceOverlay.restartPoll();return}if(isCoarsePointerViewport()){console.warn('[Checktiv] mount("idv"): openCrossDevice() is a desktop affordance; ignoring the call on a touch device (the immersive capture layout already owns the phone).');return}const sess=crossDeviceSession;if(sess===null){console.warn('[Checktiv] mount("idv"): openCrossDevice() called before the session resolved.');return}const copy=opts.crossDeviceCopy;if(copy===void 0){console.warn('[Checktiv] mount("idv"): openCrossDevice() requires `crossDeviceCopy` (with `unavailableMessage`).');return}const openOverlay=getCrossDeviceOpener();if(openOverlay===null){console.warn(`[Checktiv] mount("idv"): cross-device is not enabled. Import '@checktiv/sdk-web/idv/cross-device' in your app.`);return}crossDeviceOverlay=openOverlay({ctx,fetchImpl,target:sess.element,stepId:sess.stepId,sessionId:sess.sessionId,copy,isMobile:isCoarsePointerViewport(),onOpenCrossDevice:opts.onOpenCrossDevice,emit,onClose:closeCrossDevice});};void(async()=>{try{await setupCapture(element);}catch(err){if(cancelled)return;console.warn('[Checktiv] mount("idv") setup failed.',err);emit(createChecktivErrorEvent("sdk_load_failed"));}})();async function resolveOwnSession(){const resolution=await resolveSession(ctx,fetchImpl);if(cancelled)return null;let session;switch(resolution.kind){case "ok":session=resolution.session;break;case "wrong_token":warnWrongTokenPlane();emit(createChecktivErrorEvent("wrong_token_type"));return null;case "unresolved":emit(createChecktivErrorEvent("session_expired"));return null;case "parked":emit(createChecktivErrorEvent("session_parked"));return null;case "nothing_to_render":emit({type:"checktiv.idv.processing",reason:"no_renderable_step"});return null;default:return assertNever(resolution)}return {sessionId:session.sessionId,stepId:session.stepId,config:session.config}}async function setupCapture(element2){let session;if(opts.session!==void 0){session=opts.session;}else {const resolved=await resolveOwnSession();if(resolved===null)return;session=resolved;}const idvConfig=session.config;if(idvConfig===null){emit(createChecktivErrorEvent("session_expired"));return}const captureConfig=toCaptureConfig(idvConfig);const readyConfig=toReadyConfig(captureConfig);if(ctx.mode==="test"&&opts.synthetic!==void 0){const synthHandle=createSyntheticIdv(opts,readyConfig,session.sessionId,opts.synthetic);teardown=()=>synthHandle.destroy();return}crossDeviceSession={sessionId:session.sessionId,stepId:session.stepId,element:element2};const transport=createIdvTransport(ctx,{fetchImpl,sessionId:session.sessionId,stepId:session.stepId,config:()=>captureConfig,onError:emit});let pinnedOrigin=null;let everReady=false;const onState=state=>{if(state.kind==="ready"){pinnedOrigin=state.embedOrigin;everReady=true;}if(state.kind==="capture_error"&&state.errorKind==="protocol_mismatch"){transport.failProtocolMismatch();return}const event=mapStateToEvent(state,{config:readyConfig,sessionId:session.sessionId});if(event!==null)emit(event);};const onControllerEvent=event=>{if(event.type==="all-complete"){emit({type:"checktiv.idv.submitted",sessionId:session.sessionId});}};const handle=mount(element2,{mintToken:transport.mintToken,submit:transport.submit,getEmbedSrc:transport.getEmbedSrc,initPayload:transport.initPayload,copy:opts.copy??{},layout:opts.layout,maxWidth:opts.maxWidth,onBeforeSubmit:opts.onBeforeSubmit,onBehaviorSegment:opts.onBehaviorSegment,onEmbedTiming:timing=>emit({type:"checktiv.idv.timing",...timing}),onState,onControllerEvent});let reminting=false;let awaitingRemintReady=false;let remintReadyTimeoutHandle=null;const clearRemintReadyTimeout=()=>{if(remintReadyTimeoutHandle!==null){clearTimeout(remintReadyTimeoutHandle);remintReadyTimeoutHandle=null;}};const armRemintReadyTimeout=()=>{clearRemintReadyTimeout();remintReadyTimeoutHandle=setTimeout(()=>{remintReadyTimeoutHandle=null;if(!awaitingRemintReady)return;if(cancelled)return;void(async()=>{const minted=await transport.remint();if(cancelled||minted===null){awaitingRemintReady=false;reminting=false;return}if(!awaitingRemintReady){reminting=false;return}const frame=element2.querySelector("iframe.idv-capture-frame");if(frame===null){awaitingRemintReady=false;reminting=false;return}armRemintReadyTimeout();frame.src=transport.getEmbedSrc(minted.embedOrigin);})();},REMINT_READY_TIMEOUT_MS);};const isCaptureReady=data=>typeof data==="object"&&data!==null&&"type"in data&&data.type==="capture:ready";const onReloadMessage=mev=>{if(pinnedOrigin===null||mev.origin!==pinnedOrigin)return;if(!everReady)return;if(!isCaptureReady(mev.data))return;const pinnedFrame=element2.querySelector("iframe.idv-capture-frame");if(pinnedFrame===null)return;if(mev.source!==null&&mev.source!==pinnedFrame.contentWindow)return;if(reminting){if(awaitingRemintReady){clearRemintReadyTimeout();awaitingRemintReady=false;reminting=false;}return}reminting=true;void(async()=>{const minted=await transport.remint();if(cancelled||minted===null){reminting=false;return}const frame=element2.querySelector("iframe.idv-capture-frame");if(frame===null){reminting=false;return}awaitingRemintReady=true;armRemintReadyTimeout();frame.src=transport.getEmbedSrc(minted.embedOrigin);})();};if(typeof window!=="undefined"){window.addEventListener("message",onReloadMessage);}teardown=()=>{clearRemintReadyTimeout();if(typeof window!=="undefined"){window.removeEventListener("message",onReloadMessage);}handle.destroy();};}const destroy=()=>{cancelled=true;closeCrossDevice();if(teardown!==null){teardown();teardown=null;}};return {destroy,unmount:destroy,openCrossDevice}}registerModule("idv",createIdv);
|
|
19
19
|
|
|
20
20
|
export { REMINT_READY_TIMEOUT_MS, createIdv };
|