@strands.gg/accui 2.17.18 → 2.17.22
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/accui.css +1 -1
- package/dist/index.cjs.js +5 -5
- package/dist/index.es.js +4394 -4148
- package/dist/nuxt/runtime/composables/useStrandsAuth.cjs.js +1 -1
- package/dist/nuxt/runtime/composables/useStrandsAuth.es.js +1 -1
- package/dist/{useStrandsAuth-DzMk9Hla.es.js → useStrandsAuth-CX9dSRKi.es.js} +106 -106
- package/dist/useStrandsAuth-Dhcd1aWs.cjs.js +1 -0
- package/package.json +1 -1
- package/dist/useStrandsAuth-BCnZXu1A.cjs.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("nuxt/app"),a=require("../../../useStrandsAuth-
|
|
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-
|
|
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(),
|
|
12
|
-
if (
|
|
13
|
-
return
|
|
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),
|
|
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
|
|
111
|
-
function
|
|
112
|
-
const { getUrl: n, config: f } = Se(), { fetch: v, clear: g, invalidate: P } = Te(), { currentUser:
|
|
113
|
-
if (
|
|
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
|
-
},
|
|
118
|
-
c(() =>
|
|
119
|
-
const
|
|
120
|
-
() =>
|
|
121
|
-
),
|
|
122
|
-
const e =
|
|
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
|
-
}),
|
|
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(() =>
|
|
176
|
-
|
|
175
|
+
}, X = c(() => s.value !== null), Z = async (e) => {
|
|
176
|
+
i.value.signingIn = !0;
|
|
177
177
|
try {
|
|
178
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
213
|
+
i.value.signingIn = !1;
|
|
214
214
|
}
|
|
215
215
|
}, ee = async (e) => {
|
|
216
|
-
|
|
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
|
-
|
|
220
|
+
i.value.signingUp = !1;
|
|
221
221
|
}
|
|
222
222
|
}, te = async () => {
|
|
223
|
-
|
|
223
|
+
i.value.signingOut = !0;
|
|
224
224
|
try {
|
|
225
|
-
E(), M(), y = null, g(),
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 && (
|
|
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 ||
|
|
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)),
|
|
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
|
|
262
|
+
return T(), !1;
|
|
263
263
|
} finally {
|
|
264
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
287
|
+
i.value.loadingProfile = !1;
|
|
288
288
|
}
|
|
289
289
|
}, ne = async (e) => {
|
|
290
|
-
|
|
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
|
|
306
|
+
return s.value = x(a), s.value && L("strands_auth_user", JSON.stringify(s.value)), s.value;
|
|
307
307
|
} finally {
|
|
308
|
-
|
|
308
|
+
i.value.loadingProfile = !1;
|
|
309
309
|
}
|
|
310
310
|
}, se = async (e) => {
|
|
311
|
-
|
|
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
|
|
326
|
+
return s.value = x(a), s.value && L("strands_auth_user", JSON.stringify(s.value)), s.value;
|
|
327
327
|
} finally {
|
|
328
|
-
|
|
328
|
+
i.value.loadingProfile = !1;
|
|
329
329
|
}
|
|
330
330
|
}, ie = async (e, t) => {
|
|
331
|
-
|
|
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
|
|
354
|
-
...
|
|
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(
|
|
359
|
+
}, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(s.value))), r;
|
|
360
360
|
} finally {
|
|
361
|
-
|
|
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
|
-
|
|
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
|
|
375
|
-
let
|
|
374
|
+
const z = await l.text();
|
|
375
|
+
let j = "MFA verification failed";
|
|
376
376
|
try {
|
|
377
|
-
const F = JSON.parse(
|
|
378
|
-
|
|
377
|
+
const F = JSON.parse(z);
|
|
378
|
+
j = F.message || F.error || z;
|
|
379
379
|
} catch {
|
|
380
|
-
|
|
380
|
+
j = z || "MFA verification failed";
|
|
381
381
|
}
|
|
382
|
-
throw new Error(
|
|
382
|
+
throw new Error(j);
|
|
383
383
|
}
|
|
384
384
|
const d = await l.json();
|
|
385
|
-
return
|
|
385
|
+
return S.value = !1, h.value = null, _.value = [], await N(d), d;
|
|
386
386
|
} finally {
|
|
387
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 && (
|
|
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:
|
|
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)),
|
|
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
|
-
},
|
|
454
|
-
if (
|
|
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
|
-
|
|
462
|
-
(typeof document > "u" || document.visibilityState === "visible") && await $() &&
|
|
461
|
+
A = setTimeout(async () => {
|
|
462
|
+
(typeof document > "u" || document.visibilityState === "visible") && await $() && k();
|
|
463
463
|
}, a);
|
|
464
464
|
}, E = () => {
|
|
465
|
-
|
|
465
|
+
A && (clearTimeout(A), A = null);
|
|
466
466
|
}, C = () => {
|
|
467
|
-
|
|
468
|
-
|
|
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
|
-
|
|
471
|
+
b && (clearInterval(b), b = null);
|
|
472
472
|
}, D = async () => {
|
|
473
|
-
if (
|
|
474
|
-
|
|
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
|
|
478
|
-
|
|
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,
|
|
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
|
-
]) ||
|
|
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
|
-
|
|
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
|
-
|
|
497
|
+
console.log("[useStrandsAuth] finally - setting initializing=false"), i.value.initializing = !1, O = null;
|
|
498
498
|
}
|
|
499
|
-
})(),
|
|
499
|
+
})(), O);
|
|
500
500
|
}, ue = async (e) => {
|
|
501
|
-
|
|
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
|
|
519
|
-
...
|
|
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(
|
|
523
|
+
}, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(s.value))), a;
|
|
524
524
|
} finally {
|
|
525
|
-
|
|
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 =
|
|
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:
|
|
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:
|
|
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:
|
|
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 ? (
|
|
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 &&
|
|
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") &&
|
|
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
|
|
604
|
+
return p.value || D(), {
|
|
605
605
|
// State
|
|
606
|
-
user: c(() =>
|
|
607
|
-
currentUser: c(() =>
|
|
606
|
+
user: c(() => s.value),
|
|
607
|
+
currentUser: c(() => s.value),
|
|
608
608
|
currentSession: c(() => o.value),
|
|
609
609
|
isAuthenticated: X,
|
|
610
|
-
isLoading: c(() =>
|
|
611
|
-
loading:
|
|
612
|
-
loadingMessage:
|
|
610
|
+
isLoading: c(() => G.value || !p.value),
|
|
611
|
+
loading: J,
|
|
612
|
+
loadingMessage: H,
|
|
613
613
|
// Specific loading states
|
|
614
|
-
isInitializing:
|
|
615
|
-
isSigningIn:
|
|
614
|
+
isInitializing: U,
|
|
615
|
+
isSigningIn: R,
|
|
616
616
|
isSigningUp: B,
|
|
617
617
|
isSigningOut: V,
|
|
618
618
|
isRefreshingToken: q,
|
|
619
619
|
isSendingMfaEmail: K,
|
|
620
|
-
isVerifyingMfa:
|
|
620
|
+
isVerifyingMfa: W,
|
|
621
621
|
// MFA State
|
|
622
|
-
mfaRequired: c(() =>
|
|
622
|
+
mfaRequired: c(() => S.value),
|
|
623
623
|
mfaSessionId: c(() => h.value),
|
|
624
|
-
availableMfaMethods: c(() =>
|
|
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:
|
|
650
|
+
startTokenRefreshTimer: k,
|
|
651
651
|
stopTokenRefreshTimer: E,
|
|
652
|
-
getAuthHeaders:
|
|
652
|
+
getAuthHeaders: I,
|
|
653
653
|
// Force re-initialization (useful for testing or navigation)
|
|
654
654
|
forceReInit: () => {
|
|
655
|
-
|
|
655
|
+
p.value = !1, i.value.initializing = !0, D();
|
|
656
656
|
}
|
|
657
657
|
};
|
|
658
658
|
}
|
|
659
659
|
export {
|
|
660
|
-
|
|
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 +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;
|