mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 19:47:34 +00:00
override cookie sameSite settings
This commit is contained in:
@@ -20,7 +20,10 @@ export type Cookie = {
|
|||||||
|
|
||||||
type SessionCookie<T> = Cookie & T;
|
type SessionCookie<T> = Cookie & T;
|
||||||
|
|
||||||
async function setSessionHttpOnlyCookie<T>(sessions: SessionCookie<T>[]) {
|
async function setSessionHttpOnlyCookie<T>(
|
||||||
|
sessions: SessionCookie<T>[],
|
||||||
|
sameSite: boolean | "lax" | "strict" | "none" = true,
|
||||||
|
) {
|
||||||
const cookiesList = await cookies();
|
const cookiesList = await cookies();
|
||||||
|
|
||||||
return cookiesList.set({
|
return cookiesList.set({
|
||||||
@@ -28,6 +31,7 @@ async function setSessionHttpOnlyCookie<T>(sessions: SessionCookie<T>[]) {
|
|||||||
value: JSON.stringify(sessions),
|
value: JSON.stringify(sessions),
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
path: "/",
|
path: "/",
|
||||||
|
sameSite,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +46,15 @@ export async function setLanguageCookie(language: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addSessionToCookie<T>(
|
export async function addSessionToCookie<T>({
|
||||||
session: SessionCookie<T>,
|
session,
|
||||||
cleanup: boolean = false,
|
cleanup,
|
||||||
): Promise<any> {
|
sameSite,
|
||||||
|
}: {
|
||||||
|
session: SessionCookie<T>;
|
||||||
|
cleanup?: boolean;
|
||||||
|
sameSite?: boolean | "lax" | "strict" | "none" | undefined;
|
||||||
|
}): Promise<any> {
|
||||||
const cookiesList = await cookies();
|
const cookiesList = await cookies();
|
||||||
const stringifiedCookie = cookiesList.get("sessions");
|
const stringifiedCookie = cookiesList.get("sessions");
|
||||||
|
|
||||||
@@ -79,17 +88,23 @@ export async function addSessionToCookie<T>(
|
|||||||
? timestampDate(timestampFromMs(Number(session.expirationTs))) > now
|
? timestampDate(timestampFromMs(Number(session.expirationTs))) > now
|
||||||
: true,
|
: true,
|
||||||
);
|
);
|
||||||
return setSessionHttpOnlyCookie(filteredSessions);
|
return setSessionHttpOnlyCookie(filteredSessions, sameSite);
|
||||||
} else {
|
} else {
|
||||||
return setSessionHttpOnlyCookie(currentSessions);
|
return setSessionHttpOnlyCookie(currentSessions, sameSite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateSessionCookie<T>(
|
export async function updateSessionCookie<T>({
|
||||||
id: string,
|
id,
|
||||||
session: SessionCookie<T>,
|
session,
|
||||||
cleanup: boolean = false,
|
cleanup,
|
||||||
): Promise<any> {
|
sameSite,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
session: SessionCookie<T>;
|
||||||
|
cleanup?: boolean;
|
||||||
|
sameSite?: boolean | "lax" | "strict" | "none" | undefined;
|
||||||
|
}): Promise<any> {
|
||||||
const cookiesList = await cookies();
|
const cookiesList = await cookies();
|
||||||
const stringifiedCookie = cookiesList.get("sessions");
|
const stringifiedCookie = cookiesList.get("sessions");
|
||||||
|
|
||||||
@@ -108,19 +123,24 @@ export async function updateSessionCookie<T>(
|
|||||||
? timestampDate(timestampFromMs(Number(session.expirationTs))) > now
|
? timestampDate(timestampFromMs(Number(session.expirationTs))) > now
|
||||||
: true,
|
: true,
|
||||||
);
|
);
|
||||||
return setSessionHttpOnlyCookie(filteredSessions);
|
return setSessionHttpOnlyCookie(filteredSessions, sameSite);
|
||||||
} else {
|
} else {
|
||||||
return setSessionHttpOnlyCookie(sessions);
|
return setSessionHttpOnlyCookie(sessions, sameSite);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw "updateSessionCookie<T>: session id now found";
|
throw "updateSessionCookie<T>: session id now found";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function removeSessionFromCookie<T>(
|
export async function removeSessionFromCookie<T>({
|
||||||
session: SessionCookie<T>,
|
session,
|
||||||
cleanup: boolean = false,
|
cleanup,
|
||||||
): Promise<any> {
|
sameSite,
|
||||||
|
}: {
|
||||||
|
session: SessionCookie<T>;
|
||||||
|
cleanup?: boolean;
|
||||||
|
sameSite?: boolean | "lax" | "strict" | "none" | undefined;
|
||||||
|
}): Promise<any> {
|
||||||
const cookiesList = await cookies();
|
const cookiesList = await cookies();
|
||||||
const stringifiedCookie = cookiesList.get("sessions");
|
const stringifiedCookie = cookiesList.get("sessions");
|
||||||
|
|
||||||
@@ -136,9 +156,9 @@ export async function removeSessionFromCookie<T>(
|
|||||||
? timestampDate(timestampFromMs(Number(session.expirationTs))) > now
|
? timestampDate(timestampFromMs(Number(session.expirationTs))) > now
|
||||||
: true,
|
: true,
|
||||||
);
|
);
|
||||||
return setSessionHttpOnlyCookie(filteredSessions);
|
return setSessionHttpOnlyCookie(filteredSessions, sameSite);
|
||||||
} else {
|
} else {
|
||||||
return setSessionHttpOnlyCookie(reducedSessions);
|
return setSessionHttpOnlyCookie(reducedSessions, sameSite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import { addSessionToCookie, updateSessionCookie } from "@/lib/cookies";
|
|||||||
import {
|
import {
|
||||||
createSessionForUserIdAndIdpIntent,
|
createSessionForUserIdAndIdpIntent,
|
||||||
createSessionFromChecks,
|
createSessionFromChecks,
|
||||||
|
getSecuritySettings,
|
||||||
getSession,
|
getSession,
|
||||||
setSession,
|
setSession,
|
||||||
} from "@/lib/zitadel";
|
} from "@/lib/zitadel";
|
||||||
@@ -65,7 +66,7 @@ export async function createSessionAndUpdateCookie(command: {
|
|||||||
serviceUrl,
|
serviceUrl,
|
||||||
sessionId: createdSession.sessionId,
|
sessionId: createdSession.sessionId,
|
||||||
sessionToken: createdSession.sessionToken,
|
sessionToken: createdSession.sessionToken,
|
||||||
}).then((response) => {
|
}).then(async (response) => {
|
||||||
if (response?.session && response.session?.factors?.user?.loginName) {
|
if (response?.session && response.session?.factors?.user?.loginName) {
|
||||||
const sessionCookie: CustomCookieData = {
|
const sessionCookie: CustomCookieData = {
|
||||||
id: createdSession.sessionId,
|
id: createdSession.sessionId,
|
||||||
@@ -91,9 +92,14 @@ export async function createSessionAndUpdateCookie(command: {
|
|||||||
response.session.factors.user.organizationId;
|
response.session.factors.user.organizationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return addSessionToCookie(sessionCookie).then(() => {
|
const securitySettings = await getSecuritySettings({ serviceUrl });
|
||||||
return response.session as Session;
|
const sameSite = securitySettings?.embeddedIframe?.enabled
|
||||||
});
|
? "none"
|
||||||
|
: true;
|
||||||
|
|
||||||
|
await addSessionToCookie({ session: sessionCookie, sameSite });
|
||||||
|
|
||||||
|
return response.session as Session;
|
||||||
} else {
|
} else {
|
||||||
throw "could not get session or session does not have loginName";
|
throw "could not get session or session does not have loginName";
|
||||||
}
|
}
|
||||||
@@ -167,7 +173,10 @@ export async function createSessionForIdpAndUpdateCookie(
|
|||||||
sessionCookie.organization = session.factors.user.organizationId;
|
sessionCookie.organization = session.factors.user.organizationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return addSessionToCookie(sessionCookie).then(() => {
|
const securitySettings = await getSecuritySettings({ serviceUrl });
|
||||||
|
const sameSite = securitySettings?.embeddedIframe?.enabled ? "none" : true;
|
||||||
|
|
||||||
|
return addSessionToCookie({ session: sessionCookie, sameSite }).then(() => {
|
||||||
return session as Session;
|
return session as Session;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -217,32 +226,44 @@ export async function setSessionAndUpdateCookie(
|
|||||||
serviceUrl,
|
serviceUrl,
|
||||||
sessionId: sessionCookie.id,
|
sessionId: sessionCookie.id,
|
||||||
sessionToken: sessionCookie.token,
|
sessionToken: sessionCookie.token,
|
||||||
}).then((response) => {
|
}).then(async (response) => {
|
||||||
if (response?.session && response.session.factors?.user?.loginName) {
|
if (
|
||||||
const { session } = response;
|
!response?.session ||
|
||||||
const newCookie: CustomCookieData = {
|
!response.session.factors?.user?.loginName
|
||||||
id: sessionCookie.id,
|
) {
|
||||||
token: updatedSession.sessionToken,
|
|
||||||
creationTs: sessionCookie.creationTs,
|
|
||||||
expirationTs: sessionCookie.expirationTs,
|
|
||||||
// just overwrite the changeDate with the new one
|
|
||||||
changeTs: updatedSession.details?.changeDate
|
|
||||||
? `${timestampMs(updatedSession.details.changeDate)}`
|
|
||||||
: "",
|
|
||||||
loginName: session.factors?.user?.loginName ?? "",
|
|
||||||
organization: session.factors?.user?.organizationId ?? "",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (sessionCookie.requestId) {
|
|
||||||
newCookie.requestId = sessionCookie.requestId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return updateSessionCookie(sessionCookie.id, newCookie).then(() => {
|
|
||||||
return { challenges: updatedSession.challenges, ...session };
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw "could not get session or session does not have loginName";
|
throw "could not get session or session does not have loginName";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { session } = response;
|
||||||
|
const newCookie: CustomCookieData = {
|
||||||
|
id: sessionCookie.id,
|
||||||
|
token: updatedSession.sessionToken,
|
||||||
|
creationTs: sessionCookie.creationTs,
|
||||||
|
expirationTs: sessionCookie.expirationTs,
|
||||||
|
// just overwrite the changeDate with the new one
|
||||||
|
changeTs: updatedSession.details?.changeDate
|
||||||
|
? `${timestampMs(updatedSession.details.changeDate)}`
|
||||||
|
: "",
|
||||||
|
loginName: session.factors?.user?.loginName ?? "",
|
||||||
|
organization: session.factors?.user?.organizationId ?? "",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (sessionCookie.requestId) {
|
||||||
|
newCookie.requestId = sessionCookie.requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const securitySettings = await getSecuritySettings({ serviceUrl });
|
||||||
|
const sameSite = securitySettings?.embeddedIframe?.enabled
|
||||||
|
? "none"
|
||||||
|
: true;
|
||||||
|
|
||||||
|
return updateSessionCookie({
|
||||||
|
id: sessionCookie.id,
|
||||||
|
session: newCookie,
|
||||||
|
sameSite,
|
||||||
|
}).then(() => {
|
||||||
|
return { challenges: updatedSession.challenges, ...session };
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw "Session not be set";
|
throw "Session not be set";
|
||||||
|
@@ -4,6 +4,7 @@ import { setSessionAndUpdateCookie } from "@/lib/server/cookie";
|
|||||||
import {
|
import {
|
||||||
deleteSession,
|
deleteSession,
|
||||||
getLoginSettings,
|
getLoginSettings,
|
||||||
|
getSecuritySettings,
|
||||||
humanMFAInitSkipped,
|
humanMFAInitSkipped,
|
||||||
listAuthenticationMethodTypes,
|
listAuthenticationMethodTypes,
|
||||||
} from "@/lib/zitadel";
|
} from "@/lib/zitadel";
|
||||||
@@ -209,8 +210,11 @@ export async function clearSession(options: ClearSessionOptions) {
|
|||||||
sessionToken: session.token,
|
sessionToken: session.token,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const securitySettings = await getSecuritySettings({ serviceUrl });
|
||||||
|
const sameSite = securitySettings?.embeddedIframe?.enabled ? "none" : true;
|
||||||
|
|
||||||
if (deletedSession) {
|
if (deletedSession) {
|
||||||
return removeSessionFromCookie(session);
|
return removeSessionFromCookie({ session, sameSite });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,9 +234,12 @@ export async function cleanupSession({ sessionId }: CleanupSessionCommand) {
|
|||||||
sessionToken: sessionCookie.token,
|
sessionToken: sessionCookie.token,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const securitySettings = await getSecuritySettings({ serviceUrl });
|
||||||
|
const sameSite = securitySettings?.embeddedIframe?.enabled ? "none" : true;
|
||||||
|
|
||||||
if (!deleteResponse) {
|
if (!deleteResponse) {
|
||||||
throw new Error("Could not delete session");
|
throw new Error("Could not delete session");
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeSessionFromCookie(sessionCookie);
|
return removeSessionFromCookie({ session: sessionCookie, sameSite });
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user