nuxt-surrealdb
Version:
A Nuxt module aimed to simplify the use of SurrealDB
121 lines (120 loc) • 3.69 kB
JavaScript
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)
};
}