@trymellon/js 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD CHANGED
@@ -49,10 +49,14 @@ curl -X POST https://api.trymellonauth.com/onboarding/ai \
49
49
  "tenantId": "...",
50
50
  "clientId": "cli_...",
51
51
  "clientSecret": "sec_...",
52
+ "publishableKey": "cli_...",
53
+ "applicationId": "...",
52
54
  "limits": { "maxUsers": 15, "maxApps": 1 }
53
55
  }
54
56
  ```
55
57
 
58
+ Use `publishableKey` (same as `clientId`) in the SDK: `TryMellon.create({ appId: '...', publishableKey: response.publishableKey })`. Use `applicationId` to update allowed origins (step 4) if you use passkeys or cross-device from your agent's domain.
59
+
56
60
  ### 2. Authenticate
57
61
  Use the `clientId` and `clientSecret` to get an access token via OAuth2 Client Credentials flow.
58
62
 
@@ -81,6 +85,18 @@ curl -X POST https://api.trymellonauth.com/v1/users \
81
85
  -d '{ "external_user_id": "user_123" }'
82
86
  ```
83
87
 
88
+ ### 4. Update allowed origins (required for passkeys / cross-device)
89
+ If your agent uses passkeys or cross-device auth from a real domain, the API must allow that origin. Call PATCH with the `applicationId` from step 1:
90
+
91
+ ```bash
92
+ curl -X PATCH https://api.trymellonauth.com/v1/applications/<applicationId> \
93
+ -H "Authorization: Bearer <access_token>" \
94
+ -H "Content-Type: application/json" \
95
+ -d '{ "allowed_origins": ["https://your-agent-domain.com"] }'
96
+ ```
97
+
98
+ Without this, requests from your agent's origin will get 404 when resolving the application. You can keep `https://agent.local` in the list for local testing.
99
+
84
100
  ---
85
101
 
86
102
  ## Installation
@@ -101,6 +117,19 @@ That's it. No peer dependencies. No bloat.
101
117
 
102
118
  ---
103
119
 
