Files
pp-tcms/frontend/src/app/[locale]/admin/page.tsx
LittleYellow 1c977f9266 feat: add LDAP authentication settings and toggle
Add an admin-only LDAP configuration UI with an enable toggle and full
sign-in integration.

Backend:
- ldapSettings model + migration (single-row config)
- GET/PUT/test routes under /ldap (admin-gated; bind password masked)
- shared ldapClient with RFC 4515 filter escaping and empty-password guard
- signin tries local auth first, then LDAP when enabled (find-or-create
  local user) so the bootstrap admin is never locked out

Frontend:
- LDAP settings page (Switch + form + test connection) under /admin/ldap
- AdminNav tabs between user management and LDAP
- ldapControl util, types, and Ldap i18n namespace for all 6 locales

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 07:20:08 +08:00

48 lines
1.5 KiB
TypeScript

import { getTranslations } from 'next-intl/server';
import { useTranslations } from 'next-intl';
import AdminPage from './AdminPage';
import { PageType } from '@/types/base';
import { LocaleCodeType } from '@/types/locale';
import { AdminMessages } from '@/types/user';
export async function generateMetadata({ params: { locale } }: { params: { locale: LocaleCodeType } }) {
const t = await getTranslations({ locale, namespace: 'Admin' });
return {
title: `${t('user_management')} | UnitTCMS`,
robots: { index: false, follow: false },
};
}
export default function Page({ params }: PageType) {
const t = useTranslations('Admin');
const messages: AdminMessages = {
userManagement: t('user_management'),
ldap: t('ldap'),
avatar: t('avatar'),
id: t('id'),
email: t('email'),
username: t('username'),
role: t('role'),
administrator: t('administrator'),
user: t('user'),
noUsersFound: t('no_users_found'),
quitAdmin: t('quit_admin'),
quit: t('quit'),
quitConfirm: t('quit_confirm'),
close: t('close'),
roleChanged: t('role_changed'),
lostAdminAuth: t('lost_admin_auth'),
atLeast: t('at_least'),
resetPassword: t('reset_password'),
reset: t('reset'),
invalidPassword: t('invalid_password'),
passwordNotMatch: t('password_not_match'),
};
return (
<div className="w-full flex items-center justify-center">
<AdminPage messages={messages} locale={params.locale as LocaleCodeType} />
</div>
);
}