check for valid sessions, cleanup

This commit is contained in:
Max Peintner
2024-12-09 09:44:56 +01:00
parent 1a7d97421f
commit 2e2ae590f9

View File

@@ -9,7 +9,7 @@ import {
listSessions,
startIdentityProviderFlow,
} from "@/lib/zitadel";
import { create } from "@zitadel/client";
import { create, timestampDate } from "@zitadel/client";
import {
AuthRequest,
Prompt,
@@ -37,26 +37,53 @@ const ORG_SCOPE_REGEX = /urn:zitadel:iam:org:id:([0-9]+)/;
const ORG_DOMAIN_SCOPE_REGEX = /urn:zitadel:iam:org:domain:primary:(.+)/; // TODO: check regex for all domain character options
const IDP_SCOPE_REGEX = /urn:zitadel:iam:org:idp:id:(.+)/;
function findSession(
function isSessionValid(session: Session): boolean {
const validPassword = session?.factors?.password?.verifiedAt;
const validPasskey = session?.factors?.webAuthN?.verifiedAt;
const validIDP = session?.factors?.intent?.verifiedAt;
const stillValid = session.expirationDate
? timestampDate(session.expirationDate) > new Date()
: true;
const validFactors = !!(
(validPassword || validPasskey || validIDP) &&
stillValid
);
return stillValid && validFactors;
}
function findValidSession(
sessions: Session[],
authRequest: AuthRequest,
): Session | undefined {
const validSessionsWithHint = sessions
.filter((s) => {
if (authRequest.hintUserId) {
console.log(`find session for hintUserId: ${authRequest.hintUserId}`);
return sessions.find((s) => s.factors?.user?.id === authRequest.hintUserId);
return s.factors?.user?.id === authRequest.hintUserId;
}
if (authRequest.loginHint) {
console.log(`find session for loginHint: ${authRequest.loginHint}`);
return sessions.find(
(s) => s.factors?.user?.loginName === authRequest.loginHint,
);
}
if (sessions.length) {
return sessions[0];
return s.factors?.user?.loginName === authRequest.loginHint;
}
return false;
})
.filter(isSessionValid);
if (validSessionsWithHint.length === 0) {
return undefined;
}
validSessionsWithHint.sort((a, b) => {
const dateA = a.changeDate ? timestampDate(a.changeDate).getTime() : 0;
const dateB = b.changeDate ? timestampDate(b.changeDate).getTime() : 0;
return dateB - dateA;
});
// return most recently changed session
return sessions[0];
}
export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams;
const authRequestId = searchParams.get("authRequest");
@@ -226,8 +253,8 @@ export async function GET(request: NextRequest) {
if (authRequest && authRequest.prompt.includes(Prompt.CREATE)) {
const registerUrl = new URL("/register", request.url);
if (authRequest?.id) {
registerUrl.searchParams.set("authRequestId", authRequest?.id);
if (authRequest.id) {
registerUrl.searchParams.set("authRequestId", authRequest.id);
}
if (organization) {
registerUrl.searchParams.set("organization", organization);
@@ -260,8 +287,8 @@ export async function GET(request: NextRequest) {
}
const loginNameUrl = new URL("/loginname", request.url);
if (authRequest?.id) {
loginNameUrl.searchParams.set("authRequestId", authRequest?.id);
if (authRequest.id) {
loginNameUrl.searchParams.set("authRequestId", authRequest.id);
}
if (authRequest.loginHint) {
loginNameUrl.searchParams.set("loginName", authRequest.loginHint);
@@ -272,19 +299,31 @@ export async function GET(request: NextRequest) {
return NextResponse.redirect(loginNameUrl);
} else if (authRequest.prompt.includes(Prompt.NONE)) {
// NONE prompt - silent authentication
const selectedSession = findValidSession(sessions, authRequest);
let selectedSession = findSession(sessions, authRequest);
if (!selectedSession || !selectedSession.id) {
return NextResponse.json(
{ error: "No active session found" },
{ status: 400 },
);
}
if (selectedSession && selectedSession.id) {
const cookie = sessionCookies.find(
(cookie) => cookie.id === selectedSession?.id,
(cookie) => cookie.id === selectedSession.id,
);
if (cookie && cookie.id && cookie.token) {
if (!cookie || !cookie.id || !cookie.token) {
return NextResponse.json(
{ error: "No active session found" },
{ status: 400 },
);
}
const session = {
sessionId: cookie?.id,
sessionToken: cookie?.token,
sessionId: cookie.id,
sessionToken: cookie.token,
};
const { callbackUrl } = await createCallback(
create(CreateCallbackRequestSchema, {
authRequestId,
@@ -296,31 +335,26 @@ export async function GET(request: NextRequest) {
);
return NextResponse.redirect(callbackUrl);
} else {
return NextResponse.json(
{ error: "No active session found" },
{ status: 400 }, // TODO: check for correct status code
);
}
} else {
return NextResponse.json(
{ error: "No active session found" },
{ status: 400 }, // TODO: check for correct status code
);
}
} else {
// check for loginHint, userId hint sessions
let selectedSession = findSession(sessions, authRequest);
// check for loginHint, userId hint and valid sessions
let selectedSession = findValidSession(sessions, authRequest);
if (!selectedSession || !selectedSession.id) {
return gotoAccounts();
}
if (selectedSession && selectedSession.id) {
const cookie = sessionCookies.find(
(cookie) => cookie.id === selectedSession?.id,
(cookie) => cookie.id === selectedSession.id,
);
if (cookie && cookie.id && cookie.token) {
if (!cookie || !cookie.id || !cookie.token) {
return gotoAccounts();
}
const session = {
sessionId: cookie?.id,
sessionToken: cookie?.token,
sessionId: cookie.id,
sessionToken: cookie.token,
};
try {
const { callbackUrl } = await createCallback(
create(CreateCallbackRequestSchema, {
@@ -343,12 +377,6 @@ export async function GET(request: NextRequest) {
console.error(error);
return gotoAccounts();
}
} else {
return gotoAccounts();
}
} else {
return gotoAccounts();
}
}
} else {
const loginNameUrl = new URL("/loginname", request.url);