67 lines
2.2 KiB
TypeScript
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;
|
||
|
|
}
|