mirror of
https://github.com/better-auth/better-auth.git
synced 2026-05-23 15:42:09 -05:00
fix: multi session conflicting with nextjs plugin on clearing cookies
This commit is contained in:
@@ -19,7 +19,7 @@ describe("session", async () => {
|
||||
const cookies = parseSetCookieHeader(header || "");
|
||||
expect(cookies.get("better-auth.session_token")).toMatchObject({
|
||||
value: expect.any(String),
|
||||
"max-age": (60 * 60 * 24 * 7).toString(),
|
||||
"max-age": 60 * 60 * 24 * 7,
|
||||
path: "/",
|
||||
httponly: true,
|
||||
samesite: "lax",
|
||||
@@ -141,7 +141,7 @@ describe("session", async () => {
|
||||
const cookies = parseSetCookieHeader(header || "");
|
||||
expect(cookies.get("better-auth.session_token")).toMatchObject({
|
||||
value: expect.any(String),
|
||||
"max-age": (60 * 60 * 24 * 7).toString(),
|
||||
"max-age": 60 * 60 * 24 * 7,
|
||||
path: "/",
|
||||
httponly: true,
|
||||
samesite: "lax",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
interface CookieAttributes {
|
||||
value: string;
|
||||
"max-age"?: string;
|
||||
"max-age"?: number;
|
||||
expires?: Date;
|
||||
domain?: string;
|
||||
path?: string;
|
||||
@@ -34,12 +34,13 @@ export function parseSetCookieHeader(
|
||||
const [attrName, ...attrValueParts] = attribute.split("=");
|
||||
const attrValue = attrValueParts.join("=");
|
||||
|
||||
// Normalize the attribute name to camelCase
|
||||
const normalizedAttrName = attrName.trim().toLowerCase();
|
||||
|
||||
switch (normalizedAttrName) {
|
||||
case "max-age":
|
||||
attrObj["max-age"] = attrValue;
|
||||
attrObj["max-age"] = attrValue
|
||||
? parseInt(attrValue.trim(), 10)
|
||||
: undefined;
|
||||
break;
|
||||
case "expires":
|
||||
attrObj.expires = attrValue ? new Date(attrValue.trim()) : undefined;
|
||||
|
||||
@@ -24,24 +24,23 @@ export const nextCookies = () => {
|
||||
hooks: {
|
||||
after: [
|
||||
{
|
||||
matcher() {
|
||||
matcher(ctx) {
|
||||
return true;
|
||||
},
|
||||
handler: async (ctx) => {
|
||||
const returned = ctx.context.endpoint?.headers;
|
||||
const returned = ctx.responseHeader;
|
||||
if (returned instanceof Headers) {
|
||||
const setCookies = returned?.get("set-cookie");
|
||||
if (!setCookies) return;
|
||||
const parsed = parseSetCookieHeader(setCookies);
|
||||
const cookieHelper = await cookies();
|
||||
parsed.forEach((value, key) => {
|
||||
if (!value) return;
|
||||
if (!key) return;
|
||||
const opts = {
|
||||
samesite: value.samesite,
|
||||
sameSite: value.samesite,
|
||||
secure: value.secure,
|
||||
"max-age": value["max-age"],
|
||||
httponly: value.httponly,
|
||||
maxAge: value["max-age"],
|
||||
httpOnly: value.httponly,
|
||||
domain: value.domain,
|
||||
path: value.path,
|
||||
};
|
||||
|
||||
@@ -6,11 +6,13 @@ import {
|
||||
sessionMiddleware,
|
||||
} from "../../api";
|
||||
import {
|
||||
deleteSessionCookie,
|
||||
parseCookies,
|
||||
parseSetCookieHeader,
|
||||
setSessionCookie,
|
||||
} from "../../cookies";
|
||||
import type { BetterAuthPlugin } from "../../types";
|
||||
import { returnHookResponse } from "../../utils/plugin-helper";
|
||||
|
||||
interface MultiSessionConfig {
|
||||
/**
|
||||
@@ -98,12 +100,7 @@ export const multiSession = (options?: MultiSessionConfig) => {
|
||||
message: "Invalid session id",
|
||||
});
|
||||
}
|
||||
await ctx.setSignedCookie(
|
||||
ctx.context.authCookies.sessionToken.name,
|
||||
sessionId,
|
||||
ctx.context.secret,
|
||||
ctx.context.authCookies.sessionToken.options,
|
||||
);
|
||||
await setSessionCookie(ctx, session);
|
||||
return ctx.json(session);
|
||||
},
|
||||
),
|
||||
@@ -139,7 +136,6 @@ export const multiSession = (options?: MultiSessionConfig) => {
|
||||
if (!isActive) return ctx.json({ success: true });
|
||||
|
||||
const cookieHeader = ctx.headers?.get("cookie");
|
||||
const authCookies = ctx.context.authCookies;
|
||||
if (cookieHeader) {
|
||||
const cookies = Object.fromEntries(parseCookies(cookieHeader));
|
||||
|
||||
@@ -165,22 +161,13 @@ export const multiSession = (options?: MultiSessionConfig) => {
|
||||
const nextSession = validSessions[0];
|
||||
await setSessionCookie(ctx, nextSession);
|
||||
} else {
|
||||
ctx.setCookie(authCookies.sessionToken.name, "", {
|
||||
...authCookies.sessionToken.options,
|
||||
maxAge: 0,
|
||||
});
|
||||
deleteSessionCookie(ctx);
|
||||
}
|
||||
} else {
|
||||
ctx.setCookie(authCookies.sessionToken.name, "", {
|
||||
...authCookies.sessionToken.options,
|
||||
maxAge: 0,
|
||||
});
|
||||
deleteSessionCookie(ctx);
|
||||
}
|
||||
} else {
|
||||
ctx.setCookie(authCookies.sessionToken.name, "", {
|
||||
...authCookies.sessionToken.options,
|
||||
maxAge: 0,
|
||||
});
|
||||
deleteSessionCookie(ctx);
|
||||
}
|
||||
return ctx.json({
|
||||
success: true,
|
||||
@@ -244,22 +231,27 @@ export const multiSession = (options?: MultiSessionConfig) => {
|
||||
handler: createAuthMiddleware(async (ctx) => {
|
||||
const cookieHeader = ctx.headers?.get("cookie");
|
||||
if (!cookieHeader) return;
|
||||
|
||||
const cookies = Object.fromEntries(parseCookies(cookieHeader));
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(cookies).map(async ([key, value]) => {
|
||||
const ids = Object.keys(cookies)
|
||||
.map((key) => {
|
||||
if (isMultiSessionCookie(key)) {
|
||||
ctx.setCookie(key, "", { maxAge: 0 });
|
||||
const id = key.split("_multi-")[1];
|
||||
await ctx.context.internalAdapter.deleteSession(id);
|
||||
return id;
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
responseHeader: ctx.responseHeader,
|
||||
};
|
||||
return null;
|
||||
})
|
||||
.filter((v): v is string => v !== null);
|
||||
await ctx.context.internalAdapter.deleteSessions(ids);
|
||||
const response = ctx.context.returned;
|
||||
if (response instanceof Response) {
|
||||
console.log("response", ctx.responseHeader.get("set-cookie"));
|
||||
response.headers.append(
|
||||
"Set-Cookie",
|
||||
ctx.responseHeader.get("set-cookie")!,
|
||||
);
|
||||
return { response };
|
||||
}
|
||||
}),
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user