www_site/apps/cms/src/app/(payload)/api/cms-logout/route.ts

67 lines
2.2 KiB
TypeScript

import config from "@payload-config";
import { headers as getHeaders } from "next/headers";
import { NextResponse } from "next/server";
import { createLocalReq, getPayload, logoutOperation } from "payload";
const COOKIE_PATHS = ["/", "/cms", "/cms/admin", "/cms/api"];
const EXPIRED_DATE = "Thu, 01 Jan 1970 00:00:00 GMT";
function appendExpiredCookie(response: NextResponse, name: string, path: string, domain?: string) {
const domainPart = domain ? `; Domain=${domain}` : "";
response.headers.append(
"Set-Cookie",
`${name}=; Path=${path}${domainPart}; Expires=${EXPIRED_DATE}; Max-Age=0; HttpOnly; SameSite=Lax`,
);
}
function getDomainCandidates(host: string | null) {
if (!host) {
return [undefined];
}
const hostname = host.split(":")[0]?.toLowerCase();
if (!hostname || hostname === "localhost" || /^[\d.]+$/.test(hostname)) {
return [undefined];
}
const parentDomain = hostname.startsWith("www.") ? hostname.slice(4) : undefined;
return Array.from(new Set([undefined, hostname, parentDomain ? `.${parentDomain}` : undefined]));
}
export async function POST() {
const requestHeaders = await getHeaders();
const response = NextResponse.json({ success: true }, { headers: { "Cache-Control": "no-store" } });
try {
const payload = await getPayload({ config, cron: true });
const authResult = await payload.auth({ headers: requestHeaders });
const user = authResult.user;
if (user) {
const req = await createLocalReq({ user }, payload);
const collection = payload.collections[user.collection];
if (collection) {
await logoutOperation({ allSessions: false, collection, req });
}
}
} catch (error) {
console.error("CMS logout operation failed", error);
}
const configuredPrefix = (config as { cookiePrefix?: string }).cookiePrefix || "payload";
const cookieNames = new Set(["payload-token", `${configuredPrefix}-token`]);
const domains = getDomainCandidates(requestHeaders.get("host"));
for (const name of cookieNames) {
for (const path of COOKIE_PATHS) {
for (const domain of domains) {
appendExpiredCookie(response, name, path, domain);
}
}
}
return response;
}