import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { useAuth } from "@/hooks/use-auth"; import { useOrganization } from "@/context/organization-context"; import { Redirect, useLocation } from "wouter"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ThemeToggle } from "@/components/shared/theme-toggle"; import { useTheme } from "@/hooks/use-theme"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Separator } from "@/components/ui/separator"; import { Loader2 } from "lucide-react"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { useQuery } from "@tanstack/react-query"; import { useEffect, useState } from "react"; const loginSchema = z.object({ username: z.string().min(3, "Username must be at least 3 characters"), password: z.string().min(8, "Password must be at least 8 characters"), }); const registerSchema = z.object({ username: z.string().min(3, "Username must be at least 3 characters"), email: z.string().email("Please enter a valid email"), password: z.string().min(8, "Password must be at least 8 characters"), fullName: z.string().optional(), organizationId: z.string().optional(), }); // Define LDAP login schema const ldapSchema = z.object({ username: z.string().min(1, "Username is required"), password: z.string().min(1, "Password is required"), }); // Type for Auth config from API interface AuthConfig { localAuthEnabled: boolean; registrationEnabled: boolean; ldapEnabled: boolean; oidcEnabled: boolean; oidcButtonText: string; } export default function AuthPage() { const { user, loginMutation, registerMutation } = useAuth(); const { theme } = useTheme(); const { organizations, isLoading: orgsLoading } = useOrganization(); const [location, setLocation] = useLocation(); // Fetch authentication configuration const { data: authConfig, isLoading: configLoading } = useQuery({ queryKey: ['/api/auth/config'], staleTime: 1000 * 60 * 5, // 5 minutes }); // State for managing LDAP login const [ldapLoginPending, setLdapLoginPending] = useState(false); const [authError, setAuthError] = useState(null); const loginForm = useForm>({ resolver: zodResolver(loginSchema), defaultValues: { username: "", password: "", }, }); const ldapForm = useForm>({ resolver: zodResolver(ldapSchema), defaultValues: { username: "", password: "", }, }); const registerForm = useForm>({ resolver: zodResolver(registerSchema), defaultValues: { username: "", email: "", password: "", fullName: "", organizationId: undefined, }, }); const onLoginSubmit = (values: z.infer) => { setAuthError(null); loginMutation.mutate(values, { onError: (error: any) => { setAuthError(error.message || "Login failed. Please check your credentials."); } }); }; const onLdapSubmit = async (values: z.infer) => { try { setLdapLoginPending(true); setAuthError(null); const response = await fetch('/api/auth/ldap', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(values), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || 'LDAP authentication failed'); } // Force refresh user data window.location.href = '/'; } catch (error: any) { setAuthError(error.message || "LDAP login failed. Please check your credentials."); } finally { setLdapLoginPending(false); } }; const onRegisterSubmit = (values: z.infer) => { setAuthError(null); registerMutation.mutate(values, { onError: (error: any) => { setAuthError(error.message || "Registration failed. Please try again."); } }); }; // Function to handle OIDC login const handleOidcLogin = () => { window.location.href = '/api/auth/oidc'; }; // Redirect if already logged in if (user) { return ; } return (
{/* Auth Form */}
DynamoDNS
Welcome {configLoading ? "Loading..." : authConfig?.registrationEnabled ? "Sign in to your account or create a new one" : "Sign in to your account" }
Login {(!configLoading && authConfig?.registrationEnabled) && ( Register )} {authError && ( Authentication Error {authError} )} {configLoading ? (
) : ( <> {/* Local Authentication */} {authConfig?.localAuthEnabled && (
( Username or Email )} /> ( Password )} /> )} {/* LDAP Authentication */} {authConfig?.ldapEnabled && ( <> {authConfig?.localAuthEnabled && (

Or login with LDAP

)}
( LDAP Username )} /> ( LDAP Password )} /> )} {/* OIDC Authentication */} {authConfig?.oidcEnabled && ( <> {(authConfig?.localAuthEnabled || authConfig?.ldapEnabled) && (

Or

)} )} {!authConfig?.localAuthEnabled && !authConfig?.ldapEnabled && !authConfig?.oidcEnabled && ( Authentication Error No authentication methods are enabled. Please contact your administrator. )} )}
( Username )} /> ( Email )} /> ( Full Name (Optional) )} /> ( Password )} /> ( Organization )} />
{/* Hero Section */}

Dynamic DNS Management System

Keep your DNS records up to date across multiple providers with our powerful management platform.

Automatic Updates

Keep your DNS records in sync with your changing IP addresses.

Multi-Provider Support

Manage DNS records across Cloudflare, Route53, GoDaddy, and more.

Comprehensive Metrics

View performance metrics and history for all your DNS records.

); }