@strands.gg/accui 2.2.0 → 2.2.2
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/module.cjs.js +1 -1
- package/dist/nuxt/module.es.js +41 -0
- package/dist/nuxt/runtime/composables/useStrandsAuth.cjs.js +1 -1
- package/dist/nuxt/runtime/composables/useStrandsAuth.es.js +1 -1
- 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-v4/module.cjs.js +1 -1
- package/dist/nuxt-v4/module.es.js +41 -0
- package/dist/nuxt-v4/runtime/composables/useStrandsAuth.cjs.js +1 -1
- package/dist/nuxt-v4/runtime/composables/useStrandsAuth.es.js +1 -1
- package/dist/nuxt-v4/runtime/plugin.client.cjs.js +1 -1
- package/dist/nuxt-v4/runtime/plugin.client.es.js +1 -1
- package/dist/nuxt-v4/runtime/plugin.server.cjs.js +1 -1
- package/dist/nuxt-v4/runtime/plugin.server.es.js +1 -1
- package/dist/strands-auth-ui.cjs.js +1 -1
- package/dist/strands-auth-ui.es.js +8 -10
- package/dist/{useStrandsAuth-Ce_6sRDL.es.js → useStrandsAuth-B91u7n_t.es.js} +1 -1
- package/dist/{useStrandsAuth-s1xHo4S-.cjs.js → useStrandsAuth-C4UY4aTP.cjs.js} +1 -1
- package/dist/useStrandsConfig-B6uW6Zkd.cjs.js +1 -0
- package/dist/{useStrandsConfig-Dkr8gpzR.es.js → useStrandsConfig-C3gBJK6y.es.js} +27 -11
- package/package.json +1 -1
- package/dist/useStrandsConfig-CzIbm2Z6.cjs.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineComponent, computed, createElementBlock, openBlock, createElementVNode, normalizeClass, createCommentVNode, toDisplayString, renderSlot, createTextVNode, h, useSlots, normalizeStyle, Fragment, createBlock, unref, resolveDynamicComponent, ref, mergeProps, withCtx, onMounted, nextTick, toRefs, watch, renderList, reactive, withModifiers, createStaticVNode, createVNode, withDirectives, vModelText, onUnmounted, Teleport, Transition, createSlots, vModelSelect, onBeforeUnmount, withKeys, isMemoSame, provide, inject, getCurrentInstance } from "vue";
|
|
2
|
-
import { u as useStrandsConfig, p as provideStrandsConfig } from "./useStrandsConfig-
|
|
3
|
-
import { s } from "./useStrandsConfig-
|
|
4
|
-
import { u as useStrandsAuth } from "./useStrandsAuth-
|
|
2
|
+
import { u as useStrandsConfig, p as provideStrandsConfig } from "./useStrandsConfig-C3gBJK6y.es.js";
|
|
3
|
+
import { s } from "./useStrandsConfig-C3gBJK6y.es.js";
|
|
4
|
+
import { u as useStrandsAuth } from "./useStrandsAuth-B91u7n_t.es.js";
|
|
5
5
|
const _hoisted_1$G = { class: "accui-component-scope" };
|
|
6
6
|
const _hoisted_2$z = { class: "alert-content" };
|
|
7
7
|
const _hoisted_3$y = { class: "alert-icon-container" };
|
|
@@ -13202,7 +13202,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
13202
13202
|
])) : signedOutOrInverted.value ? (openBlock(), createElementBlock("div", _hoisted_2$5, [
|
|
13203
13203
|
renderSlot(_ctx.$slots, "fallback", { signIn }, () => [
|
|
13204
13204
|
createElementVNode("div", { class: "signed-in-fallback" }, [
|
|
13205
|
-
_cache[0] || (_cache[0] = createStaticVNode('<div class="signed-in-icon-container" data-v-
|
|
13205
|
+
_cache[0] || (_cache[0] = createStaticVNode('<div class="signed-in-icon-container" data-v-5f545a2c><svg class="signed-in-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" data-v-5f545a2c><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" data-v-5f545a2c></path></svg></div><h3 class="signed-in-title" data-v-5f545a2c>Sign in required</h3><p class="signed-in-subtitle" data-v-5f545a2c>You need to be signed in to access this content.</p>', 3)),
|
|
13206
13206
|
createElementVNode("button", {
|
|
13207
13207
|
onClick: signIn,
|
|
13208
13208
|
class: "signed-in-button"
|
|
@@ -13212,8 +13212,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
13212
13212
|
])) : showLoading.value ? (openBlock(), createElementBlock("div", _hoisted_3$5, [
|
|
13213
13213
|
renderSlot(_ctx.$slots, "loading", {}, () => [
|
|
13214
13214
|
createVNode(unref(StrandsUiLoader), {
|
|
13215
|
-
size:
|
|
13216
|
-
text: "Checking authentication...",
|
|
13215
|
+
size: 30,
|
|
13217
13216
|
variant: "circle",
|
|
13218
13217
|
"show-particles": true
|
|
13219
13218
|
})
|
|
@@ -13222,7 +13221,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
13222
13221
|
};
|
|
13223
13222
|
}
|
|
13224
13223
|
});
|
|
13225
|
-
const SignedIn = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-
|
|
13224
|
+
const SignedIn = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-5f545a2c"]]);
|
|
13226
13225
|
const _hoisted_1$6 = {
|
|
13227
13226
|
key: 0,
|
|
13228
13227
|
class: "animate-fade-in"
|
|
@@ -13291,8 +13290,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
|
13291
13290
|
])) : unref(isLoading) ? (openBlock(), createElementBlock("div", _hoisted_5$3, [
|
|
13292
13291
|
renderSlot(_ctx.$slots, "loading", {}, () => [
|
|
13293
13292
|
createVNode(unref(StrandsUiLoader), {
|
|
13294
|
-
size:
|
|
13295
|
-
text: "Checking authentication...",
|
|
13293
|
+
size: 30,
|
|
13296
13294
|
variant: "circle",
|
|
13297
13295
|
"show-particles": true
|
|
13298
13296
|
})
|
|
@@ -13301,7 +13299,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
|
13301
13299
|
};
|
|
13302
13300
|
}
|
|
13303
13301
|
});
|
|
13304
|
-
const SignedOut = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-
|
|
13302
|
+
const SignedOut = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-76829d00"]]);
|
|
13305
13303
|
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
13306
13304
|
__name: "StrandsConfigProvider",
|
|
13307
13305
|
props: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, ref, onUnmounted } from "vue";
|
|
2
|
-
import { u as useStrandsConfig } from "./useStrandsConfig-
|
|
2
|
+
import { u as useStrandsConfig } from "./useStrandsConfig-C3gBJK6y.es.js";
|
|
3
3
|
class RequestCache {
|
|
4
4
|
cache = /* @__PURE__ */ new Map();
|
|
5
5
|
DEFAULT_TTL = 5 * 60 * 1e3;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("vue"),t=require("./useStrandsConfig-CzIbm2Z6.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"),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()}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const e=require("vue"),i={baseUrl:"https://your-api.example.com",accentColor:"#EA00A8",redirectUrl:"/",onSignInUrl:"/dashboard",onSignOutUrl:"/",autoRefresh:1,refreshInterval:4,protectedRoutes:[],guestOnlyRoutes:["/auth","/login","/register"],devMode:0,styles:1,endpoints:{},useSquircle:1},a=Symbol("strands-config"),s=e.ref(null);function t(e){if("undefined"==typeof window||!document.documentElement)return;if("undefined"!=typeof CSS&&CSS.registerProperty)try{CSS.registerProperty({name:"--strands-accent",syntax:"<color>",inherits:1,initialValue:e})}catch(a){}document.documentElement.style.setProperty("--strands-accent",e),document.documentElement.style.setProperty("--accui-strands-accent",e);const i={"--accui-strands-50":`color-mix(in srgb, ${e} 10%, white)`,"--accui-strands-100":`color-mix(in srgb, ${e} 20%, white)`,"--accui-strands-200":`color-mix(in srgb, ${e} 30%, white)`,"--accui-strands-300":`color-mix(in srgb, ${e} 40%, white)`,"--accui-strands-400":`color-mix(in srgb, ${e} 70%, white)`,"--accui-strands-500":e,"--accui-strands-600":`color-mix(in srgb, ${e} 85%, black)`,"--accui-strands-700":`color-mix(in srgb, ${e} 70%, black)`,"--accui-strands-800":`color-mix(in srgb, ${e} 55%, black)`,"--accui-strands-900":`color-mix(in srgb, ${e} 40%, black)`,"--accui-strands-950":`color-mix(in srgb, ${e} 25%, black)`};for(const[s,t]of Object.entries(i))document.documentElement.style.setProperty(s,t)}exports.STRANDS_AUTH_DEFAULTS=i,exports.provideStrandsConfig=function(i){if(s.value=i,"undefined"!=typeof window&&document.documentElement){const e=void 0!==i.useSquircle?i.useSquircle:1;document.documentElement.style.setProperty("--strands-allow-squircle",e?"1":"0"),i.accentColor&&t(i.accentColor)}try{e.provide(a,i)}catch(n){}},exports.setStrandsConfig=function(e){if(s.value=e,"undefined"!=typeof window&&document.documentElement){const i=void 0!==e.useSquircle?e.useSquircle:1;document.documentElement.style.setProperty("--strands-allow-squircle",i?"1":"0"),e.accentColor&&t(e.accentColor)}},exports.useStrandsConfig=function(t){const n=e.inject(a,null);let r=null;try{if("undefined"!=typeof window)if(window.__STRANDS_CONFIG__)r=window.__STRANDS_CONFIG__;else if(window.__NUXT__){const e=window.__NUXT__;r=e?.config?.public?.strandsAuth||e?.public?.strandsAuth||e?.strandsAuth}}catch(u){}const o=e.computed(()=>{const e={...i,...t||{},...n||{},...s.value||{},...r||{}};if(e.baseUrl,"undefined"!=typeof window&&document.documentElement){const i=void 0!==e.useSquircle?e.useSquircle:1;document.documentElement.style.setProperty("--strands-allow-squircle",i?"1":"0"),e.accentColor&&document.documentElement.style.setProperty("--strands-accent",e.accentColor)}return e}),c=e.computed(()=>{const e=o.value.endpoints||{};return{signIn:e.signIn||"/api/v1/auth/sign-in",signUp:e.signUp||"/api/v1/auth/sign-up",signOut:e.signOut||"/api/v1/auth/sign-out",refresh:e.refresh||"/api/v1/auth/refresh",passwordReset:e.passwordReset||"/api/v1/auth/password-reset",passwordResetConfirm:e.passwordResetConfirm||"/api/v1/auth/password-reset/confirm",completeRegistration:e.completeRegistration||"/api/v1/auth/complete-registration",profile:e.profile||"/api/v1/user/profile",verifyEmail:e.verifyEmail||"/api/v1/auth/verify-email",oauthProviders:e.oauthProviders||"/api/v1/oauth/providers",oauthProvider:e.oauthProvider||"/api/v1/oauth/providers/{provider_id}",changeEmail:e.changeEmail||"/api/v1/user/change-email",avatar:e.avatar||"/api/v1/user/avatar",settings:e.settings||"/api/v1/user/settings",changeUsername:e.changeUsername||"/api/v1/user/username",usernameCooldown:e.usernameCooldown||"/api/v1/user/username/cooldown",checkUsernameAvailability:e.checkUsernameAvailability||"/api/v1/username/{username}/available",mfaDevices:e.mfaDevices||"/api/v1/mfa/devices",mfaTotpSetup:e.mfaTotpSetup||"/api/v1/mfa/totp/setup",mfaTotpVerify:e.mfaTotpVerify||"/api/v1/mfa/totp/verify",mfaEmailSetup:e.mfaEmailSetup||"/api/v1/mfa/email/setup",mfaEmailSend:e.mfaEmailSend||"/api/v1/mfa/email/send",mfaEmailVerify:e.mfaEmailVerify||"/api/v1/mfa/email/verify",mfaDeviceDisable:e.mfaDeviceDisable||"/api/v1/mfa/device/disable",mfaBackupCodes:e.mfaBackupCodes||"/api/v1/mfa/backup-codes/regenerate",mfaHardwareStartRegistration:e.mfaHardwareStartRegistration||"/api/v1/mfa/hardware/start-registration",mfaHardwareCompleteRegistration:e.mfaHardwareCompleteRegistration||"/api/v1/mfa/hardware/complete-registration",mfaSigninSendEmail:e.mfaSigninSendEmail||"/api/v1/auth/mfa/email/send",mfaSigninVerify:e.mfaSigninVerify||"/api/v1/auth/mfa/verify",mfaBackupCodeVerify:e.mfaBackupCodeVerify||"/api/v1/auth/mfa/backup-code/verify",mfaWebAuthnChallenge:e.mfaWebAuthnChallenge||"/api/v1/auth/mfa/webauthn/challenge",sessions:e.sessions||"/api/v1/sessions",sessionsStats:e.sessionsStats||"/api/v1/sessions/stats",sessionRevoke:e.sessionRevoke||"/api/v1/sessions/{session_id}/revoke",sessionsRevokeAll:e.sessionsRevokeAll||"/api/v1/sessions/revoke-all"}});return{config:o,endpoints:c,getUrl:e=>{const i=o.value;if(!i.baseUrl)throw new Error("Base URL is required in configuration");let a;return a="string"==typeof e&&e in c.value?c.value[e]:"string"==typeof e?e:c.value[e],`${i.baseUrl.replace(/\/$/,"")}${a.startsWith("/")?a:`/${a}`}`},getSupportEmail:()=>o.value.supportEmail||null}};
|
|
@@ -60,19 +60,35 @@ const STRANDS_CONFIG_KEY = Symbol("strands-config");
|
|
|
60
60
|
const globalConfig = ref(null);
|
|
61
61
|
function generateColorShades(accentColor) {
|
|
62
62
|
if (typeof window === "undefined" || !document.documentElement) return;
|
|
63
|
+
if (typeof CSS !== "undefined" && CSS.registerProperty) {
|
|
64
|
+
try {
|
|
65
|
+
CSS.registerProperty({
|
|
66
|
+
name: "--strands-accent",
|
|
67
|
+
syntax: "<color>",
|
|
68
|
+
inherits: true,
|
|
69
|
+
initialValue: accentColor
|
|
70
|
+
});
|
|
71
|
+
} catch (e) {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
63
74
|
document.documentElement.style.setProperty("--strands-accent", accentColor);
|
|
64
75
|
document.documentElement.style.setProperty("--accui-strands-accent", accentColor);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
const shades = {
|
|
77
|
+
"--accui-strands-50": `color-mix(in srgb, ${accentColor} 10%, white)`,
|
|
78
|
+
"--accui-strands-100": `color-mix(in srgb, ${accentColor} 20%, white)`,
|
|
79
|
+
"--accui-strands-200": `color-mix(in srgb, ${accentColor} 30%, white)`,
|
|
80
|
+
"--accui-strands-300": `color-mix(in srgb, ${accentColor} 40%, white)`,
|
|
81
|
+
"--accui-strands-400": `color-mix(in srgb, ${accentColor} 70%, white)`,
|
|
82
|
+
"--accui-strands-500": accentColor,
|
|
83
|
+
"--accui-strands-600": `color-mix(in srgb, ${accentColor} 85%, black)`,
|
|
84
|
+
"--accui-strands-700": `color-mix(in srgb, ${accentColor} 70%, black)`,
|
|
85
|
+
"--accui-strands-800": `color-mix(in srgb, ${accentColor} 55%, black)`,
|
|
86
|
+
"--accui-strands-900": `color-mix(in srgb, ${accentColor} 40%, black)`,
|
|
87
|
+
"--accui-strands-950": `color-mix(in srgb, ${accentColor} 25%, black)`
|
|
88
|
+
};
|
|
89
|
+
for (const [property, value] of Object.entries(shades)) {
|
|
90
|
+
document.documentElement.style.setProperty(property, value);
|
|
91
|
+
}
|
|
76
92
|
}
|
|
77
93
|
function provideStrandsConfig(config) {
|
|
78
94
|
globalConfig.value = config;
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const e=require("vue"),i={baseUrl:"https://your-api.example.com",accentColor:"#EA00A8",redirectUrl:"/",onSignInUrl:"/dashboard",onSignOutUrl:"/",autoRefresh:1,refreshInterval:4,protectedRoutes:[],guestOnlyRoutes:["/auth","/login","/register"],devMode:0,styles:1,endpoints:{},useSquircle:1},a=Symbol("strands-config"),s=e.ref(null);function t(e){"undefined"!=typeof window&&document.documentElement&&(document.documentElement.style.setProperty("--strands-accent",e),document.documentElement.style.setProperty("--accui-strands-accent",e),document.documentElement.style.setProperty("--accui-strands-50",`color-mix(in srgb, ${e} 10%, white)`),document.documentElement.style.setProperty("--accui-strands-100",`color-mix(in srgb, ${e} 20%, white)`),document.documentElement.style.setProperty("--accui-strands-200",`color-mix(in srgb, ${e} 30%, white)`),document.documentElement.style.setProperty("--accui-strands-300",`color-mix(in srgb, ${e} 40%, white)`),document.documentElement.style.setProperty("--accui-strands-400",`color-mix(in srgb, ${e} 70%, white)`),document.documentElement.style.setProperty("--accui-strands-500",e),document.documentElement.style.setProperty("--accui-strands-600",`color-mix(in srgb, ${e} 85%, black)`),document.documentElement.style.setProperty("--accui-strands-700",`color-mix(in srgb, ${e} 70%, black)`),document.documentElement.style.setProperty("--accui-strands-800",`color-mix(in srgb, ${e} 55%, black)`),document.documentElement.style.setProperty("--accui-strands-900",`color-mix(in srgb, ${e} 40%, black)`),document.documentElement.style.setProperty("--accui-strands-950",`color-mix(in srgb, ${e} 25%, black)`))}exports.STRANDS_AUTH_DEFAULTS=i,exports.provideStrandsConfig=function(i){if(s.value=i,"undefined"!=typeof window&&document.documentElement){const e=void 0!==i.useSquircle?i.useSquircle:1;document.documentElement.style.setProperty("--strands-allow-squircle",e?"1":"0"),i.accentColor&&t(i.accentColor)}try{e.provide(a,i)}catch(n){}},exports.setStrandsConfig=function(e){if(s.value=e,"undefined"!=typeof window&&document.documentElement){const i=void 0!==e.useSquircle?e.useSquircle:1;document.documentElement.style.setProperty("--strands-allow-squircle",i?"1":"0"),e.accentColor&&t(e.accentColor)}},exports.useStrandsConfig=function(t){const n=e.inject(a,null);let o=null;try{if("undefined"!=typeof window)if(window.__STRANDS_CONFIG__)o=window.__STRANDS_CONFIG__;else if(window.__NUXT__){const e=window.__NUXT__;o=e?.config?.public?.strandsAuth||e?.public?.strandsAuth||e?.strandsAuth}}catch(u){}const r=e.computed(()=>{const e={...i,...t||{},...n||{},...s.value||{},...o||{}};if(e.baseUrl,"undefined"!=typeof window&&document.documentElement){const i=void 0!==e.useSquircle?e.useSquircle:1;document.documentElement.style.setProperty("--strands-allow-squircle",i?"1":"0"),e.accentColor&&document.documentElement.style.setProperty("--strands-accent",e.accentColor)}return e}),c=e.computed(()=>{const e=r.value.endpoints||{};return{signIn:e.signIn||"/api/v1/auth/sign-in",signUp:e.signUp||"/api/v1/auth/sign-up",signOut:e.signOut||"/api/v1/auth/sign-out",refresh:e.refresh||"/api/v1/auth/refresh",passwordReset:e.passwordReset||"/api/v1/auth/password-reset",passwordResetConfirm:e.passwordResetConfirm||"/api/v1/auth/password-reset/confirm",completeRegistration:e.completeRegistration||"/api/v1/auth/complete-registration",profile:e.profile||"/api/v1/user/profile",verifyEmail:e.verifyEmail||"/api/v1/auth/verify-email",oauthProviders:e.oauthProviders||"/api/v1/oauth/providers",oauthProvider:e.oauthProvider||"/api/v1/oauth/providers/{provider_id}",changeEmail:e.changeEmail||"/api/v1/user/change-email",avatar:e.avatar||"/api/v1/user/avatar",settings:e.settings||"/api/v1/user/settings",changeUsername:e.changeUsername||"/api/v1/user/username",usernameCooldown:e.usernameCooldown||"/api/v1/user/username/cooldown",checkUsernameAvailability:e.checkUsernameAvailability||"/api/v1/username/{username}/available",mfaDevices:e.mfaDevices||"/api/v1/mfa/devices",mfaTotpSetup:e.mfaTotpSetup||"/api/v1/mfa/totp/setup",mfaTotpVerify:e.mfaTotpVerify||"/api/v1/mfa/totp/verify",mfaEmailSetup:e.mfaEmailSetup||"/api/v1/mfa/email/setup",mfaEmailSend:e.mfaEmailSend||"/api/v1/mfa/email/send",mfaEmailVerify:e.mfaEmailVerify||"/api/v1/mfa/email/verify",mfaDeviceDisable:e.mfaDeviceDisable||"/api/v1/mfa/device/disable",mfaBackupCodes:e.mfaBackupCodes||"/api/v1/mfa/backup-codes/regenerate",mfaHardwareStartRegistration:e.mfaHardwareStartRegistration||"/api/v1/mfa/hardware/start-registration",mfaHardwareCompleteRegistration:e.mfaHardwareCompleteRegistration||"/api/v1/mfa/hardware/complete-registration",mfaSigninSendEmail:e.mfaSigninSendEmail||"/api/v1/auth/mfa/email/send",mfaSigninVerify:e.mfaSigninVerify||"/api/v1/auth/mfa/verify",mfaBackupCodeVerify:e.mfaBackupCodeVerify||"/api/v1/auth/mfa/backup-code/verify",mfaWebAuthnChallenge:e.mfaWebAuthnChallenge||"/api/v1/auth/mfa/webauthn/challenge",sessions:e.sessions||"/api/v1/sessions",sessionsStats:e.sessionsStats||"/api/v1/sessions/stats",sessionRevoke:e.sessionRevoke||"/api/v1/sessions/{session_id}/revoke",sessionsRevokeAll:e.sessionsRevokeAll||"/api/v1/sessions/revoke-all"}});return{config:r,endpoints:c,getUrl:e=>{const i=r.value;if(!i.baseUrl)throw new Error("Base URL is required in configuration");let a;return a="string"==typeof e&&e in c.value?c.value[e]:"string"==typeof e?e:c.value[e],`${i.baseUrl.replace(/\/$/,"")}${a.startsWith("/")?a:`/${a}`}`},getSupportEmail:()=>r.value.supportEmail||null}};
|