115 lines
2.5 KiB
Vue
115 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
definePageMeta({ layout: false });
|
|
useHead({ title: "Sign-In Error — Ghost Guild" });
|
|
|
|
const route = useRoute();
|
|
|
|
// Vue's default {{ }} interpolation escapes HTML on render, so these
|
|
// values from the query string can never execute as markup — fixing the
|
|
// XSS that existed in the old guildPageShell renderError implementation.
|
|
const errorCode = computed(() =>
|
|
typeof route.query.error === "string" ? route.query.error : "",
|
|
);
|
|
const errorDescription = computed(() =>
|
|
typeof route.query.error_description === "string"
|
|
? route.query.error_description
|
|
: "",
|
|
);
|
|
const hasDetail = computed(
|
|
() => Boolean(errorCode.value) || Boolean(errorDescription.value),
|
|
);
|
|
</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">Something went wrong</h1>
|
|
</header>
|
|
|
|
<hr class="section-divider" />
|
|
|
|
<p class="auth-body">
|
|
An error occurred during authentication. Please try again.
|
|
</p>
|
|
|
|
<div v-if="hasDetail" class="auth-detail" role="status">
|
|
<p v-if="errorCode" class="auth-detail-code">{{ errorCode }}</p>
|
|
<p v-if="errorDescription" class="auth-detail-desc">
|
|
{{ errorDescription }}
|
|
</p>
|
|
</div>
|
|
|
|
<a href="https://wiki.ghostguild.org" class="btn btn-primary auth-btn">
|
|
Return to Wiki
|
|
</a>
|
|
</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-detail {
|
|
border: 1px dashed var(--border);
|
|
padding: 12px 14px;
|
|
font-family: "Commit Mono", monospace;
|
|
font-size: 12px;
|
|
color: var(--text-dim);
|
|
text-align: left;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.auth-detail-code {
|
|
color: var(--ember);
|
|
font-weight: 600;
|
|
margin: 0 0 4px;
|
|
}
|
|
|
|
.auth-detail-desc {
|
|
margin: 0;
|
|
}
|
|
|
|
.auth-btn {
|
|
width: 100%;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-top: 4px;
|
|
}
|
|
</style>
|