Provide a basic account system with login and server side session store identified by a cookie. Upon successful login a signed session cookie is set by the server with the session stored on the server identifying which account it is logged in as. The client uses a shared useFetch on the session endpoint to identify if it's logged in and which account it is logged in as, and refreshes this when loggin in or out.
64 lines
1.3 KiB
Vue
64 lines
1.3 KiB
Vue
<template>
|
|
<header>
|
|
<nav>
|
|
<ul>
|
|
<NuxtLink to="/">Home</NuxtLink>
|
|
<NuxtLink to="/schedule">Schedule</NuxtLink>
|
|
</ul>
|
|
</nav>
|
|
<div class="account">
|
|
<template v-if="session?.account">
|
|
{{ session?.account.name || "anonymous" }}
|
|
(s:{{ session?.id }} a:{{ session?.account.id }})
|
|
{{ session?.account.type }}
|
|
<button type="button" @click="logOut">Log out</button>
|
|
</template>
|
|
<template v-else>
|
|
<NuxtLink to="/login">Log In</NuxtLink>
|
|
</template>
|
|
</div>
|
|
</header>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
const { data: session, refresh: sessionRefresh } = useAccountSession();
|
|
|
|
async function logOut() {
|
|
try {
|
|
const res = await $fetch.raw("/api/auth/session", {
|
|
method: "DELETE",
|
|
});
|
|
await sessionRefresh();
|
|
|
|
} catch (err: any) {
|
|
alert(`Log out failed: ${err.statusCode} ${err.statusMessage}`);
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
header {
|
|
line-height: 1.5; /* Prevent layout shift from log out button */
|
|
display: flex;
|
|
column-gap: 1em;
|
|
flex-wrap: wrap;
|
|
border-bottom: 1px solid var(--foreground);
|
|
margin-block-start: 1rem;
|
|
}
|
|
.account {
|
|
display: flex;
|
|
justify-content: end;
|
|
flex-grow: 1;
|
|
column-gap: 0.5em;
|
|
flex-wrap: wrap;
|
|
}
|
|
nav ul {
|
|
padding: 0;
|
|
display: flex;
|
|
column-gap: 0.5em;
|
|
}
|
|
button {
|
|
font-family: inherit;
|
|
font-size: inherit;
|
|
}
|
|
</style>
|