Add error page for when a session has been taken

Describe to the user what it means when a session has been detected as
taken and provide a means to abandoned the session and log in again.
This commit is contained in:
Hornwitser 2025-07-08 15:51:50 +02:00
parent 011687b391
commit ebeedff5d0
2 changed files with 49 additions and 9 deletions

View file

@ -3,6 +3,35 @@
SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<template v-if='data?.data?.code === "SESSION_TAKEN"'>
<h1>Session taken</h1>
<p>
Your session with the server has been taken over by another browser, device, or HTTP agent. This could happen due to one of the following reasons:
</p>
<ul>
<li>
The session cookie on this device got restored to an earlier state for example as a result of a restore or a crash.
</li>
<li>
The server issued a new session to the client but the client didn't get the repsonse.
</li>
<li>
The session cookie was copied and used on another device, browser or HTTP agent.
</li>
</ul>
<p>
It's possible however unlikely that someone else have hijacked your session.
</p>
<p>
<button
type="button"
@click="abandonSession"
>
Abandon Session
</button>
</p>
</template>
<template v-else>
<Header />
<h1>{{ error.statusCode }} {{ error.statusMessage }}</h1>
<p v-if="error.message !== error.statusMessage">
@ -10,19 +39,29 @@
</p>
<pre v-if="error.stack"><code>{{ error.stack }}</code></pre>
</template>
</template>
<script setup lang="ts">
defineProps<{ error: {
const props = defineProps<{ error: {
statusCode: number,
fatal: boolean,
unhandled: boolean,
statusMessage?: string,
data?: unknown,
data?: string,
cause?: unknown,
// Undocumented fields
url?: string,
message?: string,
stack?: string,
} }>()
}}>();
const data = computed<{
data?: {
code?: string,
},
}>(() => props.error.data ? JSON.parse(props.error.data) : undefined);
async function abandonSession() {
await $fetch("/api/auth/session", { method: "DELETE", }).catch(err => alert(err.message));
await navigateTo("/");
}
</script>

View file

@ -106,6 +106,7 @@ export async function getServerSession(event: H3Event, ignoreExpired: boolean) {
statusCode: 403,
statusMessage: "Forbidden",
message: "Session has been taken by another agent.",
data: { code: "SESSION_TAKEN" },
});
}
const now = Date.now();