@strands.gg/accui 2.17.9 → 2.17.11
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 +3720 -3714
- package/dist/nuxt/runtime/composables/useStrandsAuth.cjs.js +1 -1
- package/dist/nuxt/runtime/composables/useStrandsAuth.es.js +1 -1
- package/dist/nuxt/runtime/middleware/auth.global.cjs.js +1 -1
- package/dist/nuxt/runtime/middleware/auth.global.es.js +5 -5
- package/dist/nuxt/runtime/plugin.client.cjs.js +1 -1
- package/dist/nuxt/runtime/plugin.client.es.js +1 -1
- package/dist/nuxt/runtime/plugin.server.cjs.js +1 -1
- package/dist/nuxt/runtime/plugin.server.es.js +1 -1
- package/dist/nuxt/types.d.ts +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/{useStrandsAuth-Bv61_QkS.es.js → useStrandsAuth-C2WOjQ2Z.es.js} +75 -73
- package/dist/useStrandsAuth-DSDtq0F7.cjs.js +1 -0
- package/dist/useStrandsConfig-B5kp4aF9.cjs.js +1 -0
- package/dist/{useStrandsConfig-Cd22bj_E.es.js → useStrandsConfig-CMKVW1p3.es.js} +1 -0
- package/dist/vite.cjs.js +1 -1
- package/dist/vite.es.js +1 -1
- package/package.json +1 -1
- package/dist/useStrandsAuth-BVqpuhrO.cjs.js +0 -1
- package/dist/useStrandsConfig-D7a0QXz3.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-DSDtq0F7.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-C2WOjQ2Z.es.js";
|
|
3
3
|
const u = () => {
|
|
4
4
|
const n = e().public.strandsAuth, t = r();
|
|
5
5
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const r=require("nuxt/app"),g=r.defineNuxtRouteMiddleware(a=>{const n=r.useRuntimeConfig().public.strandsAuth;return new Promise(c=>{Promise.resolve().then(()=>require("../composables/useStrandsAuth.cjs.js")).then(({useStrandsAuth:d})=>{const{isAuthenticated:i,isLoading:h}=d(),s=()=>{if(h.value){setTimeout(s,50);return}const e=a.path,l=n.protectedRoutes?.some(t=>t.endsWith("*")?e.startsWith(t.slice(0,-1)):e===t||e.startsWith(t+"/")),f=n.guestOnlyRoutes?.some(t=>t.endsWith("*")?e.startsWith(t.slice(0,-1)):e===t||e.startsWith(t+"/"));if(l&&!i.value){const t=n.
|
|
1
|
+
"use strict";const r=require("nuxt/app"),g=r.defineNuxtRouteMiddleware(a=>{const n=r.useRuntimeConfig().public.strandsAuth;return new Promise(c=>{Promise.resolve().then(()=>require("../composables/useStrandsAuth.cjs.js")).then(({useStrandsAuth:d})=>{const{isAuthenticated:i,isLoading:h}=d(),s=()=>{if(h.value){setTimeout(s,50);return}const e=a.path,l=n.protectedRoutes?.some(t=>t.endsWith("*")?e.startsWith(t.slice(0,-1)):e===t||e.startsWith(t+"/")),f=n.guestOnlyRoutes?.some(t=>t.endsWith("*")?e.startsWith(t.slice(0,-1)):e===t||e.startsWith(t+"/"));if(l&&!i.value){const t=n.authUrl||"/auth",o=t.includes("?")?`${t}&redirect=${encodeURIComponent(e)}`:`${t}?redirect=${encodeURIComponent(e)}`;try{return r.navigateTo(o)}catch(u){if(console.warn("[Strands Auth] navigateTo failed, using window.location:",u),typeof window<"u"){window.location.href=o;return}throw u}}if(f&&i.value)return r.navigateTo(n.onSignInUrl||"/dashboard");c()};s()})})});module.exports=g;
|
|
@@ -4,14 +4,14 @@ const w = m((u) => {
|
|
|
4
4
|
if (!import.meta.server)
|
|
5
5
|
return new Promise((c) => {
|
|
6
6
|
import("../composables/useStrandsAuth.es.js").then(({ useStrandsAuth: d }) => {
|
|
7
|
-
const { isAuthenticated: r, isLoading:
|
|
8
|
-
if (
|
|
7
|
+
const { isAuthenticated: r, isLoading: l } = d(), i = () => {
|
|
8
|
+
if (l.value) {
|
|
9
9
|
setTimeout(i, 50);
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
-
const e = u.path,
|
|
13
|
-
if (
|
|
14
|
-
const t = n.
|
|
12
|
+
const e = u.path, h = n.protectedRoutes?.some((t) => t.endsWith("*") ? e.startsWith(t.slice(0, -1)) : e === t || e.startsWith(t + "/")), f = n.guestOnlyRoutes?.some((t) => t.endsWith("*") ? e.startsWith(t.slice(0, -1)) : e === t || e.startsWith(t + "/"));
|
|
13
|
+
if (h && !r.value) {
|
|
14
|
+
const t = n.authUrl || "/auth", o = t.includes("?") ? `${t}&redirect=${encodeURIComponent(e)}` : `${t}?redirect=${encodeURIComponent(e)}`;
|
|
15
15
|
try {
|
|
16
16
|
return a(o);
|
|
17
17
|
} catch (s) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("nuxt/app"),t=require("../../useStrandsConfig-
|
|
1
|
+
"use strict";const e=require("nuxt/app"),t=require("../../useStrandsConfig-B5kp4aF9.cjs.js"),c=e.defineNuxtPlugin({name:"strands-auth-client",async setup(){const i=e.useRuntimeConfig().public.strandsAuth,n={...t.STRANDS_AUTH_DEFAULTS,...i};t.setStrandsConfig(n),typeof window<"u"&&(window.__STRANDS_CONFIG__=n),n?.accentColor&&typeof window<"u"&&document.documentElement.style.setProperty("--strands-accent",n.accentColor);const{useStrandsAuth:s}=await Promise.resolve().then(()=>require("./composables/useStrandsAuth.cjs.js")),{initialize:o}=s();await o()}});module.exports=c;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineNuxtPlugin as i, useRuntimeConfig as s } from "nuxt/app";
|
|
2
|
-
import { s as a, S as c } from "../../useStrandsConfig-
|
|
2
|
+
import { s as a, S as c } from "../../useStrandsConfig-CMKVW1p3.es.js";
|
|
3
3
|
const u = i({
|
|
4
4
|
name: "strands-auth-client",
|
|
5
5
|
async setup() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const n=require("nuxt/app"),s=require("../../useStrandsConfig-
|
|
1
|
+
"use strict";const n=require("nuxt/app"),s=require("../../useStrandsConfig-B5kp4aF9.cjs.js"),r=n.defineNuxtPlugin({name:"strands-auth-server",setup(){const e=n.useRuntimeConfig().public.strandsAuth,t={...s.STRANDS_AUTH_DEFAULTS,...e};s.setStrandsConfig(t)}});module.exports=r;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineNuxtPlugin as t, useRuntimeConfig as e } from "nuxt/app";
|
|
2
|
-
import { s as o, S as r } from "../../useStrandsConfig-
|
|
2
|
+
import { s as o, S as r } from "../../useStrandsConfig-CMKVW1p3.es.js";
|
|
3
3
|
const u = t({
|
|
4
4
|
name: "strands-auth-server",
|
|
5
5
|
setup() {
|
package/dist/nuxt/types.d.ts
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -114,6 +114,11 @@ export interface StrandsAuthConfig {
|
|
|
114
114
|
* @default '/'
|
|
115
115
|
*/
|
|
116
116
|
onSignOutUrl?: string;
|
|
117
|
+
/**
|
|
118
|
+
* URL of the authentication/login page (where unauthenticated users are redirected)
|
|
119
|
+
* @default '/auth'
|
|
120
|
+
*/
|
|
121
|
+
authUrl?: string;
|
|
117
122
|
/**
|
|
118
123
|
* Enable automatic token refresh
|
|
119
124
|
* @default true
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed as c, ref as m, getCurrentInstance as me, onUnmounted as ye } from "vue";
|
|
2
|
-
import { u as pe } from "./useStrandsConfig-
|
|
2
|
+
import { u as pe } from "./useStrandsConfig-CMKVW1p3.es.js";
|
|
3
3
|
class Se {
|
|
4
4
|
cache = /* @__PURE__ */ new Map();
|
|
5
5
|
DEFAULT_TTL = 300 * 1e3;
|
|
@@ -8,9 +8,9 @@ class Se {
|
|
|
8
8
|
* Memoized fetch - prevents duplicate requests and caches results
|
|
9
9
|
*/
|
|
10
10
|
async fetch(f, v, g = this.DEFAULT_TTL) {
|
|
11
|
-
const b = Date.now(),
|
|
12
|
-
if (
|
|
13
|
-
return
|
|
11
|
+
const b = Date.now(), i = this.cache.get(f);
|
|
12
|
+
if (i && b - i.timestamp < i.ttl)
|
|
13
|
+
return i.promise;
|
|
14
14
|
this.cleanExpired();
|
|
15
15
|
const o = v().finally(() => {
|
|
16
16
|
setTimeout(() => {
|
|
@@ -109,17 +109,17 @@ const z = Te((n, f) => {
|
|
|
109
109
|
};
|
|
110
110
|
let k = null, y = null, x = null;
|
|
111
111
|
function Ee() {
|
|
112
|
-
const { getUrl: n, config: f } = pe(), { fetch: v, clear: g, invalidate: b } = _e(), { currentUser:
|
|
113
|
-
if (
|
|
112
|
+
const { getUrl: n, config: f } = pe(), { fetch: v, clear: g, invalidate: b } = _e(), { currentUser: i, currentSession: o, loadingStates: s, isInitialized: A, mfaRequired: p, mfaSessionId: d, availableMfaMethods: S } = ke, _ = () => {
|
|
113
|
+
if (i.value = null, o.value = null, p.value = !1, d.value = null, S.value = [], typeof window < "u" && (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user")), E(), P(), 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
|
-
}, L = c(() =>
|
|
118
|
-
c(() =>
|
|
117
|
+
}, L = c(() => s.value.initializing), R = c(() => s.value.signingIn), U = c(() => s.value.signingUp), B = c(() => s.value.signingOut), V = c(() => s.value.refreshingToken), q = c(() => s.value.sendingMfaEmail), K = c(() => s.value.verifyingMfa);
|
|
118
|
+
c(() => s.value.loadingProfile);
|
|
119
119
|
const J = c(
|
|
120
|
-
() =>
|
|
121
|
-
), G = c(() =>
|
|
122
|
-
const e =
|
|
120
|
+
() => s.value.signingIn || s.value.signingUp || s.value.signingOut || s.value.refreshingToken || s.value.sendingMfaEmail || s.value.verifyingMfa || s.value.loadingProfile
|
|
121
|
+
), G = c(() => s.value.initializing || J.value), H = c(() => {
|
|
122
|
+
const e = s.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
|
}), O = () => {
|
|
125
125
|
const e = {};
|
|
@@ -172,8 +172,8 @@ function Ee() {
|
|
|
172
172
|
throw new Error(l);
|
|
173
173
|
}
|
|
174
174
|
return r.json();
|
|
175
|
-
}, Q = c(() =>
|
|
176
|
-
|
|
175
|
+
}, Q = c(() => i.value !== null), X = async (e) => {
|
|
176
|
+
s.value.signingIn = !0;
|
|
177
177
|
try {
|
|
178
178
|
p.value = !1, d.value = null, S.value = [];
|
|
179
179
|
const t = {
|
|
@@ -204,27 +204,27 @@ function Ee() {
|
|
|
204
204
|
device_info: l.device_info
|
|
205
205
|
};
|
|
206
206
|
});
|
|
207
|
-
return S.value = u,
|
|
207
|
+
return S.value = u, s.value.signingIn = !1, r;
|
|
208
208
|
}
|
|
209
209
|
return await M(r), r;
|
|
210
210
|
} catch (t) {
|
|
211
211
|
throw t;
|
|
212
212
|
} finally {
|
|
213
|
-
|
|
213
|
+
s.value.signingIn = !1;
|
|
214
214
|
}
|
|
215
215
|
}, Z = async (e) => {
|
|
216
|
-
|
|
216
|
+
s.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
|
+
s.value.signingUp = !1;
|
|
221
221
|
}
|
|
222
222
|
}, ee = async () => {
|
|
223
|
-
|
|
223
|
+
s.value.signingOut = !0;
|
|
224
224
|
try {
|
|
225
|
-
E(), P(), y = null, g(),
|
|
225
|
+
E(), P(), y = null, g(), i.value = null, o.value = null, p.value = !1, d.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);
|
|
226
226
|
} finally {
|
|
227
|
-
|
|
227
|
+
s.value.signingOut = !1;
|
|
228
228
|
}
|
|
229
229
|
}, $ = async () => {
|
|
230
230
|
if (!o.value?.refreshToken)
|
|
@@ -232,7 +232,7 @@ function Ee() {
|
|
|
232
232
|
if (y)
|
|
233
233
|
return await y;
|
|
234
234
|
y = (async () => {
|
|
235
|
-
|
|
235
|
+
s.value.refreshingToken = !0;
|
|
236
236
|
try {
|
|
237
237
|
const t = await fetch(n("refresh"), {
|
|
238
238
|
method: "POST",
|
|
@@ -249,26 +249,26 @@ function Ee() {
|
|
|
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 && (i.value = I(a.user), i.value && typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(i.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 || i.value?.id
|
|
259
259
|
};
|
|
260
260
|
return o.value = r, typeof window < "u" && localStorage.setItem("strands_auth_session", JSON.stringify(r)), T(), N(), b(`sessions:${o.value.accessToken.slice(0, 20)}`), !0;
|
|
261
261
|
} catch {
|
|
262
262
|
return _(), !1;
|
|
263
263
|
} finally {
|
|
264
|
-
|
|
264
|
+
s.value.refreshingToken = !1;
|
|
265
265
|
}
|
|
266
266
|
})();
|
|
267
267
|
const e = await y;
|
|
268
268
|
return y = null, e;
|
|
269
269
|
}, te = async () => {
|
|
270
270
|
const e = `profile:${o.value.accessToken.slice(0, 20)}`;
|
|
271
|
-
|
|
271
|
+
s.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 Ee() {
|
|
|
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 i.value = I(a), i.value && typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(i.value)), i.value;
|
|
285
285
|
});
|
|
286
286
|
} finally {
|
|
287
|
-
|
|
287
|
+
s.value.loadingProfile = !1;
|
|
288
288
|
}
|
|
289
289
|
}, ae = async (e) => {
|
|
290
|
-
|
|
290
|
+
s.value.loadingProfile = !0;
|
|
291
291
|
try {
|
|
292
292
|
const t = await fetch(n("profile"), {
|
|
293
293
|
method: "POST",
|
|
@@ -303,12 +303,12 @@ function Ee() {
|
|
|
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 i.value = I(a), i.value && z("strands_auth_user", JSON.stringify(i.value)), i.value;
|
|
307
307
|
} finally {
|
|
308
|
-
|
|
308
|
+
s.value.loadingProfile = !1;
|
|
309
309
|
}
|
|
310
310
|
}, ne = async (e) => {
|
|
311
|
-
|
|
311
|
+
s.value.loadingProfile = !0;
|
|
312
312
|
try {
|
|
313
313
|
const t = await fetch(n("settings"), {
|
|
314
314
|
method: "POST",
|
|
@@ -323,12 +323,12 @@ function Ee() {
|
|
|
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 i.value = I(a), i.value && z("strands_auth_user", JSON.stringify(i.value)), i.value;
|
|
327
327
|
} finally {
|
|
328
|
-
|
|
328
|
+
s.value.loadingProfile = !1;
|
|
329
329
|
}
|
|
330
330
|
}, se = async (e, t) => {
|
|
331
|
-
|
|
331
|
+
s.value.loadingProfile = !0;
|
|
332
332
|
try {
|
|
333
333
|
const a = await fetch(n("changeEmail"), {
|
|
334
334
|
method: "POST",
|
|
@@ -350,20 +350,20 @@ function Ee() {
|
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
352
|
const r = await a.json();
|
|
353
|
-
return
|
|
354
|
-
...
|
|
353
|
+
return i.value && (i.value = {
|
|
354
|
+
...i.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(i.value))), r;
|
|
360
360
|
} finally {
|
|
361
|
-
|
|
361
|
+
s.value.loadingProfile = !1;
|
|
362
362
|
}
|
|
363
363
|
}, ie = async (e, t, a = !1) => {
|
|
364
364
|
if (!d.value)
|
|
365
365
|
throw new Error("No MFA session available");
|
|
366
|
-
|
|
366
|
+
s.value.verifyingMfa = !0;
|
|
367
367
|
try {
|
|
368
368
|
const r = n(a ? "mfaBackupCodeVerify" : "mfaSigninVerify"), u = a ? { mfa_session_id: d.value, backup_code: t } : { mfa_session_id: d.value, device_id: e, code: t }, l = await fetch(r, {
|
|
369
369
|
method: "POST",
|
|
@@ -384,12 +384,12 @@ function Ee() {
|
|
|
384
384
|
const h = await l.json();
|
|
385
385
|
return p.value = !1, d.value = null, S.value = [], await M(h), h;
|
|
386
386
|
} finally {
|
|
387
|
-
|
|
387
|
+
s.value.verifyingMfa = !1;
|
|
388
388
|
}
|
|
389
389
|
}, re = async (e) => {
|
|
390
390
|
if (!d.value)
|
|
391
391
|
throw new Error("No MFA session available");
|
|
392
|
-
|
|
392
|
+
s.value.sendingMfaEmail = !0;
|
|
393
393
|
try {
|
|
394
394
|
const t = await fetch(n("mfaSigninSendEmail"), {
|
|
395
395
|
method: "POST",
|
|
@@ -412,7 +412,7 @@ function Ee() {
|
|
|
412
412
|
}
|
|
413
413
|
return await t.json();
|
|
414
414
|
} finally {
|
|
415
|
-
|
|
415
|
+
s.value.sendingMfaEmail = !1;
|
|
416
416
|
}
|
|
417
417
|
}, oe = async (e) => {
|
|
418
418
|
if (!d.value)
|
|
@@ -439,15 +439,15 @@ function Ee() {
|
|
|
439
439
|
return t.json();
|
|
440
440
|
}, M = async (e) => {
|
|
441
441
|
try {
|
|
442
|
-
e.user && (
|
|
442
|
+
e.user && (i.value = I(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: i.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)), i.value && localStorage.setItem("strands_auth_user", JSON.stringify(i.value))), T(), N();
|
|
451
451
|
} catch {
|
|
452
452
|
}
|
|
453
453
|
}, T = () => {
|
|
@@ -465,32 +465,34 @@ function Ee() {
|
|
|
465
465
|
k && (clearTimeout(k), k = null);
|
|
466
466
|
}, N = () => {
|
|
467
467
|
x || typeof window > "u" || (x = setInterval(() => {
|
|
468
|
-
|
|
468
|
+
i.value && o.value && (localStorage.getItem("strands_auth_session") || (P(), _()));
|
|
469
469
|
}, 2e3));
|
|
470
470
|
}, P = () => {
|
|
471
471
|
x && (clearInterval(x), x = null);
|
|
472
472
|
}, C = async () => {
|
|
473
|
-
if (
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
} finally {
|
|
489
|
-
i.value.initializing = !1;
|
|
473
|
+
if (A.value) {
|
|
474
|
+
s.value.initializing = !1;
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
s.value.initializing = !0;
|
|
478
|
+
try {
|
|
479
|
+
if (typeof window < "u") {
|
|
480
|
+
const e = localStorage.getItem("strands_auth_session"), t = localStorage.getItem("strands_auth_user");
|
|
481
|
+
if (e && t)
|
|
482
|
+
try {
|
|
483
|
+
const a = JSON.parse(e), r = JSON.parse(t);
|
|
484
|
+
a.expiresAt = new Date(a.expiresAt), a.expiresAt <= /* @__PURE__ */ new Date() && a.refreshToken ? (o.value = a, i.value = r, await $() || _()) : a.expiresAt > /* @__PURE__ */ new Date() ? (o.value = a, i.value = r, T(), N()) : (localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user"));
|
|
485
|
+
} catch {
|
|
486
|
+
localStorage.removeItem("strands_auth_session"), localStorage.removeItem("strands_auth_user");
|
|
487
|
+
}
|
|
490
488
|
}
|
|
489
|
+
A.value = !0, await new Promise((e) => setTimeout(e, 50));
|
|
490
|
+
} catch {
|
|
491
|
+
} finally {
|
|
492
|
+
s.value.initializing = !1;
|
|
491
493
|
}
|
|
492
494
|
}, le = async (e) => {
|
|
493
|
-
|
|
495
|
+
s.value.loadingProfile = !0;
|
|
494
496
|
try {
|
|
495
497
|
const t = await fetch(n("changeUsername"), {
|
|
496
498
|
method: "POST",
|
|
@@ -507,14 +509,14 @@ function Ee() {
|
|
|
507
509
|
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}`);
|
|
508
510
|
}
|
|
509
511
|
const a = await t.json();
|
|
510
|
-
return
|
|
511
|
-
...
|
|
512
|
+
return i.value && (i.value = {
|
|
513
|
+
...i.value,
|
|
512
514
|
username: e,
|
|
513
515
|
usernameLastChangedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
514
516
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
515
|
-
}, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(
|
|
517
|
+
}, typeof window < "u" && localStorage.setItem("strands_auth_user", JSON.stringify(i.value))), a;
|
|
516
518
|
} finally {
|
|
517
|
-
|
|
519
|
+
s.value.loadingProfile = !1;
|
|
518
520
|
}
|
|
519
521
|
}, ue = async () => {
|
|
520
522
|
const e = await fetch(n("usernameCooldown"), {
|
|
@@ -579,10 +581,10 @@ function Ee() {
|
|
|
579
581
|
typeof document < "u" && document.addEventListener("visibilitychange", () => {
|
|
580
582
|
document.visibilityState === "visible" && o.value ? (T(), ve()) : document.visibilityState === "hidden" && E();
|
|
581
583
|
}), typeof window < "u" && window.addEventListener("storage", (e) => {
|
|
582
|
-
(e.key === "strands_auth_session" || e.key === "strands_auth_user") && !e.newValue &&
|
|
584
|
+
(e.key === "strands_auth_session" || e.key === "strands_auth_user") && !e.newValue && i.value && _();
|
|
583
585
|
});
|
|
584
586
|
const ve = () => {
|
|
585
|
-
if (!(typeof window > "u") &&
|
|
587
|
+
if (!(typeof window > "u") && i.value && o.value) {
|
|
586
588
|
const e = localStorage.getItem("strands_auth_session"), t = localStorage.getItem("strands_auth_user");
|
|
587
589
|
(!e || !t) && _();
|
|
588
590
|
}
|
|
@@ -595,8 +597,8 @@ function Ee() {
|
|
|
595
597
|
}
|
|
596
598
|
return A.value || C(), {
|
|
597
599
|
// State
|
|
598
|
-
user: c(() =>
|
|
599
|
-
currentUser: c(() =>
|
|
600
|
+
user: c(() => i.value),
|
|
601
|
+
currentUser: c(() => i.value),
|
|
600
602
|
currentSession: c(() => o.value),
|
|
601
603
|
isAuthenticated: Q,
|
|
602
604
|
isLoading: c(() => G.value || !A.value),
|
|
@@ -644,7 +646,7 @@ function Ee() {
|
|
|
644
646
|
getAuthHeaders: O,
|
|
645
647
|
// Force re-initialization (useful for testing or navigation)
|
|
646
648
|
forceReInit: () => {
|
|
647
|
-
A.value = !1,
|
|
649
|
+
A.value = !1, s.value.initializing = !0, C();
|
|
648
650
|
}
|
|
649
651
|
};
|
|
650
652
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const u=require("vue"),we=require("./useStrandsConfig-B5kp4aF9.cjs.js");class me{cache=new Map;DEFAULT_TTL=300*1e3;async fetch(d,v,g=this.DEFAULT_TTL){const x=Date.now(),i=this.cache.get(d);if(i&&x-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:x,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 w=new me;function ye(){return{fetch:w.fetch.bind(w),clear:w.clear.bind(w),invalidate:w.invalidate.bind(w),getStats:w.getStats.bind(w)}}function pe(n,d){let v=null;return(...g)=>{v&&clearTimeout(v),v=setTimeout(()=>{n(...g)},d)}}const F=pe((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()}),Se={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,m=null,I=null;function _e(){const{getUrl:n,config:d}=we.useStrandsConfig(),{fetch:v,clear:g,invalidate:x}=ye(),{currentUser:i,currentSession:o,loadingStates:s,isInitialized:k,mfaRequired:y,mfaSessionId:f,availableMfaMethods:p}=Se,S=()=>{if(i.value=null,o.value=null,y.value=!1,f.value=null,p.value=[],typeof window<"u"&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")),O(),$(),m=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)}},z=u.computed(()=>s.value.initializing),L=u.computed(()=>s.value.signingIn),R=u.computed(()=>s.value.signingUp),U=u.computed(()=>s.value.signingOut),q=u.computed(()=>s.value.refreshingToken),B=u.computed(()=>s.value.sendingMfaEmail),V=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),K=u.computed(()=>s.value.initializing||j.value),G=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},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 h=JSON.parse(c);l=h.message||h.error||c}catch{l=c||"Failed to complete hardware key registration"}throw new Error(l)}return r.json()},W=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 h=JSON.parse(c);l=h.message||h.error||c}catch{l=c||"Failed to start hardware key registration"}throw new Error(l)}return r.json()},Y=u.computed(()=>i.value!==null),Q=async e=>{s.value.signingIn=!0;try{y.value=!1,f.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,f.value=r.mfa_session_id||null;const c=(r.available_mfa_methods||[]).map(l=>{let h=`${l.device_type.charAt(0).toUpperCase()+l.device_type.slice(1)} Authentication`;return l.device_type==="hardware"?h=l.device_name||"Security Key":l.device_type==="totp"?h=l.device_name||"Authenticator App":l.device_type==="email"&&(h=l.device_name||"Email Verification"),{id:l.device_id,device_type:l.device_type,device_name:l.device_name||h,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 P(r),r}catch(t){throw t}finally{s.value.signingIn=!1}},X=async e=>{s.value.signingUp=!0;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{s.value.signingUp=!1}},Z=async()=>{s.value.signingOut=!0;try{O(),$(),m=null,g(),i.value=null,o.value=null,y.value=!1,f.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}},b=async()=>{if(!o.value?.refreshToken)return!1;if(m)return await m;m=(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)),_(),C(),x(`sessions:${o.value.accessToken.slice(0,20)}`),!0}catch{return S(),!1}finally{s.value.refreshingToken=!1}})();const e=await m;return m=null,e},ee=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}},te=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}},ae=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}},ne=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}},se=async(e,t,a=!1)=>{if(!f.value)throw new Error("No MFA session available");s.value.verifyingMfa=!0;try{const r=n(a?"mfaBackupCodeVerify":"mfaSigninVerify"),c=a?{mfa_session_id:f.value,backup_code:t}:{mfa_session_id:f.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 N=await l.text();let D="MFA verification failed";try{const J=JSON.parse(N);D=J.message||J.error||N}catch{D=N||"MFA verification failed"}throw new Error(D)}const h=await l.json();return y.value=!1,f.value=null,p.value=[],await P(h),h}finally{s.value.verifyingMfa=!1}},ie=async e=>{if(!f.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:f.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}},re=async e=>{if(!f.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:f.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()},P=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))),_(),C()}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){b();return}T=setTimeout(async()=>{(typeof document>"u"||document.visibilityState==="visible")&&await b()&&_()},a)},O=()=>{T&&(clearTimeout(T),T=null)},C=()=>{I||typeof window>"u"||(I=setInterval(()=>{i.value&&o.value&&(localStorage.getItem("strands_auth_session")||($(),S()))},2e3))},$=()=>{I&&(clearInterval(I),I=null)},M=async()=>{if(k.value){s.value.initializing=!1;return}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 b()||S()):a.expiresAt>new Date?(o.value=a,i.value=r,_(),C()):(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{}finally{s.value.initializing=!1}},oe=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}},le=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()},ue=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()},ce=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}},de=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()},fe=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},he=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?(_(),ge()):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 ge=()=>{if(!(typeof window>"u")&&i.value&&o.value){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");(!e||!t)&&S()}},ve=()=>{O(),$(),g()};try{u.getCurrentInstance()&&u.onUnmounted(ve)}catch{}return k.value||M(),{user:u.computed(()=>i.value),currentUser:u.computed(()=>i.value),currentSession:u.computed(()=>o.value),isAuthenticated:Y,isLoading:u.computed(()=>K.value||!k.value),loading:j,loadingMessage:G,isInitializing:z,isSigningIn:L,isSigningUp:R,isSigningOut:U,isRefreshingToken:q,isSendingMfaEmail:B,isVerifyingMfa:V,mfaRequired:u.computed(()=>y.value),mfaSessionId:u.computed(()=>f.value),availableMfaMethods:u.computed(()=>p.value),signIn:Q,signUp:X,signOut:Z,refreshToken:b,fetchProfile:ee,updateProfile:te,updateUserSettings:ae,changeEmail:ne,changeUsername:oe,getUsernameCooldown:le,checkUsernameAvailability:ue,getUserSessions:ce,getSessionStats:de,revokeSession:fe,revokeAllOtherSessions:he,initialize:M,setAuthData:P,verifyMfa:se,sendMfaEmailCode:ie,getMfaWebAuthnChallenge:re,registerHardwareKey:W,completeHardwareKeyRegistration:H,startTokenRefreshTimer:_,stopTokenRefreshTimer:O,getAuthHeaders:A,forceReInit:()=>{k.value=!1,s.value.initializing=!0,M()}}}exports.useStrandsAuth=_e;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const u=require("vue"),c={baseUrl:"https://your-api.example.com",accentColor:"#EA00A8",redirectUrl:"/",onSignInUrl:"/dashboard",onSignOutUrl:"/",authUrl:"/auth",autoRefresh:!0,refreshInterval:4,protectedRoutes:[],guestOnlyRoutes:["/auth","/login","/register"],devMode:!1,styles:!0,endpoints:{},useSquircle:!0},a={signIn:"/api/v1/auth/sign-in",signUp:"/api/v1/auth/sign-up",signOut:"/api/v1/auth/sign-out",refresh:"/api/v1/auth/refresh",passwordReset:"/api/v1/auth/password-reset",passwordResetConfirm:"/api/v1/auth/password-reset/confirm",completeRegistration:"/api/v1/auth/complete-registration",profile:"/api/v1/user/profile",verifyEmail:"/api/v1/auth/verify-email",oauthProviders:"/api/v1/oauth/providers",oauthProvider:"/api/v1/oauth/providers/{provider_id}",changeEmail:"/api/v1/user/change-email",avatar:"/api/v1/user/avatar",settings:"/api/v1/user/settings",changeUsername:"/api/v1/user/username",usernameCooldown:"/api/v1/user/username/cooldown",checkUsernameAvailability:"/api/v1/username/{username}/available",mfaDevices:"/api/v1/mfa/devices",mfaTotpSetup:"/api/v1/mfa/totp/setup",mfaTotpVerify:"/api/v1/mfa/totp/verify",mfaEmailSetup:"/api/v1/mfa/email/setup",mfaEmailSend:"/api/v1/mfa/email/send",mfaEmailVerify:"/api/v1/mfa/email/verify",mfaDeviceDisable:"/api/v1/mfa/device/disable",mfaBackupCodes:"/api/v1/mfa/backup-codes/regenerate",mfaHardwareStartRegistration:"/api/v1/mfa/hardware/start-registration",mfaHardwareCompleteRegistration:"/api/v1/mfa/hardware/complete-registration",mfaSigninSendEmail:"/api/v1/auth/mfa/email/send",mfaSigninVerify:"/api/v1/auth/mfa/verify",mfaBackupCodeVerify:"/api/v1/auth/mfa/backup-code/verify",mfaWebAuthnChallenge:"/api/v1/auth/mfa/webauthn/challenge",sessions:"/api/v1/sessions",sessionsStats:"/api/v1/sessions/stats",sessionRevoke:"/api/v1/sessions/{session_id}/revoke",sessionsRevokeAll:"/api/v1/sessions/revoke-all"},p=Symbol("strands-config"),m=u.ref(null);function v(s){if(typeof window>"u"||!document.documentElement)return;if(typeof CSS<"u"&&CSS.registerProperty)try{CSS.registerProperty({name:"--strands-accent",syntax:"<color>",inherits:!0,initialValue:s})}catch{}document.documentElement.style.setProperty("--strands-accent",s),document.documentElement.style.setProperty("--accui-strands-accent",s);const t={"--accui-strands-50":`color-mix(in srgb, ${s} 10%, white)`,"--accui-strands-100":`color-mix(in srgb, ${s} 20%, white)`,"--accui-strands-200":`color-mix(in srgb, ${s} 30%, white)`,"--accui-strands-300":`color-mix(in srgb, ${s} 40%, white)`,"--accui-strands-400":`color-mix(in srgb, ${s} 70%, white)`,"--accui-strands-500":s,"--accui-strands-600":`color-mix(in srgb, ${s} 85%, black)`,"--accui-strands-700":`color-mix(in srgb, ${s} 70%, black)`,"--accui-strands-800":`color-mix(in srgb, ${s} 55%, black)`,"--accui-strands-900":`color-mix(in srgb, ${s} 40%, black)`,"--accui-strands-950":`color-mix(in srgb, ${s} 25%, black)`};for(const[r,n]of Object.entries(t))document.documentElement.style.setProperty(r,n)}function g(s){if(m.value=s,typeof window<"u"&&document.documentElement){const t=s.useSquircle!==void 0?s.useSquircle:!0;document.documentElement.style.setProperty("--strands-allow-squircle",t?"1":"0"),s.accentColor&&v(s.accentColor)}try{u.provide(p,s)}catch(t){console.warn("[Strands Auth] Could not provide config via Vue provide/inject. Config available via global state only.",t)}}function h(s){let t=null;try{u.getCurrentInstance()&&(t=u.inject(p,null))}catch{t=null}let r=null;try{if(typeof window<"u"){if(window.__STRANDS_CONFIG__)r=window.__STRANDS_CONFIG__;else if(window.__NUXT__){const i=window.__NUXT__;r=i?.config?.public?.strandsAuth||i?.public?.strandsAuth||i?.strandsAuth}}}catch(i){console.error("[Strands Auth] Error accessing runtime configuration:",i)}const n=u.computed(()=>{const i={...c,...s||{},...t||{},...m.value||{},...r||{}};if(i.baseUrl===c.baseUrl&&typeof window>"u"&&console.warn("[Strands Auth] No baseUrl configured for SSR. Please provide a baseUrl in your strandsAuth configuration."),typeof window<"u"&&document.documentElement){const e=i.useSquircle!==void 0?i.useSquircle:!0;document.documentElement.style.setProperty("--strands-allow-squircle",e?"1":"0"),i.accentColor&&document.documentElement.style.setProperty("--strands-accent",i.accentColor)}return i}),l=u.computed(()=>{const e=n.value.endpoints||{};return{signIn:e.signIn||a.signIn,signUp:e.signUp||a.signUp,signOut:e.signOut||a.signOut,refresh:e.refresh||a.refresh,passwordReset:e.passwordReset||a.passwordReset,passwordResetConfirm:e.passwordResetConfirm||a.passwordResetConfirm,completeRegistration:e.completeRegistration||a.completeRegistration,profile:e.profile||a.profile,verifyEmail:e.verifyEmail||a.verifyEmail,oauthProviders:e.oauthProviders||a.oauthProviders,oauthProvider:e.oauthProvider||a.oauthProvider,changeEmail:e.changeEmail||a.changeEmail,avatar:e.avatar||a.avatar,settings:e.settings||a.settings,changeUsername:e.changeUsername||a.changeUsername,usernameCooldown:e.usernameCooldown||a.usernameCooldown,checkUsernameAvailability:e.checkUsernameAvailability||a.checkUsernameAvailability,mfaDevices:e.mfaDevices||a.mfaDevices,mfaTotpSetup:e.mfaTotpSetup||a.mfaTotpSetup,mfaTotpVerify:e.mfaTotpVerify||a.mfaTotpVerify,mfaEmailSetup:e.mfaEmailSetup||a.mfaEmailSetup,mfaEmailSend:e.mfaEmailSend||a.mfaEmailSend,mfaEmailVerify:e.mfaEmailVerify||a.mfaEmailVerify,mfaDeviceDisable:e.mfaDeviceDisable||a.mfaDeviceDisable,mfaBackupCodes:e.mfaBackupCodes||a.mfaBackupCodes,mfaHardwareStartRegistration:e.mfaHardwareStartRegistration||a.mfaHardwareStartRegistration,mfaHardwareCompleteRegistration:e.mfaHardwareCompleteRegistration||a.mfaHardwareCompleteRegistration,mfaSigninSendEmail:e.mfaSigninSendEmail||a.mfaSigninSendEmail,mfaSigninVerify:e.mfaSigninVerify||a.mfaSigninVerify,mfaBackupCodeVerify:e.mfaBackupCodeVerify||a.mfaBackupCodeVerify,mfaWebAuthnChallenge:e.mfaWebAuthnChallenge||a.mfaWebAuthnChallenge,sessions:e.sessions||a.sessions,sessionsStats:e.sessionsStats||a.sessionsStats,sessionRevoke:e.sessionRevoke||a.sessionRevoke,sessionsRevokeAll:e.sessionsRevokeAll||a.sessionsRevokeAll}});return{config:n,endpoints:l,getUrl:i=>{const e=n.value;if(!e.baseUrl)throw new Error("Base URL is required in configuration");let o;typeof i=="string"&&i in l.value?o=l.value[i]:typeof i=="string"?o=i:o=l.value[i];const f=e.baseUrl.replace(/\/$/,""),d=o.startsWith("/")?o:`/${o}`;return console.debug(`[Strands Auth] Constructing URL for endpoint "${i}": ${f}${d}`),`${f}${d}`},getSupportEmail:()=>n.value.supportEmail||null}}function S(s){if(m.value=s,typeof window<"u"&&document.documentElement){const t=s.useSquircle!==void 0?s.useSquircle:!0;document.documentElement.style.setProperty("--strands-allow-squircle",t?"1":"0"),s.accentColor&&v(s.accentColor)}}const y=Object.freeze(Object.defineProperty({__proto__:null,provideStrandsConfig:g,setStrandsConfig:S,useStrandsConfig:h},Symbol.toStringTag,{value:"Module"}));exports.STRANDS_AUTH_DEFAULTS=c;exports.provideStrandsConfig=g;exports.setStrandsConfig=S;exports.useStrandsConfig=h;exports.useStrandsConfig$1=y;
|
package/dist/vite.cjs.js
CHANGED
|
@@ -26,4 +26,4 @@ if (typeof window !== 'undefined') {
|
|
|
26
26
|
window.__STRANDS_INJECTED__ = true
|
|
27
27
|
}
|
|
28
28
|
`}
|
|
29
|
-
${s}`,map:null}:null}}}function d(i={}){return{install(a){Promise.resolve().then(()=>require("./StrandsUIPlugin-Bwc7jBcb.cjs.js")).then(n=>n.StrandsUIPlugin$1).then(n=>{const r=n.default;a.use(r)}),Promise.resolve().then(()=>require("./useStrandsConfig-
|
|
29
|
+
${s}`,map:null}:null}}}function d(i={}){return{install(a){Promise.resolve().then(()=>require("./StrandsUIPlugin-Bwc7jBcb.cjs.js")).then(n=>n.StrandsUIPlugin$1).then(n=>{const r=n.default;a.use(r)}),Promise.resolve().then(()=>require("./useStrandsConfig-B5kp4aF9.cjs.js")).then(n=>n.useStrandsConfig$1).then(n=>{const{setStrandsConfig:r}=n;r(i),typeof window<"u"&&(window.__STRANDS_CONFIG__=i)})}}}exports.StrandsAuth=e;exports.StrandsAuthVitePlugin=e;exports.createStrandsAuth=d;exports.default=e;exports.strandsAuth=e;
|
package/dist/vite.es.js
CHANGED
|
@@ -76,7 +76,7 @@ function d(r = {}) {
|
|
|
76
76
|
import("./StrandsUIPlugin-RTFzvRED.es.js").then((n) => n.n).then((n) => {
|
|
77
77
|
const i = n.default;
|
|
78
78
|
a.use(i);
|
|
79
|
-
}), import("./useStrandsConfig-
|
|
79
|
+
}), import("./useStrandsConfig-CMKVW1p3.es.js").then((n) => n.a).then((n) => {
|
|
80
80
|
const { setStrandsConfig: i } = n;
|
|
81
81
|
i(r), typeof window < "u" && (window.__STRANDS_CONFIG__ = r);
|
|
82
82
|
});
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const u=require("vue"),me=require("./useStrandsConfig-D7a0QXz3.cjs.js");class we{cache=new Map;DEFAULT_TTL=300*1e3;async fetch(d,v,g=this.DEFAULT_TTL){const x=Date.now(),s=this.cache.get(d);if(s&&x-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:x,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 we;function ye(){return{fetch:m.fetch.bind(m),clear:m.clear.bind(m),invalidate:m.invalidate.bind(m),getStats:m.getStats.bind(m)}}function pe(n,d){let v=null;return(...g)=>{v&&clearTimeout(v),v=setTimeout(()=>{n(...g)},d)}}const F=pe((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()}),Se={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;function _e(){const{getUrl:n,config:d}=me.useStrandsConfig(),{fetch:v,clear:g,invalidate:x}=ye(),{currentUser:s,currentSession:o,loadingStates:i,isInitialized:k,mfaRequired:y,mfaSessionId:f,availableMfaMethods:p}=Se,S=()=>{if(s.value=null,o.value=null,y.value=!1,f.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)}},z=u.computed(()=>i.value.initializing),L=u.computed(()=>i.value.signingIn),R=u.computed(()=>i.value.signingUp),U=u.computed(()=>i.value.signingOut),q=u.computed(()=>i.value.refreshingToken),B=u.computed(()=>i.value.sendingMfaEmail),V=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),K=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..."}),A=()=>{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 h=JSON.parse(c);l=h.message||h.error||c}catch{l=c||"Failed to complete hardware key registration"}throw new Error(l)}return r.json()},W=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 h=JSON.parse(c);l=h.message||h.error||c}catch{l=c||"Failed to start hardware key registration"}throw new Error(l)}return r.json()},Y=u.computed(()=>s.value!==null),Q=async e=>{i.value.signingIn=!0;try{y.value=!1,f.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,f.value=r.mfa_session_id||null;const c=(r.available_mfa_methods||[]).map(l=>{let h=`${l.device_type.charAt(0).toUpperCase()+l.device_type.slice(1)} Authentication`;return l.device_type==="hardware"?h=l.device_name||"Security Key":l.device_type==="totp"?h=l.device_name||"Authenticator App":l.device_type==="email"&&(h=l.device_name||"Email Verification"),{id:l.device_id,device_type:l.device_type,device_name:l.device_name||h,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,i.value.signingIn=!1,r}return await P(r),r}catch(t){throw t}finally{i.value.signingIn=!1}},X=async e=>{i.value.signingUp=!0;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{i.value.signingUp=!1}},Z=async()=>{i.value.signingOut=!0;try{O(),$(),w=null,g(),s.value=null,o.value=null,y.value=!1,f.value=null,p.value=[],typeof window<"u"&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}finally{i.value.signingOut=!1}},b=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 S(),!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)),_(),C(),x(`sessions:${o.value.accessToken.slice(0,20)}`),!0}catch{return S(),!1}finally{i.value.refreshingToken=!1}})();const e=await w;return w=null,e},ee=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}},te=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}},ae=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}},ne=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}},se=async(e,t,a=!1)=>{if(!f.value)throw new Error("No MFA session available");i.value.verifyingMfa=!0;try{const r=n(a?"mfaBackupCodeVerify":"mfaSigninVerify"),c=a?{mfa_session_id:f.value,backup_code:t}:{mfa_session_id:f.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 N=await l.text();let D="MFA verification failed";try{const J=JSON.parse(N);D=J.message||J.error||N}catch{D=N||"MFA verification failed"}throw new Error(D)}const h=await l.json();return y.value=!1,f.value=null,p.value=[],await P(h),h}finally{i.value.verifyingMfa=!1}},ie=async e=>{if(!f.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:f.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}},re=async e=>{if(!f.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:f.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()},P=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))),_(),C()}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){b();return}T=setTimeout(async()=>{(typeof document>"u"||document.visibilityState==="visible")&&await b()&&_()},a)},O=()=>{T&&(clearTimeout(T),T=null)},C=()=>{I||typeof window>"u"||(I=setInterval(()=>{s.value&&o.value&&(localStorage.getItem("strands_auth_session")||($(),S()))},2e3))},$=()=>{I&&(clearInterval(I),I=null)},M=async()=>{if(!k.value){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 b()||S()):a.expiresAt>new Date?(o.value=a,s.value=r,_(),C()):(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{}finally{i.value.initializing=!1}}},oe=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}},le=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()},ue=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()},ce=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}},de=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()},fe=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},he=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?(_(),ge()):document.visibilityState==="hidden"&&O()}),typeof window<"u"&&window.addEventListener("storage",e=>{(e.key==="strands_auth_session"||e.key==="strands_auth_user")&&!e.newValue&&s.value&&S()});const ge=()=>{if(!(typeof window>"u")&&s.value&&o.value){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");(!e||!t)&&S()}},ve=()=>{O(),$(),g()};try{u.getCurrentInstance()&&u.onUnmounted(ve)}catch{}return k.value||M(),{user:u.computed(()=>s.value),currentUser:u.computed(()=>s.value),currentSession:u.computed(()=>o.value),isAuthenticated:Y,isLoading:u.computed(()=>K.value||!k.value),loading:j,loadingMessage:G,isInitializing:z,isSigningIn:L,isSigningUp:R,isSigningOut:U,isRefreshingToken:q,isSendingMfaEmail:B,isVerifyingMfa:V,mfaRequired:u.computed(()=>y.value),mfaSessionId:u.computed(()=>f.value),availableMfaMethods:u.computed(()=>p.value),signIn:Q,signUp:X,signOut:Z,refreshToken:b,fetchProfile:ee,updateProfile:te,updateUserSettings:ae,changeEmail:ne,changeUsername:oe,getUsernameCooldown:le,checkUsernameAvailability:ue,getUserSessions:ce,getSessionStats:de,revokeSession:fe,revokeAllOtherSessions:he,initialize:M,setAuthData:P,verifyMfa:se,sendMfaEmailCode:ie,getMfaWebAuthnChallenge:re,registerHardwareKey:W,completeHardwareKeyRegistration:H,startTokenRefreshTimer:_,stopTokenRefreshTimer:O,getAuthHeaders:A,forceReInit:()=>{k.value=!1,i.value.initializing=!0,M()}}}exports.useStrandsAuth=_e;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const u=require("vue"),c={baseUrl:"https://your-api.example.com",accentColor:"#EA00A8",redirectUrl:"/",onSignInUrl:"/dashboard",onSignOutUrl:"/",autoRefresh:!0,refreshInterval:4,protectedRoutes:[],guestOnlyRoutes:["/auth","/login","/register"],devMode:!1,styles:!0,endpoints:{},useSquircle:!0},a={signIn:"/api/v1/auth/sign-in",signUp:"/api/v1/auth/sign-up",signOut:"/api/v1/auth/sign-out",refresh:"/api/v1/auth/refresh",passwordReset:"/api/v1/auth/password-reset",passwordResetConfirm:"/api/v1/auth/password-reset/confirm",completeRegistration:"/api/v1/auth/complete-registration",profile:"/api/v1/user/profile",verifyEmail:"/api/v1/auth/verify-email",oauthProviders:"/api/v1/oauth/providers",oauthProvider:"/api/v1/oauth/providers/{provider_id}",changeEmail:"/api/v1/user/change-email",avatar:"/api/v1/user/avatar",settings:"/api/v1/user/settings",changeUsername:"/api/v1/user/username",usernameCooldown:"/api/v1/user/username/cooldown",checkUsernameAvailability:"/api/v1/username/{username}/available",mfaDevices:"/api/v1/mfa/devices",mfaTotpSetup:"/api/v1/mfa/totp/setup",mfaTotpVerify:"/api/v1/mfa/totp/verify",mfaEmailSetup:"/api/v1/mfa/email/setup",mfaEmailSend:"/api/v1/mfa/email/send",mfaEmailVerify:"/api/v1/mfa/email/verify",mfaDeviceDisable:"/api/v1/mfa/device/disable",mfaBackupCodes:"/api/v1/mfa/backup-codes/regenerate",mfaHardwareStartRegistration:"/api/v1/mfa/hardware/start-registration",mfaHardwareCompleteRegistration:"/api/v1/mfa/hardware/complete-registration",mfaSigninSendEmail:"/api/v1/auth/mfa/email/send",mfaSigninVerify:"/api/v1/auth/mfa/verify",mfaBackupCodeVerify:"/api/v1/auth/mfa/backup-code/verify",mfaWebAuthnChallenge:"/api/v1/auth/mfa/webauthn/challenge",sessions:"/api/v1/sessions",sessionsStats:"/api/v1/sessions/stats",sessionRevoke:"/api/v1/sessions/{session_id}/revoke",sessionsRevokeAll:"/api/v1/sessions/revoke-all"},p=Symbol("strands-config"),m=u.ref(null);function v(s){if(typeof window>"u"||!document.documentElement)return;if(typeof CSS<"u"&&CSS.registerProperty)try{CSS.registerProperty({name:"--strands-accent",syntax:"<color>",inherits:!0,initialValue:s})}catch{}document.documentElement.style.setProperty("--strands-accent",s),document.documentElement.style.setProperty("--accui-strands-accent",s);const t={"--accui-strands-50":`color-mix(in srgb, ${s} 10%, white)`,"--accui-strands-100":`color-mix(in srgb, ${s} 20%, white)`,"--accui-strands-200":`color-mix(in srgb, ${s} 30%, white)`,"--accui-strands-300":`color-mix(in srgb, ${s} 40%, white)`,"--accui-strands-400":`color-mix(in srgb, ${s} 70%, white)`,"--accui-strands-500":s,"--accui-strands-600":`color-mix(in srgb, ${s} 85%, black)`,"--accui-strands-700":`color-mix(in srgb, ${s} 70%, black)`,"--accui-strands-800":`color-mix(in srgb, ${s} 55%, black)`,"--accui-strands-900":`color-mix(in srgb, ${s} 40%, black)`,"--accui-strands-950":`color-mix(in srgb, ${s} 25%, black)`};for(const[r,n]of Object.entries(t))document.documentElement.style.setProperty(r,n)}function g(s){if(m.value=s,typeof window<"u"&&document.documentElement){const t=s.useSquircle!==void 0?s.useSquircle:!0;document.documentElement.style.setProperty("--strands-allow-squircle",t?"1":"0"),s.accentColor&&v(s.accentColor)}try{u.provide(p,s)}catch(t){console.warn("[Strands Auth] Could not provide config via Vue provide/inject. Config available via global state only.",t)}}function S(s){let t=null;try{u.getCurrentInstance()&&(t=u.inject(p,null))}catch{t=null}let r=null;try{if(typeof window<"u"){if(window.__STRANDS_CONFIG__)r=window.__STRANDS_CONFIG__;else if(window.__NUXT__){const i=window.__NUXT__;r=i?.config?.public?.strandsAuth||i?.public?.strandsAuth||i?.strandsAuth}}}catch(i){console.error("[Strands Auth] Error accessing runtime configuration:",i)}const n=u.computed(()=>{const i={...c,...s||{},...t||{},...m.value||{},...r||{}};if(i.baseUrl===c.baseUrl&&typeof window>"u"&&console.warn("[Strands Auth] No baseUrl configured for SSR. Please provide a baseUrl in your strandsAuth configuration."),typeof window<"u"&&document.documentElement){const e=i.useSquircle!==void 0?i.useSquircle:!0;document.documentElement.style.setProperty("--strands-allow-squircle",e?"1":"0"),i.accentColor&&document.documentElement.style.setProperty("--strands-accent",i.accentColor)}return i}),l=u.computed(()=>{const e=n.value.endpoints||{};return{signIn:e.signIn||a.signIn,signUp:e.signUp||a.signUp,signOut:e.signOut||a.signOut,refresh:e.refresh||a.refresh,passwordReset:e.passwordReset||a.passwordReset,passwordResetConfirm:e.passwordResetConfirm||a.passwordResetConfirm,completeRegistration:e.completeRegistration||a.completeRegistration,profile:e.profile||a.profile,verifyEmail:e.verifyEmail||a.verifyEmail,oauthProviders:e.oauthProviders||a.oauthProviders,oauthProvider:e.oauthProvider||a.oauthProvider,changeEmail:e.changeEmail||a.changeEmail,avatar:e.avatar||a.avatar,settings:e.settings||a.settings,changeUsername:e.changeUsername||a.changeUsername,usernameCooldown:e.usernameCooldown||a.usernameCooldown,checkUsernameAvailability:e.checkUsernameAvailability||a.checkUsernameAvailability,mfaDevices:e.mfaDevices||a.mfaDevices,mfaTotpSetup:e.mfaTotpSetup||a.mfaTotpSetup,mfaTotpVerify:e.mfaTotpVerify||a.mfaTotpVerify,mfaEmailSetup:e.mfaEmailSetup||a.mfaEmailSetup,mfaEmailSend:e.mfaEmailSend||a.mfaEmailSend,mfaEmailVerify:e.mfaEmailVerify||a.mfaEmailVerify,mfaDeviceDisable:e.mfaDeviceDisable||a.mfaDeviceDisable,mfaBackupCodes:e.mfaBackupCodes||a.mfaBackupCodes,mfaHardwareStartRegistration:e.mfaHardwareStartRegistration||a.mfaHardwareStartRegistration,mfaHardwareCompleteRegistration:e.mfaHardwareCompleteRegistration||a.mfaHardwareCompleteRegistration,mfaSigninSendEmail:e.mfaSigninSendEmail||a.mfaSigninSendEmail,mfaSigninVerify:e.mfaSigninVerify||a.mfaSigninVerify,mfaBackupCodeVerify:e.mfaBackupCodeVerify||a.mfaBackupCodeVerify,mfaWebAuthnChallenge:e.mfaWebAuthnChallenge||a.mfaWebAuthnChallenge,sessions:e.sessions||a.sessions,sessionsStats:e.sessionsStats||a.sessionsStats,sessionRevoke:e.sessionRevoke||a.sessionRevoke,sessionsRevokeAll:e.sessionsRevokeAll||a.sessionsRevokeAll}});return{config:n,endpoints:l,getUrl:i=>{const e=n.value;if(!e.baseUrl)throw new Error("Base URL is required in configuration");let o;typeof i=="string"&&i in l.value?o=l.value[i]:typeof i=="string"?o=i:o=l.value[i];const f=e.baseUrl.replace(/\/$/,""),d=o.startsWith("/")?o:`/${o}`;return console.debug(`[Strands Auth] Constructing URL for endpoint "${i}": ${f}${d}`),`${f}${d}`},getSupportEmail:()=>n.value.supportEmail||null}}function h(s){if(m.value=s,typeof window<"u"&&document.documentElement){const t=s.useSquircle!==void 0?s.useSquircle:!0;document.documentElement.style.setProperty("--strands-allow-squircle",t?"1":"0"),s.accentColor&&v(s.accentColor)}}const y=Object.freeze(Object.defineProperty({__proto__:null,provideStrandsConfig:g,setStrandsConfig:h,useStrandsConfig:S},Symbol.toStringTag,{value:"Module"}));exports.STRANDS_AUTH_DEFAULTS=c;exports.provideStrandsConfig=g;exports.setStrandsConfig=h;exports.useStrandsConfig=S;exports.useStrandsConfig$1=y;
|