@corbado/autocapture 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -154,12 +154,18 @@ backup-state, AAGUID, transport, and discoverability insight. Client-extension o
154
154
  `credProps.rk`; PRF and unrelated extension results are omitted. The payload therefore still contains
155
155
  credential IDs, user handles, challenges, signatures, authenticator data, and attestation material.
156
156
 
157
- The tested 1Password browser extension exposes locked `get` and `create` accessors. WebAuthn capture
158
- therefore reports `mode: "unavailable"`; passkey operations continue through 1Password unchanged but
159
- produce no autocaptured WebAuthn events. Password managers that wrap the writable methods before
160
- autocapture are delegated to; one that assigns its wrapper afterwards keeps working, and its
161
- ceremonies stay observed when the wrapper forwards through the method it replaced (the surveyed
162
- managers do). A later assignment that does not forward displaces WebAuthn telemetry.
157
+ The tested 1Password browser extension exposes locked `get` and `create` accessors. By default
158
+ WebAuthn capture therefore reports `mode: "unavailable"`; passkey operations continue through
159
+ 1Password unchanged but produce no autocaptured WebAuthn events. Password managers that wrap the
160
+ writable methods before autocapture are delegated to; one that assigns its wrapper afterwards keeps
161
+ working, and its ceremonies stay observed when the wrapper forwards through the method it replaced
162
+ (the surveyed managers do). A later assignment that does not forward displaces WebAuthn telemetry.
163
+
164
+ `captureWebAuthn({ attach: "container" })` opts into a second attachment surface for that case: when
165
+ the methods cannot be patched, capture attaches to the `navigator.credentials` container instead and
166
+ observes reads of `get`/`create` there. The methods surface is always tried first, so the option
167
+ changes nothing where the direct patch works. The integration holding the methods is never written
168
+ to and keeps handling every ceremony.
163
169
 
164
170
  ## Runtime support
165
171
 
package/dist/index.d.mts CHANGED
@@ -63,12 +63,39 @@ type WebAuthnCeremonyFailedEvent = WebAuthnCeremonyBase & {
63
63
  };
64
64
  /** A protocol-native lifecycle event for WebAuthn authentication or registration. */
65
65
  type WebAuthnCeremonyEvent = WebAuthnCeremonyStartedEvent | WebAuthnCeremonyCompletedEvent | WebAuthnCeremonyFailedEvent;
66
+ /**
67
+ * Surface WebAuthn capture may attach to.
68
+ *
69
+ * - `"methods"`: `credentials.get` / `credentials.create` only.
70
+ * - `"container"`: additionally the `navigator.credentials` container, used when the methods are
71
+ * held by another integration in a form that cannot be shared.
72
+ */
73
+ type WebAuthnAttachSurface = "methods" | "container";
66
74
  /** Options for {@link captureWebAuthn}. */
67
75
  type WebAuthnCaptureOptions = {
68
76
  /** Receives WebAuthn lifecycle events. Return values are not awaited. */
69
77
  onEvent: (event: WebAuthnCeremonyEvent) => void;
70
78
  /** Optional diagnostic logger. */
71
79
  logger?: Logger;
80
+ /**
81
+ * Highest surface capture may attach to. Defaults to `"methods"`.
82
+ *
83
+ * With `"container"`, a capture that cannot patch the methods attaches to the
84
+ * `navigator.credentials` container instead: reads of `get`/`create` are observed while the
85
+ * integration holding them keeps handling the ceremony. The methods surface is always tried
86
+ * first, so this changes nothing when it is available.
87
+ */
88
+ attach?: WebAuthnAttachSurface;
89
+ };
90
+ /**
91
+ * Handle returned by {@link captureWebAuthn}.
92
+ *
93
+ * `surface` reports where the capture actually attached, which is not implied by `mode`: an
94
+ * `attach: "container"` capture reports `mode: "standard"` from either surface.
95
+ */
96
+ type WebAuthnCaptureHandle = CaptureHandle & {
97
+ /** Surface this capture attached to; `"none"` when `mode` is `"unavailable"`. */
98
+ readonly surface: WebAuthnAttachSurface | "none";
72
99
  };
73
100
  /** Network API used for an observed exchange. */
74
101
  type NetworkTransport = "xhr" | "fetch";
@@ -241,7 +268,7 @@ type NavigationCaptureOptions = {
241
268
  * @throws TypeError when `onEvent` is not a function — a misconfigured
242
269
  * integration is a programming error, not a degraded mode.
243
270
  */
244
- declare function captureWebAuthn(options: WebAuthnCaptureOptions): CaptureHandle;
271
+ declare function captureWebAuthn(options: WebAuthnCaptureOptions): WebAuthnCaptureHandle;
245
272
 
246
273
  /**
247
274
  * Observes selected requests made through `XMLHttpRequest` and `fetch`.
@@ -285,4 +312,4 @@ declare function composedPath(event: Event): readonly EventTarget[];
285
312
  /** Version identifier embedded in the current build. */
286
313
  declare const VERSION: string;
287
314
 
288
- export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureWebAuthn, composedPath };
315
+ export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, VERSION, type WebAuthnAttachSurface, type WebAuthnCaptureHandle, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureWebAuthn, composedPath };
package/dist/index.d.ts CHANGED
@@ -63,12 +63,39 @@ type WebAuthnCeremonyFailedEvent = WebAuthnCeremonyBase & {
63
63
  };
64
64
  /** A protocol-native lifecycle event for WebAuthn authentication or registration. */
65
65
  type WebAuthnCeremonyEvent = WebAuthnCeremonyStartedEvent | WebAuthnCeremonyCompletedEvent | WebAuthnCeremonyFailedEvent;
66
+ /**
67
+ * Surface WebAuthn capture may attach to.
68
+ *
69
+ * - `"methods"`: `credentials.get` / `credentials.create` only.
70
+ * - `"container"`: additionally the `navigator.credentials` container, used when the methods are
71
+ * held by another integration in a form that cannot be shared.
72
+ */
73
+ type WebAuthnAttachSurface = "methods" | "container";
66
74
  /** Options for {@link captureWebAuthn}. */
67
75
  type WebAuthnCaptureOptions = {
68
76
  /** Receives WebAuthn lifecycle events. Return values are not awaited. */
69
77
  onEvent: (event: WebAuthnCeremonyEvent) => void;
70
78
  /** Optional diagnostic logger. */
71
79
  logger?: Logger;
80
+ /**
81
+ * Highest surface capture may attach to. Defaults to `"methods"`.
82
+ *
83
+ * With `"container"`, a capture that cannot patch the methods attaches to the
84
+ * `navigator.credentials` container instead: reads of `get`/`create` are observed while the
85
+ * integration holding them keeps handling the ceremony. The methods surface is always tried
86
+ * first, so this changes nothing when it is available.
87
+ */
88
+ attach?: WebAuthnAttachSurface;
89
+ };
90
+ /**
91
+ * Handle returned by {@link captureWebAuthn}.
92
+ *
93
+ * `surface` reports where the capture actually attached, which is not implied by `mode`: an
94
+ * `attach: "container"` capture reports `mode: "standard"` from either surface.
95
+ */
96
+ type WebAuthnCaptureHandle = CaptureHandle & {
97
+ /** Surface this capture attached to; `"none"` when `mode` is `"unavailable"`. */
98
+ readonly surface: WebAuthnAttachSurface | "none";
72
99
  };
73
100
  /** Network API used for an observed exchange. */
74
101
  type NetworkTransport = "xhr" | "fetch";
