diff --git a/apps/login/app/(login)/loginname/page.tsx b/apps/login/app/(login)/loginname/page.tsx index ecf4ac6dbce..98ae5535681 100644 --- a/apps/login/app/(login)/loginname/page.tsx +++ b/apps/login/app/(login)/loginname/page.tsx @@ -8,9 +8,10 @@ export default async function Page({ }) { const loginName = searchParams?.loginName; const authRequestId = searchParams?.authRequestId; + const organization = searchParams?.organization; const submit: boolean = searchParams?.submit === "true"; - const loginSettings = await getLoginSettings(server); + const loginSettings = await getLoginSettings(server, organization); return (
@@ -21,6 +22,7 @@ export default async function Page({ loginSettings={loginSettings} loginName={loginName} authRequestId={authRequestId} + organization={organization} submit={submit} />
diff --git a/apps/login/app/api/loginname/route.ts b/apps/login/app/api/loginname/route.ts index 257e56e5cc5..cd1823db980 100644 --- a/apps/login/app/api/loginname/route.ts +++ b/apps/login/app/api/loginname/route.ts @@ -1,12 +1,15 @@ -import { listAuthenticationMethodTypes } from "#/lib/zitadel"; +import { listAuthenticationMethodTypes, listUsers } from "#/lib/zitadel"; import { createSessionAndUpdateCookie } from "#/utils/session"; import { NextRequest, NextResponse } from "next/server"; export async function POST(request: NextRequest) { const body = await request.json(); if (body) { - const { loginName, authRequestId } = body; - + const { loginName, authRequestId, organization } = body; + // TODO - search for users with org + // return listUsers(loginName).then((users) => { + // if (users.details && users.details.totalResult == 1) { + // } return createSessionAndUpdateCookie( loginName, undefined, @@ -33,6 +36,7 @@ export async function POST(request: NextRequest) { .catch((error) => { return NextResponse.json(error, { status: 500 }); }); + // }); } else { return NextResponse.error(); } diff --git a/apps/login/lib/zitadel.ts b/apps/login/lib/zitadel.ts index 9148fb9e008..e075a43a80b 100644 --- a/apps/login/lib/zitadel.ts +++ b/apps/login/lib/zitadel.ts @@ -21,6 +21,8 @@ import { VerifyEmailResponse, SetSessionResponse, SetSessionRequest, + ListUsersResponse, + ListUsersRequest, DeleteSessionResponse, VerifyPasskeyRegistrationResponse, LoginSettings, @@ -35,6 +37,7 @@ import { CreateCallbackRequest, CreateCallbackResponse, RequestChallenges, + TextQueryMethod, AddHumanUserRequest, } from "@zitadel/server"; @@ -61,11 +64,12 @@ export async function getBrandingSettings( } export async function getLoginSettings( - server: ZitadelServer + server: ZitadelServer, + orgId?: string ): Promise { const settingsService = settings.getSettings(server); return settingsService - .getLoginSettings({}, {}) + .getLoginSettings({ ctx: orgId ? { orgId } : { instance: true } }, {}) .then((resp: GetLoginSettingsResponse) => resp.settings); } @@ -211,6 +215,25 @@ export async function addHumanUser( }); } +export async function listUsers(userName: string): Promise { + // TODO limit for organization + const userService = user.getUser(server); + + return userService.listUsers( + { + queries: [ + { + userNameQuery: { + userName, + method: TextQueryMethod.TEXT_QUERY_METHOD_EQUALS, + }, + }, + ], + }, + {} + ); +} + export async function startIdentityProviderFlow( server: ZitadelServer, { idpId, urls }: StartIdentityProviderIntentRequest diff --git a/apps/login/ui/UsernameForm.tsx b/apps/login/ui/UsernameForm.tsx index 5fd098eb84c..f555ae5a6fd 100644 --- a/apps/login/ui/UsernameForm.tsx +++ b/apps/login/ui/UsernameForm.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from "react"; import { Button, ButtonVariants } from "./Button"; import { TextInput } from "./Input"; -import { useForm } from "react-hook-form"; +import { SubmitHandler, useForm } from "react-hook-form"; import { useRouter } from "next/navigation"; import { Spinner } from "./Spinner"; import { LoginSettings } from "@zitadel/server"; @@ -17,6 +17,7 @@ type Props = { loginSettings: LoginSettings | undefined; loginName: string | undefined; authRequestId: string | undefined; + organization?: string; submit: boolean; }; @@ -24,6 +25,7 @@ export default function UsernameForm({ loginSettings, loginName, authRequestId, + organization, submit, }: Props) { const { register, handleSubmit, formState } = useForm({ @@ -38,13 +40,17 @@ export default function UsernameForm({ const [loading, setLoading] = useState(false); const [error, setError] = useState(""); - async function submitLoginName(values: Inputs) { + async function submitLoginName(values: Inputs, organization?: string) { setLoading(true); - const body = { + let body: any = { loginName: values.loginName, }; + if (organization) { + body.organization = organization; + } + const res = await fetch("/api/loginname", { method: "POST", headers: { @@ -63,8 +69,11 @@ export default function UsernameForm({ return res.json(); } - async function setLoginNameAndGetAuthMethods(values: Inputs) { - return submitLoginName(values).then((response) => { + function setLoginNameAndGetAuthMethods( + values: Inputs, + organization?: string + ) { + return submitLoginName(values, organization).then((response) => { if (response.authMethodTypes.length == 1) { const method = response.authMethodTypes[0]; switch (method) { @@ -152,7 +161,7 @@ export default function UsernameForm({ useEffect(() => { if (submit && loginName) { // When we navigate to this page, we always want to be redirected if submit is true and the parameters are valid. - setLoginNameAndGetAuthMethods({ loginName }); + setLoginNameAndGetAuthMethods({ loginName }, organization); } }, []); @@ -180,7 +189,9 @@ export default function UsernameForm({ className="self-end" variant={ButtonVariants.Primary} disabled={loading || !formState.isValid} - onClick={handleSubmit(setLoginNameAndGetAuthMethods)} + onClick={handleSubmit((e) => + setLoginNameAndGetAuthMethods(e, organization) + )} > {loading && } continue diff --git a/packages/zitadel-server/src/index.ts b/packages/zitadel-server/src/index.ts index 1b6bfb5aacf..2c8f16a5000 100644 --- a/packages/zitadel-server/src/index.ts +++ b/packages/zitadel-server/src/index.ts @@ -63,6 +63,7 @@ export { GetActiveIdentityProvidersResponse, GetActiveIdentityProvidersRequest, } from "./proto/server/zitadel/settings/v2beta/settings_service"; +export { TextQueryMethod } from "./proto/server/zitadel/object/v2beta/object"; export { AddHumanUserResponse, AddHumanUserRequest, @@ -80,6 +81,8 @@ export { StartIdentityProviderIntentResponse, RetrieveIdentityProviderIntentRequest, RetrieveIdentityProviderIntentResponse, + ListUsersRequest, + ListUsersResponse, } from "./proto/server/zitadel/user/v2beta/user_service"; export { SetHumanPasswordResponse,