Add LDAP/Active Directory authentication (#794)

Users can authenticate against an LDAP/AD server with configurable
  server URL, bind DN, search base, and user filter. Supports StartTLS
  and LDAPS — plaintext is not allowed. Both Active Directory (memberOf)
  and POSIX groups (memberUid) are mapped to BamBuddy groups on each
  login. Auto-provisioning creates local accounts on first LDAP login.
  Local admin accounts remain as fallback when LDAP is unreachable.
  Password management is disabled for LDAP users.
This commit is contained in:
maziggy
2026-04-08 10:41:27 +02:00
parent f3a8d5db20
commit b6599dd419
25 changed files with 1740 additions and 254 deletions
+27
View File
@@ -903,6 +903,16 @@ export interface AppSettings {
queue_shortest_first: boolean;
// Default sidebar order (admin-set for all users)
default_sidebar_order: string;
// LDAP authentication
ldap_enabled: boolean;
ldap_server_url: string;
ldap_bind_dn: string;
ldap_bind_password: string;
ldap_search_base: string;
ldap_user_filter: string;
ldap_security: string;
ldap_group_mapping: string;
ldap_auto_provision: boolean;
}
export type AppSettingsUpdate = Partial<AppSettings>;
@@ -2275,6 +2285,7 @@ export interface UserResponse {
role: string; // Deprecated, kept for backward compatibility
is_active: boolean;
is_admin: boolean; // Computed from role and group membership
auth_source: string; // "local" or "ldap"
groups: GroupBrief[];
permissions: Permission[]; // All permissions from groups
created_at: string;
@@ -2344,6 +2355,16 @@ export interface AdvancedAuthStatus {
smtp_configured: boolean;
}
export interface LDAPStatus {
ldap_enabled: boolean;
ldap_configured: boolean;
}
export interface LDAPTestResponse {
success: boolean;
message: string;
}
export interface SetupResponse {
auth_enabled: boolean;
admin_created?: boolean;
@@ -2399,6 +2420,12 @@ export const api = {
method: 'POST',
}),
getAdvancedAuthStatus: () => request<AdvancedAuthStatus>('/auth/advanced-auth/status'),
// LDAP Authentication
getLDAPStatus: () => request<LDAPStatus>('/auth/ldap/status'),
testLDAP: () =>
request<LDAPTestResponse>('/auth/ldap/test', {
method: 'POST',
}),
forgotPassword: (data: ForgotPasswordRequest) =>
request<ForgotPasswordResponse>('/auth/forgot-password', {
method: 'POST',