diff --git a/frontend/index.html b/frontend/index.html
index 7ffbbff..97b7829 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -17,8 +17,8 @@
<
-
-
+
+
+
+
+ class="fixed top-14 left-0 right-0 bottom-0 bg-black opacity-0 pointer-events-none transition-opacity duration-300 z-30">
diff --git a/frontend/src/auth/index.ts b/frontend/src/auth/index.ts
index 449dabc..008e94d 100644
--- a/frontend/src/auth/index.ts
+++ b/frontend/src/auth/index.ts
@@ -1,5 +1,8 @@
import { showError } from "@app/toast";
import client from '@app/api';
+import cookie from 'js-cookie';
+
+cookie.remove('pkce');
export type User = {
id: string;
diff --git a/frontend/src/carousel/index.ts b/frontend/src/carousel/index.ts
index 999c996..693e21d 100644
--- a/frontend/src/carousel/index.ts
+++ b/frontend/src/carousel/index.ts
@@ -7,6 +7,7 @@ const overlay = document.querySelector('#overlay')!;
menuBtn.addEventListener('click', () => {
sidebar.classList.toggle('-translate-x-full')
overlay.classList.toggle('opacity-0');
+ overlay.classList.toggle('opacity-40');
overlay.classList.toggle('pointer-events-none');
menuBtn.classList.toggle('flipped');
});
@@ -14,4 +15,5 @@ menuBtn.addEventListener('click', () => {
overlay.addEventListener('click', () => {
sidebar.classList.add('-translate-x-full');
overlay.classList.add('opacity-0', 'pointer-events-none');
+ overlay.classList.remove('opacity-40');
});
diff --git a/frontend/src/pages/index.ts b/frontend/src/pages/index.ts
index dfab156..92cebd5 100644
--- a/frontend/src/pages/index.ts
+++ b/frontend/src/pages/index.ts
@@ -5,6 +5,7 @@ import './login/login.ts'
import './signin/signin.ts'
import './ttt/ttt.ts'
import './profile/profile.ts'
+import './logout/logout.ts'
// ---- Initial load ----
setTitle("");
diff --git a/frontend/src/pages/login/login.ts b/frontend/src/pages/login/login.ts
index 5eb5123..f128455 100644
--- a/frontend/src/pages/login/login.ts
+++ b/frontend/src/pages/login/login.ts
@@ -17,7 +17,11 @@ import { updateUser } from "@app/auth";
const TOTP_LENGTH = 6;
-async function handleOtp(app: HTMLElement, token: string, returnTo: string | null) {
+async function handleOtp(
+ app: HTMLElement,
+ token: string,
+ returnTo: string | null,
+) {
app.innerHTML = totpHtml;
const container = app.querySelector("#totp-container")!;
@@ -76,19 +80,18 @@ async function handleOtp(app: HTMLElement, token: string, returnTo: string | nul
if (code.length === TOTP_LENGTH && /^[0-9]+$/.test(code)) {
let res = await client.loginOtp({
loginOtpRequest: {
- code, token,
- }
- })
+ code,
+ token,
+ },
+ });
if (res.kind === "success") {
Cookie.set("token", res.payload.token, {
path: "/",
sameSite: "lax",
});
- if (returnTo !== null) navigateTo(returnTo);
- else navigateTo("/");
- }
- else if (res.kind === "failed") {
+ navigateTo(returnTo ?? "/");
+ } else if (res.kind === "failed") {
showError(`Failed to authenticate: ${res.msg}`);
}
}
@@ -97,7 +100,6 @@ async function handleOtp(app: HTMLElement, token: string, returnTo: string | nul
inputs[0].focus();
}
-
async function handleLogin(
_url: string,
_args: RouteHandlerParams,
@@ -131,7 +133,7 @@ async function handleLogin(
if (returnTo !== null) {
bReturnTo.parentElement!.hidden = false;
bReturnTo.addEventListener("click", async () => {
- if (returnTo !== null) navigateTo(returnTo);
+ navigateTo(returnTo ?? "/");
});
}
},
@@ -189,11 +191,15 @@ async function handleLogin(
setTitle(
`Welcome ${user.guest ? "[GUEST] " : ""}${user.name}`,
);
- if (returnTo !== null) navigateTo(returnTo);
+ navigateTo(returnTo ?? "/");
break;
}
case "otpRequired": {
- return await handleOtp(app!, res.payload.token, returnTo);
+ return await handleOtp(
+ app!,
+ res.payload.token,
+ returnTo,
+ );
}
case "failed": {
showError(`Failed to login: ${res.msg}`);
@@ -209,7 +215,9 @@ async function handleLogin(
document.querySelector("#bGuestLogin");
bLoginAsGuest?.addEventListener("click", async () => {
try {
- const res = await client.guestLogin({ guestLoginRequest: { name: undefined } });
+ const res = await client.guestLogin({
+ guestLoginRequest: { name: undefined },
+ });
switch (res.kind) {
case "success": {
Cookie.set("token", res.payload.token, {
@@ -224,7 +232,7 @@ async function handleLogin(
setTitle(
`Welcome ${user.guest ? "[GUEST] " : ""}${user.name}`,
);
- if (returnTo !== null) navigateTo(returnTo);
+ navigateTo(returnTo ?? "/");
break;
}
case "failed": {
diff --git a/frontend/src/pages/logout/logout.ts b/frontend/src/pages/logout/logout.ts
new file mode 100644
index 0000000..16fa9a4
--- /dev/null
+++ b/frontend/src/pages/logout/logout.ts
@@ -0,0 +1,16 @@
+import { addRoute, navigateTo, setTitle, type RouteHandlerReturn } from "@app/routing";
+import cookie from "js-cookie";
+
+async function route(_url: string, _args: { [k: string]: string }): Promise {
+ setTitle('Logout')
+ return {
+ html: "you should have been logged out", postInsert: async (app) => {
+ cookie.remove("token");
+ navigateTo("/");
+ }
+ };
+}
+
+
+
+addRoute('/logout', route, { bypass_auth: true })