@trymellon/js 2.3.1 → 2.3.2

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/index.d.cts CHANGED
@@ -726,6 +726,11 @@ declare class TryMellon {
726
726
  * This constructor will throw errors if configuration is invalid.
727
727
  */
728
728
  constructor(config: TryMellonConfig);
729
+ /**
730
+ * DX: warn when sandbox is ON and origin is not localhost/127.0.0.1 (e.g. production).
731
+ * No-op in non-browser (SSR/Node). No exceptions; only console.warn.
732
+ */
733
+ private warnIfSandboxOnProd;
729
734
  /**
730
735
  * Bridge (KP-BRIDGE-04): complete enrollment or auth from a second device (e.g. mobile scanning desktop QR).
731
736
  * Use kind 'enrollment' for enrollment-bridge sessions, 'auth' for auth-bridge sessions.
package/dist/index.d.ts CHANGED
@@ -726,6 +726,11 @@ declare class TryMellon {
726
726
  * This constructor will throw errors if configuration is invalid.
727
727
  */
728
728
  constructor(config: TryMellonConfig);
729
+ /**
730
+ * DX: warn when sandbox is ON and origin is not localhost/127.0.0.1 (e.g. production).
731
+ * No-op in non-browser (SSR/Node). No exceptions; only console.warn.
732
+ */
733
+ private warnIfSandboxOnProd;
729
734
  /**
730
735
  * Bridge (KP-BRIDGE-04): complete enrollment or auth from a second device (e.g. mobile scanning desktop QR).
731
736
  * Use kind 'enrollment' for enrollment-bridge sessions, 'auth' for auth-bridge sessions.
@@ -1,3 +1,3 @@
1
- var TryMellon=(function(exports){'use strict';var ce="https://api.trymellonauth.com",je="https://api.trymellonauth.com/v1/telemetry";var pe="trymellon_sandbox_session_token_v1",He="/v1/enrollment-bridge",Ve="/v1/auth-bridge";var d=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var B=class e extends Error{code;details;isTryMellonError=true;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e);}},dr={NOT_SUPPORTED:"WebAuthn is not supported in this environment",USER_CANCELLED:"User cancelled the operation",PASSKEY_NOT_FOUND:"Passkey not found",SESSION_EXPIRED:"Session has expired",NETWORK_FAILURE:"Network request failed",INVALID_ARGUMENT:"Invalid argument provided",TIMEOUT:"Operation timed out",ABORTED:"Operation was aborted",ABORT_ERROR:"Operation aborted by user or timeout",CHALLENGE_MISMATCH:"This link was already used or expired. Please try again from your computer.",TICKET_NOT_FOUND:"Enrollment ticket not found or invalid",TICKET_EXPIRED:"Enrollment ticket has expired",TICKET_ALREADY_USED:"Enrollment ticket was already used",PIN_MISMATCH:"PIN does not match",PIN_LOCKED:"PIN is locked due to too many failed attempts",BRIDGE_SESSION_EXPIRED:"Bridge session has expired",UNKNOWN_ERROR:"An unknown error occurred"};function f(e,r,t){return new B(e,r??dr[e],t)}function H(e){return e instanceof B||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function ge(){return f("NOT_SUPPORTED")}function cr(){return f("USER_CANCELLED")}function pr(e){return f("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function gr(){return f("TIMEOUT")}function _(e,r){return f("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function qe(e){return f("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function me(e){return f("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function We(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw _(r,"must use http or https protocol")}catch(t){throw H(t)?t:_(r,"must be a valid URL")}}function V(e,r,t,n){if(!Number.isFinite(e))throw _(r,"must be a finite number");if(e<t||e>n)throw _(r,`must be between ${t} and ${n}`)}function q(e,r){if(typeof e!="string"||e.length===0)throw _(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw _(r,"must be a valid base64url string")}var mr={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function L(e){if(typeof e!="string")return "UNKNOWN_ERROR";let r=e.toLowerCase().trim();return {challenge_mismatch:"CHALLENGE_MISMATCH",session_expired:"SESSION_EXPIRED",unauthorized:"SESSION_EXPIRED",validation_error:"INVALID_ARGUMENT",invalid_argument:"INVALID_ARGUMENT",user_not_found:"SESSION_EXPIRED",passkey_not_found:"PASSKEY_NOT_FOUND",ticket_not_found:"TICKET_NOT_FOUND",ticket_expired:"TICKET_EXPIRED",ticket_already_consumed:"TICKET_ALREADY_USED",not_found:"TICKET_NOT_FOUND",expired:"TICKET_EXPIRED",already_consumed:"TICKET_ALREADY_USED",context_mismatch:"CHALLENGE_MISMATCH",challenge_not_found:"CHALLENGE_MISMATCH",invalid_ticket_id:"INVALID_ARGUMENT",invalid_context_hash:"INVALID_ARGUMENT",invalid_ticket_status:"INVALID_ARGUMENT",invalid_config:"INVALID_ARGUMENT",enrollment_not_enabled:"INVALID_ARGUMENT",pin_mismatch:"PIN_MISMATCH",pin_locked:"PIN_LOCKED",bridge_not_enabled:"UNKNOWN_ERROR",bridge_session_expired:"BRIDGE_SESSION_EXPIRED",session_not_found:"BRIDGE_SESSION_EXPIRED"}[r]??"UNKNOWN_ERROR"}function v(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=mr[r]??"UNKNOWN_ERROR";return f(n,t,{originalError:e})}return e instanceof Error?f("UNKNOWN_ERROR",e.message,{originalError:e}):f("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function m(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function u(e){return typeof e=="string"}function P(e){return typeof e=="number"&&Number.isFinite(e)}function W(e){return typeof e=="boolean"}function D(e){return Array.isArray(e)}function o(e,r){return a(f("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function c(e,r){return e[r]}function fr(e,r){return !m(e)||!u(e.name)||!u(e.id)?o("Invalid API response: challenge.rp must have name and id strings",{originalData:r}):d(true)}function Rr(e,r){return !m(e)||!u(e.id)||!u(e.name)||!u(e.displayName)?o("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:r}):d(true)}function yr(e,r){if(!D(e))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:r});for(let t of e)if(!m(t)||t.type!=="public-key"||!P(t.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:r});return d(true)}function G(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id");if(!u(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=c(e,"challenge");if(!m(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=fr(c(t,"rp"),e);if(!n.ok)return n;let s=Rr(c(t,"user"),e);if(!s.ok)return s;let i=c(t,"challenge");if(!u(i))return o("Invalid API response: challenge.challenge must be string",{originalData:e});let l=yr(c(t,"pubKeyCredParams"),e);if(!l.ok)return l;let p=t.timeout;if(p!==void 0&&!P(p))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let g=t.excludeCredentials;if(g!==void 0){if(!D(g))return o("Invalid API response: excludeCredentials must be array",{originalData:e});for(let R of g)if(!m(R)||R.type!=="public-key"||!u(R.id))return o("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let y=t.authenticatorSelection;return y!==void 0&&!m(y)?o("Invalid API response: authenticatorSelection must be object",{originalData:e}):d({session_id:r,challenge:{rp:t.rp,user:t.user,challenge:i,pubKeyCredParams:t.pubKeyCredParams,...p!==void 0&&{timeout:p},...g!==void 0&&{excludeCredentials:g},...y!==void 0&&{authenticatorSelection:y}}})}function fe(e,r){if(!m(e))return o("Invalid API response: user must be object",{field:"user",originalData:r});let t=c(e,"user_id"),n=c(e,"external_user_id");if(!u(t)||!u(n))return o("Invalid API response: user must have user_id and external_user_id strings",{originalData:r});let s=e.email,i=e.metadata;return s!==void 0&&!u(s)?o("Invalid API response: user.email must be string",{originalData:r}):i!==void 0&&(typeof i!="object"||i===null)?o("Invalid API response: user.metadata must be object",{originalData:r}):d({user_id:t,external_user_id:n,...s!==void 0&&{email:s},...i!==void 0&&{metadata:i}})}function Re(e){let r=G(e);return r.ok?d({session_id:r.value.session_id,challenge:r.value.challenge}):r}function ye(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id");if(!u(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=c(e,"challenge");if(!m(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=c(t,"challenge"),s=c(t,"rpId"),i=t.allowCredentials;if(!u(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!u(s))return o("Invalid API response: challenge.rpId must be string",{originalData:e});if(i!==void 0&&!D(i))return o("Invalid API response: allowCredentials must be array",{originalData:e});if(i){for(let g of i)if(!m(g)||g.type!=="public-key"||!u(g.id))return o("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let l=t.timeout;if(l!==void 0&&!P(l))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let p=t.userVerification;return p!==void 0&&!["required","preferred","discouraged"].includes(String(p))?o("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):d({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:i??[],...l!==void 0&&{timeout:l},...p!==void 0&&{userVerification:p}}})}function he(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"credential_id"),t=c(e,"status"),n=c(e,"session_token"),s=c(e,"user");if(!u(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!u(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!u(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});let i=fe(s,e);if(!i.ok)return a(i.error);let l=e.redirect_url;return l!==void 0&&!u(l)?o("Invalid API response: redirect_url must be string",{originalData:e}):d({credential_id:r,status:t,session_token:n,user:i.value,...l!==void 0&&{redirect_url:l}})}function ve(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"authenticated"),t=c(e,"session_token"),n=c(e,"user"),s=c(e,"signals");if(!W(r))return o("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!u(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});let i=fe(n,e);if(!i.ok)return a(i.error);if(s!==void 0&&!m(s))return o("Invalid API response: signals must be object",{originalData:e});let l=e.redirect_url;return l!==void 0&&!u(l)?o("Invalid API response: redirect_url must be string",{originalData:e}):d({authenticated:r,session_token:t,user:i.value,signals:s,...l!==void 0&&{redirect_url:l}})}function Ee(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"valid"),t=c(e,"user_id"),n=c(e,"external_user_id"),s=c(e,"tenant_id"),i=c(e,"app_id");return W(r)?u(t)?u(n)?u(s)?u(i)?d({valid:r,userId:t,externalUserId:n,tenantId:s,appId:i}):o("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):o("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):o("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):o("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):o("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function _e(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=e.session_token??e.sessionToken;if(!u(r))return o("Invalid API response: session_token/sessionToken must be string",{field:"session_token",originalData:e});let t=e.redirect_url;return t!==void 0&&!u(t)?o("Invalid API response: redirect_url must be string",{originalData:e}):d({sessionToken:r,...t!==void 0&&{redirectUrl:t}})}var hr=["pending_passkey","pending_data","completed"],vr=["pending_data","completed"];function be(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"onboarding_url"),n=c(e,"expires_in");return u(r)?u(t)?P(n)?d({session_id:r,onboarding_url:t,expires_in:n}):o("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):o("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):o("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function Te(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"status"),t=c(e,"onboarding_url"),n=c(e,"expires_in");return !u(r)||!hr.includes(r)?o("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):u(t)?P(n)?d({status:r,onboarding_url:t,expires_in:n}):o("Invalid API response: expires_in must be number",{originalData:e}):o("Invalid API response: onboarding_url must be string",{originalData:e})}function Ie(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"status"),n=c(e,"onboarding_url");if(!u(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return o("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!u(n))return o("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,i;if(s!==void 0){let l=Er(s);if(!l.ok)return l;i=l.value;}return d({session_id:r,status:"pending_passkey",onboarding_url:n,...i!==void 0&&{challenge:i}})}function Er(e){if(!m(e))return o("Invalid API response: challenge must be object",{originalData:e});let r=c(e,"rp"),t=c(e,"user"),n=c(e,"challenge"),s=c(e,"pubKeyCredParams");if(!m(r)||!u(r.name)||!u(r.id))return o("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!m(t)||!u(t.id)||!u(t.name)||!u(t.displayName))return o("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!u(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!D(s))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let i of s)if(!m(i)||i.type!=="public-key"||!P(i.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return d({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function Ae(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"status"),n=c(e,"user_id"),s=c(e,"tenant_id");return u(r)?!u(t)||!vr.includes(t)?o("Invalid API response: status must be pending_data|completed",{originalData:e}):u(n)?u(s)?d({session_id:r,status:t,user_id:n,tenant_id:s}):o("Invalid API response: tenant_id must be string",{originalData:e}):o("Invalid API response: user_id must be string",{originalData:e}):o("Invalid API response: session_id must be string",{originalData:e})}function Ce(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"status"),n=c(e,"user_id"),s=c(e,"tenant_id"),i=c(e,"session_token");return u(r)?t!=="completed"?o("Invalid API response: status must be completed",{originalData:e}):!u(n)||!u(s)||!u(i)?o("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):d({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:i}):o("Invalid API response: session_id must be string",{originalData:e})}function X(e){return e==null?d(void 0):m(e)&&Object.keys(e).length===0?d(void 0):o("Invalid API response: expected empty body (204)",{originalData:e})}function _r(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&r.rp!=null&&typeof r.rp=="object"&&r.user!=null&&typeof r.user=="object"&&Array.isArray(r.pubKeyCredParams)}function br(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function $(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r="resultado"in e&&m(e.resultado)?e.resultado:e,t=r.session_id,n=r.qr_url,s=r.expires_at,i=r.polling_token;if(!u(t)||!u(n)||!u(s)||!u(i))return o("Invalid API response: missing required fields",{originalData:e});let l={session_id:t,qr_url:n,expires_at:s,polling_token:i};return r.external_user_id!==void 0&&u(r.external_user_id)&&(l.external_user_id=r.external_user_id),d(l)}function Se(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r="resultado"in e&&m(e.resultado)?e.resultado:e,t=r.status;if(!u(t)||!["pending","authenticated","completed"].includes(t))return o("Invalid API response: invalid status",{originalData:e});let n=r.user_id,s=r.session_token,i=r.redirect_url;return n!==void 0&&!u(n)?o("Invalid API response: user_id must be a string when present",{originalData:e}):s!==void 0&&!u(s)?o("Invalid API response: session_token must be a string when present",{originalData:e}):i!==void 0&&!u(i)?o("Invalid API response: redirect_url must be a string when present",{originalData:e}):d({status:t,user_id:n,session_token:s,redirect_url:i})}function ke(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;if(!m(n))return o("Invalid API response: options are required",{originalData:e});let s=200,i=Ge(e.approval_context,s),l=Ge(e.application_name,s);if(i===false||l===false)return o("Invalid API response: approval_context/application_name must be string max 200 chars",{originalData:e});let p={};return typeof i=="string"&&(p.approval_context=i),typeof l=="string"&&(p.application_name=l),t==="registration"?_r(n)?d({type:"registration",options:n,...p}):o("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):br(n)?d({type:"auth",options:n,...p}):o("Invalid API response: auth options must have challenge and rpId",{originalData:e})}function Ge(e,r){if(e!=null)return typeof e!="string"||e.length>r?false:e}function xe(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"challenge"),t=c(e,"recovery_session_id");return m(r)?u(t)?d({challenge:r,recovery_session_id:t}):o("Invalid API response: recovery_session_id must be string",{field:"recovery_session_id",originalData:e}):o("Invalid API response: challenge must be object",{field:"challenge",originalData:e})}function Oe(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"status"),t=c(e,"session_token"),n=c(e,"user"),s=c(e,"credential_id");if(!u(r))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!u(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!u(s))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!m(n))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=c(n,"user_id");if(!u(i))return o("Invalid API response: user.user_id must be string",{field:"user.user_id",originalData:e});let p=e.redirect_url;if(p!==void 0&&!u(p))return o("Invalid API response: redirect_url must be string",{field:"redirect_url",originalData:e});let g=n;return d({status:r,session_token:t,credential_id:s,user:{user_id:i,external_user_id:u(g.external_user_id)?g.external_user_id:void 0,email:u(g.email)?g.email:void 0,metadata:m(g.metadata)?g.metadata:void 0},...p!==void 0&&{redirect_url:p}})}function Pe(e){let r=G(e);return r.ok?d({session_id:r.value.session_id,challenge:r.value.challenge}):r}function Tr(e,r){if(!m(e))return o("Invalid API response: user must be object",{field:"user",originalData:r});let t=c(e,"user_id");if(!u(t))return o("Invalid API response: user.user_id must be string",{originalData:r});let n=e.external_user_id;if(n!==void 0&&!u(n))return o("Invalid API response: user.external_user_id must be string",{originalData:r});let s=e.email;if(s!==void 0&&!u(s))return o("Invalid API response: user.email must be string",{originalData:r});let i=e.metadata;return i!==void 0&&(typeof i!="object"||i===null)?o("Invalid API response: user.metadata must be object",{originalData:r}):d({user_id:t,...n!==void 0&&{external_user_id:n},...s!==void 0&&{email:s},...i!==void 0&&{metadata:i}})}function De(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"credential_id"),t=c(e,"status"),n=c(e,"session_token"),s=c(e,"user");if(!u(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!u(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!u(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});let i=Tr(s,e);return i.ok?d({credential_id:r,status:t,session_token:n,user:i.value}):i}var Ir=["pending","pin_verified","pin_locked","completed"];function Me(e){if(!m(e))return o("Invalid bridge context response: expected object",{originalData:e});let r=c(e,"type");if(r!=="auth"&&r!=="registration")return o('Invalid bridge context response: type must be "auth" or "registration"',{field:"type",expected:"auth | registration",originalData:e});let t=c(e,"options");if(!m(t))return o("Invalid bridge context response: options must be object",{field:"options",originalData:e});let n=e.application_name;return n!==void 0&&!u(n)?o("Invalid bridge context response: application_name must be string",{field:"application_name",originalData:e}):d({type:r,options:t,...n!==void 0&&{application_name:n}})}function we(e){if(!m(e))return o("Invalid bridge verify response: expected object",{originalData:e});let r=c(e,"session_id");if(!u(r)||r.trim()==="")return o("Invalid bridge verify response: session_id must be non-empty string (UUID expected)",{field:"session_id",originalData:e});let t=e.challenge;if(t!==void 0&&!u(t))return o("Invalid bridge verify response: challenge must be string when present",{field:"challenge",originalData:e});let n=e.registration_options;if(n!==void 0&&!m(n))return o("Invalid bridge verify response: registration_options must be object when present",{field:"registration_options",originalData:e});let s=e.authentication_options;return s!==void 0&&!m(s)?o("Invalid bridge verify response: authentication_options must be object when present",{field:"authentication_options",originalData:e}):d({session_id:r,...t!==void 0&&{challenge:t},...n!==void 0&&{registration_options:n},...s!==void 0&&{authentication_options:s}})}function Ne(e){if(!m(e))return o("Invalid bridge complete enrollment response: expected object",{originalData:e});let r=c(e,"credential_id"),t=c(e,"entity_id"),n=c(e,"user_id"),s=c(e,"session_token");return u(r)?u(t)?u(n)?u(s)?d({credential_id:r,entity_id:t,user_id:n,session_token:s}):o("Invalid bridge complete enrollment response: session_token must be string",{field:"session_token",originalData:e}):o("Invalid bridge complete enrollment response: user_id must be string",{field:"user_id",originalData:e}):o("Invalid bridge complete enrollment response: entity_id must be string",{field:"entity_id",originalData:e}):o("Invalid bridge complete enrollment response: credential_id must be string",{field:"credential_id",originalData:e})}function Ue(e){if(!m(e))return o("Invalid bridge complete auth response: expected object",{originalData:e});let r=c(e,"session_token");return u(r)?d({session_token:r}):o("Invalid bridge complete auth response: session_token must be string",{field:"session_token",originalData:e})}function Be(e){if(!m(e))return o("Invalid bridge status response: expected object",{originalData:e});let r=c(e,"status");if(typeof r!="string"||!Ir.includes(r))return o("Invalid bridge status response: status must be one of pending, pin_verified, pin_locked, completed",{field:"status",originalData:e});let t=e.ts;return t!==void 0&&!u(t)?o("Invalid bridge status response: ts must be string when present",{field:"ts",originalData:e}):d({status:r,...t!==void 0&&{ts:t}})}var Y=class{constructor(r,t,n={}){this.httpClient=r;this.baseUrl=t;this.defaultHeaders=n;}mergeHeaders(r){return {...this.defaultHeaders,...r}}async post(r,t,n,s){let i=`${this.baseUrl}${r}`,l=await this.httpClient.post(i,t,this.mergeHeaders(s));return l.ok?n(l.value):a(l.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,i=await this.httpClient.get(s,this.mergeHeaders(n));return i.ok?t(i.value):a(i.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,Re)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,ye)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,he)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,ve)}async validateSession(r){return this.get("/v1/sessions/validate",Ee,{Authorization:`Bearer ${r}`})}async startEmailFallback(r){let t=`${this.baseUrl}/v1/fallback/email/start`,n=await this.httpClient.post(t,{userId:r.userId,email:r.email},this.mergeHeaders());return n.ok?d(void 0):a(n.error)}async verifyEmailCode(r){let t={userId:r.userId,code:r.code};return r.successUrl&&(t.success_url=r.successUrl),this.post("/v1/fallback/email/verify",t,_e)}async startOnboarding(r){return this.post("/v1/onboarding/start",r,be)}async getOnboardingStatus(r){return this.get(`/v1/onboarding/${r}/status`,Te)}async getOnboardingRegister(r){return this.get(`/v1/onboarding/${r}/register`,Ie)}async registerOnboardingPasskey(r,t){return this.post(`/v1/onboarding/${r}/register-passkey`,t,Ae)}async completeOnboarding(r,t){return this.post(`/v1/onboarding/${r}/complete`,t,Ce)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},$)}async initCrossDeviceRegistration(r){let t=typeof r?.externalUserId=="string"?r.externalUserId.trim():"",n=t.length>0?{external_user_id:t}:{};return this.post("/v1/auth/cross-device/init-registration",n,$)}async getCrossDeviceStatus(r,t){let n={};return typeof t=="string"&&t.length>0&&(n["X-Polling-Token"]=t),this.get(`/v1/auth/cross-device/status/${r}`,Se,Object.keys(n).length>0?n:void 0)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ke)}async verifyCrossDeviceAuth(r){return this.post("/v1/auth/cross-device/verify",r,X)}async verifyCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/verify-registration",r,X)}async verifyAccountRecoveryOtp(r,t){return this.post("/v1/users/recovery/verify",{external_id:r,otp:t},xe)}async completeAccountRecovery(r,t){return this.post("/v1/users/recovery/complete",{recovery_session_id:r,credential:t},Oe)}async startEnrollment(r,t,n){return this.post("/v1/enrollment/register/options",{ticket_id:r,context_hash:t},Pe,n)}async finishEnrollment(r,t,n){return this.post("/v1/enrollment/register",{...t,ticket_id:r},De,n)}bridgePrefix(r){return r==="enrollment"?He:Ve}async getBridgeContext(r,t,n){return this.get(`${this.bridgePrefix(t)}/context/${r}`,Me,n)}async verifyBridgePin(r,t,n,s){return this.post(`${this.bridgePrefix(n)}/verify/${r}`,{pin:t},we,s)}async completeBridgeEnrollment(r,t){return this.post(`${this.bridgePrefix("enrollment")}/complete`,r,Ne,t)}async completeBridgeAuth(r,t){return this.post(`${this.bridgePrefix("auth")}/complete`,r,Ue,t)}getBridgeStatusUrl(r,t){return `${this.baseUrl}${this.bridgePrefix(t)}/status/${r}`}async getBridgeStatus(r,t,n){return this.get(`${this.bridgePrefix(t)}/status/${r}`,Be,n)}};function Ar(e){return typeof e=="object"&&e!==null&&e.ok===true&&"resultado"in e}function Ye(e){if(typeof e!="object"||e===null)return false;let r=e;if(r.ok!==false||!r.error||typeof r.error!="object")return false;let t=r.error;return typeof t.code=="string"&&typeof t.message=="string"}function Xe(e,r){if(Ye(e))return {message:e.error.message,code:L(e.error.code)};let t=e,n=t?.error;if(typeof n=="object"&&n!==null&&"code"in n&&typeof n.code=="string")return {message:n.message??t?.message??r,code:L(n.code)};let s=t?.message??r,i=t?.error,l=typeof i=="string"?L(i):i===void 0?"NETWORK_FAILURE":L(String(i));return {message:s,code:l}}function Cr(){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")return globalThis.crypto.randomUUID();throw new Error("Web Crypto API is required but not available.")}function $e(e,r){let t=r*Math.pow(2,e);return Math.min(t,3e4)}function Sr(e,r){return e!=="GET"?false:r>=500||r===429}var z=class{constructor(r,t=0,n=1e3,s){this.timeoutMs=r;this.maxRetries=t;this.retryDelayMs=n;this.logger=s;}async get(r,t){return this.request(r,{method:"GET",headers:t})}async post(r,t,n){return this.request(r,{method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",...n}})}async request(r,t){let n=(t.method??"GET").toUpperCase(),s=Cr(),i=new Headers(t.headers);i.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let l;for(let p=0;p<=this.maxRetries;p++)try{let g=new AbortController,y=setTimeout(()=>g.abort(),this.timeoutMs);try{let R=await fetch(r,{...t,headers:i,signal:g.signal});if(!R.ok){let I;try{I=await R.json();}catch{}let{message:b,code:C}=Xe(I,R.statusText),A=f(C,b,{requestId:s,status:R.status,statusText:R.statusText,data:I});if(Sr(n,R.status)&&p<this.maxRetries){l=A,clearTimeout(y),await new Promise(ae=>setTimeout(ae,$e(p,this.retryDelayMs)));continue}return a(A)}if(R.status===204)return d(void 0);if(R.headers.get("content-length")==="0")return d(void 0);let h=await R.json();if(Ar(h))return d(h.resultado);let T=h;if(typeof h=="object"&&h!==null&&T.ok===true&&!("resultado"in T))return d(void 0);if(Ye(h)){let{message:I,code:b}=Xe(h,R.statusText);return a(f(b,I,{requestId:s,status:R.status,statusText:R.statusText,data:h}))}return d(h)}finally{clearTimeout(y);}}catch(g){if(l=g,n==="GET"&&p<this.maxRetries)await new Promise(R=>setTimeout(R,$e(p,this.retryDelayMs)));else break}return l instanceof Error&&l.name==="AbortError"?a(f("TIMEOUT","Request timed out",{requestId:s})):a(f("NETWORK_FAILURE",l instanceof Error?l.message:"Request failed",{requestId:s,cause:l}))}};function O(e){let r=new Uint8Array(e),t=Array.from(r,s=>String.fromCharCode(s)).join("");if(typeof globalThis.btoa>"u")throw me("encode");return globalThis.btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function kr(e){if(typeof globalThis.atob>"u")throw me("decode");let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4,n=t===0?r:r+"=".repeat(4-t),s=globalThis.atob(n);return Uint8Array.from(s,i=>i.charCodeAt(0))}function M(e){return kr(e).buffer}function ze(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw f("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!ze(r))throw f("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw f("UNKNOWN_ERROR","Invalid credential response structure for register: attestationObject is missing",{response:r});let t=r.clientDataJSON,n=r.attestationObject;return {id:e.id,rawId:O(e.rawId),response:{clientDataJSON:O(t),attestationObject:O(n)},type:"public-key"}}function w(e){if(!e.response)throw f("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!ze(r))throw f("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw f("UNKNOWN_ERROR","Invalid credential response structure for auth: authenticatorData or signature is missing",{response:r});let t=r.clientDataJSON,n=r.authenticatorData,s=r.signature,i=r.userHandle;return {id:e.id,rawId:O(e.rawId),response:{authenticatorData:O(n),clientDataJSON:O(t),signature:O(s),...i&&{userHandle:O(i)}},type:"public-key"}}function S(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw qe(r)}function N(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function xr(){try{return !N()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Je(){let e=N(),r=await xr();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}async function F(e){let{operation:r,eventEmitter:t,start:n,createOptions:s,invoke:i,finish:l}=e;try{if(t.emit("start",{type:"start",operation:r}),!N()){let E=ge();return t.emit("error",{type:"error",error:E}),a(E)}let p=await n();if(!p.ok)return t.emit("error",{type:"error",error:p.error}),a(p.error);let g=s(p.value);if(!g.ok)return t.emit("error",{type:"error",error:g.error}),a(g.error);let y=await i(g.value);if(!y){let E=_("credential",`${r==="register"?"creation":"retrieval"} failed`);return t.emit("error",{type:"error",error:E}),a(E)}try{S(y);}catch(E){let h=v(E);return t.emit("error",{type:"error",error:h}),a(h)}let R=await l(p.value,y);return R.ok?d(R.value):(t.emit("error",{type:"error",error:R.error}),a(R.error))}catch(p){let g=v(p);return t.emit("error",{type:"error",error:g}),a(g)}}function x(e,r){try{q(e.challenge,"challenge"),q(e.user.id,"user.id");let t=M(e.challenge),n=M(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let i={rp:{id:e.rp.id,name:e.rp.name},user:{id:n,name:e.user.name,displayName:e.user.displayName},challenge:t,pubKeyCredParams:e.pubKeyCredParams,...e.timeout!==void 0&&{timeout:e.timeout},attestation:"none",authenticatorSelection:s,...e.excludeCredentials&&{excludeCredentials:e.excludeCredentials.map(l=>({id:M(l.id),type:l.type,...l.transports&&{transports:l.transports}}))}};return d({publicKey:i})}catch(t){return a(v(t))}}async function Ze(e,r){let t=x(e);if(!t.ok)return a(t.error);let n={...t.value,...r!==void 0&&{signal:r}},s;try{s=await navigator.credentials.create(n);}catch(i){return a(v(i))}try{S(s,"create");}catch(i){return a(v(i))}try{return d(k(s))}catch(i){return a(v(i))}}function K(e,r){try{q(e.challenge,"challenge");let t=M(e.challenge);return d({publicKey:{challenge:t,rpId:e.rpId,...e.timeout!==void 0&&{timeout:e.timeout},userVerification:e.userVerification??"preferred",...e.allowCredentials&&{allowCredentials:e.allowCredentials.map(n=>({id:M(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(v(t))}}async function Qe(e,r,t){let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let i=_("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:i}),a(i)}let s=await F({operation:"register",eventEmitter:t,start:()=>r.startRegister({external_user_id:n}),createOptions:i=>x(i.challenge,e.authenticatorType),invoke:async i=>{let l={...i,...e.signal&&{signal:e.signal}};return navigator.credentials.create(l)},finish:async(i,l)=>{let p=await r.finishRegister({session_id:i.session_id,credential:k(l),...e.successUrl&&{success_url:e.successUrl}});return p.ok?d({success:true,credentialId:p.value.credential_id,credential_id:p.value.credential_id,status:p.value.status,sessionToken:p.value.session_token,user:{userId:p.value.user.user_id,externalUserId:p.value.user.external_user_id,email:p.value.user.email,metadata:p.value.user.metadata},...p.value.redirect_url&&{redirectUrl:p.value.redirect_url}}):a(p.error)}});return s.ok&&t.emit("success",{type:"success",operation:"register",token:s.value.sessionToken,user:s.value.user}),s}async function er(e,r,t){let n=e.externalUserId??e.external_user_id,s=n!==void 0&&typeof n=="string"&&n.trim()!=="",i=await F({operation:"authenticate",eventEmitter:t,start:()=>r.startAuth(s?{external_user_id:n.trim()}:{}),createOptions:l=>K(l.challenge,e.mediation),invoke:async l=>{let p={...l,...e.signal&&{signal:e.signal}};return navigator.credentials.get(p)},finish:async(l,p)=>{let g=await r.finishAuthentication({session_id:l.session_id,credential:w(p),...e.successUrl&&{success_url:e.successUrl}});return g.ok?d({authenticated:g.value.authenticated,sessionToken:g.value.session_token,user:{userId:g.value.user.user_id,externalUserId:g.value.user.external_user_id,email:g.value.user.email,metadata:g.value.user.metadata},signals:g.value.signals,...g.value.redirect_url&&{redirectUrl:g.value.redirect_url}}):a(g.error)}});return i.ok&&t.emit("success",{type:"success",operation:"authenticate",token:i.value.sessionToken,user:i.value.user}),i}async function J(e,r){return r?r.aborted?"aborted":new Promise(t=>{let n=()=>{s(),t("aborted");},s=()=>{clearTimeout(i),r.removeEventListener("abort",n);},i=setTimeout(()=>{s(),t("completed");},e);r.addEventListener("abort",n);}):(await new Promise(t=>setTimeout(t,e)),"completed")}var Or=2e3,Pr=60,Z=class{constructor(r){this.apiClient=r;}async startFlow(r,t){let n=await this.apiClient.startOnboarding({user_role:r.user_role});if(!n.ok)return a(n.error);let{session_id:s}=n.value;for(let i=0;i<Pr;i++){if(t?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));if(await J(Or,t)==="aborted")return a(f("ABORT_ERROR","Operation aborted by user or timeout"));let p=await this.apiClient.getOnboardingStatus(s);if(!p.ok)return a(p.error);let g=p.value.status,y=p.value.onboarding_url;if(g==="pending_passkey"){let R=await this.apiClient.getOnboardingRegister(s);if(!R.ok)return a(R.error);let E=R.value;if(!E.challenge)return a(f("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:y}));let h=x(E.challenge);if(!h.ok)return a(h.error);let T;try{T=await navigator.credentials.create(h.value);}catch(A){return a(v(A))}try{S(T,"create");}catch(A){return a(v(A))}let I;try{I=k(T);}catch(A){return a(v(A))}let b=await this.apiClient.registerOnboardingPasskey(s,{credential:I,challenge:E.challenge.challenge});return b.ok?await this.apiClient.completeOnboarding(s,{company_name:r.company_name}):a(b.error)}if(g==="completed")return await this.apiClient.completeOnboarding(s,{company_name:r.company_name})}return a(f("TIMEOUT","Onboarding timed out"))}};var rr="trymellon_context_hash";var Dr=/^[a-f0-9]{64}$/;function Mr(e){return typeof e=="string"&&Dr.test(e)}function wr(){let e=new Uint8Array(32);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(e);else throw new Error("crypto.getRandomValues is not available");return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}function Nr(){let e=null;return {getItem(){return e},setItem(r,t){e=t;}}}var tr=Nr();function nr(e){let r=e.getItem(rr);if(r&&Mr(r))return r;let t=wr();return e.setItem(rr,t),t}function U(e){let r=e??tr;try{return nr(r)}catch{return nr(tr)}}var Q=class{constructor(r,t){this.apiClient=r;this.storage=t;}async enroll(r){if(r.signal?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));let t=this.storage??(typeof sessionStorage<"u"?sessionStorage:void 0),n=U(t),s=await this.apiClient.startEnrollment(r.ticketId,n);if(!s.ok)return a(s.error);let i=await Ze(s.value.challenge,r.signal);if(!i.ok)return a(i.error);let l=await this.apiClient.finishEnrollment(r.ticketId,{credential:i.value,context_hash:n});return l.ok?d({sessionToken:l.value.session_token}):a(l.error)}};var Ur=2e3,Br=60,ee=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t,n){if(t?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));for(let s=0;s<Br;s++){let i=await this.apiClient.getCrossDeviceStatus(r,n);if(!i.ok)return a(i.error);if(i.value.status==="completed"){if(!i.value.session_token||!i.value.user_id)return a(f("UNKNOWN_ERROR","Missing data in completed session"));let p=i.value.redirect_url!=null&&i.value.redirect_url!==""?i.value.redirect_url:void 0;return d({session_token:i.value.session_token,user_id:i.value.user_id,...p!==void 0&&{redirectUrl:p}})}if(await J(Ur,t)==="aborted")return a(f("ABORT_ERROR","Operation aborted by user or timeout"))}return a(f("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return a(t.error);let n=t.value;return n.type==="registration"?this.executeRegistrationApproval(r,n):this.executeAuthApproval(r,n)}async executeRegistrationApproval(r,t){let n=x(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(l){return a(v(l))}try{S(s,"create");}catch(l){return a(v(l))}let i;try{i=k(s);}catch(l){return a(v(l))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:i})}async executeAuthApproval(r,t){let n=K(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(l){return a(v(l))}try{S(s,"get");}catch(l){return a(v(l))}let i;try{i=w(s);}catch(l){return a(v(l))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:i})}};var Lr=new Set(["pin_verified","pin_locked","completed"]),Fr=1500,Kr=3e5;function sr(e){return Lr.has(e)}function re(e){return e==null||typeof e!="string"||e.trim()===""?a(_("sessionId","must be a non-empty string")):d(e.trim())}function jr(e){return {sessionToken:e.session_token,credentialId:e.credential_id,userId:e.user_id,entityId:e.entity_id}}function Hr(e){return {sessionToken:e.session_token}}async function Vr(e,r,t,n){let i=(n.presencePin!=null&&n.presencePin!==""?n.presencePin:null)??(typeof n.onPinRequired=="function"?await n.onPinRequired():null);return i==null||i===""?a(f("INVALID_ARGUMENT","Bridge requires PIN: provide presencePin or onPinRequired in options")):e.verifyBridgePin(r,i,t)}var te=class{constructor(r,t){this.apiClient=r;this.storage=t;}async waitForResult(r,t){let n=re(r);if(!n.ok)return a(n.error);let s=t?.kind??"enrollment",i=t?.useSse!==false,l=t?.timeoutMs??Kr,p=async g=>{for(;;){let y=await this.apiClient.getBridgeStatus(n.value,s);if(!y.ok)return a(y.error);if(sr(y.value.status))return d(y.value);if(Date.now()-g>=l)return a(f("TIMEOUT","Bridge status wait timed out"));await new Promise(R=>setTimeout(R,Fr));}};return i&&typeof EventSource<"u"?new Promise(g=>{let y=this.apiClient.getBridgeStatusUrl(n.value,s),R=false,E=T=>{if(!R){R=true;try{h.close();}catch{}g(T);}},h;try{h=new EventSource(y);}catch{p(Date.now()).then(E);return}h.onmessage=T=>{try{let I=typeof T.data=="string"?T.data:String(T.data),b=JSON.parse(I);if(b!==null&&typeof b=="object"&&"status"in b&&typeof b.status=="string"){let C=b.status;if(sr(C)){let A=b.ts;E(d({status:C,...typeof A=="string"&&{ts:A}}));}}}catch{}},h.onerror=()=>{if(!R){try{h.close();}catch{}p(Date.now()).then(E);}};}):p(Date.now())}async getContext(r,t){let n=re(r);return n.ok?this.apiClient.getBridgeContext(n.value,t):a(n.error)}async verifyPin(r,t,n){let s=re(r);return s.ok?t==null||typeof t!="string"||t===""?a(_("pin","must be a non-empty string")):this.apiClient.verifyBridgePin(s.value,t,n):a(s.error)}async complete(r,t){let n=re(r);if(!n.ok)return a(n.error);let s=t?.kind??"enrollment",i=await this.apiClient.getBridgeContext(n.value,s);if(!i.ok)return a(i.error);let l=i.value,p=await Vr(this.apiClient,n.value,s,t??{kind:s});if(!p.ok)return a(p.error);let g=p.value;if(t?.signal?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));let y=l.type==="registration"?"enrollment":"auth";if(s!==y)return a(f("INVALID_ARGUMENT",`Bridge context type "${l.type}" does not match kind "${s}"`));if(l.type==="registration"){if(!t?.ticketId?.trim()||!t?.entityId?.trim())return a(_("ticketId/entityId","required for enrollment bridge complete"));let C=g.registration_options;if(!C||typeof C!="object")return a(f("UNKNOWN_ERROR","Bridge verify response missing registration_options"));let A=x(C);if(!A.ok)return a(A.error);let ae={...A.value,...t.signal!==void 0&&{signal:t.signal}},le;try{le=await navigator.credentials.create(ae);}catch(de){return a(v(de))}try{S(le,"create");}catch(de){return a(v(de))}let j=k(le),lr=this.storage??(typeof sessionStorage<"u"?sessionStorage:void 0),ur=U(lr),ue=await this.apiClient.completeBridgeEnrollment({session_id:n.value,ticket_id:t.ticketId,entity_id:t.entityId,context_hash:ur,registration_response:{id:j.id,rawId:j.rawId,response:j.response,type:j.type}});return ue.ok?d(jr(ue.value)):a(ue.error)}let R=g.authentication_options;if(!R||typeof R!="object")return a(f("UNKNOWN_ERROR","Bridge verify response missing authentication_options"));let E=K(R);if(!E.ok)return a(E.error);let h={...E.value,...t?.signal!==void 0&&{signal:t.signal}},T;try{T=await navigator.credentials.get(h);}catch(C){return a(v(C))}try{S(T,"get");}catch(C){return a(v(C))}let I=w(T),b=await this.apiClient.completeBridgeAuth({session_id:n.value,credential:{id:I.id,rawId:I.rawId,response:I.response,type:I.type}});return b.ok?d(Hr(b.value)):a(b.error)}};var ne=class{handlers;constructor(){this.handlers=new Map;}on(r,t){let n=this.handlers.get(r);return n||(n=new Set,this.handlers.set(r,n)),n.add(t),()=>{this.off(r,t);}}off(r,t){let n=this.handlers.get(r);n&&(n.delete(t),n.size===0&&this.handlers.delete(r));}emit(r,t){let n=this.handlers.get(r);if(n)for(let s of n)try{s(t);}catch(i){console.warn("[TryMellon] Event handler threw:",i);}}removeAllListeners(){this.handlers.clear();}};function ir(e){return {async send(r){let t=JSON.stringify(r);if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"){navigator.sendBeacon(e,t);return}typeof fetch<"u"&&await fetch(e,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:true});}}}function Le(e,r){return {event:e,latencyMs:r,ok:true}}var se=class{constructor(r,t,n,s,i){this.apiClient=r;this.eventEmitter=t;this.sandbox=n;this.sandboxToken=s;this.telemetrySender=i;}async sandboxAuthResult(r,t){let n="externalUserId"in t?t.externalUserId??t.external_user_id??"sandbox":t.external_user_id??t.externalUserId??"sandbox",s=typeof n=="string"?n:"sandbox";return r==="register"?Promise.resolve(d({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:s}})):Promise.resolve(d({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:s}}))}async register(r){if(this.sandbox){let s=await this.sandboxAuthResult("register",r);return s.ok&&this.eventEmitter.emit("success",{type:"success",operation:"register",token:s.value.sessionToken,user:s.value.user}),s}let t=Date.now(),n=await Qe(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Le("register",Date.now()-t)).catch(s=>console.warn("[TryMellon] Telemetry send failed",s)),n}async authenticate(r){if(this.sandbox){let s=await this.sandboxAuthResult("authenticate",r);return s.ok&&this.eventEmitter.emit("success",{type:"success",operation:"authenticate",token:s.value.sessionToken,user:s.value.user}),s}let t=Date.now(),n=await er(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Le("authenticate",Date.now()-t)).catch(s=>console.warn("[TryMellon] Telemetry send failed",s)),n}};async function or(e,r,t){let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let i=_("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:i}),a(i)}if(!e.otp||typeof e.otp!="string"||e.otp.trim().length!==6){let i=_("otp","must be a 6-digit string");return t.emit("error",{type:"error",error:i}),a(i)}let s=await F({operation:"register",eventEmitter:t,start:()=>r.verifyAccountRecoveryOtp(n,e.otp),createOptions:i=>{let l=i.challenge;return !l||typeof l!="object"||!("rp"in l)||!("user"in l)||!("challenge"in l)||!("pubKeyCredParams"in l)?a(_("challenge","invalid recovery challenge structure")):x(l)},invoke:async i=>navigator.credentials.create(i),finish:async(i,l)=>{let p=await r.completeAccountRecovery(i.recovery_session_id,k(l));if(!p.ok)return a(p.error);let{credential_id:g,status:y,session_token:R,user:E,redirect_url:h}=p.value;return d({success:true,credentialId:g,status:y,sessionToken:R,user:{userId:E.user_id,externalUserId:E.external_user_id,email:E.email,metadata:E.metadata},...h!==void 0&&{redirectUrl:h}})}});return s.ok&&t.emit("success",{type:"success",operation:"register",token:s.value.sessionToken,user:s.value.user}),s}var ie=class{constructor(r,t){this.apiClient=r;this.eventEmitter=t;}recover(r){return or(r,this.apiClient,this.eventEmitter)}};var Fe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;authService;recoveryService;onboarding;enrollmentManager;bridgeManager;contextHashStorage;static validateConfig(r){let{appId:t,publishableKey:n}=r;if(!t||typeof t!="string"||t.trim()==="")throw _("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw _("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ce;We(s,"apiBaseUrl");let i=r.timeoutMs??3e4;V(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&V(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&V(r.retryDelayMs,"retryDelayMs",100,1e4);}static create(r){try{return e.validateConfig(r),d(new e(r))}catch(t){return H(t)?a(t):a(_("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:pe,e.validateConfig(r);let t=r.appId,n=r.publishableKey,s=r.apiBaseUrl??ce,i=r.timeoutMs??3e4,l=r.maxRetries??3,p=r.retryDelayMs??1e3,g=new z(i,l,p,r.logger),y=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),R={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...y&&{Origin:y}};this.apiClient=new Y(g,s,R),this.eventEmitter=new ne,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??ir(r.telemetryEndpoint??je)),this.authService=new se(this.apiClient,this.eventEmitter,this.sandbox,this.sandboxToken,this.telemetrySender),this.recoveryService=new ie(this.apiClient,this.eventEmitter),this.contextHashStorage=r.contextHashStorage,this.onboarding=new Z(this.apiClient),this.enrollmentManager=new Q(this.apiClient,this.contextHashStorage),this.crossDeviceManager=new ee(this.apiClient),this.bridgeManager=new te(this.apiClient,this.contextHashStorage);}get bridge(){return {getContext:(r,t)=>this.bridgeManager.getContext(r,t),verifyPin:(r,t,n)=>this.bridgeManager.verifyPin(r,t,n),complete:(r,t)=>this.bridgeManager.complete(r,t),waitForResult:(r,t)=>this.bridgeManager.waitForResult(r,t)}}static isSupported(){return N()}async register(r){return this.authService.register(r)}async authenticate(r){return this.authService.authenticate(r)}async enroll(r){this.eventEmitter.emit("start",{type:"start",operation:"enroll"});let t=await this.enrollmentManager.enroll(r);return t.ok?this.eventEmitter.emit("success",{type:"success",operation:"enroll",token:t.value.sessionToken}):this.eventEmitter.emit("error",{type:"error",operation:"enroll",error:t.error}),t}getContextHash(){let r=this.contextHashStorage??(typeof sessionStorage<"u"?sessionStorage:void 0);return U(r)}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(d({valid:true,userId:"sandbox-user",externalUserId:"sandbox",tenantId:"sandbox-tenant",appId:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Je()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "2.3.1"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>{let t=await this.apiClient.verifyEmailCode({userId:r.userId,code:r.code,...r.successUrl&&{successUrl:r.successUrl}});return t.ok?d({sessionToken:t.value.sessionToken,...t.value.redirectUrl&&{redirectUrl:t.value.redirectUrl}}):t}}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r??{}),waitForSession:(r,t,n)=>this.crossDeviceManager.waitForSession(r,t,n),getContext:r=>this.apiClient.getCrossDeviceContext(r),approve:r=>this.crossDeviceManager.approve(r)},recoverAccount:r=>this.recoveryService.recover(r)}};function oe(e,r,t){t&&Object.keys(t).length>0?e(`[TryMellon] ${r}`,t):e(`[TryMellon] ${r}`);}var Ke=class{debug(r,t){oe(console.debug,r,t);}info(r,t){oe(console.info,r,t);}warn(r,t){oe(console.warn,r,t);}error(r,t){oe(console.error,r,t);}};
2
- exports.ConsoleLogger=Ke;exports.SANDBOX_SESSION_TOKEN=pe;exports.TryMellon=Fe;exports.TryMellonError=B;exports.createError=f;exports.createInvalidArgumentError=_;exports.createNetworkError=pr;exports.createNotSupportedError=ge;exports.createTimeoutError=gr;exports.createUserCancelledError=cr;exports.err=a;exports.isTryMellonError=H;exports.mapWebAuthnError=v;exports.ok=d;return exports;})({});//# sourceMappingURL=index.global.js.map
1
+ var TryMellon=(function(exports){'use strict';var ce="https://api.trymellonauth.com",Ve="https://api.trymellonauth.com/v1/telemetry";var pe="trymellon_sandbox_session_token_v1",qe="https://trymellon.com/docs/getting-started#sandbox",We="/v1/enrollment-bridge",Ge="/v1/auth-bridge";var d=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var B=class e extends Error{code;details;isTryMellonError=true;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e);}},gr={NOT_SUPPORTED:"WebAuthn is not supported in this environment",USER_CANCELLED:"User cancelled the operation",PASSKEY_NOT_FOUND:"Passkey not found",SESSION_EXPIRED:"Session has expired",NETWORK_FAILURE:"Network request failed",INVALID_ARGUMENT:"Invalid argument provided",TIMEOUT:"Operation timed out",ABORTED:"Operation was aborted",ABORT_ERROR:"Operation aborted by user or timeout",CHALLENGE_MISMATCH:"This link was already used or expired. Please try again from your computer.",TICKET_NOT_FOUND:"Enrollment ticket not found or invalid",TICKET_EXPIRED:"Enrollment ticket has expired",TICKET_ALREADY_USED:"Enrollment ticket was already used",PIN_MISMATCH:"PIN does not match",PIN_LOCKED:"PIN is locked due to too many failed attempts",BRIDGE_SESSION_EXPIRED:"Bridge session has expired",UNKNOWN_ERROR:"An unknown error occurred"};function f(e,r,t){return new B(e,r??gr[e],t)}function H(e){return e instanceof B||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function ge(){return f("NOT_SUPPORTED")}function mr(){return f("USER_CANCELLED")}function fr(e){return f("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Rr(){return f("TIMEOUT")}function _(e,r){return f("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function Xe(e){return f("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function me(e){return f("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function $e(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw _(r,"must use http or https protocol")}catch(t){throw H(t)?t:_(r,"must be a valid URL")}}function V(e,r,t,n){if(!Number.isFinite(e))throw _(r,"must be a finite number");if(e<t||e>n)throw _(r,`must be between ${t} and ${n}`)}function q(e,r){if(typeof e!="string"||e.length===0)throw _(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw _(r,"must be a valid base64url string")}var yr={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"},hr=["origin_not_allowed","origin_not_allowed_for_application"];function fe(e){return hr.includes(e)}function L(e){if(typeof e!="string")return "UNKNOWN_ERROR";let r=e.toLowerCase().trim();return {challenge_mismatch:"CHALLENGE_MISMATCH",session_expired:"SESSION_EXPIRED",unauthorized:"SESSION_EXPIRED",validation_error:"INVALID_ARGUMENT",invalid_argument:"INVALID_ARGUMENT",user_not_found:"SESSION_EXPIRED",passkey_not_found:"PASSKEY_NOT_FOUND",ticket_not_found:"TICKET_NOT_FOUND",ticket_expired:"TICKET_EXPIRED",ticket_already_consumed:"TICKET_ALREADY_USED",not_found:"TICKET_NOT_FOUND",expired:"TICKET_EXPIRED",already_consumed:"TICKET_ALREADY_USED",context_mismatch:"CHALLENGE_MISMATCH",challenge_not_found:"CHALLENGE_MISMATCH",invalid_ticket_id:"INVALID_ARGUMENT",invalid_context_hash:"INVALID_ARGUMENT",invalid_ticket_status:"INVALID_ARGUMENT",invalid_config:"INVALID_ARGUMENT",enrollment_not_enabled:"INVALID_ARGUMENT",pin_mismatch:"PIN_MISMATCH",pin_locked:"PIN_LOCKED",bridge_not_enabled:"UNKNOWN_ERROR",bridge_session_expired:"BRIDGE_SESSION_EXPIRED",session_not_found:"BRIDGE_SESSION_EXPIRED",origin_not_allowed:"INVALID_ARGUMENT",origin_not_allowed_for_application:"INVALID_ARGUMENT"}[r]??"UNKNOWN_ERROR"}function v(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=yr[r]??"UNKNOWN_ERROR";return f(n,t,{originalError:e})}return e instanceof Error?f("UNKNOWN_ERROR",e.message,{originalError:e}):f("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function m(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function u(e){return typeof e=="string"}function P(e){return typeof e=="number"&&Number.isFinite(e)}function W(e){return typeof e=="boolean"}function D(e){return Array.isArray(e)}function o(e,r){return a(f("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function c(e,r){return e[r]}function vr(e,r){return !m(e)||!u(e.name)||!u(e.id)?o("Invalid API response: challenge.rp must have name and id strings",{originalData:r}):d(true)}function Er(e,r){return !m(e)||!u(e.id)||!u(e.name)||!u(e.displayName)?o("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:r}):d(true)}function _r(e,r){if(!D(e))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:r});for(let t of e)if(!m(t)||t.type!=="public-key"||!P(t.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:r});return d(true)}function G(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id");if(!u(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=c(e,"challenge");if(!m(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=vr(c(t,"rp"),e);if(!n.ok)return n;let s=Er(c(t,"user"),e);if(!s.ok)return s;let i=c(t,"challenge");if(!u(i))return o("Invalid API response: challenge.challenge must be string",{originalData:e});let l=_r(c(t,"pubKeyCredParams"),e);if(!l.ok)return l;let p=t.timeout;if(p!==void 0&&!P(p))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let g=t.excludeCredentials;if(g!==void 0){if(!D(g))return o("Invalid API response: excludeCredentials must be array",{originalData:e});for(let R of g)if(!m(R)||R.type!=="public-key"||!u(R.id))return o("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!m(h)?o("Invalid API response: authenticatorSelection must be object",{originalData:e}):d({session_id:r,challenge:{rp:t.rp,user:t.user,challenge:i,pubKeyCredParams:t.pubKeyCredParams,...p!==void 0&&{timeout:p},...g!==void 0&&{excludeCredentials:g},...h!==void 0&&{authenticatorSelection:h}}})}function Re(e,r){if(!m(e))return o("Invalid API response: user must be object",{field:"user",originalData:r});let t=c(e,"user_id"),n=c(e,"external_user_id");if(!u(t)||!u(n))return o("Invalid API response: user must have user_id and external_user_id strings",{originalData:r});let s=e.email,i=e.metadata;return s!==void 0&&!u(s)?o("Invalid API response: user.email must be string",{originalData:r}):i!==void 0&&(typeof i!="object"||i===null)?o("Invalid API response: user.metadata must be object",{originalData:r}):d({user_id:t,external_user_id:n,...s!==void 0&&{email:s},...i!==void 0&&{metadata:i}})}function ye(e){let r=G(e);return r.ok?d({session_id:r.value.session_id,challenge:r.value.challenge}):r}function he(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id");if(!u(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=c(e,"challenge");if(!m(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=c(t,"challenge"),s=c(t,"rpId"),i=t.allowCredentials;if(!u(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!u(s))return o("Invalid API response: challenge.rpId must be string",{originalData:e});if(i!==void 0&&!D(i))return o("Invalid API response: allowCredentials must be array",{originalData:e});if(i){for(let g of i)if(!m(g)||g.type!=="public-key"||!u(g.id))return o("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let l=t.timeout;if(l!==void 0&&!P(l))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let p=t.userVerification;return p!==void 0&&!["required","preferred","discouraged"].includes(String(p))?o("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):d({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:i??[],...l!==void 0&&{timeout:l},...p!==void 0&&{userVerification:p}}})}function ve(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"credential_id"),t=c(e,"status"),n=c(e,"session_token"),s=c(e,"user");if(!u(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!u(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!u(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});let i=Re(s,e);if(!i.ok)return a(i.error);let l=e.redirect_url;return l!==void 0&&!u(l)?o("Invalid API response: redirect_url must be string",{originalData:e}):d({credential_id:r,status:t,session_token:n,user:i.value,...l!==void 0&&{redirect_url:l}})}function Ee(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"authenticated"),t=c(e,"session_token"),n=c(e,"user"),s=c(e,"signals");if(!W(r))return o("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!u(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});let i=Re(n,e);if(!i.ok)return a(i.error);if(s!==void 0&&!m(s))return o("Invalid API response: signals must be object",{originalData:e});let l=e.redirect_url;return l!==void 0&&!u(l)?o("Invalid API response: redirect_url must be string",{originalData:e}):d({authenticated:r,session_token:t,user:i.value,signals:s,...l!==void 0&&{redirect_url:l}})}function _e(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"valid"),t=c(e,"user_id"),n=c(e,"external_user_id"),s=c(e,"tenant_id"),i=c(e,"app_id");return W(r)?u(t)?u(n)?u(s)?u(i)?d({valid:r,userId:t,externalUserId:n,tenantId:s,appId:i}):o("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):o("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):o("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):o("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):o("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function be(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=e.session_token??e.sessionToken;if(!u(r))return o("Invalid API response: session_token/sessionToken must be string",{field:"session_token",originalData:e});let t=e.redirect_url;return t!==void 0&&!u(t)?o("Invalid API response: redirect_url must be string",{originalData:e}):d({sessionToken:r,...t!==void 0&&{redirectUrl:t}})}var br=["pending_passkey","pending_data","completed"],Tr=["pending_data","completed"];function Te(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"onboarding_url"),n=c(e,"expires_in");return u(r)?u(t)?P(n)?d({session_id:r,onboarding_url:t,expires_in:n}):o("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):o("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):o("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function Ie(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"status"),t=c(e,"onboarding_url"),n=c(e,"expires_in");return !u(r)||!br.includes(r)?o("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):u(t)?P(n)?d({status:r,onboarding_url:t,expires_in:n}):o("Invalid API response: expires_in must be number",{originalData:e}):o("Invalid API response: onboarding_url must be string",{originalData:e})}function Ae(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"status"),n=c(e,"onboarding_url");if(!u(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return o("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!u(n))return o("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,i;if(s!==void 0){let l=Ir(s);if(!l.ok)return l;i=l.value;}return d({session_id:r,status:"pending_passkey",onboarding_url:n,...i!==void 0&&{challenge:i}})}function Ir(e){if(!m(e))return o("Invalid API response: challenge must be object",{originalData:e});let r=c(e,"rp"),t=c(e,"user"),n=c(e,"challenge"),s=c(e,"pubKeyCredParams");if(!m(r)||!u(r.name)||!u(r.id))return o("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!m(t)||!u(t.id)||!u(t.name)||!u(t.displayName))return o("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!u(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!D(s))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let i of s)if(!m(i)||i.type!=="public-key"||!P(i.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return d({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function Ce(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"status"),n=c(e,"user_id"),s=c(e,"tenant_id");return u(r)?!u(t)||!Tr.includes(t)?o("Invalid API response: status must be pending_data|completed",{originalData:e}):u(n)?u(s)?d({session_id:r,status:t,user_id:n,tenant_id:s}):o("Invalid API response: tenant_id must be string",{originalData:e}):o("Invalid API response: user_id must be string",{originalData:e}):o("Invalid API response: session_id must be string",{originalData:e})}function Se(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"session_id"),t=c(e,"status"),n=c(e,"user_id"),s=c(e,"tenant_id"),i=c(e,"session_token");return u(r)?t!=="completed"?o("Invalid API response: status must be completed",{originalData:e}):!u(n)||!u(s)||!u(i)?o("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):d({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:i}):o("Invalid API response: session_id must be string",{originalData:e})}function X(e){return e==null?d(void 0):m(e)&&Object.keys(e).length===0?d(void 0):o("Invalid API response: expected empty body (204)",{originalData:e})}function Ar(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&r.rp!=null&&typeof r.rp=="object"&&r.user!=null&&typeof r.user=="object"&&Array.isArray(r.pubKeyCredParams)}function Cr(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function $(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r="resultado"in e&&m(e.resultado)?e.resultado:e,t=r.session_id,n=r.qr_url,s=r.expires_at,i=r.polling_token;if(!u(t)||!u(n)||!u(s)||!u(i))return o("Invalid API response: missing required fields",{originalData:e});let l={session_id:t,qr_url:n,expires_at:s,polling_token:i};return r.external_user_id!==void 0&&u(r.external_user_id)&&(l.external_user_id=r.external_user_id),d(l)}function ke(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r="resultado"in e&&m(e.resultado)?e.resultado:e,t=r.status;if(!u(t)||!["pending","authenticated","completed"].includes(t))return o("Invalid API response: invalid status",{originalData:e});let n=r.user_id,s=r.session_token,i=r.redirect_url;return n!==void 0&&!u(n)?o("Invalid API response: user_id must be a string when present",{originalData:e}):s!==void 0&&!u(s)?o("Invalid API response: session_token must be a string when present",{originalData:e}):i!==void 0&&!u(i)?o("Invalid API response: redirect_url must be a string when present",{originalData:e}):d({status:t,user_id:n,session_token:s,redirect_url:i})}function xe(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;if(!m(n))return o("Invalid API response: options are required",{originalData:e});let s=200,i=Ye(e.approval_context,s),l=Ye(e.application_name,s);if(i===false||l===false)return o("Invalid API response: approval_context/application_name must be string max 200 chars",{originalData:e});let p={};return typeof i=="string"&&(p.approval_context=i),typeof l=="string"&&(p.application_name=l),t==="registration"?Ar(n)?d({type:"registration",options:n,...p}):o("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):Cr(n)?d({type:"auth",options:n,...p}):o("Invalid API response: auth options must have challenge and rpId",{originalData:e})}function Ye(e,r){if(e!=null)return typeof e!="string"||e.length>r?false:e}function Oe(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"challenge"),t=c(e,"recovery_session_id");return m(r)?u(t)?d({challenge:r,recovery_session_id:t}):o("Invalid API response: recovery_session_id must be string",{field:"recovery_session_id",originalData:e}):o("Invalid API response: challenge must be object",{field:"challenge",originalData:e})}function Pe(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"status"),t=c(e,"session_token"),n=c(e,"user"),s=c(e,"credential_id");if(!u(r))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!u(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!u(s))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!m(n))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=c(n,"user_id");if(!u(i))return o("Invalid API response: user.user_id must be string",{field:"user.user_id",originalData:e});let p=e.redirect_url;if(p!==void 0&&!u(p))return o("Invalid API response: redirect_url must be string",{field:"redirect_url",originalData:e});let g=n;return d({status:r,session_token:t,credential_id:s,user:{user_id:i,external_user_id:u(g.external_user_id)?g.external_user_id:void 0,email:u(g.email)?g.email:void 0,metadata:m(g.metadata)?g.metadata:void 0},...p!==void 0&&{redirect_url:p}})}function De(e){let r=G(e);return r.ok?d({session_id:r.value.session_id,challenge:r.value.challenge}):r}function Sr(e,r){if(!m(e))return o("Invalid API response: user must be object",{field:"user",originalData:r});let t=c(e,"user_id");if(!u(t))return o("Invalid API response: user.user_id must be string",{originalData:r});let n=e.external_user_id;if(n!==void 0&&!u(n))return o("Invalid API response: user.external_user_id must be string",{originalData:r});let s=e.email;if(s!==void 0&&!u(s))return o("Invalid API response: user.email must be string",{originalData:r});let i=e.metadata;return i!==void 0&&(typeof i!="object"||i===null)?o("Invalid API response: user.metadata must be object",{originalData:r}):d({user_id:t,...n!==void 0&&{external_user_id:n},...s!==void 0&&{email:s},...i!==void 0&&{metadata:i}})}function Me(e){if(!m(e))return o("Invalid API response: expected object",{originalData:e});let r=c(e,"credential_id"),t=c(e,"status"),n=c(e,"session_token"),s=c(e,"user");if(!u(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!u(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!u(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});let i=Sr(s,e);return i.ok?d({credential_id:r,status:t,session_token:n,user:i.value}):i}var kr=["pending","pin_verified","pin_locked","completed"];function we(e){if(!m(e))return o("Invalid bridge context response: expected object",{originalData:e});let r=c(e,"type");if(r!=="auth"&&r!=="registration")return o('Invalid bridge context response: type must be "auth" or "registration"',{field:"type",expected:"auth | registration",originalData:e});let t=c(e,"options");if(!m(t))return o("Invalid bridge context response: options must be object",{field:"options",originalData:e});let n=e.application_name;return n!==void 0&&!u(n)?o("Invalid bridge context response: application_name must be string",{field:"application_name",originalData:e}):d({type:r,options:t,...n!==void 0&&{application_name:n}})}function Ne(e){if(!m(e))return o("Invalid bridge verify response: expected object",{originalData:e});let r=c(e,"session_id");if(!u(r)||r.trim()==="")return o("Invalid bridge verify response: session_id must be non-empty string (UUID expected)",{field:"session_id",originalData:e});let t=e.challenge;if(t!==void 0&&!u(t))return o("Invalid bridge verify response: challenge must be string when present",{field:"challenge",originalData:e});let n=e.registration_options;if(n!==void 0&&!m(n))return o("Invalid bridge verify response: registration_options must be object when present",{field:"registration_options",originalData:e});let s=e.authentication_options;return s!==void 0&&!m(s)?o("Invalid bridge verify response: authentication_options must be object when present",{field:"authentication_options",originalData:e}):d({session_id:r,...t!==void 0&&{challenge:t},...n!==void 0&&{registration_options:n},...s!==void 0&&{authentication_options:s}})}function Ue(e){if(!m(e))return o("Invalid bridge complete enrollment response: expected object",{originalData:e});let r=c(e,"credential_id"),t=c(e,"entity_id"),n=c(e,"user_id"),s=c(e,"session_token");return u(r)?u(t)?u(n)?u(s)?d({credential_id:r,entity_id:t,user_id:n,session_token:s}):o("Invalid bridge complete enrollment response: session_token must be string",{field:"session_token",originalData:e}):o("Invalid bridge complete enrollment response: user_id must be string",{field:"user_id",originalData:e}):o("Invalid bridge complete enrollment response: entity_id must be string",{field:"entity_id",originalData:e}):o("Invalid bridge complete enrollment response: credential_id must be string",{field:"credential_id",originalData:e})}function Be(e){if(!m(e))return o("Invalid bridge complete auth response: expected object",{originalData:e});let r=c(e,"session_token");return u(r)?d({session_token:r}):o("Invalid bridge complete auth response: session_token must be string",{field:"session_token",originalData:e})}function Le(e){if(!m(e))return o("Invalid bridge status response: expected object",{originalData:e});let r=c(e,"status");if(typeof r!="string"||!kr.includes(r))return o("Invalid bridge status response: status must be one of pending, pin_verified, pin_locked, completed",{field:"status",originalData:e});let t=e.ts;return t!==void 0&&!u(t)?o("Invalid bridge status response: ts must be string when present",{field:"ts",originalData:e}):d({status:r,...t!==void 0&&{ts:t}})}var Y=class{constructor(r,t,n={}){this.httpClient=r;this.baseUrl=t;this.defaultHeaders=n;}mergeHeaders(r){return {...this.defaultHeaders,...r}}async post(r,t,n,s){let i=`${this.baseUrl}${r}`,l=await this.httpClient.post(i,t,this.mergeHeaders(s));return l.ok?n(l.value):a(l.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,i=await this.httpClient.get(s,this.mergeHeaders(n));return i.ok?t(i.value):a(i.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,ye)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,he)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,ve)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,Ee)}async validateSession(r){return this.get("/v1/sessions/validate",_e,{Authorization:`Bearer ${r}`})}async startEmailFallback(r){let t=`${this.baseUrl}/v1/fallback/email/start`,n=await this.httpClient.post(t,{userId:r.userId,email:r.email},this.mergeHeaders());return n.ok?d(void 0):a(n.error)}async verifyEmailCode(r){let t={userId:r.userId,code:r.code};return r.successUrl&&(t.success_url=r.successUrl),this.post("/v1/fallback/email/verify",t,be)}async startOnboarding(r){return this.post("/v1/onboarding/start",r,Te)}async getOnboardingStatus(r){return this.get(`/v1/onboarding/${r}/status`,Ie)}async getOnboardingRegister(r){return this.get(`/v1/onboarding/${r}/register`,Ae)}async registerOnboardingPasskey(r,t){return this.post(`/v1/onboarding/${r}/register-passkey`,t,Ce)}async completeOnboarding(r,t){return this.post(`/v1/onboarding/${r}/complete`,t,Se)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},$)}async initCrossDeviceRegistration(r){let t=typeof r?.externalUserId=="string"?r.externalUserId.trim():"",n=t.length>0?{external_user_id:t}:{};return this.post("/v1/auth/cross-device/init-registration",n,$)}async getCrossDeviceStatus(r,t){let n={};return typeof t=="string"&&t.length>0&&(n["X-Polling-Token"]=t),this.get(`/v1/auth/cross-device/status/${r}`,ke,Object.keys(n).length>0?n:void 0)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,xe)}async verifyCrossDeviceAuth(r){return this.post("/v1/auth/cross-device/verify",r,X)}async verifyCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/verify-registration",r,X)}async verifyAccountRecoveryOtp(r,t){return this.post("/v1/users/recovery/verify",{external_id:r,otp:t},Oe)}async completeAccountRecovery(r,t){return this.post("/v1/users/recovery/complete",{recovery_session_id:r,credential:t},Pe)}async startEnrollment(r,t,n){return this.post("/v1/enrollment/register/options",{ticket_id:r,context_hash:t},De,n)}async finishEnrollment(r,t,n){return this.post("/v1/enrollment/register",{...t,ticket_id:r},Me,n)}bridgePrefix(r){return r==="enrollment"?We:Ge}async getBridgeContext(r,t,n){return this.get(`${this.bridgePrefix(t)}/context/${r}`,we,n)}async verifyBridgePin(r,t,n,s){return this.post(`${this.bridgePrefix(n)}/verify/${r}`,{pin:t},Ne,s)}async completeBridgeEnrollment(r,t){return this.post(`${this.bridgePrefix("enrollment")}/complete`,r,Ue,t)}async completeBridgeAuth(r,t){return this.post(`${this.bridgePrefix("auth")}/complete`,r,Be,t)}getBridgeStatusUrl(r,t){return `${this.baseUrl}${this.bridgePrefix(t)}/status/${r}`}async getBridgeStatus(r,t,n){return this.get(`${this.bridgePrefix(t)}/status/${r}`,Le,n)}};function xr(e){return typeof e=="object"&&e!==null&&e.ok===true&&"resultado"in e}function Ke(e){if(typeof e!="object"||e===null)return false;let r=e;if(r.ok!==false||!r.error||typeof r.error!="object")return false;let t=r.error;return typeof t.code=="string"&&typeof t.message=="string"}var Or="https://trymellon.com/docs/getting-started#allowed-origins",Pr="Add your origin to allowed origins in the TryMellon dashboard.";function ze(e){let r=e.error.hint??Pr,t=e.error.docs_url??Or;console.warn(`[TryMellon] ${r} See: ${t}`);}function Je(e,r){if(Ke(e))return {message:e.error.message,code:L(e.error.code)};let t=e,n=t?.error;if(typeof n=="object"&&n!==null&&"code"in n&&typeof n.code=="string")return {message:n.message??t?.message??r,code:L(n.code)};let s=t?.message??r,i=t?.error,l=typeof i=="string"?L(i):i===void 0?"NETWORK_FAILURE":L(String(i));return {message:s,code:l}}function Dr(){if(typeof globalThis.crypto<"u"&&typeof globalThis.crypto.randomUUID=="function")return globalThis.crypto.randomUUID();throw new Error("Web Crypto API is required but not available.")}function Ze(e,r){let t=r*Math.pow(2,e);return Math.min(t,3e4)}function Mr(e,r){return e!=="GET"?false:r>=500||r===429}var z=class{constructor(r,t=0,n=1e3,s){this.timeoutMs=r;this.maxRetries=t;this.retryDelayMs=n;this.logger=s;}async get(r,t){return this.request(r,{method:"GET",headers:t})}async post(r,t,n){return this.request(r,{method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",...n}})}async request(r,t){let n=(t.method??"GET").toUpperCase(),s=Dr(),i=new Headers(t.headers);i.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let l;for(let p=0;p<=this.maxRetries;p++)try{let g=new AbortController,h=setTimeout(()=>g.abort(),this.timeoutMs);try{let R=await fetch(r,{...t,headers:i,signal:g.signal});if(!R.ok){let b;try{b=await R.json();}catch{}Ke(b)&&fe(b.error.code)&&ze(b);let{message:T,code:C}=Je(b,R.statusText),A=f(C,T,{requestId:s,status:R.status,statusText:R.statusText,data:b});if(Mr(n,R.status)&&p<this.maxRetries){l=A,clearTimeout(h),await new Promise(ae=>setTimeout(ae,Ze(p,this.retryDelayMs)));continue}return a(A)}if(R.status===204)return d(void 0);if(R.headers.get("content-length")==="0")return d(void 0);let y=await R.json();if(xr(y))return d(y.resultado);let I=y;if(typeof y=="object"&&y!==null&&I.ok===true&&!("resultado"in I))return d(void 0);if(Ke(y)){fe(y.error.code)&&ze(y);let{message:b,code:T}=Je(y,R.statusText);return a(f(T,b,{requestId:s,status:R.status,statusText:R.statusText,data:y}))}return d(y)}finally{clearTimeout(h);}}catch(g){if(l=g,n==="GET"&&p<this.maxRetries)await new Promise(R=>setTimeout(R,Ze(p,this.retryDelayMs)));else break}return l instanceof Error&&l.name==="AbortError"?a(f("TIMEOUT","Request timed out",{requestId:s})):a(f("NETWORK_FAILURE",l instanceof Error?l.message:"Request failed",{requestId:s,cause:l}))}};function O(e){let r=new Uint8Array(e),t=Array.from(r,s=>String.fromCharCode(s)).join("");if(typeof globalThis.btoa>"u")throw me("encode");return globalThis.btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function wr(e){if(typeof globalThis.atob>"u")throw me("decode");let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4,n=t===0?r:r+"=".repeat(4-t),s=globalThis.atob(n);return Uint8Array.from(s,i=>i.charCodeAt(0))}function M(e){return wr(e).buffer}function Qe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw f("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Qe(r))throw f("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw f("UNKNOWN_ERROR","Invalid credential response structure for register: attestationObject is missing",{response:r});let t=r.clientDataJSON,n=r.attestationObject;return {id:e.id,rawId:O(e.rawId),response:{clientDataJSON:O(t),attestationObject:O(n)},type:"public-key"}}function w(e){if(!e.response)throw f("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Qe(r))throw f("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw f("UNKNOWN_ERROR","Invalid credential response structure for auth: authenticatorData or signature is missing",{response:r});let t=r.clientDataJSON,n=r.authenticatorData,s=r.signature,i=r.userHandle;return {id:e.id,rawId:O(e.rawId),response:{authenticatorData:O(n),clientDataJSON:O(t),signature:O(s),...i&&{userHandle:O(i)}},type:"public-key"}}function S(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw Xe(r)}function N(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function Nr(){try{return !N()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function er(){let e=N(),r=await Nr();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}async function K(e){let{operation:r,eventEmitter:t,start:n,createOptions:s,invoke:i,finish:l}=e;try{if(t.emit("start",{type:"start",operation:r}),!N()){let E=ge();return t.emit("error",{type:"error",error:E}),a(E)}let p=await n();if(!p.ok)return t.emit("error",{type:"error",error:p.error}),a(p.error);let g=s(p.value);if(!g.ok)return t.emit("error",{type:"error",error:g.error}),a(g.error);let h=await i(g.value);if(!h){let E=_("credential",`${r==="register"?"creation":"retrieval"} failed`);return t.emit("error",{type:"error",error:E}),a(E)}try{S(h);}catch(E){let y=v(E);return t.emit("error",{type:"error",error:y}),a(y)}let R=await l(p.value,h);return R.ok?d(R.value):(t.emit("error",{type:"error",error:R.error}),a(R.error))}catch(p){let g=v(p);return t.emit("error",{type:"error",error:g}),a(g)}}function x(e,r){try{q(e.challenge,"challenge"),q(e.user.id,"user.id");let t=M(e.challenge),n=M(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let i={rp:{id:e.rp.id,name:e.rp.name},user:{id:n,name:e.user.name,displayName:e.user.displayName},challenge:t,pubKeyCredParams:e.pubKeyCredParams,...e.timeout!==void 0&&{timeout:e.timeout},attestation:"none",authenticatorSelection:s,...e.excludeCredentials&&{excludeCredentials:e.excludeCredentials.map(l=>({id:M(l.id),type:l.type,...l.transports&&{transports:l.transports}}))}};return d({publicKey:i})}catch(t){return a(v(t))}}async function rr(e,r){let t=x(e);if(!t.ok)return a(t.error);let n={...t.value,...r!==void 0&&{signal:r}},s;try{s=await navigator.credentials.create(n);}catch(i){return a(v(i))}try{S(s,"create");}catch(i){return a(v(i))}try{return d(k(s))}catch(i){return a(v(i))}}function F(e,r){try{q(e.challenge,"challenge");let t=M(e.challenge);return d({publicKey:{challenge:t,rpId:e.rpId,...e.timeout!==void 0&&{timeout:e.timeout},userVerification:e.userVerification??"preferred",...e.allowCredentials&&{allowCredentials:e.allowCredentials.map(n=>({id:M(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(v(t))}}async function tr(e,r,t){let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let i=_("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:i}),a(i)}let s=await K({operation:"register",eventEmitter:t,start:()=>r.startRegister({external_user_id:n}),createOptions:i=>x(i.challenge,e.authenticatorType),invoke:async i=>{let l={...i,...e.signal&&{signal:e.signal}};return navigator.credentials.create(l)},finish:async(i,l)=>{let p=await r.finishRegister({session_id:i.session_id,credential:k(l),...e.successUrl&&{success_url:e.successUrl}});return p.ok?d({success:true,credentialId:p.value.credential_id,credential_id:p.value.credential_id,status:p.value.status,sessionToken:p.value.session_token,user:{userId:p.value.user.user_id,externalUserId:p.value.user.external_user_id,email:p.value.user.email,metadata:p.value.user.metadata},...p.value.redirect_url&&{redirectUrl:p.value.redirect_url}}):a(p.error)}});return s.ok&&t.emit("success",{type:"success",operation:"register",token:s.value.sessionToken,user:s.value.user}),s}async function nr(e,r,t){let n=e.externalUserId??e.external_user_id,s=n!==void 0&&typeof n=="string"&&n.trim()!=="",i=await K({operation:"authenticate",eventEmitter:t,start:()=>r.startAuth(s?{external_user_id:n.trim()}:{}),createOptions:l=>F(l.challenge,e.mediation),invoke:async l=>{let p={...l,...e.signal&&{signal:e.signal}};return navigator.credentials.get(p)},finish:async(l,p)=>{let g=await r.finishAuthentication({session_id:l.session_id,credential:w(p),...e.successUrl&&{success_url:e.successUrl}});return g.ok?d({authenticated:g.value.authenticated,sessionToken:g.value.session_token,user:{userId:g.value.user.user_id,externalUserId:g.value.user.external_user_id,email:g.value.user.email,metadata:g.value.user.metadata},signals:g.value.signals,...g.value.redirect_url&&{redirectUrl:g.value.redirect_url}}):a(g.error)}});return i.ok&&t.emit("success",{type:"success",operation:"authenticate",token:i.value.sessionToken,user:i.value.user}),i}async function J(e,r){return r?r.aborted?"aborted":new Promise(t=>{let n=()=>{s(),t("aborted");},s=()=>{clearTimeout(i),r.removeEventListener("abort",n);},i=setTimeout(()=>{s(),t("completed");},e);r.addEventListener("abort",n);}):(await new Promise(t=>setTimeout(t,e)),"completed")}var Ur=2e3,Br=60,Z=class{constructor(r){this.apiClient=r;}async startFlow(r,t){let n=await this.apiClient.startOnboarding({user_role:r.user_role});if(!n.ok)return a(n.error);let{session_id:s}=n.value;for(let i=0;i<Br;i++){if(t?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));if(await J(Ur,t)==="aborted")return a(f("ABORT_ERROR","Operation aborted by user or timeout"));let p=await this.apiClient.getOnboardingStatus(s);if(!p.ok)return a(p.error);let g=p.value.status,h=p.value.onboarding_url;if(g==="pending_passkey"){let R=await this.apiClient.getOnboardingRegister(s);if(!R.ok)return a(R.error);let E=R.value;if(!E.challenge)return a(f("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:h}));let y=x(E.challenge);if(!y.ok)return a(y.error);let I;try{I=await navigator.credentials.create(y.value);}catch(A){return a(v(A))}try{S(I,"create");}catch(A){return a(v(A))}let b;try{b=k(I);}catch(A){return a(v(A))}let T=await this.apiClient.registerOnboardingPasskey(s,{credential:b,challenge:E.challenge.challenge});return T.ok?await this.apiClient.completeOnboarding(s,{company_name:r.company_name}):a(T.error)}if(g==="completed")return await this.apiClient.completeOnboarding(s,{company_name:r.company_name})}return a(f("TIMEOUT","Onboarding timed out"))}};var sr="trymellon_context_hash";var Lr=/^[a-f0-9]{64}$/;function Kr(e){return typeof e=="string"&&Lr.test(e)}function Fr(){let e=new Uint8Array(32);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(e);else throw new Error("crypto.getRandomValues is not available");return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}function jr(){let e=null;return {getItem(){return e},setItem(r,t){e=t;}}}var ir=jr();function or(e){let r=e.getItem(sr);if(r&&Kr(r))return r;let t=Fr();return e.setItem(sr,t),t}function U(e){let r=e??ir;try{return or(r)}catch{return or(ir)}}var Q=class{constructor(r,t){this.apiClient=r;this.storage=t;}async enroll(r){if(r.signal?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));let t=this.storage??(typeof sessionStorage<"u"?sessionStorage:void 0),n=U(t),s=await this.apiClient.startEnrollment(r.ticketId,n);if(!s.ok)return a(s.error);let i=await rr(s.value.challenge,r.signal);if(!i.ok)return a(i.error);let l=await this.apiClient.finishEnrollment(r.ticketId,{credential:i.value,context_hash:n});return l.ok?d({sessionToken:l.value.session_token}):a(l.error)}};var Hr=2e3,Vr=60,ee=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t,n){if(t?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));for(let s=0;s<Vr;s++){let i=await this.apiClient.getCrossDeviceStatus(r,n);if(!i.ok)return a(i.error);if(i.value.status==="completed"){if(!i.value.session_token||!i.value.user_id)return a(f("UNKNOWN_ERROR","Missing data in completed session"));let p=i.value.redirect_url!=null&&i.value.redirect_url!==""?i.value.redirect_url:void 0;return d({session_token:i.value.session_token,user_id:i.value.user_id,...p!==void 0&&{redirectUrl:p}})}if(await J(Hr,t)==="aborted")return a(f("ABORT_ERROR","Operation aborted by user or timeout"))}return a(f("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return a(t.error);let n=t.value;return n.type==="registration"?this.executeRegistrationApproval(r,n):this.executeAuthApproval(r,n)}async executeRegistrationApproval(r,t){let n=x(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(l){return a(v(l))}try{S(s,"create");}catch(l){return a(v(l))}let i;try{i=k(s);}catch(l){return a(v(l))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:i})}async executeAuthApproval(r,t){let n=F(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(l){return a(v(l))}try{S(s,"get");}catch(l){return a(v(l))}let i;try{i=w(s);}catch(l){return a(v(l))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:i})}};var qr=new Set(["pin_verified","pin_locked","completed"]),Wr=1500,Gr=3e5;function ar(e){return qr.has(e)}function re(e){return e==null||typeof e!="string"||e.trim()===""?a(_("sessionId","must be a non-empty string")):d(e.trim())}function Xr(e){return {sessionToken:e.session_token,credentialId:e.credential_id,userId:e.user_id,entityId:e.entity_id}}function $r(e){return {sessionToken:e.session_token}}async function Yr(e,r,t,n){let i=(n.presencePin!=null&&n.presencePin!==""?n.presencePin:null)??(typeof n.onPinRequired=="function"?await n.onPinRequired():null);return i==null||i===""?a(f("INVALID_ARGUMENT","Bridge requires PIN: provide presencePin or onPinRequired in options")):e.verifyBridgePin(r,i,t)}var te=class{constructor(r,t){this.apiClient=r;this.storage=t;}async waitForResult(r,t){let n=re(r);if(!n.ok)return a(n.error);let s=t?.kind??"enrollment",i=t?.useSse!==false,l=t?.timeoutMs??Gr,p=async g=>{for(;;){let h=await this.apiClient.getBridgeStatus(n.value,s);if(!h.ok)return a(h.error);if(ar(h.value.status))return d(h.value);if(Date.now()-g>=l)return a(f("TIMEOUT","Bridge status wait timed out"));await new Promise(R=>setTimeout(R,Wr));}};return i&&typeof EventSource<"u"?new Promise(g=>{let h=this.apiClient.getBridgeStatusUrl(n.value,s),R=false,E=I=>{if(!R){R=true;try{y.close();}catch{}g(I);}},y;try{y=new EventSource(h);}catch{p(Date.now()).then(E);return}y.onmessage=I=>{try{let b=typeof I.data=="string"?I.data:String(I.data),T=JSON.parse(b);if(T!==null&&typeof T=="object"&&"status"in T&&typeof T.status=="string"){let C=T.status;if(ar(C)){let A=T.ts;E(d({status:C,...typeof A=="string"&&{ts:A}}));}}}catch{}},y.onerror=()=>{if(!R){try{y.close();}catch{}p(Date.now()).then(E);}};}):p(Date.now())}async getContext(r,t){let n=re(r);return n.ok?this.apiClient.getBridgeContext(n.value,t):a(n.error)}async verifyPin(r,t,n){let s=re(r);return s.ok?t==null||typeof t!="string"||t===""?a(_("pin","must be a non-empty string")):this.apiClient.verifyBridgePin(s.value,t,n):a(s.error)}async complete(r,t){let n=re(r);if(!n.ok)return a(n.error);let s=t?.kind??"enrollment",i=await this.apiClient.getBridgeContext(n.value,s);if(!i.ok)return a(i.error);let l=i.value,p=await Yr(this.apiClient,n.value,s,t??{kind:s});if(!p.ok)return a(p.error);let g=p.value;if(t?.signal?.aborted)return a(f("ABORT_ERROR","Operation aborted by user or timeout"));let h=l.type==="registration"?"enrollment":"auth";if(s!==h)return a(f("INVALID_ARGUMENT",`Bridge context type "${l.type}" does not match kind "${s}"`));if(l.type==="registration"){if(!t?.ticketId?.trim()||!t?.entityId?.trim())return a(_("ticketId/entityId","required for enrollment bridge complete"));let C=g.registration_options;if(!C||typeof C!="object")return a(f("UNKNOWN_ERROR","Bridge verify response missing registration_options"));let A=x(C);if(!A.ok)return a(A.error);let ae={...A.value,...t.signal!==void 0&&{signal:t.signal}},le;try{le=await navigator.credentials.create(ae);}catch(de){return a(v(de))}try{S(le,"create");}catch(de){return a(v(de))}let j=k(le),cr=this.storage??(typeof sessionStorage<"u"?sessionStorage:void 0),pr=U(cr),ue=await this.apiClient.completeBridgeEnrollment({session_id:n.value,ticket_id:t.ticketId,entity_id:t.entityId,context_hash:pr,registration_response:{id:j.id,rawId:j.rawId,response:j.response,type:j.type}});return ue.ok?d(Xr(ue.value)):a(ue.error)}let R=g.authentication_options;if(!R||typeof R!="object")return a(f("UNKNOWN_ERROR","Bridge verify response missing authentication_options"));let E=F(R);if(!E.ok)return a(E.error);let y={...E.value,...t?.signal!==void 0&&{signal:t.signal}},I;try{I=await navigator.credentials.get(y);}catch(C){return a(v(C))}try{S(I,"get");}catch(C){return a(v(C))}let b=w(I),T=await this.apiClient.completeBridgeAuth({session_id:n.value,credential:{id:b.id,rawId:b.rawId,response:b.response,type:b.type}});return T.ok?d($r(T.value)):a(T.error)}};var ne=class{handlers;constructor(){this.handlers=new Map;}on(r,t){let n=this.handlers.get(r);return n||(n=new Set,this.handlers.set(r,n)),n.add(t),()=>{this.off(r,t);}}off(r,t){let n=this.handlers.get(r);n&&(n.delete(t),n.size===0&&this.handlers.delete(r));}emit(r,t){let n=this.handlers.get(r);if(n)for(let s of n)try{s(t);}catch(i){console.warn("[TryMellon] Event handler threw:",i);}}removeAllListeners(){this.handlers.clear();}};function lr(e){return {async send(r){let t=JSON.stringify(r);if(typeof navigator<"u"&&typeof navigator.sendBeacon=="function"){navigator.sendBeacon(e,t);return}typeof fetch<"u"&&await fetch(e,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:true});}}}function Fe(e,r){return {event:e,latencyMs:r,ok:true}}var se=class{constructor(r,t,n,s,i){this.apiClient=r;this.eventEmitter=t;this.sandbox=n;this.sandboxToken=s;this.telemetrySender=i;}async sandboxAuthResult(r,t){let n="externalUserId"in t?t.externalUserId??t.external_user_id??"sandbox":t.external_user_id??t.externalUserId??"sandbox",s=typeof n=="string"?n:"sandbox";return r==="register"?Promise.resolve(d({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:s}})):Promise.resolve(d({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:s}}))}async register(r){if(this.sandbox){let s=await this.sandboxAuthResult("register",r);return s.ok&&this.eventEmitter.emit("success",{type:"success",operation:"register",token:s.value.sessionToken,user:s.value.user}),s}let t=Date.now(),n=await tr(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Fe("register",Date.now()-t)).catch(s=>console.warn("[TryMellon] Telemetry send failed",s)),n}async authenticate(r){if(this.sandbox){let s=await this.sandboxAuthResult("authenticate",r);return s.ok&&this.eventEmitter.emit("success",{type:"success",operation:"authenticate",token:s.value.sessionToken,user:s.value.user}),s}let t=Date.now(),n=await nr(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Fe("authenticate",Date.now()-t)).catch(s=>console.warn("[TryMellon] Telemetry send failed",s)),n}};async function ur(e,r,t){let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let i=_("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:i}),a(i)}if(!e.otp||typeof e.otp!="string"||e.otp.trim().length!==6){let i=_("otp","must be a 6-digit string");return t.emit("error",{type:"error",error:i}),a(i)}let s=await K({operation:"register",eventEmitter:t,start:()=>r.verifyAccountRecoveryOtp(n,e.otp),createOptions:i=>{let l=i.challenge;return !l||typeof l!="object"||!("rp"in l)||!("user"in l)||!("challenge"in l)||!("pubKeyCredParams"in l)?a(_("challenge","invalid recovery challenge structure")):x(l)},invoke:async i=>navigator.credentials.create(i),finish:async(i,l)=>{let p=await r.completeAccountRecovery(i.recovery_session_id,k(l));if(!p.ok)return a(p.error);let{credential_id:g,status:h,session_token:R,user:E,redirect_url:y}=p.value;return d({success:true,credentialId:g,status:h,sessionToken:R,user:{userId:E.user_id,externalUserId:E.external_user_id,email:E.email,metadata:E.metadata},...y!==void 0&&{redirectUrl:y}})}});return s.ok&&t.emit("success",{type:"success",operation:"register",token:s.value.sessionToken,user:s.value.user}),s}var ie=class{constructor(r,t){this.apiClient=r;this.eventEmitter=t;}recover(r){return ur(r,this.apiClient,this.eventEmitter)}};function st(e){if(typeof e!="string"||e==="")return false;try{let r=new URL(e).hostname.toLowerCase();return r==="localhost"||r==="127.0.0.1"}catch{return false}}var je=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;authService;recoveryService;onboarding;enrollmentManager;bridgeManager;contextHashStorage;static validateConfig(r){let{appId:t,publishableKey:n}=r;if(!t||typeof t!="string"||t.trim()==="")throw _("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw _("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ce;$e(s,"apiBaseUrl");let i=r.timeoutMs??3e4;V(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&V(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&V(r.retryDelayMs,"retryDelayMs",100,1e4);}static create(r){try{return e.validateConfig(r),d(new e(r))}catch(t){return H(t)?a(t):a(_("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:pe,e.validateConfig(r);let t=r.appId,n=r.publishableKey,s=r.apiBaseUrl??ce,i=r.timeoutMs??3e4,l=r.maxRetries??3,p=r.retryDelayMs??1e3,g=new z(i,l,p,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),R={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new Y(g,s,R),this.eventEmitter=new ne,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??lr(r.telemetryEndpoint??Ve)),this.authService=new se(this.apiClient,this.eventEmitter,this.sandbox,this.sandboxToken,this.telemetrySender),this.recoveryService=new ie(this.apiClient,this.eventEmitter),this.contextHashStorage=r.contextHashStorage,this.onboarding=new Z(this.apiClient),this.enrollmentManager=new Q(this.apiClient,this.contextHashStorage),this.crossDeviceManager=new ee(this.apiClient),this.bridgeManager=new te(this.apiClient,this.contextHashStorage),this.warnIfSandboxOnProd();}warnIfSandboxOnProd(){if(typeof window>"u"||!this.sandbox)return;let r=window.location.origin;st(r)||console.warn(`[TryMellon] Sandbox mode is ON but origin is not localhost (current: ${r}). Use sandbox: false in production. See: ${qe}`);}get bridge(){return {getContext:(r,t)=>this.bridgeManager.getContext(r,t),verifyPin:(r,t,n)=>this.bridgeManager.verifyPin(r,t,n),complete:(r,t)=>this.bridgeManager.complete(r,t),waitForResult:(r,t)=>this.bridgeManager.waitForResult(r,t)}}static isSupported(){return N()}async register(r){return this.authService.register(r)}async authenticate(r){return this.authService.authenticate(r)}async enroll(r){this.eventEmitter.emit("start",{type:"start",operation:"enroll"});let t=await this.enrollmentManager.enroll(r);return t.ok?this.eventEmitter.emit("success",{type:"success",operation:"enroll",token:t.value.sessionToken}):this.eventEmitter.emit("error",{type:"error",operation:"enroll",error:t.error}),t}getContextHash(){let r=this.contextHashStorage??(typeof sessionStorage<"u"?sessionStorage:void 0);return U(r)}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(d({valid:true,userId:"sandbox-user",externalUserId:"sandbox",tenantId:"sandbox-tenant",appId:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return er()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "2.3.2"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>{let t=await this.apiClient.verifyEmailCode({userId:r.userId,code:r.code,...r.successUrl&&{successUrl:r.successUrl}});return t.ok?d({sessionToken:t.value.sessionToken,...t.value.redirectUrl&&{redirectUrl:t.value.redirectUrl}}):t}}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r??{}),waitForSession:(r,t,n)=>this.crossDeviceManager.waitForSession(r,t,n),getContext:r=>this.apiClient.getCrossDeviceContext(r),approve:r=>this.crossDeviceManager.approve(r)},recoverAccount:r=>this.recoveryService.recover(r)}};function oe(e,r,t){t&&Object.keys(t).length>0?e(`[TryMellon] ${r}`,t):e(`[TryMellon] ${r}`);}var He=class{debug(r,t){oe(console.debug,r,t);}info(r,t){oe(console.info,r,t);}warn(r,t){oe(console.warn,r,t);}error(r,t){oe(console.error,r,t);}};
2
+ exports.ConsoleLogger=He;exports.SANDBOX_SESSION_TOKEN=pe;exports.TryMellon=je;exports.TryMellonError=B;exports.createError=f;exports.createInvalidArgumentError=_;exports.createNetworkError=fr;exports.createNotSupportedError=ge;exports.createTimeoutError=Rr;exports.createUserCancelledError=mr;exports.err=a;exports.isTryMellonError=H;exports.mapWebAuthnError=v;exports.ok=d;return exports;})({});//# sourceMappingURL=index.global.js.map
3
3
  //# sourceMappingURL=index.global.js.map