Skip to content

Commit 449a3f3

Browse files
committed
feat: enable email lookup using userId to improve login for IDP users when loginName search fails.
1 parent 9aa070e commit 449a3f3

3 files changed

Lines changed: 42 additions & 7 deletions

File tree

apps/login/src/components/session-item.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export function SessionItem({
8888
loginName: session.factors?.user?.loginName,
8989
organization: session.factors.user.organizationId,
9090
requestId: requestId,
91+
userId: session.factors?.user?.id, // Pass userId to handle IDP users
9192
}).catch(() => {
9293
setError("An internal error occurred");
9394
return;

apps/login/src/lib/server/loginname.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type SendLoginnameCommand = {
2828
requestId?: string;
2929
organization?: string;
3030
suffix?: string;
31+
userId?: string; // Optional: when provided, used to get user email if loginName search fails
3132
};
3233

3334
const ORG_SUFFIX_REGEX = /(?<=@)(.+)/;
@@ -56,6 +57,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
5657
organizationId: command.organization,
5758
loginSettings: loginSettingsByContext,
5859
suffix: command.suffix,
60+
userId: command.userId, // Pass userId for email lookup if loginName search fails
5961
};
6062

6163
const searchResult = await searchUsers(searchUsersRequest);

apps/login/src/lib/zitadel.ts

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,7 @@ export type SearchUsersCommand = {
771771
loginSettings: LoginSettings;
772772
organizationId?: string;
773773
suffix?: string;
774+
userId?: string; // Optional: when provided, get user email if loginName search fails
774775
};
775776

776777
const PhoneQuery = (searchValue: string) =>
@@ -816,6 +817,7 @@ export async function searchUsers({
816817
loginSettings,
817818
organizationId,
818819
suffix,
820+
userId,
819821
}: SearchUsersCommand) {
820822
const queries: SearchQuery[] = [];
821823

@@ -861,27 +863,57 @@ export async function searchUsers({
861863
return loginNameResult;
862864
}
863865

866+
// If loginName search returned 0 results and we have a userId,
867+
// try to get the user's email and search by that instead
868+
// This handles IDP users where loginName might be the IDP username (e.g., GitHub username)
869+
let effectiveSearchValue = searchValue;
870+
871+
if (userId && loginNameResult.result.length === 0) {
872+
try {
873+
const userResponse = await userService.getUserByID({ userId });
874+
875+
const email =
876+
userResponse?.user?.type?.case === "human"
877+
? userResponse.user.type.value?.email?.email
878+
: undefined;
879+
if (email) {
880+
effectiveSearchValue = email;
881+
}
882+
} catch (error) {
883+
console.error("Failed to get user by ID for email lookup:", error);
884+
// Continue with original searchValue
885+
}
886+
}
887+
888+
console.log("searching by email", effectiveSearchValue);
889+
864890
const emailAndPhoneQueries: SearchQuery[] = [];
865891
if (
866892
loginSettings.disableLoginWithEmail &&
867893
loginSettings.disableLoginWithPhone
868894
) {
869-
return { error: "User not found in the system" };
870-
} else if (loginSettings.disableLoginWithEmail && searchValue.length <= 20) {
871-
const phoneQuery = PhoneQuery(searchValue);
895+
// For IDP-only setups, we still need to search by email since the session's loginName
896+
// may be the user's email address from the identity provider
897+
const emailQuery = EmailQuery(effectiveSearchValue);
898+
emailAndPhoneQueries.push(emailQuery);
899+
} else if (
900+
loginSettings.disableLoginWithEmail &&
901+
effectiveSearchValue.length <= 20
902+
) {
903+
const phoneQuery = PhoneQuery(effectiveSearchValue);
872904
emailAndPhoneQueries.push(phoneQuery);
873905
} else if (loginSettings.disableLoginWithPhone) {
874-
const emailQuery = EmailQuery(searchValue);
906+
const emailQuery = EmailQuery(effectiveSearchValue);
875907
emailAndPhoneQueries.push(emailQuery);
876908
} else {
877909
const orQuery: SearchQuery[] = [];
878910

879-
const emailQuery = EmailQuery(searchValue);
911+
const emailQuery = EmailQuery(effectiveSearchValue);
880912
orQuery.push(emailQuery);
881913

882914
let phoneQuery;
883-
if (searchValue.length <= 20) {
884-
phoneQuery = PhoneQuery(searchValue);
915+
if (effectiveSearchValue.length <= 20) {
916+
phoneQuery = PhoneQuery(effectiveSearchValue);
885917
orQuery.push(phoneQuery);
886918
}
887919

0 commit comments

Comments
 (0)