diff --git a/apps/web/src/app/[locale]/auth/logout/route.ts b/apps/web/src/app/[locale]/auth/logout/route.ts deleted file mode 100644 index 7e55c2e1e..000000000 --- a/apps/web/src/app/[locale]/auth/logout/route.ts +++ /dev/null @@ -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; -} diff --git a/apps/web/src/app/api/logout/route.ts b/apps/web/src/app/api/logout/route.ts new file mode 100644 index 000000000..6887de148 --- /dev/null +++ b/apps/web/src/app/api/logout/route.ts @@ -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; +} diff --git a/apps/web/src/app/components/logout-button.tsx b/apps/web/src/app/components/logout-button.tsx index c78496dfc..47693ac86 100644 --- a/apps/web/src/app/components/logout-button.tsx +++ b/apps/web/src/app/components/logout-button.tsx @@ -1,6 +1,5 @@ "use client"; import { Button, ButtonProps } from "@rallly/ui/button"; -import { signOut } from "next-auth/react"; import { usePostHog } from "@/utils/posthog"; @@ -15,12 +14,10 @@ export function LogoutButton({ {...rest} onClick={async (e) => { onClick?.(e); + await fetch("/api/logout", { method: "POST" }); posthog?.capture("logout"); posthog?.reset(); - signOut({ - redirect: true, - callbackUrl: "/login", - }); + window.location.href = "/login"; }} > {children} diff --git a/apps/web/src/app/guest.ts b/apps/web/src/app/guest.ts index 20d245c3a..c56cd5e61 100644 --- a/apps/web/src/app/guest.ts +++ b/apps/web/src/app/guest.ts @@ -1,9 +1,13 @@ +import languages from "@rallly/languages"; +import languageParser from "accept-language-parser"; import { NextRequest, NextResponse } from "next/server"; import { encode, JWT } from "next-auth/jwt"; import { absoluteUrl } from "@/utils/absolute-url"; import { randomid } from "@/utils/nanoid"; +const supportedLocales = Object.keys(languages); + function getCookieSettings() { const secure = absoluteUrl().startsWith("https://"); 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) { 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 + const locale = await getLocaleFromHeader(req); + const jwt: JWT = { sub: `user-${randomid()}`, email: null, + locale, }; await setCookie(res, jwt); } -export async function initGuest( - req: NextRequest, - res: NextResponse, - { - locale, - }: { - locale: string; - }, -) { +export async function initGuest(req: NextRequest, res: NextResponse) { const { name } = getCookieSettings(); if (req.cookies.has(name)) { @@ -58,6 +67,8 @@ export async function initGuest( return; } + const locale = await getLocaleFromHeader(req); + const jwt: JWT = { sub: `user-${randomid()}`, email: null, diff --git a/apps/web/src/middleware.ts b/apps/web/src/middleware.ts index 9a3425677..23e50cdb6 100644 --- a/apps/web/src/middleware.ts +++ b/apps/web/src/middleware.ts @@ -1,16 +1,15 @@ import languages from "@rallly/languages"; -import languageParser from "accept-language-parser"; import { NextResponse } from "next/server"; import withAuth from "next-auth/middleware"; -import { initGuest } from "@/app/guest"; +import { getLocaleFromHeader, initGuest } from "@/app/guest"; import { isSelfHosted } from "@/utils/constants"; const supportedLocales = Object.keys(languages); export const middleware = withAuth( async function middleware(req) { - const { headers, nextUrl } = req; + const { nextUrl } = req; const newUrl = nextUrl.clone(); // 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}`; } else { // Check if locale is specified in header - const acceptLanguageHeader = headers.get("accept-language"); - const localeFromHeader = acceptLanguageHeader - ? languageParser.pick(supportedLocales, acceptLanguageHeader) - : null; - locale = localeFromHeader ?? "en"; + locale = await getLocaleFromHeader(req); newUrl.pathname = `/${locale}${newUrl.pathname}`; } const res = NextResponse.rewrite(newUrl); - await initGuest(req, res, { - locale, - }); + await initGuest(req, res); return res; },