UNPKG

nuxt-surrealdb

Version:

A Nuxt module aimed to simplify the use of SurrealDB

121 lines (120 loc) 3.69 kB
import { computed, createError, useCookie, useRuntimeConfig, useState, useSurrealDB } from "#imports"; export function useSurrealAuth(database) { const { databases, auth: { adminMaxAge, database: authDb, sessionName, cookieName, sameSite } } = useRuntimeConfig().public.surrealdb; const db = databases[database || authDb]; const { $authenticate, $info, $invalidate, $query, $signin, $signup } = useSurrealDB({ database: db }); const session = useState(sessionName, () => ({})); const setToken = (unixTimestamp) => useCookie(cookieName, { ...unixTimestamp && { expires: new Date(unixTimestamp * 1e3) }, sameSite, secure: !import.meta.dev }); const token = setToken(); async function reAuthenticate() { if (!token.value) throw createError({ statusCode: 401, message: "Unauthorized" }); await $authenticate(token.value); await refreshInfo(); } async function getSessionExp(authToken) { const _token = authToken || token.value; if (!_token) throw createError({ statusCode: 401, message: "Unauthorized" }); return (await $query("SELECT exp FROM $session;", void 0, { token: _token }))[0].result[0]; } async function refreshInfo(authToken) { const _token = authToken || token.value; if (!_token) throw createError({ statusCode: 401, message: "Unauthorized" }); const result = await $info({ token: _token }); if (!result) return; session.value.user = result; } async function invalidate(authToken) { const _token = authToken || token.value; if (!_token) throw createError({ statusCode: 401, message: "Unauthorized" }); await $invalidate({ token: _token }).then(() => { token.value = null; session.value = {}; }); } async function signin(credentials, o = {}) { const { NS, DB, SC, AC } = db; if ((!NS || !DB) && !o.admin) throw createError({ statusCode: 500, message: "Sign In: Missing database preset" }); const SC_AC = _userScope("Sign In: Missing either SC/AC", SC, AC); const result = await $signin({ ...credentials, ...!o.admin && { NS, DB, ...SC_AC } }); if (result) { await getSessionExp(result).then(async ({ exp }) => { if (!exp) throw createError({ statusCode: 401, message: "User is not authenticated" }); else if (exp === "NONE") { setToken(adminMaxAge).value = result; await refreshInfo(result); } else { setToken(exp).value = result; await refreshInfo(result); } }); } } async function signup(credentials) { const { NS, DB, SC, AC } = db; if (!NS || !DB) throw createError({ statusCode: 500, message: "Sign Up: Missing database preset" }); const SC_AC = _userScope("Sign Up: Missing either SC/AC", SC, AC); const result = await $signup({ ...credentials, NS, DB, ...SC_AC }); if (result) { await getSessionExp(result).then(async ({ exp }) => { if (!exp) throw createError({ statusCode: 401, message: "User is not authenticated" }); else { setToken(exp).value = result; await refreshInfo(result); } }); } } function _userScope(message, SC, AC) { if (AC) return { AC }; else if (SC) return { SC }; throw createError({ statusCode: 500, message }); } return { getSessionExp, isAuthenticated: computed(() => Boolean(session.value.user)), invalidate, reAuthenticate, session, signin, signout: invalidate, signup, token, refreshInfo, user: computed(() => session.value.user || null) }; }