🐛 Fix session empty session when logging out (#1345)

This commit is contained in:
Luke Vella 2024-09-13 17:39:25 +01:00 committed by GitHub
parent b75dfed611
commit 8f34f755b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 36 additions and 36 deletions

View file

@ -1,10 +0,0 @@
import { NextResponse } from "next/server";
import { resetUser } from "@/app/guest";
import { absoluteUrl } from "@/utils/absolute-url";
export async function POST() {
const res = NextResponse.redirect(absoluteUrl("/login"), 302);
await resetUser(res);
return res;
}

View file

@ -0,0 +1,9 @@
import { NextRequest, NextResponse } from "next/server";
import { resetUser } from "@/app/guest";
export async function POST(req: NextRequest) {
const res = NextResponse.json({ ok: 1 });
await resetUser(req, res);
return res;
}

View file

@ -1,6 +1,5 @@
"use client"; "use client";
import { Button, ButtonProps } from "@rallly/ui/button"; import { Button, ButtonProps } from "@rallly/ui/button";
import { signOut } from "next-auth/react";
import { usePostHog } from "@/utils/posthog"; import { usePostHog } from "@/utils/posthog";
@ -15,12 +14,10 @@ export function LogoutButton({
{...rest} {...rest}
onClick={async (e) => { onClick={async (e) => {
onClick?.(e); onClick?.(e);
await fetch("/api/logout", { method: "POST" });
posthog?.capture("logout"); posthog?.capture("logout");
posthog?.reset(); posthog?.reset();
signOut({ window.location.href = "/login";
redirect: true,
callbackUrl: "/login",
});
}} }}
> >
{children} {children}

View file

@ -1,9 +1,13 @@
import languages from "@rallly/languages";
import languageParser from "accept-language-parser";
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
import { encode, JWT } from "next-auth/jwt"; import { encode, JWT } from "next-auth/jwt";
import { absoluteUrl } from "@/utils/absolute-url"; import { absoluteUrl } from "@/utils/absolute-url";
import { randomid } from "@/utils/nanoid"; import { randomid } from "@/utils/nanoid";
const supportedLocales = Object.keys(languages);
function getCookieSettings() { function getCookieSettings() {
const secure = absoluteUrl().startsWith("https://"); const secure = absoluteUrl().startsWith("https://");
const prefix = secure ? "__Secure-" : ""; const prefix = secure ? "__Secure-" : "";
@ -14,6 +18,16 @@ function getCookieSettings() {
}; };
} }
export async function getLocaleFromHeader(req: NextRequest) {
// Check if locale is specified in header
const headers = req.headers;
const acceptLanguageHeader = headers.get("accept-language");
const localeFromHeader = acceptLanguageHeader
? languageParser.pick(supportedLocales, acceptLanguageHeader)
: null;
return localeFromHeader ?? "en";
}
async function setCookie(res: NextResponse, jwt: JWT) { async function setCookie(res: NextResponse, jwt: JWT) {
const { name, secure } = getCookieSettings(); const { name, secure } = getCookieSettings();
@ -32,25 +46,20 @@ async function setCookie(res: NextResponse, jwt: JWT) {
}); });
} }
export async function resetUser(res: NextResponse) { export async function resetUser(req: NextRequest, res: NextResponse) {
// resets to a new guest user // resets to a new guest user
const locale = await getLocaleFromHeader(req);
const jwt: JWT = { const jwt: JWT = {
sub: `user-${randomid()}`, sub: `user-${randomid()}`,
email: null, email: null,
locale,
}; };
await setCookie(res, jwt); await setCookie(res, jwt);
} }
export async function initGuest( export async function initGuest(req: NextRequest, res: NextResponse) {
req: NextRequest,
res: NextResponse,
{
locale,
}: {
locale: string;
},
) {
const { name } = getCookieSettings(); const { name } = getCookieSettings();
if (req.cookies.has(name)) { if (req.cookies.has(name)) {
@ -58,6 +67,8 @@ export async function initGuest(
return; return;
} }
const locale = await getLocaleFromHeader(req);
const jwt: JWT = { const jwt: JWT = {
sub: `user-${randomid()}`, sub: `user-${randomid()}`,
email: null, email: null,

View file

@ -1,16 +1,15 @@
import languages from "@rallly/languages"; import languages from "@rallly/languages";
import languageParser from "accept-language-parser";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import withAuth from "next-auth/middleware"; import withAuth from "next-auth/middleware";
import { initGuest } from "@/app/guest"; import { getLocaleFromHeader, initGuest } from "@/app/guest";
import { isSelfHosted } from "@/utils/constants"; import { isSelfHosted } from "@/utils/constants";
const supportedLocales = Object.keys(languages); const supportedLocales = Object.keys(languages);
export const middleware = withAuth( export const middleware = withAuth(
async function middleware(req) { async function middleware(req) {
const { headers, nextUrl } = req; const { nextUrl } = req;
const newUrl = nextUrl.clone(); const newUrl = nextUrl.clone();
// if the user is already logged in, don't let them access the login page // if the user is already logged in, don't let them access the login page
@ -28,20 +27,14 @@ export const middleware = withAuth(
newUrl.pathname = `/${locale}${newUrl.pathname}`; newUrl.pathname = `/${locale}${newUrl.pathname}`;
} else { } else {
// Check if locale is specified in header // Check if locale is specified in header
const acceptLanguageHeader = headers.get("accept-language"); locale = await getLocaleFromHeader(req);
const localeFromHeader = acceptLanguageHeader
? languageParser.pick(supportedLocales, acceptLanguageHeader)
: null;
locale = localeFromHeader ?? "en";
newUrl.pathname = `/${locale}${newUrl.pathname}`; newUrl.pathname = `/${locale}${newUrl.pathname}`;
} }
const res = NextResponse.rewrite(newUrl); const res = NextResponse.rewrite(newUrl);
await initGuest(req, res, { await initGuest(req, res);
locale,
});
return res; return res;
}, },