@incodetech/core 2.4.0-rc.4 → 2.4.1-agentic
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/{FaceDetectionProvider-CzQEFzP8.esm.js → FaceDetectionProvider-B83VmClw.esm.js} +29 -64
- package/dist/IBrowserEnvironmentCapability-D7JG7ML3.esm.js +16 -0
- package/dist/IGeolocationCapability-r49Qo7rR.d.ts +10 -0
- package/dist/{IWasmUtilCapability-GF2n7sfm.d.ts → IWasmUtilCapability-Cqiaxydi.d.ts} +31 -4
- package/dist/{PhoneValidationProvider-SZiOS0jB.esm.js → PhoneValidationProvider-Co4zk2en.esm.js} +7 -0
- package/dist/{StreamCanvasCapture-7JRf-2ck.d.ts → StreamCanvasCapture-C3xNfOsv.d.ts} +12 -3
- package/dist/{WasmUtilProvider-DtJuBdt-.esm.js → WasmUtilProvider-GTkoJyFY.esm.js} +75 -22
- package/dist/{addressSearch-DPjIKJrX.esm.js → addressSearch-41sMcnJk.esm.js} +72 -31
- package/dist/{advanceableErrors-q_pfU3Cn.esm.js → advanceableErrors-k-U-cL5m.esm.js} +1 -2
- package/dist/ae-signature.esm.js +1 -1
- package/dist/antifraud.esm.js +2 -2
- package/dist/{antifraudManager-CaweCYnY.esm.js → antifraudManager-CQ08atTC.esm.js} +2 -2
- package/dist/{antifraudStateMachine-DRl0UVyA.esm.js → antifraudStateMachine-BcsUTTIr.esm.js} +1 -1
- package/dist/{api-Cz90EHyu.esm.js → api-BO8JA7Pf.esm.js} +6 -5
- package/dist/{apiError-B_uY7RO6.esm.js → apiError-CfuIvnUy.esm.js} +1 -1
- package/dist/attemptCarry-BjTJ6bMQ.esm.js +45 -0
- package/dist/authentication.d.ts +3 -3
- package/dist/authentication.esm.js +2 -2
- package/dist/{authenticationManager-BIZC55Bi.d.ts → authenticationManager-C-cOki0Y.d.ts} +1 -1
- package/dist/{authenticationManager-CSHZQTlb.esm.js → authenticationManager-DvmklBTE.esm.js} +5 -5
- package/dist/{authenticationStateMachine-DrO14KyC.esm.js → authenticationStateMachine-BL2ptOA0.esm.js} +3 -3
- package/dist/{backCameraStream-CMvXj4X4.esm.js → backCameraStream-C5_NNfUN.esm.js} +3 -43
- package/dist/{browser-DlFgHpoC-DnyrCR8r.esm.js → browser-pQZA35G2-DtkAf6sn.esm.js} +161 -150
- package/dist/{camera-sIa9ceW2.esm.js → camera-E_Kcre4O.esm.js} +15 -23
- package/dist/camera.esm.js +1 -1
- package/dist/certificate-issuance.esm.js +2 -2
- package/dist/{certificateIssuanceManager-BfeMv2PU.esm.js → certificateIssuanceManager-CM0fuqDC.esm.js} +2 -2
- package/dist/{certificateIssuanceStateMachine-Frgjbjw8.esm.js → certificateIssuanceStateMachine-kksIUOPD.esm.js} +2 -2
- package/dist/cnpj-Co1ottYN.esm.js +77 -0
- package/dist/connectivity-HSl0diCx.esm.js +133 -0
- package/dist/consent.d.ts +1 -1
- package/dist/consent.esm.js +2 -2
- package/dist/{consentManager-CvEu8h_W.esm.js → consentManager-CBwFozhv.esm.js} +4 -3
- package/dist/{consentManager-Cv_0QKLD.d.ts → consentManager-_q9yJUku.d.ts} +14 -7
- package/dist/{consentStateMachine-DJTgN_-1.esm.js → consentStateMachine-CpmRAcr2.esm.js} +20 -7
- package/dist/cross-document-data-match.esm.js +1 -1
- package/dist/{crossDocumentDataMatchManager-Cu141CE8.esm.js → crossDocumentDataMatchManager-64O8t10a.esm.js} +2 -2
- package/dist/curp-validation.d.ts +1 -1
- package/dist/curp-validation.esm.js +2 -2
- package/dist/{curpValidationManager-B-z9q5V3.esm.js → curpValidationManager-CLgJQcx0.esm.js} +3 -2
- package/dist/{curpValidationManager-C9sqoh9n.d.ts → curpValidationManager-CXpFE-Mv.d.ts} +1 -1
- package/dist/{curpValidationStateMachine-vDEFLMPw.esm.js → curpValidationStateMachine-Bx9YhVkJ.esm.js} +28 -20
- package/dist/custom-fields.esm.js +1 -1
- package/dist/custom-watchlist.esm.js +2 -2
- package/dist/{customFieldsManager-D1ex2cFM.esm.js → customFieldsManager-DWt_0YtJ.esm.js} +2 -2
- package/dist/{customWatchlistManager-CTI-SGk0.esm.js → customWatchlistManager-D8o-2Nej.esm.js} +2 -2
- package/dist/{customWatchlistStateMachine-hmRd0f2I.esm.js → customWatchlistStateMachine-Sbi6DIcK.esm.js} +1 -1
- package/dist/{deepsightLoader-DkrG5zbN.esm.js → deepsightLoader-DMxtowCm.esm.js} +6 -28
- package/dist/{deepsightService-BrltL1DF.esm.js → deepsightService-twg3bXqY.esm.js} +20 -59
- package/dist/{createCameraCycleOwnership-Dj_LHUvN.esm.js → desktopCameraElection-kHY2IDJi.esm.js} +177 -40
- package/dist/device.esm.js +2 -2
- package/dist/document-capture.d.ts +2 -2
- package/dist/document-capture.esm.js +2 -2
- package/dist/{documentCaptureManager-DkyDtm3Y.d.ts → documentCaptureManager-6tnnDkMX.d.ts} +14 -2
- package/dist/{documentCaptureManager-DUJwpKC5.esm.js → documentCaptureManager-CMSC_Mhd.esm.js} +26 -19
- package/dist/{documentCaptureStateMachine-B8i7GnLh.esm.js → documentCaptureStateMachine-BCwD5Rto.esm.js} +43 -35
- package/dist/dynamic-forms.d.ts +2 -2
- package/dist/dynamic-forms.esm.js +2 -2
- package/dist/{dynamicFormsManager-C0dHs1ty.d.ts → dynamicFormsManager-9kwY8Bf5.d.ts} +1 -1
- package/dist/{dynamicFormsManager-D7Xnjm7B.esm.js → dynamicFormsManager-DU6W1e20.esm.js} +2 -2
- package/dist/{dynamicFormsStateMachine-Cgk0VPP4.esm.js → dynamicFormsStateMachine-C8Z7k3vo.esm.js} +2 -2
- package/dist/ekyb.d.ts +4 -4
- package/dist/ekyb.esm.js +3 -3
- package/dist/{ekybManager-BaZ_7CEu.d.ts → ekybManager-TB6ZG5lX.d.ts} +2 -2
- package/dist/{ekybManager-yj_Y36jM.esm.js → ekybManager-TGfqyjuu.esm.js} +2 -2
- package/dist/{ekybStateMachine-DIRBMkaD.esm.js → ekybStateMachine-DBgFuEPK.esm.js} +26 -44
- package/dist/ekyc.d.ts +3 -3
- package/dist/ekyc.esm.js +3 -3
- package/dist/{ekycManager-DW-ynodd.d.ts → ekycManager-BSQteIfC.d.ts} +1 -1
- package/dist/{ekycManager-BO-Lui3t.esm.js → ekycManager-C2cgG2Pl.esm.js} +2 -2
- package/dist/ekycStateMachine-CuNF7z4O.esm.js +7505 -0
- package/dist/ekycUtils-BFncpC4F.esm.js +1401 -0
- package/dist/electronic-signature.esm.js +1 -1
- package/dist/{electronicSignatureManager-Btsa7Prh.esm.js → electronicSignatureManager-C7pqXsRm.esm.js} +4 -4
- package/dist/email.esm.js +2 -2
- package/dist/{emailManager-ButFktRm.esm.js → emailManager-FH_CP0cT.esm.js} +2 -2
- package/dist/{emailStateMachine-BXtlC0NV.esm.js → emailStateMachine-Cx-uTaBV.esm.js} +32 -20
- package/dist/{events-Du2A4-Qr.esm.js → events-CQteqXfy.esm.js} +2 -2
- package/dist/events.esm.js +1 -1
- package/dist/extensibility.d.ts +35 -21
- package/dist/extensibility.esm.js +34 -34
- package/dist/{externalFetch-DrR9xshk.esm.js → externalFetch-CQY41QT1.esm.js} +4 -1
- package/dist/face-match.d.ts +1 -1
- package/dist/face-match.esm.js +2 -2
- package/dist/{faceCaptureManagerFactory-1hzeS_rB.d.ts → faceCaptureManagerFactory-C-xKdj-d.d.ts} +71 -66
- package/dist/{faceCaptureManagerFactory-CdDfnyyb.esm.js → faceCaptureManagerFactory-CBm05KnT.esm.js} +4 -4
- package/dist/{faceCaptureSetup-CCucWLdy.esm.js → faceCaptureSetup-BQjCbL51.esm.js} +82 -64
- package/dist/{faceMatchManager-DWFUQjMQ.esm.js → faceMatchManager-B2zp7yP4.esm.js} +2 -2
- package/dist/{faceMatchManager-DIgG-UFS.d.ts → faceMatchManager-Z4UDLwAv.d.ts} +16 -7
- package/dist/{faceMatchStateMachine-CUCvlydD.esm.js → faceMatchStateMachine-ByTMQCUC.esm.js} +40 -27
- package/dist/{feature-management-DCD0I_XZ.esm.js → feature-management-DjAG5lsJ.esm.js} +1 -1
- package/dist/feature-management.esm.js +1 -1
- package/dist/field-comparison.esm.js +1 -1
- package/dist/{fieldComparisonManager-v3knTYV_.esm.js → fieldComparisonManager-CC0vKmpf.esm.js} +2 -2
- package/dist/fiscal-qr.esm.js +1 -1
- package/dist/{fiscalQrManager-Dt9fHG7h.esm.js → fiscalQrManager-Be-r4oZj.esm.js} +4 -4
- package/dist/flow-events.d.ts +1 -1
- package/dist/flow.d.ts +10 -10
- package/dist/flow.esm.js +8 -11
- package/dist/{flowCompletionService-xFODSJEq.esm.js → flowCompletionService-ChMU2v79.esm.js} +2 -2
- package/dist/{flowServices-COMEf-WP.esm.js → flowServices-g2tVWsJl.esm.js} +8 -50
- package/dist/geolocation.d.ts +1 -1
- package/dist/geolocation.esm.js +2 -2
- package/dist/{geolocationManager-Dn24g1fl.d.ts → geolocationManager-6e1i9UIR.d.ts} +15 -17
- package/dist/{geolocationManager-B2C2yfrn.esm.js → geolocationManager-DLbvZwUB.esm.js} +6 -8
- package/dist/{geolocationStateMachine-Dbg9jw62.esm.js → geolocationStateMachine-CAJVongM.esm.js} +12 -8
- package/dist/{getDeviceClass-bsWdEDxP.esm.js → getDeviceClass-DoIWuKI8.esm.js} +1 -1
- package/dist/government-validation.esm.js +2 -2
- package/dist/{governmentValidationManager-BtXWHICu.esm.js → governmentValidationManager-CkX9TEkh.esm.js} +2 -2
- package/dist/{governmentValidationStateMachine-COL-Vs48.esm.js → governmentValidationStateMachine-PTPCP26N.esm.js} +1 -1
- package/dist/home.d.ts +1 -1
- package/dist/home.esm.js +1 -1
- package/dist/http.esm.js +1 -1
- package/dist/id-ocr.esm.js +2 -2
- package/dist/id-selfie-flow.d.ts +1 -1
- package/dist/id-selfie-flow.esm.js +9 -9
- package/dist/id-verification.esm.js +2 -2
- package/dist/id.d.ts +3 -16
- package/dist/id.esm.js +3 -3
- package/dist/{idCaptureDefaults-BGsG2OAs.esm.js → idCaptureDefaults-MSQoqScU.esm.js} +3 -3
- package/dist/{idCaptureManager-0M02hSuC.d.ts → idCaptureManager-DzTfQ1Am.d.ts} +66 -5
- package/dist/{idCaptureManager-DZtgScdd.esm.js → idCaptureManager-zZdTcpG1.esm.js} +63 -17
- package/dist/{idCaptureServices-mpibFz4U.esm.js → idCaptureServices-8OHinO0N.esm.js} +9 -9
- package/dist/{idCaptureStateMachine-DWJOHeGn.esm.js → idCaptureStateMachine-B3G6XoDG.esm.js} +914 -536
- package/dist/{idOcrManager-D3-HNMXP.esm.js → idOcrManager-B64-fjWg.esm.js} +2 -2
- package/dist/{idOcrStateMachine-DyENX6Ki.esm.js → idOcrStateMachine-B1aZnobs.esm.js} +2 -2
- package/dist/{idVerificationManager-iWz7Avkr.esm.js → idVerificationManager-_Kebv-Ue.esm.js} +2 -2
- package/dist/{idVerificationStateMachine-CL1kUdBe.esm.js → idVerificationStateMachine-DQn6c84z.esm.js} +1 -1
- package/dist/identity-reuse.d.ts +1 -1
- package/dist/identity-reuse.esm.js +2 -2
- package/dist/{identityReuseManager-CD1ucp1d.esm.js → identityReuseManager-DDXkNVZi.esm.js} +2 -2
- package/dist/{identityReuseManager-B1birg5X.d.ts → identityReuseManager-ooAbp6Kc.d.ts} +4 -4
- package/dist/{identityReuseStateMachine-DfV81wQC.esm.js → identityReuseStateMachine-Bcnkbjf8.esm.js} +1 -1
- package/dist/{index-BKOWUhxG.d.ts → index-DEfwds5y.d.ts} +55 -8
- package/dist/{index-CKQ9QBZP.d.ts → index-DMDAk85K.d.ts} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/{invokeOnCaptureCallback-DYrkOXO6.esm.js → invokeOnCaptureCallback-CXIBwBeE.esm.js} +1 -1
- package/dist/mandatory-consent.d.ts +2 -2
- package/dist/mandatory-consent.esm.js +2 -2
- package/dist/{mandatoryConsentManager-Cwqx1nK7.esm.js → mandatoryConsentManager-43W5d_8G.esm.js} +4 -3
- package/dist/{mandatoryConsentManager-okPILEru.d.ts → mandatoryConsentManager-xx3mY-xw.d.ts} +13 -6
- package/dist/{mandatoryConsentStateMachine-pXWqAHo_.esm.js → mandatoryConsentStateMachine-CVlgdlnt.esm.js} +20 -7
- package/dist/{multipartRecordingService-CLwrF5wD.esm.js → multipartRecordingService-DMBxHKS2.esm.js} +3 -13
- package/dist/nationalIds-B91f_RuB.esm.js +99 -0
- package/dist/{permissionGuards-gcy3U0SL.esm.js → permissionGuards-B3OPL8Si.esm.js} +1 -1
- package/dist/{permissionServices-Ca-tSNhT.esm.js → permissionServices-DnBAN_hW.esm.js} +4 -4
- package/dist/phone-number.d.ts +7 -1
- package/dist/phone-number.esm.js +15 -2
- package/dist/phone.d.ts +1 -1
- package/dist/phone.esm.js +2 -2
- package/dist/{phoneManager-BO-LTih5.d.ts → phoneManager-6nrJkvkG.d.ts} +5 -0
- package/dist/{phoneManager-KKUq-Vgo.esm.js → phoneManager-C6jut_pz.esm.js} +3 -3
- package/dist/{phoneStateMachine-D2QWS2cu.esm.js → phoneStateMachine-T1-drWfG.esm.js} +37 -25
- package/dist/{phoneValidation-DnBcNUNh.esm.js → phoneValidation-OggtfjRt.esm.js} +1 -2
- package/dist/{platform-DkcRc9JV.esm.js → platform-aPh7gTWh.esm.js} +15 -1
- package/dist/processFaceMatch-BWme3kVV.esm.js +21 -0
- package/dist/qe-signature.esm.js +1 -1
- package/dist/redirect-to-mobile.d.ts +2 -2
- package/dist/redirect-to-mobile.esm.js +2 -2
- package/dist/{redirectToMobileManager-uHW3dyuQ.esm.js → redirectToMobileManager-BJXC6Kx9.esm.js} +4 -3
- package/dist/{redirectToMobileManager-CVsvpVbQ.d.ts → redirectToMobileManager-Dm9ctRCC.d.ts} +3 -1
- package/dist/{redirectToMobileStateMachine-b-H-ipGM.esm.js → redirectToMobileStateMachine-BBMAc2Gb.esm.js} +27 -6
- package/dist/{runChildModule-C09a9ACV.esm.js → runChildModule-DPHTqSdF.esm.js} +3 -3
- package/dist/{sdkVersion-xE2xE2_9.esm.js → sdkVersion-C3_P-Qbq.esm.js} +1 -1
- package/dist/selfie.d.ts +4 -4
- package/dist/selfie.esm.js +10 -10
- package/dist/{selfieErrorUtils-CoXIxVCy.esm.js → selfieErrorUtils-BL0BLMnp.esm.js} +1 -1
- package/dist/{selfieManager-BJdNu_nd.d.ts → selfieManager-BMmpUii2.d.ts} +1 -1
- package/dist/{selfieManager-RcVUu1KJ.esm.js → selfieManager-Cbliomv7.esm.js} +5 -5
- package/dist/{selfieStateMachine-nWbIRIBD.esm.js → selfieStateMachine-B5m_Kn0O.esm.js} +3 -3
- package/dist/{session-Cr4IVgYu.esm.js → session-DAaAewMX.esm.js} +77 -9
- package/dist/session.d.ts +96 -10
- package/dist/session.esm.js +7 -6
- package/dist/{sessionInitializer-c3CChZts.esm.js → sessionInitializer-CWFT4dfw.esm.js} +402 -202
- package/dist/{setup-BvKrAlOo.esm.js → setup-CDAKwTr7.esm.js} +32 -19
- package/dist/{setup-YPKTUCY5.d.ts → setup-D9qt8YVU.d.ts} +2 -2
- package/dist/signature.esm.js +2 -2
- package/dist/{signatureManager-f_dPAGXn.esm.js → signatureManager-BeEVCcsC.esm.js} +2 -2
- package/dist/{signatureStateMachine-C-nUq_oq.esm.js → signatureStateMachine-_1c1vSid.esm.js} +1 -1
- package/dist/{stats-BEvexnKC.esm.js → stats-BpMz-hTP.esm.js} +1 -1
- package/dist/stats.esm.js +1 -1
- package/dist/{tri-xzRLIIMN.esm.js → tri-BajQnjbf.esm.js} +142 -8
- package/dist/tri.d.ts +1 -1
- package/dist/tri.esm-CzTNi5Q_.esm.js +3826 -0
- package/dist/tri.esm.js +1 -1
- package/dist/{trueSightService-BAvhAU7T.esm.js → trueSightService-BujtUIW6.esm.js} +19 -10
- package/dist/trust-graph.esm.js +1 -1
- package/dist/{types-yPH8lAH-.d.ts → types--3HDl2SF.d.ts} +2 -2
- package/dist/types-B2FK_wYb.d.ts +249 -0
- package/dist/types-B9C8W01q.d.ts +34 -0
- package/dist/{types-0L-eFDmr.d.ts → types-C397LhmN.d.ts} +1 -1
- package/dist/types-D9r3zRfY.d.ts +6 -0
- package/dist/{types-DPIDuhut.d.ts → types-DNVzoRvi.d.ts} +2 -1
- package/dist/{types-B6HsSzpk.d.ts → types-DuD8TRJU.d.ts} +3 -2
- package/dist/{types-Ckir_BEs.d.ts → types-PTZHRhGX.d.ts} +1 -1
- package/dist/{types-DUnFZ08M.d.ts → types-ZTZelfbM.d.ts} +2 -2
- package/dist/{types-CK8Jbjkp.d.ts → types-e8fCsvvk.d.ts} +1 -1
- package/dist/{types-BAxn7MpY.d.ts → types-xEEWCx1j.d.ts} +123 -48
- package/dist/{urlUtils-6jsE6rKp.esm.js → urlUtils-eYiyWjh0.esm.js} +4 -1
- package/dist/video-selfie.d.ts +8 -8
- package/dist/video-selfie.esm.js +95 -22
- package/dist/{videoSelfieCameraWarmer-LeE2vbAW.esm.js → videoSelfieCameraWarmer-DjkPpoj_.esm.js} +18 -21
- package/dist/{videoSelfieStepDetector-CGsTltqB.d.ts → videoSelfieStepDetector-RfSmlFFW.d.ts} +9 -4
- package/dist/{warmup-BElYWRh7.esm.js → warmup-BkfxQZsC.esm.js} +175 -11
- package/dist/wasm.d.ts +2 -2
- package/dist/wasm.esm.js +3 -3
- package/dist/{wasmDsFlagSync-CYj5LL9z.esm.js → wasmDsFlagSync-BhU5H2oR.esm.js} +1 -1
- package/dist/wasmMetadataVersionSync-U8EFUr1T.esm.js +27 -0
- package/dist/{wasmWebClient-BjZw_7OB.esm.js → wasmWebClient-DTj9auyA.esm.js} +43 -17
- package/dist/watchlist-for-business.d.ts +2 -1
- package/dist/watchlist-for-business.esm.js +2 -2
- package/dist/watchlist.esm.js +2 -2
- package/dist/{watchlistForBusinessManager-CZZOFkGl.esm.js → watchlistForBusinessManager-CVay6-9A.esm.js} +37 -7
- package/dist/{watchlistForBusinessManager-B3GDPZrr.d.ts → watchlistForBusinessManager-DX2AyM4Y.d.ts} +54 -18
- package/dist/watchlistForBusinessStateMachine-DA6K5na4.esm.js +166 -0
- package/dist/{watchlistManager-DXtX94SN.esm.js → watchlistManager-B8gQ_rw3.esm.js} +2 -2
- package/dist/{watchlistStateMachine-McALifag.esm.js → watchlistStateMachine-CSi_ZhtT.esm.js} +1 -1
- package/dist/workflow.d.ts +5 -2
- package/dist/workflow.esm.js +57 -47
- package/package.json +3 -2
- package/dist/IBrowserEnvironmentCapability-DEaRRk-R.esm.js +0 -9
- package/dist/ekycStateMachine-CDnI_NRq.esm.js +0 -1443
- package/dist/ekycUtils-zY8CdKJL.esm.js +0 -300
- package/dist/thumbmark.esm-CRc0cYvz.esm.js +0 -1242
- package/dist/tri.esm-BIjHhBJ2.esm.js +0 -2620
- package/dist/types-BvLo3U4u.d.ts +0 -134
- package/dist/types-zOgZqMni.d.ts +0 -6
- package/dist/watchlistForBusinessStateMachine-B66E7jud.esm.js +0 -78
- /package/dist/{types-BSBzhHRH2.d.ts → types-BSBzhHRH.d.ts} +0 -0
package/dist/{idCaptureStateMachine-DWJOHeGn.esm.js → idCaptureStateMachine-B3G6XoDG.esm.js}
RENAMED
|
@@ -1,32 +1,33 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { l as isGoogleWalletSignedRequestsEnabled, u as BrowserStorageProvider } from "./setup-
|
|
3
|
-
import { t as WasmUtilProvider } from "./WasmUtilProvider-
|
|
4
|
-
import { n as eventModuleNames, o as createManagerInstrumentation, s as recordExperimentAssignmentOnce, y as addEvent } from "./events-
|
|
5
|
-
import { r as getToken, t as api, u as endpoints } from "./api-
|
|
6
|
-
import { l as trueSightHintTransition, r as noteTrueSightCaptureActivity, u as trueSightLog, y as isTrueSightTesting } from "./trueSightService-
|
|
7
|
-
import { t as getDisableIpify } from "./sessionInitializer-
|
|
1
|
+
import { n as getTimestamp, r as revokeObjectURL } from "./IBrowserEnvironmentCapability-D7JG7ML3.esm.js";
|
|
2
|
+
import { l as isGoogleWalletSignedRequestsEnabled, t as ensureWasmPipelines, u as BrowserStorageProvider } from "./setup-CDAKwTr7.esm.js";
|
|
3
|
+
import { t as WasmUtilProvider } from "./WasmUtilProvider-GTkoJyFY.esm.js";
|
|
4
|
+
import { n as eventModuleNames, o as createManagerInstrumentation, s as recordExperimentAssignmentOnce, y as addEvent } from "./events-CQteqXfy.esm.js";
|
|
5
|
+
import { r as getToken, t as api, u as endpoints } from "./api-BO8JA7Pf.esm.js";
|
|
6
|
+
import { l as trueSightHintTransition, r as noteTrueSightCaptureActivity, u as trueSightLog, y as isTrueSightTesting } from "./trueSightService-BujtUIW6.esm.js";
|
|
7
|
+
import { t as getDisableIpify } from "./sessionInitializer-CWFT4dfw.esm.js";
|
|
8
8
|
import { t as BrowserTimerProvider } from "./BrowserTimerProvider-BXhgNxLt.esm.js";
|
|
9
|
-
import { s as exposeExperimentOnce } from "./feature-management-
|
|
10
|
-
import { t as addDeviceStats } from "./stats-
|
|
11
|
-
import { a as isIOS, s as isIPad, t as isAndroid, u as isMacOsSafari } from "./platform-
|
|
12
|
-
import "./session-
|
|
9
|
+
import { s as exposeExperimentOnce } from "./feature-management-DjAG5lsJ.esm.js";
|
|
10
|
+
import { t as addDeviceStats } from "./stats-BpMz-hTP.esm.js";
|
|
11
|
+
import { a as isIOS, c as isIPhone14OrHigher, f as isSamsungDevice, s as isIPad, t as isAndroid, u as isMacOsSafari } from "./platform-aPh7gTWh.esm.js";
|
|
12
|
+
import "./session-DAaAewMX.esm.js";
|
|
13
13
|
import { c as not, i as assign, l as raise, n as enqueueActions, o as and, r as sendTo, s as createActor, t as setup, u as createManager } from "./xstate.esm-DSajW7CJ.esm.js";
|
|
14
14
|
import { n as fromPromise, t as fromCallback } from "./xstate-actors.esm-8Gzepa_A.esm.js";
|
|
15
|
-
import { n as getUrlSearchParam, t as buildUrlWithSearchParams } from "./urlUtils-
|
|
16
|
-
import {
|
|
17
|
-
import { i as requestMotionPermission, n as invokeRequestPermissionActor, o as requiresMotionPermissionUserGesture, t as checkPermission } from "./permissionServices-
|
|
18
|
-
import {
|
|
15
|
+
import { n as getUrlSearchParam, t as buildUrlWithSearchParams } from "./urlUtils-eYiyWjh0.esm.js";
|
|
16
|
+
import { s as isCameraDenialErrorName } from "./camera-E_Kcre4O.esm.js";
|
|
17
|
+
import { i as requestMotionPermission, n as invokeRequestPermissionActor, o as requiresMotionPermissionUserGesture, t as checkPermission, u as queryPermission } from "./permissionServices-DnBAN_hW.esm.js";
|
|
18
|
+
import { i as cameraCycleProvider, n as createCameraCycleOwnership, o as flagIdManualReview, r as runProtectedAttempt, s as PROTECTED_CAPTURE_TARGET, t as electDesktopCameraDevice } from "./desktopCameraElection-kHY2IDJi.esm.js";
|
|
19
19
|
import { t as IncodeCanvas } from "./canvas-BxFzWTt-.esm.js";
|
|
20
|
-
import { n as needsMotionPrimeOnlyFromPermission, r as resolveStoredPermissionResult, t as isReadyForCaptureFromPermission } from "./permissionGuards-
|
|
21
|
-
import {
|
|
20
|
+
import { n as needsMotionPrimeOnlyFromPermission, r as resolveStoredPermissionResult, t as isReadyForCaptureFromPermission } from "./permissionGuards-B3OPL8Si.esm.js";
|
|
21
|
+
import { t as carryAttempts } from "./attemptCarry-BjTJ6bMQ.esm.js";
|
|
22
|
+
import { o as StreamCanvasProcessingSession } from "./multipartRecordingService-DMBxHKS2.esm.js";
|
|
22
23
|
import { t as sleep } from "./ITimerCapability-DgdDzp8G.esm.js";
|
|
23
24
|
import { t as getBrowser } from "./getBrowser-Cbe1C4Tn.esm.js";
|
|
24
|
-
import {
|
|
25
|
+
import { r as isBackCameraLabel } from "./backCameraStream-C5_NNfUN.esm.js";
|
|
25
26
|
import { n as getWindowDimensions } from "./getDeviceClass-CeBiEayS.esm.js";
|
|
26
|
-
import { n as frameSources, r as runVirtualCameraCheck } from "./deepsightService-
|
|
27
|
-
import { t as getDeviceClass } from "./getDeviceClass-
|
|
28
|
-
import { n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider } from "./idCaptureDefaults-
|
|
29
|
-
import { C as getIdCameraStream, S as OPTIMIZING_WATCHDOG_MARGIN_MS, _ as ID_ERROR_CODES, a as getRealQualityValue, b as resolveIdCaptureThresholds, c as pauseRecordingForAttempt, d as resumeRecordingAfterPause, f as startRecordingSession, g as validateUploadResponse, h as uploadIdImage, i as finalizeRecordingSession, l as prepareRecordingForCameraRetry, m as stopStream, o as initializeIdCapture, p as stopRecording, r as disposeRecordingSession, s as isSuspendableRecordingSession, t as addBarcode, u as processId, x as CAPTURE_OPTIMIZING, y as resolveCountdownStepMs } from "./idCaptureServices-
|
|
27
|
+
import { n as frameSources, r as runVirtualCameraCheck } from "./deepsightService-twg3bXqY.esm.js";
|
|
28
|
+
import { t as getDeviceClass } from "./getDeviceClass-DoIWuKI8.esm.js";
|
|
29
|
+
import { n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider } from "./idCaptureDefaults-MSQoqScU.esm.js";
|
|
30
|
+
import { C as getIdCameraStream, S as OPTIMIZING_WATCHDOG_MARGIN_MS, _ as ID_ERROR_CODES, a as getRealQualityValue, b as resolveIdCaptureThresholds, c as pauseRecordingForAttempt, d as resumeRecordingAfterPause, f as startRecordingSession, g as validateUploadResponse, h as uploadIdImage, i as finalizeRecordingSession, l as prepareRecordingForCameraRetry, m as stopStream, o as initializeIdCapture, p as stopRecording, r as disposeRecordingSession, s as isSuspendableRecordingSession, t as addBarcode, u as processId, x as CAPTURE_OPTIMIZING, y as resolveCountdownStepMs } from "./idCaptureServices-8OHinO0N.esm.js";
|
|
30
31
|
import { t as StreamCanvasCapture } from "./StreamCanvasCapture-C9jtgBdT.esm.js";
|
|
31
32
|
//#region src/modules/id/digitalUpload/digitalUploadErrors.ts
|
|
32
33
|
const TERMINAL_FAIL_REASONS = /* @__PURE__ */ new Set(["DIGITAL_ID_REQUESTED_BUT_OTHER_PROVIDED", "ID_TYPE_UNACCEPTABLE"]);
|
|
@@ -550,7 +551,36 @@ const deviceWalletMachine = setup({
|
|
|
550
551
|
function resolveWalletPlatform(provider) {
|
|
551
552
|
if (provider === "apple_web") return "ios";
|
|
552
553
|
if (provider === "google") return "android";
|
|
553
|
-
return
|
|
554
|
+
return isApplePlatform() ? "ios" : "android";
|
|
555
|
+
}
|
|
556
|
+
/** iOS / iPadOS / macOS Safari — the only platforms Apple Wallet web runs on. */
|
|
557
|
+
function isApplePlatform() {
|
|
558
|
+
return isIOS() || isMacOsSafari() || isIPad();
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* The wallet family this device *certainly* reaches, for naming it in the UI:
|
|
562
|
+
* `apple` on the Apple platform, `samsung` on a detectable Samsung Android
|
|
563
|
+
* device, `android` on any other Android device. `undefined` when the OS gives
|
|
564
|
+
* no certain answer (desktop Chrome, Windows, Linux). Unlike
|
|
565
|
+
* `resolveWalletPlatform`, which must pick a handshake and so maps every
|
|
566
|
+
* non-Apple browser to Google, this does not guess.
|
|
567
|
+
*/
|
|
568
|
+
function resolveWalletDevice() {
|
|
569
|
+
if (isApplePlatform()) return "apple";
|
|
570
|
+
if (isAndroid()) return isSamsungDevice() ? "samsung" : "android";
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* The device facts the digital-ID funnel filters wallets on: Credentials API
|
|
574
|
+
* availability, the OS wallet the device reaches (the same answer the
|
|
575
|
+
* handshake later launches with) and whether it is a Samsung device.
|
|
576
|
+
* No injected capability reads as "no Credentials API".
|
|
577
|
+
*/
|
|
578
|
+
function getDigitalIdPlatformSupport(credentials) {
|
|
579
|
+
return {
|
|
580
|
+
credentialsAvailable: credentials?.isAvailable() ?? false,
|
|
581
|
+
walletPlatform: resolveWalletPlatform(),
|
|
582
|
+
samsungDevice: isSamsungDevice()
|
|
583
|
+
};
|
|
554
584
|
}
|
|
555
585
|
//#endregion
|
|
556
586
|
//#region src/modules/id/deviceWallet/instrumentation.ts
|
|
@@ -769,6 +799,580 @@ function renderWallet({ onSuccess, onError, ...actorOptions }) {
|
|
|
769
799
|
});
|
|
770
800
|
}
|
|
771
801
|
//#endregion
|
|
802
|
+
//#region src/modules/id/digitalIdCountry.ts
|
|
803
|
+
/** Longest the chooser waits for country signals before rendering. */
|
|
804
|
+
const DIGITAL_ID_COUNTRY_DETECTION_TIMEOUT_MS = 1e3;
|
|
805
|
+
/** Upper-cased ISO 3166-1 alpha-2, or `undefined` for anything else. */
|
|
806
|
+
function normalizeCountryCode(value) {
|
|
807
|
+
if (typeof value !== "string") return;
|
|
808
|
+
const code = value.trim().toUpperCase();
|
|
809
|
+
return /^[A-Z]{2}$/.test(code) ? code : void 0;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* The region subtags of BCP 47 language tags, in order, deduped. Tags without
|
|
813
|
+
* an explicit alpha-2 region (`sv`, `es-419`) or that do not parse contribute
|
|
814
|
+
* nothing — a bare language is not a country.
|
|
815
|
+
*/
|
|
816
|
+
function getLocaleRegions(tags) {
|
|
817
|
+
const regions = [];
|
|
818
|
+
for (const tag of tags) {
|
|
819
|
+
let region;
|
|
820
|
+
try {
|
|
821
|
+
region = new Intl.Locale(tag).region;
|
|
822
|
+
} catch {
|
|
823
|
+
region = void 0;
|
|
824
|
+
}
|
|
825
|
+
const code = normalizeCountryCode(region);
|
|
826
|
+
if (code && !regions.includes(code)) regions.push(code);
|
|
827
|
+
}
|
|
828
|
+
return regions;
|
|
829
|
+
}
|
|
830
|
+
/** Whether any signal is wired at all (otherwise detection is a no-op). */
|
|
831
|
+
function hasCountrySignals(dependencies) {
|
|
832
|
+
if (!dependencies) return false;
|
|
833
|
+
return dependencies.ipCountry !== void 0 || dependencies.locale !== void 0 || dependencies.geolocation !== void 0 && dependencies.reverseGeocodeCountry !== void 0;
|
|
834
|
+
}
|
|
835
|
+
async function detectGpsCountry(dependencies, signal) {
|
|
836
|
+
const { geolocation, reverseGeocodeCountry } = dependencies;
|
|
837
|
+
if (!geolocation || !reverseGeocodeCountry) return;
|
|
838
|
+
if (await queryPermission("geolocation") !== "granted") return;
|
|
839
|
+
return reverseGeocodeCountry(await geolocation.getCurrentPosition(), signal);
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Region subtags of the browser languages. A locale capability that throws
|
|
843
|
+
* (e.g. a custom one) is dropped like any other failing signal, so detection
|
|
844
|
+
* still never rejects.
|
|
845
|
+
*/
|
|
846
|
+
function readLocaleRegions(locale) {
|
|
847
|
+
if (!locale) return [];
|
|
848
|
+
try {
|
|
849
|
+
return getLocaleRegions(locale.getPreferredLanguages());
|
|
850
|
+
} catch {
|
|
851
|
+
return [];
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Collects the country signals and returns their countries, strongest first,
|
|
856
|
+
* deduped (see the module doc for the order). Never rejects: a failing or
|
|
857
|
+
* late signal is dropped.
|
|
858
|
+
*/
|
|
859
|
+
async function detectDigitalIdCountries(dependencies, options = {}) {
|
|
860
|
+
const { timeoutMs = DIGITAL_ID_COUNTRY_DETECTION_TIMEOUT_MS, signal } = options;
|
|
861
|
+
const timer = BrowserTimerProvider.getInstance();
|
|
862
|
+
let deadlineHandle;
|
|
863
|
+
const deadline = new Promise((resolve) => {
|
|
864
|
+
deadlineHandle = timer.setTimeout(() => resolve(void 0), timeoutMs);
|
|
865
|
+
});
|
|
866
|
+
const settle = (run) => Promise.race([Promise.resolve().then(run).catch(() => void 0), deadline]);
|
|
867
|
+
try {
|
|
868
|
+
const [gpsCountry, ipCountry] = await Promise.all([settle(() => detectGpsCountry(dependencies, signal)), settle(() => dependencies.ipCountry ? dependencies.ipCountry(signal) : Promise.resolve(void 0))]);
|
|
869
|
+
const localeRegions = readLocaleRegions(dependencies.locale);
|
|
870
|
+
const countries = [];
|
|
871
|
+
for (const candidate of [
|
|
872
|
+
gpsCountry,
|
|
873
|
+
ipCountry,
|
|
874
|
+
...localeRegions
|
|
875
|
+
]) {
|
|
876
|
+
const code = normalizeCountryCode(candidate);
|
|
877
|
+
if (code && !countries.includes(code)) countries.push(code);
|
|
878
|
+
}
|
|
879
|
+
return countries;
|
|
880
|
+
} finally {
|
|
881
|
+
if (deadlineHandle !== void 0) timer.clearTimeout(deadlineHandle);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
//#endregion
|
|
885
|
+
//#region src/modules/id/digitalIdRegistry.ts
|
|
886
|
+
/**
|
|
887
|
+
* True when a digital-ID method uses a full-page web-redirect flow (Trinsic
|
|
888
|
+
* iDIN, FTN, itsme, …). Accepts both the module `FlowType` value (`REDIRECT`) and the
|
|
889
|
+
* backend value (`WEB_REDIRECT`). (Lives here rather than in
|
|
890
|
+
* `idCaptureHelpers` to keep the registry free of circular imports; the
|
|
891
|
+
* helpers re-export it.)
|
|
892
|
+
*/
|
|
893
|
+
function isRedirectFlowType(flowType) {
|
|
894
|
+
return flowType === "REDIRECT" || flowType === "WEB_REDIRECT";
|
|
895
|
+
}
|
|
896
|
+
const DIGITAL_ID_REGISTRY = {
|
|
897
|
+
mDL: [{
|
|
898
|
+
kind: "incodeWallet",
|
|
899
|
+
documentType: "digitalId"
|
|
900
|
+
}, {
|
|
901
|
+
kind: "trinsicRedirect",
|
|
902
|
+
documentType: "digitalIdRedirect",
|
|
903
|
+
providerId: "trinsic_mdl_placeholder",
|
|
904
|
+
method: "MDL"
|
|
905
|
+
}],
|
|
906
|
+
iDIN: [{
|
|
907
|
+
kind: "trinsicRedirect",
|
|
908
|
+
documentType: "digitalIdRedirect",
|
|
909
|
+
providerId: "trinsic_netherlands_idin",
|
|
910
|
+
method: "IDIN",
|
|
911
|
+
countries: ["NL"]
|
|
912
|
+
}],
|
|
913
|
+
FTN: [{
|
|
914
|
+
kind: "trinsicRedirect",
|
|
915
|
+
documentType: "digitalIdRedirect",
|
|
916
|
+
providerId: "trinsic_finnish_trust_network",
|
|
917
|
+
method: "FTN",
|
|
918
|
+
countries: ["FI"]
|
|
919
|
+
}],
|
|
920
|
+
itsme: [{
|
|
921
|
+
kind: "trinsicRedirect",
|
|
922
|
+
documentType: "digitalIdRedirect",
|
|
923
|
+
providerId: "trinsic_belgium_itsme",
|
|
924
|
+
method: "ITSME",
|
|
925
|
+
countries: ["BE"]
|
|
926
|
+
}],
|
|
927
|
+
SPID: [{
|
|
928
|
+
kind: "trinsicRedirect",
|
|
929
|
+
documentType: "digitalIdRedirect",
|
|
930
|
+
providerId: "trinsic_italy_spid",
|
|
931
|
+
method: "SPID",
|
|
932
|
+
countries: ["IT"]
|
|
933
|
+
}],
|
|
934
|
+
MitID: [{
|
|
935
|
+
kind: "trinsicRedirect",
|
|
936
|
+
documentType: "digitalIdRedirect",
|
|
937
|
+
providerId: "trinsic_denmark_mitid",
|
|
938
|
+
method: "MITID",
|
|
939
|
+
countries: ["DK"]
|
|
940
|
+
}],
|
|
941
|
+
BankIDSweden: [{
|
|
942
|
+
kind: "trinsicRedirect",
|
|
943
|
+
documentType: "digitalIdRedirect",
|
|
944
|
+
providerId: "trinsic_sweden_bankid",
|
|
945
|
+
method: "BANKID_SWEDEN",
|
|
946
|
+
countries: ["SE"]
|
|
947
|
+
}],
|
|
948
|
+
FranceIdentite: [{
|
|
949
|
+
kind: "trinsicRedirect",
|
|
950
|
+
documentType: "digitalIdRedirect",
|
|
951
|
+
providerId: "trinsic_france_identite",
|
|
952
|
+
method: "FRANCE_IDENTITE",
|
|
953
|
+
countries: ["FR"]
|
|
954
|
+
}],
|
|
955
|
+
IdentiteNumerique: [{
|
|
956
|
+
kind: "trinsicRedirect",
|
|
957
|
+
documentType: "digitalIdRedirect",
|
|
958
|
+
providerId: "trinsic_france_identite_numerique",
|
|
959
|
+
method: "IDENTITE_NUMERIQUE",
|
|
960
|
+
countries: ["FR"]
|
|
961
|
+
}],
|
|
962
|
+
LAWallet: [{
|
|
963
|
+
kind: "trinsicRedirect",
|
|
964
|
+
documentType: "digitalIdRedirect",
|
|
965
|
+
providerId: "trinsic_usa_louisiana_wallet",
|
|
966
|
+
method: "LA_WALLET",
|
|
967
|
+
countries: ["US"]
|
|
968
|
+
}],
|
|
969
|
+
DigiLocker: [{
|
|
970
|
+
kind: "trinsicRedirect",
|
|
971
|
+
documentType: "digitalIdRedirect",
|
|
972
|
+
providerId: "trinsic_india_digilocker_aadhaar",
|
|
973
|
+
method: "DIGILOCKER",
|
|
974
|
+
countries: ["IN"]
|
|
975
|
+
}]
|
|
976
|
+
};
|
|
977
|
+
const DIGITAL_ID_DOCUMENT_TYPES = Object.keys(DIGITAL_ID_REGISTRY);
|
|
978
|
+
/**
|
|
979
|
+
* Single place that widens `config.digitalIds` to the shapes the backend
|
|
980
|
+
* actually sends — the mapped array or the raw `{ enabled, methods }` object.
|
|
981
|
+
* Shared so the cast is written once.
|
|
982
|
+
*/
|
|
983
|
+
function asDigitalIdsConfig(config) {
|
|
984
|
+
return config.digitalIds;
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* TODO(test-only): the identity network's test-environment mock providers, one per
|
|
988
|
+
* integration type, for E2E testing — remove before production. Persisted method →
|
|
989
|
+
* provider id only: they are standalone redirect cards, never part of a wallet
|
|
990
|
+
* funnel, so they need no `DigitalIdDocumentType` / `DIGITAL_ID_REGISTRY` entry and
|
|
991
|
+
* stay off the public API. Like every redirect method they render a card only
|
|
992
|
+
* when a flow enables the method in `digitalIds.methods`.
|
|
993
|
+
*/
|
|
994
|
+
const TEST_MOCK_REDIRECT_PROVIDER_BY_METHOD = {
|
|
995
|
+
TRINSIC_TEST_REDIRECT: "trinsic_trinsic_test_redirect",
|
|
996
|
+
TRINSIC_TEST_DELAYED_RESULTS: "trinsic_trinsic_test_delayed_results",
|
|
997
|
+
TRINSIC_TEST_SUB_PROVIDERS: "trinsic_trinsic_test_sub_providers",
|
|
998
|
+
TRINSIC_TEST_DEEPLINK: "trinsic_trinsic_test_deeplink",
|
|
999
|
+
TRINSIC_TEST_DEEPLINK_REFRESH: "trinsic_trinsic_test_deeplink_refresh",
|
|
1000
|
+
TRINSIC_TEST_SHOW_CONTENT: "trinsic_trinsic_test_show_content",
|
|
1001
|
+
TRINSIC_TEST_SHOW_CONTENT_REFRESH: "trinsic_trinsic_test_show_content_refresh",
|
|
1002
|
+
TRINSIC_TEST_HANDOFF: "trinsic_trinsic_test_handoff",
|
|
1003
|
+
TRINSIC_TEST_OFFLINE: "trinsic_trinsic_test_offline",
|
|
1004
|
+
TRINSIC_MOCK_OUTPUT: "trinsic_trinsic_mock_output"
|
|
1005
|
+
};
|
|
1006
|
+
/**
|
|
1007
|
+
* Persisted method name → catalog provider id, derived from the registry's
|
|
1008
|
+
* Trinsic entries (single source of truth). Lets the SDK launch iDIN / FTN
|
|
1009
|
+
* from a backend that does not yet send `providerId` on each method.
|
|
1010
|
+
* TODO(roadmap: fully-catalog-driven): remove once every backend enriches
|
|
1011
|
+
* `digitalIds.methods[]` with `providerId` + `flowType`.
|
|
1012
|
+
*/
|
|
1013
|
+
const REDIRECT_PROVIDER_BY_METHOD = (() => {
|
|
1014
|
+
const map = { ...TEST_MOCK_REDIRECT_PROVIDER_BY_METHOD };
|
|
1015
|
+
for (const docType of DIGITAL_ID_DOCUMENT_TYPES) for (const entry of DIGITAL_ID_REGISTRY[docType]) if (entry.kind === "trinsicRedirect") map[entry.method] = entry.providerId;
|
|
1016
|
+
return map;
|
|
1017
|
+
})();
|
|
1018
|
+
/**
|
|
1019
|
+
* Catalog provider id → the countries it serves, from the registry. Lets the
|
|
1020
|
+
* chooser rank redirect providers by country even when the backend does not enrich
|
|
1021
|
+
* `digitalIds.methods[]` with `countries`.
|
|
1022
|
+
*/
|
|
1023
|
+
const REDIRECT_PROVIDER_COUNTRIES = Object.fromEntries(DIGITAL_ID_DOCUMENT_TYPES.flatMap((docType) => DIGITAL_ID_REGISTRY[docType].flatMap((entry) => entry.kind === "trinsicRedirect" && entry.countries ? [[entry.providerId, entry.countries]] : [])));
|
|
1024
|
+
/**
|
|
1025
|
+
* Redirect providers that are the fallback leg of a wallet-first funnel
|
|
1026
|
+
* (mDL): they are reached through the `digitalId` tile's funnel resolution,
|
|
1027
|
+
* not offered as a standalone chooser card.
|
|
1028
|
+
*/
|
|
1029
|
+
const WALLET_FUNNEL_REDIRECT_PROVIDER_IDS = new Set(DIGITAL_ID_DOCUMENT_TYPES.flatMap((docType) => {
|
|
1030
|
+
const entries = DIGITAL_ID_REGISTRY[docType];
|
|
1031
|
+
if (!entries.some((entry) => entry.kind === "incodeWallet")) return [];
|
|
1032
|
+
return entries.flatMap((entry) => entry.kind === "trinsicRedirect" ? [entry.providerId] : []);
|
|
1033
|
+
}));
|
|
1034
|
+
/**
|
|
1035
|
+
* True for a redirect provider that gets its own chooser card (iDIN, FTN, any
|
|
1036
|
+
* catalog-enriched redirect method) — as opposed to the mDL wallet fallback,
|
|
1037
|
+
* which only surfaces through the Digital ID tile.
|
|
1038
|
+
*/
|
|
1039
|
+
function isStandaloneRedirectProvider(providerId) {
|
|
1040
|
+
return !WALLET_FUNNEL_REDIRECT_PROVIDER_IDS.has(providerId);
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* The provider id a configured method launches with, when it is a
|
|
1044
|
+
* web-redirect method; `undefined` for wallets / other flow shapes.
|
|
1045
|
+
*
|
|
1046
|
+
* Resolution order:
|
|
1047
|
+
* 1. an explicit redirect `flowType` with a `provider` (mapped shape) or
|
|
1048
|
+
* `providerId` (catalog-enriched raw shape) — backend-authoritative;
|
|
1049
|
+
* 2. otherwise the persisted method name via the registry (legacy raw shape).
|
|
1050
|
+
*/
|
|
1051
|
+
function resolveRedirectProviderId(method) {
|
|
1052
|
+
if (method.flowType) {
|
|
1053
|
+
if (!isRedirectFlowType(method.flowType)) return;
|
|
1054
|
+
const explicit = method.provider ?? method.providerId;
|
|
1055
|
+
if (explicit) return explicit;
|
|
1056
|
+
}
|
|
1057
|
+
return method.method ? REDIRECT_PROVIDER_BY_METHOD[method.method.toUpperCase()] : void 0;
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Tolerant view over `config.digitalIds`: accepts both the mapped array
|
|
1061
|
+
* (`IdCaptureDigitalIdMethod[]`) and the raw backend object
|
|
1062
|
+
* (`{ enabled, methods: [...] }`). Extracted from the old
|
|
1063
|
+
* `getDigitalIdRedirectMethod` cast so every consumer parses it the same way.
|
|
1064
|
+
*
|
|
1065
|
+
* Honors both dashboard toggles: a raw object with `enabled: false` yields no
|
|
1066
|
+
* methods, and individual methods with `enabled: false` are dropped (absent
|
|
1067
|
+
* `enabled` counts as on). This is what "enabled for the flow / workflow"
|
|
1068
|
+
* means — for the redirect chooser cards as much as for the wallet tile.
|
|
1069
|
+
*/
|
|
1070
|
+
function normalizeDigitalIdMethods(config) {
|
|
1071
|
+
const raw = asDigitalIdsConfig(config);
|
|
1072
|
+
if (!Array.isArray(raw) && raw?.enabled === false) return [];
|
|
1073
|
+
return (Array.isArray(raw) ? raw : raw?.methods ?? []).filter((method) => method.enabled !== false);
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Persisted method names of the Incode-native device wallets — the backend
|
|
1077
|
+
* `DigitalIdMethodCatalog` entries of type `MDL`. A catalog-enriched method
|
|
1078
|
+
* carries `type: 'MDL'` instead of relying on the name; both are honoured.
|
|
1079
|
+
*
|
|
1080
|
+
* `SAMSUNG_WALLET` is listed by name because the onboarding catalog does not
|
|
1081
|
+
* enrich it yet: it arrives as a bare `{ method: 'SAMSUNG_WALLET' }`. Without
|
|
1082
|
+
* the name it would fall through to the unfiltered `deviceWallet` flag and
|
|
1083
|
+
* skip `WALLET_PLATFORM_RULES`' Samsung-only rule.
|
|
1084
|
+
*/
|
|
1085
|
+
const DEVICE_WALLET_METHODS = /* @__PURE__ */ new Set([
|
|
1086
|
+
"APPLE_WALLET",
|
|
1087
|
+
"GOOGLE_WALLET",
|
|
1088
|
+
"CA_DMV_WALLET",
|
|
1089
|
+
"SAMSUNG_WALLET"
|
|
1090
|
+
]);
|
|
1091
|
+
/**
|
|
1092
|
+
* True for a configured method the native device-wallet handshake can fulfil.
|
|
1093
|
+
* Redirect methods (iDIN, FTN) never count, whatever their name or type — they
|
|
1094
|
+
* must not surface a wallet tile with no wallet behind it.
|
|
1095
|
+
*
|
|
1096
|
+
* Classifies by *kind* only. Whether a method is switched on is already
|
|
1097
|
+
* settled by `normalizeDigitalIdMethods`, which drops disabled methods before
|
|
1098
|
+
* any caller walks the list.
|
|
1099
|
+
*/
|
|
1100
|
+
function isDeviceWalletMethod(method) {
|
|
1101
|
+
if (method.flowType && isRedirectFlowType(method.flowType)) return false;
|
|
1102
|
+
if (method.type?.toUpperCase() === "MDL") return true;
|
|
1103
|
+
return method.method !== void 0 && DEVICE_WALLET_METHODS.has(method.method.toUpperCase());
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Device-level hard filter per wallet method: a wallet the device cannot reach
|
|
1107
|
+
* is never offered. Apple Wallet needs the Apple platform, Google Wallet any
|
|
1108
|
+
* other, and Samsung Wallet a Samsung device. Methods without a rule (CA DMV
|
|
1109
|
+
* Wallet, an unknown catalog `MDL` method) run on either platform.
|
|
1110
|
+
*
|
|
1111
|
+
* A rule only rejects on a known platform fact, so a caller that omits
|
|
1112
|
+
* `walletPlatform` / `samsungDevice` gets no filtering.
|
|
1113
|
+
*/
|
|
1114
|
+
const WALLET_PLATFORM_RULES = {
|
|
1115
|
+
APPLE_WALLET: (platform) => platform.walletPlatform !== "android",
|
|
1116
|
+
GOOGLE_WALLET: (platform) => platform.walletPlatform !== "ios",
|
|
1117
|
+
SAMSUNG_WALLET: (platform) => platform.walletPlatform !== "ios" && platform.samsungDevice !== false
|
|
1118
|
+
};
|
|
1119
|
+
function isDeviceWalletMethodEligible(method, platform) {
|
|
1120
|
+
const rule = method.method !== void 0 ? WALLET_PLATFORM_RULES[method.method.toUpperCase()] : void 0;
|
|
1121
|
+
return rule ? rule(platform) : true;
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Whether a device wallet can run for this config on this device: an enabled
|
|
1125
|
+
* wallet method that passes `WALLET_PLATFORM_RULES`, or, when the config lists
|
|
1126
|
+
* no wallet method at all, the legacy `deviceWallet` flag (which names no
|
|
1127
|
+
* wallet, so there is nothing to filter).
|
|
1128
|
+
*
|
|
1129
|
+
* The method list is the authority. The dashboard persists a wallet only in
|
|
1130
|
+
* `digitalIds.methods` and leaves the legacy `deviceWallet` / `appleWallet`
|
|
1131
|
+
* booleans at their stored `false`; the workflow-node response historically
|
|
1132
|
+
* shipped them raw, so reading the list is what keeps the tile visible there
|
|
1133
|
+
* (and matches SDK 1). It also means a config whose only wallet is Apple
|
|
1134
|
+
* Wallet yields `false` on Android even when `deviceWallet` is `true`. Unlike
|
|
1135
|
+
* the backend's `deriveDeviceWalletFlag`, an unrecognised method does not
|
|
1136
|
+
* count as a wallet: it must not launch a handshake that cannot know what to
|
|
1137
|
+
* request.
|
|
1138
|
+
*/
|
|
1139
|
+
function hasEligibleDeviceWallet(config, platform) {
|
|
1140
|
+
const walletMethods = normalizeDigitalIdMethods(config).filter(isDeviceWalletMethod);
|
|
1141
|
+
if (walletMethods.length > 0) return walletMethods.some((method) => isDeviceWalletMethodEligible(method, platform));
|
|
1142
|
+
return config.deviceWallet === true;
|
|
1143
|
+
}
|
|
1144
|
+
/** Whether a funnel entry is activated by config + platform capabilities. */
|
|
1145
|
+
function isEntryActive(entry, config, platform) {
|
|
1146
|
+
if (entry.kind === "incodeWallet") return platform.credentialsAvailable && hasEligibleDeviceWallet(config, platform);
|
|
1147
|
+
return findConfiguredMethod(entry, config) !== void 0;
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* The configured `digitalIds` method matching a Trinsic funnel entry — by
|
|
1151
|
+
* persisted method name, or (mapped shape) by provider id on a redirect
|
|
1152
|
+
* flowType. First match wins; disabled methods are already dropped by
|
|
1153
|
+
* `normalizeDigitalIdMethods`.
|
|
1154
|
+
*/
|
|
1155
|
+
function findConfiguredMethod(entry, config) {
|
|
1156
|
+
return normalizeDigitalIdMethods(config).find((method) => method.method?.toUpperCase() === entry.method || method.provider === entry.providerId && !!method.flowType && isRedirectFlowType(method.flowType));
|
|
1157
|
+
}
|
|
1158
|
+
/** Normalizes a raw configured method into the mapped shape for the child input. */
|
|
1159
|
+
function toMappedMethod(entry, method) {
|
|
1160
|
+
if (method.flowType && isRedirectFlowType(method.flowType)) return method;
|
|
1161
|
+
return {
|
|
1162
|
+
method: method.method,
|
|
1163
|
+
provider: entry.providerId,
|
|
1164
|
+
flowType: "WEB_REDIRECT",
|
|
1165
|
+
country: method.country ?? method.countries?.[0],
|
|
1166
|
+
displayName: method.displayName,
|
|
1167
|
+
logoUrl: method.logoUrl
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Resolves the implementation that should fulfil a digital-ID document type:
|
|
1172
|
+
* the first funnel entry that is active under the given config and platform.
|
|
1173
|
+
* `undefined` when nothing can run it (the chooser then shows no tile for it).
|
|
1174
|
+
*/
|
|
1175
|
+
function resolveDigitalIdImplementation(docType, config, platform) {
|
|
1176
|
+
for (const entry of DIGITAL_ID_REGISTRY[docType]) {
|
|
1177
|
+
if (!isEntryActive(entry, config, platform)) continue;
|
|
1178
|
+
if (entry.kind === "incodeWallet") return { kind: "incodeWallet" };
|
|
1179
|
+
const method = findConfiguredMethod(entry, config);
|
|
1180
|
+
return {
|
|
1181
|
+
kind: "trinsicRedirect",
|
|
1182
|
+
providerId: entry.providerId,
|
|
1183
|
+
method: method ? toMappedMethod(entry, method) : void 0
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
//#endregion
|
|
1188
|
+
//#region src/modules/id/idCaptureHelpers.ts
|
|
1189
|
+
/**
|
|
1190
|
+
* Normalizes a configured method into the mapped redirect shape for a
|
|
1191
|
+
* resolved provider. The already-mapped shape is returned as-is; the raw
|
|
1192
|
+
* backend shape gets `provider` + `WEB_REDIRECT` filled in.
|
|
1193
|
+
*/
|
|
1194
|
+
function toRedirectMethod(method, provider) {
|
|
1195
|
+
if (method.provider && method.flowType) return method;
|
|
1196
|
+
return {
|
|
1197
|
+
method: method.method,
|
|
1198
|
+
provider,
|
|
1199
|
+
flowType: "WEB_REDIRECT",
|
|
1200
|
+
country: method.country ?? method.countries?.[0],
|
|
1201
|
+
displayName: method.displayName,
|
|
1202
|
+
logoUrl: method.logoUrl
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
/**
|
|
1206
|
+
* The enabled web-redirect digital-ID method to launch — the one matching
|
|
1207
|
+
* `providerId` when given (a chooser card was picked), else the first
|
|
1208
|
+
* configured redirect method — or `undefined` when none is configured.
|
|
1209
|
+
* Drives the provider and country passed to the `digitalIdRedirectMachine`.
|
|
1210
|
+
*
|
|
1211
|
+
* Accepts both the mapped array (`IdCaptureDigitalIdMethod[]`) and the raw
|
|
1212
|
+
* backend `configuration.digitalIds` object (`{ enabled, methods: [...] }`);
|
|
1213
|
+
* for the raw shape the provider comes from the backend-enriched
|
|
1214
|
+
* `providerId`/`flowType` when present, else from the persisted method name
|
|
1215
|
+
* via the digital-ID registry (`IDIN` → `trinsic_netherlands_idin`).
|
|
1216
|
+
*/
|
|
1217
|
+
function getDigitalIdRedirectMethod(config, providerId) {
|
|
1218
|
+
for (const method of normalizeDigitalIdMethods(config)) {
|
|
1219
|
+
const provider = resolveRedirectProviderId(method);
|
|
1220
|
+
if (!provider || providerId !== void 0 && provider !== providerId) continue;
|
|
1221
|
+
return toRedirectMethod(method, provider);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
function collectDigitalIdRedirectOptions(config) {
|
|
1225
|
+
const entries = [];
|
|
1226
|
+
for (const method of normalizeDigitalIdMethods(config)) {
|
|
1227
|
+
const providerId = resolveRedirectProviderId(method);
|
|
1228
|
+
if (!providerId || !isStandaloneRedirectProvider(providerId) || entries.some((entry) => entry.option.providerId === providerId)) continue;
|
|
1229
|
+
const countries = (method.countries ?? (method.country ? [method.country] : void 0) ?? REDIRECT_PROVIDER_COUNTRIES[providerId] ?? []).flatMap((country) => normalizeCountryCode(country) ?? []);
|
|
1230
|
+
entries.push({
|
|
1231
|
+
option: {
|
|
1232
|
+
providerId,
|
|
1233
|
+
method: method.method,
|
|
1234
|
+
displayName: method.displayName,
|
|
1235
|
+
logoUrl: method.logoUrl,
|
|
1236
|
+
country: method.country ?? method.countries?.[0] ?? countries[0]
|
|
1237
|
+
},
|
|
1238
|
+
countries
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
return entries;
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Rank of an option against the detected countries: the index of the
|
|
1245
|
+
* strongest detected country it serves, `Infinity` when it serves none.
|
|
1246
|
+
*/
|
|
1247
|
+
function countryRank(countries, preferredCountries) {
|
|
1248
|
+
const ranks = countries.map((country) => preferredCountries.indexOf(country)).filter((index) => index >= 0);
|
|
1249
|
+
return ranks.length > 0 ? Math.min(...ranks) : Number.POSITIVE_INFINITY;
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* The digital-ID web-redirect providers that get their own chooser card: one
|
|
1253
|
+
* per enabled redirect method in `config.digitalIds`, deduped by provider.
|
|
1254
|
+
* Wallet-funnel fallbacks (the Trinsic mDL leg) are excluded — they surface
|
|
1255
|
+
* through the Digital ID tile instead.
|
|
1256
|
+
*
|
|
1257
|
+
* Order: providers serving the strongest detected country first
|
|
1258
|
+
* (`preferredCountries`, see `detectDigitalIdCountries`), then those serving
|
|
1259
|
+
* weaker ones, then the rest. Country only ranks — nothing is hidden — and
|
|
1260
|
+
* ties keep backend (dashboard) order. With no detected country this is plain
|
|
1261
|
+
* backend order.
|
|
1262
|
+
*
|
|
1263
|
+
* Card display data (`displayName`, `logoUrl`, `country`) is whatever the
|
|
1264
|
+
* backend enriched the method with; the UI falls back to generic copy / icon
|
|
1265
|
+
* when absent.
|
|
1266
|
+
*/
|
|
1267
|
+
function getAvailableDigitalIdRedirectOptions(config, preferredCountries = []) {
|
|
1268
|
+
const entries = collectDigitalIdRedirectOptions(config);
|
|
1269
|
+
if (preferredCountries.length === 0) return entries.map((entry) => entry.option);
|
|
1270
|
+
return entries.map((entry) => ({
|
|
1271
|
+
entry,
|
|
1272
|
+
rank: countryRank(entry.countries, preferredCountries)
|
|
1273
|
+
})).sort((a, b) => a.rank - b.rank).map(({ entry }) => entry.option);
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Re-orders the given redirect options for `preferredCountries` without
|
|
1277
|
+
* changing the set: same ranking as `getAvailableDigitalIdRedirectOptions`,
|
|
1278
|
+
* ties in backend order. Each option's countries come from its configured
|
|
1279
|
+
* method (all of them), falling back to the option's own `country`.
|
|
1280
|
+
*/
|
|
1281
|
+
function rankDigitalIdRedirectOptions(options, config, preferredCountries) {
|
|
1282
|
+
const entries = collectDigitalIdRedirectOptions(config);
|
|
1283
|
+
const backendIndex = (option) => {
|
|
1284
|
+
const index = entries.findIndex((entry) => entry.option.providerId === option.providerId);
|
|
1285
|
+
return index >= 0 ? index : entries.length;
|
|
1286
|
+
};
|
|
1287
|
+
const countriesOf = (option) => {
|
|
1288
|
+
const configured = entries.find((entry) => entry.option.providerId === option.providerId);
|
|
1289
|
+
const own = normalizeCountryCode(option.country);
|
|
1290
|
+
return configured?.countries ?? (own ? [own] : []);
|
|
1291
|
+
};
|
|
1292
|
+
return options.map((option, position) => ({
|
|
1293
|
+
option,
|
|
1294
|
+
rank: countryRank(countriesOf(option), preferredCountries),
|
|
1295
|
+
order: backendIndex(option),
|
|
1296
|
+
position
|
|
1297
|
+
})).sort((a, b) => a.rank - b.rank || a.order - b.order || a.position - b.position).map(({ option }) => option);
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Whether country ranking can change the order of the redirect options: at
|
|
1301
|
+
* least two options serving different countries. When it cannot, the chooser
|
|
1302
|
+
* skips country detection entirely (no request, no wait).
|
|
1303
|
+
*/
|
|
1304
|
+
function canRankDigitalIdRedirectOptionsByCountry(config) {
|
|
1305
|
+
const entries = collectDigitalIdRedirectOptions(config);
|
|
1306
|
+
if (entries.length < 2) return false;
|
|
1307
|
+
return new Set(entries.map((entry) => [...entry.countries].sort().join(","))).size > 1;
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* Map of config properties received from the backend to adjusted, internal document types.
|
|
1311
|
+
*/
|
|
1312
|
+
const DOCUMENT_TYPES_CONFIG_TO_ADJUSTED_MAP = [
|
|
1313
|
+
["enableId", "id"],
|
|
1314
|
+
["enablePassport", "passport"],
|
|
1315
|
+
["digitalIdsUpload", "digitalIdUpload"]
|
|
1316
|
+
];
|
|
1317
|
+
/**
|
|
1318
|
+
* Returns the list of document types enabled by config for the chooser screen, in display order.
|
|
1319
|
+
* Used to populate chooser state so UI and headless consumers can render the correct options.
|
|
1320
|
+
*
|
|
1321
|
+
* Digital-ID document types (device wallet, Trinsic web-redirect) come from
|
|
1322
|
+
* the digital-ID registry funnel: each registry document type contributes the
|
|
1323
|
+
* tile of its first active implementation. A `deviceWallet: true` config on a
|
|
1324
|
+
* platform without the Credentials API therefore shows the Trinsic fallback
|
|
1325
|
+
* tile when one is configured — or no tile at all, instead of a dead-end one.
|
|
1326
|
+
*
|
|
1327
|
+
* @param config - ID capture configuration (from flow or init)
|
|
1328
|
+
* @param platform - Platform capabilities consulted by the digital-ID funnel.
|
|
1329
|
+
* Defaults to no Credentials API for pure-node callers; the machine passes
|
|
1330
|
+
* the real capability check.
|
|
1331
|
+
* @returns Array of IdDocumentType values that should be shown in the document type chooser
|
|
1332
|
+
*/
|
|
1333
|
+
function getAvailableDocumentTypes(config, platform = { credentialsAvailable: false }) {
|
|
1334
|
+
const adjustedDocumentTypes = [];
|
|
1335
|
+
for (const [configProperty, adjustedType] of DOCUMENT_TYPES_CONFIG_TO_ADJUSTED_MAP) if (config[configProperty]) adjustedDocumentTypes.push(adjustedType);
|
|
1336
|
+
for (const docType of DIGITAL_ID_DOCUMENT_TYPES) {
|
|
1337
|
+
const route = resolveDigitalIdImplementation(docType, config, platform);
|
|
1338
|
+
if (!route) continue;
|
|
1339
|
+
const documentType = route.kind === "incodeWallet" ? "digitalId" : "digitalIdRedirect";
|
|
1340
|
+
if (!adjustedDocumentTypes.includes(documentType)) adjustedDocumentTypes.push(documentType);
|
|
1341
|
+
}
|
|
1342
|
+
if (!adjustedDocumentTypes.includes("digitalIdRedirect") && getAvailableDigitalIdRedirectOptions(config).length > 0) adjustedDocumentTypes.push("digitalIdRedirect");
|
|
1343
|
+
return adjustedDocumentTypes;
|
|
1344
|
+
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Computes `idCaptureMachine`'s terminal output — the downstream module-skip
|
|
1347
|
+
* signal read by the Flow orchestrator (via `runChildModule`'s `MODULE_COMPLETE`).
|
|
1348
|
+
*
|
|
1349
|
+
* `skipFaceMatch` is set ONLY for the US Smart Capture *camera back-only* path:
|
|
1350
|
+
* a back image was captured on-device (`capturedImages.back`) and no front was
|
|
1351
|
+
* (`!capturedImages.front`) — "no front, no ID face, no match".
|
|
1352
|
+
*
|
|
1353
|
+
* Requiring a captured back is deliberate and load-bearing: the digital-ID
|
|
1354
|
+
* upload path submits a full ID (front face present) but does NOT
|
|
1355
|
+
* populate `capturedImages` (only the camera path does). Gating on a captured
|
|
1356
|
+
* back excludes those upload paths so a real ID-vs-selfie match is never
|
|
1357
|
+
* silently skipped. `capturedImages.front`/`forceFrontIdCapture` alone are not
|
|
1358
|
+
* enough (a later front upload clears the request; uploads set neither field).
|
|
1359
|
+
*
|
|
1360
|
+
* Always `false` outside US Smart Capture. The selfie/face capture itself is
|
|
1361
|
+
* unaffected — only the ID-vs-selfie match is skipped.
|
|
1362
|
+
*
|
|
1363
|
+
* Also `true` on the Digital ID web-redirect (Trinsic iDIN/FTN) COMPLETED path
|
|
1364
|
+
* when the scheme returned no portrait (`isDigitalIdRedirect && !portraitPresent`,
|
|
1365
|
+
* FM-1/FM-2): there is no ID face to match the selfie against.
|
|
1366
|
+
*/
|
|
1367
|
+
function computeIdCaptureOutput(context) {
|
|
1368
|
+
const frontIdCaptured = Boolean(context.capturedImages.front);
|
|
1369
|
+
const backIdCaptured = Boolean(context.capturedImages.back);
|
|
1370
|
+
return {
|
|
1371
|
+
frontIdCaptured,
|
|
1372
|
+
skipFaceMatch: context.isDigitalIdRedirect === true && context.portraitPresent !== true || context.config.usSmartCapture === true && backIdCaptured && !frontIdCaptured
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
//#endregion
|
|
772
1376
|
//#region src/modules/id/idCaptureGuards.ts
|
|
773
1377
|
function getPermissionOutput(event) {
|
|
774
1378
|
if (!("output" in event)) return;
|
|
@@ -874,6 +1478,13 @@ const supportsOptimizingStatusGuard = ({ context }) => context.config.supportsOp
|
|
|
874
1478
|
const isDeepsightEnabledGuard = ({ context }) => context.dependencies !== void 0;
|
|
875
1479
|
const isDeepsightReadyGuard = ({ context }) => context.deepsightService !== void 0;
|
|
876
1480
|
const needsDeepsightInitGuard = ({ context }) => context.dependencies !== void 0 && context.deepsightService === void 0 && !context.deepsightInitAttempted;
|
|
1481
|
+
/**
|
|
1482
|
+
* Route into the chooser through `detectingCountry`: detection has not run
|
|
1483
|
+
* yet, a country signal is wired, and the ranking could actually reorder the
|
|
1484
|
+
* redirect options (two or more serving different countries). Otherwise the
|
|
1485
|
+
* chooser opens at once, with no request and no spinner.
|
|
1486
|
+
*/
|
|
1487
|
+
const needsCountryDetectionGuard = ({ context }) => context.detectedCountries === void 0 && hasCountrySignals(context.dependencies?.countryDetection) && canRankDigitalIdRedirectOptionsByCountry(context.config);
|
|
877
1488
|
/** No capture option is enabled — the ID module is misconfigured. */
|
|
878
1489
|
const hasNoDocumentTypesAvailableGuard = ({ context }) => context.availableDocumentTypes.length === 0;
|
|
879
1490
|
const isDigitalIdUploadSelectedGuard = ({ event }) => event.type === "SELECT_DOCUMENT" && event.documentType === "digitalIdUpload";
|
|
@@ -1420,7 +2031,7 @@ fromPromise(async ({ input }) => {
|
|
|
1420
2031
|
});
|
|
1421
2032
|
fromPromise(async ({ input }) => {
|
|
1422
2033
|
if (!input.dependencies) return;
|
|
1423
|
-
const { loadDeepsightSession } = await import("./deepsightLoader-
|
|
2034
|
+
const { loadDeepsightSession } = await import("./deepsightLoader-DMxtowCm.esm.js");
|
|
1424
2035
|
return loadDeepsightSession({
|
|
1425
2036
|
ds: input.ds,
|
|
1426
2037
|
storage: input.dependencies.storage,
|
|
@@ -1863,21 +2474,28 @@ function cleanup(service) {
|
|
|
1863
2474
|
service.cleanup();
|
|
1864
2475
|
} catch {}
|
|
1865
2476
|
}
|
|
1866
|
-
function createIdMetadataPreparationCoordinator(load = async (input) => (await import("./deepsightLoader-
|
|
2477
|
+
function createIdMetadataPreparationCoordinator(load = async (input) => (await import("./deepsightLoader-DMxtowCm.esm.js")).loadDeepsightSession(input)) {
|
|
1867
2478
|
let disposed = false;
|
|
1868
2479
|
let preparation;
|
|
1869
2480
|
let service;
|
|
2481
|
+
let failure;
|
|
1870
2482
|
const prepare = (input) => {
|
|
1871
2483
|
if (disposed) return Promise.reject(/* @__PURE__ */ new Error("ID metadata coordinator is disposed"));
|
|
1872
|
-
|
|
1873
|
-
const
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
2484
|
+
if (!preparation) {
|
|
2485
|
+
const pending = (async () => {
|
|
2486
|
+
const prepared = await load(input);
|
|
2487
|
+
if (disposed) {
|
|
2488
|
+
cleanup(prepared);
|
|
2489
|
+
throw new Error("ID metadata coordinator is disposed");
|
|
2490
|
+
}
|
|
2491
|
+
service = prepared;
|
|
2492
|
+
return prepared;
|
|
2493
|
+
})();
|
|
2494
|
+
preparation = pending;
|
|
2495
|
+
pending.catch((error) => {
|
|
2496
|
+
if (preparation === pending) failure = { error };
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
1881
2499
|
return preparation;
|
|
1882
2500
|
};
|
|
1883
2501
|
return {
|
|
@@ -1885,10 +2503,19 @@ function createIdMetadataPreparationCoordinator(load = async (input) => (await i
|
|
|
1885
2503
|
prepare(input).catch(() => void 0);
|
|
1886
2504
|
},
|
|
1887
2505
|
prepare,
|
|
2506
|
+
/**
|
|
2507
|
+
* The memoized preparation's rejection once it has settled. `undefined`
|
|
2508
|
+
* while it is pending or after it succeeded. Preparation is never retried,
|
|
2509
|
+
* so a failure here fails every later attempt of this capture too.
|
|
2510
|
+
*/
|
|
2511
|
+
settledFailure() {
|
|
2512
|
+
return failure;
|
|
2513
|
+
},
|
|
1888
2514
|
dispose() {
|
|
1889
2515
|
if (disposed) return;
|
|
1890
2516
|
disposed = true;
|
|
1891
2517
|
preparation = void 0;
|
|
2518
|
+
failure = void 0;
|
|
1892
2519
|
const prepared = service;
|
|
1893
2520
|
service = void 0;
|
|
1894
2521
|
if (prepared) cleanup(prepared);
|
|
@@ -1981,18 +2608,18 @@ function streamUsesBackCamera(stream) {
|
|
|
1981
2608
|
if (isBackCameraLabel(label)) return true;
|
|
1982
2609
|
if (label.includes("front") || label.includes("user")) return false;
|
|
1983
2610
|
}
|
|
2611
|
+
/** The tutorial pre-acquire's default work: have the ID pipeline loaded. */
|
|
2612
|
+
const warmupIdPipeline = () => ensureWasmPipelines(["idCapture"]);
|
|
1984
2613
|
function createIdProtectedCaptureController(dependencies = {}) {
|
|
1985
2614
|
const metadataCoordinator = createIdMetadataPreparationCoordinator(dependencies.loadMetadata);
|
|
1986
2615
|
let disposed = false;
|
|
1987
2616
|
let visible = true;
|
|
1988
2617
|
let preAcquired;
|
|
1989
2618
|
let preAcquirePromise;
|
|
1990
|
-
let preAcquireGeneration = 0;
|
|
1991
2619
|
let provider;
|
|
1992
2620
|
let displayStream;
|
|
1993
2621
|
let frameCapturer;
|
|
1994
2622
|
let captureResolution;
|
|
1995
|
-
let cameraFallbackLevel;
|
|
1996
2623
|
let usingBackCamera;
|
|
1997
2624
|
let previewImageUrl;
|
|
1998
2625
|
let pendingPreviewCanvas;
|
|
@@ -2042,23 +2669,21 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2042
2669
|
releasePreAcquired();
|
|
2043
2670
|
preAcquired = value;
|
|
2044
2671
|
captureResolution = streamResolution(value.stream);
|
|
2045
|
-
cameraFallbackLevel = value.fallbackLevel;
|
|
2046
2672
|
usingBackCamera = streamUsesBackCamera(value.stream);
|
|
2047
2673
|
return true;
|
|
2048
2674
|
};
|
|
2675
|
+
/**
|
|
2676
|
+
* Overlaps the ID pipeline warm-up with the tutorial so the attempt's
|
|
2677
|
+
* `configureWorkflow` finds it loaded. Nothing here opens a camera: since
|
|
2678
|
+
* ml-wasm-kit v2.14.52 the kit acquires it inside the protected camera step.
|
|
2679
|
+
* In-flight calls are deduplicated; the warm-up itself is idempotent.
|
|
2680
|
+
*/
|
|
2049
2681
|
const preAcquire = () => {
|
|
2050
2682
|
if (disposed) return Promise.reject(/* @__PURE__ */ new Error("ID protected capture controller is disposed"));
|
|
2051
|
-
if (preAcquired) return Promise.resolve();
|
|
2052
2683
|
if (preAcquirePromise) return preAcquirePromise;
|
|
2053
|
-
const generation = preAcquireGeneration;
|
|
2054
2684
|
const pending = (async () => {
|
|
2055
|
-
|
|
2056
|
-
if (disposed
|
|
2057
|
-
stopStream(value.stream);
|
|
2058
|
-
if (disposed) throw new Error("ID protected capture controller is disposed");
|
|
2059
|
-
return;
|
|
2060
|
-
}
|
|
2061
|
-
acceptPreAcquired(value);
|
|
2685
|
+
await (dependencies.warmupPipelines ?? warmupIdPipeline)();
|
|
2686
|
+
if (disposed) throw new Error("ID protected capture controller is disposed");
|
|
2062
2687
|
})();
|
|
2063
2688
|
preAcquirePromise = pending;
|
|
2064
2689
|
pending.then(() => {
|
|
@@ -2148,6 +2773,7 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2148
2773
|
beginAttempt(context, send, getLiveContext) {
|
|
2149
2774
|
if (disposed) throw new Error("ID protected capture controller is disposed");
|
|
2150
2775
|
clearAttempt();
|
|
2776
|
+
usingBackCamera = getDeviceClass() !== "desktop";
|
|
2151
2777
|
if (stepRecording.session && stepRecording.scope !== recordingScopeFor(context)) completeStepRecording();
|
|
2152
2778
|
diagnosticAttempt = {
|
|
2153
2779
|
attempt: ++protectedIdAttemptSequence,
|
|
@@ -2158,7 +2784,6 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2158
2784
|
attemptSend = send;
|
|
2159
2785
|
getAttemptLiveContext = getLiveContext;
|
|
2160
2786
|
provider = (dependencies.createProvider ?? createProtectedIdProvider)(context.config, context.currentMode);
|
|
2161
|
-
cycleOwnership = createCameraCycleOwnership(cameraCycleProvider);
|
|
2162
2787
|
logDiagnostic("attempt-start", { aggregationMs: context.config?.thresholds?.framesAggregationInterval ?? DEFAULT_ID_CAPTURE_THRESHOLDS.framesAggregationInterval });
|
|
2163
2788
|
noteTrueSightCaptureActivity(true);
|
|
2164
2789
|
},
|
|
@@ -2171,6 +2796,9 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2171
2796
|
disableIpify: context.disableIpify
|
|
2172
2797
|
});
|
|
2173
2798
|
},
|
|
2799
|
+
settledMetadataFailure() {
|
|
2800
|
+
return metadataCoordinator.settledFailure();
|
|
2801
|
+
},
|
|
2174
2802
|
prepareMetadata(context) {
|
|
2175
2803
|
const storage = context.dependencies?.storage;
|
|
2176
2804
|
if (!storage) return Promise.reject(/* @__PURE__ */ new Error("ID metadata storage is unavailable"));
|
|
@@ -2184,7 +2812,6 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2184
2812
|
dispose() {
|
|
2185
2813
|
if (disposed) return;
|
|
2186
2814
|
disposed = true;
|
|
2187
|
-
preAcquireGeneration += 1;
|
|
2188
2815
|
metadataCoordinator.dispose();
|
|
2189
2816
|
releasePreAcquired();
|
|
2190
2817
|
clearAttempt();
|
|
@@ -2218,27 +2845,26 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2218
2845
|
return visible;
|
|
2219
2846
|
},
|
|
2220
2847
|
storePreAcquiredStream(value) {
|
|
2221
|
-
preAcquireGeneration += 1;
|
|
2222
2848
|
return acceptPreAcquired(value);
|
|
2223
2849
|
},
|
|
2224
2850
|
takePreAcquiredStream() {
|
|
2225
2851
|
const value = preAcquired;
|
|
2226
2852
|
preAcquired = void 0;
|
|
2227
|
-
if (value) cameraFallbackLevel = value.fallbackLevel;
|
|
2228
2853
|
return value;
|
|
2229
2854
|
},
|
|
2230
2855
|
getProvider() {
|
|
2231
2856
|
return provider;
|
|
2232
2857
|
},
|
|
2233
2858
|
getCycleOwnership() {
|
|
2234
|
-
if (!
|
|
2859
|
+
if (!attemptContext) throw new Error("Protected ID cycle ownership is unavailable");
|
|
2860
|
+
cycleOwnership ??= createCameraCycleOwnership(cameraCycleProvider);
|
|
2235
2861
|
return cycleOwnership;
|
|
2236
2862
|
},
|
|
2237
2863
|
getProjection() {
|
|
2238
2864
|
return {
|
|
2239
2865
|
stream: displayStream,
|
|
2240
2866
|
captureResolution,
|
|
2241
|
-
cameraFallbackLevel,
|
|
2867
|
+
cameraFallbackLevel: void 0,
|
|
2242
2868
|
usingBackCamera
|
|
2243
2869
|
};
|
|
2244
2870
|
},
|
|
@@ -2287,14 +2913,12 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2287
2913
|
type,
|
|
2288
2914
|
qualityElements: context.qualityElements,
|
|
2289
2915
|
onProgress,
|
|
2290
|
-
deepsightService: void 0,
|
|
2291
2916
|
stream: displayStream,
|
|
2292
2917
|
isSecondId: context.config.isSecondId ?? false,
|
|
2293
2918
|
onlyFront: type === "front" && (context.config.onlyFront ?? false),
|
|
2294
2919
|
ageAssurance: context.config.ageAssurance,
|
|
2295
2920
|
dependencies: context.dependencies,
|
|
2296
2921
|
captureResolution,
|
|
2297
|
-
cameraFallbackLevel,
|
|
2298
2922
|
extractIdFace: context.config.extractIdFace,
|
|
2299
2923
|
croppedCanvas: provider?.getCapturedCanvas() ?? null
|
|
2300
2924
|
};
|
|
@@ -2313,12 +2937,18 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2313
2937
|
},
|
|
2314
2938
|
async deliverCaptureOnly(signal) {
|
|
2315
2939
|
if (!dependencies.finalizeCaptureOnly || !attemptContext || !attemptSend) throw new Error(ID_ERROR_CODES.UPLOAD_ERROR);
|
|
2316
|
-
|
|
2940
|
+
const upload = controller.buildCaptureOnlyUpload(attemptContext, (progress) => {
|
|
2317
2941
|
attemptSend?.({
|
|
2318
2942
|
type: "UPLOAD_PROGRESS",
|
|
2319
2943
|
progress
|
|
2320
2944
|
});
|
|
2321
|
-
})
|
|
2945
|
+
});
|
|
2946
|
+
const deepsightService = await controller.prepareMetadata(attemptContext).catch(() => void 0);
|
|
2947
|
+
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
2948
|
+
return dependencies.finalizeCaptureOnly({
|
|
2949
|
+
...upload,
|
|
2950
|
+
deepsightService
|
|
2951
|
+
}, signal);
|
|
2322
2952
|
},
|
|
2323
2953
|
resourceSink: {
|
|
2324
2954
|
ready(stream) {
|
|
@@ -2327,10 +2957,7 @@ function createIdProtectedCaptureController(dependencies = {}) {
|
|
|
2327
2957
|
return;
|
|
2328
2958
|
}
|
|
2329
2959
|
replaceDisplayStream(stream);
|
|
2330
|
-
logDiagnostic("protected-camera-ready",
|
|
2331
|
-
...getIdCameraTrackDiagnosticFields(stream.getVideoTracks()[0]),
|
|
2332
|
-
fallbackLevel: cameraFallbackLevel
|
|
2333
|
-
});
|
|
2960
|
+
logDiagnostic("protected-camera-ready", getIdCameraTrackDiagnosticFields(stream.getVideoTracks()[0]));
|
|
2334
2961
|
},
|
|
2335
2962
|
autoCommitted: storeCommit,
|
|
2336
2963
|
manualCommitted: storeCommit,
|
|
@@ -2775,48 +3402,34 @@ function createProtectedIdAttemptInput(input) {
|
|
|
2775
3402
|
const target = resolveProtectedIdTarget(context.config, context.currentMode);
|
|
2776
3403
|
const callbackSession = createProtectedIdCallbackSession(input);
|
|
2777
3404
|
let wasmUtil;
|
|
2778
|
-
const preAcquired = controller.takePreAcquiredStream();
|
|
2779
|
-
let selectedVideoTrack = preAcquired?.stream.getVideoTracks()[0];
|
|
2780
|
-
const constraints = getCameraReacquisitionConstraints(selectedVideoTrack, preAcquired?.constraints);
|
|
2781
3405
|
const captureOnly = hasOnCaptureCallback(context.config);
|
|
2782
3406
|
const diagnosticAttempt = controller.getDiagnosticAttempt();
|
|
2783
3407
|
const isAttemptActive = () => !controller.disposed && controller.getProvider() === provider && controller.getDiagnosticAttempt() === diagnosticAttempt;
|
|
2784
|
-
|
|
2785
|
-
if (!diagnosticAttempt) return;
|
|
2786
|
-
logIdCameraDiagnostic("selected-camera", {
|
|
2787
|
-
attempt: diagnosticAttempt.attempt,
|
|
2788
|
-
side: diagnosticAttempt.side,
|
|
2789
|
-
elapsedMs: Math.round(getTimestamp() - diagnosticAttempt.startedAt),
|
|
2790
|
-
...getIdCameraTrackDiagnosticFields(stream.getVideoTracks()[0]),
|
|
2791
|
-
preAcquired: preAcquiredStream,
|
|
2792
|
-
fallbackLevel,
|
|
2793
|
-
workflow: String(workflow),
|
|
2794
|
-
devicePinned: reacquisitionConstraints?.deviceId !== void 0
|
|
2795
|
-
});
|
|
2796
|
-
};
|
|
2797
|
-
if (preAcquired) logSelectedCamera(preAcquired.stream, preAcquired.fallbackLevel, constraints, true);
|
|
3408
|
+
let cameraStepFacts = {};
|
|
2798
3409
|
return {
|
|
2799
3410
|
attemptId: `protected-id-${diagnosticAttempt?.attempt ?? ++protectedIdAttemptSequence}`,
|
|
2800
3411
|
target,
|
|
2801
3412
|
workflow,
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
3413
|
+
preflight: captureOnly ? void 0 : () => {
|
|
3414
|
+
const failure = controller.settledMetadataFailure();
|
|
3415
|
+
if (failure) throw failure.error;
|
|
3416
|
+
},
|
|
3417
|
+
cameraStep: async () => {
|
|
3418
|
+
const di = await electDesktopCameraDevice("environment");
|
|
3419
|
+
const hs = controller.takePreAcquiredStream()?.stream;
|
|
3420
|
+
cameraStepFacts = {
|
|
3421
|
+
preAcquired: hs !== void 0,
|
|
3422
|
+
devicePinned: di !== ""
|
|
3423
|
+
};
|
|
3424
|
+
return {
|
|
3425
|
+
vs: "environment",
|
|
3426
|
+
di,
|
|
3427
|
+
ew: 0,
|
|
3428
|
+
eh: 0,
|
|
3429
|
+
i14: isIPhone14OrHigher(),
|
|
3430
|
+
pa: false,
|
|
3431
|
+
hs
|
|
3432
|
+
};
|
|
2820
3433
|
},
|
|
2821
3434
|
initiallyBackgrounded: !controller.isVisible(),
|
|
2822
3435
|
resourceSink: controller.resourceSink,
|
|
@@ -2830,13 +3443,11 @@ function createProtectedIdAttemptInput(input) {
|
|
|
2830
3443
|
enabled: !captureOnly,
|
|
2831
3444
|
stepRecording: controller.getStepRecording()
|
|
2832
3445
|
}),
|
|
2833
|
-
|
|
2834
|
-
beforeAdopt: captureOnly ? void 0 : async (stream) => {
|
|
2835
|
-
const track = stream.getVideoTracks()[0];
|
|
2836
|
-
if (!track) throw new Error("Protected ID camera has no selected video track");
|
|
3446
|
+
afterReady: captureOnly ? void 0 : async (displayStream) => {
|
|
2837
3447
|
const metadata = await controller.prepareMetadata(context);
|
|
2838
3448
|
if (!isAttemptActive()) return;
|
|
2839
|
-
|
|
3449
|
+
const track = displayStream.getVideoTracks()[0];
|
|
3450
|
+
if (track) await metadata.checkVirtualCamera(track);
|
|
2840
3451
|
},
|
|
2841
3452
|
onStartupTiming(timing) {
|
|
2842
3453
|
if (!diagnosticAttempt) return;
|
|
@@ -2844,6 +3455,8 @@ function createProtectedIdAttemptInput(input) {
|
|
|
2844
3455
|
attempt: diagnosticAttempt.attempt,
|
|
2845
3456
|
side: diagnosticAttempt.side,
|
|
2846
3457
|
elapsedMs: Math.round(getTimestamp() - diagnosticAttempt.startedAt),
|
|
3458
|
+
workflow: String(workflow),
|
|
3459
|
+
...cameraStepFacts,
|
|
2847
3460
|
...timing
|
|
2848
3461
|
});
|
|
2849
3462
|
},
|
|
@@ -2862,12 +3475,6 @@ function createProtectedIdAttemptInput(input) {
|
|
|
2862
3475
|
callbacks: callbackSession.callbacks
|
|
2863
3476
|
});
|
|
2864
3477
|
},
|
|
2865
|
-
async runPrc() {
|
|
2866
|
-
if (!isAttemptActive()) return;
|
|
2867
|
-
wasmUtil = await (input.getWasmUtil ?? WasmUtilProvider.getInstance)();
|
|
2868
|
-
if (!isAttemptActive()) return;
|
|
2869
|
-
await wasmUtil.prc();
|
|
2870
|
-
},
|
|
2871
3478
|
async runPoc() {
|
|
2872
3479
|
if (captureOnly) return;
|
|
2873
3480
|
if (!isAttemptActive()) return;
|
|
@@ -2911,385 +3518,53 @@ function createProtectedIdAttemptInput(input) {
|
|
|
2911
3518
|
if (isAttemptActive()) trueSightLog("warning", "deepsight", "idScan", "protected capture diagnostics failed");
|
|
2912
3519
|
}
|
|
2913
3520
|
}
|
|
2914
|
-
}
|
|
2915
|
-
};
|
|
2916
|
-
}
|
|
2917
|
-
function protectedIdResultToCaptureResponse(result) {
|
|
2918
|
-
const regulationType = result.regulationType === "US" || result.regulationType === "Worldwide" || result.regulationType === "Other" || result.regulationType === "US_Illinois" || result.regulationType === "US_Texas" || result.regulationType === "US_California" || result.regulationType === "US_Washington" ? result.regulationType : void 0;
|
|
2919
|
-
return {
|
|
2920
|
-
sharpness: result.sharpness ?? 0,
|
|
2921
|
-
correctSharpness: result.sharpness != null && result.sharpness >= 10,
|
|
2922
|
-
glare: result.glare ?? 0,
|
|
2923
|
-
correctGlare: result.glare != null && result.glare >= 10,
|
|
2924
|
-
horizontalResolution: 0,
|
|
2925
|
-
classification: result.classification === true,
|
|
2926
|
-
readability: result.readability === true,
|
|
2927
|
-
typeOfId: result.typeOfId ?? "",
|
|
2928
|
-
issueYear: 0,
|
|
2929
|
-
issueName: "",
|
|
2930
|
-
sessionStatus: result.sessionStatus ?? "",
|
|
2931
|
-
countryCode: result.countryCode ?? "",
|
|
2932
|
-
skipBackIdCapture: result.skipBackIdCapture,
|
|
2933
|
-
skipGlareFront: result.skipGlareFront,
|
|
2934
|
-
skipGlareBack: result.skipGlareBack,
|
|
2935
|
-
acceptedDocuments: result.acceptedDocuments ? [...result.acceptedDocuments] : void 0,
|
|
2936
|
-
forceFrontIdCapture: result.forceFrontIdCapture,
|
|
2937
|
-
idValidationCompleted: result.idValidationCompleted,
|
|
2938
|
-
showMandatoryConsent: result.showMandatoryConsent,
|
|
2939
|
-
regulationType,
|
|
2940
|
-
failReason: result.failReason,
|
|
2941
|
-
side: result.side,
|
|
2942
|
-
idQualityAttemptApproved: result.idQualityAttemptApproved,
|
|
2943
|
-
isDocumentExpired: result.isDocumentExpired,
|
|
2944
|
-
success: result.success
|
|
2945
|
-
};
|
|
2946
|
-
}
|
|
2947
|
-
function getProtectedIdUploadRequest(context, sessionToken = getToken()) {
|
|
2948
|
-
const target = resolveProtectedIdTarget(context.config, context.currentMode);
|
|
2949
|
-
const front = context.currentMode !== "back";
|
|
2950
|
-
const params = { captureType: context.manualCaptureTriggered ? "MANUAL" : "AUTO" };
|
|
2951
|
-
if (front && context.config.onlyFront === true) params.onlyFront = true;
|
|
2952
|
-
if (front && context.config.extractIdFace === false) params.extractIdFace = false;
|
|
2953
|
-
const sharpness = context.qualityElements?.sharpness;
|
|
2954
|
-
if (sharpness !== void 0 && sharpness !== 0 && Number.isFinite(sharpness)) params.sharpness = getRealQualityValue(sharpness);
|
|
2955
|
-
return {
|
|
2956
|
-
target,
|
|
2957
|
-
config: {
|
|
2958
|
-
...sessionToken ? { headers: { "X-Incode-Hardware-Id": sessionToken } } : {},
|
|
2959
|
-
params
|
|
2960
|
-
}
|
|
2961
|
-
};
|
|
2962
|
-
}
|
|
2963
|
-
//#endregion
|
|
2964
|
-
//#region src/modules/id/digitalIdRegistry.ts
|
|
2965
|
-
/**
|
|
2966
|
-
* True when a digital-ID method uses a full-page web-redirect flow (Trinsic
|
|
2967
|
-
* iDIN/FTN). Accepts both the module `FlowType` value (`REDIRECT`) and the
|
|
2968
|
-
* backend value (`WEB_REDIRECT`). (Lives here rather than in
|
|
2969
|
-
* `idCaptureHelpers` to keep the registry free of circular imports; the
|
|
2970
|
-
* helpers re-export it.)
|
|
2971
|
-
*/
|
|
2972
|
-
function isRedirectFlowType(flowType) {
|
|
2973
|
-
return flowType === "REDIRECT" || flowType === "WEB_REDIRECT";
|
|
2974
|
-
}
|
|
2975
|
-
const DIGITAL_ID_REGISTRY = {
|
|
2976
|
-
mDL: [{
|
|
2977
|
-
kind: "incodeWallet",
|
|
2978
|
-
documentType: "digitalId"
|
|
2979
|
-
}, {
|
|
2980
|
-
kind: "trinsicRedirect",
|
|
2981
|
-
documentType: "digitalIdRedirect",
|
|
2982
|
-
providerId: "trinsic_mdl_placeholder",
|
|
2983
|
-
method: "MDL"
|
|
2984
|
-
}],
|
|
2985
|
-
iDIN: [{
|
|
2986
|
-
kind: "trinsicRedirect",
|
|
2987
|
-
documentType: "digitalIdRedirect",
|
|
2988
|
-
providerId: "trinsic_netherlands_idin",
|
|
2989
|
-
method: "IDIN"
|
|
2990
|
-
}],
|
|
2991
|
-
FTN: [{
|
|
2992
|
-
kind: "trinsicRedirect",
|
|
2993
|
-
documentType: "digitalIdRedirect",
|
|
2994
|
-
providerId: "trinsic_finnish_trust_network",
|
|
2995
|
-
method: "FTN"
|
|
2996
|
-
}]
|
|
2997
|
-
};
|
|
2998
|
-
const DIGITAL_ID_DOCUMENT_TYPES = Object.keys(DIGITAL_ID_REGISTRY);
|
|
2999
|
-
/**
|
|
3000
|
-
* Single place that widens `config.digitalIds` to the shapes the backend
|
|
3001
|
-
* actually sends — the mapped array or the raw `{ enabled, methods }` object.
|
|
3002
|
-
* Shared so the cast is written once.
|
|
3003
|
-
*/
|
|
3004
|
-
function asDigitalIdsConfig(config) {
|
|
3005
|
-
return config.digitalIds;
|
|
3006
|
-
}
|
|
3007
|
-
/**
|
|
3008
|
-
* Persisted method name → catalog provider id, derived from the registry's
|
|
3009
|
-
* Trinsic entries (single source of truth). Lets the SDK launch iDIN / FTN
|
|
3010
|
-
* from a backend that does not yet send `providerId` on each method.
|
|
3011
|
-
* TODO(roadmap: fully-catalog-driven): remove once every backend enriches
|
|
3012
|
-
* `digitalIds.methods[]` with `providerId` + `flowType`.
|
|
3013
|
-
*/
|
|
3014
|
-
const REDIRECT_PROVIDER_BY_METHOD = (() => {
|
|
3015
|
-
const map = {};
|
|
3016
|
-
for (const docType of DIGITAL_ID_DOCUMENT_TYPES) for (const entry of DIGITAL_ID_REGISTRY[docType]) if (entry.kind === "trinsicRedirect") map[entry.method] = entry.providerId;
|
|
3017
|
-
return map;
|
|
3018
|
-
})();
|
|
3019
|
-
/**
|
|
3020
|
-
* Redirect providers that are the fallback leg of a wallet-first funnel
|
|
3021
|
-
* (mDL): they are reached through the `digitalId` tile's funnel resolution,
|
|
3022
|
-
* not offered as a standalone chooser card.
|
|
3023
|
-
*/
|
|
3024
|
-
const WALLET_FUNNEL_REDIRECT_PROVIDER_IDS = new Set(DIGITAL_ID_DOCUMENT_TYPES.flatMap((docType) => {
|
|
3025
|
-
const entries = DIGITAL_ID_REGISTRY[docType];
|
|
3026
|
-
if (!entries.some((entry) => entry.kind === "incodeWallet")) return [];
|
|
3027
|
-
return entries.flatMap((entry) => entry.kind === "trinsicRedirect" ? [entry.providerId] : []);
|
|
3028
|
-
}));
|
|
3029
|
-
/**
|
|
3030
|
-
* True for a redirect provider that gets its own chooser card (iDIN, FTN, any
|
|
3031
|
-
* catalog-enriched redirect method) — as opposed to the mDL wallet fallback,
|
|
3032
|
-
* which only surfaces through the Digital ID tile.
|
|
3033
|
-
*/
|
|
3034
|
-
function isStandaloneRedirectProvider(providerId) {
|
|
3035
|
-
return !WALLET_FUNNEL_REDIRECT_PROVIDER_IDS.has(providerId);
|
|
3036
|
-
}
|
|
3037
|
-
/**
|
|
3038
|
-
* The provider id a configured method launches with, when it is a
|
|
3039
|
-
* web-redirect method; `undefined` for wallets / other flow shapes.
|
|
3040
|
-
*
|
|
3041
|
-
* Resolution order:
|
|
3042
|
-
* 1. an explicit redirect `flowType` with a `provider` (mapped shape) or
|
|
3043
|
-
* `providerId` (catalog-enriched raw shape) — backend-authoritative;
|
|
3044
|
-
* 2. otherwise the persisted method name via the registry (legacy raw shape).
|
|
3045
|
-
*/
|
|
3046
|
-
function resolveRedirectProviderId(method) {
|
|
3047
|
-
if (method.flowType) {
|
|
3048
|
-
if (!isRedirectFlowType(method.flowType)) return;
|
|
3049
|
-
const explicit = method.provider ?? method.providerId;
|
|
3050
|
-
if (explicit) return explicit;
|
|
3051
|
-
}
|
|
3052
|
-
return method.method ? REDIRECT_PROVIDER_BY_METHOD[method.method.toUpperCase()] : void 0;
|
|
3053
|
-
}
|
|
3054
|
-
/**
|
|
3055
|
-
* Tolerant view over `config.digitalIds`: accepts both the mapped array
|
|
3056
|
-
* (`IdCaptureDigitalIdMethod[]`) and the raw backend object
|
|
3057
|
-
* (`{ enabled, methods: [...] }`). Extracted from the old
|
|
3058
|
-
* `getDigitalIdRedirectMethod` cast so every consumer parses it the same way.
|
|
3059
|
-
*
|
|
3060
|
-
* Honors both dashboard toggles: a raw object with `enabled: false` yields no
|
|
3061
|
-
* methods, and individual methods with `enabled: false` are dropped (absent
|
|
3062
|
-
* `enabled` counts as on). This is what "enabled for the flow / workflow"
|
|
3063
|
-
* means — for the redirect chooser cards as much as for the wallet tile.
|
|
3064
|
-
*/
|
|
3065
|
-
function normalizeDigitalIdMethods(config) {
|
|
3066
|
-
const raw = asDigitalIdsConfig(config);
|
|
3067
|
-
if (!Array.isArray(raw) && raw?.enabled === false) return [];
|
|
3068
|
-
return (Array.isArray(raw) ? raw : raw?.methods ?? []).filter((method) => method.enabled !== false);
|
|
3069
|
-
}
|
|
3070
|
-
/**
|
|
3071
|
-
* Persisted method names of the Incode-native device wallets — the backend
|
|
3072
|
-
* `DigitalIdMethodCatalog` entries of type `MDL`. A catalog-enriched method
|
|
3073
|
-
* carries `type: 'MDL'` instead of relying on the name; both are honoured.
|
|
3074
|
-
*/
|
|
3075
|
-
const DEVICE_WALLET_METHODS = /* @__PURE__ */ new Set([
|
|
3076
|
-
"APPLE_WALLET",
|
|
3077
|
-
"GOOGLE_WALLET",
|
|
3078
|
-
"CA_DMV_WALLET"
|
|
3079
|
-
]);
|
|
3080
|
-
/**
|
|
3081
|
-
* True for a configured method the native device-wallet handshake can fulfil.
|
|
3082
|
-
* Redirect methods (iDIN, FTN) never count, whatever their name or type — they
|
|
3083
|
-
* must not surface a wallet tile with no wallet behind it.
|
|
3084
|
-
*
|
|
3085
|
-
* Classifies by *kind* only. Whether a method is switched on is already
|
|
3086
|
-
* settled by `normalizeDigitalIdMethods`, which drops disabled methods before
|
|
3087
|
-
* any caller walks the list.
|
|
3088
|
-
*/
|
|
3089
|
-
function isDeviceWalletMethod(method) {
|
|
3090
|
-
if (method.flowType && isRedirectFlowType(method.flowType)) return false;
|
|
3091
|
-
if (method.type?.toUpperCase() === "MDL") return true;
|
|
3092
|
-
return method.method !== void 0 && DEVICE_WALLET_METHODS.has(method.method.toUpperCase());
|
|
3093
|
-
}
|
|
3094
|
-
/**
|
|
3095
|
-
* Whether a device wallet is enabled for this ID-capture config: the coarse
|
|
3096
|
-
* `deviceWallet` flag, or an enabled wallet method in `config.digitalIds`.
|
|
3097
|
-
*
|
|
3098
|
-
* The dashboard persists a wallet only in `digitalIds.methods` and leaves the
|
|
3099
|
-
* legacy `deviceWallet` / `appleWallet` booleans at their stored `false`. The
|
|
3100
|
-
* backend derives the booleans from `digitalIds` for the flow response, but
|
|
3101
|
-
* the workflow-node response historically shipped them raw — so a workflow
|
|
3102
|
-
* with Apple Wallet enabled arrived here as `deviceWallet: false`, and the
|
|
3103
|
-
* tile was dropped while SDK 1 (which reads `digitalIds` itself) showed it.
|
|
3104
|
-
* Mirrors the backend's own `deriveDeviceWalletFlag`, minus its "unknown
|
|
3105
|
-
* method counts as a wallet" fallback: an unrecognised method must not
|
|
3106
|
-
* launch a handshake that cannot know what to request.
|
|
3107
|
-
*/
|
|
3108
|
-
function isDeviceWalletEnabled(config) {
|
|
3109
|
-
if (config.deviceWallet === true) return true;
|
|
3110
|
-
return hasEnabledDeviceWalletMethod(config);
|
|
3111
|
-
}
|
|
3112
|
-
/** Whether a funnel entry is activated by config + platform capabilities. */
|
|
3113
|
-
function isEntryActive(entry, config, platform) {
|
|
3114
|
-
if (entry.kind === "incodeWallet") return isDeviceWalletEnabled(config) && platform.credentialsAvailable;
|
|
3115
|
-
return findConfiguredMethod(entry, config) !== void 0;
|
|
3116
|
-
}
|
|
3117
|
-
/**
|
|
3118
|
-
* The configured `digitalIds` method matching a Trinsic funnel entry — by
|
|
3119
|
-
* persisted method name, or (mapped shape) by provider id on a redirect
|
|
3120
|
-
* flowType. First match wins; disabled methods are already dropped by
|
|
3121
|
-
* `normalizeDigitalIdMethods`.
|
|
3122
|
-
*/
|
|
3123
|
-
function findConfiguredMethod(entry, config) {
|
|
3124
|
-
return normalizeDigitalIdMethods(config).find((method) => method.method?.toUpperCase() === entry.method || method.provider === entry.providerId && !!method.flowType && isRedirectFlowType(method.flowType));
|
|
3125
|
-
}
|
|
3126
|
-
/** Normalizes a raw configured method into the mapped shape for the child input. */
|
|
3127
|
-
function toMappedMethod(entry, method) {
|
|
3128
|
-
if (method.flowType && isRedirectFlowType(method.flowType)) return method;
|
|
3129
|
-
return {
|
|
3130
|
-
method: method.method,
|
|
3131
|
-
provider: entry.providerId,
|
|
3132
|
-
flowType: "WEB_REDIRECT",
|
|
3133
|
-
country: method.country ?? method.countries?.[0],
|
|
3134
|
-
displayName: method.displayName,
|
|
3135
|
-
logoUrl: method.logoUrl
|
|
3521
|
+
}
|
|
3136
3522
|
};
|
|
3137
3523
|
}
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
* on, honouring both dashboard toggles: the `digitalIds.enabled` master switch
|
|
3141
|
-
* and each method's own `enabled` flag. An absent `enabled` counts as on, the
|
|
3142
|
-
* tolerant reading the rest of this module uses.
|
|
3143
|
-
*
|
|
3144
|
-
* Both toggles are applied by `normalizeDigitalIdMethods`, so this only has to
|
|
3145
|
-
* ask whether any surviving method is a wallet.
|
|
3146
|
-
*/
|
|
3147
|
-
function hasEnabledDeviceWalletMethod(config) {
|
|
3148
|
-
return normalizeDigitalIdMethods(config).some(isDeviceWalletMethod);
|
|
3149
|
-
}
|
|
3150
|
-
/**
|
|
3151
|
-
* Resolves the implementation that should fulfil a digital-ID document type:
|
|
3152
|
-
* the first funnel entry that is active under the given config and platform.
|
|
3153
|
-
* `undefined` when nothing can run it (the chooser then shows no tile for it).
|
|
3154
|
-
*/
|
|
3155
|
-
function resolveDigitalIdImplementation(docType, config, platform) {
|
|
3156
|
-
for (const entry of DIGITAL_ID_REGISTRY[docType]) {
|
|
3157
|
-
if (!isEntryActive(entry, config, platform)) continue;
|
|
3158
|
-
if (entry.kind === "incodeWallet") return { kind: "incodeWallet" };
|
|
3159
|
-
const method = findConfiguredMethod(entry, config);
|
|
3160
|
-
return {
|
|
3161
|
-
kind: "trinsicRedirect",
|
|
3162
|
-
providerId: entry.providerId,
|
|
3163
|
-
method: method ? toMappedMethod(entry, method) : void 0
|
|
3164
|
-
};
|
|
3165
|
-
}
|
|
3166
|
-
}
|
|
3167
|
-
//#endregion
|
|
3168
|
-
//#region src/modules/id/idCaptureHelpers.ts
|
|
3169
|
-
/**
|
|
3170
|
-
* Normalizes a configured method into the mapped redirect shape for a
|
|
3171
|
-
* resolved provider. The already-mapped shape is returned as-is; the raw
|
|
3172
|
-
* backend shape gets `provider` + `WEB_REDIRECT` filled in.
|
|
3173
|
-
*/
|
|
3174
|
-
function toRedirectMethod(method, provider) {
|
|
3175
|
-
if (method.provider && method.flowType) return method;
|
|
3524
|
+
function protectedIdResultToCaptureResponse(result) {
|
|
3525
|
+
const regulationType = result.regulationType === "US" || result.regulationType === "Worldwide" || result.regulationType === "Other" || result.regulationType === "US_Illinois" || result.regulationType === "US_Texas" || result.regulationType === "US_California" || result.regulationType === "US_Washington" ? result.regulationType : void 0;
|
|
3176
3526
|
return {
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3527
|
+
sharpness: result.sharpness ?? 0,
|
|
3528
|
+
correctSharpness: result.sharpness != null && result.sharpness >= 10,
|
|
3529
|
+
glare: result.glare ?? 0,
|
|
3530
|
+
correctGlare: result.glare != null && result.glare >= 10,
|
|
3531
|
+
horizontalResolution: 0,
|
|
3532
|
+
classification: result.classification === true,
|
|
3533
|
+
readability: result.readability === true,
|
|
3534
|
+
typeOfId: result.typeOfId ?? "",
|
|
3535
|
+
issueYear: 0,
|
|
3536
|
+
issueName: "",
|
|
3537
|
+
sessionStatus: result.sessionStatus ?? "",
|
|
3538
|
+
countryCode: result.countryCode ?? "",
|
|
3539
|
+
skipBackIdCapture: result.skipBackIdCapture,
|
|
3540
|
+
skipGlareFront: result.skipGlareFront,
|
|
3541
|
+
skipGlareBack: result.skipGlareBack,
|
|
3542
|
+
acceptedDocuments: result.acceptedDocuments ? [...result.acceptedDocuments] : void 0,
|
|
3543
|
+
forceFrontIdCapture: result.forceFrontIdCapture,
|
|
3544
|
+
idValidationCompleted: result.idValidationCompleted,
|
|
3545
|
+
showMandatoryConsent: result.showMandatoryConsent,
|
|
3546
|
+
regulationType,
|
|
3547
|
+
failReason: result.failReason,
|
|
3548
|
+
side: result.side,
|
|
3549
|
+
idQualityAttemptApproved: result.idQualityAttemptApproved,
|
|
3550
|
+
isDocumentExpired: result.isDocumentExpired,
|
|
3551
|
+
success: result.success
|
|
3183
3552
|
};
|
|
3184
3553
|
}
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
* for the raw shape the provider comes from the backend-enriched
|
|
3194
|
-
* `providerId`/`flowType` when present, else from the persisted method name
|
|
3195
|
-
* via the digital-ID registry (`IDIN` → `trinsic_netherlands_idin`).
|
|
3196
|
-
*/
|
|
3197
|
-
function getDigitalIdRedirectMethod(config, providerId) {
|
|
3198
|
-
for (const method of normalizeDigitalIdMethods(config)) {
|
|
3199
|
-
const provider = resolveRedirectProviderId(method);
|
|
3200
|
-
if (!provider || providerId !== void 0 && provider !== providerId) continue;
|
|
3201
|
-
return toRedirectMethod(method, provider);
|
|
3202
|
-
}
|
|
3203
|
-
}
|
|
3204
|
-
/**
|
|
3205
|
-
* The digital-ID web-redirect providers that get their own chooser card: one
|
|
3206
|
-
* per enabled redirect method in `config.digitalIds`, in backend (dashboard)
|
|
3207
|
-
* order, deduped by provider. Wallet-funnel fallbacks (the Trinsic mDL leg)
|
|
3208
|
-
* are excluded — they surface through the Digital ID tile instead.
|
|
3209
|
-
*
|
|
3210
|
-
* Card display data (`displayName`, `logoUrl`, `country`) is whatever the
|
|
3211
|
-
* backend enriched the method with; the UI falls back to generic copy / icon
|
|
3212
|
-
* when absent.
|
|
3213
|
-
*/
|
|
3214
|
-
function getAvailableDigitalIdRedirectOptions(config) {
|
|
3215
|
-
const options = [];
|
|
3216
|
-
for (const method of normalizeDigitalIdMethods(config)) {
|
|
3217
|
-
const providerId = resolveRedirectProviderId(method);
|
|
3218
|
-
if (!providerId || !isStandaloneRedirectProvider(providerId) || options.some((option) => option.providerId === providerId)) continue;
|
|
3219
|
-
options.push({
|
|
3220
|
-
providerId,
|
|
3221
|
-
method: method.method,
|
|
3222
|
-
displayName: method.displayName,
|
|
3223
|
-
logoUrl: method.logoUrl,
|
|
3224
|
-
country: method.country ?? method.countries?.[0]
|
|
3225
|
-
});
|
|
3226
|
-
}
|
|
3227
|
-
return options;
|
|
3228
|
-
}
|
|
3229
|
-
/**
|
|
3230
|
-
* Map of config properties received from the backend to adjusted, internal document types.
|
|
3231
|
-
*/
|
|
3232
|
-
const DOCUMENT_TYPES_CONFIG_TO_ADJUSTED_MAP = [
|
|
3233
|
-
["enableId", "id"],
|
|
3234
|
-
["enablePassport", "passport"],
|
|
3235
|
-
["digitalIdsUpload", "digitalIdUpload"]
|
|
3236
|
-
];
|
|
3237
|
-
/**
|
|
3238
|
-
* Returns the list of document types enabled by config for the chooser screen, in display order.
|
|
3239
|
-
* Used to populate chooser state so UI and headless consumers can render the correct options.
|
|
3240
|
-
*
|
|
3241
|
-
* Digital-ID document types (device wallet, Trinsic web-redirect) come from
|
|
3242
|
-
* the digital-ID registry funnel: each registry document type contributes the
|
|
3243
|
-
* tile of its first active implementation. A `deviceWallet: true` config on a
|
|
3244
|
-
* platform without the Credentials API therefore shows the Trinsic fallback
|
|
3245
|
-
* tile when one is configured — or no tile at all, instead of a dead-end one.
|
|
3246
|
-
*
|
|
3247
|
-
* @param config - ID capture configuration (from flow or init)
|
|
3248
|
-
* @param platform - Platform capabilities consulted by the digital-ID funnel.
|
|
3249
|
-
* Defaults to no Credentials API for pure-node callers; the machine passes
|
|
3250
|
-
* the real capability check.
|
|
3251
|
-
* @returns Array of IdDocumentType values that should be shown in the document type chooser
|
|
3252
|
-
*/
|
|
3253
|
-
function getAvailableDocumentTypes(config, platform = { credentialsAvailable: false }) {
|
|
3254
|
-
const adjustedDocumentTypes = [];
|
|
3255
|
-
for (const [configProperty, adjustedType] of DOCUMENT_TYPES_CONFIG_TO_ADJUSTED_MAP) if (config[configProperty]) adjustedDocumentTypes.push(adjustedType);
|
|
3256
|
-
for (const docType of DIGITAL_ID_DOCUMENT_TYPES) {
|
|
3257
|
-
const route = resolveDigitalIdImplementation(docType, config, platform);
|
|
3258
|
-
if (!route) continue;
|
|
3259
|
-
const documentType = route.kind === "incodeWallet" ? "digitalId" : "digitalIdRedirect";
|
|
3260
|
-
if (!adjustedDocumentTypes.includes(documentType)) adjustedDocumentTypes.push(documentType);
|
|
3261
|
-
}
|
|
3262
|
-
if (!adjustedDocumentTypes.includes("digitalIdRedirect") && getAvailableDigitalIdRedirectOptions(config).length > 0) adjustedDocumentTypes.push("digitalIdRedirect");
|
|
3263
|
-
return adjustedDocumentTypes;
|
|
3264
|
-
}
|
|
3265
|
-
/**
|
|
3266
|
-
* Computes `idCaptureMachine`'s terminal output — the downstream module-skip
|
|
3267
|
-
* signal read by the Flow orchestrator (via `runChildModule`'s `MODULE_COMPLETE`).
|
|
3268
|
-
*
|
|
3269
|
-
* `skipFaceMatch` is set ONLY for the US Smart Capture *camera back-only* path:
|
|
3270
|
-
* a back image was captured on-device (`capturedImages.back`) and no front was
|
|
3271
|
-
* (`!capturedImages.front`) — "no front, no ID face, no match".
|
|
3272
|
-
*
|
|
3273
|
-
* Requiring a captured back is deliberate and load-bearing: the digital-ID
|
|
3274
|
-
* upload path submits a full ID (front face present) but does NOT
|
|
3275
|
-
* populate `capturedImages` (only the camera path does). Gating on a captured
|
|
3276
|
-
* back excludes those upload paths so a real ID-vs-selfie match is never
|
|
3277
|
-
* silently skipped. `capturedImages.front`/`forceFrontIdCapture` alone are not
|
|
3278
|
-
* enough (a later front upload clears the request; uploads set neither field).
|
|
3279
|
-
*
|
|
3280
|
-
* Always `false` outside US Smart Capture. The selfie/face capture itself is
|
|
3281
|
-
* unaffected — only the ID-vs-selfie match is skipped.
|
|
3282
|
-
*
|
|
3283
|
-
* Also `true` on the Digital ID web-redirect (Trinsic iDIN/FTN) COMPLETED path
|
|
3284
|
-
* when the scheme returned no portrait (`isDigitalIdRedirect && !portraitPresent`,
|
|
3285
|
-
* FM-1/FM-2): there is no ID face to match the selfie against.
|
|
3286
|
-
*/
|
|
3287
|
-
function computeIdCaptureOutput(context) {
|
|
3288
|
-
const frontIdCaptured = Boolean(context.capturedImages.front);
|
|
3289
|
-
const backIdCaptured = Boolean(context.capturedImages.back);
|
|
3554
|
+
function getProtectedIdUploadRequest(context, sessionToken = getToken()) {
|
|
3555
|
+
const target = resolveProtectedIdTarget(context.config, context.currentMode);
|
|
3556
|
+
const front = context.currentMode !== "back";
|
|
3557
|
+
const params = { captureType: context.manualCaptureTriggered ? "MANUAL" : "AUTO" };
|
|
3558
|
+
if (front && context.config.onlyFront === true) params.onlyFront = true;
|
|
3559
|
+
if (front && context.config.extractIdFace === false) params.extractIdFace = false;
|
|
3560
|
+
const sharpness = context.qualityElements?.sharpness;
|
|
3561
|
+
if (sharpness !== void 0 && sharpness !== 0 && Number.isFinite(sharpness)) params.sharpness = getRealQualityValue(sharpness);
|
|
3290
3562
|
return {
|
|
3291
|
-
|
|
3292
|
-
|
|
3563
|
+
target,
|
|
3564
|
+
config: {
|
|
3565
|
+
...sessionToken ? { headers: { "X-Incode-Hardware-Id": sessionToken } } : {},
|
|
3566
|
+
params
|
|
3567
|
+
}
|
|
3293
3568
|
};
|
|
3294
3569
|
}
|
|
3295
3570
|
//#endregion
|
|
@@ -3834,12 +4109,8 @@ const idCaptureMachine = setup({
|
|
|
3834
4109
|
digitalUploadMachine,
|
|
3835
4110
|
digitalIdRedirectMachine,
|
|
3836
4111
|
deviceWalletMachine,
|
|
3837
|
-
readPendingDigitalIdRedirect: fromPromise(
|
|
3838
|
-
|
|
3839
|
-
if (!pending) return null;
|
|
3840
|
-
await clearPendingRedirect(input.storage);
|
|
3841
|
-
return pending;
|
|
3842
|
-
})
|
|
4112
|
+
readPendingDigitalIdRedirect: fromPromise(({ input }) => readPendingRedirect(input.storage)),
|
|
4113
|
+
detectCountries: fromPromise(({ input, signal }) => detectDigitalIdCountries(input.dependencies, { signal }))
|
|
3843
4114
|
},
|
|
3844
4115
|
actions: {
|
|
3845
4116
|
attachProtectedController: assign(({ self }) => {
|
|
@@ -3847,7 +4118,7 @@ const idCaptureMachine = setup({
|
|
|
3847
4118
|
return {};
|
|
3848
4119
|
}),
|
|
3849
4120
|
startProtectedMetadataPreparation: ({ context, self }) => {
|
|
3850
|
-
|
|
4121
|
+
getIdProtectedCaptureController(self).startMetadataPreparation(context);
|
|
3851
4122
|
},
|
|
3852
4123
|
bindProtectedControllerLifetime: sendTo("protectedControllerLifetime", ({ self }) => ({
|
|
3853
4124
|
type: "BIND_PROTECTED_ID_CONTROLLER",
|
|
@@ -4229,7 +4500,35 @@ const idCaptureMachine = setup({
|
|
|
4229
4500
|
* it runs inside the tile click's `send()`, preserving the transient
|
|
4230
4501
|
* user activation `navigator.credentials.get()` needs on iOS Safari.
|
|
4231
4502
|
*/
|
|
4232
|
-
resolveDigitalIdRoute: assign(({ context }) => ({ digitalIdRoute: resolveDigitalIdImplementation("mDL", context.config,
|
|
4503
|
+
resolveDigitalIdRoute: assign(({ context }) => ({ digitalIdRoute: resolveDigitalIdImplementation("mDL", context.config, getDigitalIdPlatformSupport(context.dependencies?.credentials)) })),
|
|
4504
|
+
/**
|
|
4505
|
+
* Stores the detected countries and re-ranks the redirect options by them
|
|
4506
|
+
* (`getAvailableDigitalIdRedirectOptions`). The option *set* is unchanged —
|
|
4507
|
+
* country only reorders.
|
|
4508
|
+
*/
|
|
4509
|
+
storeDetectedCountries: assign(({ context, event }) => {
|
|
4510
|
+
const countries = event.output ?? [];
|
|
4511
|
+
return {
|
|
4512
|
+
detectedCountries: countries,
|
|
4513
|
+
digitalIdRedirectOptions: getAvailableDigitalIdRedirectOptions(context.config, countries)
|
|
4514
|
+
};
|
|
4515
|
+
}),
|
|
4516
|
+
/**
|
|
4517
|
+
* The user picked a country on the chooser: it becomes the strongest
|
|
4518
|
+
* country, the detected ones stay behind it as tiebreakers, and the
|
|
4519
|
+
* redirect options are re-ranked. An invalid code is ignored.
|
|
4520
|
+
*/
|
|
4521
|
+
setChooserCountry: assign(({ context, event }) => {
|
|
4522
|
+
const country = event.type === "SET_CHOOSER_COUNTRY" ? normalizeCountryCode(event.country) : void 0;
|
|
4523
|
+
if (!country) return {};
|
|
4524
|
+
const countries = [country, ...(context.detectedCountries ?? []).filter((detected) => detected !== country)];
|
|
4525
|
+
return {
|
|
4526
|
+
detectedCountries: countries,
|
|
4527
|
+
digitalIdRedirectOptions: rankDigitalIdRedirectOptions(context.digitalIdRedirectOptions, context.config, countries)
|
|
4528
|
+
};
|
|
4529
|
+
}),
|
|
4530
|
+
/** Detection failed outright: mark it done so it is not retried. */
|
|
4531
|
+
markCountryDetectionFailed: assign({ detectedCountries: () => [] }),
|
|
4233
4532
|
/**
|
|
4234
4533
|
* Records a completed device-wallet (mDL) handshake from the child's
|
|
4235
4534
|
* `onDone` output. Wallet credentials are single-side; the verified
|
|
@@ -4271,6 +4570,13 @@ const idCaptureMachine = setup({
|
|
|
4271
4570
|
digitalIdResumeProviderId: () => void 0,
|
|
4272
4571
|
digitalIdRoute: () => void 0
|
|
4273
4572
|
}),
|
|
4573
|
+
/**
|
|
4574
|
+
* Drops the persisted return-leg record once the digital-ID attempt ends.
|
|
4575
|
+
* Fire-and-forget: a stale record is only read on the host's return route.
|
|
4576
|
+
*/
|
|
4577
|
+
clearPendingDigitalIdRedirect: ({ context }) => {
|
|
4578
|
+
clearPendingRedirect(resolveIdCaptureDependencies(context.dependencies).storage).catch(() => void 0);
|
|
4579
|
+
},
|
|
4274
4580
|
incrementProcessingExpiredAttempts: assign(({ context }) => ({ processingExpiredAttempts: context.processingExpiredAttempts + 1 })),
|
|
4275
4581
|
setSkipProcessId: assign({ skipProcessId: () => true }),
|
|
4276
4582
|
setExpiredFromUpload: assign({ expiredFromUpload: () => true }),
|
|
@@ -4283,10 +4589,15 @@ const idCaptureMachine = setup({
|
|
|
4283
4589
|
isCaptureOnlyDelivery: ({ context }) => hasOnCaptureCallback(context.config),
|
|
4284
4590
|
isProtectedUploadFailure: ({ event }) => protectedFailure(event)?.failure.stage === "upload",
|
|
4285
4591
|
isProtectedManualRefusal: ({ event }) => protectedFailure(event)?.failure.stage === "manualCommit",
|
|
4592
|
+
isProtectedAcquireDenied: ({ event }) => {
|
|
4593
|
+
const failure = protectedFailure(event)?.failure;
|
|
4594
|
+
return failure?.stage === "acquire" && isCameraDenialErrorName(failure.errorName);
|
|
4595
|
+
},
|
|
4286
4596
|
canCaptureManuallyDuringDetection: ({ context }) => context.config.showCaptureButtonInAuto === true && context.detectionStatus !== "capturing",
|
|
4287
4597
|
hasShowTutorial: hasShowTutorialGuard,
|
|
4288
4598
|
hasAgeAssurance: hasAgeAssuranceGuard,
|
|
4289
4599
|
hasShowDocumentChooser: hasShowDocumentChooserGuard,
|
|
4600
|
+
needsCountryDetection: needsCountryDetectionGuard,
|
|
4290
4601
|
isPermissionGranted: ({ event }) => isPermissionGrantedGuard({ event: asPublicIdEvent(event) }),
|
|
4291
4602
|
isReadyForCapture: ({ context, event }) => isReadyForCaptureGuard({
|
|
4292
4603
|
context,
|
|
@@ -4383,9 +4694,22 @@ const idCaptureMachine = setup({
|
|
|
4383
4694
|
},
|
|
4384
4695
|
context: ({ input, self }) => {
|
|
4385
4696
|
attachIdProtectedCaptureController(self, createIdProtectedCaptureController());
|
|
4697
|
+
const carried = carryAttempts(input.config.isSecondId ? "secondIdCapture" : "idCapture", self, (s, previous) => {
|
|
4698
|
+
const c = s.context;
|
|
4699
|
+
const child = s.children.digitalIdUpload?.getSnapshot()?.context;
|
|
4700
|
+
const left = Math.min(previous.attemptsRemaining ?? Infinity, c.attemptsRemaining, child?.attemptsRemaining ?? Infinity);
|
|
4701
|
+
return {
|
|
4702
|
+
attemptsRemaining: s.matches("expiredExhausted") || left <= 0 && left < c.config.captureAttempts ? -1 : left,
|
|
4703
|
+
expiredAttempts: Math.max(previous.expiredAttempts ?? 0, c.expiredAttempts),
|
|
4704
|
+
expiredRedirected: c.expiredRedirected,
|
|
4705
|
+
processingExpiredAttempts: c.processingExpiredAttempts,
|
|
4706
|
+
skipProcessId: previous.skipProcessId === true || c.skipProcessId || s.matches("expiredExhausted") && !shouldProcessAfterExhaustionGuard({ context: c })
|
|
4707
|
+
};
|
|
4708
|
+
});
|
|
4709
|
+
const configured = input.config.captureAttempts ?? 1;
|
|
4386
4710
|
const config = {
|
|
4387
4711
|
...input.config,
|
|
4388
|
-
captureAttempts:
|
|
4712
|
+
captureAttempts: Math.max(0, Math.min(configured, carried.attemptsRemaining ?? configured))
|
|
4389
4713
|
};
|
|
4390
4714
|
const currentMode = input.config.onlyBack ? "back" : !input.config.enableId && input.config.enablePassport ? "passport" : input.config.usSmartCapture ? "back" : "front";
|
|
4391
4715
|
return {
|
|
@@ -4409,11 +4733,11 @@ const idCaptureMachine = setup({
|
|
|
4409
4733
|
barcodeFastPathAttempted: false,
|
|
4410
4734
|
barcodeFastPathCaptured: false,
|
|
4411
4735
|
recordingSession: void 0,
|
|
4412
|
-
attemptsRemaining: config.captureAttempts,
|
|
4413
|
-
expiredAttempts: 0,
|
|
4414
|
-
expiredRedirected: false,
|
|
4415
|
-
processingExpiredAttempts: 0,
|
|
4416
|
-
skipProcessId: input.config.skipProcessId === true,
|
|
4736
|
+
attemptsRemaining: Math.min(config.captureAttempts, carried.attemptsRemaining ?? Infinity),
|
|
4737
|
+
expiredAttempts: carried.expiredAttempts ?? 0,
|
|
4738
|
+
expiredRedirected: carried.expiredRedirected ?? false,
|
|
4739
|
+
processingExpiredAttempts: carried.processingExpiredAttempts ?? 0,
|
|
4740
|
+
skipProcessId: input.config.skipProcessId === true || (carried.attemptsRemaining ?? 0) < 0 && carried.skipProcessId === true,
|
|
4417
4741
|
expiredFromUpload: false,
|
|
4418
4742
|
isDigitalUpload: false,
|
|
4419
4743
|
isDigitalIdRedirect: false,
|
|
@@ -4442,8 +4766,10 @@ const idCaptureMachine = setup({
|
|
|
4442
4766
|
dependencies: resolveIdCaptureDependencies(input.dependencies),
|
|
4443
4767
|
disableIpify: getDisableIpify(),
|
|
4444
4768
|
deepsightInitAttempted: false,
|
|
4445
|
-
availableDocumentTypes: getAvailableDocumentTypes(input.config,
|
|
4769
|
+
availableDocumentTypes: getAvailableDocumentTypes(input.config, getDigitalIdPlatformSupport(input.dependencies?.credentials)),
|
|
4446
4770
|
digitalIdRedirectOptions: getAvailableDigitalIdRedirectOptions(input.config),
|
|
4771
|
+
detectedCountries: void 0,
|
|
4772
|
+
walletDevice: resolveWalletDevice(),
|
|
4447
4773
|
selectedDigitalIdProviderId: void 0,
|
|
4448
4774
|
captureResolution: void 0,
|
|
4449
4775
|
cameraFallbackLevel: void 0,
|
|
@@ -4460,11 +4786,20 @@ const idCaptureMachine = setup({
|
|
|
4460
4786
|
target: "digitalIdRedirectReturning",
|
|
4461
4787
|
guard: "hasDigitalIdReturn"
|
|
4462
4788
|
},
|
|
4789
|
+
{
|
|
4790
|
+
target: "processing",
|
|
4791
|
+
guard: ({ context }) => context.attemptsRemaining < 0,
|
|
4792
|
+
actions: ["flagIdManualReview", "setForceFinishAfterProcessing"]
|
|
4793
|
+
},
|
|
4463
4794
|
{
|
|
4464
4795
|
target: "error",
|
|
4465
4796
|
guard: "hasNoDocumentTypesAvailable",
|
|
4466
4797
|
actions: [() => console.error(ID_CAPTURE_NO_DOCUMENT_TYPES_ERROR), assign({ error: () => ID_CAPTURE_NO_DOCUMENT_TYPES_ERROR })]
|
|
4467
4798
|
},
|
|
4799
|
+
{
|
|
4800
|
+
target: "detectingCountry",
|
|
4801
|
+
guard: and(["hasShowDocumentChooser", "needsCountryDetection"])
|
|
4802
|
+
},
|
|
4468
4803
|
{
|
|
4469
4804
|
target: "chooser",
|
|
4470
4805
|
guard: "hasShowDocumentChooser"
|
|
@@ -4479,37 +4814,53 @@ const idCaptureMachine = setup({
|
|
|
4479
4814
|
},
|
|
4480
4815
|
{ target: "loading" }
|
|
4481
4816
|
] } },
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
target: "digitalIdRedirect",
|
|
4490
|
-
guard: "isDigitalIdRedirectSelected",
|
|
4491
|
-
actions: ["setSelectedDocument"]
|
|
4492
|
-
},
|
|
4493
|
-
{
|
|
4494
|
-
target: "digitalIdUpload",
|
|
4495
|
-
guard: "isDigitalIdUploadSelected",
|
|
4496
|
-
actions: ["setSelectedDocument"]
|
|
4497
|
-
},
|
|
4498
|
-
{
|
|
4499
|
-
target: "ageVerification",
|
|
4500
|
-
guard: "hasAgeAssurance",
|
|
4501
|
-
actions: ["setSelectedDocument", "setCurrentMode"]
|
|
4502
|
-
},
|
|
4503
|
-
{
|
|
4504
|
-
target: "tutorial",
|
|
4505
|
-
guard: "hasShowTutorial",
|
|
4506
|
-
actions: ["setSelectedDocument", "setCurrentMode"]
|
|
4817
|
+
detectingCountry: { invoke: {
|
|
4818
|
+
id: "detectCountries",
|
|
4819
|
+
src: "detectCountries",
|
|
4820
|
+
input: ({ context }) => ({ dependencies: context.dependencies?.countryDetection ?? {} }),
|
|
4821
|
+
onDone: {
|
|
4822
|
+
target: "chooser",
|
|
4823
|
+
actions: "storeDetectedCountries"
|
|
4507
4824
|
},
|
|
4508
|
-
{
|
|
4509
|
-
target: "
|
|
4510
|
-
actions:
|
|
4825
|
+
onError: {
|
|
4826
|
+
target: "chooser",
|
|
4827
|
+
actions: "markCountryDetectionFailed"
|
|
4511
4828
|
}
|
|
4512
|
-
|
|
4829
|
+
} },
|
|
4830
|
+
chooser: { on: {
|
|
4831
|
+
SET_CHOOSER_COUNTRY: { actions: "setChooserCountry" },
|
|
4832
|
+
SELECT_DOCUMENT: [
|
|
4833
|
+
{
|
|
4834
|
+
target: "digitalIdRouting",
|
|
4835
|
+
guard: "isDigitalIdSelected",
|
|
4836
|
+
actions: ["setSelectedDocument", "resolveDigitalIdRoute"]
|
|
4837
|
+
},
|
|
4838
|
+
{
|
|
4839
|
+
target: "digitalIdRedirect",
|
|
4840
|
+
guard: "isDigitalIdRedirectSelected",
|
|
4841
|
+
actions: ["setSelectedDocument"]
|
|
4842
|
+
},
|
|
4843
|
+
{
|
|
4844
|
+
target: "digitalIdUpload",
|
|
4845
|
+
guard: "isDigitalIdUploadSelected",
|
|
4846
|
+
actions: ["setSelectedDocument"]
|
|
4847
|
+
},
|
|
4848
|
+
{
|
|
4849
|
+
target: "ageVerification",
|
|
4850
|
+
guard: "hasAgeAssurance",
|
|
4851
|
+
actions: ["setSelectedDocument", "setCurrentMode"]
|
|
4852
|
+
},
|
|
4853
|
+
{
|
|
4854
|
+
target: "tutorial",
|
|
4855
|
+
guard: "hasShowTutorial",
|
|
4856
|
+
actions: ["setSelectedDocument", "setCurrentMode"]
|
|
4857
|
+
},
|
|
4858
|
+
{
|
|
4859
|
+
target: "loading",
|
|
4860
|
+
actions: ["setSelectedDocument", "setCurrentMode"]
|
|
4861
|
+
}
|
|
4862
|
+
]
|
|
4863
|
+
} },
|
|
4513
4864
|
ageVerification: {
|
|
4514
4865
|
entry: "startProtectedMetadataPreparation",
|
|
4515
4866
|
on: { NEXT_STEP: [{
|
|
@@ -4824,6 +5175,11 @@ const idCaptureMachine = setup({
|
|
|
4824
5175
|
guard: "isProtectedUploadFailure",
|
|
4825
5176
|
actions: "setProtectedUploadFailure"
|
|
4826
5177
|
},
|
|
5178
|
+
{
|
|
5179
|
+
target: "#idCapture.permissions.denied",
|
|
5180
|
+
guard: "isProtectedAcquireDenied",
|
|
5181
|
+
actions: assign({ permissionResult: () => "denied" })
|
|
5182
|
+
},
|
|
4827
5183
|
{
|
|
4828
5184
|
target: "#idCapture.error",
|
|
4829
5185
|
actions: "setProtectedFailure"
|
|
@@ -5475,6 +5831,11 @@ const idCaptureMachine = setup({
|
|
|
5475
5831
|
target: "digitalIdRedirect",
|
|
5476
5832
|
actions: ["storePendingDigitalIdRedirect"]
|
|
5477
5833
|
},
|
|
5834
|
+
{
|
|
5835
|
+
target: "detectingCountry",
|
|
5836
|
+
guard: and(["hasShowDocumentChooser", "needsCountryDetection"]),
|
|
5837
|
+
actions: ["clearDigitalIdAttempt"]
|
|
5838
|
+
},
|
|
5478
5839
|
{
|
|
5479
5840
|
target: "chooser",
|
|
5480
5841
|
guard: "hasShowDocumentChooser",
|
|
@@ -5485,14 +5846,22 @@ const idCaptureMachine = setup({
|
|
|
5485
5846
|
actions: ["clearDigitalIdAttempt"]
|
|
5486
5847
|
}
|
|
5487
5848
|
],
|
|
5488
|
-
onError: [
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5849
|
+
onError: [
|
|
5850
|
+
{
|
|
5851
|
+
target: "detectingCountry",
|
|
5852
|
+
guard: and(["hasShowDocumentChooser", "needsCountryDetection"]),
|
|
5853
|
+
actions: ["clearDigitalIdAttempt"]
|
|
5854
|
+
},
|
|
5855
|
+
{
|
|
5856
|
+
target: "chooser",
|
|
5857
|
+
guard: "hasShowDocumentChooser",
|
|
5858
|
+
actions: ["clearDigitalIdAttempt"]
|
|
5859
|
+
},
|
|
5860
|
+
{
|
|
5861
|
+
target: "loading",
|
|
5862
|
+
actions: ["clearDigitalIdAttempt"]
|
|
5863
|
+
}
|
|
5864
|
+
]
|
|
5496
5865
|
},
|
|
5497
5866
|
on: { QUIT: { target: "closed" } }
|
|
5498
5867
|
},
|
|
@@ -5525,17 +5894,26 @@ const idCaptureMachine = setup({
|
|
|
5525
5894
|
{
|
|
5526
5895
|
guard: "isDigitalIdRedirectCompleted",
|
|
5527
5896
|
target: "#idCapture.finished",
|
|
5528
|
-
actions: ["storeDigitalIdRedirectResult"]
|
|
5897
|
+
actions: ["storeDigitalIdRedirectResult", "clearPendingDigitalIdRedirect"]
|
|
5898
|
+
},
|
|
5899
|
+
{
|
|
5900
|
+
target: "detectingCountry",
|
|
5901
|
+
guard: and(["hasShowDocumentChooser", "needsCountryDetection"]),
|
|
5902
|
+
actions: ["clearPendingDigitalIdRedirect"]
|
|
5529
5903
|
},
|
|
5530
5904
|
{
|
|
5531
5905
|
target: "chooser",
|
|
5532
|
-
guard: "hasShowDocumentChooser"
|
|
5906
|
+
guard: "hasShowDocumentChooser",
|
|
5907
|
+
actions: ["clearPendingDigitalIdRedirect"]
|
|
5533
5908
|
},
|
|
5534
|
-
{
|
|
5909
|
+
{
|
|
5910
|
+
target: "closed",
|
|
5911
|
+
actions: ["clearPendingDigitalIdRedirect"]
|
|
5912
|
+
}
|
|
5535
5913
|
],
|
|
5536
5914
|
onError: {
|
|
5537
5915
|
target: "#idCapture.error",
|
|
5538
|
-
actions: assign({ error: ({ event }) => String(event.error) })
|
|
5916
|
+
actions: [assign({ error: ({ event }) => String(event.error) }), "clearPendingDigitalIdRedirect"]
|
|
5539
5917
|
}
|
|
5540
5918
|
},
|
|
5541
5919
|
on: {
|
|
@@ -5615,4 +5993,4 @@ function provideIdProtectedCaptureController(machine, controller) {
|
|
|
5615
5993
|
});
|
|
5616
5994
|
}
|
|
5617
5995
|
//#endregion
|
|
5618
|
-
export { mapDeviceWalletScreenName as _,
|
|
5996
|
+
export { mapDeviceWalletScreenName as _, createIdProtectedCaptureController as a, hasOnCaptureCallback as c, DIGITAL_ID_REGISTRY as d, isRedirectFlowType as f, BrowserDigitalCredentialsProvider as g, createDeviceWalletManager as h, createIdCaptureOnlyDeliveryActor as i, pickIdCaptureOnlyConfig as l, renderWallet as m, provideIdProtectedCaptureController as n, findIdProtectedCaptureController as o, resolveDigitalIdImplementation as p, attachIdProtectedCaptureController as r, captureOnlyNeedsBack as s, idCaptureMachine as t, DIGITAL_ID_DOCUMENT_TYPES as u, resolveWalletPlatform as v };
|