"use client"; import { SettingsContainer, SettingsSection, SettingsSectionBody, SettingsSectionDescription, SettingsSectionForm, SettingsSectionGrid, SettingsSectionHeader, SettingsSectionTitle } from "@app/components/Settings"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@app/components/ui/form"; import HeaderTitle from "@app/components/SettingsSectionTitle"; import { z } from "zod"; import { createElement, useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { Input } from "@app/components/ui/input"; import { Button } from "@app/components/ui/button"; import { createApiClient, formatAxiosError } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { toast } from "@app/hooks/useToast"; import { useRouter } from "next/navigation"; import { Checkbox } from "@app/components/ui/checkbox"; import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert"; import { InfoIcon, ExternalLink } from "lucide-react"; import { StrategySelect } from "@app/components/StrategySelect"; import { SwitchInput } from "@app/components/SwitchInput"; import { useTranslations } from "next-intl"; export default function Page() { const { env } = useEnvContext(); const api = createApiClient({ env }); const router = useRouter(); const [createLoading, setCreateLoading] = useState(false); const t = useTranslations(); const createIdpFormSchema = z.object({ name: z.string().min(2, { message: t('nameMin', {len: 2}) }), type: z.enum(["oidc"]), clientId: z.string().min(1, { message: t('idpClientIdRequired') }), clientSecret: z.string().min(1, { message: t('idpClientSecretRequired') }), authUrl: z.string().url({ message: t('idpErrorAuthUrlInvalid') }), tokenUrl: z.string().url({ message: t('idpErrorTokenUrlInvalid') }), identifierPath: z .string() .min(1, { message: t('idpPathRequired') }), emailPath: z.string().optional(), namePath: z.string().optional(), scopes: z.string().min(1, { message: t('idpScopeRequired') }), autoProvision: z.boolean().default(false) }); type CreateIdpFormValues = z.infer; interface ProviderTypeOption { id: "oidc"; title: string; description: string; } const providerTypes: ReadonlyArray = [ { id: "oidc", title: "OAuth2/OIDC", description: t('idpOidcDescription') } ]; const form = useForm({ resolver: zodResolver(createIdpFormSchema), defaultValues: { name: "", type: "oidc", clientId: "", clientSecret: "", authUrl: "", tokenUrl: "", identifierPath: "sub", namePath: "name", emailPath: "email", scopes: "openid profile email", autoProvision: false } }); async function onSubmit(data: CreateIdpFormValues) { setCreateLoading(true); try { const payload = { name: data.name, clientId: data.clientId, clientSecret: data.clientSecret, authUrl: data.authUrl, tokenUrl: data.tokenUrl, identifierPath: data.identifierPath, emailPath: data.emailPath, namePath: data.namePath, autoProvision: data.autoProvision, scopes: data.scopes }; const res = await api.put("/idp/oidc", payload); if (res.status === 201) { toast({ title: t('success'), description: t('idpCreatedDescription') }); router.push(`/admin/idp/${res.data.data.idpId}`); } } catch (e) { toast({ title: t('error'), description: formatAxiosError(e), variant: "destructive" }); } finally { setCreateLoading(false); } } return ( <>
{t('idpTitle')} {t('idpCreateSettingsDescription')}
( {t('name')} {t('idpDisplayName')} )} />
{ form.setValue( "autoProvision", checked ); }} />
{t('idpAutoProvisionUsersDescription')}
{t('idpType')} {t('idpTypeDescription')} { form.setValue("type", value as "oidc"); }} cols={3} /> {form.watch("type") === "oidc" && ( {t('idpOidcConfigure')} {t('idpOidcConfigureDescription')}
( {t('idpClientId')} {t('idpClientIdDescription')} )} /> ( {t('idpClientSecret')} {t('idpClientSecretDescription')} )} /> ( {t('idpAuthUrl')} {t('idpAuthUrlDescription')} )} /> ( {t('idpTokenUrl')} {t('idpTokenUrlDescription')} )} /> {t('idpOidcConfigureAlert')} {t('idpOidcConfigureAlertDescription')}
{t('idpToken')} {t('idpTokenDescription')}
{t('idpJmespathAbout')} {t('idpJmespathAboutDescription')}{" "} {t('idpJmespathAboutDescriptionLink')}{" "} ( {t('idpJmespathLabel')} {t('idpJmespathLabelDescription')} )} /> ( {t('idpJmespathEmailPathOptional')} {t('idpJmespathEmailPathOptionalDescription')} )} /> ( {t('idpJmespathNamePathOptional')} {t('idpJmespathNamePathOptionalDescription')} )} /> ( {t('idpOidcConfigureScopes')} {t('idpOidcConfigureScopesDescription')} )} />
)}
); }