fix: localadmin displayName 从数据库读取;Sidebar 权限驱动导航(userRole prop)
This commit is contained in:
parent
b5b59f1c3b
commit
c876a69443
|
|
@ -24,12 +24,13 @@ export async function POST(request: NextRequest) {
|
|||
|
||||
// localadmin 密码验证(查询数据库存储的密码)
|
||||
if (username === 'localadmin') {
|
||||
const users = dbQuery<{ password_hash: string; role: string }>(`SELECT password_hash, role FROM users WHERE username = 'localadmin'`)
|
||||
const users = dbQuery<{ password_hash: string; role: string; display_name: string | null }>(`SELECT password_hash, role, display_name FROM users WHERE username = 'localadmin'`)
|
||||
if (users.length === 0) {
|
||||
return NextResponse.json({ error: 'localadmin 未配置' }, { status: 401 })
|
||||
}
|
||||
const localadminUser = users[0]
|
||||
// 与数据库存储的 bcrypt 哈希比较
|
||||
if (!bcrypt.compareSync(password, users[0].password_hash)) {
|
||||
if (!bcrypt.compareSync(password, localadminUser.password_hash)) {
|
||||
writeAuditLog({ exec: dbExec }, {
|
||||
username, action: 'login_failed', entityType: 'auth',
|
||||
details: { method: 'localadmin', reason: 'wrong_password' },
|
||||
|
|
@ -38,7 +39,9 @@ export async function POST(request: NextRequest) {
|
|||
return NextResponse.json({ error: '密码错误' }, { status: 401 })
|
||||
}
|
||||
|
||||
const token = signJwt({ secret: authConfig.jwtSecret, payload: { username: 'localadmin', role: 'admin', displayName: 'localadmin' } })
|
||||
const displayName = localadminUser.display_name || 'localadmin'
|
||||
const role = localadminUser.role || 'admin'
|
||||
const token = signJwt({ secret: authConfig.jwtSecret, payload: { username: 'localadmin', role, displayName } })
|
||||
|
||||
writeAuditLog({ exec: dbExec }, {
|
||||
username, action: 'login', entityType: 'auth',
|
||||
|
|
@ -47,7 +50,7 @@ export async function POST(request: NextRequest) {
|
|||
})
|
||||
|
||||
const response = NextResponse.json({
|
||||
user: { username: 'localadmin', role: 'admin', displayName: 'localadmin' },
|
||||
user: { username: 'localadmin', role, displayName },
|
||||
})
|
||||
response.cookies.set('tlyq_session', token, {
|
||||
httpOnly: true, secure: false, sameSite: 'lax', path: '/', maxAge: 604800,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default function ClientLayout({ children }: { children: React.ReactNode }
|
|||
return (
|
||||
<ThemeProvider>
|
||||
<div className="min-h-screen bg-slate-50 dark:bg-slate-950">
|
||||
<Sidebar />
|
||||
<Sidebar userRole={user?.role} />
|
||||
<TopBar user={user} />
|
||||
<main className="ml-60 pt-14 min-h-screen">
|
||||
<div className="p-6">{children}</div>
|
||||
|
|
|
|||
|
|
@ -8,13 +8,10 @@ import { hasPermission } from '@/lib/permissions'
|
|||
interface NavItem { label: string; href: string; icon: React.ComponentType<{ size?: number }>; permission?: string }
|
||||
interface NavSection { title?: string; items: NavItem[] }
|
||||
|
||||
export default function Sidebar() {
|
||||
export default function Sidebar({ userRole = 'viewer' }: { userRole?: string }) {
|
||||
const pathname = usePathname()
|
||||
const isActive = (href: string) => pathname === href || (href !== '/' && pathname.startsWith(href))
|
||||
|
||||
// 默认显示所有导航项(客户端权限在 API 层强制验证,此处仅 UI 过滤)
|
||||
const userRole = 'admin' // TODO: 从 cookie 或 session 读取实际角色
|
||||
|
||||
const sections: NavSection[] = [
|
||||
{
|
||||
items: [
|
||||
|
|
|
|||
Loading…
Reference in New Issue