@@ -241,7 +268,7 @@ type NavigationCaptureOptions = {
241
268
  * @throws TypeError when `onEvent` is not a function — a misconfigured
242
269
  * integration is a programming error, not a degraded mode.
243
270
  */
244
- declare function captureWebAuthn(options: WebAuthnCaptureOptions): CaptureHandle;
271
+ declare function captureWebAuthn(options: WebAuthnCaptureOptions): WebAuthnCaptureHandle;
245
272
 
246
273
  /**
247
274
  * Observes selected requests made through `XMLHttpRequest` and `fetch`.
@@ -285,4 +312,4 @@ declare function composedPath(event: Event): readonly EventTarget[];
285
312
  /** Version identifier embedded in the current build. */
286
313
  declare const VERSION: string;
287
314
 
288
- export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, VERSION, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureWebAuthn, composedPath };
315
+ export { type CaptureHandle, type HttpExchange, type HttpRequestStarted, type Logger, type NavigationCaptureOptions, type NavigationEvent, type NavigationSource, type NetworkBodyDirection, type NetworkBodyProjectionContext, type NetworkBodyProjector, type NetworkCaptureOptions, type NetworkTransport, VERSION, type WebAuthnAttachSurface, type WebAuthnCaptureHandle, type WebAuthnCaptureOptions, type WebAuthnCeremonyCompletedEvent, type WebAuthnCeremonyContext, type WebAuthnCeremonyEvent, type WebAuthnCeremonyFailedEvent, type WebAuthnCeremonyStartedEvent, type WebAuthnMediation, type WebAuthnUiMode, captureNavigation, captureNetwork, captureWebAuthn, composedPath };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var re=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var qe=Object.prototype.hasOwnProperty;var Ae=(e,n)=>{for(var t in n)re(e,t,{get:n[t],enumerable:!0})},Oe=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of ke(n))!qe.call(e,r)&&r!==t&&re(e,r,{get:()=>n[r],enumerable:!(o=Ce(n,r))||o.enumerable});return e};var Ee=e=>Oe(re({},"__esModule",{value:!0}),e);var Ue={};Ae(Ue,{VERSION:()=>we,captureNavigation:()=>be,captureNetwork:()=>ye,captureWebAuthn:()=>ce,composedPath:()=>ve});module.exports=Ee(Ue);var Pe={log:()=>{}};function F(e){return e?{log:(...n)=>{try{let t=e.log(...n);if(t&&(typeof t=="object"||typeof t=="function"))try{Promise.resolve(t).catch(()=>{})}catch{}}catch{}}}:Pe}var ue=Symbol.for("corbado.autocapture.installed");function U(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,ue)}catch{return!1}}function X(e,n){var o,r;let t=n;try{Object.defineProperty(e,ue,{value:n,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(o=t.name)!=null?o:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(r=t.length)!=null?r:0,configurable:!0})}catch{}return e}function O(){return{mode:"unavailable",disconnect:()=>{}}}function oe(e,n){return!!e&&"value"in e&&"value"in n&&e.value===n.value&&e.writable===n.writable&&e.enumerable===n.enumerable&&e.configurable===n.configurable}function J(e,n,t,o,r,i=String(n)){try{let c=Object.getOwnPropertyDescriptor(e,n);oe(c,{...o,value:t})&&Object.defineProperty(e,n,o)}catch(c){r.log(`${i} restoration skipped`,c)}}function $(e,n,t){let o=F(e);return r=>{try{let i=t(r);if(i&&(typeof i=="object"||typeof i=="function"))try{Promise.resolve(i).catch(c=>o.log(`${n} listener failed`,c))}catch(c){o.log(`${n} listener failed`,c)}}catch(i){o.log(`${n} listener failed`,i)}}}function ce(e){let n=e.onEvent;if(typeof n!="function")throw new TypeError("captureWebAuthn requires an onEvent callback");let t=F(e.logger),o=typeof navigator=="undefined"?void 0:navigator,r=o==null?void 0:o.credentials;if(!o||!r)return t.log("webauthn capture unavailable: navigator.credentials missing"),O();let i=r.get,c=r.create;if(typeof i!="function"||typeof c!="function")return t.log("webauthn capture unavailable: credentials methods missing"),O();if(U(i)||U(c))return t.log("webauthn capture unavailable: an equivalent capture is already active"),O();let y=!1,C=0,B=$(t,"webauthn",h=>{if(y)return n(h)}),k=(h,D)=>{let I={invoke(...q){let v=this,g=q[0];if(!y||!Z(g)||!Z(g.publicKey))return Reflect.apply(D,v,q);let G=g.publicKey,u=`wa-${++C}`,m=Reflect.apply(D,v,q),p=Z(g.signal)?g.signal:void 0,f=xe(h,g,G),_={...f,ceremonyId:u,phase:"started",userActivation:Be(o)};if(f.kind==="authentication"){let w=G;_.requestOptionsJson=Le(w,t)}return B(_),Promise.resolve(m).then(w=>(y&&B({...f,ceremonyId:u,phase:"completed",credentialJson:De(w,h,t),...(p==null?void 0:p.aborted)===!0?{aborted:!0}:{}}),w),w=>{throw y&&B({...f,ceremonyId:u,phase:"failed",error:w,errorName:He(w),...(p==null?void 0:p.aborted)===!0?{aborted:!0}:{}}),w})}}.invoke;return X(I,{name:h,length:0})},x=(h,D)=>{let I=k(h,D),q=Object.getOwnPropertyDescriptor(r,h);if(q&&(!("value"in q)||q.writable!==!0))return null;try{r[h]=I}catch{return null}return()=>{r[h]===I&&(q?r[h]=q.value:delete r[h])}},S=x("get",i),N=S?x("create",c):null;return!S||!N?(S==null||S(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),O()):(y=!0,{mode:"standard",disconnect:()=>{y=!1,S(),N()}})}function xe(e,n,t){let o=Se(n.mediation);if(e==="create")return{kind:"registration",mediation:o};let r=t;return{kind:"authentication",mediation:o,uiMode:Ne(n.uiMode),credentialSet:Array.isArray(r.allowCredentials)&&r.allowCredentials.length>0?"allowlisted":"discoverable"}}function Se(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function Ne(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function Be(e){let n=e.userActivation;return typeof(n==null?void 0:n.isActive)=="boolean"?n.isActive:void 0}function De(e,n,t){var o;if(e)try{let r=e,i=r.response,c={id:z(r.id),rawId:K(r.rawId),type:z(r.type),authenticatorAttachment:z(r.authenticatorAttachment),response:n==="create"?{clientDataJSON:K(i==null?void 0:i.clientDataJSON),attestationObject:K(i==null?void 0:i.attestationObject),transports:ae((o=i==null?void 0:i.getTransports)==null?void 0:o.call(i))}:{clientDataJSON:K(i==null?void 0:i.clientDataJSON),authenticatorData:K(i==null?void 0:i.authenticatorData),signature:K(i==null?void 0:i.signature),userHandle:K(i==null?void 0:i.userHandle)},...n==="create"?je(r):{}};return JSON.stringify(c)}catch(r){t.log("credential serialization failed",r);return}}function Le(e,n){try{let t={},o=z(e.rpId),r=z(e.userVerification),i=ae(e.hints);return o!==void 0&&(t.rpId=o),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(t.timeout=e.timeout),r!==void 0&&(t.userVerification=r),i!==void 0&&(t.hints=i),t.challenge=K(e.challenge),Array.isArray(e.allowCredentials)&&(t.allowCredentials=Te(e.allowCredentials)),JSON.stringify(t)}catch(t){n.log("request options serialization failed",t);return}}function Te(e){let n=[];for(let t of e){if(!Z(t))continue;let o=t;n.push({type:z(o.type),id:K(o.id),transports:ae(o.transports)})}return n}function ae(e){if(Array.isArray(e))return e.filter(n=>typeof n=="string")}function z(e){return typeof e=="string"?e:void 0}function je(e){var o;let n=(o=e.getClientExtensionResults)==null?void 0:o.call(e);if(!Z(n))return{};let t=n.credProps;return!t||typeof t.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:t.rk}}}}function K(e){let n;if(e instanceof ArrayBuffer)n=new Uint8Array(e);else if(ArrayBuffer.isView(e))n=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let t="";for(let o of n)t+=String.fromCharCode(o);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Z(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function He(e){return e instanceof DOMException?e.name:"UnknownError"}var de=0;function le(){return de+=1,`network-${de}`}function Ie(e,n){let t=e.responseType;if(t===""||t==="text")return n(e.responseText);if(t==="json"){let o=e.response;return o==null?void 0:n(o)}}var Me=500,pe=Symbol("body-read-timeout");function fe(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function he(e,n){let t=e.body;if(!t)return;let o=t.getReader(),r;try{let i=new Promise(C=>{r=setTimeout(()=>C(pe),Me)}),c=new TextDecoder,y=[];for(;;){let C=await Promise.race([o.read(),i]);if(C===pe){n.log("body omitted: read timed out"),o.cancel().catch(()=>{});return}if(C.done)break;y.push(c.decode(C.value,{stream:!0}))}return y.push(c.decode()),y.join("")}catch{o.cancel().catch(()=>{});return}finally{r!==void 0&&clearTimeout(r)}}function ie(e){var n;(n=e==null?void 0:e.body)==null||n.cancel().catch(()=>{})}function ye(e){var v,g,G;let{onExchange:n,onRequest:t,match:o}=e;if(typeof n!="function"||typeof o!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let r=F(e.logger),i=(v=e.transports)!=null?v:["xhr","fetch"],c=(g=e.bodyCapture)==null?void 0:g.request,y=(G=e.bodyCapture)==null?void 0:G.response,C=typeof c=="function",B=typeof y=="function",k=!1,x=$(r,"network",u=>{if(k)return n(u)}),S=$(r,"network request",u=>{if(k)return t==null?void 0:t(u)}),N=(u,m,p)=>{if(typeof p=="function")try{return p(u,m)}catch(f){r.log("body projection failed",f);return}},h=(u,m)=>{try{let p=typeof document!="undefined"?document.baseURI:void 0,f=new URL(String(u),p);return o(f,m)===!0?{url:f.href,path:f.pathname}:void 0}catch{return}},D=()=>{if(typeof XMLHttpRequest=="undefined")return r.log("xhr capture unavailable: XMLHttpRequest missing"),null;let u=XMLHttpRequest.prototype,m=Object.getOwnPropertyDescriptor(u,"open"),p=Object.getOwnPropertyDescriptor(u,"send");if(!m||!("value"in m)||typeof m.value!="function"||!p||!("value"in p)||typeof p.value!="function")return r.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let f=m.value,_=p.value;if(U(f)||U(_))return r.log("xhr capture unavailable: an equivalent capture is already active"),null;let w=new WeakMap,R=new Set,E=!1,L={open(...b){var d;let a=Reflect.apply(f,this,b);if(!k||!E)return a;try{let P=w.get(this);P&&(P.reported=!0,(d=P.cleanupListeners)==null||d.call(P));let T=String(b[0]).toUpperCase(),A=h(b[1],T);A?w.set(this,{method:T,url:A.url,path:A.path,reported:!1}):w.delete(this)}catch(P){r.log("xhr open observation failed",P)}return a}}.open,W={send(...b){let a=k&&E?w.get(this):void 0;if(!a||a.reported||a.cleanupListeners)return Reflect.apply(_,this,b);let d=()=>{},P=!1;try{a.requestId=le();let A={direction:"request",transport:"xhr",method:a.method,url:a.url,path:a.path};a.requestBody=C&&typeof b[0]=="string"?N(b[0],A,c):void 0;let Y=()=>{a.outcome===void 0&&(a.outcome="abort")},Q=()=>{a.outcome===void 0&&(a.outcome="timeout")},s=()=>{a.outcome===void 0&&(a.outcome="error")},l=()=>{var V;d();try{if(!k||!E||a.reported||!a.requestId)return;a.reported=!0;let H={direction:"response",transport:"xhr",method:a.method,url:a.url,path:a.path},ne=this.status,se={requestId:a.requestId,transport:"xhr",method:a.method,url:a.url,path:a.path,status:ne,ok:ne>=200&&ne<300,outcome:(V=a.outcome)!=null?V:"load",durationMs:a.startedAt!==void 0?Date.now()-a.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:a.requestBody,responseBody:B?Ie(this,Re=>N(Re,H,y)):void 0};a.requestEmitted?x(se):a.pendingExchange=se}catch(H){r.log("xhr exchange observation failed",H)}finally{w.get(this)===a&&w.delete(this)}},j=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&l()}catch(V){r.log("xhr ready-state observation failed",V)}},M=()=>l();d=()=>{for(let[V,H]of[["readystatechange",j],["abort",Y],["timeout",Q],["error",s],["loadend",M]])this.removeEventListener(V,H);a.cleanupListeners===d&&(a.cleanupListeners=void 0),R.delete(d)},this.addEventListener("readystatechange",j),this.addEventListener("abort",Y),this.addEventListener("timeout",Q),this.addEventListener("error",s),this.addEventListener("loadend",M),a.cleanupListeners=d,R.add(d),a.startedAt=Date.now(),P=!0}catch(A){r.log("xhr send observation failed",A),d()}let T;try{T=Reflect.apply(_,this,b)}catch(A){throw d(),A}if(P&&a.requestId!==void 0&&a.startedAt!==void 0){a.requestEmitted=!0,S({requestId:a.requestId,transport:"xhr",method:a.method,url:a.url,path:a.path,startedAt:a.startedAt,requestBody:a.requestBody});let A=a.pendingExchange;a.pendingExchange=void 0,A&&x(A)}return T}}.send;return X(L,f),X(W,_),m.writable!==!0||p.writable!==!0?(r.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(u,"open",{...m,value:L}),Object.defineProperty(u,"send",{...p,value:W}),E=!0,()=>{E=!1;for(let b of[...R])b();J(u,"open",L,m,r),J(u,"send",W,p,r)})},I=()=>{let u=globalThis,m=Object.getOwnPropertyDescriptor(u,"fetch");if(!m||!("value"in m))return r.log("fetch capture unavailable: fetch is not an own data property"),null;let p=m.value;if(typeof p!="function")return r.log("fetch capture unavailable: fetch missing"),null;if(U(p))return r.log("fetch capture unavailable: an equivalent capture is already active"),null;let f=!1,_=async(R,E,L,W)=>{try{if(!k||!f){ie(L);return}let[b,a]=await Promise.all([W!=null?W:Promise.resolve(void 0),L?he(L,r):Promise.resolve(void 0)]);if(!k||!f)return;let d={direction:"request",transport:"fetch",method:R.method,url:R.url,path:R.path},P={...d,direction:"response"},T=R.requestBody;T===void 0&&b!==void 0&&(T=N(b,d,c));let A=a!==void 0?N(a,P,y):void 0;x({requestId:R.requestId,transport:"fetch",method:R.method,url:R.url,path:R.path,status:E.status,ok:E.ok,outcome:"load",durationMs:Date.now()-R.startedAt,responseUrl:E.url||void 0,requestBody:T,responseBody:A})}catch(b){r.log("fetch exchange observation failed",b)}},w={fetch(...R){var T,A,Y,Q;let E;try{let s=R[0],l=R[1];if(k&&f&&C&&typeof Request!="undefined"&&s instanceof Request&&(l==null?void 0:l.body)===void 0&&s.body){let j=String((T=l==null?void 0:l.method)!=null?T:s.method).toUpperCase(),M=(A=s.headers.get("content-type"))!=null?A:"";h(s.url,j)&&fe(M)&&(E=s.clone())}}catch(s){r.log("fetch observation failed",s)}let L,W=Date.now();try{L=Reflect.apply(p,this,R)}catch(s){throw ie(E),s}let b,a;try{if(k&&f){let s=R[0],l=R[1],j=typeof Request!="undefined"&&s instanceof Request,M=String((Y=l==null?void 0:l.method)!=null?Y:j?s.method:"GET").toUpperCase(),V=j?s.url:s,H=h(V,M);H&&(b={requestId:le(),method:M,url:H.url,path:H.path,startedAt:W},a=(Q=l==null?void 0:l.signal)!=null?Q:j?s.signal:void 0,C&&typeof(l==null?void 0:l.body)=="string"&&(b.requestBody=N(l.body,{direction:"request",transport:"fetch",method:M,url:H.url,path:H.path},c)))}}catch(s){r.log("fetch observation failed",s)}if(!b)return ie(E),L;let d=b;S({requestId:d.requestId,transport:"fetch",method:d.method,url:d.url,path:d.path,startedAt:d.startedAt,requestBody:d.requestBody});let P=E?he(E,r):void 0;return L.then(s=>{var j;let l;try{if(k&&f&&B){let M=(j=s.headers.get("content-type"))!=null?j:"";fe(M)&&s.body&&(l=s.clone())}}catch{}_(d,s,l,P)},s=>{try{if(!k||!f)return;let l=(a==null?void 0:a.aborted)===!0||(s==null?void 0:s.name)==="AbortError"||typeof DOMException!="undefined"&&s instanceof DOMException&&s.code===DOMException.ABORT_ERR;x({requestId:d.requestId,transport:"fetch",method:d.method,url:d.url,path:d.path,status:0,ok:!1,outcome:l?"abort":"error",durationMs:Date.now()-d.startedAt})}catch(l){r.log("fetch failure observation failed",l)}}),L}}.fetch;return X(w,p),m.writable!==!0?(r.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(u,"fetch",{...m,value:w}),f=!0,()=>{f=!1,J(u,"fetch",w,m,r)})},q=[];if(i.includes("xhr")){let u=D();u&&q.push(u)}if(i.includes("fetch")){let u=I();u&&q.push(u)}return q.length===0?O():(k=!0,{mode:"standard",disconnect:()=>{k=!1;for(let u of q.splice(0))u()}})}function be(e){let n=e.onNavigate;if(typeof n!="function")throw new TypeError("captureNavigation requires an onNavigate callback");let t=F(e.logger),o,r,i,c,y,C;try{if(o=window,r=o==null?void 0:o.history,!o||!r)return t.log("navigation capture unavailable: window/history missing"),O();if(y=ge(r,"pushState"),C=ge(r,"replaceState"),!y||!C)return t.log("navigation capture unavailable: history method descriptors missing"),O();if(i=y.descriptor.value,c=C.descriptor.value,typeof i!="function"||typeof c!="function")return t.log("navigation capture unavailable: history methods missing"),O();if(typeof o.addEventListener!="function"||typeof o.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),O()}catch(v){return t.log("navigation capture unavailable: history inspection failed",v),O()}if(U(i)||U(c))return t.log("navigation capture unavailable: an equivalent capture is already active"),O();let B=!1,k=()=>({path:o.location.pathname,search:o.location.search,hash:o.location.hash}),x;try{x=k()}catch(v){return t.log("navigation capture unavailable: location inspection failed",v),O()}let S=$(t,"navigation",v=>{if(B)return n(v)}),N=v=>{if(B)try{let g=k();if(g.path===x.path&&g.search===x.search&&g.hash===x.hash)return;x=g,S({...g,source:v})}catch(g){t.log("navigation observation failed",g)}},h={pushState(...v){let g=Reflect.apply(i,this,v);return N("push"),g}}.pushState,D={replaceState(...v){let g=Reflect.apply(c,this,v);return N("replace"),g}}.replaceState;X(h,i),X(D,c);let I=()=>N("pop"),q=()=>N("hash");try{if(me(y,h),me(C,D),r.pushState!==h||r.replaceState!==D)throw new Error("history method replacement did not take effect");o.addEventListener("popstate",I),o.addEventListener("hashchange",q),B=!0}catch(v){return B=!1,te(o,"popstate",I,t),te(o,"hashchange",q,t),ee(C,D,t),ee(y,h,t),t.log("navigation capture unavailable: history methods are not writable",v),n=()=>{},S=()=>{},t=F(),O()}return{mode:"standard",disconnect:()=>{B=!1,n=()=>{},te(o,"popstate",I,t),te(o,"hashchange",q,t),ee(y,h,t),ee(C,D,t),S=()=>{},t=F()}}}function ge(e,n){let t=e;for(;t;){let o=Object.getOwnPropertyDescriptor(t,n);if(o)return!("value"in o)||typeof o.value!="function"?null:{owner:t,key:n,descriptor:o};t=Object.getPrototypeOf(t)}return null}function me(e,n){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let t=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!oe(t,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:n})}function ee(e,n,t){J(e.owner,e.key,n,e.descriptor,t,`navigation ${e.key}`)}function te(e,n,t,o){try{e.removeEventListener(n,t)}catch(r){o.log(`navigation ${n} listener removal skipped`,r)}}function ve(e){let n=e.composedPath();return n.length>0?n:e.target?[e.target]:[]}var we="0.3.0";0&&(module.exports={VERSION,captureNavigation,captureNetwork,captureWebAuthn,composedPath});
1
+ "use strict";var re=Object.defineProperty;var Ae=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var qe=Object.prototype.hasOwnProperty;var Oe=(e,n)=>{for(var t in n)re(e,t,{get:n[t],enumerable:!0})},Pe=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of ke(n))!qe.call(e,r)&&r!==t&&re(e,r,{get:()=>n[r],enumerable:!(o=Ae(n,r))||o.enumerable});return e};var xe=e=>Pe(re({},"__esModule",{value:!0}),e);var _e={};Oe(_e,{VERSION:()=>Re,captureNavigation:()=>ve,captureNetwork:()=>ge,captureWebAuthn:()=>de,composedPath:()=>we});module.exports=xe(_e);var Ee={log:()=>{}};function K(e){return e?{log:(...n)=>{try{let t=e.log(...n);if(t&&(typeof t=="object"||typeof t=="function"))try{Promise.resolve(t).catch(()=>{})}catch{}}catch{}}}:Ee}var ue=Symbol.for("corbado.autocapture.installed");function M(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,ue)}catch{return!1}}function F(e,n){var o,r;let t=n;try{Object.defineProperty(e,ue,{value:n,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(o=t.name)!=null?o:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(r=t.length)!=null?r:0,configurable:!0})}catch{}return e}function B(){return{mode:"unavailable",disconnect:()=>{}}}function oe(e,n){return!!e&&"value"in e&&"value"in n&&e.value===n.value&&e.writable===n.writable&&e.enumerable===n.enumerable&&e.configurable===n.configurable}function z(e,n,t,o,r,a=String(n)){try{let p=Object.getOwnPropertyDescriptor(e,n);oe(p,{...o,value:t})&&Object.defineProperty(e,n,o)}catch(p){r.log(`${a} restoration skipped`,p)}}function J(e,n,t){let o=K(e);return r=>{try{let a=t(r);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(p=>o.log(`${n} listener failed`,p))}catch(p){o.log(`${n} listener failed`,p)}}catch(a){o.log(`${n} listener failed`,a)}}}var ce=e=>({get:e("get"),create:e("create")});function de(e){let n=e.onEvent;if(typeof n!="function")throw new TypeError("captureWebAuthn requires an onEvent callback");let t=K(e.logger),o=c=>(t.log(`webauthn capture unavailable: ${c}`),{...B(),surface:"none"}),r=typeof navigator=="undefined"?void 0:navigator,a=r==null?void 0:r.credentials;if(!r||!a)return o("navigator.credentials missing");let p=a,w=ce(c=>p[c]);if(typeof w.get!="function"||typeof w.create!="function")return o("credentials methods missing");if(M(w.get)||M(w.create))return o("an equivalent capture is already active");let R=!1,I=0,q=J(t,"webauthn",n),N=(c,y,g)=>{let W={invoke(...u){let d=u[0];if(!R||g!=null&&g()||!Z(d)||!Z(d.publicKey))return y(this,u);let f=d.publicKey,s=`wa-${++I}`,v=y(this,u),C=Z(d.signal)?d.signal:void 0,h=Se(c,d,f),A=O=>{R&&q({...h,ceremonyId:s,...O()})},x=()=>(C==null?void 0:C.aborted)===!0?{aborted:!0}:{};return A(()=>({phase:"started",userActivation:De(r),...h.kind==="authentication"?{requestOptionsJson:Te(f,t)}:{}})),Promise.resolve(v).then(O=>(A(()=>({phase:"completed",credentialJson:Le(O,c,t),...x()})),O),O=>{throw A(()=>({phase:"failed",error:O,errorName:Me(O),...x()})),O})}}.invoke;return F(W,{name:c,length:0})},U=c=>{var W;let y=N(c,(u,d)=>Reflect.apply(w[c],u,d)),g=Object.getOwnPropertyDescriptor(a,c);if(g&&(!("value"in g)||g.writable!==!0))return null;try{p[c]=y}catch{return null}if(((W=Object.getOwnPropertyDescriptor(a,c))==null?void 0:W.value)!==y){try{p[c]=w[c]}catch{}return null}return()=>{p[c]===y&&(g?p[c]=g.value:delete p[c])}},D=()=>{let c=ce(()=>new WeakMap),y=(f,s)=>{let v=c[f].get(s);if(v)return v;let C=N(f,(h,A)=>Reflect.apply(s,a,A),()=>{let h=p[f];return h!==s&&h!==C});return c[f].set(s,C),C},g=f=>{let s=Object.getOwnPropertyDescriptor(a,f);return s?s.configurable===!0||!("value"in s)||s.writable===!0:!0},W=new WeakMap,u=new Proxy(a,{get(f,s){let v=Reflect.get(a,s,a);if((s==="get"||s==="create")&&g(s))return typeof v!="function"||M(v)?v:y(s,v);if(typeof v!="function"||!g(s)||s==="constructor")return v;let C=W.get(v);if(C)return C;let h=v.bind(a);return W.set(v,h),h},set(f,s,v){return Reflect.set(a,s,v,a)}}),d=Object.getOwnPropertyDescriptor(r,"credentials");if(d&&d.configurable!==!0)return null;try{Object.defineProperty(r,"credentials",{value:u,writable:!0,enumerable:!0,configurable:!0})}catch{return null}return r.credentials!==u?null:()=>{r.credentials===u&&(d?Object.defineProperty(r,"credentials",d):delete r.credentials)}},L=(c,y)=>(R=!0,{mode:"standard",surface:c,disconnect:()=>{R=!1,y()}}),E=U("get"),$=E?U("create"):null;if(E&&$)return L("methods",()=>{E(),$()});if(E==null||E(),e.attach==="container"){let c=D();if(c)return t.log("webauthn capture attached at the credentials container"),L("container",c)}return o("credentials methods cannot be patched safely")}function Se(e,n,t){let o=Ne(n.mediation);if(e==="create")return{kind:"registration",mediation:o};let r=t;return{kind:"authentication",mediation:o,uiMode:Be(n.uiMode),credentialSet:Array.isArray(r.allowCredentials)&&r.allowCredentials.length>0?"allowlisted":"discoverable"}}function Ne(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function Be(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function De(e){let n=e.userActivation;return typeof(n==null?void 0:n.isActive)=="boolean"?n.isActive:void 0}function Le(e,n,t){var o;if(e)try{let r=e,a=r.response,p={id:G(r.id),rawId:X(r.rawId),type:G(r.type),authenticatorAttachment:G(r.authenticatorAttachment),response:n==="create"?{clientDataJSON:X(a==null?void 0:a.clientDataJSON),attestationObject:X(a==null?void 0:a.attestationObject),transports:ae((o=a==null?void 0:a.getTransports)==null?void 0:o.call(a))}:{clientDataJSON:X(a==null?void 0:a.clientDataJSON),authenticatorData:X(a==null?void 0:a.authenticatorData),signature:X(a==null?void 0:a.signature),userHandle:X(a==null?void 0:a.userHandle)},...n==="create"?He(r):{}};return JSON.stringify(p)}catch(r){t.log("credential serialization failed",r);return}}function Te(e,n){try{let t={},o=G(e.rpId),r=G(e.userVerification),a=ae(e.hints);return o!==void 0&&(t.rpId=o),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(t.timeout=e.timeout),r!==void 0&&(t.userVerification=r),a!==void 0&&(t.hints=a),t.challenge=X(e.challenge),Array.isArray(e.allowCredentials)&&(t.allowCredentials=je(e.allowCredentials)),JSON.stringify(t)}catch(t){n.log("request options serialization failed",t);return}}function je(e){let n=[];for(let t of e){if(!Z(t))continue;let o=t;n.push({type:G(o.type),id:X(o.id),transports:ae(o.transports)})}return n}function ae(e){if(Array.isArray(e))return e.filter(n=>typeof n=="string")}function G(e){return typeof e=="string"?e:void 0}function He(e){var o;let n=(o=e.getClientExtensionResults)==null?void 0:o.call(e);if(!Z(n))return{};let t=n.credProps;return!t||typeof t.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:t.rk}}}}function X(e){let n;if(e instanceof ArrayBuffer)n=new Uint8Array(e);else if(ArrayBuffer.isView(e))n=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let t="";for(let o of n)t+=String.fromCharCode(o);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Z(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function Me(e){return e instanceof DOMException?e.name:"UnknownError"}var le=0;function pe(){return le+=1,`network-${le}`}function Ie(e,n){let t=e.responseType;if(t===""||t==="text")return n(e.responseText);if(t==="json"){let o=e.response;return o==null?void 0:n(o)}}var We=500,fe=Symbol("body-read-timeout");function he(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function ye(e,n){let t=e.body;if(!t)return;let o=t.getReader(),r;try{let a=new Promise(R=>{r=setTimeout(()=>R(fe),We)}),p=new TextDecoder,w=[];for(;;){let R=await Promise.race([o.read(),a]);if(R===fe){n.log("body omitted: read timed out"),o.cancel().catch(()=>{});return}if(R.done)break;w.push(p.decode(R.value,{stream:!0}))}return w.push(p.decode()),w.join("")}catch{o.cancel().catch(()=>{});return}finally{r!==void 0&&clearTimeout(r)}}function ie(e){var n;(n=e==null?void 0:e.body)==null||n.cancel().catch(()=>{})}function ge(e){var y,g,W;let{onExchange:n,onRequest:t,match:o}=e;if(typeof n!="function"||typeof o!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let r=K(e.logger),a=(y=e.transports)!=null?y:["xhr","fetch"],p=(g=e.bodyCapture)==null?void 0:g.request,w=(W=e.bodyCapture)==null?void 0:W.response,R=typeof p=="function",I=typeof w=="function",q=!1,N=J(r,"network",u=>{if(q)return n(u)}),U=J(r,"network request",u=>{if(q)return t==null?void 0:t(u)}),D=(u,d,f)=>{if(typeof f=="function")try{return f(u,d)}catch(s){r.log("body projection failed",s);return}},L=(u,d)=>{try{let f=typeof document!="undefined"?document.baseURI:void 0,s=new URL(String(u),f);return o(s,d)===!0?{url:s.href,path:s.pathname}:void 0}catch{return}},E=()=>{if(typeof XMLHttpRequest=="undefined")return r.log("xhr capture unavailable: XMLHttpRequest missing"),null;let u=XMLHttpRequest.prototype,d=Object.getOwnPropertyDescriptor(u,"open"),f=Object.getOwnPropertyDescriptor(u,"send");if(!d||!("value"in d)||typeof d.value!="function"||!f||!("value"in f)||typeof f.value!="function")return r.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let s=d.value,v=f.value;if(M(s)||M(v))return r.log("xhr capture unavailable: an equivalent capture is already active"),null;let C=new WeakMap,h=new Set,A=!1,x={open(...k){var b;let i=Reflect.apply(s,this,k);if(!q||!A)return i;try{let S=C.get(this);S&&(S.reported=!0,(b=S.cleanupListeners)==null||b.call(S));let T=String(k[0]).toUpperCase(),P=L(k[1],T);P?C.set(this,{method:T,url:P.url,path:P.path,reported:!1}):C.delete(this)}catch(S){r.log("xhr open observation failed",S)}return i}}.open,O={send(...k){let i=q&&A?C.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(v,this,k);let b=()=>{},S=!1;try{i.requestId=pe();let P={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=R&&typeof k[0]=="string"?D(k[0],P,p):void 0;let Y=()=>{i.outcome===void 0&&(i.outcome="abort")},Q=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},m=()=>{var V;b();try{if(!q||!A||i.reported||!i.requestId)return;i.reported=!0;let H={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},ne=this.status,se={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:ne,ok:ne>=200&&ne<300,outcome:(V=i.outcome)!=null?V:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:I?Ie(this,Ce=>D(Ce,H,w)):void 0};i.requestEmitted?N(se):i.pendingExchange=se}catch(H){r.log("xhr exchange observation failed",H)}finally{C.get(this)===i&&C.delete(this)}},j=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&m()}catch(V){r.log("xhr ready-state observation failed",V)}},_=()=>m();b=()=>{for(let[V,H]of[["readystatechange",j],["abort",Y],["timeout",Q],["error",l],["loadend",_]])this.removeEventListener(V,H);i.cleanupListeners===b&&(i.cleanupListeners=void 0),h.delete(b)},this.addEventListener("readystatechange",j),this.addEventListener("abort",Y),this.addEventListener("timeout",Q),this.addEventListener("error",l),this.addEventListener("loadend",_),i.cleanupListeners=b,h.add(b),i.startedAt=Date.now(),S=!0}catch(P){r.log("xhr send observation failed",P),b()}let T;try{T=Reflect.apply(v,this,k)}catch(P){throw b(),P}if(S&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,U({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let P=i.pendingExchange;i.pendingExchange=void 0,P&&N(P)}return T}}.send;return F(x,s),F(O,v),d.writable!==!0||f.writable!==!0?(r.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(u,"open",{...d,value:x}),Object.defineProperty(u,"send",{...f,value:O}),A=!0,()=>{A=!1;for(let k of[...h])k();z(u,"open",x,d,r),z(u,"send",O,f,r)})},$=()=>{let u=globalThis,d=Object.getOwnPropertyDescriptor(u,"fetch");if(!d||!("value"in d))return r.log("fetch capture unavailable: fetch is not an own data property"),null;let f=d.value;if(typeof f!="function")return r.log("fetch capture unavailable: fetch missing"),null;if(M(f))return r.log("fetch capture unavailable: an equivalent capture is already active"),null;let s=!1,v=async(h,A,x,O)=>{try{if(!q||!s){ie(x);return}let[k,i]=await Promise.all([O!=null?O:Promise.resolve(void 0),x?ye(x,r):Promise.resolve(void 0)]);if(!q||!s)return;let b={direction:"request",transport:"fetch",method:h.method,url:h.url,path:h.path},S={...b,direction:"response"},T=h.requestBody;T===void 0&&k!==void 0&&(T=D(k,b,p));let P=i!==void 0?D(i,S,w):void 0;N({requestId:h.requestId,transport:"fetch",method:h.method,url:h.url,path:h.path,status:A.status,ok:A.ok,outcome:"load",durationMs:Date.now()-h.startedAt,responseUrl:A.url||void 0,requestBody:T,responseBody:P})}catch(k){r.log("fetch exchange observation failed",k)}},C={fetch(...h){var T,P,Y,Q;let A;try{let l=h[0],m=h[1];if(q&&s&&R&&typeof Request!="undefined"&&l instanceof Request&&(m==null?void 0:m.body)===void 0&&l.body){let j=String((T=m==null?void 0:m.method)!=null?T:l.method).toUpperCase(),_=(P=l.headers.get("content-type"))!=null?P:"";L(l.url,j)&&he(_)&&(A=l.clone())}}catch(l){r.log("fetch observation failed",l)}let x,O=Date.now();try{x=Reflect.apply(f,this,h)}catch(l){throw ie(A),l}let k,i;try{if(q&&s){let l=h[0],m=h[1],j=typeof Request!="undefined"&&l instanceof Request,_=String((Y=m==null?void 0:m.method)!=null?Y:j?l.method:"GET").toUpperCase(),V=j?l.url:l,H=L(V,_);H&&(k={requestId:pe(),method:_,url:H.url,path:H.path,startedAt:O},i=(Q=m==null?void 0:m.signal)!=null?Q:j?l.signal:void 0,R&&typeof(m==null?void 0:m.body)=="string"&&(k.requestBody=D(m.body,{direction:"request",transport:"fetch",method:_,url:H.url,path:H.path},p)))}}catch(l){r.log("fetch observation failed",l)}if(!k)return ie(A),x;let b=k;U({requestId:b.requestId,transport:"fetch",method:b.method,url:b.url,path:b.path,startedAt:b.startedAt,requestBody:b.requestBody});let S=A?ye(A,r):void 0;return x.then(l=>{var j;let m;try{if(q&&s&&I){let _=(j=l.headers.get("content-type"))!=null?j:"";he(_)&&l.body&&(m=l.clone())}}catch{}v(b,l,m,S)},l=>{try{if(!q||!s)return;let m=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;N({requestId:b.requestId,transport:"fetch",method:b.method,url:b.url,path:b.path,status:0,ok:!1,outcome:m?"abort":"error",durationMs:Date.now()-b.startedAt})}catch(m){r.log("fetch failure observation failed",m)}}),x}}.fetch;return F(C,f),d.writable!==!0?(r.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(u,"fetch",{...d,value:C}),s=!0,()=>{s=!1,z(u,"fetch",C,d,r)})},c=[];if(a.includes("xhr")){let u=E();u&&c.push(u)}if(a.includes("fetch")){let u=$();u&&c.push(u)}return c.length===0?B():(q=!0,{mode:"standard",disconnect:()=>{q=!1;for(let u of c.splice(0))u()}})}function ve(e){let n=e.onNavigate;if(typeof n!="function")throw new TypeError("captureNavigation requires an onNavigate callback");let t=K(e.logger),o,r,a,p,w,R;try{if(o=window,r=o==null?void 0:o.history,!o||!r)return t.log("navigation capture unavailable: window/history missing"),B();if(w=be(r,"pushState"),R=be(r,"replaceState"),!w||!R)return t.log("navigation capture unavailable: history method descriptors missing"),B();if(a=w.descriptor.value,p=R.descriptor.value,typeof a!="function"||typeof p!="function")return t.log("navigation capture unavailable: history methods missing"),B();if(typeof o.addEventListener!="function"||typeof o.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),B()}catch(y){return t.log("navigation capture unavailable: history inspection failed",y),B()}if(M(a)||M(p))return t.log("navigation capture unavailable: an equivalent capture is already active"),B();let I=!1,q=()=>({path:o.location.pathname,search:o.location.search,hash:o.location.hash}),N;try{N=q()}catch(y){return t.log("navigation capture unavailable: location inspection failed",y),B()}let U=J(t,"navigation",y=>{if(I)return n(y)}),D=y=>{if(I)try{let g=q();if(g.path===N.path&&g.search===N.search&&g.hash===N.hash)return;N=g,U({...g,source:y})}catch(g){t.log("navigation observation failed",g)}},L={pushState(...y){let g=Reflect.apply(a,this,y);return D("push"),g}}.pushState,E={replaceState(...y){let g=Reflect.apply(p,this,y);return D("replace"),g}}.replaceState;F(L,a),F(E,p);let $=()=>D("pop"),c=()=>D("hash");try{if(me(w,L),me(R,E),r.pushState!==L||r.replaceState!==E)throw new Error("history method replacement did not take effect");o.addEventListener("popstate",$),o.addEventListener("hashchange",c),I=!0}catch(y){return I=!1,te(o,"popstate",$,t),te(o,"hashchange",c,t),ee(R,E,t),ee(w,L,t),t.log("navigation capture unavailable: history methods are not writable",y),n=()=>{},U=()=>{},t=K(),B()}return{mode:"standard",disconnect:()=>{I=!1,n=()=>{},te(o,"popstate",$,t),te(o,"hashchange",c,t),ee(w,L,t),ee(R,E,t),U=()=>{},t=K()}}}function be(e,n){let t=e;for(;t;){let o=Object.getOwnPropertyDescriptor(t,n);if(o)return!("value"in o)||typeof o.value!="function"?null:{owner:t,key:n,descriptor:o};t=Object.getPrototypeOf(t)}return null}function me(e,n){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let t=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!oe(t,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:n})}function ee(e,n,t){z(e.owner,e.key,n,e.descriptor,t,`navigation ${e.key}`)}function te(e,n,t,o){try{e.removeEventListener(n,t)}catch(r){o.log(`navigation ${n} listener removal skipped`,r)}}function we(e){let n=e.composedPath();return n.length>0?n:e.target?[e.target]:[]}var Re="0.4.0";0&&(module.exports={VERSION,captureNavigation,captureNetwork,captureWebAuthn,composedPath});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var ge={log:()=>{}};function F(e){return e?{log:(...n)=>{try{let t=e.log(...n);if(t&&(typeof t=="object"||typeof t=="function"))try{Promise.resolve(t).catch(()=>{})}catch{}}catch{}}}:ge}var se=Symbol.for("corbado.autocapture.installed");function U(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,se)}catch{return!1}}function X(e,n){var r,o;let t=n;try{Object.defineProperty(e,se,{value:n,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(r=t.name)!=null?r:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(o=t.length)!=null?o:0,configurable:!0})}catch{}return e}function O(){return{mode:"unavailable",disconnect:()=>{}}}function re(e,n){return!!e&&"value"in e&&"value"in n&&e.value===n.value&&e.writable===n.writable&&e.enumerable===n.enumerable&&e.configurable===n.configurable}function J(e,n,t,r,o,i=String(n)){try{let c=Object.getOwnPropertyDescriptor(e,n);re(c,{...r,value:t})&&Object.defineProperty(e,n,r)}catch(c){o.log(`${i} restoration skipped`,c)}}function $(e,n,t){let r=F(e);return o=>{try{let i=t(o);if(i&&(typeof i=="object"||typeof i=="function"))try{Promise.resolve(i).catch(c=>r.log(`${n} listener failed`,c))}catch(c){r.log(`${n} listener failed`,c)}}catch(i){r.log(`${n} listener failed`,i)}}}function me(e){let n=e.onEvent;if(typeof n!="function")throw new TypeError("captureWebAuthn requires an onEvent callback");let t=F(e.logger),r=typeof navigator=="undefined"?void 0:navigator,o=r==null?void 0:r.credentials;if(!r||!o)return t.log("webauthn capture unavailable: navigator.credentials missing"),O();let i=o.get,c=o.create;if(typeof i!="function"||typeof c!="function")return t.log("webauthn capture unavailable: credentials methods missing"),O();if(U(i)||U(c))return t.log("webauthn capture unavailable: an equivalent capture is already active"),O();let y=!1,C=0,B=$(t,"webauthn",h=>{if(y)return n(h)}),k=(h,D)=>{let I={invoke(...q){let v=this,g=q[0];if(!y||!Z(g)||!Z(g.publicKey))return Reflect.apply(D,v,q);let G=g.publicKey,u=`wa-${++C}`,m=Reflect.apply(D,v,q),p=Z(g.signal)?g.signal:void 0,f=be(h,g,G),_={...f,ceremonyId:u,phase:"started",userActivation:Re(r)};if(f.kind==="authentication"){let w=G;_.requestOptionsJson=ke(w,t)}return B(_),Promise.resolve(m).then(w=>(y&&B({...f,ceremonyId:u,phase:"completed",credentialJson:Ce(w,h,t),...(p==null?void 0:p.aborted)===!0?{aborted:!0}:{}}),w),w=>{throw y&&B({...f,ceremonyId:u,phase:"failed",error:w,errorName:Oe(w),...(p==null?void 0:p.aborted)===!0?{aborted:!0}:{}}),w})}}.invoke;return X(I,{name:h,length:0})},x=(h,D)=>{let I=k(h,D),q=Object.getOwnPropertyDescriptor(o,h);if(q&&(!("value"in q)||q.writable!==!0))return null;try{o[h]=I}catch{return null}return()=>{o[h]===I&&(q?o[h]=q.value:delete o[h])}},S=x("get",i),N=S?x("create",c):null;return!S||!N?(S==null||S(),t.log("webauthn capture unavailable: credentials methods cannot be patched safely"),O()):(y=!0,{mode:"standard",disconnect:()=>{y=!1,S(),N()}})}function be(e,n,t){let r=ve(n.mediation);if(e==="create")return{kind:"registration",mediation:r};let o=t;return{kind:"authentication",mediation:r,uiMode:we(n.uiMode),credentialSet:Array.isArray(o.allowCredentials)&&o.allowCredentials.length>0?"allowlisted":"discoverable"}}function ve(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function we(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function Re(e){let n=e.userActivation;return typeof(n==null?void 0:n.isActive)=="boolean"?n.isActive:void 0}function Ce(e,n,t){var r;if(e)try{let o=e,i=o.response,c={id:z(o.id),rawId:K(o.rawId),type:z(o.type),authenticatorAttachment:z(o.authenticatorAttachment),response:n==="create"?{clientDataJSON:K(i==null?void 0:i.clientDataJSON),attestationObject:K(i==null?void 0:i.attestationObject),transports:oe((r=i==null?void 0:i.getTransports)==null?void 0:r.call(i))}:{clientDataJSON:K(i==null?void 0:i.clientDataJSON),authenticatorData:K(i==null?void 0:i.authenticatorData),signature:K(i==null?void 0:i.signature),userHandle:K(i==null?void 0:i.userHandle)},...n==="create"?Ae(o):{}};return JSON.stringify(c)}catch(o){t.log("credential serialization failed",o);return}}function ke(e,n){try{let t={},r=z(e.rpId),o=z(e.userVerification),i=oe(e.hints);return r!==void 0&&(t.rpId=r),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(t.timeout=e.timeout),o!==void 0&&(t.userVerification=o),i!==void 0&&(t.hints=i),t.challenge=K(e.challenge),Array.isArray(e.allowCredentials)&&(t.allowCredentials=qe(e.allowCredentials)),JSON.stringify(t)}catch(t){n.log("request options serialization failed",t);return}}function qe(e){let n=[];for(let t of e){if(!Z(t))continue;let r=t;n.push({type:z(r.type),id:K(r.id),transports:oe(r.transports)})}return n}function oe(e){if(Array.isArray(e))return e.filter(n=>typeof n=="string")}function z(e){return typeof e=="string"?e:void 0}function Ae(e){var r;let n=(r=e.getClientExtensionResults)==null?void 0:r.call(e);if(!Z(n))return{};let t=n.credProps;return!t||typeof t.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:t.rk}}}}function K(e){let n;if(e instanceof ArrayBuffer)n=new Uint8Array(e);else if(ArrayBuffer.isView(e))n=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let t="";for(let r of n)t+=String.fromCharCode(r);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Z(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function Oe(e){return e instanceof DOMException?e.name:"UnknownError"}var ue=0;function ce(){return ue+=1,`network-${ue}`}function Ee(e,n){let t=e.responseType;if(t===""||t==="text")return n(e.responseText);if(t==="json"){let r=e.response;return r==null?void 0:n(r)}}var Pe=500,de=Symbol("body-read-timeout");function le(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function pe(e,n){let t=e.body;if(!t)return;let r=t.getReader(),o;try{let i=new Promise(C=>{o=setTimeout(()=>C(de),Pe)}),c=new TextDecoder,y=[];for(;;){let C=await Promise.race([r.read(),i]);if(C===de){n.log("body omitted: read timed out"),r.cancel().catch(()=>{});return}if(C.done)break;y.push(c.decode(C.value,{stream:!0}))}return y.push(c.decode()),y.join("")}catch{r.cancel().catch(()=>{});return}finally{o!==void 0&&clearTimeout(o)}}function ae(e){var n;(n=e==null?void 0:e.body)==null||n.cancel().catch(()=>{})}function xe(e){var v,g,G;let{onExchange:n,onRequest:t,match:r}=e;if(typeof n!="function"||typeof r!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let o=F(e.logger),i=(v=e.transports)!=null?v:["xhr","fetch"],c=(g=e.bodyCapture)==null?void 0:g.request,y=(G=e.bodyCapture)==null?void 0:G.response,C=typeof c=="function",B=typeof y=="function",k=!1,x=$(o,"network",u=>{if(k)return n(u)}),S=$(o,"network request",u=>{if(k)return t==null?void 0:t(u)}),N=(u,m,p)=>{if(typeof p=="function")try{return p(u,m)}catch(f){o.log("body projection failed",f);return}},h=(u,m)=>{try{let p=typeof document!="undefined"?document.baseURI:void 0,f=new URL(String(u),p);return r(f,m)===!0?{url:f.href,path:f.pathname}:void 0}catch{return}},D=()=>{if(typeof XMLHttpRequest=="undefined")return o.log("xhr capture unavailable: XMLHttpRequest missing"),null;let u=XMLHttpRequest.prototype,m=Object.getOwnPropertyDescriptor(u,"open"),p=Object.getOwnPropertyDescriptor(u,"send");if(!m||!("value"in m)||typeof m.value!="function"||!p||!("value"in p)||typeof p.value!="function")return o.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let f=m.value,_=p.value;if(U(f)||U(_))return o.log("xhr capture unavailable: an equivalent capture is already active"),null;let w=new WeakMap,R=new Set,E=!1,L={open(...b){var d;let a=Reflect.apply(f,this,b);if(!k||!E)return a;try{let P=w.get(this);P&&(P.reported=!0,(d=P.cleanupListeners)==null||d.call(P));let T=String(b[0]).toUpperCase(),A=h(b[1],T);A?w.set(this,{method:T,url:A.url,path:A.path,reported:!1}):w.delete(this)}catch(P){o.log("xhr open observation failed",P)}return a}}.open,W={send(...b){let a=k&&E?w.get(this):void 0;if(!a||a.reported||a.cleanupListeners)return Reflect.apply(_,this,b);let d=()=>{},P=!1;try{a.requestId=ce();let A={direction:"request",transport:"xhr",method:a.method,url:a.url,path:a.path};a.requestBody=C&&typeof b[0]=="string"?N(b[0],A,c):void 0;let Y=()=>{a.outcome===void 0&&(a.outcome="abort")},Q=()=>{a.outcome===void 0&&(a.outcome="timeout")},s=()=>{a.outcome===void 0&&(a.outcome="error")},l=()=>{var V;d();try{if(!k||!E||a.reported||!a.requestId)return;a.reported=!0;let H={direction:"response",transport:"xhr",method:a.method,url:a.url,path:a.path},ne=this.status,ie={requestId:a.requestId,transport:"xhr",method:a.method,url:a.url,path:a.path,status:ne,ok:ne>=200&&ne<300,outcome:(V=a.outcome)!=null?V:"load",durationMs:a.startedAt!==void 0?Date.now()-a.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:a.requestBody,responseBody:B?Ee(this,ye=>N(ye,H,y)):void 0};a.requestEmitted?x(ie):a.pendingExchange=ie}catch(H){o.log("xhr exchange observation failed",H)}finally{w.get(this)===a&&w.delete(this)}},j=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&l()}catch(V){o.log("xhr ready-state observation failed",V)}},M=()=>l();d=()=>{for(let[V,H]of[["readystatechange",j],["abort",Y],["timeout",Q],["error",s],["loadend",M]])this.removeEventListener(V,H);a.cleanupListeners===d&&(a.cleanupListeners=void 0),R.delete(d)},this.addEventListener("readystatechange",j),this.addEventListener("abort",Y),this.addEventListener("timeout",Q),this.addEventListener("error",s),this.addEventListener("loadend",M),a.cleanupListeners=d,R.add(d),a.startedAt=Date.now(),P=!0}catch(A){o.log("xhr send observation failed",A),d()}let T;try{T=Reflect.apply(_,this,b)}catch(A){throw d(),A}if(P&&a.requestId!==void 0&&a.startedAt!==void 0){a.requestEmitted=!0,S({requestId:a.requestId,transport:"xhr",method:a.method,url:a.url,path:a.path,startedAt:a.startedAt,requestBody:a.requestBody});let A=a.pendingExchange;a.pendingExchange=void 0,A&&x(A)}return T}}.send;return X(L,f),X(W,_),m.writable!==!0||p.writable!==!0?(o.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(u,"open",{...m,value:L}),Object.defineProperty(u,"send",{...p,value:W}),E=!0,()=>{E=!1;for(let b of[...R])b();J(u,"open",L,m,o),J(u,"send",W,p,o)})},I=()=>{let u=globalThis,m=Object.getOwnPropertyDescriptor(u,"fetch");if(!m||!("value"in m))return o.log("fetch capture unavailable: fetch is not an own data property"),null;let p=m.value;if(typeof p!="function")return o.log("fetch capture unavailable: fetch missing"),null;if(U(p))return o.log("fetch capture unavailable: an equivalent capture is already active"),null;let f=!1,_=async(R,E,L,W)=>{try{if(!k||!f){ae(L);return}let[b,a]=await Promise.all([W!=null?W:Promise.resolve(void 0),L?pe(L,o):Promise.resolve(void 0)]);if(!k||!f)return;let d={direction:"request",transport:"fetch",method:R.method,url:R.url,path:R.path},P={...d,direction:"response"},T=R.requestBody;T===void 0&&b!==void 0&&(T=N(b,d,c));let A=a!==void 0?N(a,P,y):void 0;x({requestId:R.requestId,transport:"fetch",method:R.method,url:R.url,path:R.path,status:E.status,ok:E.ok,outcome:"load",durationMs:Date.now()-R.startedAt,responseUrl:E.url||void 0,requestBody:T,responseBody:A})}catch(b){o.log("fetch exchange observation failed",b)}},w={fetch(...R){var T,A,Y,Q;let E;try{let s=R[0],l=R[1];if(k&&f&&C&&typeof Request!="undefined"&&s instanceof Request&&(l==null?void 0:l.body)===void 0&&s.body){let j=String((T=l==null?void 0:l.method)!=null?T:s.method).toUpperCase(),M=(A=s.headers.get("content-type"))!=null?A:"";h(s.url,j)&&le(M)&&(E=s.clone())}}catch(s){o.log("fetch observation failed",s)}let L,W=Date.now();try{L=Reflect.apply(p,this,R)}catch(s){throw ae(E),s}let b,a;try{if(k&&f){let s=R[0],l=R[1],j=typeof Request!="undefined"&&s instanceof Request,M=String((Y=l==null?void 0:l.method)!=null?Y:j?s.method:"GET").toUpperCase(),V=j?s.url:s,H=h(V,M);H&&(b={requestId:ce(),method:M,url:H.url,path:H.path,startedAt:W},a=(Q=l==null?void 0:l.signal)!=null?Q:j?s.signal:void 0,C&&typeof(l==null?void 0:l.body)=="string"&&(b.requestBody=N(l.body,{direction:"request",transport:"fetch",method:M,url:H.url,path:H.path},c)))}}catch(s){o.log("fetch observation failed",s)}if(!b)return ae(E),L;let d=b;S({requestId:d.requestId,transport:"fetch",method:d.method,url:d.url,path:d.path,startedAt:d.startedAt,requestBody:d.requestBody});let P=E?pe(E,o):void 0;return L.then(s=>{var j;let l;try{if(k&&f&&B){let M=(j=s.headers.get("content-type"))!=null?j:"";le(M)&&s.body&&(l=s.clone())}}catch{}_(d,s,l,P)},s=>{try{if(!k||!f)return;let l=(a==null?void 0:a.aborted)===!0||(s==null?void 0:s.name)==="AbortError"||typeof DOMException!="undefined"&&s instanceof DOMException&&s.code===DOMException.ABORT_ERR;x({requestId:d.requestId,transport:"fetch",method:d.method,url:d.url,path:d.path,status:0,ok:!1,outcome:l?"abort":"error",durationMs:Date.now()-d.startedAt})}catch(l){o.log("fetch failure observation failed",l)}}),L}}.fetch;return X(w,p),m.writable!==!0?(o.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(u,"fetch",{...m,value:w}),f=!0,()=>{f=!1,J(u,"fetch",w,m,o)})},q=[];if(i.includes("xhr")){let u=D();u&&q.push(u)}if(i.includes("fetch")){let u=I();u&&q.push(u)}return q.length===0?O():(k=!0,{mode:"standard",disconnect:()=>{k=!1;for(let u of q.splice(0))u()}})}function Se(e){let n=e.onNavigate;if(typeof n!="function")throw new TypeError("captureNavigation requires an onNavigate callback");let t=F(e.logger),r,o,i,c,y,C;try{if(r=window,o=r==null?void 0:r.history,!r||!o)return t.log("navigation capture unavailable: window/history missing"),O();if(y=fe(o,"pushState"),C=fe(o,"replaceState"),!y||!C)return t.log("navigation capture unavailable: history method descriptors missing"),O();if(i=y.descriptor.value,c=C.descriptor.value,typeof i!="function"||typeof c!="function")return t.log("navigation capture unavailable: history methods missing"),O();if(typeof r.addEventListener!="function"||typeof r.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),O()}catch(v){return t.log("navigation capture unavailable: history inspection failed",v),O()}if(U(i)||U(c))return t.log("navigation capture unavailable: an equivalent capture is already active"),O();let B=!1,k=()=>({path:r.location.pathname,search:r.location.search,hash:r.location.hash}),x;try{x=k()}catch(v){return t.log("navigation capture unavailable: location inspection failed",v),O()}let S=$(t,"navigation",v=>{if(B)return n(v)}),N=v=>{if(B)try{let g=k();if(g.path===x.path&&g.search===x.search&&g.hash===x.hash)return;x=g,S({...g,source:v})}catch(g){t.log("navigation observation failed",g)}},h={pushState(...v){let g=Reflect.apply(i,this,v);return N("push"),g}}.pushState,D={replaceState(...v){let g=Reflect.apply(c,this,v);return N("replace"),g}}.replaceState;X(h,i),X(D,c);let I=()=>N("pop"),q=()=>N("hash");try{if(he(y,h),he(C,D),o.pushState!==h||o.replaceState!==D)throw new Error("history method replacement did not take effect");r.addEventListener("popstate",I),r.addEventListener("hashchange",q),B=!0}catch(v){return B=!1,te(r,"popstate",I,t),te(r,"hashchange",q,t),ee(C,D,t),ee(y,h,t),t.log("navigation capture unavailable: history methods are not writable",v),n=()=>{},S=()=>{},t=F(),O()}return{mode:"standard",disconnect:()=>{B=!1,n=()=>{},te(r,"popstate",I,t),te(r,"hashchange",q,t),ee(y,h,t),ee(C,D,t),S=()=>{},t=F()}}}function fe(e,n){let t=e;for(;t;){let r=Object.getOwnPropertyDescriptor(t,n);if(r)return!("value"in r)||typeof r.value!="function"?null:{owner:t,key:n,descriptor:r};t=Object.getPrototypeOf(t)}return null}function he(e,n){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let t=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!re(t,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:n})}function ee(e,n,t){J(e.owner,e.key,n,e.descriptor,t,`navigation ${e.key}`)}function te(e,n,t,r){try{e.removeEventListener(n,t)}catch(o){r.log(`navigation ${n} listener removal skipped`,o)}}function Ne(e){let n=e.composedPath();return n.length>0?n:e.target?[e.target]:[]}var Be="0.3.0";export{Be as VERSION,Se as captureNavigation,xe as captureNetwork,me as captureWebAuthn,Ne as composedPath};
1
+ var be={log:()=>{}};function K(e){return e?{log:(...n)=>{try{let t=e.log(...n);if(t&&(typeof t=="object"||typeof t=="function"))try{Promise.resolve(t).catch(()=>{})}catch{}}catch{}}}:be}var se=Symbol.for("corbado.autocapture.installed");function M(e){try{return typeof e=="function"&&Object.prototype.hasOwnProperty.call(e,se)}catch{return!1}}function F(e,n){var o,r;let t=n;try{Object.defineProperty(e,se,{value:n,configurable:!0})}catch{}try{Object.defineProperty(e,"name",{value:(o=t.name)!=null?o:"",configurable:!0})}catch{}try{Object.defineProperty(e,"length",{value:(r=t.length)!=null?r:0,configurable:!0})}catch{}return e}function B(){return{mode:"unavailable",disconnect:()=>{}}}function re(e,n){return!!e&&"value"in e&&"value"in n&&e.value===n.value&&e.writable===n.writable&&e.enumerable===n.enumerable&&e.configurable===n.configurable}function z(e,n,t,o,r,a=String(n)){try{let p=Object.getOwnPropertyDescriptor(e,n);re(p,{...o,value:t})&&Object.defineProperty(e,n,o)}catch(p){r.log(`${a} restoration skipped`,p)}}function J(e,n,t){let o=K(e);return r=>{try{let a=t(r);if(a&&(typeof a=="object"||typeof a=="function"))try{Promise.resolve(a).catch(p=>o.log(`${n} listener failed`,p))}catch(p){o.log(`${n} listener failed`,p)}}catch(a){o.log(`${n} listener failed`,a)}}}var ue=e=>({get:e("get"),create:e("create")});function me(e){let n=e.onEvent;if(typeof n!="function")throw new TypeError("captureWebAuthn requires an onEvent callback");let t=K(e.logger),o=c=>(t.log(`webauthn capture unavailable: ${c}`),{...B(),surface:"none"}),r=typeof navigator=="undefined"?void 0:navigator,a=r==null?void 0:r.credentials;if(!r||!a)return o("navigator.credentials missing");let p=a,w=ue(c=>p[c]);if(typeof w.get!="function"||typeof w.create!="function")return o("credentials methods missing");if(M(w.get)||M(w.create))return o("an equivalent capture is already active");let R=!1,I=0,q=J(t,"webauthn",n),N=(c,y,g)=>{let W={invoke(...u){let d=u[0];if(!R||g!=null&&g()||!Z(d)||!Z(d.publicKey))return y(this,u);let f=d.publicKey,s=`wa-${++I}`,v=y(this,u),C=Z(d.signal)?d.signal:void 0,h=ve(c,d,f),A=O=>{R&&q({...h,ceremonyId:s,...O()})},x=()=>(C==null?void 0:C.aborted)===!0?{aborted:!0}:{};return A(()=>({phase:"started",userActivation:Ce(r),...h.kind==="authentication"?{requestOptionsJson:ke(f,t)}:{}})),Promise.resolve(v).then(O=>(A(()=>({phase:"completed",credentialJson:Ae(O,c,t),...x()})),O),O=>{throw A(()=>({phase:"failed",error:O,errorName:Pe(O),...x()})),O})}}.invoke;return F(W,{name:c,length:0})},U=c=>{var W;let y=N(c,(u,d)=>Reflect.apply(w[c],u,d)),g=Object.getOwnPropertyDescriptor(a,c);if(g&&(!("value"in g)||g.writable!==!0))return null;try{p[c]=y}catch{return null}if(((W=Object.getOwnPropertyDescriptor(a,c))==null?void 0:W.value)!==y){try{p[c]=w[c]}catch{}return null}return()=>{p[c]===y&&(g?p[c]=g.value:delete p[c])}},D=()=>{let c=ue(()=>new WeakMap),y=(f,s)=>{let v=c[f].get(s);if(v)return v;let C=N(f,(h,A)=>Reflect.apply(s,a,A),()=>{let h=p[f];return h!==s&&h!==C});return c[f].set(s,C),C},g=f=>{let s=Object.getOwnPropertyDescriptor(a,f);return s?s.configurable===!0||!("value"in s)||s.writable===!0:!0},W=new WeakMap,u=new Proxy(a,{get(f,s){let v=Reflect.get(a,s,a);if((s==="get"||s==="create")&&g(s))return typeof v!="function"||M(v)?v:y(s,v);if(typeof v!="function"||!g(s)||s==="constructor")return v;let C=W.get(v);if(C)return C;let h=v.bind(a);return W.set(v,h),h},set(f,s,v){return Reflect.set(a,s,v,a)}}),d=Object.getOwnPropertyDescriptor(r,"credentials");if(d&&d.configurable!==!0)return null;try{Object.defineProperty(r,"credentials",{value:u,writable:!0,enumerable:!0,configurable:!0})}catch{return null}return r.credentials!==u?null:()=>{r.credentials===u&&(d?Object.defineProperty(r,"credentials",d):delete r.credentials)}},L=(c,y)=>(R=!0,{mode:"standard",surface:c,disconnect:()=>{R=!1,y()}}),E=U("get"),$=E?U("create"):null;if(E&&$)return L("methods",()=>{E(),$()});if(E==null||E(),e.attach==="container"){let c=D();if(c)return t.log("webauthn capture attached at the credentials container"),L("container",c)}return o("credentials methods cannot be patched safely")}function ve(e,n,t){let o=we(n.mediation);if(e==="create")return{kind:"registration",mediation:o};let r=t;return{kind:"authentication",mediation:o,uiMode:Re(n.uiMode),credentialSet:Array.isArray(r.allowCredentials)&&r.allowCredentials.length>0?"allowlisted":"discoverable"}}function we(e){return e===void 0?"optional":e==="silent"||e==="optional"||e==="conditional"||e==="required"?e:"unknown"}function Re(e){return e===void 0?"default":e==="immediate"?"immediate":"unknown"}function Ce(e){let n=e.userActivation;return typeof(n==null?void 0:n.isActive)=="boolean"?n.isActive:void 0}function Ae(e,n,t){var o;if(e)try{let r=e,a=r.response,p={id:G(r.id),rawId:X(r.rawId),type:G(r.type),authenticatorAttachment:G(r.authenticatorAttachment),response:n==="create"?{clientDataJSON:X(a==null?void 0:a.clientDataJSON),attestationObject:X(a==null?void 0:a.attestationObject),transports:oe((o=a==null?void 0:a.getTransports)==null?void 0:o.call(a))}:{clientDataJSON:X(a==null?void 0:a.clientDataJSON),authenticatorData:X(a==null?void 0:a.authenticatorData),signature:X(a==null?void 0:a.signature),userHandle:X(a==null?void 0:a.userHandle)},...n==="create"?Oe(r):{}};return JSON.stringify(p)}catch(r){t.log("credential serialization failed",r);return}}function ke(e,n){try{let t={},o=G(e.rpId),r=G(e.userVerification),a=oe(e.hints);return o!==void 0&&(t.rpId=o),typeof e.timeout=="number"&&Number.isFinite(e.timeout)&&(t.timeout=e.timeout),r!==void 0&&(t.userVerification=r),a!==void 0&&(t.hints=a),t.challenge=X(e.challenge),Array.isArray(e.allowCredentials)&&(t.allowCredentials=qe(e.allowCredentials)),JSON.stringify(t)}catch(t){n.log("request options serialization failed",t);return}}function qe(e){let n=[];for(let t of e){if(!Z(t))continue;let o=t;n.push({type:G(o.type),id:X(o.id),transports:oe(o.transports)})}return n}function oe(e){if(Array.isArray(e))return e.filter(n=>typeof n=="string")}function G(e){return typeof e=="string"?e:void 0}function Oe(e){var o;let n=(o=e.getClientExtensionResults)==null?void 0:o.call(e);if(!Z(n))return{};let t=n.credProps;return!t||typeof t.rk!="boolean"?{}:{clientExtensionResults:{credProps:{rk:t.rk}}}}function X(e){let n;if(e instanceof ArrayBuffer)n=new Uint8Array(e);else if(ArrayBuffer.isView(e))n=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);else return;let t="";for(let o of n)t+=String.fromCharCode(o);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Z(e){return e!==null&&(typeof e=="object"||typeof e=="function")}function Pe(e){return e instanceof DOMException?e.name:"UnknownError"}var ce=0;function de(){return ce+=1,`network-${ce}`}function xe(e,n){let t=e.responseType;if(t===""||t==="text")return n(e.responseText);if(t==="json"){let o=e.response;return o==null?void 0:n(o)}}var Ee=500,le=Symbol("body-read-timeout");function pe(e){return/event-stream|octet-stream/i.test(e)?!1:/json|text|urlencoded/i.test(e)}async function fe(e,n){let t=e.body;if(!t)return;let o=t.getReader(),r;try{let a=new Promise(R=>{r=setTimeout(()=>R(le),Ee)}),p=new TextDecoder,w=[];for(;;){let R=await Promise.race([o.read(),a]);if(R===le){n.log("body omitted: read timed out"),o.cancel().catch(()=>{});return}if(R.done)break;w.push(p.decode(R.value,{stream:!0}))}return w.push(p.decode()),w.join("")}catch{o.cancel().catch(()=>{});return}finally{r!==void 0&&clearTimeout(r)}}function ae(e){var n;(n=e==null?void 0:e.body)==null||n.cancel().catch(()=>{})}function Se(e){var y,g,W;let{onExchange:n,onRequest:t,match:o}=e;if(typeof n!="function"||typeof o!="function")throw new TypeError("captureNetwork requires onExchange and match callbacks");let r=K(e.logger),a=(y=e.transports)!=null?y:["xhr","fetch"],p=(g=e.bodyCapture)==null?void 0:g.request,w=(W=e.bodyCapture)==null?void 0:W.response,R=typeof p=="function",I=typeof w=="function",q=!1,N=J(r,"network",u=>{if(q)return n(u)}),U=J(r,"network request",u=>{if(q)return t==null?void 0:t(u)}),D=(u,d,f)=>{if(typeof f=="function")try{return f(u,d)}catch(s){r.log("body projection failed",s);return}},L=(u,d)=>{try{let f=typeof document!="undefined"?document.baseURI:void 0,s=new URL(String(u),f);return o(s,d)===!0?{url:s.href,path:s.pathname}:void 0}catch{return}},E=()=>{if(typeof XMLHttpRequest=="undefined")return r.log("xhr capture unavailable: XMLHttpRequest missing"),null;let u=XMLHttpRequest.prototype,d=Object.getOwnPropertyDescriptor(u,"open"),f=Object.getOwnPropertyDescriptor(u,"send");if(!d||!("value"in d)||typeof d.value!="function"||!f||!("value"in f)||typeof f.value!="function")return r.log("xhr capture unavailable: XMLHttpRequest methods missing"),null;let s=d.value,v=f.value;if(M(s)||M(v))return r.log("xhr capture unavailable: an equivalent capture is already active"),null;let C=new WeakMap,h=new Set,A=!1,x={open(...k){var b;let i=Reflect.apply(s,this,k);if(!q||!A)return i;try{let S=C.get(this);S&&(S.reported=!0,(b=S.cleanupListeners)==null||b.call(S));let T=String(k[0]).toUpperCase(),P=L(k[1],T);P?C.set(this,{method:T,url:P.url,path:P.path,reported:!1}):C.delete(this)}catch(S){r.log("xhr open observation failed",S)}return i}}.open,O={send(...k){let i=q&&A?C.get(this):void 0;if(!i||i.reported||i.cleanupListeners)return Reflect.apply(v,this,k);let b=()=>{},S=!1;try{i.requestId=de();let P={direction:"request",transport:"xhr",method:i.method,url:i.url,path:i.path};i.requestBody=R&&typeof k[0]=="string"?D(k[0],P,p):void 0;let Y=()=>{i.outcome===void 0&&(i.outcome="abort")},Q=()=>{i.outcome===void 0&&(i.outcome="timeout")},l=()=>{i.outcome===void 0&&(i.outcome="error")},m=()=>{var V;b();try{if(!q||!A||i.reported||!i.requestId)return;i.reported=!0;let H={direction:"response",transport:"xhr",method:i.method,url:i.url,path:i.path},ne=this.status,ie={requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,status:ne,ok:ne>=200&&ne<300,outcome:(V=i.outcome)!=null?V:"load",durationMs:i.startedAt!==void 0?Date.now()-i.startedAt:void 0,responseUrl:this.responseURL||void 0,requestBody:i.requestBody,responseBody:I?xe(this,ge=>D(ge,H,w)):void 0};i.requestEmitted?N(ie):i.pendingExchange=ie}catch(H){r.log("xhr exchange observation failed",H)}finally{C.get(this)===i&&C.delete(this)}},j=()=>{try{this.readyState===XMLHttpRequest.DONE&&this.status!==0&&m()}catch(V){r.log("xhr ready-state observation failed",V)}},_=()=>m();b=()=>{for(let[V,H]of[["readystatechange",j],["abort",Y],["timeout",Q],["error",l],["loadend",_]])this.removeEventListener(V,H);i.cleanupListeners===b&&(i.cleanupListeners=void 0),h.delete(b)},this.addEventListener("readystatechange",j),this.addEventListener("abort",Y),this.addEventListener("timeout",Q),this.addEventListener("error",l),this.addEventListener("loadend",_),i.cleanupListeners=b,h.add(b),i.startedAt=Date.now(),S=!0}catch(P){r.log("xhr send observation failed",P),b()}let T;try{T=Reflect.apply(v,this,k)}catch(P){throw b(),P}if(S&&i.requestId!==void 0&&i.startedAt!==void 0){i.requestEmitted=!0,U({requestId:i.requestId,transport:"xhr",method:i.method,url:i.url,path:i.path,startedAt:i.startedAt,requestBody:i.requestBody});let P=i.pendingExchange;i.pendingExchange=void 0,P&&N(P)}return T}}.send;return F(x,s),F(O,v),d.writable!==!0||f.writable!==!0?(r.log("xhr capture unavailable: XMLHttpRequest methods are not writable"),null):(Object.defineProperty(u,"open",{...d,value:x}),Object.defineProperty(u,"send",{...f,value:O}),A=!0,()=>{A=!1;for(let k of[...h])k();z(u,"open",x,d,r),z(u,"send",O,f,r)})},$=()=>{let u=globalThis,d=Object.getOwnPropertyDescriptor(u,"fetch");if(!d||!("value"in d))return r.log("fetch capture unavailable: fetch is not an own data property"),null;let f=d.value;if(typeof f!="function")return r.log("fetch capture unavailable: fetch missing"),null;if(M(f))return r.log("fetch capture unavailable: an equivalent capture is already active"),null;let s=!1,v=async(h,A,x,O)=>{try{if(!q||!s){ae(x);return}let[k,i]=await Promise.all([O!=null?O:Promise.resolve(void 0),x?fe(x,r):Promise.resolve(void 0)]);if(!q||!s)return;let b={direction:"request",transport:"fetch",method:h.method,url:h.url,path:h.path},S={...b,direction:"response"},T=h.requestBody;T===void 0&&k!==void 0&&(T=D(k,b,p));let P=i!==void 0?D(i,S,w):void 0;N({requestId:h.requestId,transport:"fetch",method:h.method,url:h.url,path:h.path,status:A.status,ok:A.ok,outcome:"load",durationMs:Date.now()-h.startedAt,responseUrl:A.url||void 0,requestBody:T,responseBody:P})}catch(k){r.log("fetch exchange observation failed",k)}},C={fetch(...h){var T,P,Y,Q;let A;try{let l=h[0],m=h[1];if(q&&s&&R&&typeof Request!="undefined"&&l instanceof Request&&(m==null?void 0:m.body)===void 0&&l.body){let j=String((T=m==null?void 0:m.method)!=null?T:l.method).toUpperCase(),_=(P=l.headers.get("content-type"))!=null?P:"";L(l.url,j)&&pe(_)&&(A=l.clone())}}catch(l){r.log("fetch observation failed",l)}let x,O=Date.now();try{x=Reflect.apply(f,this,h)}catch(l){throw ae(A),l}let k,i;try{if(q&&s){let l=h[0],m=h[1],j=typeof Request!="undefined"&&l instanceof Request,_=String((Y=m==null?void 0:m.method)!=null?Y:j?l.method:"GET").toUpperCase(),V=j?l.url:l,H=L(V,_);H&&(k={requestId:de(),method:_,url:H.url,path:H.path,startedAt:O},i=(Q=m==null?void 0:m.signal)!=null?Q:j?l.signal:void 0,R&&typeof(m==null?void 0:m.body)=="string"&&(k.requestBody=D(m.body,{direction:"request",transport:"fetch",method:_,url:H.url,path:H.path},p)))}}catch(l){r.log("fetch observation failed",l)}if(!k)return ae(A),x;let b=k;U({requestId:b.requestId,transport:"fetch",method:b.method,url:b.url,path:b.path,startedAt:b.startedAt,requestBody:b.requestBody});let S=A?fe(A,r):void 0;return x.then(l=>{var j;let m;try{if(q&&s&&I){let _=(j=l.headers.get("content-type"))!=null?j:"";pe(_)&&l.body&&(m=l.clone())}}catch{}v(b,l,m,S)},l=>{try{if(!q||!s)return;let m=(i==null?void 0:i.aborted)===!0||(l==null?void 0:l.name)==="AbortError"||typeof DOMException!="undefined"&&l instanceof DOMException&&l.code===DOMException.ABORT_ERR;N({requestId:b.requestId,transport:"fetch",method:b.method,url:b.url,path:b.path,status:0,ok:!1,outcome:m?"abort":"error",durationMs:Date.now()-b.startedAt})}catch(m){r.log("fetch failure observation failed",m)}}),x}}.fetch;return F(C,f),d.writable!==!0?(r.log("fetch capture unavailable: fetch is not writable"),null):(Object.defineProperty(u,"fetch",{...d,value:C}),s=!0,()=>{s=!1,z(u,"fetch",C,d,r)})},c=[];if(a.includes("xhr")){let u=E();u&&c.push(u)}if(a.includes("fetch")){let u=$();u&&c.push(u)}return c.length===0?B():(q=!0,{mode:"standard",disconnect:()=>{q=!1;for(let u of c.splice(0))u()}})}function Ne(e){let n=e.onNavigate;if(typeof n!="function")throw new TypeError("captureNavigation requires an onNavigate callback");let t=K(e.logger),o,r,a,p,w,R;try{if(o=window,r=o==null?void 0:o.history,!o||!r)return t.log("navigation capture unavailable: window/history missing"),B();if(w=he(r,"pushState"),R=he(r,"replaceState"),!w||!R)return t.log("navigation capture unavailable: history method descriptors missing"),B();if(a=w.descriptor.value,p=R.descriptor.value,typeof a!="function"||typeof p!="function")return t.log("navigation capture unavailable: history methods missing"),B();if(typeof o.addEventListener!="function"||typeof o.removeEventListener!="function")return t.log("navigation capture unavailable: window event methods missing"),B()}catch(y){return t.log("navigation capture unavailable: history inspection failed",y),B()}if(M(a)||M(p))return t.log("navigation capture unavailable: an equivalent capture is already active"),B();let I=!1,q=()=>({path:o.location.pathname,search:o.location.search,hash:o.location.hash}),N;try{N=q()}catch(y){return t.log("navigation capture unavailable: location inspection failed",y),B()}let U=J(t,"navigation",y=>{if(I)return n(y)}),D=y=>{if(I)try{let g=q();if(g.path===N.path&&g.search===N.search&&g.hash===N.hash)return;N=g,U({...g,source:y})}catch(g){t.log("navigation observation failed",g)}},L={pushState(...y){let g=Reflect.apply(a,this,y);return D("push"),g}}.pushState,E={replaceState(...y){let g=Reflect.apply(p,this,y);return D("replace"),g}}.replaceState;F(L,a),F(E,p);let $=()=>D("pop"),c=()=>D("hash");try{if(ye(w,L),ye(R,E),r.pushState!==L||r.replaceState!==E)throw new Error("history method replacement did not take effect");o.addEventListener("popstate",$),o.addEventListener("hashchange",c),I=!0}catch(y){return I=!1,te(o,"popstate",$,t),te(o,"hashchange",c,t),ee(R,E,t),ee(w,L,t),t.log("navigation capture unavailable: history methods are not writable",y),n=()=>{},U=()=>{},t=K(),B()}return{mode:"standard",disconnect:()=>{I=!1,n=()=>{},te(o,"popstate",$,t),te(o,"hashchange",c,t),ee(w,L,t),ee(R,E,t),U=()=>{},t=K()}}}function he(e,n){let t=e;for(;t;){let o=Object.getOwnPropertyDescriptor(t,n);if(o)return!("value"in o)||typeof o.value!="function"?null:{owner:t,key:n,descriptor:o};t=Object.getPrototypeOf(t)}return null}function ye(e,n){if(e.descriptor.writable!==!0)throw new TypeError(`${e.key} is not writable`);let t=Object.getOwnPropertyDescriptor(e.owner,e.key);if(!re(t,e.descriptor))throw new Error(`${e.key} changed during installation`);Object.defineProperty(e.owner,e.key,{...e.descriptor,value:n})}function ee(e,n,t){z(e.owner,e.key,n,e.descriptor,t,`navigation ${e.key}`)}function te(e,n,t,o){try{e.removeEventListener(n,t)}catch(r){o.log(`navigation ${n} listener removal skipped`,r)}}function Be(e){let n=e.composedPath();return n.length>0?n:e.target?[e.target]:[]}var De="0.4.0";export{De as VERSION,Ne as captureNavigation,Se as captureNetwork,me as captureWebAuthn,Be as composedPath};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corbado/autocapture",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Observer-style capture helpers for WebAuthn ceremonies, selected network exchanges, in-app navigation, and composed event paths.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",