shared/lib/auth/ldap.ts

47 lines
1.5 KiB
TypeScript

// shared/lib/auth/ldap.ts — LLDAP 认证
import { Client } from 'ldapts'
import type { LdapAuthResult } from './types'
export interface LdapConfig {
url: string
baseDn: string
adminDn?: string
adminPassword?: string
adminGroup?: string
}
// LDAP bind 认证用户
export async function ldapAuth(config: LdapConfig, username: string, password: string): Promise<LdapAuthResult> {
const client = new Client({ url: config.url, timeout: 5000 })
try {
const userDn = `uid=${username},ou=people,${config.baseDn}`
await client.bind(userDn, password)
return { success: true, username }
} catch (err: unknown) {
const message = err instanceof Error ? err.message : 'LDAP auth failed'
return { success: false, error: message }
} finally {
await client.unbind()
}
}
// 检查用户是否在 admin 组中
export async function checkAdminGroup(config: LdapConfig, username: string): Promise<boolean> {
if (!config.adminDn || !config.adminPassword || !config.adminGroup) return false
const client = new Client({ url: config.url, timeout: 5000 })
try {
await client.bind(config.adminDn, config.adminPassword)
const { searchEntries } = await client.search(`cn=${config.adminGroup},ou=groups,${config.baseDn}`, {
scope: 'sub',
filter: `(member=uid=${username},ou=people,${config.baseDn})`,
attributes: ['cn'],
sizeLimit: 1,
})
return searchEntries.length > 0
} catch {
return false
} finally {
await client.unbind()
}
}