@strands.gg/accui 2.11.34 → 2.11.35
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/README.md +79 -10
- package/dist/StrandsUIPlugin-C9rrMU2i.cjs.js +1 -0
- package/dist/StrandsUIPlugin-tl7L52hZ.es.js +26130 -0
- package/dist/accui.css +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +364 -26458
- 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/{useStrandsAuth-Dca-zFQT.es.js → useStrandsAuth-BCnUxo-R.es.js} +1 -1
- package/dist/{useStrandsAuth-Bp5aTR3h.cjs.js → useStrandsAuth-DoJxpNLb.cjs.js} +1 -1
- package/dist/useStrandsConfig-Sr6NG90B.cjs.js +1 -0
- package/dist/{useStrandsConfig-XmPqJn_B.es.js → useStrandsConfig-fRu-OG08.es.js} +7 -0
- package/dist/vite/index.d.ts +2 -0
- package/dist/vite/plugin.d.ts +68 -0
- package/dist/vite.cjs.js +1 -0
- package/dist/vite.es.js +109 -0
- package/package.json +9 -2
- package/dist/useStrandsConfig-CLSzvTvE.cjs.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("nuxt/app"),s=require("../../../useStrandsAuth-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("nuxt/app"),s=require("../../../useStrandsAuth-DoJxpNLb.cjs.js"),a=()=>{const a=t.useRuntimeConfig().public.strandsAuth,e=s.useStrandsAuth();return{...e,initialize:async()=>{await e.initialize()},signIn:async s=>{const i=await e.signIn(s);return i&&a.onSignInUrl&&await t.navigateTo(a.onSignInUrl),i},signUp:async t=>await e.signUp({email:t.email,password:"",firstName:"",lastName:""}),signOut:async()=>{await e.signOut(),a.onSignOutUrl&&await t.navigateTo(a.onSignOutUrl)}}};exports.useAuthState=()=>{const{isAuthenticated:t,isLoading:s}=a();return{isAuthenticated:t,isLoading:s}},exports.useAuthUser=()=>{const{user:t}=a();return{user:t}},exports.useStrandsAuth=a;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useRuntimeConfig, navigateTo } from "nuxt/app";
|
|
2
|
-
import { u as useStrandsAuth$1 } from "../../../useStrandsAuth-
|
|
2
|
+
import { u as useStrandsAuth$1 } from "../../../useStrandsAuth-BCnUxo-R.es.js";
|
|
3
3
|
const useStrandsAuth = () => {
|
|
4
4
|
const config = useRuntimeConfig().public["strandsAuth"];
|
|
5
5
|
const vueAuth = useStrandsAuth$1();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("nuxt/app"),s=require("../../useStrandsConfig-
|
|
1
|
+
"use strict";const e=require("nuxt/app"),s=require("../../useStrandsConfig-Sr6NG90B.cjs.js"),n=e.defineNuxtPlugin({name:"strands-auth-client",async setup(){const n=e.useRuntimeConfig().public.strandsAuth,t={...s.STRANDS_AUTH_DEFAULTS,...n};s.setStrandsConfig(t),"undefined"!=typeof window&&(window.__STRANDS_CONFIG__=t),t?.accentColor&&"undefined"!=typeof window&&document.documentElement.style.setProperty("--strands-accent",t.accentColor);const{useStrandsAuth:i}=await Promise.resolve().then(()=>require("./composables/useStrandsAuth.cjs.js")),{initialize:a}=i();await a()}});module.exports=n;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useRuntimeConfig } from "nuxt/app";
|
|
2
|
-
import { s as setStrandsConfig, S as STRANDS_AUTH_DEFAULTS } from "../../useStrandsConfig-
|
|
2
|
+
import { s as setStrandsConfig, S as STRANDS_AUTH_DEFAULTS } from "../../useStrandsConfig-fRu-OG08.es.js";
|
|
3
3
|
const plugin_client = defineNuxtPlugin({
|
|
4
4
|
name: "strands-auth-client",
|
|
5
5
|
async setup() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const s=require("nuxt/app"),e=require("../../useStrandsConfig-
|
|
1
|
+
"use strict";const s=require("nuxt/app"),e=require("../../useStrandsConfig-Sr6NG90B.cjs.js"),r=s.defineNuxtPlugin({name:"strands-auth-server",setup(){const r=s.useRuntimeConfig().public.strandsAuth,t={...e.STRANDS_AUTH_DEFAULTS,...r};e.setStrandsConfig(t)}});module.exports=r;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useRuntimeConfig } from "nuxt/app";
|
|
2
|
-
import { s as setStrandsConfig, S as STRANDS_AUTH_DEFAULTS } from "../../useStrandsConfig-
|
|
2
|
+
import { s as setStrandsConfig, S as STRANDS_AUTH_DEFAULTS } from "../../useStrandsConfig-fRu-OG08.es.js";
|
|
3
3
|
const plugin_server = defineNuxtPlugin({
|
|
4
4
|
name: "strands-auth-server",
|
|
5
5
|
setup() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, ref, getCurrentInstance, onUnmounted } from "vue";
|
|
2
|
-
import { u as useStrandsConfig } from "./useStrandsConfig-
|
|
2
|
+
import { u as useStrandsConfig } from "./useStrandsConfig-fRu-OG08.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-CLSzvTvE.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:d,config:c}=t.useStrandsConfig(),{fetch:l,clear:u,invalidate:h}={fetch:n.fetch.bind(n),clear:n.clear.bind(n),invalidate:n.invalidate.bind(n),getStats:n.getStats.bind(n)},{currentUser:f,currentSession:w,loadingStates:y,isInitialized:g,mfaRequired:m,mfaSessionId:p,availableMfaMethods:S}=r,_=()=>{if(f.value=null,w.value=null,m.value=0,p.value=null,S.value=[],"undefined"!=typeof window&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")),D(),s=null,u(),"undefined"!=typeof window&&c.value?.onSignOutUrl){const e=window.location.pathname+window.location.search,t=c.value.onSignOutUrl;e!==t&&(window.location.href=t)}},T=e.computed(()=>y.value.initializing),E=e.computed(()=>y.value.signingIn),O=e.computed(()=>y.value.signingUp),v=e.computed(()=>y.value.signingOut),A=e.computed(()=>y.value.refreshingToken),$=e.computed(()=>y.value.sendingMfaEmail),N=e.computed(()=>y.value.verifyingMfa);e.computed(()=>y.value.loadingProfile);const b=e.computed(()=>y.value.signingIn||y.value.signingUp||y.value.signingOut||y.value.refreshingToken||y.value.sendingMfaEmail||y.value.verifyingMfa||y.value.loadingProfile),k=e.computed(()=>y.value.initializing||b.value),C=e.computed(()=>{const e=y.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..."}),J=()=>{const e={};return w.value?.accessToken&&(e.Authorization=`Bearer ${w.value.accessToken}`),w.value?.refreshToken&&(e["x-refresh-token"]=w.value.refreshToken),e},P=e.computed(()=>null!==f.value),F=async()=>{if(!w.value?.refreshToken)return 0;if(s)return await s;s=(async()=>{y.value.refreshingToken=1;try{const e=await fetch(d("refresh"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:w.value.refreshToken})});if(!e.ok){if(401===e.status)return _(),0;throw new Error(`Token refresh failed: ${e.status} ${e.statusText}`)}const t=await e.json();t.user&&(f.value=i(t.user),f.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value)));const n={accessToken:t.access_token,refreshToken:t.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:t.user?.id||f.value?.id};return w.value=n,"undefined"!=typeof window&&localStorage.setItem("strands_auth_session",JSON.stringify(n)),U(),h(`sessions:${w.value.accessToken.slice(0,20)}`),1}catch(e){return _(),0}finally{y.value.refreshingToken=0}})();const e=await s;return s=null,e},M=async e=>{try{e.user&&(f.value=i(e.user));const t={accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:f.value?.id||e.user?.id};w.value=t,"undefined"!=typeof window&&(localStorage.setItem("strands_auth_session",JSON.stringify(t)),f.value&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value))),U()}catch(t){}},U=()=>{if(o&&clearTimeout(o),!w.value)return;if("undefined"!=typeof document&&"hidden"===document.visibilityState)return;const e=new Date,t=w.value.expiresAt.getTime()-e.getTime()-6e4;t<=0?F():o=setTimeout(async()=>{"undefined"!=typeof document&&"visible"!==document.visibilityState||await F()&&U()},t)},D=()=>{o&&(clearTimeout(o),o=null)},I=async()=>{if(!g.value){y.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&&e.refreshToken?(w.value=e,f.value=a,await F()||_()):e.expiresAt>new Date?(w.value=e,f.value=a,U()):(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}catch(e){localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")}}g.value=1,await new Promise(e=>setTimeout(e,50))}catch(e){}finally{y.value.initializing=0}}};"undefined"!=typeof document&&document.addEventListener("visibilitychange",()=>{"visible"===document.visibilityState&&w.value?(U(),j()):"hidden"===document.visibilityState&&D()}),"undefined"!=typeof window&&window.addEventListener("storage",e=>{"strands_auth_session"!==e.key&&"strands_auth_user"!==e.key||!e.newValue&&f.value&&_()});const j=()=>{if("undefined"!=typeof window&&f.value&&w.value){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");e&&t||_()}},R=()=>{D(),u()};try{e.getCurrentInstance()&&e.onUnmounted(R)}catch(z){}return g.value||I(),{user:e.computed(()=>f.value),currentUser:e.computed(()=>f.value),currentSession:e.computed(()=>w.value),isAuthenticated:P,isLoading:e.computed(()=>k.value||!g.value),loading:b,loadingMessage:C,isInitializing:T,isSigningIn:E,isSigningUp:O,isSigningOut:v,isRefreshingToken:A,isSendingMfaEmail:$,isVerifyingMfa:N,mfaRequired:e.computed(()=>m.value),mfaSessionId:e.computed(()=>p.value),availableMfaMethods:e.computed(()=>S.value),signIn:async e=>{y.value.signingIn=1;try{m.value=0,p.value=null,S.value=[];const t={"Content-Type":"application/json"};"undefined"!=typeof window&&window.location&&(t.Origin=window.location.origin);const n=await fetch(d("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){m.value=1,p.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 S.value=e,y.value.signingIn=0,a}return await M(a),a}catch(t){throw t}finally{y.value.signingIn=0}},signUp:async e=>{y.value.signingUp=1;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{y.value.signingUp=0}},signOut:async()=>{y.value.signingOut=1;try{D(),s=null,u(),f.value=null,w.value=null,m.value=0,p.value=null,S.value=[],"undefined"!=typeof window&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}finally{y.value.signingOut=0}},refreshToken:F,fetchProfile:async()=>{const e=`profile:${w.value.accessToken.slice(0,20)}`;y.value.loadingProfile=1;try{return await l(e,async()=>{const e=await fetch(d("profile"),{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value=i(t),f.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value)),f.value})}finally{y.value.loadingProfile=0}},updateProfile:async e=>{y.value.loadingProfile=1;try{const t=await fetch(d("profile"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value=i(n),f.value&&a("strands_auth_user",JSON.stringify(f.value)),f.value}finally{y.value.loadingProfile=0}},updateUserSettings:async e=>{y.value.loadingProfile=1;try{const t=await fetch(d("settings"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value=i(n),f.value&&a("strands_auth_user",JSON.stringify(f.value)),f.value}finally{y.value.loadingProfile=0}},changeEmail:async(e,t)=>{y.value.loadingProfile=1;try{const n=await fetch(d("changeEmail"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value&&(f.value={...f.value,email:e,emailVerified:0,updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value))),a}finally{y.value.loadingProfile=0}},changeUsername:async e=>{y.value.loadingProfile=1;try{const t=await fetch(d("changeUsername"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value&&(f.value={...f.value,username:e,usernameLastChangedAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value))),n}finally{y.value.loadingProfile=0}},getUsernameCooldown:async()=>{const e=await fetch(d("usernameCooldown"),{method:"GET",headers:{Authorization:`Bearer ${w.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=d("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:${w.value?.accessToken?.slice(0,20)||"no-token"}`;try{return await l(e,async()=>{const e=J(),t=await fetch(d("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(d("sessionsStats"),{method:"GET",headers:J()});if(!e.ok)throw new Error(`Failed to get session stats: ${e.status} ${e.statusText}`);return e.json()},revokeSession:async e=>{const t=d("sessionRevoke").replace("{session_id}",encodeURIComponent(e)),n=await fetch(t,{method:"POST",headers:J()});if(!n.ok)throw new Error(`Failed to revoke session: ${n.status} ${n.statusText}`);return 200===n.status},revokeAllOtherSessions:async()=>{const e=await fetch(d("sessionsRevokeAll"),{method:"POST",headers:J()});if(!e.ok)throw new Error(`Failed to revoke all other sessions: ${e.status} ${e.statusText}`);return 200===e.status},initialize:I,setAuthData:M,verifyMfa:async(e,t,n=0)=>{if(!p.value)throw new Error("No MFA session available");y.value.verifyingMfa=1;try{const a=d(n?"mfaBackupCodeVerify":"mfaSigninVerify"),i=n?{mfa_session_id:p.value,backup_code:t}:{mfa_session_id:p.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 m.value=0,p.value=null,S.value=[],await M(o),o}finally{y.value.verifyingMfa=0}},sendMfaEmailCode:async e=>{if(!p.value)throw new Error("No MFA session available");y.value.sendingMfaEmail=1;try{const t=await fetch(d("mfaSigninSendEmail"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:p.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{y.value.sendingMfaEmail=0}},getMfaWebAuthnChallenge:async e=>{if(!p.value)throw new Error("No MFA session available");const t=await fetch(d("mfaWebAuthnChallenge"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:p.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(d("mfaHardwareStartRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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(d("mfaHardwareCompleteRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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:U,stopTokenRefreshTimer:D,getAuthHeaders:J,forceReInit:()=>{g.value=0,y.value.initializing=1,I()}}};
|
|
1
|
+
"use strict";const e=require("vue"),t=require("./useStrandsConfig-Sr6NG90B.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:d,config:c}=t.useStrandsConfig(),{fetch:l,clear:u,invalidate:h}={fetch:n.fetch.bind(n),clear:n.clear.bind(n),invalidate:n.invalidate.bind(n),getStats:n.getStats.bind(n)},{currentUser:f,currentSession:w,loadingStates:y,isInitialized:g,mfaRequired:m,mfaSessionId:p,availableMfaMethods:S}=r,_=()=>{if(f.value=null,w.value=null,m.value=0,p.value=null,S.value=[],"undefined"!=typeof window&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")),D(),s=null,u(),"undefined"!=typeof window&&c.value?.onSignOutUrl){const e=window.location.pathname+window.location.search,t=c.value.onSignOutUrl;e!==t&&(window.location.href=t)}},T=e.computed(()=>y.value.initializing),E=e.computed(()=>y.value.signingIn),O=e.computed(()=>y.value.signingUp),v=e.computed(()=>y.value.signingOut),A=e.computed(()=>y.value.refreshingToken),$=e.computed(()=>y.value.sendingMfaEmail),N=e.computed(()=>y.value.verifyingMfa);e.computed(()=>y.value.loadingProfile);const b=e.computed(()=>y.value.signingIn||y.value.signingUp||y.value.signingOut||y.value.refreshingToken||y.value.sendingMfaEmail||y.value.verifyingMfa||y.value.loadingProfile),k=e.computed(()=>y.value.initializing||b.value),C=e.computed(()=>{const e=y.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..."}),J=()=>{const e={};return w.value?.accessToken&&(e.Authorization=`Bearer ${w.value.accessToken}`),w.value?.refreshToken&&(e["x-refresh-token"]=w.value.refreshToken),e},P=e.computed(()=>null!==f.value),F=async()=>{if(!w.value?.refreshToken)return 0;if(s)return await s;s=(async()=>{y.value.refreshingToken=1;try{const e=await fetch(d("refresh"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:w.value.refreshToken})});if(!e.ok){if(401===e.status)return _(),0;throw new Error(`Token refresh failed: ${e.status} ${e.statusText}`)}const t=await e.json();t.user&&(f.value=i(t.user),f.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value)));const n={accessToken:t.access_token,refreshToken:t.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:t.user?.id||f.value?.id};return w.value=n,"undefined"!=typeof window&&localStorage.setItem("strands_auth_session",JSON.stringify(n)),U(),h(`sessions:${w.value.accessToken.slice(0,20)}`),1}catch(e){return _(),0}finally{y.value.refreshingToken=0}})();const e=await s;return s=null,e},M=async e=>{try{e.user&&(f.value=i(e.user));const t={accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:new Date(Date.now()+3e5),userId:f.value?.id||e.user?.id};w.value=t,"undefined"!=typeof window&&(localStorage.setItem("strands_auth_session",JSON.stringify(t)),f.value&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value))),U()}catch(t){}},U=()=>{if(o&&clearTimeout(o),!w.value)return;if("undefined"!=typeof document&&"hidden"===document.visibilityState)return;const e=new Date,t=w.value.expiresAt.getTime()-e.getTime()-6e4;t<=0?F():o=setTimeout(async()=>{"undefined"!=typeof document&&"visible"!==document.visibilityState||await F()&&U()},t)},D=()=>{o&&(clearTimeout(o),o=null)},I=async()=>{if(!g.value){y.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&&e.refreshToken?(w.value=e,f.value=a,await F()||_()):e.expiresAt>new Date?(w.value=e,f.value=a,U()):(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}catch(e){localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user")}}g.value=1,await new Promise(e=>setTimeout(e,50))}catch(e){}finally{y.value.initializing=0}}};"undefined"!=typeof document&&document.addEventListener("visibilitychange",()=>{"visible"===document.visibilityState&&w.value?(U(),j()):"hidden"===document.visibilityState&&D()}),"undefined"!=typeof window&&window.addEventListener("storage",e=>{"strands_auth_session"!==e.key&&"strands_auth_user"!==e.key||!e.newValue&&f.value&&_()});const j=()=>{if("undefined"!=typeof window&&f.value&&w.value){const e=localStorage.getItem("strands_auth_session"),t=localStorage.getItem("strands_auth_user");e&&t||_()}},R=()=>{D(),u()};try{e.getCurrentInstance()&&e.onUnmounted(R)}catch(z){}return g.value||I(),{user:e.computed(()=>f.value),currentUser:e.computed(()=>f.value),currentSession:e.computed(()=>w.value),isAuthenticated:P,isLoading:e.computed(()=>k.value||!g.value),loading:b,loadingMessage:C,isInitializing:T,isSigningIn:E,isSigningUp:O,isSigningOut:v,isRefreshingToken:A,isSendingMfaEmail:$,isVerifyingMfa:N,mfaRequired:e.computed(()=>m.value),mfaSessionId:e.computed(()=>p.value),availableMfaMethods:e.computed(()=>S.value),signIn:async e=>{y.value.signingIn=1;try{m.value=0,p.value=null,S.value=[];const t={"Content-Type":"application/json"};"undefined"!=typeof window&&window.location&&(t.Origin=window.location.origin);const n=await fetch(d("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){m.value=1,p.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 S.value=e,y.value.signingIn=0,a}return await M(a),a}catch(t){throw t}finally{y.value.signingIn=0}},signUp:async e=>{y.value.signingUp=1;try{throw new Error("Sign up not implemented - please integrate with auth SDK")}finally{y.value.signingUp=0}},signOut:async()=>{y.value.signingOut=1;try{D(),s=null,u(),f.value=null,w.value=null,m.value=0,p.value=null,S.value=[],"undefined"!=typeof window&&(localStorage.removeItem("strands_auth_session"),localStorage.removeItem("strands_auth_user"))}finally{y.value.signingOut=0}},refreshToken:F,fetchProfile:async()=>{const e=`profile:${w.value.accessToken.slice(0,20)}`;y.value.loadingProfile=1;try{return await l(e,async()=>{const e=await fetch(d("profile"),{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value=i(t),f.value&&"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value)),f.value})}finally{y.value.loadingProfile=0}},updateProfile:async e=>{y.value.loadingProfile=1;try{const t=await fetch(d("profile"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value=i(n),f.value&&a("strands_auth_user",JSON.stringify(f.value)),f.value}finally{y.value.loadingProfile=0}},updateUserSettings:async e=>{y.value.loadingProfile=1;try{const t=await fetch(d("settings"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value=i(n),f.value&&a("strands_auth_user",JSON.stringify(f.value)),f.value}finally{y.value.loadingProfile=0}},changeEmail:async(e,t)=>{y.value.loadingProfile=1;try{const n=await fetch(d("changeEmail"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value&&(f.value={...f.value,email:e,emailVerified:0,updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value))),a}finally{y.value.loadingProfile=0}},changeUsername:async e=>{y.value.loadingProfile=1;try{const t=await fetch(d("changeUsername"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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 f.value&&(f.value={...f.value,username:e,usernameLastChangedAt:(new Date).toISOString(),updatedAt:(new Date).toISOString()},"undefined"!=typeof window&&localStorage.setItem("strands_auth_user",JSON.stringify(f.value))),n}finally{y.value.loadingProfile=0}},getUsernameCooldown:async()=>{const e=await fetch(d("usernameCooldown"),{method:"GET",headers:{Authorization:`Bearer ${w.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=d("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:${w.value?.accessToken?.slice(0,20)||"no-token"}`;try{return await l(e,async()=>{const e=J(),t=await fetch(d("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(d("sessionsStats"),{method:"GET",headers:J()});if(!e.ok)throw new Error(`Failed to get session stats: ${e.status} ${e.statusText}`);return e.json()},revokeSession:async e=>{const t=d("sessionRevoke").replace("{session_id}",encodeURIComponent(e)),n=await fetch(t,{method:"POST",headers:J()});if(!n.ok)throw new Error(`Failed to revoke session: ${n.status} ${n.statusText}`);return 200===n.status},revokeAllOtherSessions:async()=>{const e=await fetch(d("sessionsRevokeAll"),{method:"POST",headers:J()});if(!e.ok)throw new Error(`Failed to revoke all other sessions: ${e.status} ${e.statusText}`);return 200===e.status},initialize:I,setAuthData:M,verifyMfa:async(e,t,n=0)=>{if(!p.value)throw new Error("No MFA session available");y.value.verifyingMfa=1;try{const a=d(n?"mfaBackupCodeVerify":"mfaSigninVerify"),i=n?{mfa_session_id:p.value,backup_code:t}:{mfa_session_id:p.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 m.value=0,p.value=null,S.value=[],await M(o),o}finally{y.value.verifyingMfa=0}},sendMfaEmailCode:async e=>{if(!p.value)throw new Error("No MFA session available");y.value.sendingMfaEmail=1;try{const t=await fetch(d("mfaSigninSendEmail"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:p.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{y.value.sendingMfaEmail=0}},getMfaWebAuthnChallenge:async e=>{if(!p.value)throw new Error("No MFA session available");const t=await fetch(d("mfaWebAuthnChallenge"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mfa_session_id:p.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(d("mfaHardwareStartRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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(d("mfaHardwareCompleteRegistration"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${w.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:U,stopTokenRefreshTimer:D,getAuthHeaders:J,forceReInit:()=>{g.value=0,y.value.initializing=1,I()}}};
|
|
@@ -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)}function n(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){}}function r(t){let n=null;try{e.getCurrentInstance()&&(n=e.inject(a,null))}catch(u){n=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}}function o(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)}}const c=Object.freeze(Object.defineProperty({__proto__:null,provideStrandsConfig:n,setStrandsConfig:o,useStrandsConfig:r},Symbol.toStringTag,{value:"Module"}));exports.STRANDS_AUTH_DEFAULTS=i,exports.provideStrandsConfig=n,exports.setStrandsConfig=o,exports.useStrandsConfig=r,exports.useStrandsConfig$1=c;
|
|
@@ -233,8 +233,15 @@ function setStrandsConfig(config) {
|
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
|
+
const useStrandsConfig$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
237
|
+
__proto__: null,
|
|
238
|
+
provideStrandsConfig,
|
|
239
|
+
setStrandsConfig,
|
|
240
|
+
useStrandsConfig
|
|
241
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
236
242
|
export {
|
|
237
243
|
STRANDS_AUTH_DEFAULTS as S,
|
|
244
|
+
useStrandsConfig$1 as a,
|
|
238
245
|
provideStrandsConfig as p,
|
|
239
246
|
setStrandsConfig as s,
|
|
240
247
|
useStrandsConfig as u
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import type { App } from 'vue';
|
|
3
|
+
export type { StrandsAuthConfig, StrandsAuthEndpoints } from '../types';
|
|
4
|
+
import type { StrandsAuthConfig } from '../types';
|
|
5
|
+
export interface StrandsVitePluginOptions extends StrandsAuthConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Auto-import styles
|
|
8
|
+
* @default true
|
|
9
|
+
*/
|
|
10
|
+
styles?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Vite plugin for Strands Auth UI
|
|
14
|
+
*
|
|
15
|
+
* Automatically configures the Strands Auth system with your settings
|
|
16
|
+
* and optionally auto-imports styles.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // vite.config.ts
|
|
21
|
+
* import { defineConfig } from 'vite'
|
|
22
|
+
* import vue from '@vitejs/plugin-vue'
|
|
23
|
+
* import StrandsAuth from '@strands.gg/accui/vite'
|
|
24
|
+
*
|
|
25
|
+
* export default defineConfig({
|
|
26
|
+
* plugins: [
|
|
27
|
+
* vue(),
|
|
28
|
+
* StrandsAuth({
|
|
29
|
+
* baseUrl: 'http://localhost:8000',
|
|
30
|
+
* accentColor: '#EA00A8',
|
|
31
|
+
* useSquircle: true,
|
|
32
|
+
* styles: true, // Auto-import styles
|
|
33
|
+
* })
|
|
34
|
+
* ]
|
|
35
|
+
* })
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function StrandsAuthVitePlugin(options?: StrandsVitePluginOptions): Plugin;
|
|
39
|
+
/**
|
|
40
|
+
* Vue plugin installer for Strands Auth
|
|
41
|
+
*
|
|
42
|
+
* Use this in your main.ts file to install the Strands Auth components
|
|
43
|
+
* and configure the system.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* import { createApp } from 'vue'
|
|
48
|
+
* import { createStrandsAuth } from '@strands.gg/accui/vite'
|
|
49
|
+
*
|
|
50
|
+
* const app = createApp(App)
|
|
51
|
+
*
|
|
52
|
+
* app.use(createStrandsAuth({
|
|
53
|
+
* baseUrl: 'http://localhost:8000',
|
|
54
|
+
* accentColor: '#EA00A8',
|
|
55
|
+
* }))
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function createStrandsAuth(config?: StrandsAuthConfig): {
|
|
59
|
+
install(app: App): void;
|
|
60
|
+
};
|
|
61
|
+
export default StrandsAuthVitePlugin;
|
|
62
|
+
export { StrandsAuthVitePlugin as StrandsAuth, StrandsAuthVitePlugin as strandsAuth, };
|
|
63
|
+
declare global {
|
|
64
|
+
interface Window {
|
|
65
|
+
__STRANDS_CONFIG__?: StrandsAuthConfig;
|
|
66
|
+
__STRANDS_INJECTED__?: boolean;
|
|
67
|
+
}
|
|
68
|
+
}
|
package/dist/vite.cjs.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function n(n={}){const{styles:s=1,accentColor:r="#EA00A8",useSquircle:t=1,...i}=n;let c;return{name:"@strands.gg/accui:vite-plugin",enforce:"pre",config:(n,{command:s})=>(c={accentColor:r,useSquircle:t,...i},{define:{t:JSON.stringify(c)}}),transformIndexHtml:{order:"pre",handler(n){if(r&&"#EA00A8"!==r){const s=`<style data-strands-accent>\n :root {\n --strands-accent: ${r};\n --accui-strands-accent: ${r};\n --accui-strands-50: color-mix(in srgb, ${r} 10%, white);\n --accui-strands-100: color-mix(in srgb, ${r} 20%, white);\n --accui-strands-200: color-mix(in srgb, ${r} 30%, white);\n --accui-strands-300: color-mix(in srgb, ${r} 40%, white);\n --accui-strands-400: color-mix(in srgb, ${r} 70%, white);\n --accui-strands-500: ${r};\n --accui-strands-600: color-mix(in srgb, ${r} 85%, black);\n --accui-strands-700: color-mix(in srgb, ${r} 70%, black);\n --accui-strands-800: color-mix(in srgb, ${r} 55%, black);\n --accui-strands-900: color-mix(in srgb, ${r} 40%, black);\n --accui-strands-950: color-mix(in srgb, ${r} 25%, black);\n }</style>`;return n.replace("</head>",` ${s}\n </head>`)}return n}},transform:async(n,r)=>(s&&r.endsWith("main.ts")||r.endsWith("main.js"))&&!n.includes("@strands.gg/accui/style.css")?{code:`import '@strands.gg/accui/style.css'\n${n}`,map:null}:!r.endsWith("main.ts")&&!r.endsWith("main.js")||n.includes("setStrandsConfig")||n.includes("__STRANDS_INJECTED__")?null:{code:`\n// Auto-injected by @strands.gg/accui Vite plugin\nimport { setStrandsConfig } from '@strands.gg/accui'\n\nif (typeof window !== 'undefined') {\n const strandsConfig = ${JSON.stringify(c)}\n setStrandsConfig(strandsConfig)\n window.__STRANDS_CONFIG__ = strandsConfig\n window.__STRANDS_INJECTED__ = true\n}\n\n${n}`,map:null}}}Object.defineProperties(exports,{i:{value:1},[Symbol.toStringTag]:{value:"Module"}}),exports.StrandsAuth=n,exports.StrandsAuthVitePlugin=n,exports.createStrandsAuth=function(n={}){return{install(s){Promise.resolve().then(()=>require("./StrandsUIPlugin-C9rrMU2i.cjs.js")).then(n=>n.StrandsUIPlugin$1).then(n=>{const r=n.default;s.use(r)}),Promise.resolve().then(()=>require("./useStrandsConfig-Sr6NG90B.cjs.js")).then(n=>n.useStrandsConfig$1).then(s=>{const{setStrandsConfig:r}=s;r(n),"undefined"!=typeof window&&(window.t=n)})}}},exports.default=n,exports.strandsAuth=n;
|
package/dist/vite.es.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
function StrandsAuthVitePlugin(options = {}) {
|
|
2
|
+
const {
|
|
3
|
+
styles = true,
|
|
4
|
+
accentColor = "#EA00A8",
|
|
5
|
+
useSquircle = true,
|
|
6
|
+
...authConfig
|
|
7
|
+
} = options;
|
|
8
|
+
let config;
|
|
9
|
+
return {
|
|
10
|
+
name: "@strands.gg/accui:vite-plugin",
|
|
11
|
+
enforce: "pre",
|
|
12
|
+
config(_, { command }) {
|
|
13
|
+
config = {
|
|
14
|
+
accentColor,
|
|
15
|
+
useSquircle,
|
|
16
|
+
...authConfig
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
define: {
|
|
20
|
+
// Make config available at build time
|
|
21
|
+
"__STRANDS_CONFIG__": JSON.stringify(config)
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
transformIndexHtml: {
|
|
26
|
+
order: "pre",
|
|
27
|
+
handler(html) {
|
|
28
|
+
if (accentColor && accentColor !== "#EA00A8") {
|
|
29
|
+
const cssVariables = `
|
|
30
|
+
:root {
|
|
31
|
+
--strands-accent: ${accentColor};
|
|
32
|
+
--accui-strands-accent: ${accentColor};
|
|
33
|
+
--accui-strands-50: color-mix(in srgb, ${accentColor} 10%, white);
|
|
34
|
+
--accui-strands-100: color-mix(in srgb, ${accentColor} 20%, white);
|
|
35
|
+
--accui-strands-200: color-mix(in srgb, ${accentColor} 30%, white);
|
|
36
|
+
--accui-strands-300: color-mix(in srgb, ${accentColor} 40%, white);
|
|
37
|
+
--accui-strands-400: color-mix(in srgb, ${accentColor} 70%, white);
|
|
38
|
+
--accui-strands-500: ${accentColor};
|
|
39
|
+
--accui-strands-600: color-mix(in srgb, ${accentColor} 85%, black);
|
|
40
|
+
--accui-strands-700: color-mix(in srgb, ${accentColor} 70%, black);
|
|
41
|
+
--accui-strands-800: color-mix(in srgb, ${accentColor} 55%, black);
|
|
42
|
+
--accui-strands-900: color-mix(in srgb, ${accentColor} 40%, black);
|
|
43
|
+
--accui-strands-950: color-mix(in srgb, ${accentColor} 25%, black);
|
|
44
|
+
}`;
|
|
45
|
+
const styleTag = `<style data-strands-accent>${cssVariables}</style>`;
|
|
46
|
+
return html.replace("</head>", ` ${styleTag}
|
|
47
|
+
</head>`);
|
|
48
|
+
}
|
|
49
|
+
return html;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
async transform(code, id) {
|
|
53
|
+
if (styles && id.endsWith("main.ts") || id.endsWith("main.js")) {
|
|
54
|
+
if (!code.includes("@strands.gg/accui/style.css")) {
|
|
55
|
+
return {
|
|
56
|
+
code: `import '@strands.gg/accui/style.css'
|
|
57
|
+
${code}`,
|
|
58
|
+
map: null
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (id.endsWith("main.ts") || id.endsWith("main.js")) {
|
|
63
|
+
if (!code.includes("setStrandsConfig") && !code.includes("__STRANDS_INJECTED__")) {
|
|
64
|
+
const configSetup = `
|
|
65
|
+
// Auto-injected by @strands.gg/accui Vite plugin
|
|
66
|
+
import { setStrandsConfig } from '@strands.gg/accui'
|
|
67
|
+
|
|
68
|
+
if (typeof window !== 'undefined') {
|
|
69
|
+
const strandsConfig = ${JSON.stringify(config)}
|
|
70
|
+
setStrandsConfig(strandsConfig)
|
|
71
|
+
window.__STRANDS_CONFIG__ = strandsConfig
|
|
72
|
+
window.__STRANDS_INJECTED__ = true
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
return {
|
|
76
|
+
code: `${configSetup}
|
|
77
|
+
${code}`,
|
|
78
|
+
map: null
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function createStrandsAuth(config = {}) {
|
|
87
|
+
return {
|
|
88
|
+
install(app) {
|
|
89
|
+
import("./StrandsUIPlugin-tl7L52hZ.es.js").then((n) => n.n).then((module) => {
|
|
90
|
+
const StrandsUIPlugin = module.default;
|
|
91
|
+
app.use(StrandsUIPlugin);
|
|
92
|
+
});
|
|
93
|
+
import("./useStrandsConfig-fRu-OG08.es.js").then((n) => n.a).then((module) => {
|
|
94
|
+
const { setStrandsConfig } = module;
|
|
95
|
+
setStrandsConfig(config);
|
|
96
|
+
if (typeof window !== "undefined") {
|
|
97
|
+
window.__STRANDS_CONFIG__ = config;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
StrandsAuthVitePlugin as StrandsAuth,
|
|
105
|
+
StrandsAuthVitePlugin,
|
|
106
|
+
createStrandsAuth,
|
|
107
|
+
StrandsAuthVitePlugin as default,
|
|
108
|
+
StrandsAuthVitePlugin as strandsAuth
|
|
109
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strands.gg/accui",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.35",
|
|
4
4
|
"description": "Strands Authentication UI Components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs.js",
|
|
@@ -37,6 +37,11 @@
|
|
|
37
37
|
"types": "./dist/vue/composables/useAuthenticatedFetch.d.ts",
|
|
38
38
|
"import": "./dist/index.es.js",
|
|
39
39
|
"require": "./dist/index.cjs.js"
|
|
40
|
+
},
|
|
41
|
+
"./vite": {
|
|
42
|
+
"types": "./dist/vite/index.d.ts",
|
|
43
|
+
"import": "./dist/vite.es.js",
|
|
44
|
+
"require": "./dist/vite.cjs.js"
|
|
40
45
|
}
|
|
41
46
|
},
|
|
42
47
|
"files": [
|
|
@@ -44,6 +49,7 @@
|
|
|
44
49
|
],
|
|
45
50
|
"keywords": [
|
|
46
51
|
"vue",
|
|
52
|
+
"vite",
|
|
47
53
|
"nuxt",
|
|
48
54
|
"nuxt3",
|
|
49
55
|
"nuxt4",
|
|
@@ -51,7 +57,8 @@
|
|
|
51
57
|
"ui",
|
|
52
58
|
"components",
|
|
53
59
|
"strands",
|
|
54
|
-
"nuxt-module"
|
|
60
|
+
"nuxt-module",
|
|
61
|
+
"vite-plugin"
|
|
55
62
|
],
|
|
56
63
|
"author": "Strands Services Limited",
|
|
57
64
|
"license": "MIT",
|
|
@@ -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){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){let n=null;try{e.getCurrentInstance()&&(n=e.inject(a,null))}catch(u){n=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}};
|