@strands.gg/accui 2.17.18 → 2.17.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -3,7 +3,7 @@ import { m as Hu } from "./StrandsUIPlugin-RTFzvRED.es.js";
3
3
  import { defineComponent as Ve, computed as H, provide as Yt, onMounted as Ye, onUnmounted as Mt, createElementBlock as o, openBlock as a, normalizeClass as Me, createElementVNode as e, createBlock as ye, renderSlot as Pe, Teleport as Wt, createCommentVNode as I, toDisplayString as R, ref as M, watch as Le, createTextVNode as J, reactive as Ge, withModifiers as qe, createStaticVNode as Qt, createVNode as d, withDirectives as Qe, withCtx as T, unref as i, vModelText as Xe, nextTick as yt, Fragment as De, Transition as rt, createSlots as Ft, normalizeStyle as je, renderList as Ze, mergeProps as xa, useSlots as ha, inject as fa, resolveDynamicComponent as ot, onBeforeUnmount as Ra, withKeys as st, h as oe, isMemoSame as as, getCurrentInstance as ss } from "vue";
4
4
  import { u as vt, p as La } from "./useStrandsConfig-CMKVW1p3.es.js";
5
5
  import { s as Du } from "./useStrandsConfig-CMKVW1p3.es.js";
6
- import { u as ft } from "./useStrandsAuth-DzMk9Hla.es.js";
6
+ import { u as ft } from "./useStrandsAuth-CX9dSRKi.es.js";
7
7
  const os = { class: "app-content" }, ls = {
8
8
  key: 0,
9
9
  class: "ui-app-loading-overlay"
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("nuxt/app"),a=require("../../../useStrandsAuth-BCnZXu1A.cjs.js"),u=()=>{const t=e.useRuntimeConfig().public.strandsAuth,n=a.useStrandsAuth();return{...n,initialize:async()=>{await n.initialize()},signIn:async s=>{const i=await n.signIn(s);return i&&t.onSignInUrl&&await e.navigateTo(t.onSignInUrl),i},signUp:async s=>await n.signUp({email:s.email,password:"",firstName:"",lastName:""}),signOut:async()=>{await n.signOut(),t.onSignOutUrl&&await e.navigateTo(t.onSignOutUrl)}}},r=()=>{const{user:t}=u();return{user:t}},o=()=>{const{isAuthenticated:t,isLoading:n}=u();return{isAuthenticated:t,isLoading:n}};exports.useAuthState=o;exports.useAuthUser=r;exports.useStrandsAuth=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("nuxt/app"),a=require("../../../useStrandsAuth-Dhcd1aWs.cjs.js"),u=()=>{const t=e.useRuntimeConfig().public.strandsAuth,n=a.useStrandsAuth();return{...n,initialize:async()=>{await n.initialize()},signIn:async s=>{const i=await n.signIn(s);return i&&t.onSignInUrl&&await e.navigateTo(t.onSignInUrl),i},signUp:async s=>await n.signUp({email:s.email,password:"",firstName:"",lastName:""}),signOut:async()=>{await n.signOut(),t.onSignOutUrl&&await e.navigateTo(t.onSignOutUrl)}}},r=()=>{const{user:t}=u();return{user:t}},o=()=>{const{isAuthenticated:t,isLoading:n}=u();return{isAuthenticated:t,isLoading:n}};exports.useAuthState=o;exports.useAuthUser=r;exports.useStrandsAuth=u;
@@ -1,5 +1,5 @@
1
1
  import { useRuntimeConfig as e, navigateTo as a } from "nuxt/app";
2
- import { u as r } from "../../../useStrandsAuth-DzMk9Hla.es.js";
2
+ import { u as r } from "../../../useStrandsAuth-CX9dSRKi.es.js";
3
3
  const u = () => {
4
4
  const n = e().public.strandsAuth, t = r();
5
5
  return {
@@ -8,9 +8,9 @@ class _e {
8
8
  * Memoized fetch - prevents duplicate requests and caches results
9
9
  */
10
10
  async fetch(f, v, g = this.DEFAULT_TTL) {
11
- const P = Date.now(), i = this.cache.get(f);
12
- if (i && P - i.timestamp < i.ttl)
13
- return i.promise;
11
+ const P = Date.now(), s = this.cache.get(f);
12
+ if (s && P - s.timestamp < s.ttl)
13
+ return s.promise;
14
14
  this.cleanExpired();
15
15
  const o = v().finally(() => {
16
16
  setTimeout(() => {
@@ -72,7 +72,7 @@ function ke(n, f) {
72
72
  }
73
73
  const L = ke((n, f) => {
74
74
  typeof window < "u" && localStorage.setItem(n, f);
75
- }, 300), I = (n) => ({
75
+ }, 300), x = (n) => ({
76
76
  id: n.id,
77
77
  email: n.email,
78
78
  firstName: n.first_name || n.firstName || "",
@@ -107,21 +107,21 @@ const L = ke((n, f) => {
107
107
  mfaSessionId: m(null),
108
108
  availableMfaMethods: m([])
109
109
  };
110
- let k = null, y = null, x = null, b = null;
111
- function Ie() {
112
- const { getUrl: n, config: f } = Se(), { fetch: v, clear: g, invalidate: P } = Te(), { currentUser: i, currentSession: o, loadingStates: s, isInitialized: A, mfaRequired: p, mfaSessionId: h, availableMfaMethods: S } = Ae, _ = () => {
113
- if (i.value = null, o.value = null, p.value = !1, h.value = null, S.value = [], typeof window < "u" && (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user")), E(), M(), y = null, g(), typeof window < "u" && f.value?.onSignOutUrl) {
110
+ let A = null, y = null, b = null, O = null;
111
+ function Ee() {
112
+ const { getUrl: n, config: f } = Se(), { fetch: v, clear: g, invalidate: P } = Te(), { currentUser: s, currentSession: o, loadingStates: i, isInitialized: p, mfaRequired: S, mfaSessionId: h, availableMfaMethods: _ } = Ae, T = () => {
113
+ if (s.value = null, o.value = null, S.value = !1, h.value = null, _.value = [], typeof window < "u" && (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user")), E(), M(), y = null, g(), typeof window < "u" && f.value?.onSignOutUrl) {
114
114
  const e = window.location.pathname + window.location.search, t = f.value.onSignOutUrl;
115
115
  e !== t && (window.location.href = t);
116
116
  }
117
- }, R = c(() => s.value.initializing), U = c(() => s.value.signingIn), B = c(() => s.value.signingUp), V = c(() => s.value.signingOut), q = c(() => s.value.refreshingToken), K = c(() => s.value.sendingMfaEmail), G = c(() => s.value.verifyingMfa);
118
- c(() => s.value.loadingProfile);
119
- const z = c(
120
- () => s.value.signingIn || s.value.signingUp || s.value.signingOut || s.value.refreshingToken || s.value.sendingMfaEmail || s.value.verifyingMfa || s.value.loadingProfile
121
- ), H = c(() => s.value.initializing || z.value), W = c(() => {
122
- const e = s.value;
117
+ }, U = c(() => i.value.initializing), R = c(() => i.value.signingIn), B = c(() => i.value.signingUp), V = c(() => i.value.signingOut), q = c(() => i.value.refreshingToken), K = c(() => i.value.sendingMfaEmail), W = c(() => i.value.verifyingMfa);
118
+ c(() => i.value.loadingProfile);
119
+ const J = c(
120
+ () => i.value.signingIn || i.value.signingUp || i.value.signingOut || i.value.refreshingToken || i.value.sendingMfaEmail || i.value.verifyingMfa || i.value.loadingProfile
121
+ ), G = c(() => i.value.initializing || J.value), H = c(() => {
122
+ const e = i.value;
123
123
  return e.initializing ? "Checking authentication..." : e.signingIn ? "Signing you in..." : e.signingUp ? "Creating your account..." : e.signingOut ? "Signing you out..." : e.refreshingToken ? "Refreshing session..." : e.sendingMfaEmail ? "Sending verification code..." : e.verifyingMfa ? "Verifying code..." : e.loadingProfile ? "Loading profile..." : "Loading...";
124
- }), O = () => {
124
+ }), I = () => {
125
125
  const e = {};
126
126
  return o.value?.accessToken && (e.Authorization = `Bearer ${o.value.accessToken}`), o.value?.refreshToken && (e["x-refresh-token"] = o.value.refreshToken), e;
127
127
  }, Y = async (e, t, a) => {
@@ -172,10 +172,10 @@ function Ie() {
172
172
  throw new Error(l);
173
173
  }
174
174
  return r.json();
175
- }, X = c(() => i.value !== null), Z = async (e) => {
176
- s.value.signingIn = !0;
175
+ }, X = c(() => s.value !== null), Z = async (e) => {
176
+ i.value.signingIn = !0;
177
177
  try {
178
- p.value = !1, h.value = null, S.value = [];
178
+ S.value = !1, h.value = null, _.value = [];
179
179
  const t = {
180
180
  "Content-Type": "application/json"
181
181
  };
@@ -189,7 +189,7 @@ function Ie() {
189
189
  throw a.status === 401 ? new Error("Invalid email or password") : a.status === 403 ? new Error("Please verify your email address before signing in") : new Error(`Sign in failed: ${a.status} ${a.statusText}`);
190
190
  const r = await a.json();
191
191
  if (r.mfa_required) {
192
- p.value = !0, h.value = r.mfa_session_id || null;
192
+ S.value = !0, h.value = r.mfa_session_id || null;
193
193
  const u = (r.available_mfa_methods || []).map((l) => {
194
194
  let d = `${l.device_type.charAt(0).toUpperCase() + l.device_type.slice(1)} Authentication`;
195
195
  return l.device_type === "hardware" ? d = l.device_name || "Security Key" : l.device_type === "totp" ? d = l.device_name || "Authenticator App" : l.device_type === "email" && (d = l.device_name || "Email Verification"), {
@@ -204,27 +204,27 @@ function Ie() {
204
204
  device_info: l.device_info
205
205
  };
206
206
  });
207
- return S.value = u, s.value.signingIn = !1, r;
207
+ return _.value = u, i.value.signingIn = !1, r;
208
208
  }
209
209
  return await N(r), r;
210
210
  } catch (t) {
211
211
  throw t;
212
212
  } finally {
213
- s.value.signingIn = !1;
213
+ i.value.signingIn = !1;
214
214
  }
215
215
  }, ee = async (e) => {
216
- s.value.signingUp = !0;
216
+ i.value.signingUp = !0;
217
217
  try {
218
218
  throw new Error("Sign up not implemented - please integrate with auth SDK");
219
219
  } finally {
220
- s.value.signingUp = !1;
220
+ i.value.signingUp = !1;
221
221
  }
222
222
  }, te = async () => {
223
- s.value.signingOut = !0;
223
+ i.value.signingOut = !0;
224
224
  try {
225
- E(), M(), y = null, g(), i.value = null, o.value = null, p.value = !1, h.value = null, S.value = [], typeof window < "u" && (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user")), typeof window < "u" && f.value?.onSignOutUrl && (window.location.href = f.value.onSignOutUrl);
225
+ E(), M(), y = null, g(), s.value = null, o.value = null, S.value = !1, h.value = null, _.value = [], typeof window < "u" && (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user")), typeof window < "u" && f.value?.onSignOutUrl && (window.location.href = f.value.onSignOutUrl);
226
226
  } finally {
227
- s.value.signingOut = !1;
227
+ i.value.signingOut = !1;
228
228
  }
229
229
  }, $ = async () => {
230
230
  if (!o.value?.refreshToken)
@@ -232,7 +232,7 @@ function Ie() {
232
232
  if (y)
233
233
  return await y;
234
234
  y = (async () => {
235
- s.value.refreshingToken = !0;
235
+ i.value.refreshingToken = !0;
236
236
  try {
237
237
  const t = await fetch(n("refresh"), {
238
238
  method: "POST",
@@ -245,30 +245,30 @@ function Ie() {
245
245
  });
246
246
  if (!t.ok) {
247
247
  if (t.status === 401)
248
- return _(), !1;
248
+ return T(), !1;
249
249
  throw new Error(`Token refresh failed: ${t.status} ${t.statusText}`);
250
250
  }
251
251
  const a = await t.json();
252
- a.user && (i.value = I(a.user), i.value && typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(i.value)));
252
+ a.user && (s.value = x(a.user), s.value && typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(s.value)));
253
253
  const r = {
254
254
  accessToken: a.access_token,
255
255
  refreshToken: a.refresh_token,
256
256
  expiresAt: new Date(Date.now() + 300 * 1e3),
257
257
  // 5 minutes from now
258
- userId: a.user?.id || i.value?.id
258
+ userId: a.user?.id || s.value?.id
259
259
  };
260
- return o.value = r, typeof window < "u" && localStorage.setItem("strands_auth_session", JSON.stringify(r)), T(), C(), P(`sessions:${o.value.accessToken.slice(0, 20)}`), !0;
260
+ return o.value = r, typeof window < "u" && localStorage.setItem("strands_auth_session", JSON.stringify(r)), k(), C(), P(`sessions:${o.value.accessToken.slice(0, 20)}`), !0;
261
261
  } catch {
262
- return _(), !1;
262
+ return T(), !1;
263
263
  } finally {
264
- s.value.refreshingToken = !1;
264
+ i.value.refreshingToken = !1;
265
265
  }
266
266
  })();
267
267
  const e = await y;
268
268
  return y = null, e;
269
269
  }, ae = async () => {
270
270
  const e = `profile:${o.value.accessToken.slice(0, 20)}`;
271
- s.value.loadingProfile = !0;
271
+ i.value.loadingProfile = !0;
272
272
  try {
273
273
  return await v(e, async () => {
274
274
  const t = await fetch(n("profile"), {
@@ -281,13 +281,13 @@ function Ie() {
281
281
  if (!t.ok)
282
282
  throw t.status === 401 ? new Error("Authentication expired. Please sign in again.") : new Error(`Failed to fetch profile: ${t.status} ${t.statusText}`);
283
283
  const a = await t.json();
284
- return i.value = I(a), i.value && typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(i.value)), i.value;
284
+ return s.value = x(a), s.value && typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(s.value)), s.value;
285
285
  });
286
286
  } finally {
287
- s.value.loadingProfile = !1;
287
+ i.value.loadingProfile = !1;
288
288
  }
289
289
  }, ne = async (e) => {
290
- s.value.loadingProfile = !0;
290
+ i.value.loadingProfile = !0;
291
291
  try {
292
292
  const t = await fetch(n("profile"), {
293
293
  method: "POST",
@@ -303,12 +303,12 @@ function Ie() {
303
303
  if (!t.ok)
304
304
  throw t.status === 401 ? new Error("Authentication expired. Please sign in again.") : new Error(`Profile update failed: ${t.status} ${t.statusText}`);
305
305
  const a = await t.json();
306
- return i.value = I(a), i.value && L("strands_auth_user", JSON.stringify(i.value)), i.value;
306
+ return s.value = x(a), s.value && L("strands_auth_user", JSON.stringify(s.value)), s.value;
307
307
  } finally {
308
- s.value.loadingProfile = !1;
308
+ i.value.loadingProfile = !1;
309
309
  }
310
310
  }, se = async (e) => {
311
- s.value.loadingProfile = !0;
311
+ i.value.loadingProfile = !0;
312
312
  try {
313
313
  const t = await fetch(n("settings"), {
314
314
  method: "POST",
@@ -323,12 +323,12 @@ function Ie() {
323
323
  if (!t.ok)
324
324
  throw t.status === 401 ? new Error("Authentication expired. Please sign in again.") : new Error(`Settings update failed: ${t.status} ${t.statusText}`);
325
325
  const a = await t.json();
326
- return i.value = I(a), i.value && L("strands_auth_user", JSON.stringify(i.value)), i.value;
326
+ return s.value = x(a), s.value && L("strands_auth_user", JSON.stringify(s.value)), s.value;
327
327
  } finally {
328
- s.value.loadingProfile = !1;
328
+ i.value.loadingProfile = !1;
329
329
  }
330
330
  }, ie = async (e, t) => {
331
- s.value.loadingProfile = !0;
331
+ i.value.loadingProfile = !0;
332
332
  try {
333
333
  const a = await fetch(n("changeEmail"), {
334
334
  method: "POST",
@@ -350,20 +350,20 @@ function Ie() {
350
350
  }
351
351
  }
352
352
  const r = await a.json();
353
- return i.value && (i.value = {
354
- ...i.value,
353
+ return s.value && (s.value = {
354
+ ...s.value,
355
355
  email: e,
356
356
  emailVerified: !1,
357
357
  // Email needs to be verified again
358
358
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
359
- }, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(i.value))), r;
359
+ }, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(s.value))), r;
360
360
  } finally {
361
- s.value.loadingProfile = !1;
361
+ i.value.loadingProfile = !1;
362
362
  }
363
363
  }, re = async (e, t, a = !1) => {
364
364
  if (!h.value)
365
365
  throw new Error("No MFA session available");
366
- s.value.verifyingMfa = !0;
366
+ i.value.verifyingMfa = !0;
367
367
  try {
368
368
  const r = n(a ? "mfaBackupCodeVerify" : "mfaSigninVerify"), u = a ? { mfa_session_id: h.value, backup_code: t } : { mfa_session_id: h.value, device_id: e, code: t }, l = await fetch(r, {
369
369
  method: "POST",
@@ -371,25 +371,25 @@ function Ie() {
371
371
  body: JSON.stringify(u)
372
372
  });
373
373
  if (!l.ok) {
374
- const j = await l.text();
375
- let J = "MFA verification failed";
374
+ const z = await l.text();
375
+ let j = "MFA verification failed";
376
376
  try {
377
- const F = JSON.parse(j);
378
- J = F.message || F.error || j;
377
+ const F = JSON.parse(z);
378
+ j = F.message || F.error || z;
379
379
  } catch {
380
- J = j || "MFA verification failed";
380
+ j = z || "MFA verification failed";
381
381
  }
382
- throw new Error(J);
382
+ throw new Error(j);
383
383
  }
384
384
  const d = await l.json();
385
- return p.value = !1, h.value = null, S.value = [], await N(d), d;
385
+ return S.value = !1, h.value = null, _.value = [], await N(d), d;
386
386
  } finally {
387
- s.value.verifyingMfa = !1;
387
+ i.value.verifyingMfa = !1;
388
388
  }
389
389
  }, oe = async (e) => {
390
390
  if (!h.value)
391
391
  throw new Error("No MFA session available");
392
- s.value.sendingMfaEmail = !0;
392
+ i.value.sendingMfaEmail = !0;
393
393
  try {
394
394
  const t = await fetch(n("mfaSigninSendEmail"), {
395
395
  method: "POST",
@@ -412,7 +412,7 @@ function Ie() {
412
412
  }
413
413
  return await t.json();
414
414
  } finally {
415
- s.value.sendingMfaEmail = !1;
415
+ i.value.sendingMfaEmail = !1;
416
416
  }
417
417
  }, le = async (e) => {
418
418
  if (!h.value)
@@ -439,66 +439,66 @@ function Ie() {
439
439
  return t.json();
440
440
  }, N = async (e) => {
441
441
  try {
442
- e.user && (i.value = I(e.user));
442
+ e.user && (s.value = x(e.user));
443
443
  const t = {
444
444
  accessToken: e.access_token,
445
445
  refreshToken: e.refresh_token,
446
446
  expiresAt: new Date(Date.now() + 300 * 1e3),
447
447
  // 5 minutes from now (matching API token expiry)
448
- userId: i.value?.id || e.user?.id
448
+ userId: s.value?.id || e.user?.id
449
449
  };
450
- o.value = t, typeof window < "u" && (localStorage.setItem("strands_auth_session", JSON.stringify(t)), i.value && localStorage.setItem("strands_auth_user", JSON.stringify(i.value))), T(), C();
450
+ o.value = t, typeof window < "u" && (localStorage.setItem("strands_auth_session", JSON.stringify(t)), s.value && localStorage.setItem("strands_auth_user", JSON.stringify(s.value))), k(), C();
451
451
  } catch {
452
452
  }
453
- }, T = () => {
454
- if (k && clearTimeout(k), !o.value || typeof document < "u" && document.visibilityState === "hidden")
453
+ }, k = () => {
454
+ if (A && clearTimeout(A), !o.value || typeof document < "u" && document.visibilityState === "hidden")
455
455
  return;
456
456
  const e = /* @__PURE__ */ new Date(), a = o.value.expiresAt.getTime() - e.getTime() - 60 * 1e3;
457
457
  if (a <= 0) {
458
458
  $();
459
459
  return;
460
460
  }
461
- k = setTimeout(async () => {
462
- (typeof document > "u" || document.visibilityState === "visible") && await $() && T();
461
+ A = setTimeout(async () => {
462
+ (typeof document > "u" || document.visibilityState === "visible") && await $() && k();
463
463
  }, a);
464
464
  }, E = () => {
465
- k && (clearTimeout(k), k = null);
465
+ A && (clearTimeout(A), A = null);
466
466
  }, C = () => {
467
- x || typeof window > "u" || (x = setInterval(() => {
468
- i.value && o.value && (localStorage.getItem("strands_auth_session") || (M(), _()));
467
+ b || typeof window > "u" || (b = setInterval(() => {
468
+ s.value && o.value && (localStorage.getItem("strands_auth_session") || (M(), T()));
469
469
  }, 2e3));
470
470
  }, M = () => {
471
- x && (clearInterval(x), x = null);
471
+ b && (clearInterval(b), b = null);
472
472
  }, D = async () => {
473
- if (A.value) {
474
- s.value.initializing = !1;
473
+ if (console.log("[useStrandsAuth] initialize() called, isInitialized:", p.value, "hasPromise:", !!O), p.value) {
474
+ console.log("[useStrandsAuth] Already initialized, setting initializing=false"), i.value.initializing = !1;
475
475
  return;
476
476
  }
477
- return b || (b = (async () => {
478
- s.value.initializing = !0;
477
+ return O ? (console.log("[useStrandsAuth] Waiting for existing initialization..."), O) : (console.log("[useStrandsAuth] Starting new initialization..."), O = (async () => {
478
+ i.value.initializing = !0;
479
479
  try {
480
480
  if (typeof window < "u") {
481
481
  const e = localStorage.getItem("strands_auth_session"), t = localStorage.getItem("strands_auth_user");
482
482
  if (e && t)
483
483
  try {
484
484
  const a = JSON.parse(e), r = JSON.parse(t);
485
- a.expiresAt = new Date(a.expiresAt), a.expiresAt <= /* @__PURE__ */ new Date() && a.refreshToken ? (o.value = a, i.value = r, await Promise.race([
485
+ a.expiresAt = new Date(a.expiresAt), a.expiresAt <= /* @__PURE__ */ new Date() && a.refreshToken ? (o.value = a, s.value = r, await Promise.race([
486
486
  $(),
487
487
  new Promise((d) => setTimeout(() => d(!1), 5e3))
488
- ]) || _()) : a.expiresAt > /* @__PURE__ */ new Date() ? (o.value = a, i.value = r, T(), C()) : (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user"));
488
+ ]) || T()) : a.expiresAt > /* @__PURE__ */ new Date() ? (o.value = a, s.value = r, k(), C()) : (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user"));
489
489
  } catch {
490
490
  localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user");
491
491
  }
492
492
  }
493
- A.value = !0, await new Promise((e) => setTimeout(e, 50));
493
+ p.value = !0, console.log("[useStrandsAuth] isInitialized set to true, currentUser:", !!s.value), await new Promise((e) => setTimeout(e, 50));
494
494
  } catch (e) {
495
495
  console.error("[useStrandsAuth] initialization error:", e);
496
496
  } finally {
497
- s.value.initializing = !1, b = null;
497
+ console.log("[useStrandsAuth] finally - setting initializing=false"), i.value.initializing = !1, O = null;
498
498
  }
499
- })(), b);
499
+ })(), O);
500
500
  }, ue = async (e) => {
501
- s.value.loadingProfile = !0;
501
+ i.value.loadingProfile = !0;
502
502
  try {
503
503
  const t = await fetch(n("changeUsername"), {
504
504
  method: "POST",
@@ -515,14 +515,14 @@ function Ie() {
515
515
  throw t.status === 409 ? new Error("Username is already taken") : r.cooldown_end ? new Error(`You can only change your username once every 30 days. You can change it again on ${new Date(r.cooldown_end).toLocaleDateString()}`) : new Error(r.message || `Username change failed: ${t.status} ${t.statusText}`);
516
516
  }
517
517
  const a = await t.json();
518
- return i.value && (i.value = {
519
- ...i.value,
518
+ return s.value && (s.value = {
519
+ ...s.value,
520
520
  username: e,
521
521
  usernameLastChangedAt: (/* @__PURE__ */ new Date()).toISOString(),
522
522
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
523
- }, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(i.value))), a;
523
+ }, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(s.value))), a;
524
524
  } finally {
525
- s.value.loadingProfile = !1;
525
+ i.value.loadingProfile = !1;
526
526
  }
527
527
  }, ce = async () => {
528
528
  const e = await fetch(n("usernameCooldown"), {
@@ -548,7 +548,7 @@ function Ie() {
548
548
  const e = `sessions:${o.value?.accessToken?.slice(0, 20) || "no-token"}`;
549
549
  try {
550
550
  return await v(e, async () => {
551
- const t = O(), a = await fetch(n("sessions"), {
551
+ const t = I(), a = await fetch(n("sessions"), {
552
552
  method: "GET",
553
553
  headers: t
554
554
  });
@@ -562,7 +562,7 @@ function Ie() {
562
562
  }, he = async () => {
563
563
  const e = await fetch(n("sessionsStats"), {
564
564
  method: "GET",
565
- headers: O()
565
+ headers: I()
566
566
  });
567
567
  if (!e.ok)
568
568
  throw new Error(`Failed to get session stats: ${e.status} ${e.statusText}`);
@@ -570,7 +570,7 @@ function Ie() {
570
570
  }, ge = async (e) => {
571
571
  const t = n("sessionRevoke").replace("{session_id}", encodeURIComponent(e)), a = await fetch(t, {
572
572
  method: "POST",
573
- headers: O()
573
+ headers: I()
574
574
  });
575
575
  if (!a.ok)
576
576
  throw new Error(`Failed to revoke session: ${a.status} ${a.statusText}`);
@@ -578,21 +578,21 @@ function Ie() {
578
578
  }, ve = async () => {
579
579
  const e = await fetch(n("sessionsRevokeAll"), {
580
580
  method: "POST",
581
- headers: O()
581
+ headers: I()
582
582
  });
583
583
  if (!e.ok)
584
584
  throw new Error(`Failed to revoke all other sessions: ${e.status} ${e.statusText}`);
585
585
  return e.status === 200;
586
586
  };
587
587
  typeof document < "u" && document.addEventListener("visibilitychange", () => {
588
- document.visibilityState === "visible" && o.value ? (T(), we()) : document.visibilityState === "hidden" && E();
588
+ document.visibilityState === "visible" && o.value ? (k(), we()) : document.visibilityState === "hidden" && E();
589
589
  }), typeof window < "u" && window.addEventListener("storage", (e) => {
590
- (e.key === "strands_auth_session" || e.key === "strands_auth_user") && !e.newValue && i.value && _();
590
+ (e.key === "strands_auth_session" || e.key === "strands_auth_user") && !e.newValue && s.value && T();
591
591
  });
592
592
  const we = () => {
593
- if (!(typeof window > "u") && i.value && o.value) {
593
+ if (!(typeof window > "u") && s.value && o.value) {
594
594
  const e = localStorage.getItem("strands_auth_session"), t = localStorage.getItem("strands_auth_user");
595
- (!e || !t) && _();
595
+ (!e || !t) && T();
596
596
  }
597
597
  }, me = () => {
598
598
  E(), M(), g();
@@ -601,27 +601,27 @@ function Ie() {
601
601
  ye() && pe(me);
602
602
  } catch {
603
603
  }
604
- return A.value || D(), {
604
+ return p.value || D(), {
605
605
  // State
606
- user: c(() => i.value),
607
- currentUser: c(() => i.value),
606
+ user: c(() => s.value),
607
+ currentUser: c(() => s.value),
608
608
  currentSession: c(() => o.value),
609
609
  isAuthenticated: X,
610
- isLoading: c(() => H.value || !A.value),
611
- loading: z,
612
- loadingMessage: W,
610
+ isLoading: c(() => G.value || !p.value),
611
+ loading: J,
612
+ loadingMessage: H,
613
613
  // Specific loading states
614
- isInitializing: R,
615
- isSigningIn: U,
614
+ isInitializing: U,
615
+ isSigningIn: R,
616
616
  isSigningUp: B,
617
617
  isSigningOut: V,
618
618
  isRefreshingToken: q,
619
619
  isSendingMfaEmail: K,
620
- isVerifyingMfa: G,
620
+ isVerifyingMfa: W,
621
621
  // MFA State
622
- mfaRequired: c(() => p.value),
622
+ mfaRequired: c(() => S.value),
623
623
  mfaSessionId: c(() => h.value),
624
- availableMfaMethods: c(() => S.value),
624
+ availableMfaMethods: c(() => _.value),
625
625
  // Methods
626
626
  signIn: Z,
627
627
  signUp: ee,
@@ -647,15 +647,15 @@ function Ie() {
647
647
  registerHardwareKey: Q,
648
648
  completeHardwareKeyRegistration: Y,
649
649
  // Token management
650
- startTokenRefreshTimer: T,
650
+ startTokenRefreshTimer: k,
651
651
  stopTokenRefreshTimer: E,
652
- getAuthHeaders: O,
652
+ getAuthHeaders: I,
653
653
  // Force re-initialization (useful for testing or navigation)
654
654
  forceReInit: () => {
655
- A.value = !1, s.value.initializing = !0, D();
655
+ p.value = !1, i.value.initializing = !0, D();
656
656
  }
657
657
  };
658
658
  }
659
659
  export {
660
- Ie as u
660
+ Ee as u
661
661
  };
@@ -0,0 +1 @@
1
+ "use strict";const u=require("vue"),we=require("./useStrandsConfig-B5kp4aF9.cjs.js");class ye{cache=new Map;DEFAULT_TTL=300*1e3;async fetch(d,v,g=this.DEFAULT_TTL){const b=Date.now(),s=this.cache.get(d);if(s&&b-s.timestamp<s.ttl)return s.promise;this.cleanExpired();const o=v().finally(()=>{setTimeout(()=>{this.cache.delete(d)},g)});return this.cache.set(d,{promise:o,timestamp:b,ttl:g}),o}clear(){this.cache.clear()}invalidate(d){this.cache.delete(d)}cleanExpired(){const d=Date.now();for(const[v,g]of this.cache.entries())d-g.timestamp>g.ttl&&this.cache.delete(v)}getStats(){return{size:this.cache.size,entries:Array.from(this.cache.keys())}}}const m=new ye;function pe(){return{fetch:m.fetch.bind(m),clear:m.clear.bind(m),invalidate:m.invalidate.bind(m),getStats:m.getStats.bind(m)}}function Se(n,d){let v=null;return(...g)=>{v&&clearTimeout(v),v=setTimeout(()=>{n(...g)},d)}}const F=Se((n,d)=>{typeof window<"u"&&localStorage.setItem(n,d)},300),E=n=>({id:n.id,email:n.email,firstName:n.first_name||n.firstName||"",lastName:n.last_name||n.lastName||"",avatar:n.avatar_url||n.avatar,mfaEnabled:n.mfa_enabled??n.mfaEnabled??!1,emailVerified:n.email_verified??n.emailVerified??!1,passwordUpdatedAt:n.password_updated_at||n.passwordUpdatedAt,settings:n.settings||{},xp:n.xp||0,level:n.level||1,next_level_xp:n.next_level_xp||n.next_level_xp||4,username:n.username,usernameLastChangedAt:n.username_last_changed_at||n.usernameLastChangedAt,createdAt:n.created_at||n.createdAt,updatedAt:n.updated_at||n.updatedAt||new Date().toISOString()}),_e={currentUser:u.ref(null),currentSession:u.ref(null),loadingStates:u.ref({initializing:!0,signingIn:!1,signingUp:!1,signingOut:!1,refreshingToken:!1,sendingMfaEmail:!1,verifyingMfa:!1,loadingProfile:!1}),isInitialized:u.ref(!1),mfaRequired:u.ref(!1),mfaSessionId:u.ref(null),availableMfaMethods:u.ref([])};let k=null,w=null,x=null,A=null;function Te(){const{getUrl:n,config:d}=we.useStrandsConfig(),{fetch:v,clear:g,invalidate:b}=pe(),{currentUser:s,currentSession:o,loadingStates:i,isInitialized:y,mfaRequired:p,mfaSessionId:h,availableMfaMethods:S}=_e,_=()=>{if(s.value=null,o.value=null,p.value=!1,h.value=null,S.value=[],typeof window<"u"&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")),I(),$(),w=null,g(),typeof window<"u"&&d.value?.onSignOutUrl){const e=window.location.pathname+window.location.search,t=d.value.onSignOutUrl;e!==t&&(window.location.href=t)}},L=u.computed(()=>i.value.initializing),U=u.computed(()=>i.value.signingIn),R=u.computed(()=>i.value.signingUp),q=u.computed(()=>i.value.signingOut),B=u.computed(()=>i.value.refreshingToken),V=u.computed(()=>i.value.sendingMfaEmail),K=u.computed(()=>i.value.verifyingMfa);u.computed(()=>i.value.loadingProfile);const j=u.computed(()=>i.value.signingIn||i.value.signingUp||i.value.signingOut||i.value.refreshingToken||i.value.sendingMfaEmail||i.value.verifyingMfa||i.value.loadingProfile),W=u.computed(()=>i.value.initializing||j.value),G=u.computed(()=>{const e=i.value;return e.initializing?"Checking authentication...":e.signingIn?"Signing you in...":e.signingUp?"Creating your account...":e.signingOut?"Signing you out...":e.refreshingToken?"Refreshing session...":e.sendingMfaEmail?"Sending verification code...":e.verifyingMfa?"Verifying code...":e.loadingProfile?"Loading profile...":"Loading..."}),O=()=>{const e={};return o.value?.accessToken&&(e.Authorization=`Bearer ${o.value.accessToken}`),o.value?.refreshToken&&(e["x-refresh-token"]=o.value.refreshToken),e},H=async(e,t,a)=>{const r=await fetch(n("mfaHardwareCompleteRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({device_id:e,credential:t})});if(!r.ok){const c=await r.text();let l="Failed to complete hardware key registration";try{const f=JSON.parse(c);l=f.message||f.error||c}catch{l=c||"Failed to complete hardware key registration"}throw new Error(l)}return r.json()},Y=async(e,t,a="hardware")=>{const r=await fetch(n("mfaHardwareStartRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({device_name:e,device_type:a})});if(!r.ok){const c=await r.text();let l="Failed to start hardware key registration";try{const f=JSON.parse(c);l=f.message||f.error||c}catch{l=c||"Failed to start hardware key registration"}throw new Error(l)}return r.json()},Q=u.computed(()=>s.value!==null),X=async e=>{i.value.signingIn=!0;try{p.value=!1,h.value=null,S.value=[];const t={"Content-Type":"application/json"};typeof window<"u"&&window.location&&(t.Origin=window.location.origin);const a=await fetch(n("signIn"),{method:"POST",headers:t,body:JSON.stringify(e)});if(!a.ok)throw a.status===401?new Error("Invalid email or password"):a.status===403?new Error("Please verify your email address before signing in"):new Error(`Sign in failed: ${a.status} ${a.statusText}`);const r=await a.json();if(r.mfa_required){p.value=!0,h.value=r.mfa_session_id||null;const c=(r.available_mfa_methods||[]).map(l=>{let f=`${l.device_type.charAt(0).toUpperCase()+l.device_type.slice(1)} Authentication`;return l.device_type==="hardware"?f=l.device_name||"Security Key":l.device_type==="totp"?f=l.device_name||"Authenticator App":l.device_type==="email"&&(f=l.device_name||"Email Verification"),{id:l.device_id,device_type:l.device_type,device_name:l.device_name||f,is_active:!0,created_at:new Date().toISOString(),last_used_at:l.last_used_at,credential_id:l.credential_id,device_info:l.device_info}});return S.value=c,i.value.signingIn=!1,r}return await C(r),r}catch(t){throw t}finally{i.value.signingIn=!1}},Z=async e=>{i.value.signingUp=!0;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{i.value.signingUp=!1}},ee=async()=>{i.value.signingOut=!0;try{I(),$(),w=null,g(),s.value=null,o.value=null,p.value=!1,h.value=null,S.value=[],typeof window<"u"&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")),typeof window<"u"&&d.value?.onSignOutUrl&&(window.location.href=d.value.onSignOutUrl)}finally{i.value.signingOut=!1}},P=async()=>{if(!o.value?.refreshToken)return!1;if(w)return await w;w=(async()=>{i.value.refreshingToken=!0;try{const t=await fetch(n("refresh"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:o.value.refreshToken})});if(!t.ok){if(t.status===401)return _(),!1;throw new Error(`Token refresh failed: ${t.status} ${t.statusText}`)}const a=await t.json();a.user&&(s.value=E(a.user),s.value&&typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(s.value)));const r={accessToken:a.access_token,refreshToken:a.refresh_token,expiresAt:new Date(Date.now()+300*1e3),userId:a.user?.id||s.value?.id};return o.value=r,typeof window<"u"&&localStorage.setItem("strands_auth_session",JSON.stringify(r)),T(),M(),b(`sessions:${o.value.accessToken.slice(0,20)}`),!0}catch{return _(),!1}finally{i.value.refreshingToken=!1}})();const e=await w;return w=null,e},te=async()=>{const e=`profile:${o.value.accessToken.slice(0,20)}`;i.value.loadingProfile=!0;try{return await v(e,async()=>{const t=await fetch(n("profile"),{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value?.accessToken}`}});if(!t.ok)throw t.status===401?new Error("Authentication expired. Please sign in again."):new Error(`Failed to fetch profile: ${t.status} ${t.statusText}`);const a=await t.json();return s.value=E(a),s.value&&typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(s.value)),s.value})}finally{i.value.loadingProfile=!1}},ae=async e=>{i.value.loadingProfile=!0;try{const t=await fetch(n("profile"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({first_name:e.firstName,last_name:e.lastName})});if(!t.ok)throw t.status===401?new Error("Authentication expired. Please sign in again."):new Error(`Profile update failed: ${t.status} ${t.statusText}`);const a=await t.json();return s.value=E(a),s.value&&F("strands_auth_user",JSON.stringify(s.value)),s.value}finally{i.value.loadingProfile=!1}},ne=async e=>{i.value.loadingProfile=!0;try{const t=await fetch(n("settings"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({settings:e})});if(!t.ok)throw t.status===401?new Error("Authentication expired. Please sign in again."):new Error(`Settings update failed: ${t.status} ${t.statusText}`);const a=await t.json();return s.value=E(a),s.value&&F("strands_auth_user",JSON.stringify(s.value)),s.value}finally{i.value.loadingProfile=!1}},se=async(e,t)=>{i.value.loadingProfile=!0;try{const a=await fetch(n("changeEmail"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({new_email:e,password:t})});if(!a.ok){if(a.status===401)throw new Error("Authentication expired. Please sign in again.");{const c=await a.json().catch(()=>({}));throw new Error(c.message||`Email change failed: ${a.status} ${a.statusText}`)}}const r=await a.json();return s.value&&(s.value={...s.value,email:e,emailVerified:!1,updatedAt:new Date().toISOString()},typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(s.value))),r}finally{i.value.loadingProfile=!1}},ie=async(e,t,a=!1)=>{if(!h.value)throw new Error("No MFA session available");i.value.verifyingMfa=!0;try{const r=n(a?"mfaBackupCodeVerify":"mfaSigninVerify"),c=a?{mfa_session_id:h.value,backup_code:t}:{mfa_session_id:h.value,device_id:e,code:t},l=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!l.ok){const D=await l.text();let z="MFA verification failed";try{const J=JSON.parse(D);z=J.message||J.error||D}catch{z=D||"MFA verification failed"}throw new Error(z)}const f=await l.json();return p.value=!1,h.value=null,S.value=[],await C(f),f}finally{i.value.verifyingMfa=!1}},re=async e=>{if(!h.value)throw new Error("No MFA session available");i.value.sendingMfaEmail=!0;try{const t=await fetch(n("mfaSigninSendEmail"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:h.value,device_id:e})});if(!t.ok){const r=await t.text();let c="Failed to send MFA email code";try{const l=JSON.parse(r);c=l.message||l.error||r}catch{c=r||"Failed to send MFA email code"}throw new Error(c)}return await t.json()}finally{i.value.sendingMfaEmail=!1}},oe=async e=>{if(!h.value)throw new Error("No MFA session available");const t=await fetch(n("mfaWebAuthnChallenge"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:h.value,device_id:e})});if(!t.ok){const a=await t.text();let r="Failed to get WebAuthn challenge";try{const c=JSON.parse(a);r=c.message||c.error||a}catch{r=a||r}throw new Error(r)}return t.json()},C=async e=>{try{e.user&&(s.value=E(e.user));const t={accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:new Date(Date.now()+300*1e3),userId:s.value?.id||e.user?.id};o.value=t,typeof window<"u"&&(localStorage.setItem("strands_auth_session",JSON.stringify(t)),s.value&&localStorage.setItem("strands_auth_user",JSON.stringify(s.value))),T(),M()}catch{}},T=()=>{if(k&&clearTimeout(k),!o.value||typeof document<"u"&&document.visibilityState==="hidden")return;const e=new Date,a=o.value.expiresAt.getTime()-e.getTime()-60*1e3;if(a<=0){P();return}k=setTimeout(async()=>{(typeof document>"u"||document.visibilityState==="visible")&&await P()&&T()},a)},I=()=>{k&&(clearTimeout(k),k=null)},M=()=>{x||typeof window>"u"||(x=setInterval(()=>{s.value&&o.value&&(localStorage.getItem("strands_auth_session")||($(),_()))},2e3))},$=()=>{x&&(clearInterval(x),x=null)},N=async()=>{if(console.log("[useStrandsAuth] initialize() called, isInitialized:",y.value,"hasPromise:",!!A),y.value){console.log("[useStrandsAuth] Already initialized, setting initializing=false"),i.value.initializing=!1;return}return A?(console.log("[useStrandsAuth] Waiting for existing initialization..."),A):(console.log("[useStrandsAuth] Starting new initialization..."),A=(async()=>{i.value.initializing=!0;try{if(typeof window<"u"){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");if(e&&t)try{const a=JSON.parse(e),r=JSON.parse(t);a.expiresAt=new Date(a.expiresAt),a.expiresAt<=new Date&&a.refreshToken?(o.value=a,s.value=r,await Promise.race([P(),new Promise(f=>setTimeout(()=>f(!1),5e3))])||_()):a.expiresAt>new Date?(o.value=a,s.value=r,T(),M()):(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}catch{localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")}}y.value=!0,console.log("[useStrandsAuth] isInitialized set to true, currentUser:",!!s.value),await new Promise(e=>setTimeout(e,50))}catch(e){console.error("[useStrandsAuth] initialization error:",e)}finally{console.log("[useStrandsAuth] finally - setting initializing=false"),i.value.initializing=!1,A=null}})(),A)},le=async e=>{i.value.loadingProfile=!0;try{const t=await fetch(n("changeUsername"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({username:e})});if(!t.ok){const r=await t.json().catch(()=>({}));throw t.status===409?new Error("Username is already taken"):r.cooldown_end?new Error(`You can only change your username once every 30 days. You can change it again on ${new Date(r.cooldown_end).toLocaleDateString()}`):new Error(r.message||`Username change failed: ${t.status} ${t.statusText}`)}const a=await t.json();return s.value&&(s.value={...s.value,username:e,usernameLastChangedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(s.value))),a}finally{i.value.loadingProfile=!1}},ue=async()=>{const e=await fetch(n("usernameCooldown"),{method:"GET",headers:{Authorization:`Bearer ${o.value.accessToken}`}});if(!e.ok)throw new Error(`Failed to get username cooldown: ${e.status} ${e.statusText}`);return e.json()},ce=async e=>{const t=n("checkUsernameAvailability").replace("{username}",encodeURIComponent(e)),a=await fetch(t,{method:"GET",headers:{"Content-Type":"application/json"}});if(!a.ok)throw new Error(`Failed to check username availability: ${a.status} ${a.statusText}`);return a.json()},de=async()=>{const e=`sessions:${o.value?.accessToken?.slice(0,20)||"no-token"}`;try{return await v(e,async()=>{const t=O(),a=await fetch(n("sessions"),{method:"GET",headers:t});if(!a.ok)throw await a.text(),new Error(`Failed to get user sessions: ${a.status} ${a.statusText}`);return a.json()},120*1e3)}catch(t){throw t}},fe=async()=>{const e=await fetch(n("sessionsStats"),{method:"GET",headers:O()});if(!e.ok)throw new Error(`Failed to get session stats: ${e.status} ${e.statusText}`);return e.json()},he=async e=>{const t=n("sessionRevoke").replace("{session_id}",encodeURIComponent(e)),a=await fetch(t,{method:"POST",headers:O()});if(!a.ok)throw new Error(`Failed to revoke session: ${a.status} ${a.statusText}`);return a.status===200},ge=async()=>{const e=await fetch(n("sessionsRevokeAll"),{method:"POST",headers:O()});if(!e.ok)throw new Error(`Failed to revoke all other sessions: ${e.status} ${e.statusText}`);return e.status===200};typeof document<"u"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&o.value?(T(),ve()):document.visibilityState==="hidden"&&I()}),typeof window<"u"&&window.addEventListener("storage",e=>{(e.key==="strands_auth_session"||e.key==="strands_auth_user")&&!e.newValue&&s.value&&_()});const ve=()=>{if(!(typeof window>"u")&&s.value&&o.value){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");(!e||!t)&&_()}},me=()=>{I(),$(),g()};try{u.getCurrentInstance()&&u.onUnmounted(me)}catch{}return y.value||N(),{user:u.computed(()=>s.value),currentUser:u.computed(()=>s.value),currentSession:u.computed(()=>o.value),isAuthenticated:Q,isLoading:u.computed(()=>W.value||!y.value),loading:j,loadingMessage:G,isInitializing:L,isSigningIn:U,isSigningUp:R,isSigningOut:q,isRefreshingToken:B,isSendingMfaEmail:V,isVerifyingMfa:K,mfaRequired:u.computed(()=>p.value),mfaSessionId:u.computed(()=>h.value),availableMfaMethods:u.computed(()=>S.value),signIn:X,signUp:Z,signOut:ee,refreshToken:P,fetchProfile:te,updateProfile:ae,updateUserSettings:ne,changeEmail:se,changeUsername:le,getUsernameCooldown:ue,checkUsernameAvailability:ce,getUserSessions:de,getSessionStats:fe,revokeSession:he,revokeAllOtherSessions:ge,initialize:N,setAuthData:C,verifyMfa:ie,sendMfaEmailCode:re,getMfaWebAuthnChallenge:oe,registerHardwareKey:Y,completeHardwareKeyRegistration:H,startTokenRefreshTimer:T,stopTokenRefreshTimer:I,getAuthHeaders:O,forceReInit:()=>{y.value=!1,i.value.initializing=!0,N()}}}exports.useStrandsAuth=Te;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strands.gg/accui",
3
- "version": "2.17.18",
3
+ "version": "2.17.19",
4
4
  "description": "Strands Authentication UI Components",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs.js",
@@ -1 +0,0 @@
1
- "use strict";const u=require("vue"),we=require("./useStrandsConfig-B5kp4aF9.cjs.js");class ye{cache=new Map;DEFAULT_TTL=300*1e3;async fetch(d,v,g=this.DEFAULT_TTL){const b=Date.now(),i=this.cache.get(d);if(i&&b-i.timestamp<i.ttl)return i.promise;this.cleanExpired();const o=v().finally(()=>{setTimeout(()=>{this.cache.delete(d)},g)});return this.cache.set(d,{promise:o,timestamp:b,ttl:g}),o}clear(){this.cache.clear()}invalidate(d){this.cache.delete(d)}cleanExpired(){const d=Date.now();for(const[v,g]of this.cache.entries())d-g.timestamp>g.ttl&&this.cache.delete(v)}getStats(){return{size:this.cache.size,entries:Array.from(this.cache.keys())}}}const m=new ye;function pe(){return{fetch:m.fetch.bind(m),clear:m.clear.bind(m),invalidate:m.invalidate.bind(m),getStats:m.getStats.bind(m)}}function Se(n,d){let v=null;return(...g)=>{v&&clearTimeout(v),v=setTimeout(()=>{n(...g)},d)}}const F=Se((n,d)=>{typeof window<"u"&&localStorage.setItem(n,d)},300),E=n=>({id:n.id,email:n.email,firstName:n.first_name||n.firstName||"",lastName:n.last_name||n.lastName||"",avatar:n.avatar_url||n.avatar,mfaEnabled:n.mfa_enabled??n.mfaEnabled??!1,emailVerified:n.email_verified??n.emailVerified??!1,passwordUpdatedAt:n.password_updated_at||n.passwordUpdatedAt,settings:n.settings||{},xp:n.xp||0,level:n.level||1,next_level_xp:n.next_level_xp||n.next_level_xp||4,username:n.username,usernameLastChangedAt:n.username_last_changed_at||n.usernameLastChangedAt,createdAt:n.created_at||n.createdAt,updatedAt:n.updated_at||n.updatedAt||new Date().toISOString()}),_e={currentUser:u.ref(null),currentSession:u.ref(null),loadingStates:u.ref({initializing:!0,signingIn:!1,signingUp:!1,signingOut:!1,refreshingToken:!1,sendingMfaEmail:!1,verifyingMfa:!1,loadingProfile:!1}),isInitialized:u.ref(!1),mfaRequired:u.ref(!1),mfaSessionId:u.ref(null),availableMfaMethods:u.ref([])};let T=null,w=null,I=null,x=null;function Te(){const{getUrl:n,config:d}=we.useStrandsConfig(),{fetch:v,clear:g,invalidate:b}=pe(),{currentUser:i,currentSession:o,loadingStates:s,isInitialized:k,mfaRequired:y,mfaSessionId:h,availableMfaMethods:p}=_e,S=()=>{if(i.value=null,o.value=null,y.value=!1,h.value=null,p.value=[],typeof window<"u"&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")),O(),$(),w=null,g(),typeof window<"u"&&d.value?.onSignOutUrl){const e=window.location.pathname+window.location.search,t=d.value.onSignOutUrl;e!==t&&(window.location.href=t)}},L=u.computed(()=>s.value.initializing),R=u.computed(()=>s.value.signingIn),U=u.computed(()=>s.value.signingUp),q=u.computed(()=>s.value.signingOut),B=u.computed(()=>s.value.refreshingToken),V=u.computed(()=>s.value.sendingMfaEmail),K=u.computed(()=>s.value.verifyingMfa);u.computed(()=>s.value.loadingProfile);const J=u.computed(()=>s.value.signingIn||s.value.signingUp||s.value.signingOut||s.value.refreshingToken||s.value.sendingMfaEmail||s.value.verifyingMfa||s.value.loadingProfile),G=u.computed(()=>s.value.initializing||J.value),H=u.computed(()=>{const e=s.value;return e.initializing?"Checking authentication...":e.signingIn?"Signing you in...":e.signingUp?"Creating your account...":e.signingOut?"Signing you out...":e.refreshingToken?"Refreshing session...":e.sendingMfaEmail?"Sending verification code...":e.verifyingMfa?"Verifying code...":e.loadingProfile?"Loading profile...":"Loading..."}),A=()=>{const e={};return o.value?.accessToken&&(e.Authorization=`Bearer ${o.value.accessToken}`),o.value?.refreshToken&&(e["x-refresh-token"]=o.value.refreshToken),e},W=async(e,t,a)=>{const r=await fetch(n("mfaHardwareCompleteRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({device_id:e,credential:t})});if(!r.ok){const c=await r.text();let l="Failed to complete hardware key registration";try{const f=JSON.parse(c);l=f.message||f.error||c}catch{l=c||"Failed to complete hardware key registration"}throw new Error(l)}return r.json()},Y=async(e,t,a="hardware")=>{const r=await fetch(n("mfaHardwareStartRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({device_name:e,device_type:a})});if(!r.ok){const c=await r.text();let l="Failed to start hardware key registration";try{const f=JSON.parse(c);l=f.message||f.error||c}catch{l=c||"Failed to start hardware key registration"}throw new Error(l)}return r.json()},Q=u.computed(()=>i.value!==null),X=async e=>{s.value.signingIn=!0;try{y.value=!1,h.value=null,p.value=[];const t={"Content-Type":"application/json"};typeof window<"u"&&window.location&&(t.Origin=window.location.origin);const a=await fetch(n("signIn"),{method:"POST",headers:t,body:JSON.stringify(e)});if(!a.ok)throw a.status===401?new Error("Invalid email or password"):a.status===403?new Error("Please verify your email address before signing in"):new Error(`Sign in failed: ${a.status} ${a.statusText}`);const r=await a.json();if(r.mfa_required){y.value=!0,h.value=r.mfa_session_id||null;const c=(r.available_mfa_methods||[]).map(l=>{let f=`${l.device_type.charAt(0).toUpperCase()+l.device_type.slice(1)} Authentication`;return l.device_type==="hardware"?f=l.device_name||"Security Key":l.device_type==="totp"?f=l.device_name||"Authenticator App":l.device_type==="email"&&(f=l.device_name||"Email Verification"),{id:l.device_id,device_type:l.device_type,device_name:l.device_name||f,is_active:!0,created_at:new Date().toISOString(),last_used_at:l.last_used_at,credential_id:l.credential_id,device_info:l.device_info}});return p.value=c,s.value.signingIn=!1,r}return await C(r),r}catch(t){throw t}finally{s.value.signingIn=!1}},Z=async e=>{s.value.signingUp=!0;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{s.value.signingUp=!1}},ee=async()=>{s.value.signingOut=!0;try{O(),$(),w=null,g(),i.value=null,o.value=null,y.value=!1,h.value=null,p.value=[],typeof window<"u"&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")),typeof window<"u"&&d.value?.onSignOutUrl&&(window.location.href=d.value.onSignOutUrl)}finally{s.value.signingOut=!1}},P=async()=>{if(!o.value?.refreshToken)return!1;if(w)return await w;w=(async()=>{s.value.refreshingToken=!0;try{const t=await fetch(n("refresh"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:o.value.refreshToken})});if(!t.ok){if(t.status===401)return S(),!1;throw new Error(`Token refresh failed: ${t.status} ${t.statusText}`)}const a=await t.json();a.user&&(i.value=E(a.user),i.value&&typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(i.value)));const r={accessToken:a.access_token,refreshToken:a.refresh_token,expiresAt:new Date(Date.now()+300*1e3),userId:a.user?.id||i.value?.id};return o.value=r,typeof window<"u"&&localStorage.setItem("strands_auth_session",JSON.stringify(r)),_(),M(),b(`sessions:${o.value.accessToken.slice(0,20)}`),!0}catch{return S(),!1}finally{s.value.refreshingToken=!1}})();const e=await w;return w=null,e},te=async()=>{const e=`profile:${o.value.accessToken.slice(0,20)}`;s.value.loadingProfile=!0;try{return await v(e,async()=>{const t=await fetch(n("profile"),{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value?.accessToken}`}});if(!t.ok)throw t.status===401?new Error("Authentication expired. Please sign in again."):new Error(`Failed to fetch profile: ${t.status} ${t.statusText}`);const a=await t.json();return i.value=E(a),i.value&&typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(i.value)),i.value})}finally{s.value.loadingProfile=!1}},ae=async e=>{s.value.loadingProfile=!0;try{const t=await fetch(n("profile"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({first_name:e.firstName,last_name:e.lastName})});if(!t.ok)throw t.status===401?new Error("Authentication expired. Please sign in again."):new Error(`Profile update failed: ${t.status} ${t.statusText}`);const a=await t.json();return i.value=E(a),i.value&&F("strands_auth_user",JSON.stringify(i.value)),i.value}finally{s.value.loadingProfile=!1}},ne=async e=>{s.value.loadingProfile=!0;try{const t=await fetch(n("settings"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({settings:e})});if(!t.ok)throw t.status===401?new Error("Authentication expired. Please sign in again."):new Error(`Settings update failed: ${t.status} ${t.statusText}`);const a=await t.json();return i.value=E(a),i.value&&F("strands_auth_user",JSON.stringify(i.value)),i.value}finally{s.value.loadingProfile=!1}},se=async(e,t)=>{s.value.loadingProfile=!0;try{const a=await fetch(n("changeEmail"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({new_email:e,password:t})});if(!a.ok){if(a.status===401)throw new Error("Authentication expired. Please sign in again.");{const c=await a.json().catch(()=>({}));throw new Error(c.message||`Email change failed: ${a.status} ${a.statusText}`)}}const r=await a.json();return i.value&&(i.value={...i.value,email:e,emailVerified:!1,updatedAt:new Date().toISOString()},typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(i.value))),r}finally{s.value.loadingProfile=!1}},ie=async(e,t,a=!1)=>{if(!h.value)throw new Error("No MFA session available");s.value.verifyingMfa=!0;try{const r=n(a?"mfaBackupCodeVerify":"mfaSigninVerify"),c=a?{mfa_session_id:h.value,backup_code:t}:{mfa_session_id:h.value,device_id:e,code:t},l=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!l.ok){const D=await l.text();let j="MFA verification failed";try{const z=JSON.parse(D);j=z.message||z.error||D}catch{j=D||"MFA verification failed"}throw new Error(j)}const f=await l.json();return y.value=!1,h.value=null,p.value=[],await C(f),f}finally{s.value.verifyingMfa=!1}},re=async e=>{if(!h.value)throw new Error("No MFA session available");s.value.sendingMfaEmail=!0;try{const t=await fetch(n("mfaSigninSendEmail"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:h.value,device_id:e})});if(!t.ok){const r=await t.text();let c="Failed to send MFA email code";try{const l=JSON.parse(r);c=l.message||l.error||r}catch{c=r||"Failed to send MFA email code"}throw new Error(c)}return await t.json()}finally{s.value.sendingMfaEmail=!1}},oe=async e=>{if(!h.value)throw new Error("No MFA session available");const t=await fetch(n("mfaWebAuthnChallenge"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:h.value,device_id:e})});if(!t.ok){const a=await t.text();let r="Failed to get WebAuthn challenge";try{const c=JSON.parse(a);r=c.message||c.error||a}catch{r=a||r}throw new Error(r)}return t.json()},C=async e=>{try{e.user&&(i.value=E(e.user));const t={accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:new Date(Date.now()+300*1e3),userId:i.value?.id||e.user?.id};o.value=t,typeof window<"u"&&(localStorage.setItem("strands_auth_session",JSON.stringify(t)),i.value&&localStorage.setItem("strands_auth_user",JSON.stringify(i.value))),_(),M()}catch{}},_=()=>{if(T&&clearTimeout(T),!o.value||typeof document<"u"&&document.visibilityState==="hidden")return;const e=new Date,a=o.value.expiresAt.getTime()-e.getTime()-60*1e3;if(a<=0){P();return}T=setTimeout(async()=>{(typeof document>"u"||document.visibilityState==="visible")&&await P()&&_()},a)},O=()=>{T&&(clearTimeout(T),T=null)},M=()=>{I||typeof window>"u"||(I=setInterval(()=>{i.value&&o.value&&(localStorage.getItem("strands_auth_session")||($(),S()))},2e3))},$=()=>{I&&(clearInterval(I),I=null)},N=async()=>{if(k.value){s.value.initializing=!1;return}return x||(x=(async()=>{s.value.initializing=!0;try{if(typeof window<"u"){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");if(e&&t)try{const a=JSON.parse(e),r=JSON.parse(t);a.expiresAt=new Date(a.expiresAt),a.expiresAt<=new Date&&a.refreshToken?(o.value=a,i.value=r,await Promise.race([P(),new Promise(f=>setTimeout(()=>f(!1),5e3))])||S()):a.expiresAt>new Date?(o.value=a,i.value=r,_(),M()):(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}catch{localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")}}k.value=!0,await new Promise(e=>setTimeout(e,50))}catch(e){console.error("[useStrandsAuth] initialization error:",e)}finally{s.value.initializing=!1,x=null}})(),x)},le=async e=>{s.value.loadingProfile=!0;try{const t=await fetch(n("changeUsername"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.value.accessToken}`},body:JSON.stringify({username:e})});if(!t.ok){const r=await t.json().catch(()=>({}));throw t.status===409?new Error("Username is already taken"):r.cooldown_end?new Error(`You can only change your username once every 30 days. You can change it again on ${new Date(r.cooldown_end).toLocaleDateString()}`):new Error(r.message||`Username change failed: ${t.status} ${t.statusText}`)}const a=await t.json();return i.value&&(i.value={...i.value,username:e,usernameLastChangedAt:new Date().toISOString(),updatedAt:new Date().toISOString()},typeof window<"u"&&localStorage.setItem("strands_auth_user",JSON.stringify(i.value))),a}finally{s.value.loadingProfile=!1}},ue=async()=>{const e=await fetch(n("usernameCooldown"),{method:"GET",headers:{Authorization:`Bearer ${o.value.accessToken}`}});if(!e.ok)throw new Error(`Failed to get username cooldown: ${e.status} ${e.statusText}`);return e.json()},ce=async e=>{const t=n("checkUsernameAvailability").replace("{username}",encodeURIComponent(e)),a=await fetch(t,{method:"GET",headers:{"Content-Type":"application/json"}});if(!a.ok)throw new Error(`Failed to check username availability: ${a.status} ${a.statusText}`);return a.json()},de=async()=>{const e=`sessions:${o.value?.accessToken?.slice(0,20)||"no-token"}`;try{return await v(e,async()=>{const t=A(),a=await fetch(n("sessions"),{method:"GET",headers:t});if(!a.ok)throw await a.text(),new Error(`Failed to get user sessions: ${a.status} ${a.statusText}`);return a.json()},120*1e3)}catch(t){throw t}},fe=async()=>{const e=await fetch(n("sessionsStats"),{method:"GET",headers:A()});if(!e.ok)throw new Error(`Failed to get session stats: ${e.status} ${e.statusText}`);return e.json()},he=async e=>{const t=n("sessionRevoke").replace("{session_id}",encodeURIComponent(e)),a=await fetch(t,{method:"POST",headers:A()});if(!a.ok)throw new Error(`Failed to revoke session: ${a.status} ${a.statusText}`);return a.status===200},ge=async()=>{const e=await fetch(n("sessionsRevokeAll"),{method:"POST",headers:A()});if(!e.ok)throw new Error(`Failed to revoke all other sessions: ${e.status} ${e.statusText}`);return e.status===200};typeof document<"u"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&o.value?(_(),ve()):document.visibilityState==="hidden"&&O()}),typeof window<"u"&&window.addEventListener("storage",e=>{(e.key==="strands_auth_session"||e.key==="strands_auth_user")&&!e.newValue&&i.value&&S()});const ve=()=>{if(!(typeof window>"u")&&i.value&&o.value){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");(!e||!t)&&S()}},me=()=>{O(),$(),g()};try{u.getCurrentInstance()&&u.onUnmounted(me)}catch{}return k.value||N(),{user:u.computed(()=>i.value),currentUser:u.computed(()=>i.value),currentSession:u.computed(()=>o.value),isAuthenticated:Q,isLoading:u.computed(()=>G.value||!k.value),loading:J,loadingMessage:H,isInitializing:L,isSigningIn:R,isSigningUp:U,isSigningOut:q,isRefreshingToken:B,isSendingMfaEmail:V,isVerifyingMfa:K,mfaRequired:u.computed(()=>y.value),mfaSessionId:u.computed(()=>h.value),availableMfaMethods:u.computed(()=>p.value),signIn:X,signUp:Z,signOut:ee,refreshToken:P,fetchProfile:te,updateProfile:ae,updateUserSettings:ne,changeEmail:se,changeUsername:le,getUsernameCooldown:ue,checkUsernameAvailability:ce,getUserSessions:de,getSessionStats:fe,revokeSession:he,revokeAllOtherSessions:ge,initialize:N,setAuthData:C,verifyMfa:ie,sendMfaEmailCode:re,getMfaWebAuthnChallenge:oe,registerHardwareKey:Y,completeHardwareKeyRegistration:W,startTokenRefreshTimer:_,stopTokenRefreshTimer:O,getAuthHeaders:A,forceReInit:()=>{k.value=!1,s.value.initializing=!0,N()}}}exports.useStrandsAuth=Te;