ghostguild-org/app/pages/auth/logout-confirm.vue
Jennie Robinson Faber d93c16fbf7 style(visual-fidelity): pages-auth — batches D,G
font-weight 700 → 600 across auth pages; wiki-login hero 32→36
2026-04-30 00:13:05 +01:00

121 lines
2.7 KiB
Vue

<script setup lang="ts">
definePageMeta({ layout: false });
useHead({ title: "Sign Out — Ghost Guild" });
// The xsrf token comes from a short-lived httpOnly cookie set by
// oidc-provider's logoutSource callback (see server/utils/oidc-provider.ts).
// We consume it during SSR, persist it into useState so the form input
// hydrates correctly on the client, and clear the cookie immediately so the
// token is strictly one-time use.
const xsrf = useState<string>("oidc-logout-xsrf", () => "");
if (import.meta.server && !xsrf.value) {
const cookie = useCookie("oidc_logout_xsrf");
if (cookie.value) {
xsrf.value = cookie.value;
cookie.value = null;
} else {
// No active logout flow — somebody hit this page directly. Send them
// back to the wiki rather than render a dead form.
await navigateTo("https://wiki.ghostguild.org", {
external: true,
replace: true,
});
}
}
</script>
<template>
<main class="auth-shell">
<div class="dashed-box auth-box">
<header class="auth-header">
<p class="section-label">Ghost Guild</p>
<h1 class="auth-title">Sign Out</h1>
</header>
<hr class="section-divider" />
<p class="auth-body">
Do you want to sign out of your Ghost Guild session?
</p>
<p class="auth-sub">
This will sign you out of the wiki and any other connected services.
</p>
<form
method="post"
action="/oidc/session/end/confirm"
class="auth-form"
>
<input type="hidden" name="xsrf" :value="xsrf" />
<input type="hidden" name="logout" value="yes" />
<button type="submit" class="btn btn-primary auth-btn">
Yes, sign me out
</button>
<a href="https://wiki.ghostguild.org" class="btn auth-btn auth-btn-secondary">
Stay signed in
</a>
</form>
</div>
</main>
</template>
<style scoped>
.auth-shell {
display: grid;
place-items: center;
min-height: 100vh;
min-height: 100dvh;
padding: var(--page-pad-y) var(--page-pad-x);
}
.auth-box {
width: 100%;
max-width: 420px;
padding: 24px 28px;
}
.auth-header {
text-align: center;
}
.auth-title {
font-family: var(--font-display);
font-size: 28px;
font-weight: 600;
line-height: 1.1;
letter-spacing: -0.01em;
color: var(--candle);
margin: 0;
}
.auth-body {
font-size: 14px;
color: var(--text);
line-height: 1.55;
text-align: center;
margin: 0;
}
.auth-sub {
font-size: 12px;
color: var(--text-dim);
line-height: 1.5;
text-align: center;
margin: 0;
}
.auth-form {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 4px;
}
.auth-btn {
width: 100%;
display: inline-flex;
align-items: center;
justify-content: center;
}
</style>