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, getOrgsByDomain,
listUsers, listUsers,
retrieveIDPIntent, retrieveIDPIntent,
updateHuman,
} from "@/lib/zitadel"; } from "@/lib/zitadel";
import { ConnectError, create } from "@zitadel/client"; import { ConnectError, create } from "@zitadel/client";
import { AutoLinkingOption } from "@zitadel/proto/zitadel/idp/v2/idp_pb"; 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 { import {
AddHumanUserRequest, AddHumanUserRequest,
AddHumanUserRequestSchema, AddHumanUserRequestSchema,
UpdateHumanUserRequestSchema,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb"; } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { getLocale, getTranslations } from "next-intl/server"; import { getLocale, getTranslations } from "next-intl/server";
import { headers } from "next/headers"; import { headers } from "next/headers";
@@ -79,7 +81,7 @@ export default async function Page(props: {
const _headers = await headers(); const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers); const { serviceUrl } = getServiceUrlFromHeaders(_headers);
const branding = await getBrandingSettings({ let branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -106,18 +108,6 @@ export default async function Page(props: {
const { idpInformation, userId } = intent; const { idpInformation, userId } = intent;
let { addHumanUser } = 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) { if (!idpInformation) {
return loginFailed(branding, "IDP information missing"); return loginFailed(branding, "IDP information missing");
} }
@@ -126,12 +116,41 @@ export default async function Page(props: {
serviceUrl, serviceUrl,
id: idpInformation.idpId, id: idpInformation.idpId,
}); });
const options = idp?.config?.options; const options = idp?.config?.options;
if (!idp) { if (!idp) {
throw new Error("IDP not found"); 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 (link) {
if (!options?.isLinkingAllowed) { if (!options?.isLinkingAllowed) {
// linking was probably disallowed since the invitation was created // linking was probably disallowed since the invitation was created
@@ -275,6 +294,13 @@ export default async function Page(props: {
serviceUrl, serviceUrl,
}); });
if (orgToRegisterOn) {
branding = await getBrandingSettings({
serviceUrl,
organization: orgToRegisterOn,
});
}
if (!orgToRegisterOn) { if (!orgToRegisterOn) {
return loginFailed(branding, "No organization found for registration"); return loginFailed(branding, "No organization found for registration");
} }

View File

@@ -41,6 +41,7 @@ import {
SendEmailCodeRequestSchema, SendEmailCodeRequestSchema,
SetPasswordRequest, SetPasswordRequest,
SetPasswordRequestSchema, SetPasswordRequestSchema,
UpdateHumanUserRequest,
UserService, UserService,
VerifyPasskeyRegistrationRequest, VerifyPasskeyRegistrationRequest,
VerifyU2FRegistrationRequest, VerifyU2FRegistrationRequest,
@@ -455,6 +456,21 @@ export async function addHuman({
return userService.addHumanUser(request); 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({ export async function verifyTOTPRegistration({
serviceUrl, serviceUrl,
code, code,