intlayer-editor 7.3.12 → 7.3.13

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.
@@ -25116,19 +25116,19 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
25116
25116
  return { schedule, cancel, state, steps };
25117
25117
  }
25118
25118
  const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps } = /* @__PURE__ */ createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop$2, true);
25119
- let now;
25119
+ let now$2;
25120
25120
  function clearTime() {
25121
- now = void 0;
25121
+ now$2 = void 0;
25122
25122
  }
25123
25123
  const time$2 = {
25124
25124
  now: () => {
25125
- if (now === void 0) {
25125
+ if (now$2 === void 0) {
25126
25126
  time$2.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming ? frameData.timestamp : performance.now());
25127
25127
  }
25128
- return now;
25128
+ return now$2;
25129
25129
  },
25130
25130
  set: (newTime) => {
25131
- now = newTime;
25131
+ now$2 = newTime;
25132
25132
  queueMicrotask(clearTime);
25133
25133
  }
25134
25134
  };
@@ -37898,609 +37898,433 @@ const useOAuth2 = (intlayerConfiguration) => {
37898
37898
  });
37899
37899
  return { oAuth2AccessToken: data?.data };
37900
37900
  };
37901
- var __defProp = Object.defineProperty;
37902
- var __defProps = Object.defineProperties;
37903
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
37904
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
37905
- var __hasOwnProp = Object.prototype.hasOwnProperty;
37906
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
37907
- var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
37908
- var __spreadValues = (a2, b) => {
37909
- for (var prop in b || (b = {}))
37910
- if (__hasOwnProp.call(b, prop))
37911
- __defNormalProp(a2, prop, b[prop]);
37912
- if (__getOwnPropSymbols)
37913
- for (var prop of __getOwnPropSymbols(b)) {
37914
- if (__propIsEnum.call(b, prop))
37915
- __defNormalProp(a2, prop, b[prop]);
37916
- }
37917
- return a2;
37918
- };
37919
- var __spreadProps = (a2, b) => __defProps(a2, __getOwnPropDescs(b));
37920
- var BetterFetchError = class extends Error {
37921
- constructor(status, statusText, error) {
37922
- super(statusText || status.toString(), {
37923
- cause: error
37924
- });
37925
- this.status = status;
37926
- this.statusText = statusText;
37927
- this.error = error;
37928
- }
37929
- };
37930
- var initializePlugins = async (url, options) => {
37931
- var _a2, _b, _c, _d, _e2, _f;
37932
- let opts = options || {};
37933
- const hooks = {
37934
- onRequest: [options == null ? void 0 : options.onRequest],
37935
- onResponse: [options == null ? void 0 : options.onResponse],
37936
- onSuccess: [options == null ? void 0 : options.onSuccess],
37937
- onError: [options == null ? void 0 : options.onError],
37938
- onRetry: [options == null ? void 0 : options.onRetry]
37939
- };
37940
- if (!options || !(options == null ? void 0 : options.plugins)) {
37941
- return {
37942
- url,
37943
- options: opts,
37944
- hooks
37945
- };
37946
- }
37947
- for (const plugin of (options == null ? void 0 : options.plugins) || []) {
37948
- if (plugin.init) {
37949
- const pluginRes = await ((_a2 = plugin.init) == null ? void 0 : _a2.call(plugin, url.toString(), options));
37950
- opts = pluginRes.options || opts;
37951
- url = pluginRes.url;
37952
- }
37953
- hooks.onRequest.push((_b = plugin.hooks) == null ? void 0 : _b.onRequest);
37954
- hooks.onResponse.push((_c = plugin.hooks) == null ? void 0 : _c.onResponse);
37955
- hooks.onSuccess.push((_d = plugin.hooks) == null ? void 0 : _d.onSuccess);
37956
- hooks.onError.push((_e2 = plugin.hooks) == null ? void 0 : _e2.onError);
37957
- hooks.onRetry.push((_f = plugin.hooks) == null ? void 0 : _f.onRetry);
37958
- }
37959
- return {
37960
- url,
37961
- options: opts,
37962
- hooks
37963
- };
37964
- };
37965
- var LinearRetryStrategy = class {
37966
- constructor(options) {
37967
- this.options = options;
37968
- }
37969
- shouldAttemptRetry(attempt, response) {
37970
- if (this.options.shouldRetry) {
37971
- return Promise.resolve(
37972
- attempt < this.options.attempts && this.options.shouldRetry(response)
37973
- );
37974
- }
37975
- return Promise.resolve(attempt < this.options.attempts);
37976
- }
37977
- getDelay() {
37978
- return this.options.delay;
37979
- }
37980
- };
37981
- var ExponentialRetryStrategy = class {
37982
- constructor(options) {
37983
- this.options = options;
37984
- }
37985
- shouldAttemptRetry(attempt, response) {
37986
- if (this.options.shouldRetry) {
37987
- return Promise.resolve(
37988
- attempt < this.options.attempts && this.options.shouldRetry(response)
37989
- );
37990
- }
37991
- return Promise.resolve(attempt < this.options.attempts);
37992
- }
37993
- getDelay(attempt) {
37994
- const delay2 = Math.min(
37995
- this.options.maxDelay,
37996
- this.options.baseDelay * 2 ** attempt
37997
- );
37998
- return delay2;
37999
- }
38000
- };
38001
- function createRetryStrategy(options) {
38002
- if (typeof options === "number") {
38003
- return new LinearRetryStrategy({
38004
- type: "linear",
38005
- attempts: options,
38006
- delay: 1e3
38007
- });
38008
- }
38009
- switch (options.type) {
38010
- case "linear":
38011
- return new LinearRetryStrategy(options);
38012
- case "exponential":
38013
- return new ExponentialRetryStrategy(options);
38014
- default:
38015
- throw new Error("Invalid retry strategy");
38016
- }
38017
- }
38018
- var getAuthHeader = async (options) => {
38019
- const headers = {};
38020
- const getValue = async (value) => typeof value === "function" ? await value() : value;
38021
- if (options == null ? void 0 : options.auth) {
38022
- if (options.auth.type === "Bearer") {
38023
- const token = await getValue(options.auth.token);
38024
- if (!token) {
38025
- return headers;
38026
- }
38027
- headers["authorization"] = `Bearer ${token}`;
38028
- } else if (options.auth.type === "Basic") {
38029
- const username = getValue(options.auth.username);
38030
- const password = getValue(options.auth.password);
38031
- if (!username || !password) {
38032
- return headers;
38033
- }
38034
- headers["authorization"] = `Basic ${btoa(`${username}:${password}`)}`;
38035
- } else if (options.auth.type === "Custom") {
38036
- const value = getValue(options.auth.value);
38037
- if (!value) {
38038
- return headers;
38039
- }
38040
- headers["authorization"] = `${getValue(options.auth.prefix)} ${value}`;
38041
- }
38042
- }
38043
- return headers;
38044
- };
38045
- var JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
38046
- function detectResponseType(request) {
38047
- const _contentType = request.headers.get("content-type");
38048
- const textTypes = /* @__PURE__ */ new Set([
38049
- "image/svg",
38050
- "application/xml",
38051
- "application/xhtml",
38052
- "application/html"
38053
- ]);
38054
- if (!_contentType) {
38055
- return "json";
38056
- }
38057
- const contentType = _contentType.split(";").shift() || "";
38058
- if (JSON_RE.test(contentType)) {
38059
- return "json";
38060
- }
38061
- if (textTypes.has(contentType) || contentType.startsWith("text/")) {
38062
- return "text";
37901
+ function bufferToBase64URLString(buffer) {
37902
+ const bytes = new Uint8Array(buffer);
37903
+ let str = "";
37904
+ for (const charCode of bytes) {
37905
+ str += String.fromCharCode(charCode);
38063
37906
  }
38064
- return "blob";
37907
+ const base64String = btoa(str);
37908
+ return base64String.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
38065
37909
  }
38066
- function isJSONParsable(value) {
38067
- try {
38068
- JSON.parse(value);
38069
- return true;
38070
- } catch (error) {
38071
- return false;
37910
+ function base64URLStringToBuffer(base64URLString) {
37911
+ const base642 = base64URLString.replace(/-/g, "+").replace(/_/g, "/");
37912
+ const padLength = (4 - base642.length % 4) % 4;
37913
+ const padded = base642.padEnd(base642.length + padLength, "=");
37914
+ const binary = atob(padded);
37915
+ const buffer = new ArrayBuffer(binary.length);
37916
+ const bytes = new Uint8Array(buffer);
37917
+ for (let i2 = 0; i2 < binary.length; i2++) {
37918
+ bytes[i2] = binary.charCodeAt(i2);
38072
37919
  }
37920
+ return buffer;
38073
37921
  }
38074
- function isJSONSerializable(value) {
38075
- if (value === void 0) {
38076
- return false;
38077
- }
38078
- const t2 = typeof value;
38079
- if (t2 === "string" || t2 === "number" || t2 === "boolean" || t2 === null) {
38080
- return true;
38081
- }
38082
- if (t2 !== "object") {
38083
- return false;
38084
- }
38085
- if (Array.isArray(value)) {
38086
- return true;
38087
- }
38088
- if (value.buffer) {
38089
- return false;
38090
- }
38091
- return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
37922
+ function browserSupportsWebAuthn() {
37923
+ return _browserSupportsWebAuthnInternals.stubThis(globalThis?.PublicKeyCredential !== void 0 && typeof globalThis.PublicKeyCredential === "function");
38092
37924
  }
38093
- function jsonParse(text) {
38094
- try {
38095
- return JSON.parse(text);
38096
- } catch (error) {
38097
- return text;
38098
- }
37925
+ const _browserSupportsWebAuthnInternals = {
37926
+ stubThis: (value) => value
37927
+ };
37928
+ function toPublicKeyCredentialDescriptor(descriptor) {
37929
+ const { id: id2 } = descriptor;
37930
+ return {
37931
+ ...descriptor,
37932
+ id: base64URLStringToBuffer(id2),
37933
+ /**
37934
+ * `descriptor.transports` is an array of our `AuthenticatorTransportFuture` that includes newer
37935
+ * transports that TypeScript's DOM lib is ignorant of. Convince TS that our list of transports
37936
+ * are fine to pass to WebAuthn since browsers will recognize the new value.
37937
+ */
37938
+ transports: descriptor.transports
37939
+ };
38099
37940
  }
38100
- function isFunction$1(value) {
38101
- return typeof value === "function";
37941
+ function isValidDomain(hostname) {
37942
+ return (
37943
+ // Consider localhost valid as well since it's okay wrt Secure Contexts
37944
+ hostname === "localhost" || /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname)
37945
+ );
38102
37946
  }
38103
- function getFetch(options) {
38104
- if (options == null ? void 0 : options.customFetchImpl) {
38105
- return options.customFetchImpl;
38106
- }
38107
- if (typeof globalThis !== "undefined" && isFunction$1(globalThis.fetch)) {
38108
- return globalThis.fetch;
38109
- }
38110
- if (typeof window !== "undefined" && isFunction$1(window.fetch)) {
38111
- return window.fetch;
37947
+ class WebAuthnError extends Error {
37948
+ constructor({ message, code, cause, name }) {
37949
+ super(message, { cause });
37950
+ Object.defineProperty(this, "code", {
37951
+ enumerable: true,
37952
+ configurable: true,
37953
+ writable: true,
37954
+ value: void 0
37955
+ });
37956
+ this.name = name ?? cause.name;
37957
+ this.code = code;
38112
37958
  }
38113
- throw new Error("No fetch implementation found");
38114
37959
  }
38115
- async function getHeaders(opts) {
38116
- const headers = new Headers(opts == null ? void 0 : opts.headers);
38117
- const authHeader = await getAuthHeader(opts);
38118
- for (const [key2, value] of Object.entries(authHeader || {})) {
38119
- headers.set(key2, value);
37960
+ function identifyRegistrationError({ error, options }) {
37961
+ const { publicKey } = options;
37962
+ if (!publicKey) {
37963
+ throw Error("options was missing required publicKey property");
38120
37964
  }
38121
- if (!headers.has("content-type")) {
38122
- const t2 = detectContentType(opts == null ? void 0 : opts.body);
38123
- if (t2) {
38124
- headers.set("content-type", t2);
37965
+ if (error.name === "AbortError") {
37966
+ if (options.signal instanceof AbortSignal) {
37967
+ return new WebAuthnError({
37968
+ message: "Registration ceremony was sent an abort signal",
37969
+ code: "ERROR_CEREMONY_ABORTED",
37970
+ cause: error
37971
+ });
38125
37972
  }
38126
- }
38127
- return headers;
38128
- }
38129
- function detectContentType(body) {
38130
- if (isJSONSerializable(body)) {
38131
- return "application/json";
38132
- }
38133
- return null;
38134
- }
38135
- function getBody(options) {
38136
- if (!(options == null ? void 0 : options.body)) {
38137
- return null;
38138
- }
38139
- const headers = new Headers(options == null ? void 0 : options.headers);
38140
- if (isJSONSerializable(options.body) && !headers.has("content-type")) {
38141
- for (const [key2, value] of Object.entries(options == null ? void 0 : options.body)) {
38142
- if (value instanceof Date) {
38143
- options.body[key2] = value.toISOString();
38144
- }
37973
+ } else if (error.name === "ConstraintError") {
37974
+ if (publicKey.authenticatorSelection?.requireResidentKey === true) {
37975
+ return new WebAuthnError({
37976
+ message: "Discoverable credentials were required but no available authenticator supported it",
37977
+ code: "ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",
37978
+ cause: error
37979
+ });
37980
+ } else if (
37981
+ // @ts-ignore: `mediation` doesn't yet exist on CredentialCreationOptions but it's possible as of Sept 2024
37982
+ options.mediation === "conditional" && publicKey.authenticatorSelection?.userVerification === "required"
37983
+ ) {
37984
+ return new WebAuthnError({
37985
+ message: "User verification was required during automatic registration but it could not be performed",
37986
+ code: "ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",
37987
+ cause: error
37988
+ });
37989
+ } else if (publicKey.authenticatorSelection?.userVerification === "required") {
37990
+ return new WebAuthnError({
37991
+ message: "User verification was required but no available authenticator supported it",
37992
+ code: "ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",
37993
+ cause: error
37994
+ });
38145
37995
  }
38146
- return JSON.stringify(options.body);
37996
+ } else if (error.name === "InvalidStateError") {
37997
+ return new WebAuthnError({
37998
+ message: "The authenticator was previously registered",
37999
+ code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",
38000
+ cause: error
38001
+ });
38002
+ } else if (error.name === "NotAllowedError") {
38003
+ return new WebAuthnError({
38004
+ message: error.message,
38005
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
38006
+ cause: error
38007
+ });
38008
+ } else if (error.name === "NotSupportedError") {
38009
+ const validPubKeyCredParams = publicKey.pubKeyCredParams.filter((param) => param.type === "public-key");
38010
+ if (validPubKeyCredParams.length === 0) {
38011
+ return new WebAuthnError({
38012
+ message: 'No entry in pubKeyCredParams was of type "public-key"',
38013
+ code: "ERROR_MALFORMED_PUBKEYCREDPARAMS",
38014
+ cause: error
38015
+ });
38016
+ }
38017
+ return new WebAuthnError({
38018
+ message: "No available authenticator supported any of the specified pubKeyCredParams algorithms",
38019
+ code: "ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",
38020
+ cause: error
38021
+ });
38022
+ } else if (error.name === "SecurityError") {
38023
+ const effectiveDomain = globalThis.location.hostname;
38024
+ if (!isValidDomain(effectiveDomain)) {
38025
+ return new WebAuthnError({
38026
+ message: `${globalThis.location.hostname} is an invalid domain`,
38027
+ code: "ERROR_INVALID_DOMAIN",
38028
+ cause: error
38029
+ });
38030
+ } else if (publicKey.rp.id !== effectiveDomain) {
38031
+ return new WebAuthnError({
38032
+ message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`,
38033
+ code: "ERROR_INVALID_RP_ID",
38034
+ cause: error
38035
+ });
38036
+ }
38037
+ } else if (error.name === "TypeError") {
38038
+ if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) {
38039
+ return new WebAuthnError({
38040
+ message: "User ID was not between 1 and 64 characters",
38041
+ code: "ERROR_INVALID_USER_ID_LENGTH",
38042
+ cause: error
38043
+ });
38044
+ }
38045
+ } else if (error.name === "UnknownError") {
38046
+ return new WebAuthnError({
38047
+ message: "The authenticator was unable to process the specified options, or could not create a new credential",
38048
+ code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
38049
+ cause: error
38050
+ });
38147
38051
  }
38148
- return options.body;
38052
+ return error;
38149
38053
  }
38150
- function getMethod$1(url, options) {
38151
- var _a2;
38152
- if (options == null ? void 0 : options.method) {
38153
- return options.method.toUpperCase();
38054
+ class BaseWebAuthnAbortService {
38055
+ constructor() {
38056
+ Object.defineProperty(this, "controller", {
38057
+ enumerable: true,
38058
+ configurable: true,
38059
+ writable: true,
38060
+ value: void 0
38061
+ });
38154
38062
  }
38155
- if (url.startsWith("@")) {
38156
- const pMethod = (_a2 = url.split("@")[1]) == null ? void 0 : _a2.split("/")[0];
38157
- if (!methods.includes(pMethod)) {
38158
- return (options == null ? void 0 : options.body) ? "POST" : "GET";
38063
+ createNewAbortSignal() {
38064
+ if (this.controller) {
38065
+ const abortError = new Error("Cancelling existing WebAuthn API call for new one");
38066
+ abortError.name = "AbortError";
38067
+ this.controller.abort(abortError);
38159
38068
  }
38160
- return pMethod.toUpperCase();
38161
- }
38162
- return (options == null ? void 0 : options.body) ? "POST" : "GET";
38163
- }
38164
- function getTimeout(options, controller) {
38165
- let abortTimeout;
38166
- if (!(options == null ? void 0 : options.signal) && (options == null ? void 0 : options.timeout)) {
38167
- abortTimeout = setTimeout(() => controller == null ? void 0 : controller.abort(), options == null ? void 0 : options.timeout);
38069
+ const newController = new AbortController();
38070
+ this.controller = newController;
38071
+ return newController.signal;
38168
38072
  }
38169
- return {
38170
- abortTimeout,
38171
- clearTimeout: () => {
38172
- if (abortTimeout) {
38173
- clearTimeout(abortTimeout);
38174
- }
38073
+ cancelCeremony() {
38074
+ if (this.controller) {
38075
+ const abortError = new Error("Manually cancelling existing WebAuthn API call");
38076
+ abortError.name = "AbortError";
38077
+ this.controller.abort(abortError);
38078
+ this.controller = void 0;
38175
38079
  }
38176
- };
38080
+ }
38177
38081
  }
38178
- var ValidationError = class _ValidationError extends Error {
38179
- constructor(issues, message) {
38180
- super(message || JSON.stringify(issues, null, 2));
38181
- this.issues = issues;
38182
- Object.setPrototypeOf(this, _ValidationError.prototype);
38082
+ const WebAuthnAbortService = new BaseWebAuthnAbortService();
38083
+ const attachments = ["cross-platform", "platform"];
38084
+ function toAuthenticatorAttachment(attachment) {
38085
+ if (!attachment) {
38086
+ return;
38183
38087
  }
38184
- };
38185
- async function parseStandardSchema(schema, input) {
38186
- let result = await schema["~standard"].validate(input);
38187
- if (result.issues) {
38188
- throw new ValidationError(result.issues);
38088
+ if (attachments.indexOf(attachment) < 0) {
38089
+ return;
38189
38090
  }
38190
- return result.value;
38091
+ return attachment;
38191
38092
  }
38192
- var methods = ["get", "post", "put", "patch", "delete"];
38193
- var applySchemaPlugin = (config2) => ({
38194
- id: "apply-schema",
38195
- name: "Apply Schema",
38196
- version: "1.0.0",
38197
- async init(url, options) {
38198
- var _a2, _b, _c, _d;
38199
- const schema = ((_b = (_a2 = config2.plugins) == null ? void 0 : _a2.find(
38200
- (plugin) => {
38201
- var _a22;
38202
- return ((_a22 = plugin.schema) == null ? void 0 : _a22.config) ? url.startsWith(plugin.schema.config.baseURL || "") || url.startsWith(plugin.schema.config.prefix || "") : false;
38203
- }
38204
- )) == null ? void 0 : _b.schema) || config2.schema;
38205
- if (schema) {
38206
- let urlKey = url;
38207
- if ((_c = schema.config) == null ? void 0 : _c.prefix) {
38208
- if (urlKey.startsWith(schema.config.prefix)) {
38209
- urlKey = urlKey.replace(schema.config.prefix, "");
38210
- if (schema.config.baseURL) {
38211
- url = url.replace(schema.config.prefix, schema.config.baseURL);
38212
- }
38213
- }
38214
- }
38215
- if ((_d = schema.config) == null ? void 0 : _d.baseURL) {
38216
- if (urlKey.startsWith(schema.config.baseURL)) {
38217
- urlKey = urlKey.replace(schema.config.baseURL, "");
38218
- }
38219
- }
38220
- const keySchema = schema.schema[urlKey];
38221
- if (keySchema) {
38222
- let opts = __spreadProps(__spreadValues({}, options), {
38223
- method: keySchema.method,
38224
- output: keySchema.output
38225
- });
38226
- if (!(options == null ? void 0 : options.disableValidation)) {
38227
- opts = __spreadProps(__spreadValues({}, opts), {
38228
- body: keySchema.input ? await parseStandardSchema(keySchema.input, options == null ? void 0 : options.body) : options == null ? void 0 : options.body,
38229
- params: keySchema.params ? await parseStandardSchema(keySchema.params, options == null ? void 0 : options.params) : options == null ? void 0 : options.params,
38230
- query: keySchema.query ? await parseStandardSchema(keySchema.query, options == null ? void 0 : options.query) : options == null ? void 0 : options.query
38231
- });
38232
- }
38233
- return {
38234
- url,
38235
- options: opts
38236
- };
38237
- }
38238
- }
38239
- return {
38240
- url,
38241
- options
38242
- };
38093
+ async function startRegistration(options) {
38094
+ if (!options.optionsJSON && options.challenge) {
38095
+ console.warn("startRegistration() was not called correctly. It will try to continue with the provided options, but this call should be refactored to use the expected call structure instead. See https://simplewebauthn.dev/docs/packages/browser#typeerror-cannot-read-properties-of-undefined-reading-challenge for more information.");
38096
+ options = { optionsJSON: options };
38243
38097
  }
38244
- });
38245
- var createFetch = (config2) => {
38246
- async function $fetch(url, options) {
38247
- const opts = __spreadProps(__spreadValues(__spreadValues({}, config2), options), {
38248
- plugins: [...(config2 == null ? void 0 : config2.plugins) || [], applySchemaPlugin(config2 || {})]
38249
- });
38250
- if (config2 == null ? void 0 : config2.catchAllError) {
38251
- try {
38252
- return await betterFetch(url, opts);
38253
- } catch (error) {
38254
- return {
38255
- data: null,
38256
- error: {
38257
- status: 500,
38258
- statusText: "Fetch Error",
38259
- message: "Fetch related error. Captured by catchAllError option. See error property for more details.",
38260
- error
38261
- }
38262
- };
38263
- }
38264
- }
38265
- return await betterFetch(url, opts);
38098
+ const { optionsJSON, useAutoRegister = false } = options;
38099
+ if (!browserSupportsWebAuthn()) {
38100
+ throw new Error("WebAuthn is not supported in this browser");
38266
38101
  }
38267
- return $fetch;
38268
- };
38269
- function getURL2(url, option) {
38270
- let { baseURL, params, query } = option || {
38271
- query: {},
38272
- params: {},
38273
- baseURL: ""
38102
+ const publicKey = {
38103
+ ...optionsJSON,
38104
+ challenge: base64URLStringToBuffer(optionsJSON.challenge),
38105
+ user: {
38106
+ ...optionsJSON.user,
38107
+ id: base64URLStringToBuffer(optionsJSON.user.id)
38108
+ },
38109
+ excludeCredentials: optionsJSON.excludeCredentials?.map(toPublicKeyCredentialDescriptor)
38274
38110
  };
38275
- let basePath = url.startsWith("http") ? url.split("/").slice(0, 3).join("/") : baseURL || "";
38276
- if (url.startsWith("@")) {
38277
- const m2 = url.toString().split("@")[1].split("/")[0];
38278
- if (methods.includes(m2)) {
38279
- url = url.replace(`@${m2}/`, "/");
38280
- }
38111
+ const createOptions = {};
38112
+ if (useAutoRegister) {
38113
+ createOptions.mediation = "conditional";
38281
38114
  }
38282
- if (!basePath.endsWith("/")) basePath += "/";
38283
- let [path, urlQuery] = url.replace(basePath, "").split("?");
38284
- const queryParams = new URLSearchParams(urlQuery);
38285
- for (const [key2, value] of Object.entries(query || {})) {
38286
- if (value == null) continue;
38287
- queryParams.set(key2, String(value));
38115
+ createOptions.publicKey = publicKey;
38116
+ createOptions.signal = WebAuthnAbortService.createNewAbortSignal();
38117
+ let credential;
38118
+ try {
38119
+ credential = await navigator.credentials.create(createOptions);
38120
+ } catch (err) {
38121
+ throw identifyRegistrationError({ error: err, options: createOptions });
38288
38122
  }
38289
- if (params) {
38290
- if (Array.isArray(params)) {
38291
- const paramPaths = path.split("/").filter((p2) => p2.startsWith(":"));
38292
- for (const [index2, key2] of paramPaths.entries()) {
38293
- const value = params[index2];
38294
- path = path.replace(key2, value);
38295
- }
38296
- } else {
38297
- for (const [key2, value] of Object.entries(params)) {
38298
- path = path.replace(`:${key2}`, String(value));
38299
- }
38300
- }
38123
+ if (!credential) {
38124
+ throw new Error("Registration was not completed");
38301
38125
  }
38302
- path = path.split("/").map(encodeURIComponent).join("/");
38303
- if (path.startsWith("/")) path = path.slice(1);
38304
- let queryParamString = queryParams.toString();
38305
- queryParamString = queryParamString.length > 0 ? `?${queryParamString}`.replace(/\+/g, "%20") : "";
38306
- if (!basePath.startsWith("http")) {
38307
- return `${basePath}${path}${queryParamString}`;
38126
+ const { id: id2, rawId, response, type } = credential;
38127
+ let transports = void 0;
38128
+ if (typeof response.getTransports === "function") {
38129
+ transports = response.getTransports();
38308
38130
  }
38309
- const _url2 = new URL(`${path}${queryParamString}`, basePath);
38310
- return _url2;
38311
- }
38312
- var betterFetch = async (url, options) => {
38313
- var _a2, _b, _c, _d, _e2, _f, _g, _h;
38314
- const {
38315
- hooks,
38316
- url: __url,
38317
- options: opts
38318
- } = await initializePlugins(url, options);
38319
- const fetch2 = getFetch(opts);
38320
- const controller = new AbortController();
38321
- const signal = (_a2 = opts.signal) != null ? _a2 : controller.signal;
38322
- const _url2 = getURL2(__url, opts);
38323
- const body = getBody(opts);
38324
- const headers = await getHeaders(opts);
38325
- const method = getMethod$1(__url, opts);
38326
- let context = __spreadProps(__spreadValues({}, opts), {
38327
- url: _url2,
38328
- headers,
38329
- body,
38330
- method,
38331
- signal
38332
- });
38333
- for (const onRequest of hooks.onRequest) {
38334
- if (onRequest) {
38335
- const res = await onRequest(context);
38336
- if (res instanceof Object) {
38337
- context = res;
38131
+ let responsePublicKeyAlgorithm = void 0;
38132
+ if (typeof response.getPublicKeyAlgorithm === "function") {
38133
+ try {
38134
+ responsePublicKeyAlgorithm = response.getPublicKeyAlgorithm();
38135
+ } catch (error) {
38136
+ warnOnBrokenImplementation("getPublicKeyAlgorithm()", error);
38137
+ }
38138
+ }
38139
+ let responsePublicKey = void 0;
38140
+ if (typeof response.getPublicKey === "function") {
38141
+ try {
38142
+ const _publicKey = response.getPublicKey();
38143
+ if (_publicKey !== null) {
38144
+ responsePublicKey = bufferToBase64URLString(_publicKey);
38338
38145
  }
38146
+ } catch (error) {
38147
+ warnOnBrokenImplementation("getPublicKey()", error);
38339
38148
  }
38340
38149
  }
38341
- if ("pipeTo" in context && typeof context.pipeTo === "function" || typeof ((_b = options == null ? void 0 : options.body) == null ? void 0 : _b.pipe) === "function") {
38342
- if (!("duplex" in context)) {
38343
- context.duplex = "half";
38150
+ let responseAuthenticatorData;
38151
+ if (typeof response.getAuthenticatorData === "function") {
38152
+ try {
38153
+ responseAuthenticatorData = bufferToBase64URLString(response.getAuthenticatorData());
38154
+ } catch (error) {
38155
+ warnOnBrokenImplementation("getAuthenticatorData()", error);
38344
38156
  }
38345
38157
  }
38346
- const { clearTimeout: clearTimeout2 } = getTimeout(opts, controller);
38347
- let response = await fetch2(context.url, context);
38348
- clearTimeout2();
38349
- const responseContext = {
38350
- response,
38351
- request: context
38158
+ return {
38159
+ id: id2,
38160
+ rawId: bufferToBase64URLString(rawId),
38161
+ response: {
38162
+ attestationObject: bufferToBase64URLString(response.attestationObject),
38163
+ clientDataJSON: bufferToBase64URLString(response.clientDataJSON),
38164
+ transports,
38165
+ publicKeyAlgorithm: responsePublicKeyAlgorithm,
38166
+ publicKey: responsePublicKey,
38167
+ authenticatorData: responseAuthenticatorData
38168
+ },
38169
+ type,
38170
+ clientExtensionResults: credential.getClientExtensionResults(),
38171
+ authenticatorAttachment: toAuthenticatorAttachment(credential.authenticatorAttachment)
38352
38172
  };
38353
- for (const onResponse of hooks.onResponse) {
38354
- if (onResponse) {
38355
- const r2 = await onResponse(__spreadProps(__spreadValues({}, responseContext), {
38356
- response: ((_c = options == null ? void 0 : options.hookOptions) == null ? void 0 : _c.cloneResponse) ? response.clone() : response
38357
- }));
38358
- if (r2 instanceof Response) {
38359
- response = r2;
38360
- } else if (r2 instanceof Object) {
38361
- response = r2.response;
38362
- }
38363
- }
38173
+ }
38174
+ function warnOnBrokenImplementation(methodName, cause) {
38175
+ console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${methodName}. You should report this error to them.
38176
+ `, cause);
38177
+ }
38178
+ function browserSupportsWebAuthnAutofill() {
38179
+ if (!browserSupportsWebAuthn()) {
38180
+ return _browserSupportsWebAuthnAutofillInternals.stubThis(new Promise((resolve) => resolve(false)));
38364
38181
  }
38365
- if (response.ok) {
38366
- const hasBody = context.method !== "HEAD";
38367
- if (!hasBody) {
38368
- return {
38369
- data: "",
38370
- error: null
38371
- };
38372
- }
38373
- const responseType = detectResponseType(response);
38374
- const successContext = {
38375
- data: "",
38376
- response,
38377
- request: context
38378
- };
38379
- if (responseType === "json" || responseType === "text") {
38380
- const text = await response.text();
38381
- const parser2 = (_d = context.jsonParser) != null ? _d : jsonParse;
38382
- const data = await parser2(text);
38383
- successContext.data = data;
38384
- } else {
38385
- successContext.data = await response[responseType]();
38386
- }
38387
- if (context == null ? void 0 : context.output) {
38388
- if (context.output && !context.disableValidation) {
38389
- successContext.data = await parseStandardSchema(
38390
- context.output,
38391
- successContext.data
38392
- );
38393
- }
38394
- }
38395
- for (const onSuccess of hooks.onSuccess) {
38396
- if (onSuccess) {
38397
- await onSuccess(__spreadProps(__spreadValues({}, successContext), {
38398
- response: ((_e2 = options == null ? void 0 : options.hookOptions) == null ? void 0 : _e2.cloneResponse) ? response.clone() : response
38399
- }));
38400
- }
38182
+ const globalPublicKeyCredential = globalThis.PublicKeyCredential;
38183
+ if (globalPublicKeyCredential?.isConditionalMediationAvailable === void 0) {
38184
+ return _browserSupportsWebAuthnAutofillInternals.stubThis(new Promise((resolve) => resolve(false)));
38185
+ }
38186
+ return _browserSupportsWebAuthnAutofillInternals.stubThis(globalPublicKeyCredential.isConditionalMediationAvailable());
38187
+ }
38188
+ const _browserSupportsWebAuthnAutofillInternals = {
38189
+ stubThis: (value) => value
38190
+ };
38191
+ function identifyAuthenticationError({ error, options }) {
38192
+ const { publicKey } = options;
38193
+ if (!publicKey) {
38194
+ throw Error("options was missing required publicKey property");
38195
+ }
38196
+ if (error.name === "AbortError") {
38197
+ if (options.signal instanceof AbortSignal) {
38198
+ return new WebAuthnError({
38199
+ message: "Authentication ceremony was sent an abort signal",
38200
+ code: "ERROR_CEREMONY_ABORTED",
38201
+ cause: error
38202
+ });
38401
38203
  }
38402
- if (options == null ? void 0 : options.throw) {
38403
- return successContext.data;
38204
+ } else if (error.name === "NotAllowedError") {
38205
+ return new WebAuthnError({
38206
+ message: error.message,
38207
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
38208
+ cause: error
38209
+ });
38210
+ } else if (error.name === "SecurityError") {
38211
+ const effectiveDomain = globalThis.location.hostname;
38212
+ if (!isValidDomain(effectiveDomain)) {
38213
+ return new WebAuthnError({
38214
+ message: `${globalThis.location.hostname} is an invalid domain`,
38215
+ code: "ERROR_INVALID_DOMAIN",
38216
+ cause: error
38217
+ });
38218
+ } else if (publicKey.rpId !== effectiveDomain) {
38219
+ return new WebAuthnError({
38220
+ message: `The RP ID "${publicKey.rpId}" is invalid for this domain`,
38221
+ code: "ERROR_INVALID_RP_ID",
38222
+ cause: error
38223
+ });
38404
38224
  }
38405
- return {
38406
- data: successContext.data,
38407
- error: null
38408
- };
38225
+ } else if (error.name === "UnknownError") {
38226
+ return new WebAuthnError({
38227
+ message: "The authenticator was unable to process the specified options, or could not create a new assertion signature",
38228
+ code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
38229
+ cause: error
38230
+ });
38409
38231
  }
38410
- const parser = (_f = options == null ? void 0 : options.jsonParser) != null ? _f : jsonParse;
38411
- const responseText = await response.text();
38412
- const isJSONResponse = isJSONParsable(responseText);
38413
- const errorObject = isJSONResponse ? await parser(responseText) : null;
38414
- const errorContext = {
38415
- response,
38416
- responseText,
38417
- request: context,
38418
- error: __spreadProps(__spreadValues({}, errorObject), {
38419
- status: response.status,
38420
- statusText: response.statusText
38421
- })
38232
+ return error;
38233
+ }
38234
+ async function startAuthentication(options) {
38235
+ if (!options.optionsJSON && options.challenge) {
38236
+ console.warn("startAuthentication() was not called correctly. It will try to continue with the provided options, but this call should be refactored to use the expected call structure instead. See https://simplewebauthn.dev/docs/packages/browser#typeerror-cannot-read-properties-of-undefined-reading-challenge for more information.");
38237
+ options = { optionsJSON: options };
38238
+ }
38239
+ const { optionsJSON, useBrowserAutofill = false, verifyBrowserAutofillInput = true } = options;
38240
+ if (!browserSupportsWebAuthn()) {
38241
+ throw new Error("WebAuthn is not supported in this browser");
38242
+ }
38243
+ let allowCredentials;
38244
+ if (optionsJSON.allowCredentials?.length !== 0) {
38245
+ allowCredentials = optionsJSON.allowCredentials?.map(toPublicKeyCredentialDescriptor);
38246
+ }
38247
+ const publicKey = {
38248
+ ...optionsJSON,
38249
+ challenge: base64URLStringToBuffer(optionsJSON.challenge),
38250
+ allowCredentials
38422
38251
  };
38423
- for (const onError of hooks.onError) {
38424
- if (onError) {
38425
- await onError(__spreadProps(__spreadValues({}, errorContext), {
38426
- response: ((_g = options == null ? void 0 : options.hookOptions) == null ? void 0 : _g.cloneResponse) ? response.clone() : response
38427
- }));
38252
+ const getOptions = {};
38253
+ if (useBrowserAutofill) {
38254
+ if (!await browserSupportsWebAuthnAutofill()) {
38255
+ throw Error("Browser does not support WebAuthn autofill");
38428
38256
  }
38429
- }
38430
- if (options == null ? void 0 : options.retry) {
38431
- const retryStrategy = createRetryStrategy(options.retry);
38432
- const _retryAttempt = (_h = options.retryAttempt) != null ? _h : 0;
38433
- if (await retryStrategy.shouldAttemptRetry(_retryAttempt, response)) {
38434
- for (const onRetry of hooks.onRetry) {
38435
- if (onRetry) {
38436
- await onRetry(responseContext);
38437
- }
38438
- }
38439
- const delay2 = retryStrategy.getDelay(_retryAttempt);
38440
- await new Promise((resolve) => setTimeout(resolve, delay2));
38441
- return await betterFetch(url, __spreadProps(__spreadValues({}, options), {
38442
- retryAttempt: _retryAttempt + 1
38443
- }));
38257
+ const eligibleInputs = document.querySelectorAll("input[autocomplete$='webauthn']");
38258
+ if (eligibleInputs.length < 1 && verifyBrowserAutofillInput) {
38259
+ throw Error('No <input> with "webauthn" as the only or last value in its `autocomplete` attribute was detected');
38444
38260
  }
38261
+ getOptions.mediation = "conditional";
38262
+ publicKey.allowCredentials = [];
38445
38263
  }
38446
- if (options == null ? void 0 : options.throw) {
38447
- throw new BetterFetchError(
38448
- response.status,
38449
- response.statusText,
38450
- isJSONResponse ? errorObject : responseText
38451
- );
38264
+ getOptions.publicKey = publicKey;
38265
+ getOptions.signal = WebAuthnAbortService.createNewAbortSignal();
38266
+ let credential;
38267
+ try {
38268
+ credential = await navigator.credentials.get(getOptions);
38269
+ } catch (err) {
38270
+ throw identifyAuthenticationError({ error: err, options: getOptions });
38271
+ }
38272
+ if (!credential) {
38273
+ throw new Error("Authentication was not completed");
38274
+ }
38275
+ const { id: id2, rawId, response, type } = credential;
38276
+ let userHandle = void 0;
38277
+ if (response.userHandle) {
38278
+ userHandle = bufferToBase64URLString(response.userHandle);
38452
38279
  }
38453
38280
  return {
38454
- data: null,
38455
- error: __spreadProps(__spreadValues({}, errorObject), {
38456
- status: response.status,
38457
- statusText: response.statusText
38458
- })
38281
+ id: id2,
38282
+ rawId: bufferToBase64URLString(rawId),
38283
+ response: {
38284
+ authenticatorData: bufferToBase64URLString(response.authenticatorData),
38285
+ clientDataJSON: bufferToBase64URLString(response.clientDataJSON),
38286
+ signature: bufferToBase64URLString(response.signature),
38287
+ userHandle
38288
+ },
38289
+ type,
38290
+ clientExtensionResults: credential.getClientExtensionResults(),
38291
+ authenticatorAttachment: toAuthenticatorAttachment(credential.authenticatorAttachment)
38459
38292
  };
38460
- };
38293
+ }
38294
+ function capitalizeFirstLetter(str) {
38295
+ return str.charAt(0).toUpperCase() + str.slice(1);
38296
+ }
38461
38297
  var define_globalThis_process_env_default = {};
38462
38298
  var define_process_env_default = {};
38463
38299
  const _envShim = /* @__PURE__ */ Object.create(null);
38464
- const _getEnv = (useShim) => define_globalThis_process_env_default || //@ts-expect-error
38465
- globalThis.Deno?.env.toObject() || //@ts-expect-error
38466
- globalThis.__env__ || (useShim ? _envShim : globalThis);
38300
+ const _getEnv = (useShim) => define_globalThis_process_env_default || globalThis.Deno?.env.toObject() || globalThis.__env__ || (useShim ? _envShim : globalThis);
38467
38301
  const env = new Proxy(_envShim, {
38468
38302
  get(_2, prop) {
38469
- const env2 = _getEnv();
38470
- return env2[prop] ?? _envShim[prop];
38303
+ return _getEnv()[prop] ?? _envShim[prop];
38471
38304
  },
38472
38305
  has(_2, prop) {
38473
- const env2 = _getEnv();
38474
- return prop in env2 || prop in _envShim;
38306
+ return prop in _getEnv() || prop in _envShim;
38475
38307
  },
38476
38308
  set(_2, prop, value) {
38477
- const env2 = _getEnv(true);
38478
- env2[prop] = value;
38309
+ const env$1 = _getEnv(true);
38310
+ env$1[prop] = value;
38479
38311
  return true;
38480
38312
  },
38481
38313
  deleteProperty(_2, prop) {
38482
- if (!prop) {
38483
- return false;
38484
- }
38485
- const env2 = _getEnv(true);
38486
- delete env2[prop];
38314
+ if (!prop) return false;
38315
+ const env$1 = _getEnv(true);
38316
+ delete env$1[prop];
38487
38317
  return true;
38488
38318
  },
38489
38319
  ownKeys() {
38490
- const env2 = _getEnv(true);
38491
- return Object.keys(env2);
38320
+ const env$1 = _getEnv(true);
38321
+ return Object.keys(env$1);
38492
38322
  }
38493
38323
  });
38494
38324
  function getEnvVar(key2, fallback) {
38495
- if (typeof process !== "undefined" && define_process_env_default) {
38496
- return define_process_env_default[key2] ?? fallback;
38497
- }
38498
- if (typeof Deno !== "undefined") {
38499
- return Deno.env.get(key2) ?? fallback;
38500
- }
38501
- if (typeof Bun !== "undefined") {
38502
- return Bun.env[key2] ?? fallback;
38503
- }
38325
+ if (typeof process !== "undefined" && define_process_env_default) return define_process_env_default[key2] ?? fallback;
38326
+ if (typeof Deno !== "undefined") return Deno.env.get(key2) ?? fallback;
38327
+ if (typeof Bun !== "undefined") return Bun.env[key2] ?? fallback;
38504
38328
  return fallback;
38505
38329
  }
38506
38330
  const COLORS_2 = 1;
@@ -38522,24 +38346,20 @@ const TERM_ENVS = {
38522
38346
  mosh: COLORS_16m,
38523
38347
  putty: COLORS_16,
38524
38348
  st: COLORS_16,
38525
- // http://lists.schmorp.de/pipermail/rxvt-unicode/2016q2/002261.html
38526
38349
  "rxvt-unicode-24bit": COLORS_16m,
38527
- // https://bugs.launchpad.net/terminator/+bug/1030562
38528
38350
  terminator: COLORS_16m,
38529
38351
  "xterm-kitty": COLORS_16m
38530
38352
  };
38531
- const CI_ENVS_MAP = new Map(
38532
- Object.entries({
38533
- APPVEYOR: COLORS_256,
38534
- BUILDKITE: COLORS_256,
38535
- CIRCLECI: COLORS_16m,
38536
- DRONE: COLORS_256,
38537
- GITEA_ACTIONS: COLORS_16m,
38538
- GITHUB_ACTIONS: COLORS_16m,
38539
- GITLAB_CI: COLORS_256,
38540
- TRAVIS: COLORS_256
38541
- })
38542
- );
38353
+ const CI_ENVS_MAP = new Map(Object.entries({
38354
+ APPVEYOR: COLORS_256,
38355
+ BUILDKITE: COLORS_256,
38356
+ CIRCLECI: COLORS_16m,
38357
+ DRONE: COLORS_256,
38358
+ GITEA_ACTIONS: COLORS_16m,
38359
+ GITHUB_ACTIONS: COLORS_16m,
38360
+ GITLAB_CI: COLORS_256,
38361
+ TRAVIS: COLORS_256
38362
+ }));
38543
38363
  const TERM_ENVS_REG_EXP = [
38544
38364
  /ansi/,
38545
38365
  /color/,
@@ -38550,57 +38370,33 @@ const TERM_ENVS_REG_EXP = [
38550
38370
  /^screen/,
38551
38371
  /^xterm/,
38552
38372
  /^vt100/,
38553
- /^vt220/
38554
- ];
38555
- function getColorDepth() {
38556
- if (getEnvVar("FORCE_COLOR") !== void 0) {
38557
- switch (getEnvVar("FORCE_COLOR")) {
38558
- case "":
38559
- case "1":
38560
- case "true":
38561
- return COLORS_16;
38562
- case "2":
38563
- return COLORS_256;
38564
- case "3":
38565
- return COLORS_16m;
38566
- default:
38567
- return COLORS_2;
38568
- }
38569
- }
38570
- if (getEnvVar("NODE_DISABLE_COLORS") !== void 0 && getEnvVar("NODE_DISABLE_COLORS") !== "" || // See https://no-color.org/
38571
- getEnvVar("NO_COLOR") !== void 0 && getEnvVar("NO_COLOR") !== "" || // The "dumb" special terminal, as defined by terminfo, doesn't support
38572
- // ANSI color control codes.
38573
- // See https://invisible-island.net/ncurses/terminfo.ti.html#toc-_Specials
38574
- getEnvVar("TERM") === "dumb") {
38575
- return COLORS_2;
38576
- }
38577
- if (getEnvVar("TMUX")) {
38578
- return COLORS_16m;
38579
- }
38580
- if ("TF_BUILD" in env && "AGENT_NAME" in env) {
38581
- return COLORS_16;
38373
+ /^vt220/
38374
+ ];
38375
+ function getColorDepth() {
38376
+ if (getEnvVar("FORCE_COLOR") !== void 0) switch (getEnvVar("FORCE_COLOR")) {
38377
+ case "":
38378
+ case "1":
38379
+ case "true":
38380
+ return COLORS_16;
38381
+ case "2":
38382
+ return COLORS_256;
38383
+ case "3":
38384
+ return COLORS_16m;
38385
+ default:
38386
+ return COLORS_2;
38582
38387
  }
38388
+ if (getEnvVar("NODE_DISABLE_COLORS") !== void 0 && getEnvVar("NODE_DISABLE_COLORS") !== "" || getEnvVar("NO_COLOR") !== void 0 && getEnvVar("NO_COLOR") !== "" || getEnvVar("TERM") === "dumb") return COLORS_2;
38389
+ if (getEnvVar("TMUX")) return COLORS_16m;
38390
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) return COLORS_16;
38583
38391
  if ("CI" in env) {
38584
- for (const { 0: envName, 1: colors } of CI_ENVS_MAP) {
38585
- if (envName in env) {
38586
- return colors;
38587
- }
38588
- }
38589
- if (getEnvVar("CI_NAME") === "codeship") {
38590
- return COLORS_256;
38591
- }
38392
+ for (const { 0: envName, 1: colors } of CI_ENVS_MAP) if (envName in env) return colors;
38393
+ if (getEnvVar("CI_NAME") === "codeship") return COLORS_256;
38592
38394
  return COLORS_2;
38593
38395
  }
38594
- if ("TEAMCITY_VERSION" in env) {
38595
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.exec(
38596
- getEnvVar("TEAMCITY_VERSION")
38597
- ) !== null ? COLORS_16 : COLORS_2;
38598
- }
38396
+ if ("TEAMCITY_VERSION" in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.exec(getEnvVar("TEAMCITY_VERSION")) !== null ? COLORS_16 : COLORS_2;
38599
38397
  switch (getEnvVar("TERM_PROGRAM")) {
38600
38398
  case "iTerm.app":
38601
- if (!getEnvVar("TERM_PROGRAM_VERSION") || /^[0-2]\./.exec(getEnvVar("TERM_PROGRAM_VERSION")) !== null) {
38602
- return COLORS_256;
38603
- }
38399
+ if (!getEnvVar("TERM_PROGRAM_VERSION") || /^[0-2]\./.exec(getEnvVar("TERM_PROGRAM_VERSION")) !== null) return COLORS_256;
38604
38400
  return COLORS_16m;
38605
38401
  case "HyperTerm":
38606
38402
  case "MacTerm":
@@ -38608,27 +38404,15 @@ function getColorDepth() {
38608
38404
  case "Apple_Terminal":
38609
38405
  return COLORS_256;
38610
38406
  }
38611
- if (getEnvVar("COLORTERM") === "truecolor" || getEnvVar("COLORTERM") === "24bit") {
38612
- return COLORS_16m;
38613
- }
38407
+ if (getEnvVar("COLORTERM") === "truecolor" || getEnvVar("COLORTERM") === "24bit") return COLORS_16m;
38614
38408
  if (getEnvVar("TERM")) {
38615
- if (/truecolor/.exec(getEnvVar("TERM")) !== null) {
38616
- return COLORS_16m;
38617
- }
38618
- if (/^xterm-256/.exec(getEnvVar("TERM")) !== null) {
38619
- return COLORS_256;
38620
- }
38409
+ if (/truecolor/.exec(getEnvVar("TERM")) !== null) return COLORS_16m;
38410
+ if (/^xterm-256/.exec(getEnvVar("TERM")) !== null) return COLORS_256;
38621
38411
  const termEnv = getEnvVar("TERM").toLowerCase();
38622
- if (TERM_ENVS[termEnv]) {
38623
- return TERM_ENVS[termEnv];
38624
- }
38625
- if (TERM_ENVS_REG_EXP.some((term) => term.exec(termEnv) !== null)) {
38626
- return COLORS_16;
38627
- }
38628
- }
38629
- if (getEnvVar("COLORTERM")) {
38630
- return COLORS_16;
38412
+ if (TERM_ENVS[termEnv]) return TERM_ENVS[termEnv];
38413
+ if (TERM_ENVS_REG_EXP.some((term) => term.exec(termEnv) !== null)) return COLORS_16;
38631
38414
  }
38415
+ if (getEnvVar("COLORTERM")) return COLORS_16;
38632
38416
  return COLORS_2;
38633
38417
  }
38634
38418
  const TTY_COLORS = {
@@ -38643,9 +38427,15 @@ const TTY_COLORS = {
38643
38427
  magenta: "\x1B[35m"
38644
38428
  }
38645
38429
  };
38646
- const levels = ["info", "success", "warn", "error", "debug"];
38430
+ const levels = [
38431
+ "debug",
38432
+ "info",
38433
+ "success",
38434
+ "warn",
38435
+ "error"
38436
+ ];
38647
38437
  function shouldPublishLog(currentLogLevel, logLevel) {
38648
- return levels.indexOf(logLevel) <= levels.indexOf(currentLogLevel);
38438
+ return levels.indexOf(logLevel) >= levels.indexOf(currentLogLevel);
38649
38439
  }
38650
38440
  const levelColors = {
38651
38441
  info: TTY_COLORS.fg.blue,
@@ -38656,45 +38446,31 @@ const levelColors = {
38656
38446
  };
38657
38447
  const formatMessage = (level, message, colorsEnabled) => {
38658
38448
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
38659
- if (colorsEnabled) {
38660
- return `${TTY_COLORS.dim}${timestamp}${TTY_COLORS.reset} ${levelColors[level]}${level.toUpperCase()}${TTY_COLORS.reset} ${TTY_COLORS.bright}[Better Auth]:${TTY_COLORS.reset} ${message}`;
38661
- }
38449
+ if (colorsEnabled) return `${TTY_COLORS.dim}${timestamp}${TTY_COLORS.reset} ${levelColors[level]}${level.toUpperCase()}${TTY_COLORS.reset} ${TTY_COLORS.bright}[Better Auth]:${TTY_COLORS.reset} ${message}`;
38662
38450
  return `${timestamp} ${level.toUpperCase()} [Better Auth]: ${message}`;
38663
38451
  };
38664
38452
  const createLogger = (options) => {
38665
38453
  const logLevel = "error";
38666
38454
  const colorsEnabled = getColorDepth() !== 1;
38667
38455
  const LogFunc = (level, message, args = []) => {
38668
- if (!shouldPublishLog(logLevel, level)) {
38669
- return;
38670
- }
38456
+ if (!shouldPublishLog(logLevel, level)) return;
38671
38457
  const formattedMessage = formatMessage(level, message, colorsEnabled);
38672
38458
  {
38673
- if (level === "error") {
38674
- console.error(formattedMessage, ...args);
38675
- } else if (level === "warn") {
38676
- console.warn(formattedMessage, ...args);
38677
- } else {
38678
- console.log(formattedMessage, ...args);
38679
- }
38459
+ if (level === "error") console.error(formattedMessage, ...args);
38460
+ else if (level === "warn") console.warn(formattedMessage, ...args);
38461
+ else console.log(formattedMessage, ...args);
38680
38462
  return;
38681
38463
  }
38682
38464
  };
38683
- const logger2 = Object.fromEntries(
38684
- levels.map((level) => [
38685
- level,
38686
- (...[message, ...args]) => LogFunc(level, message, args)
38687
- ])
38688
- );
38689
38465
  return {
38690
- ...logger2,
38466
+ ...Object.fromEntries(levels.map((level) => [level, (...[message, ...args]) => LogFunc(level, message, args)])),
38691
38467
  get level() {
38692
38468
  return logLevel;
38693
38469
  }
38694
38470
  };
38695
38471
  };
38696
38472
  createLogger();
38697
- class BetterAuthError extends Error {
38473
+ var BetterAuthError = class extends Error {
38698
38474
  constructor(message, cause) {
38699
38475
  super(message);
38700
38476
  this.name = "BetterAuthError";
@@ -38702,44 +38478,106 @@ class BetterAuthError extends Error {
38702
38478
  this.cause = cause;
38703
38479
  this.stack = "";
38704
38480
  }
38705
- }
38481
+ };
38706
38482
  function checkHasPath(url) {
38483
+ try {
38484
+ return (new URL(url).pathname.replace(/\/+$/, "") || "/") !== "/";
38485
+ } catch (error) {
38486
+ throw new BetterAuthError(`Invalid base URL: ${url}. Please provide a valid base URL.`);
38487
+ }
38488
+ }
38489
+ function assertHasProtocol(url) {
38707
38490
  try {
38708
38491
  const parsedUrl = new URL(url);
38709
- const pathname = parsedUrl.pathname.replace(/\/+$/, "") || "/";
38710
- return pathname !== "/";
38492
+ if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") throw new BetterAuthError(`Invalid base URL: ${url}. URL must include 'http://' or 'https://'`);
38711
38493
  } catch (error) {
38712
- throw new BetterAuthError(
38713
- `Invalid base URL: ${url}. Please provide a valid base URL.`
38714
- );
38494
+ if (error instanceof BetterAuthError) throw error;
38495
+ throw new BetterAuthError(`Invalid base URL: ${url}. Please provide a valid base URL.`, String(error));
38715
38496
  }
38716
38497
  }
38717
38498
  function withPath(url, path = "/api/auth") {
38718
- const hasPath = checkHasPath(url);
38719
- if (hasPath) {
38720
- return url;
38721
- }
38499
+ assertHasProtocol(url);
38500
+ if (checkHasPath(url)) return url;
38722
38501
  const trimmedUrl = url.replace(/\/+$/, "");
38723
- if (!path || path === "/") {
38724
- return trimmedUrl;
38725
- }
38502
+ if (!path || path === "/") return trimmedUrl;
38726
38503
  path = path.startsWith("/") ? path : `/${path}`;
38727
38504
  return `${trimmedUrl}${path}`;
38728
38505
  }
38729
- function getBaseURL(url, path, request, loadEnv) {
38730
- if (url) {
38731
- return withPath(url, path);
38732
- }
38506
+ function getBaseURL(url, path, request, loadEnv, trustedProxyHeaders) {
38507
+ if (url) return withPath(url, path);
38733
38508
  {
38734
38509
  const fromEnv = env.BETTER_AUTH_URL || env.NEXT_PUBLIC_BETTER_AUTH_URL || env.PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_AUTH_URL || (env.BASE_URL !== "/" ? env.BASE_URL : void 0);
38735
- if (fromEnv) {
38736
- return withPath(fromEnv, path);
38737
- }
38510
+ if (fromEnv) return withPath(fromEnv, path);
38511
+ }
38512
+ if (typeof window !== "undefined" && window.location) return withPath(window.location.origin, path);
38513
+ }
38514
+ const PROTO_POLLUTION_PATTERNS = {
38515
+ proto: /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,
38516
+ constructor: /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,
38517
+ protoShort: /"__proto__"\s*:/,
38518
+ constructorShort: /"constructor"\s*:/
38519
+ };
38520
+ const JSON_SIGNATURE = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
38521
+ const SPECIAL_VALUES = {
38522
+ true: true,
38523
+ false: false,
38524
+ null: null,
38525
+ undefined: void 0,
38526
+ nan: NaN,
38527
+ infinity: Number.POSITIVE_INFINITY,
38528
+ "-infinity": Number.NEGATIVE_INFINITY
38529
+ };
38530
+ const ISO_DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,7}))?(?:Z|([+-])(\d{2}):(\d{2}))$/;
38531
+ function isValidDate(date2) {
38532
+ return date2 instanceof Date && !isNaN(date2.getTime());
38533
+ }
38534
+ function parseISODate(value) {
38535
+ const match = ISO_DATE_REGEX.exec(value);
38536
+ if (!match) return null;
38537
+ const [, year, month, day, hour, minute, second, ms, offsetSign, offsetHour, offsetMinute] = match;
38538
+ let date2 = new Date(Date.UTC(parseInt(year, 10), parseInt(month, 10) - 1, parseInt(day, 10), parseInt(hour, 10), parseInt(minute, 10), parseInt(second, 10), ms ? parseInt(ms.padEnd(3, "0"), 10) : 0));
38539
+ if (offsetSign) {
38540
+ const offset2 = (parseInt(offsetHour, 10) * 60 + parseInt(offsetMinute, 10)) * (offsetSign === "+" ? -1 : 1);
38541
+ date2.setUTCMinutes(date2.getUTCMinutes() + offset2);
38738
38542
  }
38739
- if (typeof window !== "undefined" && window.location) {
38740
- return withPath(window.location.origin, path);
38543
+ return isValidDate(date2) ? date2 : null;
38544
+ }
38545
+ function betterJSONParse(value, options = {}) {
38546
+ const { strict = false, warnings = false, reviver, parseDates = true } = options;
38547
+ if (typeof value !== "string") return value;
38548
+ const trimmed = value.trim();
38549
+ if (trimmed.length > 0 && trimmed[0] === '"' && trimmed.endsWith('"') && !trimmed.slice(1, -1).includes('"')) return trimmed.slice(1, -1);
38550
+ const lowerValue = trimmed.toLowerCase();
38551
+ if (lowerValue.length <= 9 && lowerValue in SPECIAL_VALUES) return SPECIAL_VALUES[lowerValue];
38552
+ if (!JSON_SIGNATURE.test(trimmed)) {
38553
+ if (strict) throw new SyntaxError("[better-json] Invalid JSON");
38554
+ return value;
38741
38555
  }
38742
- return void 0;
38556
+ if (Object.entries(PROTO_POLLUTION_PATTERNS).some(([key2, pattern]) => {
38557
+ const matches = pattern.test(trimmed);
38558
+ if (matches && warnings) console.warn(`[better-json] Detected potential prototype pollution attempt using ${key2} pattern`);
38559
+ return matches;
38560
+ }) && strict) throw new Error("[better-json] Potential prototype pollution attempt detected");
38561
+ try {
38562
+ const secureReviver = (key2, value$1) => {
38563
+ if (key2 === "__proto__" || key2 === "constructor" && value$1 && typeof value$1 === "object" && "prototype" in value$1) {
38564
+ if (warnings) console.warn(`[better-json] Dropping "${key2}" key to prevent prototype pollution`);
38565
+ return;
38566
+ }
38567
+ if (parseDates && typeof value$1 === "string") {
38568
+ const date2 = parseISODate(value$1);
38569
+ if (date2) return date2;
38570
+ }
38571
+ return reviver ? reviver(key2, value$1) : value$1;
38572
+ };
38573
+ return JSON.parse(trimmed, secureReviver);
38574
+ } catch (error) {
38575
+ if (strict) throw error;
38576
+ return value;
38577
+ }
38578
+ }
38579
+ function parseJSON(value, options = { strict: true }) {
38580
+ return betterJSONParse(value, options);
38743
38581
  }
38744
38582
  let listenerQueue = [];
38745
38583
  let lqIndex = 0;
@@ -38867,918 +38705,1073 @@ let onMount = ($store, initialize) => {
38867
38705
  };
38868
38706
  });
38869
38707
  };
38870
- const isServer = typeof window === "undefined";
38871
- const useAuthQuery = (initializedAtom, path, $fetch, options) => {
38872
- const value = /* @__PURE__ */ atom({
38873
- data: null,
38874
- error: null,
38875
- isPending: true,
38876
- isRefetching: false,
38877
- refetch: (queryParams) => {
38878
- return fn(queryParams);
38879
- }
38880
- });
38881
- const fn = (queryParams) => {
38882
- const opts = typeof options === "function" ? options({
38883
- data: value.get().data,
38884
- error: value.get().error,
38885
- isPending: value.get().isPending
38886
- }) : options;
38887
- $fetch(path, {
38888
- ...opts,
38889
- query: {
38890
- ...opts?.query,
38891
- ...queryParams?.query
38892
- },
38893
- async onSuccess(context) {
38894
- value.set({
38895
- data: context.data,
38896
- error: null,
38897
- isPending: false,
38898
- isRefetching: false,
38899
- refetch: value.value.refetch
38900
- });
38901
- await opts?.onSuccess?.(context);
38902
- },
38903
- async onError(context) {
38904
- const { request } = context;
38905
- const retryAttempts = typeof request.retry === "number" ? request.retry : request.retry?.attempts;
38906
- const retryAttempt = request.retryAttempt || 0;
38907
- if (retryAttempts && retryAttempt < retryAttempts) return;
38908
- value.set({
38909
- error: context.error,
38910
- data: null,
38911
- isPending: false,
38912
- isRefetching: false,
38913
- refetch: value.value.refetch
38914
- });
38915
- await opts?.onError?.(context);
38916
- },
38917
- async onRequest(context) {
38918
- const currentValue = value.get();
38919
- value.set({
38920
- isPending: currentValue.data === null,
38921
- data: currentValue.data,
38922
- error: null,
38923
- isRefetching: true,
38924
- refetch: value.value.refetch
38925
- });
38926
- await opts?.onRequest?.(context);
38927
- }
38928
- }).catch((error) => {
38929
- value.set({
38930
- error,
38931
- data: null,
38932
- isPending: false,
38933
- isRefetching: false,
38934
- refetch: value.value.refetch
38935
- });
38936
- });
38937
- };
38938
- initializedAtom = Array.isArray(initializedAtom) ? initializedAtom : [initializedAtom];
38939
- let isMounted = false;
38940
- for (const initAtom of initializedAtom) {
38941
- initAtom.subscribe(() => {
38942
- if (isServer) {
38943
- return;
38944
- }
38945
- if (isMounted) {
38946
- fn();
38947
- } else {
38948
- onMount(value, () => {
38949
- const timeoutId = setTimeout(() => {
38950
- if (!isMounted) {
38951
- fn();
38952
- isMounted = true;
38953
- }
38954
- }, 0);
38955
- return () => {
38956
- value.off();
38957
- initAtom.off();
38958
- clearTimeout(timeoutId);
38959
- };
38960
- });
38961
- }
38708
+ var __defProp = Object.defineProperty;
38709
+ var __defProps = Object.defineProperties;
38710
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
38711
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
38712
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
38713
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
38714
+ var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
38715
+ var __spreadValues = (a2, b) => {
38716
+ for (var prop in b || (b = {}))
38717
+ if (__hasOwnProp.call(b, prop))
38718
+ __defNormalProp(a2, prop, b[prop]);
38719
+ if (__getOwnPropSymbols)
38720
+ for (var prop of __getOwnPropSymbols(b)) {
38721
+ if (__propIsEnum.call(b, prop))
38722
+ __defNormalProp(a2, prop, b[prop]);
38723
+ }
38724
+ return a2;
38725
+ };
38726
+ var __spreadProps = (a2, b) => __defProps(a2, __getOwnPropDescs(b));
38727
+ var BetterFetchError = class extends Error {
38728
+ constructor(status, statusText, error) {
38729
+ super(statusText || status.toString(), {
38730
+ cause: error
38962
38731
  });
38732
+ this.status = status;
38733
+ this.statusText = statusText;
38734
+ this.error = error;
38963
38735
  }
38964
- return value;
38965
38736
  };
38966
- const PROTO_POLLUTION_PATTERNS = {
38967
- proto: /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,
38968
- constructor: /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,
38969
- protoShort: /"__proto__"\s*:/,
38970
- constructorShort: /"constructor"\s*:/
38737
+ var initializePlugins = async (url, options) => {
38738
+ var _a2, _b, _c, _d, _e2, _f;
38739
+ let opts = options || {};
38740
+ const hooks = {
38741
+ onRequest: [options == null ? void 0 : options.onRequest],
38742
+ onResponse: [options == null ? void 0 : options.onResponse],
38743
+ onSuccess: [options == null ? void 0 : options.onSuccess],
38744
+ onError: [options == null ? void 0 : options.onError],
38745
+ onRetry: [options == null ? void 0 : options.onRetry]
38746
+ };
38747
+ if (!options || !(options == null ? void 0 : options.plugins)) {
38748
+ return {
38749
+ url,
38750
+ options: opts,
38751
+ hooks
38752
+ };
38753
+ }
38754
+ for (const plugin of (options == null ? void 0 : options.plugins) || []) {
38755
+ if (plugin.init) {
38756
+ const pluginRes = await ((_a2 = plugin.init) == null ? void 0 : _a2.call(plugin, url.toString(), options));
38757
+ opts = pluginRes.options || opts;
38758
+ url = pluginRes.url;
38759
+ }
38760
+ hooks.onRequest.push((_b = plugin.hooks) == null ? void 0 : _b.onRequest);
38761
+ hooks.onResponse.push((_c = plugin.hooks) == null ? void 0 : _c.onResponse);
38762
+ hooks.onSuccess.push((_d = plugin.hooks) == null ? void 0 : _d.onSuccess);
38763
+ hooks.onError.push((_e2 = plugin.hooks) == null ? void 0 : _e2.onError);
38764
+ hooks.onRetry.push((_f = plugin.hooks) == null ? void 0 : _f.onRetry);
38765
+ }
38766
+ return {
38767
+ url,
38768
+ options: opts,
38769
+ hooks
38770
+ };
38971
38771
  };
38972
- const JSON_SIGNATURE = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
38973
- const SPECIAL_VALUES = {
38974
- true: true,
38975
- false: false,
38976
- null: null,
38977
- undefined: void 0,
38978
- nan: Number.NaN,
38979
- infinity: Number.POSITIVE_INFINITY,
38980
- "-infinity": Number.NEGATIVE_INFINITY
38772
+ var LinearRetryStrategy = class {
38773
+ constructor(options) {
38774
+ this.options = options;
38775
+ }
38776
+ shouldAttemptRetry(attempt, response) {
38777
+ if (this.options.shouldRetry) {
38778
+ return Promise.resolve(
38779
+ attempt < this.options.attempts && this.options.shouldRetry(response)
38780
+ );
38781
+ }
38782
+ return Promise.resolve(attempt < this.options.attempts);
38783
+ }
38784
+ getDelay() {
38785
+ return this.options.delay;
38786
+ }
38981
38787
  };
38982
- const ISO_DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,7}))?(?:Z|([+-])(\d{2}):(\d{2}))$/;
38983
- function isValidDate(date2) {
38984
- return date2 instanceof Date && !isNaN(date2.getTime());
38985
- }
38986
- function parseISODate(value) {
38987
- const match = ISO_DATE_REGEX.exec(value);
38988
- if (!match) return null;
38989
- const [
38990
- ,
38991
- year,
38992
- month,
38993
- day,
38994
- hour,
38995
- minute,
38996
- second,
38997
- ms,
38998
- offsetSign,
38999
- offsetHour,
39000
- offsetMinute
39001
- ] = match;
39002
- let date2 = new Date(
39003
- Date.UTC(
39004
- parseInt(year, 10),
39005
- parseInt(month, 10) - 1,
39006
- parseInt(day, 10),
39007
- parseInt(hour, 10),
39008
- parseInt(minute, 10),
39009
- parseInt(second, 10),
39010
- ms ? parseInt(ms.padEnd(3, "0"), 10) : 0
39011
- )
39012
- );
39013
- if (offsetSign) {
39014
- const offset2 = (parseInt(offsetHour, 10) * 60 + parseInt(offsetMinute, 10)) * (offsetSign === "+" ? -1 : 1);
39015
- date2.setUTCMinutes(date2.getUTCMinutes() + offset2);
38788
+ var ExponentialRetryStrategy = class {
38789
+ constructor(options) {
38790
+ this.options = options;
39016
38791
  }
39017
- return isValidDate(date2) ? date2 : null;
39018
- }
39019
- function betterJSONParse(value, options = {}) {
39020
- const {
39021
- strict = false,
39022
- warnings = false,
39023
- reviver,
39024
- parseDates = true
39025
- } = options;
39026
- if (typeof value !== "string") {
39027
- return value;
38792
+ shouldAttemptRetry(attempt, response) {
38793
+ if (this.options.shouldRetry) {
38794
+ return Promise.resolve(
38795
+ attempt < this.options.attempts && this.options.shouldRetry(response)
38796
+ );
38797
+ }
38798
+ return Promise.resolve(attempt < this.options.attempts);
39028
38799
  }
39029
- const trimmed = value.trim();
39030
- if (trimmed.length > 0 && trimmed[0] === '"' && trimmed.endsWith('"') && !trimmed.slice(1, -1).includes('"')) {
39031
- return trimmed.slice(1, -1);
38800
+ getDelay(attempt) {
38801
+ const delay2 = Math.min(
38802
+ this.options.maxDelay,
38803
+ this.options.baseDelay * 2 ** attempt
38804
+ );
38805
+ return delay2;
39032
38806
  }
39033
- const lowerValue = trimmed.toLowerCase();
39034
- if (lowerValue.length <= 9 && lowerValue in SPECIAL_VALUES) {
39035
- return SPECIAL_VALUES[lowerValue];
38807
+ };
38808
+ function createRetryStrategy(options) {
38809
+ if (typeof options === "number") {
38810
+ return new LinearRetryStrategy({
38811
+ type: "linear",
38812
+ attempts: options,
38813
+ delay: 1e3
38814
+ });
39036
38815
  }
39037
- if (!JSON_SIGNATURE.test(trimmed)) {
39038
- if (strict) {
39039
- throw new SyntaxError("[better-json] Invalid JSON");
39040
- }
39041
- return value;
38816
+ switch (options.type) {
38817
+ case "linear":
38818
+ return new LinearRetryStrategy(options);
38819
+ case "exponential":
38820
+ return new ExponentialRetryStrategy(options);
38821
+ default:
38822
+ throw new Error("Invalid retry strategy");
39042
38823
  }
39043
- const hasProtoPattern = Object.entries(PROTO_POLLUTION_PATTERNS).some(
39044
- ([key2, pattern]) => {
39045
- const matches = pattern.test(trimmed);
39046
- if (matches && warnings) {
39047
- console.warn(
39048
- `[better-json] Detected potential prototype pollution attempt using ${key2} pattern`
39049
- );
38824
+ }
38825
+ var getAuthHeader = async (options) => {
38826
+ const headers = {};
38827
+ const getValue = async (value) => typeof value === "function" ? await value() : value;
38828
+ if (options == null ? void 0 : options.auth) {
38829
+ if (options.auth.type === "Bearer") {
38830
+ const token = await getValue(options.auth.token);
38831
+ if (!token) {
38832
+ return headers;
39050
38833
  }
39051
- return matches;
39052
- }
39053
- );
39054
- if (hasProtoPattern && strict) {
39055
- throw new Error(
39056
- "[better-json] Potential prototype pollution attempt detected"
39057
- );
39058
- }
39059
- try {
39060
- const secureReviver = (key2, value2) => {
39061
- if (key2 === "__proto__" || key2 === "constructor" && value2 && typeof value2 === "object" && "prototype" in value2) {
39062
- if (warnings) {
39063
- console.warn(
39064
- `[better-json] Dropping "${key2}" key to prevent prototype pollution`
39065
- );
39066
- }
39067
- return void 0;
38834
+ headers["authorization"] = `Bearer ${token}`;
38835
+ } else if (options.auth.type === "Basic") {
38836
+ const username = getValue(options.auth.username);
38837
+ const password = getValue(options.auth.password);
38838
+ if (!username || !password) {
38839
+ return headers;
39068
38840
  }
39069
- if (parseDates && typeof value2 === "string") {
39070
- const date2 = parseISODate(value2);
39071
- if (date2) {
39072
- return date2;
39073
- }
38841
+ headers["authorization"] = `Basic ${btoa(`${username}:${password}`)}`;
38842
+ } else if (options.auth.type === "Custom") {
38843
+ const value = getValue(options.auth.value);
38844
+ if (!value) {
38845
+ return headers;
39074
38846
  }
39075
- return reviver ? reviver(key2, value2) : value2;
39076
- };
39077
- return JSON.parse(trimmed, secureReviver);
39078
- } catch (error) {
39079
- if (strict) {
39080
- throw error;
38847
+ headers["authorization"] = `${getValue(options.auth.prefix)} ${value}`;
39081
38848
  }
39082
- return value;
39083
38849
  }
38850
+ return headers;
38851
+ };
38852
+ var JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
38853
+ function detectResponseType(request) {
38854
+ const _contentType = request.headers.get("content-type");
38855
+ const textTypes = /* @__PURE__ */ new Set([
38856
+ "image/svg",
38857
+ "application/xml",
38858
+ "application/xhtml",
38859
+ "application/html"
38860
+ ]);
38861
+ if (!_contentType) {
38862
+ return "json";
38863
+ }
38864
+ const contentType = _contentType.split(";").shift() || "";
38865
+ if (JSON_RE.test(contentType)) {
38866
+ return "json";
38867
+ }
38868
+ if (textTypes.has(contentType) || contentType.startsWith("text/")) {
38869
+ return "text";
38870
+ }
38871
+ return "blob";
39084
38872
  }
39085
- function parseJSON(value, options = { strict: true }) {
39086
- return betterJSONParse(value, options);
39087
- }
39088
- const redirectPlugin = {
39089
- id: "redirect",
39090
- name: "Redirect",
39091
- hooks: {
39092
- onSuccess(context) {
39093
- if (context.data?.url && context.data?.redirect) {
39094
- if (typeof window !== "undefined" && window.location) {
39095
- if (window.location) {
39096
- try {
39097
- window.location.href = context.data.url;
39098
- } catch {
39099
- }
39100
- }
39101
- }
39102
- }
39103
- }
38873
+ function isJSONParsable(value) {
38874
+ try {
38875
+ JSON.parse(value);
38876
+ return true;
38877
+ } catch (error) {
38878
+ return false;
39104
38879
  }
39105
- };
39106
- function getSessionAtom($fetch) {
39107
- const $signal = /* @__PURE__ */ atom(false);
39108
- const session = useAuthQuery($signal, "/get-session", $fetch, {
39109
- method: "GET"
39110
- });
39111
- return {
39112
- session,
39113
- $sessionSignal: $signal
39114
- };
39115
38880
  }
39116
- const getClientConfig = (options, loadEnv) => {
39117
- const isCredentialsSupported = "credentials" in Request.prototype;
39118
- const baseURL = getBaseURL(options?.baseURL, options?.basePath) ?? "/api/auth";
39119
- const pluginsFetchPlugins = options?.plugins?.flatMap((plugin) => plugin.fetchPlugins).filter((pl) => pl !== void 0) || [];
39120
- const lifeCyclePlugin = {
39121
- id: "lifecycle-hooks",
39122
- name: "lifecycle-hooks",
39123
- hooks: {
39124
- onSuccess: options?.fetchOptions?.onSuccess,
39125
- onError: options?.fetchOptions?.onError,
39126
- onRequest: options?.fetchOptions?.onRequest,
39127
- onResponse: options?.fetchOptions?.onResponse
39128
- }
39129
- };
39130
- const { onSuccess, onError, onRequest, onResponse, ...restOfFetchOptions } = options?.fetchOptions || {};
39131
- const $fetch = createFetch({
39132
- baseURL,
39133
- ...isCredentialsSupported ? { credentials: "include" } : {},
39134
- method: "GET",
39135
- jsonParser(text) {
39136
- if (!text) {
39137
- return null;
39138
- }
39139
- return parseJSON(text, {
39140
- strict: false
39141
- });
39142
- },
39143
- customFetchImpl: fetch,
39144
- ...restOfFetchOptions,
39145
- plugins: [
39146
- lifeCyclePlugin,
39147
- ...restOfFetchOptions.plugins || [],
39148
- ...options?.disableDefaultFetchPlugins ? [] : [redirectPlugin],
39149
- ...pluginsFetchPlugins
39150
- ]
39151
- });
39152
- const { $sessionSignal, session } = getSessionAtom($fetch);
39153
- const plugins = options?.plugins || [];
39154
- let pluginsActions = {};
39155
- let pluginsAtoms = {
39156
- $sessionSignal,
39157
- session
39158
- };
39159
- let pluginPathMethods = {
39160
- "/sign-out": "POST",
39161
- "/revoke-sessions": "POST",
39162
- "/revoke-other-sessions": "POST",
39163
- "/delete-user": "POST"
39164
- };
39165
- const atomListeners = [
39166
- {
39167
- signal: "$sessionSignal",
39168
- matcher(path) {
39169
- return path === "/sign-out" || path === "/update-user" || path.startsWith("/sign-in") || path.startsWith("/sign-up") || path === "/delete-user" || path === "/verify-email";
39170
- }
39171
- }
39172
- ];
39173
- for (const plugin of plugins) {
39174
- if (plugin.getAtoms) {
39175
- Object.assign(pluginsAtoms, plugin.getAtoms?.($fetch));
39176
- }
39177
- if (plugin.pathMethods) {
39178
- Object.assign(pluginPathMethods, plugin.pathMethods);
39179
- }
39180
- if (plugin.atomListeners) {
39181
- atomListeners.push(...plugin.atomListeners);
39182
- }
38881
+ function isJSONSerializable(value) {
38882
+ if (value === void 0) {
38883
+ return false;
39183
38884
  }
39184
- const $store = {
39185
- notify: (signal) => {
39186
- pluginsAtoms[signal].set(
39187
- !pluginsAtoms[signal].get()
39188
- );
39189
- },
39190
- listen: (signal, listener) => {
39191
- pluginsAtoms[signal].subscribe(listener);
39192
- },
39193
- atoms: pluginsAtoms
39194
- };
39195
- for (const plugin of plugins) {
39196
- if (plugin.getActions) {
39197
- Object.assign(
39198
- pluginsActions,
39199
- plugin.getActions?.($fetch, $store, options)
39200
- );
39201
- }
38885
+ const t2 = typeof value;
38886
+ if (t2 === "string" || t2 === "number" || t2 === "boolean" || t2 === null) {
38887
+ return true;
39202
38888
  }
39203
- return {
39204
- get baseURL() {
39205
- return baseURL;
39206
- },
39207
- pluginsActions,
39208
- pluginsAtoms,
39209
- pluginPathMethods,
39210
- atomListeners,
39211
- $fetch,
39212
- $store
39213
- };
39214
- };
39215
- function isAtom(value) {
39216
- return typeof value === "object" && value !== null && "get" in value && typeof value.get === "function" && "lc" in value && typeof value.lc === "number";
39217
- }
39218
- function getMethod(path, knownPathMethods, args) {
39219
- const method = knownPathMethods[path];
39220
- const { fetchOptions, query, ...body } = args || {};
39221
- if (method) {
39222
- return method;
38889
+ if (t2 !== "object") {
38890
+ return false;
39223
38891
  }
39224
- if (fetchOptions?.method) {
39225
- return fetchOptions.method;
38892
+ if (Array.isArray(value)) {
38893
+ return true;
39226
38894
  }
39227
- if (body && Object.keys(body).length > 0) {
39228
- return "POST";
38895
+ if (value.buffer) {
38896
+ return false;
39229
38897
  }
39230
- return "GET";
38898
+ return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
39231
38899
  }
39232
- function createDynamicPathProxy(routes, client2, knownPathMethods, atoms, atomListeners) {
39233
- function createProxy(path = []) {
39234
- return new Proxy(function() {
39235
- }, {
39236
- get(_2, prop) {
39237
- if (typeof prop !== "string") {
39238
- return void 0;
39239
- }
39240
- if (prop === "then" || prop === "catch" || prop === "finally") {
39241
- return void 0;
39242
- }
39243
- const fullPath = [...path, prop];
39244
- let current = routes;
39245
- for (const segment of fullPath) {
39246
- if (current && typeof current === "object" && segment in current) {
39247
- current = current[segment];
39248
- } else {
39249
- current = void 0;
39250
- break;
39251
- }
39252
- }
39253
- if (typeof current === "function") {
39254
- return current;
39255
- }
39256
- if (isAtom(current)) {
39257
- return current;
39258
- }
39259
- return createProxy(fullPath);
39260
- },
39261
- apply: async (_2, __, args) => {
39262
- const routePath = "/" + path.map(
39263
- (segment) => segment.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)
39264
- ).join("/");
39265
- const arg = args[0] || {};
39266
- const fetchOptions = args[1] || {};
39267
- const { query, fetchOptions: argFetchOptions, ...body } = arg;
39268
- const options = {
39269
- ...fetchOptions,
39270
- ...argFetchOptions
39271
- };
39272
- const method = getMethod(routePath, knownPathMethods, arg);
39273
- return await client2(routePath, {
39274
- ...options,
39275
- body: method === "GET" ? void 0 : {
39276
- ...body,
39277
- ...options?.body || {}
39278
- },
39279
- query: query || options?.query,
39280
- method,
39281
- async onSuccess(context) {
39282
- await options?.onSuccess?.(context);
39283
- if (!atomListeners) return;
39284
- const matches = atomListeners.filter((s2) => s2.matcher(routePath));
39285
- if (!matches.length) return;
39286
- for (const match of matches) {
39287
- const signal = atoms[match.signal];
39288
- if (!signal) return;
39289
- const val = signal.get();
39290
- setTimeout(() => {
39291
- signal.set(!val);
39292
- }, 10);
39293
- }
39294
- }
39295
- });
39296
- }
39297
- });
38900
+ function jsonParse(text) {
38901
+ try {
38902
+ return JSON.parse(text);
38903
+ } catch (error) {
38904
+ return text;
39298
38905
  }
39299
- return createProxy();
39300
38906
  }
39301
- function capitalizeFirstLetter(str) {
39302
- return str.charAt(0).toUpperCase() + str.slice(1);
38907
+ function isFunction$1(value) {
38908
+ return typeof value === "function";
38909
+ }
38910
+ function getFetch(options) {
38911
+ if (options == null ? void 0 : options.customFetchImpl) {
38912
+ return options.customFetchImpl;
38913
+ }
38914
+ if (typeof globalThis !== "undefined" && isFunction$1(globalThis.fetch)) {
38915
+ return globalThis.fetch;
38916
+ }
38917
+ if (typeof window !== "undefined" && isFunction$1(window.fetch)) {
38918
+ return window.fetch;
38919
+ }
38920
+ throw new Error("No fetch implementation found");
39303
38921
  }
39304
- function createAuthClient(options) {
39305
- const {
39306
- pluginPathMethods,
39307
- pluginsActions,
39308
- pluginsAtoms,
39309
- $fetch,
39310
- atomListeners,
39311
- $store
39312
- } = getClientConfig(options);
39313
- let resolvedHooks = {};
39314
- for (const [key2, value] of Object.entries(pluginsAtoms)) {
39315
- resolvedHooks[`use${capitalizeFirstLetter(key2)}`] = value;
38922
+ async function getHeaders(opts) {
38923
+ const headers = new Headers(opts == null ? void 0 : opts.headers);
38924
+ const authHeader = await getAuthHeader(opts);
38925
+ for (const [key2, value] of Object.entries(authHeader || {})) {
38926
+ headers.set(key2, value);
39316
38927
  }
39317
- const routes = {
39318
- ...pluginsActions,
39319
- ...resolvedHooks,
39320
- $fetch,
39321
- $store
39322
- };
39323
- const proxy = createDynamicPathProxy(
39324
- routes,
39325
- $fetch,
39326
- pluginPathMethods,
39327
- pluginsAtoms,
39328
- atomListeners
39329
- );
39330
- return proxy;
38928
+ if (!headers.has("content-type")) {
38929
+ const t2 = detectContentType(opts == null ? void 0 : opts.body);
38930
+ if (t2) {
38931
+ headers.set("content-type", t2);
38932
+ }
38933
+ }
38934
+ return headers;
39331
38935
  }
39332
- function bufferToBase64URLString(buffer) {
39333
- const bytes = new Uint8Array(buffer);
39334
- let str = "";
39335
- for (const charCode of bytes) {
39336
- str += String.fromCharCode(charCode);
38936
+ function detectContentType(body) {
38937
+ if (isJSONSerializable(body)) {
38938
+ return "application/json";
39337
38939
  }
39338
- const base64String = btoa(str);
39339
- return base64String.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
38940
+ return null;
39340
38941
  }
39341
- function base64URLStringToBuffer(base64URLString) {
39342
- const base642 = base64URLString.replace(/-/g, "+").replace(/_/g, "/");
39343
- const padLength = (4 - base642.length % 4) % 4;
39344
- const padded = base642.padEnd(base642.length + padLength, "=");
39345
- const binary = atob(padded);
39346
- const buffer = new ArrayBuffer(binary.length);
39347
- const bytes = new Uint8Array(buffer);
39348
- for (let i2 = 0; i2 < binary.length; i2++) {
39349
- bytes[i2] = binary.charCodeAt(i2);
38942
+ function getBody(options) {
38943
+ if (!(options == null ? void 0 : options.body)) {
38944
+ return null;
39350
38945
  }
39351
- return buffer;
38946
+ const headers = new Headers(options == null ? void 0 : options.headers);
38947
+ if (isJSONSerializable(options.body) && !headers.has("content-type")) {
38948
+ for (const [key2, value] of Object.entries(options == null ? void 0 : options.body)) {
38949
+ if (value instanceof Date) {
38950
+ options.body[key2] = value.toISOString();
38951
+ }
38952
+ }
38953
+ return JSON.stringify(options.body);
38954
+ }
38955
+ return options.body;
39352
38956
  }
39353
- function browserSupportsWebAuthn() {
39354
- return _browserSupportsWebAuthnInternals.stubThis(globalThis?.PublicKeyCredential !== void 0 && typeof globalThis.PublicKeyCredential === "function");
38957
+ function getMethod$1(url, options) {
38958
+ var _a2;
38959
+ if (options == null ? void 0 : options.method) {
38960
+ return options.method.toUpperCase();
38961
+ }
38962
+ if (url.startsWith("@")) {
38963
+ const pMethod = (_a2 = url.split("@")[1]) == null ? void 0 : _a2.split("/")[0];
38964
+ if (!methods.includes(pMethod)) {
38965
+ return (options == null ? void 0 : options.body) ? "POST" : "GET";
38966
+ }
38967
+ return pMethod.toUpperCase();
38968
+ }
38969
+ return (options == null ? void 0 : options.body) ? "POST" : "GET";
39355
38970
  }
39356
- const _browserSupportsWebAuthnInternals = {
39357
- stubThis: (value) => value
39358
- };
39359
- function toPublicKeyCredentialDescriptor(descriptor) {
39360
- const { id: id2 } = descriptor;
38971
+ function getTimeout(options, controller) {
38972
+ let abortTimeout;
38973
+ if (!(options == null ? void 0 : options.signal) && (options == null ? void 0 : options.timeout)) {
38974
+ abortTimeout = setTimeout(() => controller == null ? void 0 : controller.abort(), options == null ? void 0 : options.timeout);
38975
+ }
39361
38976
  return {
39362
- ...descriptor,
39363
- id: base64URLStringToBuffer(id2),
39364
- /**
39365
- * `descriptor.transports` is an array of our `AuthenticatorTransportFuture` that includes newer
39366
- * transports that TypeScript's DOM lib is ignorant of. Convince TS that our list of transports
39367
- * are fine to pass to WebAuthn since browsers will recognize the new value.
39368
- */
39369
- transports: descriptor.transports
38977
+ abortTimeout,
38978
+ clearTimeout: () => {
38979
+ if (abortTimeout) {
38980
+ clearTimeout(abortTimeout);
38981
+ }
38982
+ }
39370
38983
  };
39371
38984
  }
39372
- function isValidDomain(hostname) {
39373
- return (
39374
- // Consider localhost valid as well since it's okay wrt Secure Contexts
39375
- hostname === "localhost" || /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname)
39376
- );
39377
- }
39378
- class WebAuthnError extends Error {
39379
- constructor({ message, code, cause, name }) {
39380
- super(message, { cause });
39381
- Object.defineProperty(this, "code", {
39382
- enumerable: true,
39383
- configurable: true,
39384
- writable: true,
39385
- value: void 0
39386
- });
39387
- this.name = name ?? cause.name;
39388
- this.code = code;
38985
+ var ValidationError = class _ValidationError extends Error {
38986
+ constructor(issues, message) {
38987
+ super(message || JSON.stringify(issues, null, 2));
38988
+ this.issues = issues;
38989
+ Object.setPrototypeOf(this, _ValidationError.prototype);
39389
38990
  }
39390
- }
39391
- function identifyRegistrationError({ error, options }) {
39392
- const { publicKey } = options;
39393
- if (!publicKey) {
39394
- throw Error("options was missing required publicKey property");
38991
+ };
38992
+ async function parseStandardSchema(schema, input) {
38993
+ let result = await schema["~standard"].validate(input);
38994
+ if (result.issues) {
38995
+ throw new ValidationError(result.issues);
39395
38996
  }
39396
- if (error.name === "AbortError") {
39397
- if (options.signal instanceof AbortSignal) {
39398
- return new WebAuthnError({
39399
- message: "Registration ceremony was sent an abort signal",
39400
- code: "ERROR_CEREMONY_ABORTED",
39401
- cause: error
39402
- });
39403
- }
39404
- } else if (error.name === "ConstraintError") {
39405
- if (publicKey.authenticatorSelection?.requireResidentKey === true) {
39406
- return new WebAuthnError({
39407
- message: "Discoverable credentials were required but no available authenticator supported it",
39408
- code: "ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",
39409
- cause: error
39410
- });
39411
- } else if (
39412
- // @ts-ignore: `mediation` doesn't yet exist on CredentialCreationOptions but it's possible as of Sept 2024
39413
- options.mediation === "conditional" && publicKey.authenticatorSelection?.userVerification === "required"
39414
- ) {
39415
- return new WebAuthnError({
39416
- message: "User verification was required during automatic registration but it could not be performed",
39417
- code: "ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",
39418
- cause: error
39419
- });
39420
- } else if (publicKey.authenticatorSelection?.userVerification === "required") {
39421
- return new WebAuthnError({
39422
- message: "User verification was required but no available authenticator supported it",
39423
- code: "ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",
39424
- cause: error
39425
- });
39426
- }
39427
- } else if (error.name === "InvalidStateError") {
39428
- return new WebAuthnError({
39429
- message: "The authenticator was previously registered",
39430
- code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",
39431
- cause: error
39432
- });
39433
- } else if (error.name === "NotAllowedError") {
39434
- return new WebAuthnError({
39435
- message: error.message,
39436
- code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
39437
- cause: error
39438
- });
39439
- } else if (error.name === "NotSupportedError") {
39440
- const validPubKeyCredParams = publicKey.pubKeyCredParams.filter((param) => param.type === "public-key");
39441
- if (validPubKeyCredParams.length === 0) {
39442
- return new WebAuthnError({
39443
- message: 'No entry in pubKeyCredParams was of type "public-key"',
39444
- code: "ERROR_MALFORMED_PUBKEYCREDPARAMS",
39445
- cause: error
39446
- });
39447
- }
39448
- return new WebAuthnError({
39449
- message: "No available authenticator supported any of the specified pubKeyCredParams algorithms",
39450
- code: "ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",
39451
- cause: error
39452
- });
39453
- } else if (error.name === "SecurityError") {
39454
- const effectiveDomain = globalThis.location.hostname;
39455
- if (!isValidDomain(effectiveDomain)) {
39456
- return new WebAuthnError({
39457
- message: `${globalThis.location.hostname} is an invalid domain`,
39458
- code: "ERROR_INVALID_DOMAIN",
39459
- cause: error
39460
- });
39461
- } else if (publicKey.rp.id !== effectiveDomain) {
39462
- return new WebAuthnError({
39463
- message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`,
39464
- code: "ERROR_INVALID_RP_ID",
39465
- cause: error
39466
- });
39467
- }
39468
- } else if (error.name === "TypeError") {
39469
- if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) {
39470
- return new WebAuthnError({
39471
- message: "User ID was not between 1 and 64 characters",
39472
- code: "ERROR_INVALID_USER_ID_LENGTH",
39473
- cause: error
39474
- });
38997
+ return result.value;
38998
+ }
38999
+ var methods = ["get", "post", "put", "patch", "delete"];
39000
+ var applySchemaPlugin = (config2) => ({
39001
+ id: "apply-schema",
39002
+ name: "Apply Schema",
39003
+ version: "1.0.0",
39004
+ async init(url, options) {
39005
+ var _a2, _b, _c, _d;
39006
+ const schema = ((_b = (_a2 = config2.plugins) == null ? void 0 : _a2.find(
39007
+ (plugin) => {
39008
+ var _a22;
39009
+ return ((_a22 = plugin.schema) == null ? void 0 : _a22.config) ? url.startsWith(plugin.schema.config.baseURL || "") || url.startsWith(plugin.schema.config.prefix || "") : false;
39010
+ }
39011
+ )) == null ? void 0 : _b.schema) || config2.schema;
39012
+ if (schema) {
39013
+ let urlKey = url;
39014
+ if ((_c = schema.config) == null ? void 0 : _c.prefix) {
39015
+ if (urlKey.startsWith(schema.config.prefix)) {
39016
+ urlKey = urlKey.replace(schema.config.prefix, "");
39017
+ if (schema.config.baseURL) {
39018
+ url = url.replace(schema.config.prefix, schema.config.baseURL);
39019
+ }
39020
+ }
39021
+ }
39022
+ if ((_d = schema.config) == null ? void 0 : _d.baseURL) {
39023
+ if (urlKey.startsWith(schema.config.baseURL)) {
39024
+ urlKey = urlKey.replace(schema.config.baseURL, "");
39025
+ }
39026
+ }
39027
+ const keySchema = schema.schema[urlKey];
39028
+ if (keySchema) {
39029
+ let opts = __spreadProps(__spreadValues({}, options), {
39030
+ method: keySchema.method,
39031
+ output: keySchema.output
39032
+ });
39033
+ if (!(options == null ? void 0 : options.disableValidation)) {
39034
+ opts = __spreadProps(__spreadValues({}, opts), {
39035
+ body: keySchema.input ? await parseStandardSchema(keySchema.input, options == null ? void 0 : options.body) : options == null ? void 0 : options.body,
39036
+ params: keySchema.params ? await parseStandardSchema(keySchema.params, options == null ? void 0 : options.params) : options == null ? void 0 : options.params,
39037
+ query: keySchema.query ? await parseStandardSchema(keySchema.query, options == null ? void 0 : options.query) : options == null ? void 0 : options.query
39038
+ });
39039
+ }
39040
+ return {
39041
+ url,
39042
+ options: opts
39043
+ };
39044
+ }
39475
39045
  }
39476
- } else if (error.name === "UnknownError") {
39477
- return new WebAuthnError({
39478
- message: "The authenticator was unable to process the specified options, or could not create a new credential",
39479
- code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
39480
- cause: error
39481
- });
39046
+ return {
39047
+ url,
39048
+ options
39049
+ };
39482
39050
  }
39483
- return error;
39484
- }
39485
- class BaseWebAuthnAbortService {
39486
- constructor() {
39487
- Object.defineProperty(this, "controller", {
39488
- enumerable: true,
39489
- configurable: true,
39490
- writable: true,
39491
- value: void 0
39051
+ });
39052
+ var createFetch = (config2) => {
39053
+ async function $fetch(url, options) {
39054
+ const opts = __spreadProps(__spreadValues(__spreadValues({}, config2), options), {
39055
+ plugins: [...(config2 == null ? void 0 : config2.plugins) || [], applySchemaPlugin(config2 || {})]
39492
39056
  });
39493
- }
39494
- createNewAbortSignal() {
39495
- if (this.controller) {
39496
- const abortError = new Error("Cancelling existing WebAuthn API call for new one");
39497
- abortError.name = "AbortError";
39498
- this.controller.abort(abortError);
39057
+ if (config2 == null ? void 0 : config2.catchAllError) {
39058
+ try {
39059
+ return await betterFetch(url, opts);
39060
+ } catch (error) {
39061
+ return {
39062
+ data: null,
39063
+ error: {
39064
+ status: 500,
39065
+ statusText: "Fetch Error",
39066
+ message: "Fetch related error. Captured by catchAllError option. See error property for more details.",
39067
+ error
39068
+ }
39069
+ };
39070
+ }
39499
39071
  }
39500
- const newController = new AbortController();
39501
- this.controller = newController;
39502
- return newController.signal;
39072
+ return await betterFetch(url, opts);
39503
39073
  }
39504
- cancelCeremony() {
39505
- if (this.controller) {
39506
- const abortError = new Error("Manually cancelling existing WebAuthn API call");
39507
- abortError.name = "AbortError";
39508
- this.controller.abort(abortError);
39509
- this.controller = void 0;
39074
+ return $fetch;
39075
+ };
39076
+ function getURL2(url, option) {
39077
+ let { baseURL, params, query } = option || {
39078
+ query: {},
39079
+ params: {},
39080
+ baseURL: ""
39081
+ };
39082
+ let basePath = url.startsWith("http") ? url.split("/").slice(0, 3).join("/") : baseURL || "";
39083
+ if (url.startsWith("@")) {
39084
+ const m2 = url.toString().split("@")[1].split("/")[0];
39085
+ if (methods.includes(m2)) {
39086
+ url = url.replace(`@${m2}/`, "/");
39510
39087
  }
39511
39088
  }
39512
- }
39513
- const WebAuthnAbortService = new BaseWebAuthnAbortService();
39514
- const attachments = ["cross-platform", "platform"];
39515
- function toAuthenticatorAttachment(attachment) {
39516
- if (!attachment) {
39517
- return;
39089
+ if (!basePath.endsWith("/")) basePath += "/";
39090
+ let [path, urlQuery] = url.replace(basePath, "").split("?");
39091
+ const queryParams = new URLSearchParams(urlQuery);
39092
+ for (const [key2, value] of Object.entries(query || {})) {
39093
+ if (value == null) continue;
39094
+ queryParams.set(key2, String(value));
39518
39095
  }
39519
- if (attachments.indexOf(attachment) < 0) {
39520
- return;
39096
+ if (params) {
39097
+ if (Array.isArray(params)) {
39098
+ const paramPaths = path.split("/").filter((p2) => p2.startsWith(":"));
39099
+ for (const [index2, key2] of paramPaths.entries()) {
39100
+ const value = params[index2];
39101
+ path = path.replace(key2, value);
39102
+ }
39103
+ } else {
39104
+ for (const [key2, value] of Object.entries(params)) {
39105
+ path = path.replace(`:${key2}`, String(value));
39106
+ }
39107
+ }
39521
39108
  }
39522
- return attachment;
39109
+ path = path.split("/").map(encodeURIComponent).join("/");
39110
+ if (path.startsWith("/")) path = path.slice(1);
39111
+ let queryParamString = queryParams.toString();
39112
+ queryParamString = queryParamString.length > 0 ? `?${queryParamString}`.replace(/\+/g, "%20") : "";
39113
+ if (!basePath.startsWith("http")) {
39114
+ return `${basePath}${path}${queryParamString}`;
39115
+ }
39116
+ const _url2 = new URL(`${path}${queryParamString}`, basePath);
39117
+ return _url2;
39523
39118
  }
39524
- async function startRegistration(options) {
39525
- if (!options.optionsJSON && options.challenge) {
39526
- console.warn("startRegistration() was not called correctly. It will try to continue with the provided options, but this call should be refactored to use the expected call structure instead. See https://simplewebauthn.dev/docs/packages/browser#typeerror-cannot-read-properties-of-undefined-reading-challenge for more information.");
39527
- options = { optionsJSON: options };
39119
+ var betterFetch = async (url, options) => {
39120
+ var _a2, _b, _c, _d, _e2, _f, _g, _h;
39121
+ const {
39122
+ hooks,
39123
+ url: __url,
39124
+ options: opts
39125
+ } = await initializePlugins(url, options);
39126
+ const fetch2 = getFetch(opts);
39127
+ const controller = new AbortController();
39128
+ const signal = (_a2 = opts.signal) != null ? _a2 : controller.signal;
39129
+ const _url2 = getURL2(__url, opts);
39130
+ const body = getBody(opts);
39131
+ const headers = await getHeaders(opts);
39132
+ const method = getMethod$1(__url, opts);
39133
+ let context = __spreadProps(__spreadValues({}, opts), {
39134
+ url: _url2,
39135
+ headers,
39136
+ body,
39137
+ method,
39138
+ signal
39139
+ });
39140
+ for (const onRequest of hooks.onRequest) {
39141
+ if (onRequest) {
39142
+ const res = await onRequest(context);
39143
+ if (res instanceof Object) {
39144
+ context = res;
39145
+ }
39146
+ }
39528
39147
  }
39529
- const { optionsJSON, useAutoRegister = false } = options;
39530
- if (!browserSupportsWebAuthn()) {
39531
- throw new Error("WebAuthn is not supported in this browser");
39148
+ if ("pipeTo" in context && typeof context.pipeTo === "function" || typeof ((_b = options == null ? void 0 : options.body) == null ? void 0 : _b.pipe) === "function") {
39149
+ if (!("duplex" in context)) {
39150
+ context.duplex = "half";
39151
+ }
39532
39152
  }
39533
- const publicKey = {
39534
- ...optionsJSON,
39535
- challenge: base64URLStringToBuffer(optionsJSON.challenge),
39536
- user: {
39537
- ...optionsJSON.user,
39538
- id: base64URLStringToBuffer(optionsJSON.user.id)
39539
- },
39540
- excludeCredentials: optionsJSON.excludeCredentials?.map(toPublicKeyCredentialDescriptor)
39153
+ const { clearTimeout: clearTimeout2 } = getTimeout(opts, controller);
39154
+ let response = await fetch2(context.url, context);
39155
+ clearTimeout2();
39156
+ const responseContext = {
39157
+ response,
39158
+ request: context
39541
39159
  };
39542
- const createOptions = {};
39543
- if (useAutoRegister) {
39544
- createOptions.mediation = "conditional";
39545
- }
39546
- createOptions.publicKey = publicKey;
39547
- createOptions.signal = WebAuthnAbortService.createNewAbortSignal();
39548
- let credential;
39549
- try {
39550
- credential = await navigator.credentials.create(createOptions);
39551
- } catch (err) {
39552
- throw identifyRegistrationError({ error: err, options: createOptions });
39553
- }
39554
- if (!credential) {
39555
- throw new Error("Registration was not completed");
39160
+ for (const onResponse of hooks.onResponse) {
39161
+ if (onResponse) {
39162
+ const r2 = await onResponse(__spreadProps(__spreadValues({}, responseContext), {
39163
+ response: ((_c = options == null ? void 0 : options.hookOptions) == null ? void 0 : _c.cloneResponse) ? response.clone() : response
39164
+ }));
39165
+ if (r2 instanceof Response) {
39166
+ response = r2;
39167
+ } else if (r2 instanceof Object) {
39168
+ response = r2.response;
39169
+ }
39170
+ }
39556
39171
  }
39557
- const { id: id2, rawId, response, type } = credential;
39558
- let transports = void 0;
39559
- if (typeof response.getTransports === "function") {
39560
- transports = response.getTransports();
39172
+ if (response.ok) {
39173
+ const hasBody = context.method !== "HEAD";
39174
+ if (!hasBody) {
39175
+ return {
39176
+ data: "",
39177
+ error: null
39178
+ };
39179
+ }
39180
+ const responseType = detectResponseType(response);
39181
+ const successContext = {
39182
+ data: "",
39183
+ response,
39184
+ request: context
39185
+ };
39186
+ if (responseType === "json" || responseType === "text") {
39187
+ const text = await response.text();
39188
+ const parser2 = (_d = context.jsonParser) != null ? _d : jsonParse;
39189
+ const data = await parser2(text);
39190
+ successContext.data = data;
39191
+ } else {
39192
+ successContext.data = await response[responseType]();
39193
+ }
39194
+ if (context == null ? void 0 : context.output) {
39195
+ if (context.output && !context.disableValidation) {
39196
+ successContext.data = await parseStandardSchema(
39197
+ context.output,
39198
+ successContext.data
39199
+ );
39200
+ }
39201
+ }
39202
+ for (const onSuccess of hooks.onSuccess) {
39203
+ if (onSuccess) {
39204
+ await onSuccess(__spreadProps(__spreadValues({}, successContext), {
39205
+ response: ((_e2 = options == null ? void 0 : options.hookOptions) == null ? void 0 : _e2.cloneResponse) ? response.clone() : response
39206
+ }));
39207
+ }
39208
+ }
39209
+ if (options == null ? void 0 : options.throw) {
39210
+ return successContext.data;
39211
+ }
39212
+ return {
39213
+ data: successContext.data,
39214
+ error: null
39215
+ };
39561
39216
  }
39562
- let responsePublicKeyAlgorithm = void 0;
39563
- if (typeof response.getPublicKeyAlgorithm === "function") {
39564
- try {
39565
- responsePublicKeyAlgorithm = response.getPublicKeyAlgorithm();
39566
- } catch (error) {
39567
- warnOnBrokenImplementation("getPublicKeyAlgorithm()", error);
39217
+ const parser = (_f = options == null ? void 0 : options.jsonParser) != null ? _f : jsonParse;
39218
+ const responseText = await response.text();
39219
+ const isJSONResponse = isJSONParsable(responseText);
39220
+ const errorObject = isJSONResponse ? await parser(responseText) : null;
39221
+ const errorContext = {
39222
+ response,
39223
+ responseText,
39224
+ request: context,
39225
+ error: __spreadProps(__spreadValues({}, errorObject), {
39226
+ status: response.status,
39227
+ statusText: response.statusText
39228
+ })
39229
+ };
39230
+ for (const onError of hooks.onError) {
39231
+ if (onError) {
39232
+ await onError(__spreadProps(__spreadValues({}, errorContext), {
39233
+ response: ((_g = options == null ? void 0 : options.hookOptions) == null ? void 0 : _g.cloneResponse) ? response.clone() : response
39234
+ }));
39568
39235
  }
39569
39236
  }
39570
- let responsePublicKey = void 0;
39571
- if (typeof response.getPublicKey === "function") {
39572
- try {
39573
- const _publicKey = response.getPublicKey();
39574
- if (_publicKey !== null) {
39575
- responsePublicKey = bufferToBase64URLString(_publicKey);
39237
+ if (options == null ? void 0 : options.retry) {
39238
+ const retryStrategy = createRetryStrategy(options.retry);
39239
+ const _retryAttempt = (_h = options.retryAttempt) != null ? _h : 0;
39240
+ if (await retryStrategy.shouldAttemptRetry(_retryAttempt, response)) {
39241
+ for (const onRetry of hooks.onRetry) {
39242
+ if (onRetry) {
39243
+ await onRetry(responseContext);
39244
+ }
39576
39245
  }
39577
- } catch (error) {
39578
- warnOnBrokenImplementation("getPublicKey()", error);
39246
+ const delay2 = retryStrategy.getDelay(_retryAttempt);
39247
+ await new Promise((resolve) => setTimeout(resolve, delay2));
39248
+ return await betterFetch(url, __spreadProps(__spreadValues({}, options), {
39249
+ retryAttempt: _retryAttempt + 1
39250
+ }));
39579
39251
  }
39580
39252
  }
39581
- let responseAuthenticatorData;
39582
- if (typeof response.getAuthenticatorData === "function") {
39583
- try {
39584
- responseAuthenticatorData = bufferToBase64URLString(response.getAuthenticatorData());
39585
- } catch (error) {
39586
- warnOnBrokenImplementation("getAuthenticatorData()", error);
39587
- }
39253
+ if (options == null ? void 0 : options.throw) {
39254
+ throw new BetterFetchError(
39255
+ response.status,
39256
+ response.statusText,
39257
+ isJSONResponse ? errorObject : responseText
39258
+ );
39588
39259
  }
39589
39260
  return {
39590
- id: id2,
39591
- rawId: bufferToBase64URLString(rawId),
39592
- response: {
39593
- attestationObject: bufferToBase64URLString(response.attestationObject),
39594
- clientDataJSON: bufferToBase64URLString(response.clientDataJSON),
39595
- transports,
39596
- publicKeyAlgorithm: responsePublicKeyAlgorithm,
39597
- publicKey: responsePublicKey,
39598
- authenticatorData: responseAuthenticatorData
39599
- },
39600
- type,
39601
- clientExtensionResults: credential.getClientExtensionResults(),
39602
- authenticatorAttachment: toAuthenticatorAttachment(credential.authenticatorAttachment)
39261
+ data: null,
39262
+ error: __spreadProps(__spreadValues({}, errorObject), {
39263
+ status: response.status,
39264
+ statusText: response.statusText
39265
+ })
39603
39266
  };
39604
- }
39605
- function warnOnBrokenImplementation(methodName, cause) {
39606
- console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${methodName}. You should report this error to them.
39607
- `, cause);
39608
- }
39609
- function browserSupportsWebAuthnAutofill() {
39610
- if (!browserSupportsWebAuthn()) {
39611
- return _browserSupportsWebAuthnAutofillInternals.stubThis(new Promise((resolve) => resolve(false)));
39267
+ };
39268
+ const kBroadcastChannel = Symbol.for("better-auth:broadcast-channel");
39269
+ const now$1 = () => Math.floor(Date.now() / 1e3);
39270
+ var WindowBroadcastChannel = class {
39271
+ listeners = /* @__PURE__ */ new Set();
39272
+ name;
39273
+ constructor(name = "better-auth.message") {
39274
+ this.name = name;
39612
39275
  }
39613
- const globalPublicKeyCredential = globalThis.PublicKeyCredential;
39614
- if (globalPublicKeyCredential?.isConditionalMediationAvailable === void 0) {
39615
- return _browserSupportsWebAuthnAutofillInternals.stubThis(new Promise((resolve) => resolve(false)));
39276
+ subscribe(listener) {
39277
+ this.listeners.add(listener);
39278
+ return () => {
39279
+ this.listeners.delete(listener);
39280
+ };
39616
39281
  }
39617
- return _browserSupportsWebAuthnAutofillInternals.stubThis(globalPublicKeyCredential.isConditionalMediationAvailable());
39282
+ post(message) {
39283
+ if (typeof window === "undefined") return;
39284
+ try {
39285
+ localStorage.setItem(this.name, JSON.stringify({
39286
+ ...message,
39287
+ timestamp: now$1()
39288
+ }));
39289
+ } catch {
39290
+ }
39291
+ }
39292
+ setup() {
39293
+ if (typeof window === "undefined" || typeof window.addEventListener === "undefined") return () => {
39294
+ };
39295
+ const handler = (event) => {
39296
+ if (event.key !== this.name) return;
39297
+ const message = JSON.parse(event.newValue ?? "{}");
39298
+ if (message?.event !== "session" || !message?.data) return;
39299
+ this.listeners.forEach((listener) => listener(message));
39300
+ };
39301
+ window.addEventListener("storage", handler);
39302
+ return () => {
39303
+ window.removeEventListener("storage", handler);
39304
+ };
39305
+ }
39306
+ };
39307
+ function getGlobalBroadcastChannel(name = "better-auth.message") {
39308
+ if (!globalThis[kBroadcastChannel]) globalThis[kBroadcastChannel] = new WindowBroadcastChannel(name);
39309
+ return globalThis[kBroadcastChannel];
39618
39310
  }
39619
- const _browserSupportsWebAuthnAutofillInternals = {
39620
- stubThis: (value) => value
39311
+ const kFocusManager = Symbol.for("better-auth:focus-manager");
39312
+ var WindowFocusManager = class {
39313
+ listeners = /* @__PURE__ */ new Set();
39314
+ subscribe(listener) {
39315
+ this.listeners.add(listener);
39316
+ return () => {
39317
+ this.listeners.delete(listener);
39318
+ };
39319
+ }
39320
+ setFocused(focused) {
39321
+ this.listeners.forEach((listener) => listener(focused));
39322
+ }
39323
+ setup() {
39324
+ if (typeof window === "undefined" || typeof document === "undefined" || typeof window.addEventListener === "undefined") return () => {
39325
+ };
39326
+ const visibilityHandler = () => {
39327
+ if (document.visibilityState === "visible") this.setFocused(true);
39328
+ };
39329
+ document.addEventListener("visibilitychange", visibilityHandler, false);
39330
+ return () => {
39331
+ document.removeEventListener("visibilitychange", visibilityHandler, false);
39332
+ };
39333
+ }
39621
39334
  };
39622
- function identifyAuthenticationError({ error, options }) {
39623
- const { publicKey } = options;
39624
- if (!publicKey) {
39625
- throw Error("options was missing required publicKey property");
39335
+ function getGlobalFocusManager() {
39336
+ if (!globalThis[kFocusManager]) globalThis[kFocusManager] = new WindowFocusManager();
39337
+ return globalThis[kFocusManager];
39338
+ }
39339
+ const kOnlineManager = Symbol.for("better-auth:online-manager");
39340
+ var WindowOnlineManager = class {
39341
+ listeners = /* @__PURE__ */ new Set();
39342
+ isOnline = typeof navigator !== "undefined" ? navigator.onLine : true;
39343
+ subscribe(listener) {
39344
+ this.listeners.add(listener);
39345
+ return () => {
39346
+ this.listeners.delete(listener);
39347
+ };
39626
39348
  }
39627
- if (error.name === "AbortError") {
39628
- if (options.signal instanceof AbortSignal) {
39629
- return new WebAuthnError({
39630
- message: "Authentication ceremony was sent an abort signal",
39631
- code: "ERROR_CEREMONY_ABORTED",
39632
- cause: error
39349
+ setOnline(online) {
39350
+ this.isOnline = online;
39351
+ this.listeners.forEach((listener) => listener(online));
39352
+ }
39353
+ setup() {
39354
+ if (typeof window === "undefined" || typeof window.addEventListener === "undefined") return () => {
39355
+ };
39356
+ const onOnline = () => this.setOnline(true);
39357
+ const onOffline = () => this.setOnline(false);
39358
+ window.addEventListener("online", onOnline, false);
39359
+ window.addEventListener("offline", onOffline, false);
39360
+ return () => {
39361
+ window.removeEventListener("online", onOnline, false);
39362
+ window.removeEventListener("offline", onOffline, false);
39363
+ };
39364
+ }
39365
+ };
39366
+ function getGlobalOnlineManager() {
39367
+ if (!globalThis[kOnlineManager]) globalThis[kOnlineManager] = new WindowOnlineManager();
39368
+ return globalThis[kOnlineManager];
39369
+ }
39370
+ const isServer = () => typeof window === "undefined";
39371
+ const useAuthQuery = (initializedAtom, path, $fetch, options) => {
39372
+ const value = /* @__PURE__ */ atom({
39373
+ data: null,
39374
+ error: null,
39375
+ isPending: true,
39376
+ isRefetching: false,
39377
+ refetch: (queryParams) => fn(queryParams)
39378
+ });
39379
+ const fn = async (queryParams) => {
39380
+ return new Promise((resolve) => {
39381
+ const opts = typeof options === "function" ? options({
39382
+ data: value.get().data,
39383
+ error: value.get().error,
39384
+ isPending: value.get().isPending
39385
+ }) : options;
39386
+ $fetch(path, {
39387
+ ...opts,
39388
+ query: {
39389
+ ...opts?.query,
39390
+ ...queryParams?.query
39391
+ },
39392
+ async onSuccess(context) {
39393
+ value.set({
39394
+ data: context.data,
39395
+ error: null,
39396
+ isPending: false,
39397
+ isRefetching: false,
39398
+ refetch: value.value.refetch
39399
+ });
39400
+ await opts?.onSuccess?.(context);
39401
+ },
39402
+ async onError(context) {
39403
+ const { request } = context;
39404
+ const retryAttempts = typeof request.retry === "number" ? request.retry : request.retry?.attempts;
39405
+ const retryAttempt = request.retryAttempt || 0;
39406
+ if (retryAttempts && retryAttempt < retryAttempts) return;
39407
+ value.set({
39408
+ error: context.error,
39409
+ data: null,
39410
+ isPending: false,
39411
+ isRefetching: false,
39412
+ refetch: value.value.refetch
39413
+ });
39414
+ await opts?.onError?.(context);
39415
+ },
39416
+ async onRequest(context) {
39417
+ const currentValue = value.get();
39418
+ value.set({
39419
+ isPending: currentValue.data === null,
39420
+ data: currentValue.data,
39421
+ error: null,
39422
+ isRefetching: true,
39423
+ refetch: value.value.refetch
39424
+ });
39425
+ await opts?.onRequest?.(context);
39426
+ }
39427
+ }).catch((error) => {
39428
+ value.set({
39429
+ error,
39430
+ data: null,
39431
+ isPending: false,
39432
+ isRefetching: false,
39433
+ refetch: value.value.refetch
39434
+ });
39435
+ }).finally(() => {
39436
+ resolve(void 0);
39633
39437
  });
39634
- }
39635
- } else if (error.name === "NotAllowedError") {
39636
- return new WebAuthnError({
39637
- message: error.message,
39638
- code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
39639
- cause: error
39640
39438
  });
39641
- } else if (error.name === "SecurityError") {
39642
- const effectiveDomain = globalThis.location.hostname;
39643
- if (!isValidDomain(effectiveDomain)) {
39644
- return new WebAuthnError({
39645
- message: `${globalThis.location.hostname} is an invalid domain`,
39646
- code: "ERROR_INVALID_DOMAIN",
39647
- cause: error
39648
- });
39649
- } else if (publicKey.rpId !== effectiveDomain) {
39650
- return new WebAuthnError({
39651
- message: `The RP ID "${publicKey.rpId}" is invalid for this domain`,
39652
- code: "ERROR_INVALID_RP_ID",
39653
- cause: error
39439
+ };
39440
+ initializedAtom = Array.isArray(initializedAtom) ? initializedAtom : [initializedAtom];
39441
+ let isMounted = false;
39442
+ for (const initAtom of initializedAtom) initAtom.subscribe(async () => {
39443
+ if (isServer()) return;
39444
+ if (isMounted) await fn();
39445
+ else onMount(value, () => {
39446
+ const timeoutId = setTimeout(async () => {
39447
+ if (!isMounted) {
39448
+ await fn();
39449
+ isMounted = true;
39450
+ }
39451
+ }, 0);
39452
+ return () => {
39453
+ value.off();
39454
+ initAtom.off();
39455
+ clearTimeout(timeoutId);
39456
+ };
39457
+ });
39458
+ });
39459
+ return value;
39460
+ };
39461
+ const now = () => Math.floor(Date.now() / 1e3);
39462
+ const FOCUS_REFETCH_RATE_LIMIT_SECONDS = 5;
39463
+ function createSessionRefreshManager(opts) {
39464
+ const { sessionAtom, sessionSignal, $fetch, options = {} } = opts;
39465
+ const refetchInterval = options.sessionOptions?.refetchInterval ?? 0;
39466
+ const refetchOnWindowFocus = options.sessionOptions?.refetchOnWindowFocus ?? true;
39467
+ const refetchWhenOffline = options.sessionOptions?.refetchWhenOffline ?? false;
39468
+ const state = {
39469
+ lastSync: 0,
39470
+ lastSessionRequest: 0,
39471
+ cachedSession: void 0
39472
+ };
39473
+ const shouldRefetch = () => {
39474
+ return refetchWhenOffline || getGlobalOnlineManager().isOnline;
39475
+ };
39476
+ const triggerRefetch = (event) => {
39477
+ if (!shouldRefetch()) return;
39478
+ if (event?.event === "storage") {
39479
+ state.lastSync = now();
39480
+ sessionSignal.set(!sessionSignal.get());
39481
+ return;
39482
+ }
39483
+ const currentSession = sessionAtom.get();
39484
+ if (event?.event === "poll") {
39485
+ state.lastSessionRequest = now();
39486
+ $fetch("/get-session").then((res) => {
39487
+ sessionAtom.set({
39488
+ ...currentSession,
39489
+ data: res.data,
39490
+ error: res.error || null
39491
+ });
39492
+ state.lastSync = now();
39493
+ sessionSignal.set(!sessionSignal.get());
39494
+ }).catch(() => {
39654
39495
  });
39496
+ return;
39655
39497
  }
39656
- } else if (error.name === "UnknownError") {
39657
- return new WebAuthnError({
39658
- message: "The authenticator was unable to process the specified options, or could not create a new assertion signature",
39659
- code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
39660
- cause: error
39498
+ if (event?.event === "visibilitychange") {
39499
+ if (now() - state.lastSessionRequest < FOCUS_REFETCH_RATE_LIMIT_SECONDS && currentSession?.data !== null && currentSession?.data !== void 0) return;
39500
+ }
39501
+ if (currentSession?.data === null || currentSession?.data === void 0 || event?.event === "visibilitychange") {
39502
+ if (event?.event === "visibilitychange") state.lastSessionRequest = now();
39503
+ state.lastSync = now();
39504
+ sessionSignal.set(!sessionSignal.get());
39505
+ }
39506
+ };
39507
+ const broadcastSessionUpdate = (trigger) => {
39508
+ getGlobalBroadcastChannel().post({
39509
+ event: "session",
39510
+ data: { trigger },
39511
+ clientId: Math.random().toString(36).substring(7)
39661
39512
  });
39662
- }
39663
- return error;
39513
+ };
39514
+ const setupPolling = () => {
39515
+ if (refetchInterval && refetchInterval > 0) state.pollInterval = setInterval(() => {
39516
+ if (sessionAtom.get()?.data) triggerRefetch({ event: "poll" });
39517
+ }, refetchInterval * 1e3);
39518
+ };
39519
+ const setupBroadcast = () => {
39520
+ state.unsubscribeBroadcast = getGlobalBroadcastChannel().subscribe(() => {
39521
+ triggerRefetch({ event: "storage" });
39522
+ });
39523
+ };
39524
+ const setupFocusRefetch = () => {
39525
+ if (!refetchOnWindowFocus) return;
39526
+ state.unsubscribeFocus = getGlobalFocusManager().subscribe(() => {
39527
+ triggerRefetch({ event: "visibilitychange" });
39528
+ });
39529
+ };
39530
+ const setupOnlineRefetch = () => {
39531
+ state.unsubscribeOnline = getGlobalOnlineManager().subscribe((online) => {
39532
+ if (online) triggerRefetch({ event: "visibilitychange" });
39533
+ });
39534
+ };
39535
+ const init2 = () => {
39536
+ setupPolling();
39537
+ setupBroadcast();
39538
+ setupFocusRefetch();
39539
+ setupOnlineRefetch();
39540
+ getGlobalBroadcastChannel().setup();
39541
+ getGlobalFocusManager().setup();
39542
+ getGlobalOnlineManager().setup();
39543
+ };
39544
+ const cleanup = () => {
39545
+ if (state.pollInterval) {
39546
+ clearInterval(state.pollInterval);
39547
+ state.pollInterval = void 0;
39548
+ }
39549
+ if (state.unsubscribeBroadcast) {
39550
+ state.unsubscribeBroadcast();
39551
+ state.unsubscribeBroadcast = void 0;
39552
+ }
39553
+ if (state.unsubscribeFocus) {
39554
+ state.unsubscribeFocus();
39555
+ state.unsubscribeFocus = void 0;
39556
+ }
39557
+ if (state.unsubscribeOnline) {
39558
+ state.unsubscribeOnline();
39559
+ state.unsubscribeOnline = void 0;
39560
+ }
39561
+ state.lastSync = 0;
39562
+ state.lastSessionRequest = 0;
39563
+ state.cachedSession = void 0;
39564
+ };
39565
+ return {
39566
+ init: init2,
39567
+ cleanup,
39568
+ triggerRefetch,
39569
+ broadcastSessionUpdate
39570
+ };
39664
39571
  }
39665
- async function startAuthentication(options) {
39666
- if (!options.optionsJSON && options.challenge) {
39667
- console.warn("startAuthentication() was not called correctly. It will try to continue with the provided options, but this call should be refactored to use the expected call structure instead. See https://simplewebauthn.dev/docs/packages/browser#typeerror-cannot-read-properties-of-undefined-reading-challenge for more information.");
39668
- options = { optionsJSON: options };
39669
- }
39670
- const { optionsJSON, useBrowserAutofill = false, verifyBrowserAutofillInput = true } = options;
39671
- if (!browserSupportsWebAuthn()) {
39672
- throw new Error("WebAuthn is not supported in this browser");
39673
- }
39674
- let allowCredentials;
39675
- if (optionsJSON.allowCredentials?.length !== 0) {
39676
- allowCredentials = optionsJSON.allowCredentials?.map(toPublicKeyCredentialDescriptor);
39677
- }
39678
- const publicKey = {
39679
- ...optionsJSON,
39680
- challenge: base64URLStringToBuffer(optionsJSON.challenge),
39681
- allowCredentials
39572
+ const redirectPlugin = {
39573
+ id: "redirect",
39574
+ name: "Redirect",
39575
+ hooks: { onSuccess(context) {
39576
+ if (context.data?.url && context.data?.redirect) {
39577
+ if (typeof window !== "undefined" && window.location) {
39578
+ if (window.location) try {
39579
+ window.location.href = context.data.url;
39580
+ } catch {
39581
+ }
39582
+ }
39583
+ }
39584
+ } }
39585
+ };
39586
+ function getSessionAtom($fetch, options) {
39587
+ const $signal = /* @__PURE__ */ atom(false);
39588
+ const session = useAuthQuery($signal, "/get-session", $fetch, { method: "GET" });
39589
+ onMount(session, () => {
39590
+ const refreshManager = createSessionRefreshManager({
39591
+ sessionAtom: session,
39592
+ sessionSignal: $signal,
39593
+ $fetch,
39594
+ options
39595
+ });
39596
+ refreshManager.init();
39597
+ return () => {
39598
+ refreshManager.cleanup();
39599
+ };
39600
+ });
39601
+ return {
39602
+ session,
39603
+ $sessionSignal: $signal
39682
39604
  };
39683
- const getOptions = {};
39684
- if (useBrowserAutofill) {
39685
- if (!await browserSupportsWebAuthnAutofill()) {
39686
- throw Error("Browser does not support WebAuthn autofill");
39605
+ }
39606
+ const getClientConfig = (options, loadEnv) => {
39607
+ const isCredentialsSupported = "credentials" in Request.prototype;
39608
+ const baseURL = getBaseURL(options?.baseURL, options?.basePath) ?? "/api/auth";
39609
+ const pluginsFetchPlugins = options?.plugins?.flatMap((plugin) => plugin.fetchPlugins).filter((pl) => pl !== void 0) || [];
39610
+ const lifeCyclePlugin = {
39611
+ id: "lifecycle-hooks",
39612
+ name: "lifecycle-hooks",
39613
+ hooks: {
39614
+ onSuccess: options?.fetchOptions?.onSuccess,
39615
+ onError: options?.fetchOptions?.onError,
39616
+ onRequest: options?.fetchOptions?.onRequest,
39617
+ onResponse: options?.fetchOptions?.onResponse
39687
39618
  }
39688
- const eligibleInputs = document.querySelectorAll("input[autocomplete$='webauthn']");
39689
- if (eligibleInputs.length < 1 && verifyBrowserAutofillInput) {
39690
- throw Error('No <input> with "webauthn" as the only or last value in its `autocomplete` attribute was detected');
39619
+ };
39620
+ const { onSuccess, onError, onRequest, onResponse, ...restOfFetchOptions } = options?.fetchOptions || {};
39621
+ const $fetch = createFetch({
39622
+ baseURL,
39623
+ ...isCredentialsSupported ? { credentials: "include" } : {},
39624
+ method: "GET",
39625
+ jsonParser(text) {
39626
+ if (!text) return null;
39627
+ return parseJSON(text, { strict: false });
39628
+ },
39629
+ customFetchImpl: fetch,
39630
+ ...restOfFetchOptions,
39631
+ plugins: [
39632
+ lifeCyclePlugin,
39633
+ ...restOfFetchOptions.plugins || [],
39634
+ ...options?.disableDefaultFetchPlugins ? [] : [redirectPlugin],
39635
+ ...pluginsFetchPlugins
39636
+ ]
39637
+ });
39638
+ const { $sessionSignal, session } = getSessionAtom($fetch, options);
39639
+ const plugins = options?.plugins || [];
39640
+ let pluginsActions = {};
39641
+ let pluginsAtoms = {
39642
+ $sessionSignal,
39643
+ session
39644
+ };
39645
+ let pluginPathMethods = {
39646
+ "/sign-out": "POST",
39647
+ "/revoke-sessions": "POST",
39648
+ "/revoke-other-sessions": "POST",
39649
+ "/delete-user": "POST"
39650
+ };
39651
+ const atomListeners = [{
39652
+ signal: "$sessionSignal",
39653
+ matcher(path) {
39654
+ return path === "/sign-out" || path === "/update-user" || path === "/sign-up/email" || path === "/sign-in/email" || path === "/delete-user" || path === "/verify-email" || path === "/revoke-sessions" || path === "/revoke-session" || path === "/change-email";
39691
39655
  }
39692
- getOptions.mediation = "conditional";
39693
- publicKey.allowCredentials = [];
39694
- }
39695
- getOptions.publicKey = publicKey;
39696
- getOptions.signal = WebAuthnAbortService.createNewAbortSignal();
39697
- let credential;
39698
- try {
39699
- credential = await navigator.credentials.get(getOptions);
39700
- } catch (err) {
39701
- throw identifyAuthenticationError({ error: err, options: getOptions });
39702
- }
39703
- if (!credential) {
39704
- throw new Error("Authentication was not completed");
39705
- }
39706
- const { id: id2, rawId, response, type } = credential;
39707
- let userHandle = void 0;
39708
- if (response.userHandle) {
39709
- userHandle = bufferToBase64URLString(response.userHandle);
39656
+ }];
39657
+ for (const plugin of plugins) {
39658
+ if (plugin.getAtoms) Object.assign(pluginsAtoms, plugin.getAtoms?.($fetch));
39659
+ if (plugin.pathMethods) Object.assign(pluginPathMethods, plugin.pathMethods);
39660
+ if (plugin.atomListeners) atomListeners.push(...plugin.atomListeners);
39710
39661
  }
39711
- return {
39712
- id: id2,
39713
- rawId: bufferToBase64URLString(rawId),
39714
- response: {
39715
- authenticatorData: bufferToBase64URLString(response.authenticatorData),
39716
- clientDataJSON: bufferToBase64URLString(response.clientDataJSON),
39717
- signature: bufferToBase64URLString(response.signature),
39718
- userHandle
39662
+ const $store = {
39663
+ notify: (signal) => {
39664
+ pluginsAtoms[signal].set(!pluginsAtoms[signal].get());
39719
39665
  },
39720
- type,
39721
- clientExtensionResults: credential.getClientExtensionResults(),
39722
- authenticatorAttachment: toAuthenticatorAttachment(credential.authenticatorAttachment)
39666
+ listen: (signal, listener) => {
39667
+ pluginsAtoms[signal].subscribe(listener);
39668
+ },
39669
+ atoms: pluginsAtoms
39723
39670
  };
39724
- }
39725
- const twoFactorClient = (options) => {
39671
+ for (const plugin of plugins) if (plugin.getActions) Object.assign(pluginsActions, plugin.getActions?.($fetch, $store, options));
39726
39672
  return {
39727
- id: "two-factor",
39728
- $InferServerPlugin: {},
39729
- atomListeners: [
39730
- {
39731
- matcher: (path) => path.startsWith("/two-factor/"),
39732
- signal: "$sessionSignal"
39733
- }
39734
- ],
39735
- pathMethods: {
39736
- "/two-factor/disable": "POST",
39737
- "/two-factor/enable": "POST",
39738
- "/two-factor/send-otp": "POST",
39739
- "/two-factor/generate-backup-codes": "POST"
39673
+ get baseURL() {
39674
+ return baseURL;
39740
39675
  },
39741
- fetchPlugins: [
39742
- {
39743
- id: "two-factor",
39744
- name: "two-factor",
39745
- hooks: {
39676
+ pluginsActions,
39677
+ pluginsAtoms,
39678
+ pluginPathMethods,
39679
+ atomListeners,
39680
+ $fetch,
39681
+ $store
39682
+ };
39683
+ };
39684
+ function isAtom(value) {
39685
+ return typeof value === "object" && value !== null && "get" in value && typeof value.get === "function" && "lc" in value && typeof value.lc === "number";
39686
+ }
39687
+ function getMethod(path, knownPathMethods, args) {
39688
+ const method = knownPathMethods[path];
39689
+ const { fetchOptions, query, ...body } = args || {};
39690
+ if (method) return method;
39691
+ if (fetchOptions?.method) return fetchOptions.method;
39692
+ if (body && Object.keys(body).length > 0) return "POST";
39693
+ return "GET";
39694
+ }
39695
+ function createDynamicPathProxy(routes, client2, knownPathMethods, atoms, atomListeners) {
39696
+ function createProxy(path = []) {
39697
+ return new Proxy(function() {
39698
+ }, {
39699
+ get(_2, prop) {
39700
+ if (typeof prop !== "string") return;
39701
+ if (prop === "then" || prop === "catch" || prop === "finally") return;
39702
+ const fullPath = [...path, prop];
39703
+ let current = routes;
39704
+ for (const segment of fullPath) if (current && typeof current === "object" && segment in current) current = current[segment];
39705
+ else {
39706
+ current = void 0;
39707
+ break;
39708
+ }
39709
+ if (typeof current === "function") return current;
39710
+ if (isAtom(current)) return current;
39711
+ return createProxy(fullPath);
39712
+ },
39713
+ apply: async (_2, __, args) => {
39714
+ const routePath = "/" + path.map((segment) => segment.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)).join("/");
39715
+ const arg = args[0] || {};
39716
+ const fetchOptions = args[1] || {};
39717
+ const { query, fetchOptions: argFetchOptions, ...body } = arg;
39718
+ const options = {
39719
+ ...fetchOptions,
39720
+ ...argFetchOptions
39721
+ };
39722
+ const method = getMethod(routePath, knownPathMethods, arg);
39723
+ return await client2(routePath, {
39724
+ ...options,
39725
+ body: method === "GET" ? void 0 : {
39726
+ ...body,
39727
+ ...options?.body || {}
39728
+ },
39729
+ query: query || options?.query,
39730
+ method,
39746
39731
  async onSuccess(context) {
39747
- if (context.data?.twoFactorRedirect) {
39748
- if (options?.onTwoFactorRedirect) {
39749
- await options.onTwoFactorRedirect();
39750
- }
39732
+ await options?.onSuccess?.(context);
39733
+ if (!atomListeners || options.disableSignal) return;
39734
+ const matches = atomListeners.filter((s2) => s2.matcher(routePath));
39735
+ if (!matches.length) return;
39736
+ for (const match of matches) {
39737
+ const signal = atoms[match.signal];
39738
+ if (!signal) return;
39739
+ const val = signal.get();
39740
+ setTimeout(() => {
39741
+ signal.set(!val);
39742
+ }, 10);
39751
39743
  }
39752
39744
  }
39753
- }
39745
+ });
39754
39746
  }
39755
- ]
39756
- };
39757
- };
39758
- const getPasskeyActions = ($fetch, {
39759
- $listPasskeys,
39760
- $store
39761
- }) => {
39747
+ });
39748
+ }
39749
+ return createProxy();
39750
+ }
39751
+ function createAuthClient(options) {
39752
+ const { pluginPathMethods, pluginsActions, pluginsAtoms, $fetch, atomListeners, $store } = getClientConfig(options);
39753
+ let resolvedHooks = {};
39754
+ for (const [key2, value] of Object.entries(pluginsAtoms)) resolvedHooks[`use${capitalizeFirstLetter(key2)}`] = value;
39755
+ return createDynamicPathProxy({
39756
+ ...pluginsActions,
39757
+ ...resolvedHooks,
39758
+ $fetch,
39759
+ $store
39760
+ }, $fetch, pluginPathMethods, pluginsAtoms, atomListeners);
39761
+ }
39762
+ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
39762
39763
  const signInPasskey = async (opts, options) => {
39763
- const response = await $fetch(
39764
- "/passkey/generate-authenticate-options",
39765
- {
39766
- method: "POST",
39767
- throw: false
39768
- }
39769
- );
39770
- if (!response.data) {
39771
- return response;
39772
- }
39764
+ const response = await $fetch("/passkey/generate-authenticate-options", {
39765
+ method: "GET",
39766
+ throw: false
39767
+ });
39768
+ if (!response.data) return response;
39773
39769
  try {
39774
- const res = await startAuthentication({
39775
- optionsJSON: response.data,
39776
- useBrowserAutofill: opts?.autoFill
39777
- });
39778
39770
  const verified = await $fetch("/passkey/verify-authentication", {
39779
- body: {
39780
- response: res
39781
- },
39771
+ body: { response: await startAuthentication({
39772
+ optionsJSON: response.data,
39773
+ useBrowserAutofill: opts?.autoFill
39774
+ }) },
39782
39775
  ...opts?.fetchOptions,
39783
39776
  ...options,
39784
39777
  method: "POST",
@@ -39800,24 +39793,15 @@ const getPasskeyActions = ($fetch, {
39800
39793
  }
39801
39794
  };
39802
39795
  const registerPasskey = async (opts, fetchOpts) => {
39803
- const options = await $fetch(
39804
- "/passkey/generate-register-options",
39805
- {
39806
- method: "GET",
39807
- query: {
39808
- ...opts?.authenticatorAttachment && {
39809
- authenticatorAttachment: opts.authenticatorAttachment
39810
- },
39811
- ...opts?.name && {
39812
- name: opts.name
39813
- }
39814
- },
39815
- throw: false
39816
- }
39817
- );
39818
- if (!options.data) {
39819
- return options;
39820
- }
39796
+ const options = await $fetch("/passkey/generate-register-options", {
39797
+ method: "GET",
39798
+ query: {
39799
+ ...opts?.authenticatorAttachment && { authenticatorAttachment: opts.authenticatorAttachment },
39800
+ ...opts?.name && { name: opts.name }
39801
+ },
39802
+ throw: false
39803
+ });
39804
+ if (!options.data) return options;
39821
39805
  try {
39822
39806
  const res = await startRegistration({
39823
39807
  optionsJSON: options.data,
@@ -39833,34 +39817,29 @@ const getPasskeyActions = ($fetch, {
39833
39817
  method: "POST",
39834
39818
  throw: false
39835
39819
  });
39836
- if (!verified.data) {
39837
- return verified;
39838
- }
39820
+ if (!verified.data) return verified;
39839
39821
  $listPasskeys.set(Math.random());
39822
+ return verified;
39840
39823
  } catch (e) {
39841
39824
  if (e instanceof WebAuthnError) {
39842
- if (e.code === "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED") {
39843
- return {
39844
- data: null,
39845
- error: {
39846
- code: e.code,
39847
- message: "previously registered",
39848
- status: 400,
39849
- statusText: "BAD_REQUEST"
39850
- }
39851
- };
39852
- }
39853
- if (e.code === "ERROR_CEREMONY_ABORTED") {
39854
- return {
39855
- data: null,
39856
- error: {
39857
- code: e.code,
39858
- message: "registration cancelled",
39859
- status: 400,
39860
- statusText: "BAD_REQUEST"
39861
- }
39862
- };
39863
- }
39825
+ if (e.code === "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED") return {
39826
+ data: null,
39827
+ error: {
39828
+ code: e.code,
39829
+ message: "previously registered",
39830
+ status: 400,
39831
+ statusText: "BAD_REQUEST"
39832
+ }
39833
+ };
39834
+ if (e.code === "ERROR_CEREMONY_ABORTED") return {
39835
+ data: null,
39836
+ error: {
39837
+ code: e.code,
39838
+ message: "registration cancelled",
39839
+ status: 400,
39840
+ statusText: "BAD_REQUEST"
39841
+ }
39842
+ };
39864
39843
  return {
39865
39844
  data: null,
39866
39845
  error: {
@@ -39883,21 +39862,8 @@ const getPasskeyActions = ($fetch, {
39883
39862
  }
39884
39863
  };
39885
39864
  return {
39886
- signIn: {
39887
- /**
39888
- * Sign in with a registered passkey
39889
- */
39890
- passkey: signInPasskey
39891
- },
39892
- passkey: {
39893
- /**
39894
- * Add a passkey to the user account
39895
- */
39896
- addPasskey: registerPasskey
39897
- },
39898
- /**
39899
- * Inferred Internal Types
39900
- */
39865
+ signIn: { passkey: signInPasskey },
39866
+ passkey: { addPasskey: registerPasskey },
39901
39867
  $Infer: {}
39902
39868
  };
39903
39869
  };
@@ -39911,16 +39877,8 @@ const passkeyClient = () => {
39911
39877
  $store
39912
39878
  }),
39913
39879
  getAtoms($fetch) {
39914
- const listPasskeys = useAuthQuery(
39915
- $listPasskeys,
39916
- "/passkey/list-user-passkeys",
39917
- $fetch,
39918
- {
39919
- method: "GET"
39920
- }
39921
- );
39922
39880
  return {
39923
- listPasskeys,
39881
+ listPasskeys: useAuthQuery($listPasskeys, "/passkey/list-user-passkeys", $fetch, { method: "GET" }),
39924
39882
  $listPasskeys
39925
39883
  };
39926
39884
  },
@@ -39928,18 +39886,40 @@ const passkeyClient = () => {
39928
39886
  "/passkey/register": "POST",
39929
39887
  "/passkey/authenticate": "POST"
39930
39888
  },
39931
- atomListeners: [
39932
- {
39933
- matcher(path) {
39934
- return path === "/passkey/verify-registration" || path === "/passkey/delete-passkey" || path === "/passkey/update-passkey" || path === "/sign-out";
39935
- },
39936
- signal: "$listPasskeys"
39889
+ atomListeners: [{
39890
+ matcher(path) {
39891
+ return path === "/passkey/verify-registration" || path === "/passkey/delete-passkey" || path === "/passkey/update-passkey" || path === "/sign-out";
39937
39892
  },
39938
- {
39939
- matcher: (path) => path === "/passkey/verify-authentication",
39940
- signal: "$sessionSignal"
39941
- }
39942
- ]
39893
+ signal: "$listPasskeys"
39894
+ }, {
39895
+ matcher: (path) => path === "/passkey/verify-authentication",
39896
+ signal: "$sessionSignal"
39897
+ }]
39898
+ };
39899
+ };
39900
+ const twoFactorClient = (options) => {
39901
+ return {
39902
+ id: "two-factor",
39903
+ $InferServerPlugin: {},
39904
+ atomListeners: [{
39905
+ matcher: (path) => path.startsWith("/two-factor/"),
39906
+ signal: "$sessionSignal"
39907
+ }],
39908
+ pathMethods: {
39909
+ "/two-factor/disable": "POST",
39910
+ "/two-factor/enable": "POST",
39911
+ "/two-factor/send-otp": "POST",
39912
+ "/two-factor/generate-backup-codes": "POST"
39913
+ },
39914
+ fetchPlugins: [{
39915
+ id: "two-factor",
39916
+ name: "two-factor",
39917
+ hooks: { async onSuccess(context) {
39918
+ if (context.data?.twoFactorRedirect) {
39919
+ if (options?.onTwoFactorRedirect) await options.onTwoFactorRedirect();
39920
+ }
39921
+ } }
39922
+ }]
39943
39923
  };
39944
39924
  };
39945
39925
  const magicLinkClient = () => {
@@ -50472,7 +50452,7 @@ const CodeDefault = ({
50472
50452
  })
50473
50453
  })
50474
50454
  });
50475
- const CodeBlockShiki = reactExports.lazy(() => __vitePreload(() => import("./CodeBlockShiki-C3xG8AyL.js"), true ? [] : void 0).then((mod) => ({
50455
+ const CodeBlockShiki = reactExports.lazy(() => __vitePreload(() => import("./CodeBlockShiki-By6BGsDF.js"), true ? [] : void 0).then((mod) => ({
50476
50456
  default: mod.CodeBlockShiki
50477
50457
  })));
50478
50458
  const CodeBlock = ({