cleanup idp, cleanup session actions

This commit is contained in:
Max Peintner
2024-12-20 10:57:56 +01:00
parent f1f7d661ce
commit 670ed71dd1
6 changed files with 115 additions and 86 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { createNewSessionForIdp } from "@/lib/server/session";
import { createNewSessionFromIdpIntent } from "@/lib/server/idp";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { Alert } from "./alert";
@@ -27,7 +27,7 @@ export function IdpSignin({
const router = useRouter();
useEffect(() => {
createNewSessionForIdp({
createNewSessionFromIdpIntent({
userId,
idpIntent: {
idpIntentId,

View File

@@ -1,7 +1,14 @@
"use server";
import { startIdentityProviderFlow } from "@/lib/zitadel";
import {
getLoginSettings,
getUserByID,
startIdentityProviderFlow,
} from "@/lib/zitadel";
import { headers } from "next/headers";
import { getNextUrl } from "../client";
import { checkEmailVerification } from "../verify-helper";
import { createSessionForIdpAndUpdateCookie } from "./cookie";
export type StartIDPFlowCommand = {
idpId: string;
@@ -32,3 +39,82 @@ export async function startIDPFlow(command: StartIDPFlowCommand) {
}
});
}
type CreateNewSessionCommand = {
userId: string;
idpIntent: {
idpIntentId: string;
idpIntentToken: string;
};
loginName?: string;
password?: string;
organization?: string;
authRequestId?: string;
};
export async function createNewSessionFromIdpIntent(
command: CreateNewSessionCommand,
) {
if (!command.userId || !command.idpIntent) {
throw new Error("No userId or loginName provided");
}
const userResponse = await getUserByID(command.userId);
if (!userResponse || !userResponse.user) {
return { error: "Could not find user" };
}
const loginSettings = await getLoginSettings(
userResponse.user.details?.resourceOwner,
);
const session = await createSessionForIdpAndUpdateCookie(
command.userId,
command.idpIntent,
command.authRequestId,
loginSettings?.externalLoginCheckLifetime,
);
if (!session || !session.factors?.user) {
return { error: "Could not create session" };
}
const humanUser =
userResponse.user.type.case === "human"
? userResponse.user.type.value
: undefined;
// check to see if user was verified
const emailVerificationCheck = checkEmailVerification(
session,
humanUser,
command.organization,
command.authRequestId,
);
if (emailVerificationCheck?.redirect) {
return emailVerificationCheck;
}
// TODO: check if user has MFA methods
// checkMFAFactors(session, loginSettings, authMethods, organization, authRequestId);
const url = await getNextUrl(
command.authRequestId && session.id
? {
sessionId: session.id,
authRequestId: command.authRequestId,
organization: session.factors.user.organizationId,
}
: {
loginName: session.factors.user.loginName,
organization: session.factors.user.organizationId,
},
loginSettings?.defaultRedirectUri,
);
if (url) {
return { redirect: url };
}
}

View File

@@ -175,7 +175,16 @@ export async function sendPasskey(command: SendPasskeyCommand) {
? userResponse.user.type.value
: undefined;
checkEmailVerification(session, humanUser, organization, authRequestId);
const emailVerificationCheck = checkEmailVerification(
session,
humanUser,
organization,
authRequestId,
);
if (emailVerificationCheck?.redirect) {
return emailVerificationCheck;
}
const url =
authRequestId && session.id

View File

@@ -142,26 +142,34 @@ export async function sendPassword(command: UpdateSessionCommand) {
const humanUser = user.type.case === "human" ? user.type.value : undefined;
// check if the user has to change password first
checkPasswordChangeRequired(
const passwordChangedCheck = checkPasswordChangeRequired(
session,
humanUser,
command.organization,
command.authRequestId,
);
if (passwordChangedCheck?.redirect) {
return passwordChangedCheck;
}
// throw error if user is in initial state here and do not continue
if (user.state === UserState.INITIAL) {
return { error: "Initial User not supported" };
}
// check to see if user was verified
checkEmailVerification(
const emailVerificationCheck = checkEmailVerification(
session,
humanUser,
command.organization,
command.authRequestId,
);
if (emailVerificationCheck?.redirect) {
return emailVerificationCheck;
}
// if password, check if user has MFA methods
let authMethods;
if (command.checks && command.checks.password && session.factors?.user?.id) {

View File

@@ -1,13 +1,9 @@
"use server";
import {
createSessionForIdpAndUpdateCookie,
setSessionAndUpdateCookie,
} from "@/lib/server/cookie";
import { setSessionAndUpdateCookie } from "@/lib/server/cookie";
import {
deleteSession,
getLoginSettings,
getUserByID,
listAuthenticationMethodTypes,
} from "@/lib/zitadel";
import { Duration } from "@zitadel/client";
@@ -22,81 +18,6 @@ import {
getSessionCookieByLoginName,
removeSessionFromCookie,
} from "../cookies";
import { checkPasswordChangeRequired } from "../verify-helper";
type CreateNewSessionCommand = {
userId: string;
idpIntent: {
idpIntentId: string;
idpIntentToken: string;
};
loginName?: string;
password?: string;
authRequestId?: string;
};
export async function createNewSessionForIdp(options: CreateNewSessionCommand) {
const { userId, idpIntent, authRequestId } = options;
if (!userId || !idpIntent) {
throw new Error("No userId or loginName provided");
}
const userResponse = await getUserByID(userId);
if (!userResponse || !userResponse.user) {
return { error: "Could not find user" };
}
const loginSettings = await getLoginSettings(
userResponse.user.details?.resourceOwner,
);
const session = await createSessionForIdpAndUpdateCookie(
userId,
idpIntent,
authRequestId,
loginSettings?.externalLoginCheckLifetime,
);
if (!session || !session.factors?.user) {
return { error: "Could not create session" };
}
const humanUser =
userResponse.user.type.case === "human"
? userResponse.user.type.value
: undefined;
// check if the user has to change password first
checkPasswordChangeRequired(
session,
humanUser,
session.factors.user.organizationId,
authRequestId,
);
// TODO: check if user has MFA methods
// checkMFAFactors(session, loginSettings, authMethods, organization, authRequestId);
const url = await getNextUrl(
authRequestId && session.id
? {
sessionId: session.id,
authRequestId: authRequestId,
organization: session.factors.user.organizationId,
}
: {
loginName: session.factors.user.loginName,
organization: session.factors.user.organizationId,
},
loginSettings?.defaultRedirectUri,
);
if (url) {
return { redirect: url };
}
}
export async function continueWithSession({
authRequestId,

View File

@@ -35,6 +35,11 @@ export function checkEmailVerification(
organization?: string,
authRequestId?: string,
) {
console.log(
humanUser?.email,
process.env.EMAIL_VERIFICATION,
process.env.EMAIL_VERIFICATION === "true",
);
if (
!humanUser?.email?.isVerified &&
process.env.EMAIL_VERIFICATION === "true"