@strands.gg/accui 2.15.16 → 2.17.9
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/StrandsUIPlugin-Bwc7jBcb.cjs.js +143 -0
- package/dist/StrandsUIPlugin-RTFzvRED.es.js +20536 -0
- package/dist/accui.css +1 -1
- package/dist/index.cjs.js +5 -1
- package/dist/index.es.js +8805 -12557
- package/dist/nuxt/module.cjs.js +23 -1
- package/dist/nuxt/module.es.js +58 -82
- package/dist/nuxt/runtime/composables/useAuthenticatedFetch.cjs.js +1 -1
- package/dist/nuxt/runtime/composables/useAuthenticatedFetch.es.js +82 -111
- package/dist/nuxt/runtime/composables/useStrandsAuth.cjs.js +1 -1
- package/dist/nuxt/runtime/composables/useStrandsAuth.es.js +30 -46
- package/dist/nuxt/runtime/middleware/auth.global.cjs.js +1 -1
- package/dist/nuxt/runtime/middleware/auth.global.es.js +28 -44
- package/dist/nuxt/runtime/plugin.client.cjs.js +1 -1
- package/dist/nuxt/runtime/plugin.client.es.js +10 -19
- package/dist/nuxt/runtime/plugin.server.cjs.js +1 -1
- package/dist/nuxt/runtime/plugin.server.es.js +8 -10
- package/dist/nuxt/runtime/plugins/auth-interceptor.client.cjs.js +1 -1
- package/dist/nuxt/runtime/plugins/auth-interceptor.client.es.js +27 -48
- package/dist/nuxt.cjs.js +1 -1
- package/dist/nuxt.es.js +9 -9
- package/dist/useStrandsAuth-BVqpuhrO.cjs.js +1 -0
- package/dist/useStrandsAuth-Bv61_QkS.es.js +653 -0
- package/dist/useStrandsConfig-Cd22bj_E.es.js +209 -0
- package/dist/useStrandsConfig-D7a0QXz3.cjs.js +1 -0
- package/dist/vite.cjs.js +29 -1
- package/dist/vite.es.js +58 -75
- package/dist/vue/utils/modalStack.d.ts +3 -0
- package/package.json +2 -2
- package/dist/StrandsUIPlugin-BRGzLy44.cjs.js +0 -1
- package/dist/StrandsUIPlugin-DtGqMkbS.es.js +0 -26371
- package/dist/useStrandsAuth-BCnUxo-R.es.js +0 -915
- package/dist/useStrandsAuth-DoJxpNLb.cjs.js +0 -1
- package/dist/useStrandsConfig-Sr6NG90B.cjs.js +0 -1
- package/dist/useStrandsConfig-fRu-OG08.es.js +0 -248
|
@@ -1,51 +1,35 @@
|
|
|
1
|
-
import { defineNuxtRouteMiddleware, useRuntimeConfig, navigateTo } from "nuxt/app";
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
if (import.meta.server)
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
const currentPath = to.path;
|
|
14
|
-
const isProtectedRoute = config.protectedRoutes?.some((route) => {
|
|
15
|
-
if (route.endsWith("*")) {
|
|
16
|
-
return currentPath.startsWith(route.slice(0, -1));
|
|
1
|
+
import { defineNuxtRouteMiddleware as m, useRuntimeConfig as g, navigateTo as a } from "nuxt/app";
|
|
2
|
+
const w = m((u) => {
|
|
3
|
+
const n = g().public.strandsAuth;
|
|
4
|
+
if (!import.meta.server)
|
|
5
|
+
return new Promise((c) => {
|
|
6
|
+
import("../composables/useStrandsAuth.es.js").then(({ useStrandsAuth: d }) => {
|
|
7
|
+
const { isAuthenticated: r, isLoading: h } = d(), i = () => {
|
|
8
|
+
if (h.value) {
|
|
9
|
+
setTimeout(i, 50);
|
|
10
|
+
return;
|
|
17
11
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
return navigateTo(redirectUrl);
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.warn("[Strands Auth] navigateTo failed, using window.location:", error);
|
|
33
|
-
if (typeof window !== "undefined") {
|
|
34
|
-
window.location.href = redirectUrl;
|
|
35
|
-
return;
|
|
12
|
+
const e = u.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 + "/"));
|
|
13
|
+
if (l && !r.value) {
|
|
14
|
+
const t = n.onSignOutUrl || "/auth", o = t.includes("?") ? `${t}&redirect=${encodeURIComponent(e)}` : `${t}?redirect=${encodeURIComponent(e)}`;
|
|
15
|
+
try {
|
|
16
|
+
return a(o);
|
|
17
|
+
} catch (s) {
|
|
18
|
+
if (console.warn("[Strands Auth] navigateTo failed, using window.location:", s), typeof window < "u") {
|
|
19
|
+
window.location.href = o;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
throw s;
|
|
36
23
|
}
|
|
37
|
-
throw error;
|
|
38
24
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
};
|
|
45
|
-
checkAuth();
|
|
25
|
+
if (f && r.value)
|
|
26
|
+
return a(n.onSignInUrl || "/dashboard");
|
|
27
|
+
c();
|
|
28
|
+
};
|
|
29
|
+
i();
|
|
30
|
+
});
|
|
46
31
|
});
|
|
47
|
-
});
|
|
48
32
|
});
|
|
49
33
|
export {
|
|
50
|
-
|
|
34
|
+
w as default
|
|
51
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("nuxt/app"),
|
|
1
|
+
"use strict";const e=require("nuxt/app"),t=require("../../useStrandsConfig-D7a0QXz3.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,26 +1,17 @@
|
|
|
1
|
-
import { defineNuxtPlugin, useRuntimeConfig } from "nuxt/app";
|
|
2
|
-
import { s as
|
|
3
|
-
const
|
|
1
|
+
import { defineNuxtPlugin as i, useRuntimeConfig as s } from "nuxt/app";
|
|
2
|
+
import { s as a, S as c } from "../../useStrandsConfig-Cd22bj_E.es.js";
|
|
3
|
+
const u = i({
|
|
4
4
|
name: "strands-auth-client",
|
|
5
5
|
async setup() {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
...STRANDS_AUTH_DEFAULTS,
|
|
10
|
-
...strandsConfig
|
|
6
|
+
const t = s().public.strandsAuth, n = {
|
|
7
|
+
...c,
|
|
8
|
+
...t
|
|
11
9
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
if (mergedConfig?.accentColor && typeof window !== "undefined") {
|
|
17
|
-
document.documentElement.style.setProperty("--strands-accent", mergedConfig.accentColor);
|
|
18
|
-
}
|
|
19
|
-
const { useStrandsAuth } = await import("./composables/useStrandsAuth.es.js");
|
|
20
|
-
const { initialize } = useStrandsAuth();
|
|
21
|
-
await initialize();
|
|
10
|
+
a(n), typeof window < "u" && (window.__STRANDS_CONFIG__ = n), n?.accentColor && typeof window < "u" && document.documentElement.style.setProperty("--strands-accent", n.accentColor);
|
|
11
|
+
const { useStrandsAuth: e } = await import("./composables/useStrandsAuth.es.js"), { initialize: o } = e();
|
|
12
|
+
await o();
|
|
22
13
|
}
|
|
23
14
|
});
|
|
24
15
|
export {
|
|
25
|
-
|
|
16
|
+
u as default
|
|
26
17
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const n=require("nuxt/app"),s=require("../../useStrandsConfig-D7a0QXz3.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,17 +1,15 @@
|
|
|
1
|
-
import { defineNuxtPlugin, useRuntimeConfig } from "nuxt/app";
|
|
2
|
-
import { s as
|
|
3
|
-
const
|
|
1
|
+
import { defineNuxtPlugin as t, useRuntimeConfig as e } from "nuxt/app";
|
|
2
|
+
import { s as o, S as r } from "../../useStrandsConfig-Cd22bj_E.es.js";
|
|
3
|
+
const u = t({
|
|
4
4
|
name: "strands-auth-server",
|
|
5
5
|
setup() {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
...STRANDS_AUTH_DEFAULTS,
|
|
10
|
-
...strandsConfig
|
|
6
|
+
const s = e().public.strandsAuth, n = {
|
|
7
|
+
...r,
|
|
8
|
+
...s
|
|
11
9
|
};
|
|
12
|
-
|
|
10
|
+
o(n);
|
|
13
11
|
}
|
|
14
12
|
});
|
|
15
13
|
export {
|
|
16
|
-
|
|
14
|
+
u as default
|
|
17
15
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const p=require("nuxt/app"),f=p.defineNuxtPlugin({name:"strands-auth-interceptor",setup(){if(process.server)return;const t=globalThis.fetch;globalThis.fetch=async(e,o)=>{try{const{useStrandsAuth:c}=await Promise.resolve().then(()=>require("../composables/useStrandsAuth.cjs.js")),{currentSession:n,getAuthHeaders:i}=c();let s;if(typeof e=="string"?s=e:e instanceof URL?s=e.toString():s=e.url,m(s)&&n.value?.accessToken)try{const a=i(),h=new Headers(o?.headers);Object.entries(a).forEach(([d,l])=>{h.set(d,l)});const u={...o,headers:h};return t(e,u)}catch(a){console.warn("[Strands Auth] Failed to inject auth headers:",a)}return t(e,o)}catch(c){return console.error("[Strands Auth] Error in fetch interceptor:",c),t(e,o)}}}});function m(t){if(!t.startsWith("http")||["googleapis.com","github.com/api","api.github.com","discord.com/api","graph.microsoft.com","api.stripe.com","api.twilio.com"].some(r=>t.includes(r)))return!1;const n=["/api/","/v1/","/v2/","/graphql","/trpc"].some(r=>t.includes(r)),s=[":3001",":8000",":8080",":5000",":4000"].some(r=>t.includes(r));return n||s}module.exports=f;
|
|
@@ -1,51 +1,36 @@
|
|
|
1
|
-
import { defineNuxtPlugin } from "nuxt/app";
|
|
2
|
-
const
|
|
1
|
+
import { defineNuxtPlugin as p } from "nuxt/app";
|
|
2
|
+
const g = p({
|
|
3
3
|
name: "strands-auth-interceptor",
|
|
4
4
|
setup() {
|
|
5
5
|
if (process.server) return;
|
|
6
|
-
const
|
|
7
|
-
globalThis.fetch = async (
|
|
6
|
+
const e = globalThis.fetch;
|
|
7
|
+
globalThis.fetch = async (t, o) => {
|
|
8
8
|
try {
|
|
9
|
-
const { useStrandsAuth } = await import("../composables/useStrandsAuth.es.js");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (typeof input === "string") {
|
|
13
|
-
url = input;
|
|
14
|
-
} else if (input instanceof URL) {
|
|
15
|
-
url = input.toString();
|
|
16
|
-
} else {
|
|
17
|
-
url = input.url;
|
|
18
|
-
}
|
|
19
|
-
const shouldAddAuth = shouldInjectAuth(url);
|
|
20
|
-
if (shouldAddAuth && currentSession.value?.accessToken) {
|
|
9
|
+
const { useStrandsAuth: a } = await import("../composables/useStrandsAuth.es.js"), { currentSession: c, getAuthHeaders: i } = a();
|
|
10
|
+
let s;
|
|
11
|
+
if (typeof t == "string" ? s = t : t instanceof URL ? s = t.toString() : s = t.url, f(s) && c.value?.accessToken)
|
|
21
12
|
try {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
headers.set(key, value);
|
|
13
|
+
const n = i(), h = new Headers(o?.headers);
|
|
14
|
+
Object.entries(n).forEach(([d, l]) => {
|
|
15
|
+
h.set(d, l);
|
|
26
16
|
});
|
|
27
|
-
const
|
|
28
|
-
...
|
|
29
|
-
headers
|
|
17
|
+
const u = {
|
|
18
|
+
...o,
|
|
19
|
+
headers: h
|
|
30
20
|
};
|
|
31
|
-
return
|
|
32
|
-
} catch (
|
|
33
|
-
console.warn("[Strands Auth] Failed to inject auth headers:",
|
|
21
|
+
return e(t, u);
|
|
22
|
+
} catch (n) {
|
|
23
|
+
console.warn("[Strands Auth] Failed to inject auth headers:", n);
|
|
34
24
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
console.error("[Strands Auth] Error in fetch interceptor:", error);
|
|
39
|
-
return originalFetch(input, init);
|
|
25
|
+
return e(t, o);
|
|
26
|
+
} catch (a) {
|
|
27
|
+
return console.error("[Strands Auth] Error in fetch interceptor:", a), e(t, o);
|
|
40
28
|
}
|
|
41
29
|
};
|
|
42
30
|
}
|
|
43
31
|
});
|
|
44
|
-
function
|
|
45
|
-
if (!
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
const skipDomains = [
|
|
32
|
+
function f(e) {
|
|
33
|
+
if (!e.startsWith("http") || [
|
|
49
34
|
"googleapis.com",
|
|
50
35
|
"github.com/api",
|
|
51
36
|
"api.github.com",
|
|
@@ -54,23 +39,17 @@ function shouldInjectAuth(url) {
|
|
|
54
39
|
"api.stripe.com",
|
|
55
40
|
"api.twilio.com"
|
|
56
41
|
// Add other third-party APIs here
|
|
57
|
-
]
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
const apiPatterns = [
|
|
42
|
+
].some((r) => e.includes(r)))
|
|
43
|
+
return !1;
|
|
44
|
+
const c = [
|
|
63
45
|
"/api/",
|
|
64
46
|
"/v1/",
|
|
65
47
|
"/v2/",
|
|
66
48
|
"/graphql",
|
|
67
49
|
"/trpc"
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
const apiPorts = [":3001", ":8000", ":8080", ":5000", ":4000"];
|
|
71
|
-
const hasApiPort = apiPorts.some((port) => url.includes(port));
|
|
72
|
-
return isApiRequest || hasApiPort;
|
|
50
|
+
].some((r) => e.includes(r)), s = [":3001", ":8000", ":8080", ":5000", ":4000"].some((r) => e.includes(r));
|
|
51
|
+
return c || s;
|
|
73
52
|
}
|
|
74
53
|
export {
|
|
75
|
-
|
|
54
|
+
g as default
|
|
76
55
|
};
|
package/dist/nuxt.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const u=require("./nuxt/module.cjs.js"),e=require("./nuxt/runtime/composables/useStrandsAuth.cjs.js"),t=require("./nuxt/runtime/composables/useAuthenticatedFetch.cjs.js");exports.default=u;exports.useAuthState=e.useAuthState;exports.useAuthUser=e.useAuthUser;exports.useStrandsAuth=e.useStrandsAuth;exports.$authFetch=t.$authFetch;exports.useAuthenticatedFetch=t.useAuthenticatedFetch;
|
package/dist/nuxt.es.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { default as
|
|
2
|
-
import { useAuthState, useAuthUser, useStrandsAuth } from "./nuxt/runtime/composables/useStrandsAuth.es.js";
|
|
3
|
-
import { $authFetch, useAuthenticatedFetch } from "./nuxt/runtime/composables/useAuthenticatedFetch.es.js";
|
|
1
|
+
import { default as u } from "./nuxt/module.es.js";
|
|
2
|
+
import { useAuthState as h, useAuthUser as o, useStrandsAuth as s } from "./nuxt/runtime/composables/useStrandsAuth.es.js";
|
|
3
|
+
import { $authFetch as f, useAuthenticatedFetch as A } from "./nuxt/runtime/composables/useAuthenticatedFetch.es.js";
|
|
4
4
|
export {
|
|
5
|
-
$authFetch,
|
|
6
|
-
|
|
7
|
-
useAuthState,
|
|
8
|
-
useAuthUser,
|
|
9
|
-
useAuthenticatedFetch,
|
|
10
|
-
useStrandsAuth
|
|
5
|
+
f as $authFetch,
|
|
6
|
+
u as default,
|
|
7
|
+
h as useAuthState,
|
|
8
|
+
o as useAuthUser,
|
|
9
|
+
A as useAuthenticatedFetch,
|
|
10
|
+
s as useStrandsAuth
|
|
11
11
|
};
|
|
@@ -0,0 +1 @@
|
|
|
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;
|