120
+ ## Where to get credentials
121
+
122
+ You need two values to initialize the SDK. Get both from the [TryMellon dashboard](https://trymellon-landing.pages.dev/dashboard) after creating an application and adding your app's origin.
123
+
124
+ | SDK parameter | What it is | Where to find it |
125
+ |------------------|-------------------------|-------------------------------------------|
126
+ | `appId` | **Application ID** (UUID) | Dashboard → Your app → **App ID** |
127
+ | `publishableKey` | **Client ID** (starts with `cli_`) | Dashboard → Your app → **Client ID** (same value is your publishable key) |
128
+
129
+ The API identifies your app by `publishableKey` (sent as `Authorization: Bearer <publishableKey>`) and the request **Origin**. Ensure your app's origin is allowed in the dashboard for that application.
130
+
131
+ ---
132
+
104
133
  ## Framework support & entry points
105
134
 
106
135
  The SDK is **framework-agnostic**. Use the main entry for Vanilla JS, Svelte, or any environment; use framework-specific entry points for React, Vue, and Angular to get hooks/services and tree-shaking.
@@ -124,7 +153,9 @@ npm install @trymellon/js
124
153
  import { TryMellon } from '@trymellon/js'
125
154
  import { TryMellonProvider, useTryMellon, useRegister, useAuthenticate } from '@trymellon/js/react'
126
155
 
127
- const client = new TryMellon({ appId: 'app_live_xxxx', publishableKey: 'key_live_xxxx' })
156
+ const clientResult = TryMellon.create({ appId: 'your-app-id-uuid', publishableKey: 'cli_xxxx' }) // Get these from Dashboard → Your app → App ID and Client ID
157
+ if (!clientResult.ok) throw clientResult.error
158
+ const client = clientResult.value
128
159
 
129
160
  function App() {
130
161
  return (
@@ -163,7 +194,9 @@ npm install @trymellon/js
163
194
  import { TryMellon } from '@trymellon/js'
164
195
  import { provideTryMellon, useTryMellon, useRegister, useAuthenticate } from '@trymellon/js/vue'
165
196
 
166
- const client = new TryMellon({ appId: 'app_live_xxxx', publishableKey: 'key_live_xxxx' })
197
+ const clientResult = TryMellon.create({ appId: 'your-app-id-uuid', publishableKey: 'cli_xxxx' }) // Get these from Dashboard → Your app → App ID and Client ID
198
+ if (!clientResult.ok) throw clientResult.error
199
+ const client = clientResult.value
167
200
  provideTryMellon(client)
168
201
 
169
202
  const { execute: register, loading } = useRegister()
@@ -195,8 +228,8 @@ import { provideTryMellonConfig } from '@trymellon/js/angular'
195
228
  export const appConfig = {
196
229
  providers: [
197
230
  provideTryMellonConfig({
198
- appId: 'app_live_xxxx',
199
- publishableKey: 'key_live_xxxx',
231
+ appId: 'your-app-id-uuid',
232
+ publishableKey: 'cli_xxxx',
200
233
  }),
201
234
  ],
202
235
  }
@@ -244,8 +277,8 @@ import { TryMellon } from '@trymellon/js'
244
277
 
245
278
  // 1. Initialize safely (Factory Pattern)
246
279
  const clientResult = TryMellon.create({
247
- appId: 'app_live_xxxx', // From your TryMellon dashboard
248
- publishableKey: 'key_live_xxxx', // Application API key
280
+ appId: 'your-app-id-uuid', // App ID (UUID) from Dashboard → Your app
281
+ publishableKey: 'cli_xxxx', // Client ID from Dashboard → Your app
249
282
  })
250
283
 
251
284
  if (!clientResult.ok) {
@@ -272,23 +305,34 @@ if (authResult.ok) {
272
305
 
273
306
  ## Initialization
274
307
 
308
+ Prefer **TryMellon.create()** so invalid config returns a Result instead of throwing:
309
+
275
310
  ```typescript
276
311
  import { TryMellon } from '@trymellon/js'
277
312
 
278
- const client = new TryMellon({
279
- appId: 'app_live_xxxx', // Required: application (tenant) identifier
280
- publishableKey: 'key_live_xxxx', // Required: API key for authentication
313
+ const clientResult = TryMellon.create({
314
+ appId: 'your-app-id-uuid',
315
+ publishableKey: 'cli_xxxx',
281
316
  apiBaseUrl: 'https://api.trymellonauth.com', // optional
282
- timeoutMs: 30000, // optional, default: 30000
283
- maxRetries: 3, // optional
284
- retryDelayMs: 1000, // optional
317
+ timeoutMs: 30000,
318
+ maxRetries: 3,
319
+ retryDelayMs: 1000,
285
320
  })
321
+
322
+ if (!clientResult.ok) {
323
+ console.error('Invalid config:', clientResult.error.message)
324
+ throw clientResult.error
325
+ }
326
+ const client = clientResult.value
286
327
  ```
287
328
 
329
+ > [!TIP]
330
+ > For static, validated config you can use `new TryMellon(config)`; it throws on invalid config. Prefer `TryMellon.create()` for user- or env-driven config so you can handle errors without try/catch.
331
+
288
332
  **Configuration options:**
289
333
 
290
- - `appId` (required): Your application identifier in TryMellon. Sent in header `X-App-Id`.
291
- - `publishableKey` (required): Public API key for authentication. Sent in header `Authorization: Bearer <publishableKey>`.
334
+ - `appId` (required): Your Application ID (UUID). Get it from Dashboard → Your app → App ID. Sent in header `X-App-Id`. The API identifies your app by `publishableKey` and Origin; `appId` is sent for consistency and future use.
335
+ - `publishableKey` (required): Your Client ID (value starting with `cli_`). Get it from Dashboard → Your app → Client ID. Sent in header `Authorization: Bearer <publishableKey>`. The API uses this plus the request Origin to resolve your application.
292
336
  - `apiBaseUrl` (optional): API base URL. Default: `'https://api.trymellonauth.com'`
293
337
  - `timeoutMs` (optional): HTTP request timeout. Range: `1000` - `300000`. Default: `30000`
294
338
  - `maxRetries` (optional): Retries for network errors. Range: `0` - `10`. Default: `3`
@@ -315,11 +359,13 @@ For local development or testing the integration flow without a real backend or
315
359
  ```typescript
316
360
  import { TryMellon, SANDBOX_SESSION_TOKEN } from '@trymellon/js'
317
361
 
318
- const client = new TryMellon({
362
+ const clientResult = TryMellon.create({
319
363
  sandbox: true,
320
364
  appId: 'sandbox',
321
365
  publishableKey: 'sandbox',
322
366
  })
367
+ if (!clientResult.ok) throw clientResult.error
368
+ const client = clientResult.value
323
369
 
324
370
  const result = await client.authenticate({ externalUserId: 'dev_user_1' })
325
371
  if (result.ok) {
@@ -581,6 +627,8 @@ async function authenticateWithEmail(userId: string, email: string) {
581
627
 
582
628
  Enable users to sign in on a desktop device by scanning a QR code with their mobile phone (where their passkey is stored).
583
629
 
630
+ **About `qr_url` and the mobile app:** The API returns `qr_url` in the form `{baseUrl}/mobile-auth?session_id={session_id}` (where `session_id` is a UUID). Your **mobile web app** must be deployed and its URL/origin **allowed in the TryMellon dashboard** for that application. The user scans the QR, opens that URL (which includes the `session_id`), and your mobile app must call `approve(session_id)` to complete the flow. If the mobile app’s origin is not allowed, the API will reject the request.
631
+
584
632
  ### 1. Desktop: Initialize and Show QR
585
633
 
586
634
  ```typescript
package/dist/angular.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- "use strict";var Je=Object.create;var k=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Qe=Object.prototype.hasOwnProperty;var xe=(e,r)=>(r=Symbol[e])?r:Symbol.for("Symbol."+e),K=e=>{throw TypeError(e)};var er=(e,r,t)=>r in e?k(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var Ae=(e,r)=>k(e,"name",{value:r,configurable:!0});var rr=(e,r)=>{for(var t in r)k(e,t,{get:r[t],enumerable:!0})},tr=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of Ze(r))!Qe.call(e,s)&&s!==t&&k(e,s,{get:()=>r[s],enumerable:!(n=Oe(r,s))||n.enumerable});return e};var nr=e=>tr(k({},"__esModule",{value:!0}),e);var Pe=e=>[,,,Je(e?.[xe("metadata")]??null)],De=["class","method","getter","setter","accessor","field","value","get","set"],L=e=>e!==void 0&&typeof e!="function"?K("Function expected"):e,sr=(e,r,t,n,s)=>({kind:De[e],name:r,metadata:n,addInitializer:i=>t._?K("Already initialized"):s.push(L(i||null))}),ir=(e,r)=>er(r,xe("metadata"),e[3]),Me=(e,r,t,n)=>{for(var s=0,i=e[r>>1],a=i&&i.length;s<a;s++)r&1?i[s].call(t):n=i[s].call(t,n);return n},ke=(e,r,t,n,s,i)=>{var a,c,u,h,g,m=r&7,A=!!(r&8),E=!!(r&16),M=m>3?e.length+1:m?A?1:2:0,I=De[m+5],ee=m>3&&(e[M-1]=[]),B=e[M]||(e[M]=[]),_=m&&(!E&&!A&&(s=s.prototype),m<5&&(m>3||!E)&&Oe(m<4?s:{get[t](){return Ce(this,i)},set[t](T){return Se(this,i,T)}},t));m?E&&m<4&&Ae(i,(m>2?"set ":m>1?"get ":"")+t):Ae(s,t);for(var re=n.length-1;re>=0;re--)h=sr(m,t,u={},e[3],B),m&&(h.static=A,h.private=E,g=h.access={has:E?T=>or(s,T):T=>t in T},m^3&&(g.get=E?T=>(m^1?Ce:ar)(T,s,m^4?i:_.get):T=>T[t]),m>2&&(g.set=E?(T,te)=>Se(T,s,te,m^4?i:_.set):(T,te)=>T[t]=te)),c=(0,n[re])(m?m<4?E?i:_[I]:m>4?void 0:{get:_.get,set:_.set}:s,h),u._=1,m^4||c===void 0?L(c)&&(m>4?ee.unshift(c):m?E?i=c:_[I]=c:s=c):typeof c!="object"||c===null?K("Object expected"):(L(a=c.get)&&(_.get=a),L(a=c.set)&&(_.set=a),L(a=c.init)&&ee.unshift(a));return m||ir(e,s),_&&k(s,t,_),E?m^4?i:_:s};var ne=(e,r,t)=>r.has(e)||K("Cannot "+t),or=(e,r)=>Object(r)!==r?K('Cannot use the "in" operator on this value'):e.has(r),Ce=(e,r,t)=>(ne(e,r,"read from private field"),t?t.call(e):r.get(e));var Se=(e,r,t,n)=>(ne(e,r,"write to private field"),n?n.call(e,t):r.set(e,t),t),ar=(e,r,t)=>(ne(e,r,"access private method"),t);var Sr={};rr(Sr,{TRYMELLON_CONFIG:()=>j,TryMellonService:()=>D,provideTryMellonConfig:()=>Cr});module.exports=nr(Sr);var F=require("@angular/core");var f=e=>({ok:!0,value:e}),l=e=>({ok:!1,error:e});var V=class e extends Error{code;details;isTryMellonError=!0;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}},lr={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new V(e,r??lr[e],t)}function se(e){return e instanceof V||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===!0}function ie(){return R("NOT_SUPPORTED")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function we(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function oe(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function ae(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw se(t)?t:b(r,"must be a valid URL")}}function x(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function W(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var ur={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function v(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=ur[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e){return typeof e=="string"}function S(e){return typeof e=="number"&&Number.isFinite(e)}function H(e){return typeof e=="boolean"}function w(e){return Array.isArray(e)}function o(e,r){return l(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function d(e,r){return e[r]}function le(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"rp");if(!y(n)||!p(n.name)||!p(n.id))return o("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=d(t,"user");if(!y(s)||!p(s.id)||!p(s.name)||!p(s.displayName))return o("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let i=d(t,"challenge");if(!p(i))return o("Invalid API response: challenge.challenge must be string",{originalData:e});let a=d(t,"pubKeyCredParams");if(!w(a))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let g of a)if(!y(g)||g.type!=="public-key"||!S(g.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let c=t.timeout;if(c!==void 0&&!S(c))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let u=t.excludeCredentials;if(u!==void 0){if(!w(u))return o("Invalid API response: excludeCredentials must be array",{originalData:e});for(let g of u)if(!y(g)||g.type!=="public-key"||!p(g.id))return o("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?o("Invalid API response: authenticatorSelection must be object",{originalData:e}):f({session_id:r,challenge:{rp:n,user:s,challenge:i,pubKeyCredParams:a,...c!==void 0&&{timeout:c},...u!==void 0&&{excludeCredentials:u},...h!==void 0&&{authenticatorSelection:h}}})}function ue(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"challenge"),s=d(t,"rpId"),i=t.allowCredentials;if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!p(s))return o("Invalid API response: challenge.rpId must be string",{originalData:e});if(i!==void 0&&!w(i))return o("Invalid API response: allowCredentials must be array",{originalData:e});if(i){for(let u of i)if(!y(u)||u.type!=="public-key"||!p(u.id))return o("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let a=t.timeout;if(a!==void 0&&!S(a))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let c=t.userVerification;return c!==void 0&&!["required","preferred","discouraged"].includes(String(c))?o("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):f({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:i??[],...a!==void 0&&{timeout:a},...c!==void 0&&{userVerification:c}}})}function pe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"credential_id"),t=d(e,"status"),n=d(e,"session_token"),s=d(e,"user");if(!p(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!p(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!p(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(s,"user_id"),a=d(s,"external_user_id");if(!p(i)||!p(a))return o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let c=s.email,u=s.metadata;return c!==void 0&&!p(c)?o("Invalid API response: user.email must be string",{originalData:e}):u!==void 0&&(typeof u!="object"||u===null)?o("Invalid API response: user.metadata must be object",{originalData:e}):f({credential_id:r,status:t,session_token:n,user:{user_id:i,external_user_id:a,...c!==void 0&&{email:c},...u!==void 0&&{metadata:u}}})}function de(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"authenticated"),t=d(e,"session_token"),n=d(e,"user"),s=d(e,"signals");if(!H(r))return o("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!p(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(n,"user_id"),a=d(n,"external_user_id");return!p(i)||!p(a)?o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?o("Invalid API response: signals must be object",{originalData:e}):f({authenticated:r,session_token:t,user:{user_id:i,external_user_id:a,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function ce(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"valid"),t=d(e,"user_id"),n=d(e,"external_user_id"),s=d(e,"tenant_id"),i=d(e,"app_id");return H(r)?p(t)?p(n)?p(s)?p(i)?f({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id: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 ge(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"sessionToken");return p(r)?f({sessionToken:r}):o("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var pr=["pending_passkey","pending_data","completed"],dr=["pending_data","completed"];function me(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return p(r)?p(t)?S(n)?f({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 fe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"status"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return!p(r)||!pr.includes(r)?o("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):p(t)?S(n)?f({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 ye(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"onboarding_url");if(!p(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(!p(n))return o("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,i;if(s!==void 0){let a=cr(s);if(!a.ok)return a;i=a.value}return f({session_id:r,status:"pending_passkey",onboarding_url:n,...i!==void 0&&{challenge:i}})}function cr(e){if(!y(e))return o("Invalid API response: challenge must be object",{originalData:e});let r=d(e,"rp"),t=d(e,"user"),n=d(e,"challenge"),s=d(e,"pubKeyCredParams");if(!y(r)||!p(r.name)||!p(r.id))return o("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!p(t.id)||!p(t.name)||!p(t.displayName))return o("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!w(s))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let i of s)if(!y(i)||i.type!=="public-key"||!S(i.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return f({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function Re(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id");return p(r)?!p(t)||!dr.includes(t)?o("Invalid API response: status must be pending_data|completed",{originalData:e}):p(n)?p(s)?f({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 he(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id"),i=d(e,"session_token");return p(r)?t!=="completed"?o("Invalid API response: status must be completed",{originalData:e}):!p(n)||!p(s)||!p(i)?o("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):f({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 gr(e){if(!e||typeof e!="object")return!1;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 mr(e){if(!e||typeof e!="object")return!1;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function Y(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return!p(r)||!p(t)||!p(n)?o("Invalid API response: missing required fields",{originalData:e}):f({session_id:r,qr_url:t,expires_at:n})}function ve(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.status;return!p(r)||!["pending","authenticated","completed"].includes(r)?o("Invalid API response: invalid status",{originalData:e}):f({status:r,user_id:e.user_id,session_token:e.session_token})}function be(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?gr(n)?f({type:"registration",options:n}):o("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):mr(n)?f({type:"auth",options:n}):o("Invalid API response: auth options must have challenge and rpId",{originalData:e}):o("Invalid API response: options are required",{originalData:e})}var G=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){let s=`${this.baseUrl}${r}`,i=await this.httpClient.post(s,t,this.mergeHeaders());return i.ok?n(i.value):l(i.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):l(i.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,le)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,ue)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,pe)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,de)}async validateSession(r){return this.get("/v1/sessions/validate",ce,{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?f(void 0):l(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},ge)}async startOnboarding(r){return this.post("/onboarding/start",r,me)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,fe)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,ye)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,Re)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,he)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},Y)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},Y)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,ve)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,be)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}};var fr=3e4;function yr(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function Ne(e,r){let t=r*Math.pow(2,e);return Math.min(t,fr)}function Rr(e,r){return e!=="GET"?!1:r>=500||r===429}var $=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=yr(),i=new Headers(t.headers);i.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let a;for(let c=0;c<=this.maxRetries;c++)try{let u=new AbortController,h=setTimeout(()=>u.abort(),this.timeoutMs);try{let g=await fetch(r,{...t,headers:i,signal:u.signal});if(!g.ok){let A;try{A=await g.json()}catch{}let E=A,M=E?.message??g.statusText,I=E?.error,B=R(I==="challenge_mismatch"?"CHALLENGE_MISMATCH":I??"NETWORK_FAILURE",M,{requestId:s,status:g.status,statusText:g.statusText,data:A});if(Rr(n,g.status)&&c<this.maxRetries){a=B,await new Promise(_=>setTimeout(_,Ne(c,this.retryDelayMs)));continue}return l(B)}let m=await g.json();return f(m)}finally{clearTimeout(h)}}catch(u){if(a=u,n==="GET"&&c<this.maxRetries)await new Promise(g=>setTimeout(g,Ne(c,this.retryDelayMs)));else break}return a instanceof Error&&a.name==="AbortError"?l(R("TIMEOUT","Request timed out",{requestId:s})):l(R("NETWORK_FAILURE",a instanceof Error?a.message:"Request failed",{requestId:s,cause:a}))}};function P(){try{return!(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return!1}}async function hr(){try{return!P()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?!1:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function Ue(){let e=P(),r=await hr();return{isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function C(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw oe("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function vr(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw oe("decode");let s=new Uint8Array(n.length);for(let i=0;i<n.length;i++)s[i]=n.charCodeAt(i);return s}function N(e){let r=vr(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function O(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw we(r)}function Fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function U(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:C(e.rawId),response:{clientDataJSON:C(t),attestationObject:C(n)},type:"public-key"}}function X(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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:C(e.rawId),response:{authenticatorData:C(n),clientDataJSON:C(t),signature:C(s),...i&&{userHandle:C(i)}},type:"public-key"}}function q(e,r){try{W(e.challenge,"challenge"),W(e.user.id,"user.id");let t=N(e.challenge),n=N(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(a=>({id:N(a.id),type:a.type,...a.transports&&{transports:a.transports}}))}};return f({publicKey:i})}catch(t){return l(v(t))}}function Ee(e,r){try{W(e.challenge,"challenge");let t=N(e.challenge);return f({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:N(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return l(v(t))}}async function Le(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!P()){let g=ie();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=q(s.value.challenge,e.authenticatorType);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.create(a);if(!c){let g=b("credential","creation failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishRegister({session_id:s.value.session_id,credential:U(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={success:!0,credentialId:u.value.credential_id,credential_id:u.value.credential_id,status:u.value.status,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}async function Ke(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!P()){let g=ie();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=Ee(s.value.challenge,e.mediation);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.get(a);if(!c){let g=b("credential","retrieval failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishAuthentication({session_id:s.value.session_id,credential:X(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={authenticated:u.value.authenticated,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata},signals:u.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}var br=2e3,Er=60,z=class{constructor(r){this.apiClient=r}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return l(t.error);let{session_id:n}=t.value;for(let s=0;s<Er;s++){await new Promise(u=>setTimeout(u,br));let i=await this.apiClient.getOnboardingStatus(n);if(!i.ok)return l(i.error);let a=i.value.status,c=i.value.onboarding_url;if(a==="pending_passkey"){let u=await this.apiClient.getOnboardingRegister(n);if(!u.ok)return l(u.error);let h=u.value;if(!h.challenge)return l(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:c}));let g=q(h.challenge);if(!g.ok)return l(g.error);let m;try{m=await navigator.credentials.create(g.value)}catch(I){return l(v(I))}try{O(m,"create")}catch(I){return l(v(I))}let A;try{A=U(m)}catch(I){return l(v(I))}let E=await this.apiClient.registerOnboardingPasskey(n,{credential:A,challenge:h.challenge.challenge});return E.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):l(E.error)}if(a==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return l(R("TIMEOUT","Onboarding timed out"))}};var _r=2e3,Tr=60,J=class{constructor(r){this.apiClient=r}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Tr;n++){if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return l(s.error);if(s.value.status==="completed")return!s.value.session_token||!s.value.user_id?l(R("UNKNOWN_ERROR","Missing data in completed session")):f({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(i=>{let a=setTimeout(()=>{i(null),t?.removeEventListener("abort",c)},_r),c=()=>{clearTimeout(a),i(null)};t?.addEventListener("abort",c)}),t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"))}return l(R("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return l(t.error);let n=t.value;return n.type==="registration"?this.executeRegistrationApproval(r,n):this.executeAuthApproval(r,n)}async executeRegistrationApproval(r,t){let n=q(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.create(n.value)}catch(a){return l(v(a))}try{O(s,"create")}catch(a){return l(v(a))}let i;try{i=U(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:i})}async executeAuthApproval(r,t){let n=Ee(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.get(n.value)}catch(a){return l(v(a))}try{O(s,"get")}catch(a){return l(v(a))}let i;try{i=X(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:i})}};var Z=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);n&&n.forEach(s=>{try{s(t)}catch{}})}removeAllListeners(){this.handlers.clear()}};var _e="https://api.trymellonauth.com",qe="https://api.trymellonauth.com/v1/telemetry";var je="trymellon_sandbox_session_token_v1";function Be(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:!0})}}}function Te(e,r){return{event:e,latencyMs:r,ok:!0}}var Q=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return l(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return l(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??_e;ae(s,"apiBaseUrl");let i=r.timeoutMs??3e4;return x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4),f(new e(r))}catch(t){return se(t)?l(t):l(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===!0,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:je;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??_e;ae(s,"apiBaseUrl");let i=r.timeoutMs??3e4;x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4);let a=r.maxRetries??3,c=r.retryDelayMs??1e3,u=new $(i,a,c,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),g={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new G(u,s,g),this.onboarding=new z(this.apiClient),this.crossDeviceManager=new J(this.apiClient),this.eventEmitter=new Z,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Be(r.telemetryEndpoint??qe))}static isSupported(){return P()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({success:!0,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Le(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Te("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({authenticated:!0,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Ke(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Te("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(f({valid:!0,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Ue()}on(r,t){return this.eventEmitter.on(r,t)}version(){return"1.4.1"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var j=new F.InjectionToken("TRYMELLON_CONFIG"),ze,Ie;ze=[(0,F.Injectable)({providedIn:"root"})];var D=class{config=(0,F.inject)(j,{optional:!0});_client=null;get client(){if(this._client==null){if(this.config==null)throw new Error("TryMellonService: provide TRYMELLON_CONFIG (e.g. via provideTryMellonConfig(config))");this._client=new Q(this.config)}return this._client}};Ie=Pe(null),D=ke(Ie,0,"TryMellonService",ze,D),Me(Ie,1,D);function Cr(e){return{provide:j,useValue:e}}0&&(module.exports={TRYMELLON_CONFIG,TryMellonService,provideTryMellonConfig});
2
+ "use strict";var Je=Object.create;var k=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Qe=Object.prototype.hasOwnProperty;var xe=(e,r)=>(r=Symbol[e])?r:Symbol.for("Symbol."+e),K=e=>{throw TypeError(e)};var er=(e,r,t)=>r in e?k(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var Ae=(e,r)=>k(e,"name",{value:r,configurable:!0});var rr=(e,r)=>{for(var t in r)k(e,t,{get:r[t],enumerable:!0})},tr=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of Ze(r))!Qe.call(e,s)&&s!==t&&k(e,s,{get:()=>r[s],enumerable:!(n=Oe(r,s))||n.enumerable});return e};var nr=e=>tr(k({},"__esModule",{value:!0}),e);var Pe=e=>[,,,Je(e?.[xe("metadata")]??null)],De=["class","method","getter","setter","accessor","field","value","get","set"],L=e=>e!==void 0&&typeof e!="function"?K("Function expected"):e,sr=(e,r,t,n,s)=>({kind:De[e],name:r,metadata:n,addInitializer:i=>t._?K("Already initialized"):s.push(L(i||null))}),ir=(e,r)=>er(r,xe("metadata"),e[3]),Me=(e,r,t,n)=>{for(var s=0,i=e[r>>1],a=i&&i.length;s<a;s++)r&1?i[s].call(t):n=i[s].call(t,n);return n},ke=(e,r,t,n,s,i)=>{var a,c,u,h,g,m=r&7,A=!!(r&8),E=!!(r&16),M=m>3?e.length+1:m?A?1:2:0,I=De[m+5],ee=m>3&&(e[M-1]=[]),B=e[M]||(e[M]=[]),_=m&&(!E&&!A&&(s=s.prototype),m<5&&(m>3||!E)&&Oe(m<4?s:{get[t](){return Ce(this,i)},set[t](T){return Se(this,i,T)}},t));m?E&&m<4&&Ae(i,(m>2?"set ":m>1?"get ":"")+t):Ae(s,t);for(var re=n.length-1;re>=0;re--)h=sr(m,t,u={},e[3],B),m&&(h.static=A,h.private=E,g=h.access={has:E?T=>or(s,T):T=>t in T},m^3&&(g.get=E?T=>(m^1?Ce:ar)(T,s,m^4?i:_.get):T=>T[t]),m>2&&(g.set=E?(T,te)=>Se(T,s,te,m^4?i:_.set):(T,te)=>T[t]=te)),c=(0,n[re])(m?m<4?E?i:_[I]:m>4?void 0:{get:_.get,set:_.set}:s,h),u._=1,m^4||c===void 0?L(c)&&(m>4?ee.unshift(c):m?E?i=c:_[I]=c:s=c):typeof c!="object"||c===null?K("Object expected"):(L(a=c.get)&&(_.get=a),L(a=c.set)&&(_.set=a),L(a=c.init)&&ee.unshift(a));return m||ir(e,s),_&&k(s,t,_),E?m^4?i:_:s};var ne=(e,r,t)=>r.has(e)||K("Cannot "+t),or=(e,r)=>Object(r)!==r?K('Cannot use the "in" operator on this value'):e.has(r),Ce=(e,r,t)=>(ne(e,r,"read from private field"),t?t.call(e):r.get(e));var Se=(e,r,t,n)=>(ne(e,r,"write to private field"),n?n.call(e,t):r.set(e,t),t),ar=(e,r,t)=>(ne(e,r,"access private method"),t);var Sr={};rr(Sr,{TRYMELLON_CONFIG:()=>j,TryMellonService:()=>D,provideTryMellonConfig:()=>Cr});module.exports=nr(Sr);var F=require("@angular/core");var f=e=>({ok:!0,value:e}),l=e=>({ok:!1,error:e});var V=class e extends Error{code;details;isTryMellonError=!0;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}},lr={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new V(e,r??lr[e],t)}function se(e){return e instanceof V||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===!0}function ie(){return R("NOT_SUPPORTED")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function we(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function oe(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function ae(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw se(t)?t:b(r,"must be a valid URL")}}function x(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function W(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var ur={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function v(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=ur[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e){return typeof e=="string"}function S(e){return typeof e=="number"&&Number.isFinite(e)}function H(e){return typeof e=="boolean"}function w(e){return Array.isArray(e)}function o(e,r){return l(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function d(e,r){return e[r]}function le(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"rp");if(!y(n)||!p(n.name)||!p(n.id))return o("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=d(t,"user");if(!y(s)||!p(s.id)||!p(s.name)||!p(s.displayName))return o("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let i=d(t,"challenge");if(!p(i))return o("Invalid API response: challenge.challenge must be string",{originalData:e});let a=d(t,"pubKeyCredParams");if(!w(a))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let g of a)if(!y(g)||g.type!=="public-key"||!S(g.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let c=t.timeout;if(c!==void 0&&!S(c))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let u=t.excludeCredentials;if(u!==void 0){if(!w(u))return o("Invalid API response: excludeCredentials must be array",{originalData:e});for(let g of u)if(!y(g)||g.type!=="public-key"||!p(g.id))return o("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?o("Invalid API response: authenticatorSelection must be object",{originalData:e}):f({session_id:r,challenge:{rp:n,user:s,challenge:i,pubKeyCredParams:a,...c!==void 0&&{timeout:c},...u!==void 0&&{excludeCredentials:u},...h!==void 0&&{authenticatorSelection:h}}})}function ue(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"challenge"),s=d(t,"rpId"),i=t.allowCredentials;if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!p(s))return o("Invalid API response: challenge.rpId must be string",{originalData:e});if(i!==void 0&&!w(i))return o("Invalid API response: allowCredentials must be array",{originalData:e});if(i){for(let u of i)if(!y(u)||u.type!=="public-key"||!p(u.id))return o("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let a=t.timeout;if(a!==void 0&&!S(a))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let c=t.userVerification;return c!==void 0&&!["required","preferred","discouraged"].includes(String(c))?o("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):f({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:i??[],...a!==void 0&&{timeout:a},...c!==void 0&&{userVerification:c}}})}function pe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"credential_id"),t=d(e,"status"),n=d(e,"session_token"),s=d(e,"user");if(!p(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!p(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!p(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(s,"user_id"),a=d(s,"external_user_id");if(!p(i)||!p(a))return o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let c=s.email,u=s.metadata;return c!==void 0&&!p(c)?o("Invalid API response: user.email must be string",{originalData:e}):u!==void 0&&(typeof u!="object"||u===null)?o("Invalid API response: user.metadata must be object",{originalData:e}):f({credential_id:r,status:t,session_token:n,user:{user_id:i,external_user_id:a,...c!==void 0&&{email:c},...u!==void 0&&{metadata:u}}})}function de(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"authenticated"),t=d(e,"session_token"),n=d(e,"user"),s=d(e,"signals");if(!H(r))return o("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!p(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(n,"user_id"),a=d(n,"external_user_id");return!p(i)||!p(a)?o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?o("Invalid API response: signals must be object",{originalData:e}):f({authenticated:r,session_token:t,user:{user_id:i,external_user_id:a,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function ce(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"valid"),t=d(e,"user_id"),n=d(e,"external_user_id"),s=d(e,"tenant_id"),i=d(e,"app_id");return H(r)?p(t)?p(n)?p(s)?p(i)?f({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id: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 ge(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"sessionToken");return p(r)?f({sessionToken:r}):o("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var pr=["pending_passkey","pending_data","completed"],dr=["pending_data","completed"];function me(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return p(r)?p(t)?S(n)?f({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 fe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"status"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return!p(r)||!pr.includes(r)?o("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):p(t)?S(n)?f({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 ye(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"onboarding_url");if(!p(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(!p(n))return o("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,i;if(s!==void 0){let a=cr(s);if(!a.ok)return a;i=a.value}return f({session_id:r,status:"pending_passkey",onboarding_url:n,...i!==void 0&&{challenge:i}})}function cr(e){if(!y(e))return o("Invalid API response: challenge must be object",{originalData:e});let r=d(e,"rp"),t=d(e,"user"),n=d(e,"challenge"),s=d(e,"pubKeyCredParams");if(!y(r)||!p(r.name)||!p(r.id))return o("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!p(t.id)||!p(t.name)||!p(t.displayName))return o("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!w(s))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let i of s)if(!y(i)||i.type!=="public-key"||!S(i.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return f({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function Re(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id");return p(r)?!p(t)||!dr.includes(t)?o("Invalid API response: status must be pending_data|completed",{originalData:e}):p(n)?p(s)?f({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 he(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id"),i=d(e,"session_token");return p(r)?t!=="completed"?o("Invalid API response: status must be completed",{originalData:e}):!p(n)||!p(s)||!p(i)?o("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):f({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 gr(e){if(!e||typeof e!="object")return!1;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 mr(e){if(!e||typeof e!="object")return!1;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function Y(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return!p(r)||!p(t)||!p(n)?o("Invalid API response: missing required fields",{originalData:e}):f({session_id:r,qr_url:t,expires_at:n})}function ve(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.status;return!p(r)||!["pending","authenticated","completed"].includes(r)?o("Invalid API response: invalid status",{originalData:e}):f({status:r,user_id:e.user_id,session_token:e.session_token})}function be(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?gr(n)?f({type:"registration",options:n}):o("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):mr(n)?f({type:"auth",options:n}):o("Invalid API response: auth options must have challenge and rpId",{originalData:e}):o("Invalid API response: options are required",{originalData:e})}var G=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){let s=`${this.baseUrl}${r}`,i=await this.httpClient.post(s,t,this.mergeHeaders());return i.ok?n(i.value):l(i.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):l(i.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,le)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,ue)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,pe)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,de)}async validateSession(r){return this.get("/v1/sessions/validate",ce,{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?f(void 0):l(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},ge)}async startOnboarding(r){return this.post("/onboarding/start",r,me)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,fe)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,ye)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,Re)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,he)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},Y)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},Y)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,ve)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,be)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}};var fr=3e4;function yr(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function Ne(e,r){let t=r*Math.pow(2,e);return Math.min(t,fr)}function Rr(e,r){return e!=="GET"?!1:r>=500||r===429}var $=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=yr(),i=new Headers(t.headers);i.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let a;for(let c=0;c<=this.maxRetries;c++)try{let u=new AbortController,h=setTimeout(()=>u.abort(),this.timeoutMs);try{let g=await fetch(r,{...t,headers:i,signal:u.signal});if(!g.ok){let A;try{A=await g.json()}catch{}let E=A,M=E?.message??g.statusText,I=E?.error,B=R(I==="challenge_mismatch"?"CHALLENGE_MISMATCH":I??"NETWORK_FAILURE",M,{requestId:s,status:g.status,statusText:g.statusText,data:A});if(Rr(n,g.status)&&c<this.maxRetries){a=B,await new Promise(_=>setTimeout(_,Ne(c,this.retryDelayMs)));continue}return l(B)}let m=await g.json();return f(m)}finally{clearTimeout(h)}}catch(u){if(a=u,n==="GET"&&c<this.maxRetries)await new Promise(g=>setTimeout(g,Ne(c,this.retryDelayMs)));else break}return a instanceof Error&&a.name==="AbortError"?l(R("TIMEOUT","Request timed out",{requestId:s})):l(R("NETWORK_FAILURE",a instanceof Error?a.message:"Request failed",{requestId:s,cause:a}))}};function P(){try{return!(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return!1}}async function hr(){try{return!P()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?!1:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function Ue(){let e=P(),r=await hr();return{isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function C(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw oe("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function vr(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw oe("decode");let s=new Uint8Array(n.length);for(let i=0;i<n.length;i++)s[i]=n.charCodeAt(i);return s}function N(e){let r=vr(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function O(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw we(r)}function Fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function U(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:C(e.rawId),response:{clientDataJSON:C(t),attestationObject:C(n)},type:"public-key"}}function X(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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:C(e.rawId),response:{authenticatorData:C(n),clientDataJSON:C(t),signature:C(s),...i&&{userHandle:C(i)}},type:"public-key"}}function q(e,r){try{W(e.challenge,"challenge"),W(e.user.id,"user.id");let t=N(e.challenge),n=N(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(a=>({id:N(a.id),type:a.type,...a.transports&&{transports:a.transports}}))}};return f({publicKey:i})}catch(t){return l(v(t))}}function Ee(e,r){try{W(e.challenge,"challenge");let t=N(e.challenge);return f({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:N(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return l(v(t))}}async function Le(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!P()){let g=ie();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=q(s.value.challenge,e.authenticatorType);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.create(a);if(!c){let g=b("credential","creation failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishRegister({session_id:s.value.session_id,credential:U(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={success:!0,credentialId:u.value.credential_id,credential_id:u.value.credential_id,status:u.value.status,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}async function Ke(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!P()){let g=ie();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=Ee(s.value.challenge,e.mediation);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.get(a);if(!c){let g=b("credential","retrieval failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishAuthentication({session_id:s.value.session_id,credential:X(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={authenticated:u.value.authenticated,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata},signals:u.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}var br=2e3,Er=60,z=class{constructor(r){this.apiClient=r}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return l(t.error);let{session_id:n}=t.value;for(let s=0;s<Er;s++){await new Promise(u=>setTimeout(u,br));let i=await this.apiClient.getOnboardingStatus(n);if(!i.ok)return l(i.error);let a=i.value.status,c=i.value.onboarding_url;if(a==="pending_passkey"){let u=await this.apiClient.getOnboardingRegister(n);if(!u.ok)return l(u.error);let h=u.value;if(!h.challenge)return l(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:c}));let g=q(h.challenge);if(!g.ok)return l(g.error);let m;try{m=await navigator.credentials.create(g.value)}catch(I){return l(v(I))}try{O(m,"create")}catch(I){return l(v(I))}let A;try{A=U(m)}catch(I){return l(v(I))}let E=await this.apiClient.registerOnboardingPasskey(n,{credential:A,challenge:h.challenge.challenge});return E.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):l(E.error)}if(a==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return l(R("TIMEOUT","Onboarding timed out"))}};var _r=2e3,Tr=60,J=class{constructor(r){this.apiClient=r}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Tr;n++){if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return l(s.error);if(s.value.status==="completed")return!s.value.session_token||!s.value.user_id?l(R("UNKNOWN_ERROR","Missing data in completed session")):f({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(i=>{let a=setTimeout(()=>{i(null),t?.removeEventListener("abort",c)},_r),c=()=>{clearTimeout(a),i(null)};t?.addEventListener("abort",c)}),t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"))}return l(R("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return l(t.error);let n=t.value;return n.type==="registration"?this.executeRegistrationApproval(r,n):this.executeAuthApproval(r,n)}async executeRegistrationApproval(r,t){let n=q(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.create(n.value)}catch(a){return l(v(a))}try{O(s,"create")}catch(a){return l(v(a))}let i;try{i=U(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:i})}async executeAuthApproval(r,t){let n=Ee(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.get(n.value)}catch(a){return l(v(a))}try{O(s,"get")}catch(a){return l(v(a))}let i;try{i=X(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:i})}};var Z=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);n&&n.forEach(s=>{try{s(t)}catch{}})}removeAllListeners(){this.handlers.clear()}};var _e="https://api.trymellonauth.com",qe="https://api.trymellonauth.com/v1/telemetry";var je="trymellon_sandbox_session_token_v1";function Be(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:!0})}}}function Te(e,r){return{event:e,latencyMs:r,ok:!0}}var Q=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return l(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return l(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??_e;ae(s,"apiBaseUrl");let i=r.timeoutMs??3e4;return x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4),f(new e(r))}catch(t){return se(t)?l(t):l(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===!0,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:je;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??_e;ae(s,"apiBaseUrl");let i=r.timeoutMs??3e4;x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4);let a=r.maxRetries??3,c=r.retryDelayMs??1e3,u=new $(i,a,c,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),g={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new G(u,s,g),this.onboarding=new z(this.apiClient),this.crossDeviceManager=new J(this.apiClient),this.eventEmitter=new Z,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Be(r.telemetryEndpoint??qe))}static isSupported(){return P()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({success:!0,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Le(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Te("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({authenticated:!0,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Ke(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(Te("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(f({valid:!0,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Ue()}on(r,t){return this.eventEmitter.on(r,t)}version(){return"1.4.3"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var j=new F.InjectionToken("TRYMELLON_CONFIG"),ze,Ie;ze=[(0,F.Injectable)({providedIn:"root"})];var D=class{config=(0,F.inject)(j,{optional:!0});_client=null;get client(){if(this._client==null){if(this.config==null)throw new Error("TryMellonService: provide TRYMELLON_CONFIG (e.g. via provideTryMellonConfig(config))");this._client=new Q(this.config)}return this._client}};Ie=Pe(null),D=ke(Ie,0,"TryMellonService",ze,D),Me(Ie,1,D);function Cr(e){return{provide:j,useValue:e}}0&&(module.exports={TRYMELLON_CONFIG,TryMellonService,provideTryMellonConfig});
3
3
  //# sourceMappingURL=angular.cjs.map
package/dist/angular.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- var Xe=Object.create;var re=Object.defineProperty;var ze=Object.getOwnPropertyDescriptor;var Se=(e,r)=>(r=Symbol[e])?r:Symbol.for("Symbol."+e),F=e=>{throw TypeError(e)};var Je=(e,r,t)=>r in e?re(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var Ie=(e,r)=>re(e,"name",{value:r,configurable:!0});var Oe=e=>[,,,Xe(e?.[Se("metadata")]??null)],xe=["class","method","getter","setter","accessor","field","value","get","set"],U=e=>e!==void 0&&typeof e!="function"?F("Function expected"):e,Ze=(e,r,t,n,s)=>({kind:xe[e],name:r,metadata:n,addInitializer:i=>t._?F("Already initialized"):s.push(U(i||null))}),Qe=(e,r)=>Je(r,Se("metadata"),e[3]),Pe=(e,r,t,n)=>{for(var s=0,i=e[r>>1],a=i&&i.length;s<a;s++)r&1?i[s].call(t):n=i[s].call(t,n);return n},De=(e,r,t,n,s,i)=>{var a,c,u,h,g,m=r&7,A=!!(r&8),E=!!(r&16),D=m>3?e.length+1:m?A?1:2:0,I=xe[m+5],Z=m>3&&(e[D-1]=[]),K=e[D]||(e[D]=[]),_=m&&(!E&&!A&&(s=s.prototype),m<5&&(m>3||!E)&&ze(m<4?s:{get[t](){return Ae(this,i)},set[t](T){return Ce(this,i,T)}},t));m?E&&m<4&&Ie(i,(m>2?"set ":m>1?"get ":"")+t):Ie(s,t);for(var Q=n.length-1;Q>=0;Q--)h=Ze(m,t,u={},e[3],K),m&&(h.static=A,h.private=E,g=h.access={has:E?T=>er(s,T):T=>t in T},m^3&&(g.get=E?T=>(m^1?Ae:rr)(T,s,m^4?i:_.get):T=>T[t]),m>2&&(g.set=E?(T,ee)=>Ce(T,s,ee,m^4?i:_.set):(T,ee)=>T[t]=ee)),c=(0,n[Q])(m?m<4?E?i:_[I]:m>4?void 0:{get:_.get,set:_.set}:s,h),u._=1,m^4||c===void 0?U(c)&&(m>4?Z.unshift(c):m?E?i=c:_[I]=c:s=c):typeof c!="object"||c===null?F("Object expected"):(U(a=c.get)&&(_.get=a),U(a=c.set)&&(_.set=a),U(a=c.init)&&Z.unshift(a));return m||Qe(e,s),_&&re(s,t,_),E?m^4?i:_:s};var te=(e,r,t)=>r.has(e)||F("Cannot "+t),er=(e,r)=>Object(r)!==r?F('Cannot use the "in" operator on this value'):e.has(r),Ae=(e,r,t)=>(te(e,r,"read from private field"),t?t.call(e):r.get(e));var Ce=(e,r,t,n)=>(te(e,r,"write to private field"),n?n.call(e,t):r.set(e,t),t),rr=(e,r,t)=>(te(e,r,"access private method"),t);import{Injectable as br,InjectionToken as Er,inject as _r}from"@angular/core";var f=e=>({ok:!0,value:e}),l=e=>({ok:!1,error:e});var q=class e extends Error{code;details;isTryMellonError=!0;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}},tr={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new q(e,r??tr[e],t)}function ne(e){return e instanceof q||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===!0}function se(){return R("NOT_SUPPORTED")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function Me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function ie(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function oe(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw ne(t)?t:b(r,"must be a valid URL")}}function x(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function j(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var nr={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function v(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=nr[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e){return typeof e=="string"}function S(e){return typeof e=="number"&&Number.isFinite(e)}function B(e){return typeof e=="boolean"}function M(e){return Array.isArray(e)}function o(e,r){return l(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function d(e,r){return e[r]}function ae(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"rp");if(!y(n)||!p(n.name)||!p(n.id))return o("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=d(t,"user");if(!y(s)||!p(s.id)||!p(s.name)||!p(s.displayName))return o("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let i=d(t,"challenge");if(!p(i))return o("Invalid API response: challenge.challenge must be string",{originalData:e});let a=d(t,"pubKeyCredParams");if(!M(a))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let g of a)if(!y(g)||g.type!=="public-key"||!S(g.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let c=t.timeout;if(c!==void 0&&!S(c))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let u=t.excludeCredentials;if(u!==void 0){if(!M(u))return o("Invalid API response: excludeCredentials must be array",{originalData:e});for(let g of u)if(!y(g)||g.type!=="public-key"||!p(g.id))return o("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?o("Invalid API response: authenticatorSelection must be object",{originalData:e}):f({session_id:r,challenge:{rp:n,user:s,challenge:i,pubKeyCredParams:a,...c!==void 0&&{timeout:c},...u!==void 0&&{excludeCredentials:u},...h!==void 0&&{authenticatorSelection:h}}})}function le(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"challenge"),s=d(t,"rpId"),i=t.allowCredentials;if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!p(s))return o("Invalid API response: challenge.rpId must be string",{originalData:e});if(i!==void 0&&!M(i))return o("Invalid API response: allowCredentials must be array",{originalData:e});if(i){for(let u of i)if(!y(u)||u.type!=="public-key"||!p(u.id))return o("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let a=t.timeout;if(a!==void 0&&!S(a))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let c=t.userVerification;return c!==void 0&&!["required","preferred","discouraged"].includes(String(c))?o("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):f({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:i??[],...a!==void 0&&{timeout:a},...c!==void 0&&{userVerification:c}}})}function ue(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"credential_id"),t=d(e,"status"),n=d(e,"session_token"),s=d(e,"user");if(!p(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!p(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!p(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(s,"user_id"),a=d(s,"external_user_id");if(!p(i)||!p(a))return o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let c=s.email,u=s.metadata;return c!==void 0&&!p(c)?o("Invalid API response: user.email must be string",{originalData:e}):u!==void 0&&(typeof u!="object"||u===null)?o("Invalid API response: user.metadata must be object",{originalData:e}):f({credential_id:r,status:t,session_token:n,user:{user_id:i,external_user_id:a,...c!==void 0&&{email:c},...u!==void 0&&{metadata:u}}})}function pe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"authenticated"),t=d(e,"session_token"),n=d(e,"user"),s=d(e,"signals");if(!B(r))return o("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!p(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(n,"user_id"),a=d(n,"external_user_id");return!p(i)||!p(a)?o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?o("Invalid API response: signals must be object",{originalData:e}):f({authenticated:r,session_token:t,user:{user_id:i,external_user_id:a,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function de(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"valid"),t=d(e,"user_id"),n=d(e,"external_user_id"),s=d(e,"tenant_id"),i=d(e,"app_id");return B(r)?p(t)?p(n)?p(s)?p(i)?f({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id: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 ce(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"sessionToken");return p(r)?f({sessionToken:r}):o("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var sr=["pending_passkey","pending_data","completed"],ir=["pending_data","completed"];function ge(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return p(r)?p(t)?S(n)?f({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 me(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"status"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return!p(r)||!sr.includes(r)?o("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):p(t)?S(n)?f({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 fe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"onboarding_url");if(!p(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(!p(n))return o("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,i;if(s!==void 0){let a=or(s);if(!a.ok)return a;i=a.value}return f({session_id:r,status:"pending_passkey",onboarding_url:n,...i!==void 0&&{challenge:i}})}function or(e){if(!y(e))return o("Invalid API response: challenge must be object",{originalData:e});let r=d(e,"rp"),t=d(e,"user"),n=d(e,"challenge"),s=d(e,"pubKeyCredParams");if(!y(r)||!p(r.name)||!p(r.id))return o("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!p(t.id)||!p(t.name)||!p(t.displayName))return o("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!M(s))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let i of s)if(!y(i)||i.type!=="public-key"||!S(i.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return f({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function ye(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id");return p(r)?!p(t)||!ir.includes(t)?o("Invalid API response: status must be pending_data|completed",{originalData:e}):p(n)?p(s)?f({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 Re(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id"),i=d(e,"session_token");return p(r)?t!=="completed"?o("Invalid API response: status must be completed",{originalData:e}):!p(n)||!p(s)||!p(i)?o("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):f({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 ar(e){if(!e||typeof e!="object")return!1;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 lr(e){if(!e||typeof e!="object")return!1;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function V(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return!p(r)||!p(t)||!p(n)?o("Invalid API response: missing required fields",{originalData:e}):f({session_id:r,qr_url:t,expires_at:n})}function he(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.status;return!p(r)||!["pending","authenticated","completed"].includes(r)?o("Invalid API response: invalid status",{originalData:e}):f({status:r,user_id:e.user_id,session_token:e.session_token})}function ve(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?ar(n)?f({type:"registration",options:n}):o("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):lr(n)?f({type:"auth",options:n}):o("Invalid API response: auth options must have challenge and rpId",{originalData:e}):o("Invalid API response: options are required",{originalData:e})}var W=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){let s=`${this.baseUrl}${r}`,i=await this.httpClient.post(s,t,this.mergeHeaders());return i.ok?n(i.value):l(i.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):l(i.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,ae)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,le)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,ue)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,pe)}async validateSession(r){return this.get("/v1/sessions/validate",de,{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?f(void 0):l(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},ce)}async startOnboarding(r){return this.post("/onboarding/start",r,ge)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,me)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,fe)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,ye)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,Re)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},V)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},V)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,he)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ve)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}};var ur=3e4;function pr(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ke(e,r){let t=r*Math.pow(2,e);return Math.min(t,ur)}function dr(e,r){return e!=="GET"?!1:r>=500||r===429}var H=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=pr(),i=new Headers(t.headers);i.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let a;for(let c=0;c<=this.maxRetries;c++)try{let u=new AbortController,h=setTimeout(()=>u.abort(),this.timeoutMs);try{let g=await fetch(r,{...t,headers:i,signal:u.signal});if(!g.ok){let A;try{A=await g.json()}catch{}let E=A,D=E?.message??g.statusText,I=E?.error,K=R(I==="challenge_mismatch"?"CHALLENGE_MISMATCH":I??"NETWORK_FAILURE",D,{requestId:s,status:g.status,statusText:g.statusText,data:A});if(dr(n,g.status)&&c<this.maxRetries){a=K,await new Promise(_=>setTimeout(_,ke(c,this.retryDelayMs)));continue}return l(K)}let m=await g.json();return f(m)}finally{clearTimeout(h)}}catch(u){if(a=u,n==="GET"&&c<this.maxRetries)await new Promise(g=>setTimeout(g,ke(c,this.retryDelayMs)));else break}return a instanceof Error&&a.name==="AbortError"?l(R("TIMEOUT","Request timed out",{requestId:s})):l(R("NETWORK_FAILURE",a instanceof Error?a.message:"Request failed",{requestId:s,cause:a}))}};function P(){try{return!(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return!1}}async function cr(){try{return!P()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?!1:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function we(){let e=P(),r=await cr();return{isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function C(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw ie("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function gr(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw ie("decode");let s=new Uint8Array(n.length);for(let i=0;i<n.length;i++)s[i]=n.charCodeAt(i);return s}function k(e){let r=gr(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function O(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw Me(r)}function Ne(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function w(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Ne(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:C(e.rawId),response:{clientDataJSON:C(t),attestationObject:C(n)},type:"public-key"}}function Y(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Ne(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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:C(e.rawId),response:{authenticatorData:C(n),clientDataJSON:C(t),signature:C(s),...i&&{userHandle:C(i)}},type:"public-key"}}function L(e,r){try{j(e.challenge,"challenge"),j(e.user.id,"user.id");let t=k(e.challenge),n=k(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(a=>({id:k(a.id),type:a.type,...a.transports&&{transports:a.transports}}))}};return f({publicKey:i})}catch(t){return l(v(t))}}function be(e,r){try{j(e.challenge,"challenge");let t=k(e.challenge);return f({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:k(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return l(v(t))}}async function Ue(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!P()){let g=se();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=L(s.value.challenge,e.authenticatorType);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.create(a);if(!c){let g=b("credential","creation failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishRegister({session_id:s.value.session_id,credential:w(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={success:!0,credentialId:u.value.credential_id,credential_id:u.value.credential_id,status:u.value.status,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}async function Fe(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!P()){let g=se();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=be(s.value.challenge,e.mediation);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.get(a);if(!c){let g=b("credential","retrieval failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishAuthentication({session_id:s.value.session_id,credential:Y(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={authenticated:u.value.authenticated,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata},signals:u.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}var mr=2e3,fr=60,G=class{constructor(r){this.apiClient=r}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return l(t.error);let{session_id:n}=t.value;for(let s=0;s<fr;s++){await new Promise(u=>setTimeout(u,mr));let i=await this.apiClient.getOnboardingStatus(n);if(!i.ok)return l(i.error);let a=i.value.status,c=i.value.onboarding_url;if(a==="pending_passkey"){let u=await this.apiClient.getOnboardingRegister(n);if(!u.ok)return l(u.error);let h=u.value;if(!h.challenge)return l(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:c}));let g=L(h.challenge);if(!g.ok)return l(g.error);let m;try{m=await navigator.credentials.create(g.value)}catch(I){return l(v(I))}try{O(m,"create")}catch(I){return l(v(I))}let A;try{A=w(m)}catch(I){return l(v(I))}let E=await this.apiClient.registerOnboardingPasskey(n,{credential:A,challenge:h.challenge.challenge});return E.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):l(E.error)}if(a==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return l(R("TIMEOUT","Onboarding timed out"))}};var yr=2e3,Rr=60,$=class{constructor(r){this.apiClient=r}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Rr;n++){if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return l(s.error);if(s.value.status==="completed")return!s.value.session_token||!s.value.user_id?l(R("UNKNOWN_ERROR","Missing data in completed session")):f({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(i=>{let a=setTimeout(()=>{i(null),t?.removeEventListener("abort",c)},yr),c=()=>{clearTimeout(a),i(null)};t?.addEventListener("abort",c)}),t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"))}return l(R("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return l(t.error);let n=t.value;return n.type==="registration"?this.executeRegistrationApproval(r,n):this.executeAuthApproval(r,n)}async executeRegistrationApproval(r,t){let n=L(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.create(n.value)}catch(a){return l(v(a))}try{O(s,"create")}catch(a){return l(v(a))}let i;try{i=w(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:i})}async executeAuthApproval(r,t){let n=be(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.get(n.value)}catch(a){return l(v(a))}try{O(s,"get")}catch(a){return l(v(a))}let i;try{i=Y(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:i})}};var X=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);n&&n.forEach(s=>{try{s(t)}catch{}})}removeAllListeners(){this.handlers.clear()}};var Ee="https://api.trymellonauth.com",Le="https://api.trymellonauth.com/v1/telemetry";var Ke="trymellon_sandbox_session_token_v1";function qe(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:!0})}}}function _e(e,r){return{event:e,latencyMs:r,ok:!0}}var z=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return l(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return l(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??Ee;oe(s,"apiBaseUrl");let i=r.timeoutMs??3e4;return x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4),f(new e(r))}catch(t){return ne(t)?l(t):l(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===!0,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:Ke;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??Ee;oe(s,"apiBaseUrl");let i=r.timeoutMs??3e4;x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4);let a=r.maxRetries??3,c=r.retryDelayMs??1e3,u=new H(i,a,c,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),g={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new W(u,s,g),this.onboarding=new G(this.apiClient),this.crossDeviceManager=new $(this.apiClient),this.eventEmitter=new X,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??qe(r.telemetryEndpoint??Le))}static isSupported(){return P()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({success:!0,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Ue(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(_e("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({authenticated:!0,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Fe(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(_e("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(f({valid:!0,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return we()}on(r,t){return this.eventEmitter.on(r,t)}version(){return"1.4.1"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var J=new Er("TRYMELLON_CONFIG"),$e,Te;$e=[br({providedIn:"root"})];var N=class{config=_r(J,{optional:!0});_client=null;get client(){if(this._client==null){if(this.config==null)throw new Error("TryMellonService: provide TRYMELLON_CONFIG (e.g. via provideTryMellonConfig(config))");this._client=new z(this.config)}return this._client}};Te=Oe(null),N=De(Te,0,"TryMellonService",$e,N),Pe(Te,1,N);function Zt(e){return{provide:J,useValue:e}}export{J as TRYMELLON_CONFIG,N as TryMellonService,Zt as provideTryMellonConfig};
2
+ var Xe=Object.create;var re=Object.defineProperty;var ze=Object.getOwnPropertyDescriptor;var Se=(e,r)=>(r=Symbol[e])?r:Symbol.for("Symbol."+e),F=e=>{throw TypeError(e)};var Je=(e,r,t)=>r in e?re(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var Ie=(e,r)=>re(e,"name",{value:r,configurable:!0});var Oe=e=>[,,,Xe(e?.[Se("metadata")]??null)],xe=["class","method","getter","setter","accessor","field","value","get","set"],U=e=>e!==void 0&&typeof e!="function"?F("Function expected"):e,Ze=(e,r,t,n,s)=>({kind:xe[e],name:r,metadata:n,addInitializer:i=>t._?F("Already initialized"):s.push(U(i||null))}),Qe=(e,r)=>Je(r,Se("metadata"),e[3]),Pe=(e,r,t,n)=>{for(var s=0,i=e[r>>1],a=i&&i.length;s<a;s++)r&1?i[s].call(t):n=i[s].call(t,n);return n},De=(e,r,t,n,s,i)=>{var a,c,u,h,g,m=r&7,A=!!(r&8),E=!!(r&16),D=m>3?e.length+1:m?A?1:2:0,I=xe[m+5],Z=m>3&&(e[D-1]=[]),K=e[D]||(e[D]=[]),_=m&&(!E&&!A&&(s=s.prototype),m<5&&(m>3||!E)&&ze(m<4?s:{get[t](){return Ae(this,i)},set[t](T){return Ce(this,i,T)}},t));m?E&&m<4&&Ie(i,(m>2?"set ":m>1?"get ":"")+t):Ie(s,t);for(var Q=n.length-1;Q>=0;Q--)h=Ze(m,t,u={},e[3],K),m&&(h.static=A,h.private=E,g=h.access={has:E?T=>er(s,T):T=>t in T},m^3&&(g.get=E?T=>(m^1?Ae:rr)(T,s,m^4?i:_.get):T=>T[t]),m>2&&(g.set=E?(T,ee)=>Ce(T,s,ee,m^4?i:_.set):(T,ee)=>T[t]=ee)),c=(0,n[Q])(m?m<4?E?i:_[I]:m>4?void 0:{get:_.get,set:_.set}:s,h),u._=1,m^4||c===void 0?U(c)&&(m>4?Z.unshift(c):m?E?i=c:_[I]=c:s=c):typeof c!="object"||c===null?F("Object expected"):(U(a=c.get)&&(_.get=a),U(a=c.set)&&(_.set=a),U(a=c.init)&&Z.unshift(a));return m||Qe(e,s),_&&re(s,t,_),E?m^4?i:_:s};var te=(e,r,t)=>r.has(e)||F("Cannot "+t),er=(e,r)=>Object(r)!==r?F('Cannot use the "in" operator on this value'):e.has(r),Ae=(e,r,t)=>(te(e,r,"read from private field"),t?t.call(e):r.get(e));var Ce=(e,r,t,n)=>(te(e,r,"write to private field"),n?n.call(e,t):r.set(e,t),t),rr=(e,r,t)=>(te(e,r,"access private method"),t);import{Injectable as br,InjectionToken as Er,inject as _r}from"@angular/core";var f=e=>({ok:!0,value:e}),l=e=>({ok:!1,error:e});var q=class e extends Error{code;details;isTryMellonError=!0;constructor(r,t,n){super(t),this.name="TryMellonError",this.code=r,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}},tr={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new q(e,r??tr[e],t)}function ne(e){return e instanceof q||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===!0}function se(){return R("NOT_SUPPORTED")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function Me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function ie(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function oe(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw ne(t)?t:b(r,"must be a valid URL")}}function x(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function j(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var nr={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function v(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=nr[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e){return typeof e=="string"}function S(e){return typeof e=="number"&&Number.isFinite(e)}function B(e){return typeof e=="boolean"}function M(e){return Array.isArray(e)}function o(e,r){return l(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function d(e,r){return e[r]}function ae(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"rp");if(!y(n)||!p(n.name)||!p(n.id))return o("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=d(t,"user");if(!y(s)||!p(s.id)||!p(s.name)||!p(s.displayName))return o("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let i=d(t,"challenge");if(!p(i))return o("Invalid API response: challenge.challenge must be string",{originalData:e});let a=d(t,"pubKeyCredParams");if(!M(a))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let g of a)if(!y(g)||g.type!=="public-key"||!S(g.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let c=t.timeout;if(c!==void 0&&!S(c))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let u=t.excludeCredentials;if(u!==void 0){if(!M(u))return o("Invalid API response: excludeCredentials must be array",{originalData:e});for(let g of u)if(!y(g)||g.type!=="public-key"||!p(g.id))return o("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?o("Invalid API response: authenticatorSelection must be object",{originalData:e}):f({session_id:r,challenge:{rp:n,user:s,challenge:i,pubKeyCredParams:a,...c!==void 0&&{timeout:c},...u!==void 0&&{excludeCredentials:u},...h!==void 0&&{authenticatorSelection:h}}})}function le(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id");if(!p(r))return o("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=d(e,"challenge");if(!y(t))return o("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=d(t,"challenge"),s=d(t,"rpId"),i=t.allowCredentials;if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!p(s))return o("Invalid API response: challenge.rpId must be string",{originalData:e});if(i!==void 0&&!M(i))return o("Invalid API response: allowCredentials must be array",{originalData:e});if(i){for(let u of i)if(!y(u)||u.type!=="public-key"||!p(u.id))return o("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let a=t.timeout;if(a!==void 0&&!S(a))return o("Invalid API response: challenge.timeout must be number",{originalData:e});let c=t.userVerification;return c!==void 0&&!["required","preferred","discouraged"].includes(String(c))?o("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):f({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:i??[],...a!==void 0&&{timeout:a},...c!==void 0&&{userVerification:c}}})}function ue(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"credential_id"),t=d(e,"status"),n=d(e,"session_token"),s=d(e,"user");if(!p(r))return o("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!p(t))return o("Invalid API response: status must be string",{field:"status",originalData:e});if(!p(n))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(s,"user_id"),a=d(s,"external_user_id");if(!p(i)||!p(a))return o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let c=s.email,u=s.metadata;return c!==void 0&&!p(c)?o("Invalid API response: user.email must be string",{originalData:e}):u!==void 0&&(typeof u!="object"||u===null)?o("Invalid API response: user.metadata must be object",{originalData:e}):f({credential_id:r,status:t,session_token:n,user:{user_id:i,external_user_id:a,...c!==void 0&&{email:c},...u!==void 0&&{metadata:u}}})}function pe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"authenticated"),t=d(e,"session_token"),n=d(e,"user"),s=d(e,"signals");if(!B(r))return o("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!p(t))return o("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return o("Invalid API response: user must be object",{field:"user",originalData:e});let i=d(n,"user_id"),a=d(n,"external_user_id");return!p(i)||!p(a)?o("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?o("Invalid API response: signals must be object",{originalData:e}):f({authenticated:r,session_token:t,user:{user_id:i,external_user_id:a,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function de(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"valid"),t=d(e,"user_id"),n=d(e,"external_user_id"),s=d(e,"tenant_id"),i=d(e,"app_id");return B(r)?p(t)?p(n)?p(s)?p(i)?f({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id: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 ce(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"sessionToken");return p(r)?f({sessionToken:r}):o("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var sr=["pending_passkey","pending_data","completed"],ir=["pending_data","completed"];function ge(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return p(r)?p(t)?S(n)?f({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 me(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"status"),t=d(e,"onboarding_url"),n=d(e,"expires_in");return!p(r)||!sr.includes(r)?o("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):p(t)?S(n)?f({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 fe(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"onboarding_url");if(!p(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(!p(n))return o("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,i;if(s!==void 0){let a=or(s);if(!a.ok)return a;i=a.value}return f({session_id:r,status:"pending_passkey",onboarding_url:n,...i!==void 0&&{challenge:i}})}function or(e){if(!y(e))return o("Invalid API response: challenge must be object",{originalData:e});let r=d(e,"rp"),t=d(e,"user"),n=d(e,"challenge"),s=d(e,"pubKeyCredParams");if(!y(r)||!p(r.name)||!p(r.id))return o("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!p(t.id)||!p(t.name)||!p(t.displayName))return o("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!p(n))return o("Invalid API response: challenge.challenge must be string",{originalData:e});if(!M(s))return o("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let i of s)if(!y(i)||i.type!=="public-key"||!S(i.alg))return o("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return f({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function ye(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id");return p(r)?!p(t)||!ir.includes(t)?o("Invalid API response: status must be pending_data|completed",{originalData:e}):p(n)?p(s)?f({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 Re(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=d(e,"session_id"),t=d(e,"status"),n=d(e,"user_id"),s=d(e,"tenant_id"),i=d(e,"session_token");return p(r)?t!=="completed"?o("Invalid API response: status must be completed",{originalData:e}):!p(n)||!p(s)||!p(i)?o("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):f({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 ar(e){if(!e||typeof e!="object")return!1;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 lr(e){if(!e||typeof e!="object")return!1;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function V(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return!p(r)||!p(t)||!p(n)?o("Invalid API response: missing required fields",{originalData:e}):f({session_id:r,qr_url:t,expires_at:n})}function he(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.status;return!p(r)||!["pending","authenticated","completed"].includes(r)?o("Invalid API response: invalid status",{originalData:e}):f({status:r,user_id:e.user_id,session_token:e.session_token})}function ve(e){if(!y(e))return o("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?ar(n)?f({type:"registration",options:n}):o("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):lr(n)?f({type:"auth",options:n}):o("Invalid API response: auth options must have challenge and rpId",{originalData:e}):o("Invalid API response: options are required",{originalData:e})}var W=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){let s=`${this.baseUrl}${r}`,i=await this.httpClient.post(s,t,this.mergeHeaders());return i.ok?n(i.value):l(i.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):l(i.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,ae)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,le)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,ue)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,pe)}async validateSession(r){return this.get("/v1/sessions/validate",de,{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?f(void 0):l(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},ce)}async startOnboarding(r){return this.post("/onboarding/start",r,ge)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,me)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,fe)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,ye)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,Re)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},V)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},V)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,he)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ve)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?f(void 0):l(n.error)}};var ur=3e4;function pr(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ke(e,r){let t=r*Math.pow(2,e);return Math.min(t,ur)}function dr(e,r){return e!=="GET"?!1:r>=500||r===429}var H=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=pr(),i=new Headers(t.headers);i.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let a;for(let c=0;c<=this.maxRetries;c++)try{let u=new AbortController,h=setTimeout(()=>u.abort(),this.timeoutMs);try{let g=await fetch(r,{...t,headers:i,signal:u.signal});if(!g.ok){let A;try{A=await g.json()}catch{}let E=A,D=E?.message??g.statusText,I=E?.error,K=R(I==="challenge_mismatch"?"CHALLENGE_MISMATCH":I??"NETWORK_FAILURE",D,{requestId:s,status:g.status,statusText:g.statusText,data:A});if(dr(n,g.status)&&c<this.maxRetries){a=K,await new Promise(_=>setTimeout(_,ke(c,this.retryDelayMs)));continue}return l(K)}let m=await g.json();return f(m)}finally{clearTimeout(h)}}catch(u){if(a=u,n==="GET"&&c<this.maxRetries)await new Promise(g=>setTimeout(g,ke(c,this.retryDelayMs)));else break}return a instanceof Error&&a.name==="AbortError"?l(R("TIMEOUT","Request timed out",{requestId:s})):l(R("NETWORK_FAILURE",a instanceof Error?a.message:"Request failed",{requestId:s,cause:a}))}};function P(){try{return!(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return!1}}async function cr(){try{return!P()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?!1:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function we(){let e=P(),r=await cr();return{isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function C(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw ie("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function gr(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw ie("decode");let s=new Uint8Array(n.length);for(let i=0;i<n.length;i++)s[i]=n.charCodeAt(i);return s}function k(e){let r=gr(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function O(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw Me(r)}function Ne(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function w(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Ne(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:C(e.rawId),response:{clientDataJSON:C(t),attestationObject:C(n)},type:"public-key"}}function Y(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!Ne(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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:C(e.rawId),response:{authenticatorData:C(n),clientDataJSON:C(t),signature:C(s),...i&&{userHandle:C(i)}},type:"public-key"}}function L(e,r){try{j(e.challenge,"challenge"),j(e.user.id,"user.id");let t=k(e.challenge),n=k(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(a=>({id:k(a.id),type:a.type,...a.transports&&{transports:a.transports}}))}};return f({publicKey:i})}catch(t){return l(v(t))}}function be(e,r){try{j(e.challenge,"challenge");let t=k(e.challenge);return f({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:k(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return l(v(t))}}async function Ue(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!P()){let g=se();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=L(s.value.challenge,e.authenticatorType);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.create(a);if(!c){let g=b("credential","creation failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishRegister({session_id:s.value.session_id,credential:w(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={success:!0,credentialId:u.value.credential_id,credential_id:u.value.credential_id,status:u.value.status,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}async function Fe(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!P()){let g=se();return t.emit("error",{type:"error",error:g}),l(g)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let g=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:g}),l(g)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),l(s.error);let i=be(s.value.challenge,e.mediation);if(!i.ok)return t.emit("error",{type:"error",error:i.error}),l(i.error);let a={...i.value,...e.signal&&{signal:e.signal}},c=await navigator.credentials.get(a);if(!c){let g=b("credential","retrieval failed");return t.emit("error",{type:"error",error:g}),l(g)}try{O(c)}catch(g){let m=v(g);return t.emit("error",{type:"error",error:m}),l(m)}let u=await r.finishAuthentication({session_id:s.value.session_id,credential:Y(c)});if(!u.ok)return t.emit("error",{type:"error",error:u.error}),l(u.error);let h={authenticated:u.value.authenticated,sessionToken:u.value.session_token,user:{userId:u.value.user.user_id,externalUserId:u.value.user.external_user_id,email:u.value.user.email,metadata:u.value.user.metadata},signals:u.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),f(h)}catch(n){let s=v(n);return t.emit("error",{type:"error",error:s}),l(s)}}var mr=2e3,fr=60,G=class{constructor(r){this.apiClient=r}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return l(t.error);let{session_id:n}=t.value;for(let s=0;s<fr;s++){await new Promise(u=>setTimeout(u,mr));let i=await this.apiClient.getOnboardingStatus(n);if(!i.ok)return l(i.error);let a=i.value.status,c=i.value.onboarding_url;if(a==="pending_passkey"){let u=await this.apiClient.getOnboardingRegister(n);if(!u.ok)return l(u.error);let h=u.value;if(!h.challenge)return l(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:c}));let g=L(h.challenge);if(!g.ok)return l(g.error);let m;try{m=await navigator.credentials.create(g.value)}catch(I){return l(v(I))}try{O(m,"create")}catch(I){return l(v(I))}let A;try{A=w(m)}catch(I){return l(v(I))}let E=await this.apiClient.registerOnboardingPasskey(n,{credential:A,challenge:h.challenge.challenge});return E.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):l(E.error)}if(a==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return l(R("TIMEOUT","Onboarding timed out"))}};var yr=2e3,Rr=60,$=class{constructor(r){this.apiClient=r}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Rr;n++){if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return l(s.error);if(s.value.status==="completed")return!s.value.session_token||!s.value.user_id?l(R("UNKNOWN_ERROR","Missing data in completed session")):f({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(i=>{let a=setTimeout(()=>{i(null),t?.removeEventListener("abort",c)},yr),c=()=>{clearTimeout(a),i(null)};t?.addEventListener("abort",c)}),t?.aborted)return l(R("ABORT_ERROR","Operation aborted by user or timeout"))}return l(R("TIMEOUT","Cross-device authentication timed out"))}async approve(r){let t=await this.apiClient.getCrossDeviceContext(r);if(!t.ok)return l(t.error);let n=t.value;return n.type==="registration"?this.executeRegistrationApproval(r,n):this.executeAuthApproval(r,n)}async executeRegistrationApproval(r,t){let n=L(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.create(n.value)}catch(a){return l(v(a))}try{O(s,"create")}catch(a){return l(v(a))}let i;try{i=w(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:i})}async executeAuthApproval(r,t){let n=be(t.options);if(!n.ok)return l(n.error);let s;try{s=await navigator.credentials.get(n.value)}catch(a){return l(v(a))}try{O(s,"get")}catch(a){return l(v(a))}let i;try{i=Y(s)}catch(a){return l(v(a))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:i})}};var X=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);n&&n.forEach(s=>{try{s(t)}catch{}})}removeAllListeners(){this.handlers.clear()}};var Ee="https://api.trymellonauth.com",Le="https://api.trymellonauth.com/v1/telemetry";var Ke="trymellon_sandbox_session_token_v1";function qe(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:!0})}}}function _e(e,r){return{event:e,latencyMs:r,ok:!0}}var z=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return l(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return l(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??Ee;oe(s,"apiBaseUrl");let i=r.timeoutMs??3e4;return x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4),f(new e(r))}catch(t){return ne(t)?l(t):l(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===!0,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:Ke;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??Ee;oe(s,"apiBaseUrl");let i=r.timeoutMs??3e4;x(i,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&x(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&x(r.retryDelayMs,"retryDelayMs",100,1e4);let a=r.maxRetries??3,c=r.retryDelayMs??1e3,u=new H(i,a,c,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),g={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new W(u,s,g),this.onboarding=new G(this.apiClient),this.crossDeviceManager=new $(this.apiClient),this.eventEmitter=new X,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??qe(r.telemetryEndpoint??Le))}static isSupported(){return P()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({success:!0,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Ue(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(_e("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(f({authenticated:!0,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await Fe(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(_e("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(f({valid:!0,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return we()}on(r,t){return this.eventEmitter.on(r,t)}version(){return"1.4.3"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var J=new Er("TRYMELLON_CONFIG"),$e,Te;$e=[br({providedIn:"root"})];var N=class{config=_r(J,{optional:!0});_client=null;get client(){if(this._client==null){if(this.config==null)throw new Error("TryMellonService: provide TRYMELLON_CONFIG (e.g. via provideTryMellonConfig(config))");this._client=new z(this.config)}return this._client}};Te=Oe(null),N=De(Te,0,"TryMellonService",$e,N),Pe(Te,1,N);function Zt(e){return{provide:J,useValue:e}}export{J as TRYMELLON_CONFIG,N as TryMellonService,Zt as provideTryMellonConfig};
3
3
  //# sourceMappingURL=angular.js.map
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';var g=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var D=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);}},ke={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new D(e,r??ke[e],t)}function w(e){return e instanceof D||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function N(){return R("NOT_SUPPORTED")}function Pe(){return R("USER_CANCELLED")}function De(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Me(){return R("TIMEOUT")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function H(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function $(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw w(t)?t:b(r,"must be a valid URL")}}function I(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function U(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var we={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function f(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=we[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"}function T(e){return typeof e=="number"&&Number.isFinite(e)}function F(e){return typeof e=="boolean"}function C(e){return Array.isArray(e)}function i(e,r){return a(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function p(e,r){return e[r]}function X(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"rp");if(!y(n)||!l(n.name)||!l(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=p(t,"user");if(!y(s)||!l(s.id)||!l(s.name)||!l(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=p(t,"challenge");if(!l(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let u=p(t,"pubKeyCredParams");if(!C(u))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let c of u)if(!y(c)||c.type!=="public-key"||!T(c.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let m=t.timeout;if(m!==void 0&&!T(m))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let d=t.excludeCredentials;if(d!==void 0){if(!C(d))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let c of d)if(!y(c)||c.type!=="public-key"||!l(c.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):g({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:u,...m!==void 0&&{timeout:m},...d!==void 0&&{excludeCredentials:d},...h!==void 0&&{authenticatorSelection:h}}})}function Y(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"challenge"),s=p(t,"rpId"),o=t.allowCredentials;if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!l(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!C(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let d of o)if(!y(d)||d.type!=="public-key"||!l(d.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let u=t.timeout;if(u!==void 0&&!T(u))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let m=t.userVerification;return m!==void 0&&!["required","preferred","discouraged"].includes(String(m))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):g({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...u!==void 0&&{timeout:u},...m!==void 0&&{userVerification:m}}})}function G(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"credential_id"),t=p(e,"status"),n=p(e,"session_token"),s=p(e,"user");if(!l(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!l(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(s,"user_id"),u=p(s,"external_user_id");if(!l(o)||!l(u))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let m=s.email,d=s.metadata;return m!==void 0&&!l(m)?i("Invalid API response: user.email must be string",{originalData:e}):d!==void 0&&(typeof d!="object"||d===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):g({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:u,...m!==void 0&&{email:m},...d!==void 0&&{metadata:d}}})}function z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"authenticated"),t=p(e,"session_token"),n=p(e,"user"),s=p(e,"signals");if(!F(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!l(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(n,"user_id"),u=p(n,"external_user_id");return !l(o)||!l(u)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?i("Invalid API response: signals must be object",{originalData:e}):g({authenticated:r,session_token:t,user:{user_id:o,external_user_id:u,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function J(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"valid"),t=p(e,"user_id"),n=p(e,"external_user_id"),s=p(e,"tenant_id"),o=p(e,"app_id");return F(r)?l(t)?l(n)?l(s)?l(o)?g({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function Z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"sessionToken");return l(r)?g({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Ne=["pending_passkey","pending_data","completed"],Ue=["pending_data","completed"];function Q(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return l(r)?l(t)?T(n)?g({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function ee(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"status"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return !l(r)||!Ne.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):l(t)?T(n)?g({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function re(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"onboarding_url");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let u=Fe(s);if(!u.ok)return u;o=u.value;}return g({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Fe(e){if(!y(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=p(e,"rp"),t=p(e,"user"),n=p(e,"challenge"),s=p(e,"pubKeyCredParams");if(!y(r)||!l(r.name)||!l(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!l(t.id)||!l(t.name)||!l(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!C(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!y(o)||o.type!=="public-key"||!T(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return g({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function te(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id");return l(r)?!l(t)||!Ue.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):l(n)?l(s)?g({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function ne(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id"),o=p(e,"session_token");return l(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!l(n)||!l(s)||!l(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):g({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function Le(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 Ke(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function L(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !l(r)||!l(t)||!l(n)?i("Invalid API response: missing required fields",{originalData:e}):g({session_id:r,qr_url:t,expires_at:n})}function se(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !l(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):g({status:r,user_id:e.user_id,session_token:e.session_token})}function ie(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?Le(n)?g({type:"registration",options:n}):i("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):Ke(n)?g({type:"auth",options:n}):i("Invalid API response: auth options must have challenge and rpId",{originalData:e}):i("Invalid API response: options are required",{originalData:e})}var K=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){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):a(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):a(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,X)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,Y)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,G)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,z)}async validateSession(r){return this.get("/v1/sessions/validate",J,{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?g(void 0):a(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},Z)}async startOnboarding(r){return this.post("/onboarding/start",r,Q)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,ee)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,re)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,te)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,ne)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},L)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},L)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,se)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ie)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}};var qe=3e4;function je(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ye(e,r){let t=r*Math.pow(2,e);return Math.min(t,qe)}function Be(e,r){return e!=="GET"?false:r>=500||r===429}var q=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=je(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let u;for(let m=0;m<=this.maxRetries;m++)try{let d=new AbortController,h=setTimeout(()=>d.abort(),this.timeoutMs);try{let c=await fetch(r,{...t,headers:o,signal:d.signal});if(!c.ok){let O;try{O=await c.json();}catch{}let P=O,ce=P?.message??c.statusText,_=P?.error,ge=R(_==="challenge_mismatch"?"CHALLENGE_MISMATCH":_??"NETWORK_FAILURE",ce,{requestId:s,status:c.status,statusText:c.statusText,data:O});if(Be(n,c.status)&&m<this.maxRetries){u=ge,await new Promise(xe=>setTimeout(xe,ye(m,this.retryDelayMs)));continue}return a(ge)}let v=await c.json();return g(v)}finally{clearTimeout(h);}}catch(d){if(u=d,n==="GET"&&m<this.maxRetries)await new Promise(c=>setTimeout(c,ye(m,this.retryDelayMs)));else break}return u instanceof Error&&u.name==="AbortError"?a(R("TIMEOUT","Request timed out",{requestId:s})):a(R("NETWORK_FAILURE",u instanceof Error?u.message:"Request failed",{requestId:s,cause:u}))}};function S(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function Ve(){try{return !S()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Re(){let e=S(),r=await Ve();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function E(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw H("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function We(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw H("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function x(e){let r=We(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function A(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw me(r)}function fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:E(e.rawId),response:{clientDataJSON:E(t),attestationObject:E(n)},type:"public-key"}}function j(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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,o=r.userHandle;return {id:e.id,rawId:E(e.rawId),response:{authenticatorData:E(n),clientDataJSON:E(t),signature:E(s),...o&&{userHandle:E(o)}},type:"public-key"}}function M(e,r){try{U(e.challenge,"challenge"),U(e.user.id,"user.id");let t=x(e.challenge),n=x(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={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(u=>({id:x(u.id),type:u.type,...u.transports&&{transports:u.transports}}))}};return g({publicKey:o})}catch(t){return a(f(t))}}function oe(e,r){try{U(e.challenge,"challenge");let t=x(e.challenge);return g({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:x(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(f(t))}}async function he(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=M(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.create(u);if(!m){let c=b("credential","creation failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishRegister({session_id:s.value.session_id,credential:k(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={success:true,credentialId:d.value.credential_id,credential_id:d.value.credential_id,status:d.value.status,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}async function be(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=oe(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.get(u);if(!m){let c=b("credential","retrieval failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishAuthentication({session_id:s.value.session_id,credential:j(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={authenticated:d.value.authenticated,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata},signals:d.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}var He=2e3,$e=60,B=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return a(t.error);let{session_id:n}=t.value;for(let s=0;s<$e;s++){await new Promise(d=>setTimeout(d,He));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return a(o.error);let u=o.value.status,m=o.value.onboarding_url;if(u==="pending_passkey"){let d=await this.apiClient.getOnboardingRegister(n);if(!d.ok)return a(d.error);let h=d.value;if(!h.challenge)return a(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:m}));let c=M(h.challenge);if(!c.ok)return a(c.error);let v;try{v=await navigator.credentials.create(c.value);}catch(_){return a(f(_))}try{A(v,"create");}catch(_){return a(f(_))}let O;try{O=k(v);}catch(_){return a(f(_))}let P=await this.apiClient.registerOnboardingPasskey(n,{credential:O,challenge:h.challenge.challenge});return P.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):a(P.error)}if(u==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return a(R("TIMEOUT","Onboarding timed out"))}};var Xe=2e3,Ye=60,V=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Ye;n++){if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return a(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?a(R("UNKNOWN_ERROR","Missing data in completed session")):g({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let u=setTimeout(()=>{o(null),t?.removeEventListener("abort",m);},Xe),m=()=>{clearTimeout(u),o(null);};t?.addEventListener("abort",m);}),t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"))}return a(R("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=M(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(u){return a(f(u))}try{A(s,"create");}catch(u){return a(f(u))}let o;try{o=k(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:o})}async executeAuthApproval(r,t){let n=oe(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(u){return a(f(u))}try{A(s,"get");}catch(u){return a(f(u))}let o;try{o=j(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var W=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);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var ae="https://api.trymellonauth.com",ve="https://api.trymellonauth.com/v1/telemetry";var le="trymellon_sandbox_session_token_v1";function Ee(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 ue(e,r){return {event:e,latencyMs:r,ok:true}}var pe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return a(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return a(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;return I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4),g(new e(r))}catch(t){return w(t)?a(t):a(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:le;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4);let u=r.maxRetries??3,m=r.retryDelayMs??1e3,d=new q(o,u,m,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),c={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new K(d,s,c),this.onboarding=new B(this.apiClient),this.crossDeviceManager=new V(this.apiClient),this.eventEmitter=new W,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Ee(r.telemetryEndpoint??ve));}static isSupported(){return S()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await he(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await be(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(g({valid:true,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Re()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.4.1"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var de=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
1
+ 'use strict';var g=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var D=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);}},ke={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new D(e,r??ke[e],t)}function w(e){return e instanceof D||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function N(){return R("NOT_SUPPORTED")}function Pe(){return R("USER_CANCELLED")}function De(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Me(){return R("TIMEOUT")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function H(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function $(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw w(t)?t:b(r,"must be a valid URL")}}function I(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function U(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var we={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function f(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=we[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"}function T(e){return typeof e=="number"&&Number.isFinite(e)}function F(e){return typeof e=="boolean"}function C(e){return Array.isArray(e)}function i(e,r){return a(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function p(e,r){return e[r]}function X(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"rp");if(!y(n)||!l(n.name)||!l(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=p(t,"user");if(!y(s)||!l(s.id)||!l(s.name)||!l(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=p(t,"challenge");if(!l(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let u=p(t,"pubKeyCredParams");if(!C(u))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let c of u)if(!y(c)||c.type!=="public-key"||!T(c.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let m=t.timeout;if(m!==void 0&&!T(m))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let d=t.excludeCredentials;if(d!==void 0){if(!C(d))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let c of d)if(!y(c)||c.type!=="public-key"||!l(c.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):g({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:u,...m!==void 0&&{timeout:m},...d!==void 0&&{excludeCredentials:d},...h!==void 0&&{authenticatorSelection:h}}})}function Y(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"challenge"),s=p(t,"rpId"),o=t.allowCredentials;if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!l(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!C(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let d of o)if(!y(d)||d.type!=="public-key"||!l(d.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let u=t.timeout;if(u!==void 0&&!T(u))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let m=t.userVerification;return m!==void 0&&!["required","preferred","discouraged"].includes(String(m))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):g({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...u!==void 0&&{timeout:u},...m!==void 0&&{userVerification:m}}})}function G(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"credential_id"),t=p(e,"status"),n=p(e,"session_token"),s=p(e,"user");if(!l(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!l(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(s,"user_id"),u=p(s,"external_user_id");if(!l(o)||!l(u))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let m=s.email,d=s.metadata;return m!==void 0&&!l(m)?i("Invalid API response: user.email must be string",{originalData:e}):d!==void 0&&(typeof d!="object"||d===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):g({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:u,...m!==void 0&&{email:m},...d!==void 0&&{metadata:d}}})}function z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"authenticated"),t=p(e,"session_token"),n=p(e,"user"),s=p(e,"signals");if(!F(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!l(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(n,"user_id"),u=p(n,"external_user_id");return !l(o)||!l(u)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?i("Invalid API response: signals must be object",{originalData:e}):g({authenticated:r,session_token:t,user:{user_id:o,external_user_id:u,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function J(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"valid"),t=p(e,"user_id"),n=p(e,"external_user_id"),s=p(e,"tenant_id"),o=p(e,"app_id");return F(r)?l(t)?l(n)?l(s)?l(o)?g({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function Z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"sessionToken");return l(r)?g({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Ne=["pending_passkey","pending_data","completed"],Ue=["pending_data","completed"];function Q(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return l(r)?l(t)?T(n)?g({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function ee(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"status"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return !l(r)||!Ne.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):l(t)?T(n)?g({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function re(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"onboarding_url");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let u=Fe(s);if(!u.ok)return u;o=u.value;}return g({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Fe(e){if(!y(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=p(e,"rp"),t=p(e,"user"),n=p(e,"challenge"),s=p(e,"pubKeyCredParams");if(!y(r)||!l(r.name)||!l(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!l(t.id)||!l(t.name)||!l(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!C(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!y(o)||o.type!=="public-key"||!T(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return g({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function te(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id");return l(r)?!l(t)||!Ue.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):l(n)?l(s)?g({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function ne(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id"),o=p(e,"session_token");return l(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!l(n)||!l(s)||!l(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):g({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function Le(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 Ke(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function L(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !l(r)||!l(t)||!l(n)?i("Invalid API response: missing required fields",{originalData:e}):g({session_id:r,qr_url:t,expires_at:n})}function se(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !l(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):g({status:r,user_id:e.user_id,session_token:e.session_token})}function ie(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?Le(n)?g({type:"registration",options:n}):i("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):Ke(n)?g({type:"auth",options:n}):i("Invalid API response: auth options must have challenge and rpId",{originalData:e}):i("Invalid API response: options are required",{originalData:e})}var K=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){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):a(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):a(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,X)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,Y)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,G)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,z)}async validateSession(r){return this.get("/v1/sessions/validate",J,{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?g(void 0):a(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},Z)}async startOnboarding(r){return this.post("/onboarding/start",r,Q)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,ee)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,re)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,te)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,ne)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},L)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},L)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,se)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ie)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}};var qe=3e4;function je(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ye(e,r){let t=r*Math.pow(2,e);return Math.min(t,qe)}function Be(e,r){return e!=="GET"?false:r>=500||r===429}var q=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=je(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let u;for(let m=0;m<=this.maxRetries;m++)try{let d=new AbortController,h=setTimeout(()=>d.abort(),this.timeoutMs);try{let c=await fetch(r,{...t,headers:o,signal:d.signal});if(!c.ok){let O;try{O=await c.json();}catch{}let P=O,ce=P?.message??c.statusText,_=P?.error,ge=R(_==="challenge_mismatch"?"CHALLENGE_MISMATCH":_??"NETWORK_FAILURE",ce,{requestId:s,status:c.status,statusText:c.statusText,data:O});if(Be(n,c.status)&&m<this.maxRetries){u=ge,await new Promise(xe=>setTimeout(xe,ye(m,this.retryDelayMs)));continue}return a(ge)}let v=await c.json();return g(v)}finally{clearTimeout(h);}}catch(d){if(u=d,n==="GET"&&m<this.maxRetries)await new Promise(c=>setTimeout(c,ye(m,this.retryDelayMs)));else break}return u instanceof Error&&u.name==="AbortError"?a(R("TIMEOUT","Request timed out",{requestId:s})):a(R("NETWORK_FAILURE",u instanceof Error?u.message:"Request failed",{requestId:s,cause:u}))}};function S(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function Ve(){try{return !S()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Re(){let e=S(),r=await Ve();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function E(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw H("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function We(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw H("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function x(e){let r=We(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function A(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw me(r)}function fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:E(e.rawId),response:{clientDataJSON:E(t),attestationObject:E(n)},type:"public-key"}}function j(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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,o=r.userHandle;return {id:e.id,rawId:E(e.rawId),response:{authenticatorData:E(n),clientDataJSON:E(t),signature:E(s),...o&&{userHandle:E(o)}},type:"public-key"}}function M(e,r){try{U(e.challenge,"challenge"),U(e.user.id,"user.id");let t=x(e.challenge),n=x(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={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(u=>({id:x(u.id),type:u.type,...u.transports&&{transports:u.transports}}))}};return g({publicKey:o})}catch(t){return a(f(t))}}function oe(e,r){try{U(e.challenge,"challenge");let t=x(e.challenge);return g({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:x(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(f(t))}}async function he(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=M(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.create(u);if(!m){let c=b("credential","creation failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishRegister({session_id:s.value.session_id,credential:k(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={success:true,credentialId:d.value.credential_id,credential_id:d.value.credential_id,status:d.value.status,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}async function be(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=oe(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.get(u);if(!m){let c=b("credential","retrieval failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishAuthentication({session_id:s.value.session_id,credential:j(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={authenticated:d.value.authenticated,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata},signals:d.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}var He=2e3,$e=60,B=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return a(t.error);let{session_id:n}=t.value;for(let s=0;s<$e;s++){await new Promise(d=>setTimeout(d,He));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return a(o.error);let u=o.value.status,m=o.value.onboarding_url;if(u==="pending_passkey"){let d=await this.apiClient.getOnboardingRegister(n);if(!d.ok)return a(d.error);let h=d.value;if(!h.challenge)return a(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:m}));let c=M(h.challenge);if(!c.ok)return a(c.error);let v;try{v=await navigator.credentials.create(c.value);}catch(_){return a(f(_))}try{A(v,"create");}catch(_){return a(f(_))}let O;try{O=k(v);}catch(_){return a(f(_))}let P=await this.apiClient.registerOnboardingPasskey(n,{credential:O,challenge:h.challenge.challenge});return P.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):a(P.error)}if(u==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return a(R("TIMEOUT","Onboarding timed out"))}};var Xe=2e3,Ye=60,V=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Ye;n++){if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return a(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?a(R("UNKNOWN_ERROR","Missing data in completed session")):g({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let u=setTimeout(()=>{o(null),t?.removeEventListener("abort",m);},Xe),m=()=>{clearTimeout(u),o(null);};t?.addEventListener("abort",m);}),t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"))}return a(R("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=M(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(u){return a(f(u))}try{A(s,"create");}catch(u){return a(f(u))}let o;try{o=k(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:o})}async executeAuthApproval(r,t){let n=oe(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(u){return a(f(u))}try{A(s,"get");}catch(u){return a(f(u))}let o;try{o=j(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var W=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);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var ae="https://api.trymellonauth.com",ve="https://api.trymellonauth.com/v1/telemetry";var le="trymellon_sandbox_session_token_v1";function Ee(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 ue(e,r){return {event:e,latencyMs:r,ok:true}}var pe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return a(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return a(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;return I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4),g(new e(r))}catch(t){return w(t)?a(t):a(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:le;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4);let u=r.maxRetries??3,m=r.retryDelayMs??1e3,d=new q(o,u,m,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),c={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new K(d,s,c),this.onboarding=new B(this.apiClient),this.crossDeviceManager=new V(this.apiClient),this.eventEmitter=new W,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Ee(r.telemetryEndpoint??ve));}static isSupported(){return S()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await he(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await be(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(g({valid:true,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Re()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.4.3"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var de=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
2
2
  exports.ConsoleLogger=de;exports.SANDBOX_SESSION_TOKEN=le;exports.TryMellon=pe;exports.TryMellonError=D;exports.createError=R;exports.createInvalidArgumentError=b;exports.createNetworkError=De;exports.createNotSupportedError=N;exports.createTimeoutError=Me;exports.createUserCancelledError=Pe;exports.err=a;exports.isTryMellonError=w;exports.mapWebAuthnError=f;exports.ok=g;//# sourceMappingURL=index.cjs.map
3
3
  //# sourceMappingURL=index.cjs.map
@@ -1,3 +1,3 @@
1
- var TryMellon=(function(exports){'use strict';var g=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var D=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);}},ke={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new D(e,r??ke[e],t)}function w(e){return e instanceof D||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function N(){return R("NOT_SUPPORTED")}function Pe(){return R("USER_CANCELLED")}function De(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Me(){return R("TIMEOUT")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function H(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function $(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw w(t)?t:b(r,"must be a valid URL")}}function I(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function U(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var we={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function f(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=we[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"}function T(e){return typeof e=="number"&&Number.isFinite(e)}function F(e){return typeof e=="boolean"}function C(e){return Array.isArray(e)}function i(e,r){return a(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function p(e,r){return e[r]}function X(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"rp");if(!y(n)||!l(n.name)||!l(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=p(t,"user");if(!y(s)||!l(s.id)||!l(s.name)||!l(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=p(t,"challenge");if(!l(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let u=p(t,"pubKeyCredParams");if(!C(u))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let c of u)if(!y(c)||c.type!=="public-key"||!T(c.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let m=t.timeout;if(m!==void 0&&!T(m))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let d=t.excludeCredentials;if(d!==void 0){if(!C(d))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let c of d)if(!y(c)||c.type!=="public-key"||!l(c.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):g({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:u,...m!==void 0&&{timeout:m},...d!==void 0&&{excludeCredentials:d},...h!==void 0&&{authenticatorSelection:h}}})}function Y(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"challenge"),s=p(t,"rpId"),o=t.allowCredentials;if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!l(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!C(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let d of o)if(!y(d)||d.type!=="public-key"||!l(d.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let u=t.timeout;if(u!==void 0&&!T(u))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let m=t.userVerification;return m!==void 0&&!["required","preferred","discouraged"].includes(String(m))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):g({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...u!==void 0&&{timeout:u},...m!==void 0&&{userVerification:m}}})}function G(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"credential_id"),t=p(e,"status"),n=p(e,"session_token"),s=p(e,"user");if(!l(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!l(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(s,"user_id"),u=p(s,"external_user_id");if(!l(o)||!l(u))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let m=s.email,d=s.metadata;return m!==void 0&&!l(m)?i("Invalid API response: user.email must be string",{originalData:e}):d!==void 0&&(typeof d!="object"||d===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):g({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:u,...m!==void 0&&{email:m},...d!==void 0&&{metadata:d}}})}function z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"authenticated"),t=p(e,"session_token"),n=p(e,"user"),s=p(e,"signals");if(!F(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!l(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(n,"user_id"),u=p(n,"external_user_id");return !l(o)||!l(u)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?i("Invalid API response: signals must be object",{originalData:e}):g({authenticated:r,session_token:t,user:{user_id:o,external_user_id:u,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function J(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"valid"),t=p(e,"user_id"),n=p(e,"external_user_id"),s=p(e,"tenant_id"),o=p(e,"app_id");return F(r)?l(t)?l(n)?l(s)?l(o)?g({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function Z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"sessionToken");return l(r)?g({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Ne=["pending_passkey","pending_data","completed"],Ue=["pending_data","completed"];function Q(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return l(r)?l(t)?T(n)?g({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function ee(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"status"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return !l(r)||!Ne.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):l(t)?T(n)?g({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function re(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"onboarding_url");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let u=Fe(s);if(!u.ok)return u;o=u.value;}return g({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Fe(e){if(!y(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=p(e,"rp"),t=p(e,"user"),n=p(e,"challenge"),s=p(e,"pubKeyCredParams");if(!y(r)||!l(r.name)||!l(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!l(t.id)||!l(t.name)||!l(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!C(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!y(o)||o.type!=="public-key"||!T(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return g({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function te(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id");return l(r)?!l(t)||!Ue.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):l(n)?l(s)?g({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function ne(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id"),o=p(e,"session_token");return l(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!l(n)||!l(s)||!l(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):g({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function Le(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 Ke(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function L(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !l(r)||!l(t)||!l(n)?i("Invalid API response: missing required fields",{originalData:e}):g({session_id:r,qr_url:t,expires_at:n})}function se(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !l(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):g({status:r,user_id:e.user_id,session_token:e.session_token})}function ie(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?Le(n)?g({type:"registration",options:n}):i("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):Ke(n)?g({type:"auth",options:n}):i("Invalid API response: auth options must have challenge and rpId",{originalData:e}):i("Invalid API response: options are required",{originalData:e})}var K=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){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):a(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):a(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,X)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,Y)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,G)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,z)}async validateSession(r){return this.get("/v1/sessions/validate",J,{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?g(void 0):a(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},Z)}async startOnboarding(r){return this.post("/onboarding/start",r,Q)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,ee)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,re)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,te)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,ne)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},L)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},L)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,se)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ie)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}};var qe=3e4;function je(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ye(e,r){let t=r*Math.pow(2,e);return Math.min(t,qe)}function Be(e,r){return e!=="GET"?false:r>=500||r===429}var q=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=je(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let u;for(let m=0;m<=this.maxRetries;m++)try{let d=new AbortController,h=setTimeout(()=>d.abort(),this.timeoutMs);try{let c=await fetch(r,{...t,headers:o,signal:d.signal});if(!c.ok){let O;try{O=await c.json();}catch{}let P=O,ce=P?.message??c.statusText,_=P?.error,ge=R(_==="challenge_mismatch"?"CHALLENGE_MISMATCH":_??"NETWORK_FAILURE",ce,{requestId:s,status:c.status,statusText:c.statusText,data:O});if(Be(n,c.status)&&m<this.maxRetries){u=ge,await new Promise(xe=>setTimeout(xe,ye(m,this.retryDelayMs)));continue}return a(ge)}let v=await c.json();return g(v)}finally{clearTimeout(h);}}catch(d){if(u=d,n==="GET"&&m<this.maxRetries)await new Promise(c=>setTimeout(c,ye(m,this.retryDelayMs)));else break}return u instanceof Error&&u.name==="AbortError"?a(R("TIMEOUT","Request timed out",{requestId:s})):a(R("NETWORK_FAILURE",u instanceof Error?u.message:"Request failed",{requestId:s,cause:u}))}};function S(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function Ve(){try{return !S()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Re(){let e=S(),r=await Ve();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function E(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw H("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function We(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw H("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function x(e){let r=We(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function A(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw me(r)}function fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:E(e.rawId),response:{clientDataJSON:E(t),attestationObject:E(n)},type:"public-key"}}function j(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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,o=r.userHandle;return {id:e.id,rawId:E(e.rawId),response:{authenticatorData:E(n),clientDataJSON:E(t),signature:E(s),...o&&{userHandle:E(o)}},type:"public-key"}}function M(e,r){try{U(e.challenge,"challenge"),U(e.user.id,"user.id");let t=x(e.challenge),n=x(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={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(u=>({id:x(u.id),type:u.type,...u.transports&&{transports:u.transports}}))}};return g({publicKey:o})}catch(t){return a(f(t))}}function oe(e,r){try{U(e.challenge,"challenge");let t=x(e.challenge);return g({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:x(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(f(t))}}async function he(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=M(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.create(u);if(!m){let c=b("credential","creation failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishRegister({session_id:s.value.session_id,credential:k(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={success:true,credentialId:d.value.credential_id,credential_id:d.value.credential_id,status:d.value.status,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}async function be(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=oe(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.get(u);if(!m){let c=b("credential","retrieval failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishAuthentication({session_id:s.value.session_id,credential:j(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={authenticated:d.value.authenticated,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata},signals:d.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}var He=2e3,$e=60,B=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return a(t.error);let{session_id:n}=t.value;for(let s=0;s<$e;s++){await new Promise(d=>setTimeout(d,He));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return a(o.error);let u=o.value.status,m=o.value.onboarding_url;if(u==="pending_passkey"){let d=await this.apiClient.getOnboardingRegister(n);if(!d.ok)return a(d.error);let h=d.value;if(!h.challenge)return a(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:m}));let c=M(h.challenge);if(!c.ok)return a(c.error);let v;try{v=await navigator.credentials.create(c.value);}catch(_){return a(f(_))}try{A(v,"create");}catch(_){return a(f(_))}let O;try{O=k(v);}catch(_){return a(f(_))}let P=await this.apiClient.registerOnboardingPasskey(n,{credential:O,challenge:h.challenge.challenge});return P.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):a(P.error)}if(u==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return a(R("TIMEOUT","Onboarding timed out"))}};var Xe=2e3,Ye=60,V=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Ye;n++){if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return a(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?a(R("UNKNOWN_ERROR","Missing data in completed session")):g({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let u=setTimeout(()=>{o(null),t?.removeEventListener("abort",m);},Xe),m=()=>{clearTimeout(u),o(null);};t?.addEventListener("abort",m);}),t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"))}return a(R("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=M(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(u){return a(f(u))}try{A(s,"create");}catch(u){return a(f(u))}let o;try{o=k(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:o})}async executeAuthApproval(r,t){let n=oe(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(u){return a(f(u))}try{A(s,"get");}catch(u){return a(f(u))}let o;try{o=j(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var W=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);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var ae="https://api.trymellonauth.com",ve="https://api.trymellonauth.com/v1/telemetry";var le="trymellon_sandbox_session_token_v1";function Ee(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 ue(e,r){return {event:e,latencyMs:r,ok:true}}var pe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return a(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return a(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;return I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4),g(new e(r))}catch(t){return w(t)?a(t):a(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:le;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4);let u=r.maxRetries??3,m=r.retryDelayMs??1e3,d=new q(o,u,m,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),c={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new K(d,s,c),this.onboarding=new B(this.apiClient),this.crossDeviceManager=new V(this.apiClient),this.eventEmitter=new W,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Ee(r.telemetryEndpoint??ve));}static isSupported(){return S()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await he(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await be(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(g({valid:true,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Re()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.4.1"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var de=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
1
+ var TryMellon=(function(exports){'use strict';var g=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var D=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);}},ke={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new D(e,r??ke[e],t)}function w(e){return e instanceof D||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function N(){return R("NOT_SUPPORTED")}function Pe(){return R("USER_CANCELLED")}function De(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Me(){return R("TIMEOUT")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function H(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function $(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw w(t)?t:b(r,"must be a valid URL")}}function I(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function U(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var we={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function f(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=we[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"}function T(e){return typeof e=="number"&&Number.isFinite(e)}function F(e){return typeof e=="boolean"}function C(e){return Array.isArray(e)}function i(e,r){return a(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function p(e,r){return e[r]}function X(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"rp");if(!y(n)||!l(n.name)||!l(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=p(t,"user");if(!y(s)||!l(s.id)||!l(s.name)||!l(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=p(t,"challenge");if(!l(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let u=p(t,"pubKeyCredParams");if(!C(u))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let c of u)if(!y(c)||c.type!=="public-key"||!T(c.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let m=t.timeout;if(m!==void 0&&!T(m))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let d=t.excludeCredentials;if(d!==void 0){if(!C(d))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let c of d)if(!y(c)||c.type!=="public-key"||!l(c.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):g({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:u,...m!==void 0&&{timeout:m},...d!==void 0&&{excludeCredentials:d},...h!==void 0&&{authenticatorSelection:h}}})}function Y(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"challenge"),s=p(t,"rpId"),o=t.allowCredentials;if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!l(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!C(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let d of o)if(!y(d)||d.type!=="public-key"||!l(d.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let u=t.timeout;if(u!==void 0&&!T(u))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let m=t.userVerification;return m!==void 0&&!["required","preferred","discouraged"].includes(String(m))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):g({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...u!==void 0&&{timeout:u},...m!==void 0&&{userVerification:m}}})}function G(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"credential_id"),t=p(e,"status"),n=p(e,"session_token"),s=p(e,"user");if(!l(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!l(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(s,"user_id"),u=p(s,"external_user_id");if(!l(o)||!l(u))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let m=s.email,d=s.metadata;return m!==void 0&&!l(m)?i("Invalid API response: user.email must be string",{originalData:e}):d!==void 0&&(typeof d!="object"||d===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):g({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:u,...m!==void 0&&{email:m},...d!==void 0&&{metadata:d}}})}function z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"authenticated"),t=p(e,"session_token"),n=p(e,"user"),s=p(e,"signals");if(!F(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!l(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(n,"user_id"),u=p(n,"external_user_id");return !l(o)||!l(u)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?i("Invalid API response: signals must be object",{originalData:e}):g({authenticated:r,session_token:t,user:{user_id:o,external_user_id:u,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function J(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"valid"),t=p(e,"user_id"),n=p(e,"external_user_id"),s=p(e,"tenant_id"),o=p(e,"app_id");return F(r)?l(t)?l(n)?l(s)?l(o)?g({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function Z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"sessionToken");return l(r)?g({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Ne=["pending_passkey","pending_data","completed"],Ue=["pending_data","completed"];function Q(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return l(r)?l(t)?T(n)?g({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function ee(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"status"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return !l(r)||!Ne.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):l(t)?T(n)?g({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function re(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"onboarding_url");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let u=Fe(s);if(!u.ok)return u;o=u.value;}return g({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Fe(e){if(!y(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=p(e,"rp"),t=p(e,"user"),n=p(e,"challenge"),s=p(e,"pubKeyCredParams");if(!y(r)||!l(r.name)||!l(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!l(t.id)||!l(t.name)||!l(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!C(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!y(o)||o.type!=="public-key"||!T(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return g({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function te(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id");return l(r)?!l(t)||!Ue.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):l(n)?l(s)?g({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function ne(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id"),o=p(e,"session_token");return l(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!l(n)||!l(s)||!l(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):g({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function Le(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 Ke(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function L(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !l(r)||!l(t)||!l(n)?i("Invalid API response: missing required fields",{originalData:e}):g({session_id:r,qr_url:t,expires_at:n})}function se(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !l(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):g({status:r,user_id:e.user_id,session_token:e.session_token})}function ie(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?Le(n)?g({type:"registration",options:n}):i("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):Ke(n)?g({type:"auth",options:n}):i("Invalid API response: auth options must have challenge and rpId",{originalData:e}):i("Invalid API response: options are required",{originalData:e})}var K=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){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):a(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):a(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,X)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,Y)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,G)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,z)}async validateSession(r){return this.get("/v1/sessions/validate",J,{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?g(void 0):a(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},Z)}async startOnboarding(r){return this.post("/onboarding/start",r,Q)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,ee)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,re)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,te)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,ne)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},L)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},L)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,se)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ie)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}};var qe=3e4;function je(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ye(e,r){let t=r*Math.pow(2,e);return Math.min(t,qe)}function Be(e,r){return e!=="GET"?false:r>=500||r===429}var q=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=je(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let u;for(let m=0;m<=this.maxRetries;m++)try{let d=new AbortController,h=setTimeout(()=>d.abort(),this.timeoutMs);try{let c=await fetch(r,{...t,headers:o,signal:d.signal});if(!c.ok){let O;try{O=await c.json();}catch{}let P=O,ce=P?.message??c.statusText,_=P?.error,ge=R(_==="challenge_mismatch"?"CHALLENGE_MISMATCH":_??"NETWORK_FAILURE",ce,{requestId:s,status:c.status,statusText:c.statusText,data:O});if(Be(n,c.status)&&m<this.maxRetries){u=ge,await new Promise(xe=>setTimeout(xe,ye(m,this.retryDelayMs)));continue}return a(ge)}let v=await c.json();return g(v)}finally{clearTimeout(h);}}catch(d){if(u=d,n==="GET"&&m<this.maxRetries)await new Promise(c=>setTimeout(c,ye(m,this.retryDelayMs)));else break}return u instanceof Error&&u.name==="AbortError"?a(R("TIMEOUT","Request timed out",{requestId:s})):a(R("NETWORK_FAILURE",u instanceof Error?u.message:"Request failed",{requestId:s,cause:u}))}};function S(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function Ve(){try{return !S()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Re(){let e=S(),r=await Ve();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function E(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw H("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function We(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw H("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function x(e){let r=We(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function A(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw me(r)}function fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:E(e.rawId),response:{clientDataJSON:E(t),attestationObject:E(n)},type:"public-key"}}function j(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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,o=r.userHandle;return {id:e.id,rawId:E(e.rawId),response:{authenticatorData:E(n),clientDataJSON:E(t),signature:E(s),...o&&{userHandle:E(o)}},type:"public-key"}}function M(e,r){try{U(e.challenge,"challenge"),U(e.user.id,"user.id");let t=x(e.challenge),n=x(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={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(u=>({id:x(u.id),type:u.type,...u.transports&&{transports:u.transports}}))}};return g({publicKey:o})}catch(t){return a(f(t))}}function oe(e,r){try{U(e.challenge,"challenge");let t=x(e.challenge);return g({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:x(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(f(t))}}async function he(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=M(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.create(u);if(!m){let c=b("credential","creation failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishRegister({session_id:s.value.session_id,credential:k(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={success:true,credentialId:d.value.credential_id,credential_id:d.value.credential_id,status:d.value.status,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}async function be(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=oe(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.get(u);if(!m){let c=b("credential","retrieval failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishAuthentication({session_id:s.value.session_id,credential:j(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={authenticated:d.value.authenticated,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata},signals:d.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}var He=2e3,$e=60,B=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return a(t.error);let{session_id:n}=t.value;for(let s=0;s<$e;s++){await new Promise(d=>setTimeout(d,He));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return a(o.error);let u=o.value.status,m=o.value.onboarding_url;if(u==="pending_passkey"){let d=await this.apiClient.getOnboardingRegister(n);if(!d.ok)return a(d.error);let h=d.value;if(!h.challenge)return a(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:m}));let c=M(h.challenge);if(!c.ok)return a(c.error);let v;try{v=await navigator.credentials.create(c.value);}catch(_){return a(f(_))}try{A(v,"create");}catch(_){return a(f(_))}let O;try{O=k(v);}catch(_){return a(f(_))}let P=await this.apiClient.registerOnboardingPasskey(n,{credential:O,challenge:h.challenge.challenge});return P.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):a(P.error)}if(u==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return a(R("TIMEOUT","Onboarding timed out"))}};var Xe=2e3,Ye=60,V=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Ye;n++){if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return a(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?a(R("UNKNOWN_ERROR","Missing data in completed session")):g({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let u=setTimeout(()=>{o(null),t?.removeEventListener("abort",m);},Xe),m=()=>{clearTimeout(u),o(null);};t?.addEventListener("abort",m);}),t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"))}return a(R("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=M(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(u){return a(f(u))}try{A(s,"create");}catch(u){return a(f(u))}let o;try{o=k(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:o})}async executeAuthApproval(r,t){let n=oe(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(u){return a(f(u))}try{A(s,"get");}catch(u){return a(f(u))}let o;try{o=j(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var W=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);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var ae="https://api.trymellonauth.com",ve="https://api.trymellonauth.com/v1/telemetry";var le="trymellon_sandbox_session_token_v1";function Ee(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 ue(e,r){return {event:e,latencyMs:r,ok:true}}var pe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return a(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return a(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;return I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4),g(new e(r))}catch(t){return w(t)?a(t):a(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:le;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4);let u=r.maxRetries??3,m=r.retryDelayMs??1e3,d=new q(o,u,m,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),c={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new K(d,s,c),this.onboarding=new B(this.apiClient),this.crossDeviceManager=new V(this.apiClient),this.eventEmitter=new W,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Ee(r.telemetryEndpoint??ve));}static isSupported(){return S()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await he(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await be(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(g({valid:true,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Re()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.4.3"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var de=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
2
2
  exports.ConsoleLogger=de;exports.SANDBOX_SESSION_TOKEN=le;exports.TryMellon=pe;exports.TryMellonError=D;exports.createError=R;exports.createInvalidArgumentError=b;exports.createNetworkError=De;exports.createNotSupportedError=N;exports.createTimeoutError=Me;exports.createUserCancelledError=Pe;exports.err=a;exports.isTryMellonError=w;exports.mapWebAuthnError=f;exports.ok=g;return exports;})({});//# sourceMappingURL=index.global.js.map
3
3
  //# sourceMappingURL=index.global.js.map
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- var g=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var D=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);}},ke={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new D(e,r??ke[e],t)}function w(e){return e instanceof D||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function N(){return R("NOT_SUPPORTED")}function Pe(){return R("USER_CANCELLED")}function De(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Me(){return R("TIMEOUT")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function H(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function $(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw w(t)?t:b(r,"must be a valid URL")}}function I(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function U(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var we={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function f(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=we[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"}function T(e){return typeof e=="number"&&Number.isFinite(e)}function F(e){return typeof e=="boolean"}function C(e){return Array.isArray(e)}function i(e,r){return a(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function p(e,r){return e[r]}function X(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"rp");if(!y(n)||!l(n.name)||!l(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=p(t,"user");if(!y(s)||!l(s.id)||!l(s.name)||!l(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=p(t,"challenge");if(!l(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let u=p(t,"pubKeyCredParams");if(!C(u))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let c of u)if(!y(c)||c.type!=="public-key"||!T(c.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let m=t.timeout;if(m!==void 0&&!T(m))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let d=t.excludeCredentials;if(d!==void 0){if(!C(d))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let c of d)if(!y(c)||c.type!=="public-key"||!l(c.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):g({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:u,...m!==void 0&&{timeout:m},...d!==void 0&&{excludeCredentials:d},...h!==void 0&&{authenticatorSelection:h}}})}function Y(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"challenge"),s=p(t,"rpId"),o=t.allowCredentials;if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!l(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!C(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let d of o)if(!y(d)||d.type!=="public-key"||!l(d.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let u=t.timeout;if(u!==void 0&&!T(u))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let m=t.userVerification;return m!==void 0&&!["required","preferred","discouraged"].includes(String(m))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):g({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...u!==void 0&&{timeout:u},...m!==void 0&&{userVerification:m}}})}function G(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"credential_id"),t=p(e,"status"),n=p(e,"session_token"),s=p(e,"user");if(!l(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!l(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(s,"user_id"),u=p(s,"external_user_id");if(!l(o)||!l(u))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let m=s.email,d=s.metadata;return m!==void 0&&!l(m)?i("Invalid API response: user.email must be string",{originalData:e}):d!==void 0&&(typeof d!="object"||d===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):g({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:u,...m!==void 0&&{email:m},...d!==void 0&&{metadata:d}}})}function z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"authenticated"),t=p(e,"session_token"),n=p(e,"user"),s=p(e,"signals");if(!F(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!l(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(n,"user_id"),u=p(n,"external_user_id");return !l(o)||!l(u)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?i("Invalid API response: signals must be object",{originalData:e}):g({authenticated:r,session_token:t,user:{user_id:o,external_user_id:u,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function J(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"valid"),t=p(e,"user_id"),n=p(e,"external_user_id"),s=p(e,"tenant_id"),o=p(e,"app_id");return F(r)?l(t)?l(n)?l(s)?l(o)?g({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function Z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"sessionToken");return l(r)?g({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Ne=["pending_passkey","pending_data","completed"],Ue=["pending_data","completed"];function Q(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return l(r)?l(t)?T(n)?g({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function ee(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"status"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return !l(r)||!Ne.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):l(t)?T(n)?g({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function re(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"onboarding_url");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let u=Fe(s);if(!u.ok)return u;o=u.value;}return g({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Fe(e){if(!y(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=p(e,"rp"),t=p(e,"user"),n=p(e,"challenge"),s=p(e,"pubKeyCredParams");if(!y(r)||!l(r.name)||!l(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!l(t.id)||!l(t.name)||!l(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!C(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!y(o)||o.type!=="public-key"||!T(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return g({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function te(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id");return l(r)?!l(t)||!Ue.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):l(n)?l(s)?g({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function ne(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id"),o=p(e,"session_token");return l(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!l(n)||!l(s)||!l(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):g({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function Le(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 Ke(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function L(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !l(r)||!l(t)||!l(n)?i("Invalid API response: missing required fields",{originalData:e}):g({session_id:r,qr_url:t,expires_at:n})}function se(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !l(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):g({status:r,user_id:e.user_id,session_token:e.session_token})}function ie(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?Le(n)?g({type:"registration",options:n}):i("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):Ke(n)?g({type:"auth",options:n}):i("Invalid API response: auth options must have challenge and rpId",{originalData:e}):i("Invalid API response: options are required",{originalData:e})}var K=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){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):a(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):a(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,X)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,Y)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,G)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,z)}async validateSession(r){return this.get("/v1/sessions/validate",J,{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?g(void 0):a(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},Z)}async startOnboarding(r){return this.post("/onboarding/start",r,Q)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,ee)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,re)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,te)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,ne)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},L)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},L)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,se)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ie)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}};var qe=3e4;function je(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ye(e,r){let t=r*Math.pow(2,e);return Math.min(t,qe)}function Be(e,r){return e!=="GET"?false:r>=500||r===429}var q=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=je(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let u;for(let m=0;m<=this.maxRetries;m++)try{let d=new AbortController,h=setTimeout(()=>d.abort(),this.timeoutMs);try{let c=await fetch(r,{...t,headers:o,signal:d.signal});if(!c.ok){let O;try{O=await c.json();}catch{}let P=O,ce=P?.message??c.statusText,_=P?.error,ge=R(_==="challenge_mismatch"?"CHALLENGE_MISMATCH":_??"NETWORK_FAILURE",ce,{requestId:s,status:c.status,statusText:c.statusText,data:O});if(Be(n,c.status)&&m<this.maxRetries){u=ge,await new Promise(xe=>setTimeout(xe,ye(m,this.retryDelayMs)));continue}return a(ge)}let v=await c.json();return g(v)}finally{clearTimeout(h);}}catch(d){if(u=d,n==="GET"&&m<this.maxRetries)await new Promise(c=>setTimeout(c,ye(m,this.retryDelayMs)));else break}return u instanceof Error&&u.name==="AbortError"?a(R("TIMEOUT","Request timed out",{requestId:s})):a(R("NETWORK_FAILURE",u instanceof Error?u.message:"Request failed",{requestId:s,cause:u}))}};function S(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function Ve(){try{return !S()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Re(){let e=S(),r=await Ve();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function E(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw H("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function We(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw H("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function x(e){let r=We(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function A(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw me(r)}function fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:E(e.rawId),response:{clientDataJSON:E(t),attestationObject:E(n)},type:"public-key"}}function j(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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,o=r.userHandle;return {id:e.id,rawId:E(e.rawId),response:{authenticatorData:E(n),clientDataJSON:E(t),signature:E(s),...o&&{userHandle:E(o)}},type:"public-key"}}function M(e,r){try{U(e.challenge,"challenge"),U(e.user.id,"user.id");let t=x(e.challenge),n=x(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={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(u=>({id:x(u.id),type:u.type,...u.transports&&{transports:u.transports}}))}};return g({publicKey:o})}catch(t){return a(f(t))}}function oe(e,r){try{U(e.challenge,"challenge");let t=x(e.challenge);return g({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:x(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(f(t))}}async function he(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=M(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.create(u);if(!m){let c=b("credential","creation failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishRegister({session_id:s.value.session_id,credential:k(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={success:true,credentialId:d.value.credential_id,credential_id:d.value.credential_id,status:d.value.status,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}async function be(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=oe(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.get(u);if(!m){let c=b("credential","retrieval failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishAuthentication({session_id:s.value.session_id,credential:j(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={authenticated:d.value.authenticated,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata},signals:d.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}var He=2e3,$e=60,B=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return a(t.error);let{session_id:n}=t.value;for(let s=0;s<$e;s++){await new Promise(d=>setTimeout(d,He));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return a(o.error);let u=o.value.status,m=o.value.onboarding_url;if(u==="pending_passkey"){let d=await this.apiClient.getOnboardingRegister(n);if(!d.ok)return a(d.error);let h=d.value;if(!h.challenge)return a(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:m}));let c=M(h.challenge);if(!c.ok)return a(c.error);let v;try{v=await navigator.credentials.create(c.value);}catch(_){return a(f(_))}try{A(v,"create");}catch(_){return a(f(_))}let O;try{O=k(v);}catch(_){return a(f(_))}let P=await this.apiClient.registerOnboardingPasskey(n,{credential:O,challenge:h.challenge.challenge});return P.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):a(P.error)}if(u==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return a(R("TIMEOUT","Onboarding timed out"))}};var Xe=2e3,Ye=60,V=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Ye;n++){if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return a(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?a(R("UNKNOWN_ERROR","Missing data in completed session")):g({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let u=setTimeout(()=>{o(null),t?.removeEventListener("abort",m);},Xe),m=()=>{clearTimeout(u),o(null);};t?.addEventListener("abort",m);}),t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"))}return a(R("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=M(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(u){return a(f(u))}try{A(s,"create");}catch(u){return a(f(u))}let o;try{o=k(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:o})}async executeAuthApproval(r,t){let n=oe(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(u){return a(f(u))}try{A(s,"get");}catch(u){return a(f(u))}let o;try{o=j(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var W=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);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var ae="https://api.trymellonauth.com",ve="https://api.trymellonauth.com/v1/telemetry";var le="trymellon_sandbox_session_token_v1";function Ee(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 ue(e,r){return {event:e,latencyMs:r,ok:true}}var pe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return a(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return a(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;return I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4),g(new e(r))}catch(t){return w(t)?a(t):a(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:le;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4);let u=r.maxRetries??3,m=r.retryDelayMs??1e3,d=new q(o,u,m,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),c={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new K(d,s,c),this.onboarding=new B(this.apiClient),this.crossDeviceManager=new V(this.apiClient),this.eventEmitter=new W,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Ee(r.telemetryEndpoint??ve));}static isSupported(){return S()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await he(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await be(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(g({valid:true,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Re()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.4.1"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var de=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
1
+ var g=e=>({ok:true,value:e}),a=e=>({ok:false,error:e});var D=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);}},ke={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.",UNKNOWN_ERROR:"An unknown error occurred"};function R(e,r,t){return new D(e,r??ke[e],t)}function w(e){return e instanceof D||typeof e=="object"&&e!==null&&"isTryMellonError"in e&&e.isTryMellonError===true}function N(){return R("NOT_SUPPORTED")}function Pe(){return R("USER_CANCELLED")}function De(e){return R("NETWORK_FAILURE",void 0,{cause:e?.message,originalError:e})}function Me(){return R("TIMEOUT")}function b(e,r){return R("INVALID_ARGUMENT",`Invalid argument: ${e} - ${r}`,{field:e,reason:r})}function me(e){return R("UNKNOWN_ERROR",`Failed to ${e} credential`,{operation:e})}function H(e){return R("NOT_SUPPORTED",`No base64 ${e==="encode"?"encoding":"decoding"} available`,{type:e})}function $(e,r){try{let t=new URL(e);if(t.protocol!=="https:"&&t.protocol!=="http:")throw b(r,"must use http or https protocol")}catch(t){throw w(t)?t:b(r,"must be a valid URL")}}function I(e,r,t,n){if(!Number.isFinite(e))throw b(r,"must be a finite number");if(e<t||e>n)throw b(r,`must be between ${t} and ${n}`)}function U(e,r){if(typeof e!="string"||e.length===0)throw b(r,"must be a non-empty string");if(!/^[A-Za-z0-9_-]+$/.test(e))throw b(r,"must be a valid base64url string")}var we={NotAllowedError:"USER_CANCELLED",AbortError:"ABORTED",NotSupportedError:"NOT_SUPPORTED",SecurityError:"NOT_SUPPORTED",InvalidStateError:"UNKNOWN_ERROR",UnknownError:"UNKNOWN_ERROR"};function f(e){if(e instanceof DOMException){let r=e.name,t=e.message||"WebAuthn operation failed",n=we[r]??"UNKNOWN_ERROR";return R(n,t,{originalError:e})}return e instanceof Error?R("UNKNOWN_ERROR",e.message,{originalError:e}):R("UNKNOWN_ERROR","An unknown error occurred",{originalError:e})}function y(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"}function T(e){return typeof e=="number"&&Number.isFinite(e)}function F(e){return typeof e=="boolean"}function C(e){return Array.isArray(e)}function i(e,r){return a(R("UNKNOWN_ERROR",e,{...r,originalData:r?.originalData}))}function p(e,r){return e[r]}function X(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"rp");if(!y(n)||!l(n.name)||!l(n.id))return i("Invalid API response: challenge.rp must have name and id strings",{originalData:e});let s=p(t,"user");if(!y(s)||!l(s.id)||!l(s.name)||!l(s.displayName))return i("Invalid API response: challenge.user must have id, name, displayName strings",{originalData:e});let o=p(t,"challenge");if(!l(o))return i("Invalid API response: challenge.challenge must be string",{originalData:e});let u=p(t,"pubKeyCredParams");if(!C(u))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let c of u)if(!y(c)||c.type!=="public-key"||!T(c.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});let m=t.timeout;if(m!==void 0&&!T(m))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let d=t.excludeCredentials;if(d!==void 0){if(!C(d))return i("Invalid API response: excludeCredentials must be array",{originalData:e});for(let c of d)if(!y(c)||c.type!=="public-key"||!l(c.id))return i("Invalid API response: excludeCredentials items must have id and type",{originalData:e})}let h=t.authenticatorSelection;return h!==void 0&&!y(h)?i("Invalid API response: authenticatorSelection must be object",{originalData:e}):g({session_id:r,challenge:{rp:n,user:s,challenge:o,pubKeyCredParams:u,...m!==void 0&&{timeout:m},...d!==void 0&&{excludeCredentials:d},...h!==void 0&&{authenticatorSelection:h}}})}function Y(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});let t=p(e,"challenge");if(!y(t))return i("Invalid API response: challenge must be object",{field:"challenge",originalData:e});let n=p(t,"challenge"),s=p(t,"rpId"),o=t.allowCredentials;if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!l(s))return i("Invalid API response: challenge.rpId must be string",{originalData:e});if(o!==void 0&&!C(o))return i("Invalid API response: allowCredentials must be array",{originalData:e});if(o){for(let d of o)if(!y(d)||d.type!=="public-key"||!l(d.id))return i("Invalid API response: allowCredentials items must have id and type",{originalData:e})}let u=t.timeout;if(u!==void 0&&!T(u))return i("Invalid API response: challenge.timeout must be number",{originalData:e});let m=t.userVerification;return m!==void 0&&!["required","preferred","discouraged"].includes(String(m))?i("Invalid API response: userVerification must be required|preferred|discouraged",{originalData:e}):g({session_id:r,challenge:{challenge:n,rpId:s,allowCredentials:o??[],...u!==void 0&&{timeout:u},...m!==void 0&&{userVerification:m}}})}function G(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"credential_id"),t=p(e,"status"),n=p(e,"session_token"),s=p(e,"user");if(!l(r))return i("Invalid API response: credential_id must be string",{field:"credential_id",originalData:e});if(!l(t))return i("Invalid API response: status must be string",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(s))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(s,"user_id"),u=p(s,"external_user_id");if(!l(o)||!l(u))return i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e});let m=s.email,d=s.metadata;return m!==void 0&&!l(m)?i("Invalid API response: user.email must be string",{originalData:e}):d!==void 0&&(typeof d!="object"||d===null)?i("Invalid API response: user.metadata must be object",{originalData:e}):g({credential_id:r,status:t,session_token:n,user:{user_id:o,external_user_id:u,...m!==void 0&&{email:m},...d!==void 0&&{metadata:d}}})}function z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"authenticated"),t=p(e,"session_token"),n=p(e,"user"),s=p(e,"signals");if(!F(r))return i("Invalid API response: authenticated must be boolean",{field:"authenticated",originalData:e});if(!l(t))return i("Invalid API response: session_token must be string",{field:"session_token",originalData:e});if(!y(n))return i("Invalid API response: user must be object",{field:"user",originalData:e});let o=p(n,"user_id"),u=p(n,"external_user_id");return !l(o)||!l(u)?i("Invalid API response: user must have user_id and external_user_id strings",{originalData:e}):s!==void 0&&!y(s)?i("Invalid API response: signals must be object",{originalData:e}):g({authenticated:r,session_token:t,user:{user_id:o,external_user_id:u,...n.email!==void 0&&{email:n.email},...n.metadata!==void 0&&{metadata:n.metadata}},signals:s})}function J(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"valid"),t=p(e,"user_id"),n=p(e,"external_user_id"),s=p(e,"tenant_id"),o=p(e,"app_id");return F(r)?l(t)?l(n)?l(s)?l(o)?g({valid:r,user_id:t,external_user_id:n,tenant_id:s,app_id:o}):i("Invalid API response: app_id must be string",{field:"app_id",originalData:e}):i("Invalid API response: tenant_id must be string",{field:"tenant_id",originalData:e}):i("Invalid API response: external_user_id must be string",{field:"external_user_id",originalData:e}):i("Invalid API response: user_id must be string",{field:"user_id",originalData:e}):i("Invalid API response: valid must be boolean",{field:"valid",originalData:e})}function Z(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"sessionToken");return l(r)?g({sessionToken:r}):i("Invalid API response: sessionToken must be string",{field:"sessionToken",originalData:e})}var Ne=["pending_passkey","pending_data","completed"],Ue=["pending_data","completed"];function Q(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return l(r)?l(t)?T(n)?g({session_id:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{field:"expires_in",originalData:e}):i("Invalid API response: onboarding_url must be string",{field:"onboarding_url",originalData:e}):i("Invalid API response: session_id must be string",{field:"session_id",originalData:e})}function ee(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"status"),t=p(e,"onboarding_url"),n=p(e,"expires_in");return !l(r)||!Ne.includes(r)?i("Invalid API response: status must be pending_passkey|pending_data|completed",{field:"status",originalData:e}):l(t)?T(n)?g({status:r,onboarding_url:t,expires_in:n}):i("Invalid API response: expires_in must be number",{originalData:e}):i("Invalid API response: onboarding_url must be string",{originalData:e})}function re(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"onboarding_url");if(!l(r))return i("Invalid API response: session_id must be string",{field:"session_id",originalData:e});if(t!=="pending_passkey")return i("Invalid API response: status must be pending_passkey",{field:"status",originalData:e});if(!l(n))return i("Invalid API response: onboarding_url must be string",{originalData:e});let s=e.challenge,o;if(s!==void 0){let u=Fe(s);if(!u.ok)return u;o=u.value;}return g({session_id:r,status:"pending_passkey",onboarding_url:n,...o!==void 0&&{challenge:o}})}function Fe(e){if(!y(e))return i("Invalid API response: challenge must be object",{originalData:e});let r=p(e,"rp"),t=p(e,"user"),n=p(e,"challenge"),s=p(e,"pubKeyCredParams");if(!y(r)||!l(r.name)||!l(r.id))return i("Invalid API response: challenge.rp must have name and id",{originalData:e});if(!y(t)||!l(t.id)||!l(t.name)||!l(t.displayName))return i("Invalid API response: challenge.user must have id, name, displayName",{originalData:e});if(!l(n))return i("Invalid API response: challenge.challenge must be string",{originalData:e});if(!C(s))return i("Invalid API response: challenge.pubKeyCredParams must be array",{originalData:e});for(let o of s)if(!y(o)||o.type!=="public-key"||!T(o.alg))return i("Invalid API response: pubKeyCredParams items must have type and alg",{originalData:e});return g({rp:r,user:t,challenge:n,pubKeyCredParams:s})}function te(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id");return l(r)?!l(t)||!Ue.includes(t)?i("Invalid API response: status must be pending_data|completed",{originalData:e}):l(n)?l(s)?g({session_id:r,status:t,user_id:n,tenant_id:s}):i("Invalid API response: tenant_id must be string",{originalData:e}):i("Invalid API response: user_id must be string",{originalData:e}):i("Invalid API response: session_id must be string",{originalData:e})}function ne(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=p(e,"session_id"),t=p(e,"status"),n=p(e,"user_id"),s=p(e,"tenant_id"),o=p(e,"session_token");return l(r)?t!=="completed"?i("Invalid API response: status must be completed",{originalData:e}):!l(n)||!l(s)||!l(o)?i("Invalid API response: user_id, tenant_id, session_token must be strings",{originalData:e}):g({session_id:r,status:"completed",user_id:n,tenant_id:s,session_token:o}):i("Invalid API response: session_id must be string",{originalData:e})}function Le(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 Ke(e){if(!e||typeof e!="object")return false;let r=e;return typeof r.challenge=="string"&&typeof r.rpId=="string"}function L(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.session_id,t=e.qr_url,n=e.expires_at;return !l(r)||!l(t)||!l(n)?i("Invalid API response: missing required fields",{originalData:e}):g({session_id:r,qr_url:t,expires_at:n})}function se(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.status;return !l(r)||!["pending","authenticated","completed"].includes(r)?i("Invalid API response: invalid status",{originalData:e}):g({status:r,user_id:e.user_id,session_token:e.session_token})}function ie(e){if(!y(e))return i("Invalid API response: expected object",{originalData:e});let r=e.type,t=r==="registration"?"registration":"auth",n=e.options;return y(n)?t==="registration"?Le(n)?g({type:"registration",options:n}):i("Invalid API response: registration options must have challenge, rp, user, pubKeyCredParams",{originalData:e}):Ke(n)?g({type:"auth",options:n}):i("Invalid API response: auth options must have challenge and rpId",{originalData:e}):i("Invalid API response: options are required",{originalData:e})}var K=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){let s=`${this.baseUrl}${r}`,o=await this.httpClient.post(s,t,this.mergeHeaders());return o.ok?n(o.value):a(o.error)}async get(r,t,n){let s=`${this.baseUrl}${r}`,o=await this.httpClient.get(s,this.mergeHeaders(n));return o.ok?t(o.value):a(o.error)}async startRegister(r){return this.post("/v1/passkeys/register/start",r,X)}async startAuth(r){return this.post("/v1/passkeys/auth/start",r,Y)}async finishRegister(r){return this.post("/v1/passkeys/register/finish",r,G)}async finishAuthentication(r){return this.post("/v1/passkeys/auth/finish",r,z)}async validateSession(r){return this.get("/v1/sessions/validate",J,{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?g(void 0):a(n.error)}async verifyEmailCode(r,t){return this.post("/v1/fallback/email/verify",{userId:r,code:t},Z)}async startOnboarding(r){return this.post("/onboarding/start",r,Q)}async getOnboardingStatus(r){return this.get(`/onboarding/${r}/status`,ee)}async getOnboardingRegister(r){return this.get(`/onboarding/${r}/register`,re)}async registerOnboardingPasskey(r,t){return this.post(`/onboarding/${r}/register-passkey`,t,te)}async completeOnboarding(r,t){return this.post(`/onboarding/${r}/complete`,t,ne)}async initCrossDeviceAuth(){return this.post("/v1/auth/cross-device/init",{},L)}async initCrossDeviceRegistration(r){return this.post("/v1/auth/cross-device/init-registration",{external_user_id:r.externalUserId},L)}async getCrossDeviceStatus(r){return this.get(`/v1/auth/cross-device/status/${r}`,se)}async getCrossDeviceContext(r){return this.get(`/v1/auth/cross-device/context/${r}`,ie)}async verifyCrossDeviceAuth(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}async verifyCrossDeviceRegistration(r){let t=`${this.baseUrl}/v1/auth/cross-device/verify-registration`,n=await this.httpClient.post(t,r,this.mergeHeaders());return n.ok?g(void 0):a(n.error)}};var qe=3e4;function je(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`}function ye(e,r){let t=r*Math.pow(2,e);return Math.min(t,qe)}function Be(e,r){return e!=="GET"?false:r>=500||r===429}var q=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=je(),o=new Headers(t.headers);o.set("X-Request-Id",s),this.logger&&this.logger.debug("request",{requestId:s,url:r,method:n});let u;for(let m=0;m<=this.maxRetries;m++)try{let d=new AbortController,h=setTimeout(()=>d.abort(),this.timeoutMs);try{let c=await fetch(r,{...t,headers:o,signal:d.signal});if(!c.ok){let O;try{O=await c.json();}catch{}let P=O,ce=P?.message??c.statusText,_=P?.error,ge=R(_==="challenge_mismatch"?"CHALLENGE_MISMATCH":_??"NETWORK_FAILURE",ce,{requestId:s,status:c.status,statusText:c.statusText,data:O});if(Be(n,c.status)&&m<this.maxRetries){u=ge,await new Promise(xe=>setTimeout(xe,ye(m,this.retryDelayMs)));continue}return a(ge)}let v=await c.json();return g(v)}finally{clearTimeout(h);}}catch(d){if(u=d,n==="GET"&&m<this.maxRetries)await new Promise(c=>setTimeout(c,ye(m,this.retryDelayMs)));else break}return u instanceof Error&&u.name==="AbortError"?a(R("TIMEOUT","Request timed out",{requestId:s})):a(R("NETWORK_FAILURE",u instanceof Error?u.message:"Request failed",{requestId:s,cause:u}))}};function S(){try{return !(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")}catch{return false}}async function Ve(){try{return !S()||typeof PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable!="function"?false:await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return false}}async function Re(){let e=S(),r=await Ve();return {isPasskeySupported:e,platformAuthenticatorAvailable:r,recommendedFlow:e?"passkey":"fallback"}}function E(e){let r=new Uint8Array(e),t="";for(let s=0;s<r.length;s++)t+=String.fromCharCode(r[s]??0);let n="";if(typeof btoa<"u")n=btoa(t);else if(typeof Buffer<"u")n=Buffer.from(t,"binary").toString("base64");else throw H("encode");return n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function We(e){let r=e.replace(/-/g,"+").replace(/_/g,"/"),t=r.length%4;t!==0&&(r+="=".repeat(4-t));let n="";if(typeof atob<"u")n=atob(r);else if(typeof Buffer<"u")n=Buffer.from(r,"base64").toString("binary");else throw H("decode");let s=new Uint8Array(n.length);for(let o=0;o<n.length;o++)s[o]=n.charCodeAt(o);return s}function x(e){let r=We(e),t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}function A(e,r="create"){if(!e||typeof e!="object"||!("id"in e)||!("rawId"in e)||!("response"in e))throw me(r)}function fe(e){return e!==null&&typeof e=="object"&&"clientDataJSON"in e&&e.clientDataJSON instanceof ArrayBuffer}function k(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("attestationObject"in r))throw R("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:E(e.rawId),response:{clientDataJSON:E(t),attestationObject:E(n)},type:"public-key"}}function j(e){if(!e.response)throw R("UNKNOWN_ERROR","Credential response is missing",{credential:e});let r=e.response;if(!fe(r))throw R("UNKNOWN_ERROR","Invalid credential response structure",{response:r});if(!("authenticatorData"in r)||!("signature"in r))throw R("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,o=r.userHandle;return {id:e.id,rawId:E(e.rawId),response:{authenticatorData:E(n),clientDataJSON:E(t),signature:E(s),...o&&{userHandle:E(o)}},type:"public-key"}}function M(e,r){try{U(e.challenge,"challenge"),U(e.user.id,"user.id");let t=x(e.challenge),n=x(e.user.id),s={userVerification:"preferred"};e.authenticatorSelection&&(s={...e.authenticatorSelection}),r&&(s={...s,authenticatorAttachment:r});let o={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(u=>({id:x(u.id),type:u.type,...u.transports&&{transports:u.transports}}))}};return g({publicKey:o})}catch(t){return a(f(t))}}function oe(e,r){try{U(e.challenge,"challenge");let t=x(e.challenge);return g({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:x(n.id),type:n.type,...n.transports&&{transports:n.transports}}))}},...r!==void 0&&{mediation:r}})}catch(t){return a(f(t))}}async function he(e,r,t){try{if(t.emit("start",{type:"start",operation:"register"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startRegister({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=M(s.value.challenge,e.authenticatorType);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.create(u);if(!m){let c=b("credential","creation failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishRegister({session_id:s.value.session_id,credential:k(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={success:true,credentialId:d.value.credential_id,credential_id:d.value.credential_id,status:d.value.status,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata}};return t.emit("success",{type:"success",operation:"register"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}async function be(e,r,t){try{if(t.emit("start",{type:"start",operation:"authenticate"}),!S()){let c=N();return t.emit("error",{type:"error",error:c}),a(c)}let n=e.externalUserId??e.external_user_id;if(!n||typeof n!="string"||n.trim()===""){let c=b("externalUserId","must be a non-empty string");return t.emit("error",{type:"error",error:c}),a(c)}let s=await r.startAuth({external_user_id:n});if(!s.ok)return t.emit("error",{type:"error",error:s.error}),a(s.error);let o=oe(s.value.challenge,e.mediation);if(!o.ok)return t.emit("error",{type:"error",error:o.error}),a(o.error);let u={...o.value,...e.signal&&{signal:e.signal}},m=await navigator.credentials.get(u);if(!m){let c=b("credential","retrieval failed");return t.emit("error",{type:"error",error:c}),a(c)}try{A(m);}catch(c){let v=f(c);return t.emit("error",{type:"error",error:v}),a(v)}let d=await r.finishAuthentication({session_id:s.value.session_id,credential:j(m)});if(!d.ok)return t.emit("error",{type:"error",error:d.error}),a(d.error);let h={authenticated:d.value.authenticated,sessionToken:d.value.session_token,user:{userId:d.value.user.user_id,externalUserId:d.value.user.external_user_id,email:d.value.user.email,metadata:d.value.user.metadata},signals:d.value.signals};return t.emit("success",{type:"success",operation:"authenticate"}),g(h)}catch(n){let s=f(n);return t.emit("error",{type:"error",error:s}),a(s)}}var He=2e3,$e=60,B=class{constructor(r){this.apiClient=r;}async startFlow(r){let t=await this.apiClient.startOnboarding({user_role:r.user_role});if(!t.ok)return a(t.error);let{session_id:n}=t.value;for(let s=0;s<$e;s++){await new Promise(d=>setTimeout(d,He));let o=await this.apiClient.getOnboardingStatus(n);if(!o.ok)return a(o.error);let u=o.value.status,m=o.value.onboarding_url;if(u==="pending_passkey"){let d=await this.apiClient.getOnboardingRegister(n);if(!d.ok)return a(d.error);let h=d.value;if(!h.challenge)return a(R("NOT_SUPPORTED","Onboarding requires user action - complete passkey registration at the provided onboarding_url",{onboarding_url:m}));let c=M(h.challenge);if(!c.ok)return a(c.error);let v;try{v=await navigator.credentials.create(c.value);}catch(_){return a(f(_))}try{A(v,"create");}catch(_){return a(f(_))}let O;try{O=k(v);}catch(_){return a(f(_))}let P=await this.apiClient.registerOnboardingPasskey(n,{credential:O,challenge:h.challenge.challenge});return P.ok?await this.apiClient.completeOnboarding(n,{company_name:r.company_name}):a(P.error)}if(u==="completed")return await this.apiClient.completeOnboarding(n,{company_name:r.company_name})}return a(R("TIMEOUT","Onboarding timed out"))}};var Xe=2e3,Ye=60,V=class{constructor(r){this.apiClient=r;}async init(){return this.apiClient.initCrossDeviceAuth()}async initRegistration(r){return this.apiClient.initCrossDeviceRegistration(r)}async waitForSession(r,t){for(let n=0;n<Ye;n++){if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));let s=await this.apiClient.getCrossDeviceStatus(r);if(!s.ok)return a(s.error);if(s.value.status==="completed")return !s.value.session_token||!s.value.user_id?a(R("UNKNOWN_ERROR","Missing data in completed session")):g({session_token:s.value.session_token,user_id:s.value.user_id});if(t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"));if(await new Promise(o=>{let u=setTimeout(()=>{o(null),t?.removeEventListener("abort",m);},Xe),m=()=>{clearTimeout(u),o(null);};t?.addEventListener("abort",m);}),t?.aborted)return a(R("ABORT_ERROR","Operation aborted by user or timeout"))}return a(R("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=M(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.create(n.value);}catch(u){return a(f(u))}try{A(s,"create");}catch(u){return a(f(u))}let o;try{o=k(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceRegistration({session_id:r,credential:o})}async executeAuthApproval(r,t){let n=oe(t.options);if(!n.ok)return a(n.error);let s;try{s=await navigator.credentials.get(n.value);}catch(u){return a(f(u))}try{A(s,"get");}catch(u){return a(f(u))}let o;try{o=j(s);}catch(u){return a(f(u))}return this.apiClient.verifyCrossDeviceAuth({session_id:r,credential:o})}};var W=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);n&&n.forEach(s=>{try{s(t);}catch{}});}removeAllListeners(){this.handlers.clear();}};var ae="https://api.trymellonauth.com",ve="https://api.trymellonauth.com/v1/telemetry";var le="trymellon_sandbox_session_token_v1";function Ee(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 ue(e,r){return {event:e,latencyMs:r,ok:true}}var pe=class e{sandbox;sandboxToken;apiClient;eventEmitter;telemetrySender;crossDeviceManager;onboarding;static create(r){try{let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")return a(b("appId","must be a non-empty string"));if(!n||typeof n!="string"||n.trim()==="")return a(b("publishableKey","must be a non-empty string"));let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;return I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4),g(new e(r))}catch(t){return w(t)?a(t):a(b("config",t.message))}}constructor(r){this.sandbox=r.sandbox===true,this.sandboxToken=this.sandbox&&r.sandboxToken!=null&&r.sandboxToken!==""?r.sandboxToken:le;let t=r.appId,n=r.publishableKey;if(!t||typeof t!="string"||t.trim()==="")throw b("appId","must be a non-empty string");if(!n||typeof n!="string"||n.trim()==="")throw b("publishableKey","must be a non-empty string");let s=r.apiBaseUrl??ae;$(s,"apiBaseUrl");let o=r.timeoutMs??3e4;I(o,"timeoutMs",1e3,3e5),r.maxRetries!==void 0&&I(r.maxRetries,"maxRetries",0,10),r.retryDelayMs!==void 0&&I(r.retryDelayMs,"retryDelayMs",100,1e4);let u=r.maxRetries??3,m=r.retryDelayMs??1e3,d=new q(o,u,m,r.logger),h=r.origin??(typeof window<"u"&&window?.location?.origin?window.location.origin:void 0),c={"X-App-Id":t.trim(),Authorization:`Bearer ${n.trim()}`,...h&&{Origin:h}};this.apiClient=new K(d,s,c),this.onboarding=new B(this.apiClient),this.crossDeviceManager=new V(this.apiClient),this.eventEmitter=new W,r.enableTelemetry&&(this.telemetrySender=r.telemetrySender??Ee(r.telemetryEndpoint??ve));}static isSupported(){return S()}async register(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({success:true,credentialId:"",status:"sandbox",sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await he(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("register",Date.now()-t)).catch(()=>{}),n}async authenticate(r){if(this.sandbox){let s=r.externalUserId??r.external_user_id??"sandbox";return Promise.resolve(g({authenticated:true,sessionToken:this.sandboxToken,user:{userId:"sandbox-user",externalUserId:typeof s=="string"?s:"sandbox"}}))}let t=Date.now(),n=await be(r,this.apiClient,this.eventEmitter);return n.ok&&this.telemetrySender&&this.telemetrySender.send(ue("authenticate",Date.now()-t)).catch(()=>{}),n}async validateSession(r){return this.sandbox&&r===this.sandboxToken?Promise.resolve(g({valid:true,user_id:"sandbox-user",external_user_id:"sandbox",tenant_id:"sandbox-tenant",app_id:"sandbox-app"})):this.apiClient.validateSession(r)}async getStatus(){return Re()}on(r,t){return this.eventEmitter.on(r,t)}version(){return "1.4.3"}fallback={email:{start:async r=>this.apiClient.startEmailFallback(r),verify:async r=>this.apiClient.verifyEmailCode(r.userId,r.code)}};auth={crossDevice:{init:()=>this.crossDeviceManager.init(),initRegistration:r=>this.crossDeviceManager.initRegistration(r),waitForSession:(r,t)=>this.crossDeviceManager.waitForSession(r,t),approve:r=>this.crossDeviceManager.approve(r)}}};var de=class{debug(r,t){t&&Object.keys(t).length>0?console.debug(`[TryMellon] ${r}`,t):console.debug(`[TryMellon] ${r}`);}info(r,t){t&&Object.keys(t).length>0?console.info(`[TryMellon] ${r}`,t):console.info(`[TryMellon] ${r}`);}warn(r,t){t&&Object.keys(t).length>0?console.warn(`[TryMellon] ${r}`,t):console.warn(`[TryMellon] ${r}`);}error(r,t){t&&Object.keys(t).length>0?console.error(`[TryMellon] ${r}`,t):console.error(`[TryMellon] ${r}`);}};
2
2
  export{de as ConsoleLogger,le as SANDBOX_SESSION_TOKEN,pe as TryMellon,D as TryMellonError,R as createError,b as createInvalidArgumentError,De as createNetworkError,N as createNotSupportedError,Me as createTimeoutError,Pe as createUserCancelledError,a as err,w as isTryMellonError,f as mapWebAuthnError,g as ok};//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trymellon/js",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "SDK oficial de TryMellon para integrar autenticación passwordless con Passkeys / WebAuthn",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",