@strands.gg/accui 2.3.8 → 2.3.10
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/nuxt/runtime/composables/useStrandsAuth.cjs.js +1 -1
- package/dist/nuxt/runtime/composables/useStrandsAuth.es.js +1 -1
- package/dist/nuxt-v4/runtime/composables/useStrandsAuth.cjs.js +1 -1
- package/dist/nuxt-v4/runtime/composables/useStrandsAuth.es.js +1 -1
- package/dist/strands-auth-ui.cjs.js +1 -1
- package/dist/strands-auth-ui.es.js +119 -59
- package/dist/{useStrandsAuth-B91u7n_t.es.js → useStrandsAuth-DoUupKb8.es.js} +11 -1
- package/dist/{useStrandsAuth-C4UY4aTP.cjs.js → useStrandsAuth-WChBcwNF.cjs.js} +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { defineComponent, computed, provide, onMounted, onUnmounted, createElementBlock, openBlock, normalizeClass, renderSlot, createBlock, Teleport, createCommentVNode, unref, createElementVNode, toDisplayString, createTextVNode, h, useSlots,
|
|
1
|
+
import { defineComponent, computed, provide, onMounted, onUnmounted, createElementBlock, openBlock, normalizeClass, renderSlot, createBlock, Teleport, createCommentVNode, unref, createElementVNode, toDisplayString, createTextVNode, h, useSlots, resolveDynamicComponent, mergeProps, withCtx, Fragment, ref, nextTick, toRefs, watch, normalizeStyle, renderList, reactive, withModifiers, createStaticVNode, createVNode, withDirectives, vModelText, Transition, createSlots, vModelSelect, inject, onBeforeUnmount, withKeys, isMemoSame, getCurrentInstance } from "vue";
|
|
2
2
|
import { u as useStrandsConfig, p as provideStrandsConfig } from "./useStrandsConfig-C3gBJK6y.es.js";
|
|
3
3
|
import { s } from "./useStrandsConfig-C3gBJK6y.es.js";
|
|
4
|
-
import { u as useStrandsAuth } from "./useStrandsAuth-
|
|
4
|
+
import { u as useStrandsAuth } from "./useStrandsAuth-DoUupKb8.es.js";
|
|
5
5
|
class ModalStack {
|
|
6
6
|
stack = [];
|
|
7
7
|
escapeHandlerRegistered = false;
|
|
@@ -146,7 +146,7 @@ const _hoisted_4$t = {
|
|
|
146
146
|
"aria-hidden": "true"
|
|
147
147
|
};
|
|
148
148
|
const _hoisted_5$q = ["d"];
|
|
149
|
-
const _hoisted_6$
|
|
149
|
+
const _hoisted_6$n = { class: "alert-text-container" };
|
|
150
150
|
const _hoisted_7$m = {
|
|
151
151
|
key: 0,
|
|
152
152
|
class: "alert-dismiss-container"
|
|
@@ -202,7 +202,7 @@ const _sfc_main$J = /* @__PURE__ */ defineComponent({
|
|
|
202
202
|
}, null, 8, _hoisted_5$q)
|
|
203
203
|
]))
|
|
204
204
|
]),
|
|
205
|
-
createElementVNode("div", _hoisted_6$
|
|
205
|
+
createElementVNode("div", _hoisted_6$n, [
|
|
206
206
|
_ctx.title ? (openBlock(), createElementBlock("h3", {
|
|
207
207
|
key: 0,
|
|
208
208
|
class: normalizeClass(titleClasses.value)
|
|
@@ -613,21 +613,20 @@ const Users = createLucideIcon("users", [
|
|
|
613
613
|
["path", { d: "M22 21v-2a4 4 0 0 0-3-3.87", key: "kshegd" }],
|
|
614
614
|
["circle", { cx: "9", cy: "7", r: "4", key: "nufk8" }]
|
|
615
615
|
]);
|
|
616
|
-
const _hoisted_1$E =
|
|
617
|
-
const _hoisted_2$x = {
|
|
616
|
+
const _hoisted_1$E = {
|
|
618
617
|
key: 0,
|
|
619
618
|
class: "button-loading-content"
|
|
620
619
|
};
|
|
621
|
-
const
|
|
622
|
-
const
|
|
620
|
+
const _hoisted_2$x = { key: 0 };
|
|
621
|
+
const _hoisted_3$v = {
|
|
623
622
|
key: 1,
|
|
624
623
|
class: "button-content"
|
|
625
624
|
};
|
|
626
|
-
const
|
|
625
|
+
const _hoisted_4$s = {
|
|
627
626
|
key: 0,
|
|
628
627
|
class: "leading-icon"
|
|
629
628
|
};
|
|
630
|
-
const
|
|
629
|
+
const _hoisted_5$p = {
|
|
631
630
|
key: 1,
|
|
632
631
|
class: "trailing-icon"
|
|
633
632
|
};
|
|
@@ -647,7 +646,8 @@ const _sfc_main$I = /* @__PURE__ */ defineComponent({
|
|
|
647
646
|
iconName: {},
|
|
648
647
|
leadingIcon: {},
|
|
649
648
|
trailingIcon: {},
|
|
650
|
-
squircle: { type: Boolean, default: false }
|
|
649
|
+
squircle: { type: Boolean, default: false },
|
|
650
|
+
to: {}
|
|
651
651
|
},
|
|
652
652
|
emits: ["click"],
|
|
653
653
|
setup(__props) {
|
|
@@ -676,6 +676,36 @@ const _sfc_main$I = /* @__PURE__ */ defineComponent({
|
|
|
676
676
|
const LeadingIconComponent = computed(() => props.leadingIcon ? getLucideIcon(props.leadingIcon) : null);
|
|
677
677
|
const TrailingIconComponent = computed(() => props.trailingIcon ? getLucideIcon(props.trailingIcon) : null);
|
|
678
678
|
const IconComponent = computed(() => props.iconName ? getLucideIcon(props.iconName) : null);
|
|
679
|
+
const componentTag = computed(() => {
|
|
680
|
+
if (!props.to) return "button";
|
|
681
|
+
if (typeof process !== "undefined" && process.client !== void 0) {
|
|
682
|
+
return "nuxt-link";
|
|
683
|
+
}
|
|
684
|
+
if (typeof window !== "undefined" && (window.__NUXT__ || window.$nuxt)) {
|
|
685
|
+
return "nuxt-link";
|
|
686
|
+
}
|
|
687
|
+
try {
|
|
688
|
+
if (typeof window !== "undefined" && window.Vue?.Router) {
|
|
689
|
+
return "router-link";
|
|
690
|
+
}
|
|
691
|
+
} catch (e) {
|
|
692
|
+
}
|
|
693
|
+
return "a";
|
|
694
|
+
});
|
|
695
|
+
const linkProps = computed(() => {
|
|
696
|
+
if (!props.to) return {};
|
|
697
|
+
const tag = componentTag.value;
|
|
698
|
+
if (tag === "nuxt-link" || tag === "router-link") {
|
|
699
|
+
return { to: props.to };
|
|
700
|
+
}
|
|
701
|
+
if (tag === "a") {
|
|
702
|
+
if (typeof props.to === "object") {
|
|
703
|
+
return { href: "#route-object-not-supported" };
|
|
704
|
+
}
|
|
705
|
+
return { href: props.to };
|
|
706
|
+
}
|
|
707
|
+
return {};
|
|
708
|
+
});
|
|
679
709
|
const buttonClasses = computed(() => {
|
|
680
710
|
const classes = [
|
|
681
711
|
"ui-button",
|
|
@@ -696,56 +726,59 @@ const _sfc_main$I = /* @__PURE__ */ defineComponent({
|
|
|
696
726
|
};
|
|
697
727
|
});
|
|
698
728
|
return (_ctx, _cache) => {
|
|
699
|
-
return openBlock(),
|
|
700
|
-
type: _ctx.type,
|
|
729
|
+
return openBlock(), createBlock(resolveDynamicComponent(componentTag.value), mergeProps(linkProps.value, {
|
|
730
|
+
type: componentTag.value === "button" ? _ctx.type : void 0,
|
|
701
731
|
disabled: _ctx.disabled || _ctx.loading,
|
|
702
|
-
class:
|
|
703
|
-
style:
|
|
732
|
+
class: buttonClasses.value,
|
|
733
|
+
style: buttonStyles.value,
|
|
704
734
|
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event))
|
|
705
|
-
},
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
IconComponent.value
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
TrailingIconComponent.value
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
735
|
+
}), {
|
|
736
|
+
default: withCtx(() => [
|
|
737
|
+
_ctx.loading ? (openBlock(), createElementBlock("span", _hoisted_1$E, [
|
|
738
|
+
_cache[1] || (_cache[1] = createElementVNode("svg", {
|
|
739
|
+
class: "button-loading-icon",
|
|
740
|
+
fill: "none",
|
|
741
|
+
viewBox: "0 0 24 24"
|
|
742
|
+
}, [
|
|
743
|
+
createElementVNode("circle", {
|
|
744
|
+
class: "button-loading-track",
|
|
745
|
+
cx: "12",
|
|
746
|
+
cy: "12",
|
|
747
|
+
r: "10",
|
|
748
|
+
stroke: "currentColor",
|
|
749
|
+
"stroke-width": "4"
|
|
750
|
+
}),
|
|
751
|
+
createElementVNode("path", {
|
|
752
|
+
class: "button-loading-spinner",
|
|
753
|
+
fill: "currentColor",
|
|
754
|
+
d: "m4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 0 1 4 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
755
|
+
})
|
|
756
|
+
], -1)),
|
|
757
|
+
!_ctx.icon ? (openBlock(), createElementBlock("span", _hoisted_2$x, toDisplayString(_ctx.loadingText || "Loading..."), 1)) : createCommentVNode("", true)
|
|
758
|
+
])) : (openBlock(), createElementBlock("span", _hoisted_3$v, [
|
|
759
|
+
_ctx.icon ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
760
|
+
IconComponent.value && !unref(slots)["default"] ? (openBlock(), createBlock(resolveDynamicComponent(IconComponent.value), { key: 0 })) : renderSlot(_ctx.$slots, "default", { key: 1 }, void 0, true)
|
|
761
|
+
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
762
|
+
IconComponent.value || LeadingIconComponent.value || unref(slots)["leading-icon"] ? (openBlock(), createElementBlock("span", _hoisted_4$s, [
|
|
763
|
+
IconComponent.value && !LeadingIconComponent.value && !unref(slots)["leading-icon"] ? (openBlock(), createBlock(resolveDynamicComponent(IconComponent.value), { key: 0 })) : createCommentVNode("", true),
|
|
764
|
+
LeadingIconComponent.value && !unref(slots)["leading-icon"] ? (openBlock(), createBlock(resolveDynamicComponent(LeadingIconComponent.value), { key: 1 })) : createCommentVNode("", true),
|
|
765
|
+
unref(slots)["leading-icon"] ? renderSlot(_ctx.$slots, "leading-icon", { key: 2 }, void 0, true) : createCommentVNode("", true)
|
|
766
|
+
])) : createCommentVNode("", true),
|
|
767
|
+
renderSlot(_ctx.$slots, "icon", {}, void 0, true),
|
|
768
|
+
renderSlot(_ctx.$slots, "default", {}, void 0, true),
|
|
769
|
+
TrailingIconComponent.value || unref(slots)["trailing-icon"] ? (openBlock(), createElementBlock("span", _hoisted_5$p, [
|
|
770
|
+
TrailingIconComponent.value && !unref(slots)["trailing-icon"] ? (openBlock(), createBlock(resolveDynamicComponent(TrailingIconComponent.value), { key: 0 })) : createCommentVNode("", true),
|
|
771
|
+
unref(slots)["trailing-icon"] ? renderSlot(_ctx.$slots, "trailing-icon", { key: 1 }, void 0, true) : createCommentVNode("", true)
|
|
772
|
+
])) : createCommentVNode("", true)
|
|
773
|
+
], 64))
|
|
774
|
+
]))
|
|
775
|
+
]),
|
|
776
|
+
_: 3
|
|
777
|
+
}, 16, ["type", "disabled", "class", "style"]);
|
|
745
778
|
};
|
|
746
779
|
}
|
|
747
780
|
});
|
|
748
|
-
const StrandsUiButton = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-
|
|
781
|
+
const StrandsUiButton = /* @__PURE__ */ _export_sfc(_sfc_main$I, [["__scopeId", "data-v-0a40a982"]]);
|
|
749
782
|
const _hoisted_1$D = {
|
|
750
783
|
key: 0,
|
|
751
784
|
class: "ui-card-header"
|
|
@@ -1010,14 +1043,41 @@ const _sfc_main$F = /* @__PURE__ */ defineComponent({
|
|
|
1010
1043
|
const props = __props;
|
|
1011
1044
|
const emit = __emit;
|
|
1012
1045
|
const tag = computed(() => {
|
|
1013
|
-
if (props.to)
|
|
1046
|
+
if (props.to) {
|
|
1047
|
+
if (typeof process !== "undefined" && process.client !== void 0) {
|
|
1048
|
+
return "nuxt-link";
|
|
1049
|
+
}
|
|
1050
|
+
if (typeof window !== "undefined" && (window.__NUXT__ || window.$nuxt)) {
|
|
1051
|
+
return "nuxt-link";
|
|
1052
|
+
}
|
|
1053
|
+
try {
|
|
1054
|
+
if (typeof window !== "undefined" && window.Vue?.Router) {
|
|
1055
|
+
return "router-link";
|
|
1056
|
+
}
|
|
1057
|
+
} catch (e) {
|
|
1058
|
+
}
|
|
1059
|
+
return "a";
|
|
1060
|
+
}
|
|
1014
1061
|
if (props.href) return "a";
|
|
1015
1062
|
return "button";
|
|
1016
1063
|
});
|
|
1017
1064
|
const linkProps = computed(() => {
|
|
1018
1065
|
const baseProps = {};
|
|
1066
|
+
const currentTag = tag.value;
|
|
1019
1067
|
if (props.to) {
|
|
1020
|
-
|
|
1068
|
+
if (currentTag === "nuxt-link" || currentTag === "router-link") {
|
|
1069
|
+
baseProps["to"] = props.to;
|
|
1070
|
+
} else if (currentTag === "a") {
|
|
1071
|
+
if (typeof props.to === "object") {
|
|
1072
|
+
baseProps["href"] = "#route-object-not-supported";
|
|
1073
|
+
} else {
|
|
1074
|
+
baseProps["href"] = props.to;
|
|
1075
|
+
if (props.external) {
|
|
1076
|
+
baseProps["target"] = "_blank";
|
|
1077
|
+
baseProps["rel"] = "noopener noreferrer";
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1021
1081
|
} else if (props.href) {
|
|
1022
1082
|
baseProps["href"] = props.href;
|
|
1023
1083
|
if (props.external) {
|
|
@@ -1100,7 +1160,7 @@ const _sfc_main$F = /* @__PURE__ */ defineComponent({
|
|
|
1100
1160
|
};
|
|
1101
1161
|
}
|
|
1102
1162
|
});
|
|
1103
|
-
const StrandsUiLink = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["__scopeId", "data-v-
|
|
1163
|
+
const StrandsUiLink = /* @__PURE__ */ _export_sfc(_sfc_main$F, [["__scopeId", "data-v-a9d22fbf"]]);
|
|
1104
1164
|
const _hoisted_1$B = { class: "tabs-wrapper" };
|
|
1105
1165
|
const _hoisted_2$u = {
|
|
1106
1166
|
key: 0,
|
|
@@ -648,7 +648,17 @@ function useStrandsAuth() {
|
|
|
648
648
|
const session = JSON.parse(storedSession);
|
|
649
649
|
const user = JSON.parse(storedUser);
|
|
650
650
|
session.expiresAt = new Date(session.expiresAt);
|
|
651
|
-
if (session.expiresAt
|
|
651
|
+
if (session.expiresAt <= /* @__PURE__ */ new Date() && session.refreshToken) {
|
|
652
|
+
currentSession.value = session;
|
|
653
|
+
currentUser.value = user;
|
|
654
|
+
const refreshSuccess = await refreshToken();
|
|
655
|
+
if (!refreshSuccess) {
|
|
656
|
+
localStorage.removeItem("strands_auth_session");
|
|
657
|
+
localStorage.removeItem("strands_auth_user");
|
|
658
|
+
currentSession.value = null;
|
|
659
|
+
currentUser.value = null;
|
|
660
|
+
}
|
|
661
|
+
} else if (session.expiresAt > /* @__PURE__ */ new Date()) {
|
|
652
662
|
currentSession.value = session;
|
|
653
663
|
currentUser.value = user;
|
|
654
664
|
startTokenRefreshTimer();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("vue"),t=require("./useStrandsConfig-B6uW6Zkd.cjs.js"),n=new class{cache=new Map;DEFAULT_TTL=3e5;async fetch(e,t,n=this.DEFAULT_TTL){const a=Date.now(),i=this.cache.get(e);if(i&&a-i.timestamp<i.ttl)return i.promise;this.cleanExpired();const r=t().finally(()=>{setTimeout(()=>{this.cache.delete(e)},n)});return this.cache.set(e,{promise:r,timestamp:a,ttl:n}),r}clear(){this.cache.clear()}invalidate(e){this.cache.delete(e)}cleanExpired(){const e=Date.now();for(const[t,n]of this.cache.entries())e-n.timestamp>n.ttl&&this.cache.delete(t)}getStats(){return{size:this.cache.size,entries:Array.from(this.cache.keys())}}},a=function(){let e=null;return(...t)=>{e&&clearTimeout(e),e=setTimeout(()=>{((e,t)=>{"undefined"!=typeof window&&localStorage.setItem(e,t)})(...t)},300)}}(),i=e=>({id:e.id,email:e.email,firstName:e.first_name||e.firstName||"",lastName:e.last_name||e.lastName||"",avatar:e.avatar_url||e.avatar,mfaEnabled:e.mfa_enabled??e.mfaEnabled??0,emailVerified:e.email_verified??e.emailVerified??0,passwordUpdatedAt:e.password_updated_at||e.passwordUpdatedAt,settings:e.settings||{},xp:e.xp||0,level:e.level||1,next_level_xp:e.next_level_xp||e.next_level_xp||4,username:e.username,usernameLastChangedAt:e.username_last_changed_at||e.usernameLastChangedAt,createdAt:e.created_at||e.createdAt,updatedAt:e.updated_at||e.updatedAt||(new Date).toISOString()}),r={currentUser:e.ref(null),currentSession:e.ref(null),loadingStates:e.ref({initializing:1,signingIn:0,signingUp:0,signingOut:0,refreshingToken:0,sendingMfaEmail:0,verifyingMfa:0,loadingProfile:0}),isInitialized:e.ref(0),mfaRequired:e.ref(0),mfaSessionId:e.ref(null),availableMfaMethods:e.ref([])};let o=null,s=null;exports.useStrandsAuth=function(){const{getUrl:c}=t.useStrandsConfig(),{fetch:d,clear:l,invalidate:h}={fetch:n.fetch.bind(n),clear:n.clear.bind(n),invalidate:n.invalidate.bind(n),getStats:n.getStats.bind(n)},{currentUser:u,currentSession:f,loadingStates:w,isInitialized:y,mfaRequired:g,mfaSessionId:m,availableMfaMethods:p}=r,S=e.computed(()=>w.value.initializing),_=e.computed(()=>w.value.signingIn),T=e.computed(()=>w.value.signingUp),E=e.computed(()=>w.value.signingOut),v=e.computed(()=>w.value.refreshingToken),O=e.computed(()=>w.value.sendingMfaEmail),A=e.computed(()=>w.value.verifyingMfa);e.computed(()=>w.value.loadingProfile);const $=e.computed(()=>w.value.signingIn||w.value.signingUp||w.value.signingOut||w.value.refreshingToken||w.value.sendingMfaEmail||w.value.verifyingMfa||w.value.loadingProfile),N=e.computed(()=>w.value.initializing||$.value),b=e.computed(()=>{const e=w.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..."}),k=()=>{const e={};return f.value?.accessToken&&(e.Authorization=`Bearer ${f.value.accessToken}`),f.value?.refreshToken&&(e["x-refresh-token"]=f.value.refreshToken),e},C=e.computed(()=>null!==u.value),J=async()=>{w.value.signingOut=1;try{U(),s=null,l(),u.value=null,f.value=null,g.value=0,m.value=null,p.value=[],"undefined"!=typeof window&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}finally{w.value.signingOut=0}},P=async()=>{if(!f.value?.refreshToken)return 0;if(s)return await s;s=(async()=>{w.value.refreshingToken=1;try{const e=await fetch(c("refresh"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:f.value.refreshToken})});if(!e.ok){if(401===e.status)return await J(),0;throw new Error(`Token refresh failed: ${e.status} ${e.statusText}`)}const t=await e.json();t.user&&(u.value=i(t.user),u.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value)));const n={accessToken:t.access_token,refreshToken:t.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:t.user?.id||u.value?.id};return f.value=n,"undefined"!=typeof window&&localStorage.setItem("strands_auth_session",JSON.stringify(n)),M(),h(`sessions:${f.value.accessToken.slice(0,20)}`),1}catch(e){return await J(),0}finally{w.value.refreshingToken=0}})();const e=await s;return s=null,e},F=async e=>{try{e.user&&(u.value=i(e.user));const t={accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:u.value?.id||e.user?.id};f.value=t,"undefined"!=typeof window&&(localStorage.setItem("strands_auth_session",JSON.stringify(t)),u.value&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value))),M()}catch(t){}},M=()=>{if(o&&clearTimeout(o),!f.value)return;if("undefined"!=typeof document&&"hidden"===document.visibilityState)return;const e=new Date,t=f.value.expiresAt.getTime()-e.getTime()-6e4;t<=0?P():o=setTimeout(async()=>{"undefined"!=typeof document&&"visible"!==document.visibilityState||await P()&&M()},t)},U=()=>{o&&(clearTimeout(o),o=null)},D=async()=>{if(!y.value){w.value.initializing=1;try{if("undefined"!=typeof window){const t=localStorage.getItem("strands_auth_session"),n=localStorage.getItem("strands_auth_user");if(t&&n)try{const e=JSON.parse(t),a=JSON.parse(n);e.expiresAt=new Date(e.expiresAt),e.expiresAt>new Date?(f.value=e,u.value=a,M()):(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}catch(e){localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")}}y.value=1,await new Promise(e=>setTimeout(e,50))}catch(e){}finally{w.value.initializing=0}}};"undefined"!=typeof document&&document.addEventListener("visibilitychange",()=>{"visible"===document.visibilityState&&f.value?M():"hidden"===document.visibilityState&&U()});const I=()=>{U(),l(),"undefined"!=typeof document&&document.removeEventListener("visibilitychange",()=>{})};try{e.onUnmounted(I)}catch(j){}return y.value||D(),{user:e.computed(()=>u.value),currentUser:e.computed(()=>u.value),currentSession:e.computed(()=>f.value),isAuthenticated:C,isLoading:e.computed(()=>N.value||!y.value),loading:e.computed(()=>$.value),loadingMessage:b,isInitializing:S,isSigningIn:_,isSigningUp:T,isSigningOut:E,isRefreshingToken:v,isSendingMfaEmail:O,isVerifyingMfa:A,mfaRequired:e.computed(()=>g.value),mfaSessionId:e.computed(()=>m.value),availableMfaMethods:e.computed(()=>p.value),signIn:async e=>{w.value.signingIn=1;try{g.value=0,m.value=null,p.value=[];const t={"Content-Type":"application/json"};"undefined"!=typeof window&&window.location&&(t.Origin=window.location.origin);const n=await fetch(c("signIn"),{method:"POST",headers:t,body:JSON.stringify(e)});if(!n.ok)throw 401===n.status?new Error("Invalid email or password"):403===n.status?new Error("Please verify your email address before signing in"):new Error(`Sign in failed: ${n.status} ${n.statusText}`);const a=await n.json();if(a.mfa_required){g.value=1,m.value=a.mfa_session_id||null;const e=(a.available_mfa_methods||[]).map(e=>{let t=`${e.device_type.charAt(0).toUpperCase()+e.device_type.slice(1)} Authentication`;return"hardware"===e.device_type?t=e.device_name||"Security Key":"totp"===e.device_type?t=e.device_name||"Authenticator App":"email"===e.device_type&&(t=e.device_name||"Email Verification"),{id:e.device_id,device_type:e.device_type,device_name:e.device_name||t,is_active:1,created_at:(new Date).toISOString(),last_used_at:e.last_used_at,credential_id:e.credential_id,device_info:e.device_info}});return p.value=e,w.value.signingIn=0,a}return await F(a),a}catch(t){throw t}finally{w.value.signingIn=0}},signUp:async e=>{w.value.signingUp=1;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{w.value.signingUp=0}},signOut:J,refreshToken:P,fetchProfile:async()=>{const e=`profile:${f.value.accessToken.slice(0,20)}`;w.value.loadingProfile=1;try{return await d(e,async()=>{const e=await fetch(c("profile"),{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value?.accessToken}`}});if(!e.ok)throw 401===e.status?new Error("Authentication expired. Please sign in again."):new Error(`Failed to fetch profile: ${e.status} ${e.statusText}`);const t=await e.json();return u.value=i(t),u.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value)),u.value})}finally{w.value.loadingProfile=0}},updateProfile:async e=>{w.value.loadingProfile=1;try{const t=await fetch(c("profile"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({first_name:e.firstName,last_name:e.lastName})});if(!t.ok)throw 401===t.status?new Error("Authentication expired. Please sign in again."):new Error(`Profile update failed: ${t.status} ${t.statusText}`);const n=await t.json();return u.value=i(n),u.value&&a("strands_auth_user",JSON.stringify(u.value)),u.value}finally{w.value.loadingProfile=0}},updateUserSettings:async e=>{w.value.loadingProfile=1;try{const t=await fetch(c("settings"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({settings:e})});if(!t.ok)throw 401===t.status?new Error("Authentication expired. Please sign in again."):new Error(`Settings update failed: ${t.status} ${t.statusText}`);const n=await t.json();return u.value=i(n),u.value&&a("strands_auth_user",JSON.stringify(u.value)),u.value}finally{w.value.loadingProfile=0}},changeEmail:async(e,t)=>{w.value.loadingProfile=1;try{const n=await fetch(c("changeEmail"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({new_email:e,password:t})});if(!n.ok){if(401===n.status)throw new Error("Authentication expired. Please sign in again.");{const e=await n.json().catch(()=>({}));throw new Error(e.message||`Email change failed: ${n.status} ${n.statusText}`)}}const a=await n.json();return u.value&&(u.value={...u.value,email:e,emailVerified:0,updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value))),a}finally{w.value.loadingProfile=0}},changeUsername:async e=>{w.value.loadingProfile=1;try{const t=await fetch(c("changeUsername"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({username:e})});if(!t.ok){const e=await t.json().catch(()=>({}));if(409===t.status)throw new Error("Username is already taken");if(e.cooldown_end)throw new Error(`You can only change your username once every 30 days. You can change it again on ${new Date(e.cooldown_end).toLocaleDateString()}`);throw new Error(e.message||`Username change failed: ${t.status} ${t.statusText}`)}const n=await t.json();return u.value&&(u.value={...u.value,username:e,usernameLastChangedAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value))),n}finally{w.value.loadingProfile=0}},getUsernameCooldown:async()=>{const e=await fetch(c("usernameCooldown"),{method:"GET",headers:{Authorization:`Bearer ${f.value.accessToken}`}});if(!e.ok)throw new Error(`Failed to get username cooldown: ${e.status} ${e.statusText}`);return e.json()},checkUsernameAvailability:async e=>{const t=c("checkUsernameAvailability").replace("{username}",encodeURIComponent(e)),n=await fetch(t,{method:"GET",headers:{"Content-Type":"application/json"}});if(!n.ok)throw new Error(`Failed to check username availability: ${n.status} ${n.statusText}`);return n.json()},getUserSessions:async()=>{const e=`sessions:${f.value?.accessToken?.slice(0,20)||"no-token"}`;try{return await d(e,async()=>{const e=k(),t=await fetch(c("sessions"),{method:"GET",headers:e});if(!t.ok)throw await t.text(),new Error(`Failed to get user sessions: ${t.status} ${t.statusText}`);return t.json()},12e4)}catch(t){throw t}},getSessionStats:async()=>{const e=await fetch(c("sessionsStats"),{method:"GET",headers:k()});if(!e.ok)throw new Error(`Failed to get session stats: ${e.status} ${e.statusText}`);return e.json()},revokeSession:async e=>{const t=c("sessionRevoke").replace("{session_id}",encodeURIComponent(e)),n=await fetch(t,{method:"POST",headers:k()});if(!n.ok)throw new Error(`Failed to revoke session: ${n.status} ${n.statusText}`);return 200===n.status},revokeAllOtherSessions:async()=>{const e=await fetch(c("sessionsRevokeAll"),{method:"POST",headers:k()});if(!e.ok)throw new Error(`Failed to revoke all other sessions: ${e.status} ${e.statusText}`);return 200===e.status},initialize:D,setAuthData:F,verifyMfa:async(e,t,n=0)=>{if(!m.value)throw new Error("No MFA session available");w.value.verifyingMfa=1;try{const a=c(n?"mfaBackupCodeVerify":"mfaSigninVerify"),i=n?{mfa_session_id:m.value,backup_code:t}:{mfa_session_id:m.value,device_id:e,code:t},r=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!r.ok){const e=await r.text();let t="MFA verification failed";try{const n=JSON.parse(e);t=n.message||n.error||e}catch{t=e||"MFA verification failed"}throw new Error(t)}const o=await r.json();return g.value=0,m.value=null,p.value=[],await F(o),o}finally{w.value.verifyingMfa=0}},sendMfaEmailCode:async e=>{if(!m.value)throw new Error("No MFA session available");w.value.sendingMfaEmail=1;try{const t=await fetch(c("mfaSigninSendEmail"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:m.value,device_id:e})});if(!t.ok){const e=await t.text();let n="Failed to send MFA email code";try{const t=JSON.parse(e);n=t.message||t.error||e}catch{n=e||"Failed to send MFA email code"}throw new Error(n)}return await t.json()}finally{w.value.sendingMfaEmail=0}},getMfaWebAuthnChallenge:async e=>{if(!m.value)throw new Error("No MFA session available");const t=await fetch(c("mfaWebAuthnChallenge"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:m.value,device_id:e})});if(!t.ok){const e=await t.text();let n="Failed to get WebAuthn challenge";try{const t=JSON.parse(e);n=t.message||t.error||e}catch{n=e||n}throw new Error(n)}return t.json()},registerHardwareKey:async(e,t,n="hardware")=>{const a=await fetch(c("mfaHardwareStartRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({device_name:e,device_type:n})});if(!a.ok){const e=await a.text();let t="Failed to start hardware key registration";try{const n=JSON.parse(e);t=n.message||n.error||e}catch{t=e||"Failed to start hardware key registration"}throw new Error(t)}return a.json()},completeHardwareKeyRegistration:async(e,t,n)=>{const a=await fetch(c("mfaHardwareCompleteRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({device_id:e,credential:t})});if(!a.ok){const e=await a.text();let t="Failed to complete hardware key registration";try{const n=JSON.parse(e);t=n.message||n.error||e}catch{t=e||"Failed to complete hardware key registration"}throw new Error(t)}return a.json()},startTokenRefreshTimer:M,stopTokenRefreshTimer:U,getAuthHeaders:k,forceReInit:()=>{y.value=0,w.value.initializing=1,D()}}};
|
|
1
|
+
"use strict";const e=require("vue"),t=require("./useStrandsConfig-B6uW6Zkd.cjs.js"),a=new class{cache=new Map;DEFAULT_TTL=3e5;async fetch(e,t,a=this.DEFAULT_TTL){const n=Date.now(),i=this.cache.get(e);if(i&&n-i.timestamp<i.ttl)return i.promise;this.cleanExpired();const r=t().finally(()=>{setTimeout(()=>{this.cache.delete(e)},a)});return this.cache.set(e,{promise:r,timestamp:n,ttl:a}),r}clear(){this.cache.clear()}invalidate(e){this.cache.delete(e)}cleanExpired(){const e=Date.now();for(const[t,a]of this.cache.entries())e-a.timestamp>a.ttl&&this.cache.delete(t)}getStats(){return{size:this.cache.size,entries:Array.from(this.cache.keys())}}},n=function(){let e=null;return(...t)=>{e&&clearTimeout(e),e=setTimeout(()=>{((e,t)=>{"undefined"!=typeof window&&localStorage.setItem(e,t)})(...t)},300)}}(),i=e=>({id:e.id,email:e.email,firstName:e.first_name||e.firstName||"",lastName:e.last_name||e.lastName||"",avatar:e.avatar_url||e.avatar,mfaEnabled:e.mfa_enabled??e.mfaEnabled??0,emailVerified:e.email_verified??e.emailVerified??0,passwordUpdatedAt:e.password_updated_at||e.passwordUpdatedAt,settings:e.settings||{},xp:e.xp||0,level:e.level||1,next_level_xp:e.next_level_xp||e.next_level_xp||4,username:e.username,usernameLastChangedAt:e.username_last_changed_at||e.usernameLastChangedAt,createdAt:e.created_at||e.createdAt,updatedAt:e.updated_at||e.updatedAt||(new Date).toISOString()}),r={currentUser:e.ref(null),currentSession:e.ref(null),loadingStates:e.ref({initializing:1,signingIn:0,signingUp:0,signingOut:0,refreshingToken:0,sendingMfaEmail:0,verifyingMfa:0,loadingProfile:0}),isInitialized:e.ref(0),mfaRequired:e.ref(0),mfaSessionId:e.ref(null),availableMfaMethods:e.ref([])};let o=null,s=null;exports.useStrandsAuth=function(){const{getUrl:c}=t.useStrandsConfig(),{fetch:d,clear:l,invalidate:h}={fetch:a.fetch.bind(a),clear:a.clear.bind(a),invalidate:a.invalidate.bind(a),getStats:a.getStats.bind(a)},{currentUser:u,currentSession:f,loadingStates:w,isInitialized:y,mfaRequired:g,mfaSessionId:m,availableMfaMethods:p}=r,S=e.computed(()=>w.value.initializing),_=e.computed(()=>w.value.signingIn),T=e.computed(()=>w.value.signingUp),E=e.computed(()=>w.value.signingOut),v=e.computed(()=>w.value.refreshingToken),O=e.computed(()=>w.value.sendingMfaEmail),A=e.computed(()=>w.value.verifyingMfa);e.computed(()=>w.value.loadingProfile);const $=e.computed(()=>w.value.signingIn||w.value.signingUp||w.value.signingOut||w.value.refreshingToken||w.value.sendingMfaEmail||w.value.verifyingMfa||w.value.loadingProfile),N=e.computed(()=>w.value.initializing||$.value),b=e.computed(()=>{const e=w.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..."}),k=()=>{const e={};return f.value?.accessToken&&(e.Authorization=`Bearer ${f.value.accessToken}`),f.value?.refreshToken&&(e["x-refresh-token"]=f.value.refreshToken),e},C=e.computed(()=>null!==u.value),J=async()=>{w.value.signingOut=1;try{U(),s=null,l(),u.value=null,f.value=null,g.value=0,m.value=null,p.value=[],"undefined"!=typeof window&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}finally{w.value.signingOut=0}},P=async()=>{if(!f.value?.refreshToken)return 0;if(s)return await s;s=(async()=>{w.value.refreshingToken=1;try{const e=await fetch(c("refresh"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:f.value.refreshToken})});if(!e.ok){if(401===e.status)return await J(),0;throw new Error(`Token refresh failed: ${e.status} ${e.statusText}`)}const t=await e.json();t.user&&(u.value=i(t.user),u.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value)));const a={accessToken:t.access_token,refreshToken:t.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:t.user?.id||u.value?.id};return f.value=a,"undefined"!=typeof window&&localStorage.setItem("strands_auth_session",JSON.stringify(a)),M(),h(`sessions:${f.value.accessToken.slice(0,20)}`),1}catch(e){return await J(),0}finally{w.value.refreshingToken=0}})();const e=await s;return s=null,e},F=async e=>{try{e.user&&(u.value=i(e.user));const t={accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:u.value?.id||e.user?.id};f.value=t,"undefined"!=typeof window&&(localStorage.setItem("strands_auth_session",JSON.stringify(t)),u.value&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value))),M()}catch(t){}},M=()=>{if(o&&clearTimeout(o),!f.value)return;if("undefined"!=typeof document&&"hidden"===document.visibilityState)return;const e=new Date,t=f.value.expiresAt.getTime()-e.getTime()-6e4;t<=0?P():o=setTimeout(async()=>{"undefined"!=typeof document&&"visible"!==document.visibilityState||await P()&&M()},t)},U=()=>{o&&(clearTimeout(o),o=null)},D=async()=>{if(!y.value){w.value.initializing=1;try{if("undefined"!=typeof window){const t=localStorage.getItem("strands_auth_session"),a=localStorage.getItem("strands_auth_user");if(t&&a)try{const e=JSON.parse(t),n=JSON.parse(a);e.expiresAt=new Date(e.expiresAt),e.expiresAt<=new Date&&e.refreshToken?(f.value=e,u.value=n,await P()||(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"),f.value=null,u.value=null)):e.expiresAt>new Date?(f.value=e,u.value=n,M()):(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}catch(e){localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")}}y.value=1,await new Promise(e=>setTimeout(e,50))}catch(e){}finally{w.value.initializing=0}}};"undefined"!=typeof document&&document.addEventListener("visibilitychange",()=>{"visible"===document.visibilityState&&f.value?M():"hidden"===document.visibilityState&&U()});const I=()=>{U(),l(),"undefined"!=typeof document&&document.removeEventListener("visibilitychange",()=>{})};try{e.onUnmounted(I)}catch(j){}return y.value||D(),{user:e.computed(()=>u.value),currentUser:e.computed(()=>u.value),currentSession:e.computed(()=>f.value),isAuthenticated:C,isLoading:e.computed(()=>N.value||!y.value),loading:e.computed(()=>$.value),loadingMessage:b,isInitializing:S,isSigningIn:_,isSigningUp:T,isSigningOut:E,isRefreshingToken:v,isSendingMfaEmail:O,isVerifyingMfa:A,mfaRequired:e.computed(()=>g.value),mfaSessionId:e.computed(()=>m.value),availableMfaMethods:e.computed(()=>p.value),signIn:async e=>{w.value.signingIn=1;try{g.value=0,m.value=null,p.value=[];const t={"Content-Type":"application/json"};"undefined"!=typeof window&&window.location&&(t.Origin=window.location.origin);const a=await fetch(c("signIn"),{method:"POST",headers:t,body:JSON.stringify(e)});if(!a.ok)throw 401===a.status?new Error("Invalid email or password"):403===a.status?new Error("Please verify your email address before signing in"):new Error(`Sign in failed: ${a.status} ${a.statusText}`);const n=await a.json();if(n.mfa_required){g.value=1,m.value=n.mfa_session_id||null;const e=(n.available_mfa_methods||[]).map(e=>{let t=`${e.device_type.charAt(0).toUpperCase()+e.device_type.slice(1)} Authentication`;return"hardware"===e.device_type?t=e.device_name||"Security Key":"totp"===e.device_type?t=e.device_name||"Authenticator App":"email"===e.device_type&&(t=e.device_name||"Email Verification"),{id:e.device_id,device_type:e.device_type,device_name:e.device_name||t,is_active:1,created_at:(new Date).toISOString(),last_used_at:e.last_used_at,credential_id:e.credential_id,device_info:e.device_info}});return p.value=e,w.value.signingIn=0,n}return await F(n),n}catch(t){throw t}finally{w.value.signingIn=0}},signUp:async e=>{w.value.signingUp=1;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{w.value.signingUp=0}},signOut:J,refreshToken:P,fetchProfile:async()=>{const e=`profile:${f.value.accessToken.slice(0,20)}`;w.value.loadingProfile=1;try{return await d(e,async()=>{const e=await fetch(c("profile"),{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value?.accessToken}`}});if(!e.ok)throw 401===e.status?new Error("Authentication expired. Please sign in again."):new Error(`Failed to fetch profile: ${e.status} ${e.statusText}`);const t=await e.json();return u.value=i(t),u.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value)),u.value})}finally{w.value.loadingProfile=0}},updateProfile:async e=>{w.value.loadingProfile=1;try{const t=await fetch(c("profile"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({first_name:e.firstName,last_name:e.lastName})});if(!t.ok)throw 401===t.status?new Error("Authentication expired. Please sign in again."):new Error(`Profile update failed: ${t.status} ${t.statusText}`);const a=await t.json();return u.value=i(a),u.value&&n("strands_auth_user",JSON.stringify(u.value)),u.value}finally{w.value.loadingProfile=0}},updateUserSettings:async e=>{w.value.loadingProfile=1;try{const t=await fetch(c("settings"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({settings:e})});if(!t.ok)throw 401===t.status?new Error("Authentication expired. Please sign in again."):new Error(`Settings update failed: ${t.status} ${t.statusText}`);const a=await t.json();return u.value=i(a),u.value&&n("strands_auth_user",JSON.stringify(u.value)),u.value}finally{w.value.loadingProfile=0}},changeEmail:async(e,t)=>{w.value.loadingProfile=1;try{const a=await fetch(c("changeEmail"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({new_email:e,password:t})});if(!a.ok){if(401===a.status)throw new Error("Authentication expired. Please sign in again.");{const e=await a.json().catch(()=>({}));throw new Error(e.message||`Email change failed: ${a.status} ${a.statusText}`)}}const n=await a.json();return u.value&&(u.value={...u.value,email:e,emailVerified:0,updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value))),n}finally{w.value.loadingProfile=0}},changeUsername:async e=>{w.value.loadingProfile=1;try{const t=await fetch(c("changeUsername"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({username:e})});if(!t.ok){const e=await t.json().catch(()=>({}));if(409===t.status)throw new Error("Username is already taken");if(e.cooldown_end)throw new Error(`You can only change your username once every 30 days. You can change it again on ${new Date(e.cooldown_end).toLocaleDateString()}`);throw new Error(e.message||`Username change failed: ${t.status} ${t.statusText}`)}const a=await t.json();return u.value&&(u.value={...u.value,username:e,usernameLastChangedAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(u.value))),a}finally{w.value.loadingProfile=0}},getUsernameCooldown:async()=>{const e=await fetch(c("usernameCooldown"),{method:"GET",headers:{Authorization:`Bearer ${f.value.accessToken}`}});if(!e.ok)throw new Error(`Failed to get username cooldown: ${e.status} ${e.statusText}`);return e.json()},checkUsernameAvailability:async e=>{const t=c("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()},getUserSessions:async()=>{const e=`sessions:${f.value?.accessToken?.slice(0,20)||"no-token"}`;try{return await d(e,async()=>{const e=k(),t=await fetch(c("sessions"),{method:"GET",headers:e});if(!t.ok)throw await t.text(),new Error(`Failed to get user sessions: ${t.status} ${t.statusText}`);return t.json()},12e4)}catch(t){throw t}},getSessionStats:async()=>{const e=await fetch(c("sessionsStats"),{method:"GET",headers:k()});if(!e.ok)throw new Error(`Failed to get session stats: ${e.status} ${e.statusText}`);return e.json()},revokeSession:async e=>{const t=c("sessionRevoke").replace("{session_id}",encodeURIComponent(e)),a=await fetch(t,{method:"POST",headers:k()});if(!a.ok)throw new Error(`Failed to revoke session: ${a.status} ${a.statusText}`);return 200===a.status},revokeAllOtherSessions:async()=>{const e=await fetch(c("sessionsRevokeAll"),{method:"POST",headers:k()});if(!e.ok)throw new Error(`Failed to revoke all other sessions: ${e.status} ${e.statusText}`);return 200===e.status},initialize:D,setAuthData:F,verifyMfa:async(e,t,a=0)=>{if(!m.value)throw new Error("No MFA session available");w.value.verifyingMfa=1;try{const n=c(a?"mfaBackupCodeVerify":"mfaSigninVerify"),i=a?{mfa_session_id:m.value,backup_code:t}:{mfa_session_id:m.value,device_id:e,code:t},r=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!r.ok){const e=await r.text();let t="MFA verification failed";try{const a=JSON.parse(e);t=a.message||a.error||e}catch{t=e||"MFA verification failed"}throw new Error(t)}const o=await r.json();return g.value=0,m.value=null,p.value=[],await F(o),o}finally{w.value.verifyingMfa=0}},sendMfaEmailCode:async e=>{if(!m.value)throw new Error("No MFA session available");w.value.sendingMfaEmail=1;try{const t=await fetch(c("mfaSigninSendEmail"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:m.value,device_id:e})});if(!t.ok){const e=await t.text();let a="Failed to send MFA email code";try{const t=JSON.parse(e);a=t.message||t.error||e}catch{a=e||"Failed to send MFA email code"}throw new Error(a)}return await t.json()}finally{w.value.sendingMfaEmail=0}},getMfaWebAuthnChallenge:async e=>{if(!m.value)throw new Error("No MFA session available");const t=await fetch(c("mfaWebAuthnChallenge"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:m.value,device_id:e})});if(!t.ok){const e=await t.text();let a="Failed to get WebAuthn challenge";try{const t=JSON.parse(e);a=t.message||t.error||e}catch{a=e||a}throw new Error(a)}return t.json()},registerHardwareKey:async(e,t,a="hardware")=>{const n=await fetch(c("mfaHardwareStartRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({device_name:e,device_type:a})});if(!n.ok){const e=await n.text();let t="Failed to start hardware key registration";try{const a=JSON.parse(e);t=a.message||a.error||e}catch{t=e||"Failed to start hardware key registration"}throw new Error(t)}return n.json()},completeHardwareKeyRegistration:async(e,t,a)=>{const n=await fetch(c("mfaHardwareCompleteRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.value.accessToken}`},body:JSON.stringify({device_id:e,credential:t})});if(!n.ok){const e=await n.text();let t="Failed to complete hardware key registration";try{const a=JSON.parse(e);t=a.message||a.error||e}catch{t=e||"Failed to complete hardware key registration"}throw new Error(t)}return n.json()},startTokenRefreshTimer:M,stopTokenRefreshTimer:U,getAuthHeaders:k,forceReInit:()=>{y.value=0,w.value.initializing=1,D()}}};
|