|
|
@@ -1,8 +1,116 @@
|
|
|
+import { createAuthClient } from "better-auth/client"
|
|
|
+import { adminClient, inferAdditionalFields } from "better-auth/client/plugins"
|
|
|
+import { additionalFields } from "#shared/utils/auth/additionalFields.js"
|
|
|
+
|
|
|
+import {
|
|
|
+ ac,
|
|
|
+ admin as adminRole,
|
|
|
+ user as userRole
|
|
|
+} from "#shared/utils/auth/permissions.js"
|
|
|
+
|
|
|
export default function useAuthClient() {
|
|
|
+ const headers = import.meta.server ? useRequestHeaders() : undefined
|
|
|
+
|
|
|
+ const authClient = createAuthClient({
|
|
|
+ fetchOptions: { headers },
|
|
|
+
|
|
|
+ plugins: [
|
|
|
+ adminClient({ ac, roles: { admin: adminRole, user: userRole } }),
|
|
|
+ inferAdditionalFields(additionalFields)
|
|
|
+ ]
|
|
|
+ })
|
|
|
+
|
|
|
+ const session = useState("auth:session", () => null)
|
|
|
+ const user = useState("auth:user", () => null)
|
|
|
+ const isSignedIn = computed(() => !!session.value)
|
|
|
+
|
|
|
+ const fetchingSession = import.meta.server
|
|
|
+ ? ref(false)
|
|
|
+ : useState("auth:fetchingSession", () => false)
|
|
|
+
|
|
|
+ async function signIn({ email, password, rememberMe, redirectTo } = {}) {
|
|
|
+ // noinspection JSUnresolvedReference
|
|
|
+ const result = await authClient.signIn.email({
|
|
|
+ email,
|
|
|
+ password,
|
|
|
+ rememberMe
|
|
|
+ })
|
|
|
+
|
|
|
+ if (redirectTo) {
|
|
|
+ await navigateTo(redirectTo)
|
|
|
+ } else {
|
|
|
+ const route = useRoute()
|
|
|
+
|
|
|
+ if (route.name === "characterView") {
|
|
|
+ await navigateTo({ name: "characterEdit", params: route.params })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result
|
|
|
+ }
|
|
|
+
|
|
|
+ async function signOut({ redirectTo } = {}) {
|
|
|
+ // noinspection JSUnresolvedReference
|
|
|
+ const result = await authClient.signOut()
|
|
|
+ session.value = null
|
|
|
+ user.value = null
|
|
|
+
|
|
|
+ if (redirectTo) {
|
|
|
+ await navigateTo(redirectTo)
|
|
|
+ } else {
|
|
|
+ const route = useRoute()
|
|
|
+
|
|
|
+ if (route.name === "characterEdit") {
|
|
|
+ await navigateTo({ name: "characterView", params: route.params })
|
|
|
+ } else {
|
|
|
+ // noinspection JSUnresolvedReference
|
|
|
+ if (
|
|
|
+ _includes(route.meta?.middleware, "signed-in") ||
|
|
|
+ _includes(route.meta?.middleware, "admin")
|
|
|
+ ) {
|
|
|
+ await navigateTo({ name: "characters" })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result
|
|
|
+ }
|
|
|
+
|
|
|
+ async function fetchSession() {
|
|
|
+ if (fetchingSession.value) {
|
|
|
+ console.log("[useAuthClient] [fetchSession] already fetching session")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ fetchingSession.value = true
|
|
|
+ // noinspection JSUnresolvedReference
|
|
|
+ const { data } = await authClient.getSession({ fetchOptions: { headers } })
|
|
|
+ session.value = data?.session || null
|
|
|
+ user.value = data?.user || null
|
|
|
+ fetchingSession.value = false
|
|
|
+
|
|
|
+ return data
|
|
|
+ }
|
|
|
+
|
|
|
+ if (import.meta.client) {
|
|
|
+ authClient.$store.listen("$sessionSignal", async (signal) => {
|
|
|
+ if (!signal) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ await fetchSession()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // noinspection JSUnresolvedReference
|
|
|
return {
|
|
|
- isSignedIn: ref(false),
|
|
|
- signIn: _noop(),
|
|
|
- signOut: _noop(),
|
|
|
- user: ref(null)
|
|
|
+ session,
|
|
|
+ user,
|
|
|
+ isSignedIn,
|
|
|
+ signIn,
|
|
|
+ signUp: authClient.signUp,
|
|
|
+ signOut,
|
|
|
+ fetchSession,
|
|
|
+ authClient
|
|
|
}
|
|
|
}
|