Merge pull request #482 from zitadel/fix-idp-update

fix(idp): update human on login and if options.isAutoUpdate is enabled
This commit is contained in:
Max Peintner
2025-06-18 14:31:23 +02:00
committed by GitHub
2 changed files with 55 additions and 13 deletions

View File

@@ -16,6 +16,7 @@ import {
getOrgsByDomain,
listUsers,
retrieveIDPIntent,
updateHuman,
} from "@/lib/zitadel";
import { ConnectError, create } from "@zitadel/client";
import { AutoLinkingOption } from "@zitadel/proto/zitadel/idp/v2/idp_pb";
@@ -24,6 +25,7 @@ import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
import {
AddHumanUserRequest,
AddHumanUserRequestSchema,
UpdateHumanUserRequestSchema,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { getLocale, getTranslations } from "next-intl/server";
import { headers } from "next/headers";
@@ -79,7 +81,7 @@ export default async function Page(props: {
const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
const branding = await getBrandingSettings({
let branding = await getBrandingSettings({
serviceUrl,
organization,
});
@@ -106,18 +108,6 @@ export default async function Page(props: {
const { idpInformation, userId } = intent;
let { addHumanUser } = intent;
// sign in user. If user should be linked continue
if (userId && !link) {
// TODO: update user if idp.options.isAutoUpdate is true
return loginSuccess(
userId,
{ idpIntentId: id, idpIntentToken: token },
requestId,
branding,
);
}
if (!idpInformation) {
return loginFailed(branding, "IDP information missing");
}
@@ -126,12 +116,41 @@ export default async function Page(props: {
serviceUrl,
id: idpInformation.idpId,
});
const options = idp?.config?.options;
if (!idp) {
throw new Error("IDP not found");
}
// sign in user. If user should be linked continue
if (userId && !link) {
// if auto update is enabled, we will update the user with the new information
if (options?.isAutoUpdate && addHumanUser) {
try {
await updateHuman({
serviceUrl,
request: create(UpdateHumanUserRequestSchema, {
userId: userId,
profile: addHumanUser.profile,
email: addHumanUser.email,
phone: addHumanUser.phone,
}),
});
} catch (error: unknown) {
// Log the error and continue with the login process
console.warn("An error occurred while updating the user:", error);
}
}
return loginSuccess(
userId,
{ idpIntentId: id, idpIntentToken: token },
requestId,
branding,
);
}
if (link) {
if (!options?.isLinkingAllowed) {
// linking was probably disallowed since the invitation was created
@@ -275,6 +294,13 @@ export default async function Page(props: {
serviceUrl,
});
if (orgToRegisterOn) {
branding = await getBrandingSettings({
serviceUrl,
organization: orgToRegisterOn,
});
}
if (!orgToRegisterOn) {
return loginFailed(branding, "No organization found for registration");
}

View File

@@ -41,6 +41,7 @@ import {
SendEmailCodeRequestSchema,
SetPasswordRequest,
SetPasswordRequestSchema,
UpdateHumanUserRequest,
UserService,
VerifyPasskeyRegistrationRequest,
VerifyU2FRegistrationRequest,
@@ -455,6 +456,21 @@ export async function addHuman({
return userService.addHumanUser(request);
}
export async function updateHuman({
serviceUrl,
request,
}: {
serviceUrl: string;
request: UpdateHumanUserRequest;
}) {
const userService: Client<typeof UserService> = await createServiceForHost(
UserService,
serviceUrl,
);
return userService.updateHumanUser(request);
}
export async function verifyTOTPRegistration({
serviceUrl,
code,