diff --git a/apps/login/src/app/(login)/authenticator/set/page.tsx b/apps/login/src/app/(login)/authenticator/set/page.tsx
index 5a8dfe810d..82b494f200 100644
--- a/apps/login/src/app/(login)/authenticator/set/page.tsx
+++ b/apps/login/src/app/(login)/authenticator/set/page.tsx
@@ -184,7 +184,7 @@ export default async function Page(props: {
>
)}
- {loginSettings?.allowExternalIdp && identityProviders && (
+ {loginSettings?.allowExternalIdp && !!identityProviders.length && (
<>
{identityProviders.length && (
diff --git a/apps/login/src/app/(login)/idp/ldap/page.tsx b/apps/login/src/app/(login)/idp/ldap/page.tsx
new file mode 100644
index 0000000000..6a54c2d648
--- /dev/null
+++ b/apps/login/src/app/(login)/idp/ldap/page.tsx
@@ -0,0 +1,55 @@
+import { DynamicTheme } from "@/components/dynamic-theme";
+import { UsernamePasswordForm } from "@/components/username-password-form";
+import { getServiceUrlFromHeaders } from "@/lib/service-url";
+import { getBrandingSettings, getDefaultOrg } from "@/lib/zitadel";
+import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
+import { getLocale, getTranslations } from "next-intl/server";
+import { headers } from "next/headers";
+
+export default async function Page(props: {
+ searchParams: Promise
>;
+ params: Promise<{ provider: string }>;
+}) {
+ const searchParams = await props.searchParams;
+ const locale = getLocale();
+ const t = await getTranslations({ locale, namespace: "ldap" });
+ const { idpId, requestId, organization, link } = searchParams;
+
+ if (!idpId) {
+ throw new Error("No idpId provided in searchParams");
+ }
+
+ const _headers = await headers();
+ const { serviceUrl } = getServiceUrlFromHeaders(_headers);
+
+ let defaultOrganization;
+ if (!organization) {
+ const org: Organization | null = await getDefaultOrg({
+ serviceUrl,
+ });
+ if (org) {
+ defaultOrganization = org.id;
+ }
+ }
+
+ const branding = await getBrandingSettings({
+ serviceUrl,
+ organization: organization ?? defaultOrganization,
+ });
+
+ // return login failed if no linking or creation is allowed and no user was found
+ return (
+
+
+
{t("title")}
+
{t("description")}
+
+
+
+
+ );
+}
diff --git a/apps/login/src/components/username-password-form.tsx b/apps/login/src/components/username-password-form.tsx
index fb6a98d8c3..4c5543866d 100644
--- a/apps/login/src/components/username-password-form.tsx
+++ b/apps/login/src/components/username-password-form.tsx
@@ -1,9 +1,6 @@
"use client";
-import { sendPassword } from "@/lib/server/password";
-import { create } from "@zitadel/client";
-import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
-import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
+import { createNewSessionForLDAP } from "@/lib/server/idp";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
import { useState } from "react";
@@ -20,17 +17,15 @@ type Inputs = {
};
type Props = {
- loginSettings: LoginSettings | undefined;
- loginName: string;
organization?: string;
requestId?: string;
+ idpId: string;
};
export function UsernamePasswordForm({
- loginSettings,
- loginName,
organization,
requestId,
+ idpId,
}: Props) {
const t = useTranslations("password");
@@ -48,13 +43,10 @@ export function UsernamePasswordForm({
setError("");
setLoading(true);
- const response = await sendPassword({
- loginName,
- organization,
- checks: create(ChecksSchema, {
- password: { password: values.password },
- }),
- requestId,
+ const response = await createNewSessionForLDAP({
+ idpId: idpId,
+ username: values.loginName,
+ password: values.password,
})
.catch(() => {
setError("Could not verify password");
@@ -75,7 +67,7 @@ export function UsernamePasswordForm({
}
return (
-