From 4b6bee1868a60721efad6b74c950696982b74109 Mon Sep 17 00:00:00 2001 From: gitadmin Date: Thu, 14 May 2026 16:37:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20SSO=20=E9=9B=86=E6=88=90=20=E2=80=94=20?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=20JWT=20+=20LDAP=20=E8=AE=A4=E8=AF=81=20+=20?= =?UTF-8?q?=E8=B7=A8=E7=AB=99=E7=82=B9=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?= =?UTF-8?q?=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 src/lib/jwt-shared.ts:共享 JWT 签发/验证(与 OA 共用密钥) - 新增 src/lib/ldap.ts:LDAP 认证与用户存在性检查 - 新增 src/app/api/internal/roles/route.ts:内部 API 供 OA 查询角色 - 重构 auth.ts:SSO 共享 JWT 验证 - 重构 middleware.ts:SSO 优先 + 本地认证回退 - 更新 docker-compose.yml:挂载 docker.sock 用于运行时 LLDAP 密码获取 - 更新 next.config.ts:serverExternalPackages 添加 ldapts - 更新 Dockerfile:生产依赖安装优化 --- CHANGELOG.md | 31 ++++++++ CLAUDE.md | 21 +++++- Dockerfile | 5 +- docker-compose.yml | 9 ++- next.config.ts | 4 +- oa-cloud-fixed.png | Bin 0 -> 29195 bytes oa-cloud-login.png | Bin 0 -> 64183 bytes oa-login-current.png | Bin 0 -> 63329 bytes oa-login-page.png | Bin 0 -> 23136 bytes package-lock.json | 19 +++++ package.json | 1 + public/.gitkeep | 0 src/app/(app)/settings/users/page.tsx | 24 +++++- src/app/api/auth/login/route.ts | 87 +++++++++++++++++++-- src/app/api/auth/logout/route.ts | 4 +- src/app/api/auth/me/route.ts | 39 +--------- src/app/api/internal/roles/route.ts | 13 ++++ src/app/api/tickets/[id]/route.ts | 2 +- src/app/api/tickets/batch/route.ts | 2 +- src/app/api/users/[id]/route.ts | 14 +++- src/app/api/users/route.ts | 7 +- src/app/page.tsx | 11 +-- src/components/tickets/TicketList.tsx | 7 +- src/lib/auth.ts | 44 ++++++++++- src/lib/db-schema.ts | 28 ++++--- src/lib/jwt-shared.ts | 61 +++++++++++++++ src/lib/ldap.ts | 71 +++++++++++++++++ src/middleware.ts | 105 +++++++++++++------------- 28 files changed, 473 insertions(+), 136 deletions(-) create mode 100644 oa-cloud-fixed.png create mode 100644 oa-cloud-login.png create mode 100644 oa-login-current.png create mode 100644 oa-login-page.png create mode 100644 public/.gitkeep create mode 100644 src/app/api/internal/roles/route.ts create mode 100644 src/lib/jwt-shared.ts create mode 100644 src/lib/ldap.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 65cda11..b9c95b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # 变更日志 +## 2026-05-14 + +- [修复] SSO 新用户免登录失败:根页面 `getCurrentUser()` 改为直接 `redirect('/dashboard')`,由中间件统一处理共享 JWT 认证(与 assets-ai 行为一致) +- [修复] `next.config.ts` 添加 `ldapts` 到 `serverExternalPackages`,确保 Next.js standalone 构建包含 LLDAP 客户端模块,避免 `ldapUserExists()` 因模块缺失失败导致 SSO 自动创建用户静默中断 +- [调整] 全局证书切换:Cloudflare Origin CA → Let's Encrypt(`/etc/letsencrypt/live/www.tlyq.ai/`),覆盖全部 7 个子域名,nginx 8 个站点配置同步更新 + +## 2026-05-12 + +- [部署] 云端 JWT 密钥统一为 oa-shared-jwt-secret-tlyq-2026,三站点密钥一致 +- [部署] docker-compose 移除 AUTHELIA_URL,添加 LDAP/COOKIE/INTERNAL_API_KEY 环境变量 +- [部署] LLDAP admin 密码更新为 3Vm!Y!@RCiPs +- [部署] nginx 移除 auth_request,恢复纯反向代理;改为运行时 DNS 解析 +- [新增] `src/lib/db-schema.ts`:users 表新增 last_login_at / last_active_at 列 +- [新增] `src/lib/auth.ts`:getCurrentUser() 更新 last_active_at +- [新增] `src/app/api/auth/login/route.ts`:登录时更新 last_login_at 和 last_active_at + +## 2026-05-11 + +- [新增] `src/lib/ldap.ts`:`ldapUserExists()` 函数,检查 LLDAP 中用户是否存在(admin bind 搜索,不可达时容错放行) +- [新增] `src/lib/jwt-shared.ts`:共享 JWT 签发/验证(`tlyq_session` cookie,HS256,与 OA/assets 共用密钥) +- [调整] `src/lib/auth.ts`:`getCurrentUser()` 优先 `tlyq_session`,加入 LLDAP 存在性检查,用户被删除后自动清除 cookie 踢出 +- [调整] `src/app/api/auth/login/route.ts`:LDAP 优先认证 + 本地密码缓存回退 + localadmin 应急用户直连 +- [调整] `src/app/api/auth/logout/route.ts`:同时清除 `session_issue` 和 `tlyq_session` +- [调整] `src/app/api/auth/me/route.ts`:移除 SSO header 路径,改用 `getCurrentUser()` 统一获取 +- [调整] `src/middleware.ts`:优先 `tlyq_session` → 回退 `session_issue`,移除 SSO 代理路径,放行 `/api/internal/` +- [新增] `src/app/api/internal/roles/route.ts`:内部 API,返回站点可用角色列表(INTERNAL_API_KEY 鉴权) +- [新增] `src/app/api/users/[id]/route.ts`:admin/localadmin 用户禁止删除和修改角色 +- [修复] `src/components/tickets/TicketList.tsx`:已办工单点击业务IP/节点名称跳转到待办页面,改用 `usePathname()` 保持当前页面并正确筛选 +- [调整] `src/app/(app)/settings/users/page.tsx`:admin/localadmin 用户隐藏删除按钮,编辑时角色字段显示为只读 +- [新增] `src/lib/db-schema.ts`:预置 localadmin 应急用户(admin 角色,纯本地 BCrypt 认证) + ## 2026-05-07 - [新增] 月报跨月进行中工单支持:第一章折线图覆盖未结单离线天数,第二章标注"处理中",第三章显示"进行中"/"—",第四章标注"仅计本月部分" diff --git a/CLAUDE.md b/CLAUDE.md index 18156bd..94eb76a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -99,11 +99,16 @@ npm run import # 导入工单 ### 认证 +登录逻辑(v2.1):LDAP 优先 + 本地密码缓存回退 + localadmin 应急用户。 +登录成功签发两个 cookie:`session_issue`(本地 JWT,7 天)+ `tlyq_session`(共享 JWT,7 天,domain=.tlyq.ai)。 +中间件优先检查 `tlyq_session`,回退 `session_issue`。`getCurrentUser()` 每次验证时检查 LLDAP 用户是否存在(已删除则清除 cookie 踢出)。 + | 方法 | 路径 | 说明 | |------|------|------| -| POST | `/api/auth/login` | 登录(username + password → JWT cookie) | -| POST | `/api/auth/logout` | 登出 | +| POST | `/api/auth/login` | 登录(LDAP 优先 + 本地回退) | +| POST | `/api/auth/logout` | 登出(清除两个 cookie) | | GET | `/api/auth/me` | 当前用户信息 | +| GET | `/api/internal/roles` | 内部 API:返回角色列表(x-internal-key 鉴权) | ### 工单 @@ -133,6 +138,14 @@ npm run import # 导入工单 --- +## 认证机制 + +- **Web UI(v2.1)**:`middleware.ts` 优先检查 `tlyq_session`(共享 JWT,OA 统一签发)→ 回退 `session_issue`(本地 JWT)。`getCurrentUser()` 每次请求时检查 LLDAP 用户是否存在,已删除则清除 cookie 踢出 +- **localadmin**:纯本地 BCrypt 认证,不依赖 LLDAP,用于 LLDAP 故障时应急登录(DB 预置,admin 角色) +- **API Key**:`Bearer ak_<32位十六进制>`,存储时 SHA-256 hash,由 `ALLOWED_API_KEYS` 控制 + +--- + ## 环境配置 ### 本地与云端差异 @@ -225,7 +238,9 @@ NEXT_PUBLIC_ASSETS_URL=https://assets.tlyq.ai - **新增 API**:在 `src/app/api/` 下创建路由 → 顶部调用 `initDatabase()` → `getCurrentUser()` 验证 → `hasPermission()` 校验 - **新增页面**:在 `src/app/(app)/` 下创建 → 布局由 `(app)/layout.tsx` 提供 - **权限格式**:`resource:action`,如 `hasPermission(user, 'tickets:write')` -- **日期处理**:禁止使用 `Date.toISOString()` 格式化本地日期。`toISOString()` 返回 UTC 时间,在中国时区(UTC+8)下 `new Date('2026-04-01T00:00:00').toISOString()` 会返回 `"2026-03-31T16:00:00.000Z"`,日期偏移一天。应使用本地时间方法拼接:`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}` +- **日期处理(时区规范)**:整个系统统一使用 UTC+8(北京时间)。两处必须遵守: + 1. **JavaScript/TypeScript**:禁止使用 `Date.toISOString()` 格式化本地日期。`toISOString()` 返回 UTC 时间,在中国时区(UTC+8)下 `new Date('2026-04-01T00:00:00').toISOString()` 会返回 `"2026-03-31T16:00:00.000Z"`,日期偏移一天。应使用本地时间方法拼接:`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}` + 2. **SQLite**:所有 `datetime('now')` 必须写成 `datetime('now', '+8 hours')`,包括 CREATE TABLE 的 DEFAULT 值、UPDATE/SET 语句、以及查询条件中的时间比较。禁止使用不含时区偏移的 `datetime('now')`。 --- diff --git a/Dockerfile b/Dockerfile index b3590b9..cae7bcc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,8 +33,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libcairo2 \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /app/package.json /app/package-lock.json ./ -RUN npm install --omit=dev COPY --from=builder /app/.next/standalone ./ +RUN npm install --omit=dev && \ + npm rebuild better-sqlite3 && \ + rm -rf node_modules/@img/sharp-linuxmusl-x64 node_modules/@img/sharp-libvips-linuxmusl-x64 \ + node_modules/@next/swc-linux-x64-musl COPY --from=builder /app/.next/static ./.next/static COPY --from=builder /app/public ./public RUN mkdir -p /app/data /app/uploads /app/reports diff --git a/docker-compose.yml b/docker-compose.yml index 0ea31df..50e77ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,14 +10,21 @@ services: - issue-reports:/app/reports # .next 目录从主机挂载,npm run build 后直接生效,无需重建镜像 - ./.next:/app/.next + # 运行时从 LLDAP 容器动态读取 admin 密码 + - /var/run/docker.sock:/var/run/docker.sock environment: - DATABASE_PATH=/app/data/issue.db - - JWT_SECRET=${ISSUE_JWT_SECRET:-change-me-in-production} + - JWT_SECRET=oa-shared-jwt-secret-tlyq-2026 - ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin123} - ASSETS_API_URL=${ASSETS_API_URL:-https://assets.tlyq.ai/api} - ASSETS_API_KEY=${ASSETS_API_KEY} - ALLOWED_API_KEYS=${ALLOWED_API_KEYS} - NODE_ENV=production + - COOKIE_DOMAIN=.tlyq.ai + - AUTHELIA_URL=${AUTHELIA_URL:-https://sso.tlyq.ai} + - LDAP_URL=ldap://lldap:3890 + - LDAP_BASE_DN=dc=tlyq,dc=ai + - LDAP_ADMIN_DN=uid=admin,ou=people,dc=tlyq,dc=ai - TZ=Asia/Shanghai restart: unless-stopped networks: diff --git a/next.config.ts b/next.config.ts index dd4b3dd..966379f 100644 --- a/next.config.ts +++ b/next.config.ts @@ -4,7 +4,9 @@ const nextConfig: NextConfig = { images: { unoptimized: true }, eslint: { ignoreDuringBuilds: true }, typescript: { ignoreBuildErrors: true }, - serverExternalPackages: ['better-sqlite3'], + // better-sqlite3: 原生模块,必须 external + // ldapts: SSO 自动创建用户依赖 LLDAP 验证,缺少则新用户无法免登录进入系统 + serverExternalPackages: ['better-sqlite3', 'ldapts'], // 确保 fs.readFileSync 加载的文件也被追踪到 standalone 输出中 // 防止 Docker 镜像中 npm install --omit=dev 漏装时缺失依赖 outputFileTracingIncludes: { diff --git a/oa-cloud-fixed.png b/oa-cloud-fixed.png new file mode 100644 index 0000000000000000000000000000000000000000..a8bc38a938e2b9f167b47a9557149afb79eba9cb GIT binary patch literal 29195 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

>D$!GS~T-JDVA_RIZNl0uwDkV1R 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�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 Af&c&j literal 0 HcmV?d00001 diff --git a/oa-login-current.png b/oa-login-current.png new file mode 100644 index 0000000000000000000000000000000000000000..5a45c50d4455b2d4f0e2ced327f667f319915470 GIT binary patch literal 63329 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

|!=uGsMN=K^$ea{u*D3UPnNm;y^KS$YDr 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 IU$=k$KN^O!(*OVf literal 0 HcmV?d00001 diff --git a/oa-login-page.png b/oa-login-page.png new file mode 100644 index 0000000000000000000000000000000000000000..55293b48d791e65aaab3710f869d3d9903272d43 GIT binary patch literal 23136 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 6304c15..66a79ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "echarts": "^5.5.0", "jsonwebtoken": "^9.0.2", "jszip": "^3.10.1", + "ldapts": "^8.1.7", "lucide-react": "^1.8.0", "next": "^15.1.0", "puppeteer": "^23.0.0", @@ -3592,6 +3593,18 @@ "json-buffer": "3.0.1" } }, + "node_modules/ldapts": { + "version": "8.1.7", + "resolved": "https://registry.npmjs.org/ldapts/-/ldapts-8.1.7.tgz", + "integrity": "sha512-TJl6T92eIwMf/OJ0hDfKVa6ISwzo+lqCWCI5Mf//ARlKa3LKQZaSrme/H2rCRBhW0DZCQlrsV+fgoW5YHRNLUw==", + "license": "MIT", + "dependencies": { + "strict-event-emitter-types": "2.0.0" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4978,6 +4991,12 @@ "text-decoder": "^1.1.0" } }, + "node_modules/strict-event-emitter-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", + "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==", + "license": "ISC" + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", diff --git a/package.json b/package.json index 72b2643..bd57457 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "echarts": "^5.5.0", "jsonwebtoken": "^9.0.2", "jszip": "^3.10.1", + "ldapts": "^8.1.7", "lucide-react": "^1.8.0", "next": "^15.1.0", "puppeteer": "^23.0.0", diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/app/(app)/settings/users/page.tsx b/src/app/(app)/settings/users/page.tsx index 58911a0..416249a 100644 --- a/src/app/(app)/settings/users/page.tsx +++ b/src/app/(app)/settings/users/page.tsx @@ -11,6 +11,8 @@ interface User { role: string is_active: number created_at: string + last_login_at: string | null + is_online: number } export default function UsersPage() { @@ -85,7 +87,7 @@ export default function UsersPage() { {loading ? (

) : ( - +
{users.map(u => ( @@ -97,11 +99,20 @@ export default function UsersPage() { {u.is_active ? '启用' : '禁用'} + + @@ -115,7 +126,14 @@ export default function UsersPage() { setForm(p => ({ ...p, display_name: e.target.value }))} required /> setForm(p => ({ ...p, password: e.target.value }))} /> setForm(p => ({ ...p, email: e.target.value }))} /> - setForm(p => ({ ...p, role: e.target.value }))} /> + )} {error &&

{error}

}
diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index 5dbf2c9..af84e03 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -1,16 +1,93 @@ import { NextRequest, NextResponse } from 'next/server' -import { login } from '@/lib/auth' +import { createToken } from '@/lib/auth' import { initDatabase } from '@/lib/db-schema' +import { signSharedJwt, sharedCookieConfig } from '@/lib/jwt-shared' +import { ldapAuth } from '@/lib/ldap' +import { getDb } from '@/lib/db' +import bcrypt from 'bcryptjs' export async function POST(request: NextRequest) { try { initDatabase() const { username, password } = await request.json() if (!username || !password) return NextResponse.json({ error: '请输入用户名和密码' }, { status: 400 }) - const result = await login(username, password) - if (!result) return NextResponse.json({ error: '用户名或密码错误' }, { status: 401 }) - const response = NextResponse.json({ user: result.user }) - response.cookies.set('session_issue', result.token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: 7 * 24 * 60 * 60, path: '/' }) + + let userId: number + let role: string + let displayName: string + const db = getDb() + + // 1. localadmin:纯本地 BCrypt,不依赖 LLDAP + if (username === 'localadmin') { + const localUser = db.prepare( + 'SELECT * FROM users WHERE username = ? AND is_active = 1' + ).get(username) as { id: number; username: string; display_name: string; role: string; password_hash: string } | undefined + if (!localUser || !bcrypt.compareSync(password, localUser.password_hash)) { + return NextResponse.json({ error: '用户名或密码错误' }, { status: 401 }) + } + userId = localUser.id + role = localUser.role + displayName = localUser.display_name || username + } else { + // 2. 其他用户:LLDAP 优先 + const ldapResult = await ldapAuth(username, password) + + if (ldapResult.success) { + // LDAP 认证成功 → 更新本地密码缓存 + 自动创建用户 + displayName = ldapResult.displayName || username + const pwHash = bcrypt.hashSync(password, 10) + const existing = db.prepare( + 'SELECT id, role FROM users WHERE username = ? AND is_active = 1' + ).get(username) as { id: number; role: string } | undefined + + if (existing) { + db.prepare('UPDATE users SET password_hash = ?, display_name = ? WHERE id = ?') + .run(pwHash, displayName, existing.id) + userId = existing.id + role = existing.role + } else { + db.prepare( + "INSERT INTO users (username, password_hash, display_name, role, is_active, created_at, updated_at) VALUES (?, ?, ?, 'viewer', 1, datetime('now', '+8 hours'), datetime('now', '+8 hours'))" + ).run(username, pwHash, displayName) + const created = db.prepare( + 'SELECT id, role FROM users WHERE username = ?' + ).get(username) as { id: number; role: string } | undefined + if (!created) return NextResponse.json({ error: '用户创建失败' }, { status: 500 }) + userId = created.id + role = created.role + } + } else if (ldapResult.unreachable) { + // LLDAP 不可达 → 回退本地密码缓存 + const localUser = db.prepare( + 'SELECT * FROM users WHERE username = ? AND is_active = 1' + ).get(username) as { id: number; username: string; display_name: string; role: string; password_hash: string } | undefined + if (!localUser || !bcrypt.compareSync(password, localUser.password_hash)) { + return NextResponse.json({ error: '认证服务不可用,且本地密码不匹配' }, { status: 401 }) + } + userId = localUser.id + role = localUser.role + displayName = localUser.display_name || username + } else { + return NextResponse.json({ error: '用户名或密码错误' }, { status: 401 }) + } + } + + // 3. 更新最后登录时间和活跃时间 + db.prepare("UPDATE users SET last_login_at = datetime('now', '+8 hours'), last_active_at = datetime('now', '+8 hours') WHERE id = ?").run(userId) + + // 4. 签发两个 cookie + const localToken = await createToken({ id: userId, username, display_name: displayName, role }) + const sharedToken = signSharedJwt({ username, displayName }) + const sharedCfg = sharedCookieConfig() + + const response = NextResponse.json({ + user: { id: userId, username, display_name: displayName, role }, + }) + response.cookies.set('session_issue', localToken, { + httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', + maxAge: 7 * 24 * 60 * 60, path: '/', + }) + response.cookies.set(sharedCfg.name, sharedToken, sharedCfg) return response } catch (e) { console.error('Login error:', e); return NextResponse.json({ error: '登录失败' }, { status: 500 }) } } diff --git a/src/app/api/auth/logout/route.ts b/src/app/api/auth/logout/route.ts index b684ae7..32dba4c 100644 --- a/src/app/api/auth/logout/route.ts +++ b/src/app/api/auth/logout/route.ts @@ -3,8 +3,6 @@ import { NextResponse } from 'next/server' export async function POST() { const r = NextResponse.json({ success: true }) r.cookies.set('session_issue', '', { maxAge: 0, path: '/' }) - r.cookies.set('session', '', { maxAge: 0, path: '/' }) - // 清除 Authelia SSO cookie - r.cookies.set('authelia_session', '', { maxAge: 0, path: '/', domain: '127.0.0.1' }) + r.cookies.set('tlyq_session', '', { maxAge: 0, path: '/' }) return r } diff --git a/src/app/api/auth/me/route.ts b/src/app/api/auth/me/route.ts index 74b7e37..39000d1 100644 --- a/src/app/api/auth/me/route.ts +++ b/src/app/api/auth/me/route.ts @@ -1,45 +1,8 @@ import { NextResponse } from 'next/server' -import { cookies, headers } from 'next/headers' -import { getDb } from '@/lib/db' -import { getCurrentUser, createToken } from '@/lib/auth' +import { getCurrentUser } from '@/lib/auth' export async function GET() { try { - const cookieStore = await cookies() - - // 路径 1:SSO(来自 nginx auth_request 代理) - let ssoUsername = '' - try { - const ssoSession = cookieStore.get('session')?.value - if (ssoSession) ssoUsername = JSON.parse(ssoSession).username || '' - } catch { } - if (!ssoUsername) { - const headersList = await headers() - ssoUsername = headersList.get('x-remote-user') || '' - } - - if (ssoUsername) { - const db = getDb() - db.prepare( - "INSERT OR IGNORE INTO users (username, password_hash, display_name, role, is_active) VALUES (?, '__SSO__', ?, ?, 1)" - ).run(ssoUsername, ssoUsername, 'viewer') - const user = db.prepare( - 'SELECT id, username, display_name, role FROM users WHERE username = ? AND is_active = 1' - ).get(ssoUsername) as Record | undefined - if (user) { - const jwt = await createToken({ - id: user.id as number, - username: user.username as string, - display_name: (user.display_name as string) || '', - role: user.role as string, - }) - const response = NextResponse.json({ user }) - response.cookies.set('session_issue', jwt, { httpOnly: true, sameSite: 'lax', path: '/', maxAge: 7 * 24 * 60 * 60 }) - return response - } - } - - // 路径 2:JWT cookie(本地开发 / @fallback 紧急绕过) const user = await getCurrentUser() if (!user) return NextResponse.json({ error: '未登录' }, { status: 401 }) return NextResponse.json({ user }) diff --git a/src/app/api/internal/roles/route.ts b/src/app/api/internal/roles/route.ts new file mode 100644 index 0000000..493c00f --- /dev/null +++ b/src/app/api/internal/roles/route.ts @@ -0,0 +1,13 @@ +import { NextRequest, NextResponse } from 'next/server' +import { getDb } from '@/lib/db' + +const INTERNAL_KEY = process.env.INTERNAL_API_KEY || 'oa-internal-key-tlyq-2026' + +export async function GET(request: NextRequest) { + const key = request.headers.get('x-internal-key') + if (key !== INTERNAL_KEY) return NextResponse.json({ error: 'Forbidden' }, { status: 403 }) + + const db = getDb() + const roles = db.prepare('SELECT name, display_name FROM roles ORDER BY name').all() as { name: string; display_name: string }[] + return NextResponse.json({ roles }) +} diff --git a/src/app/api/tickets/[id]/route.ts b/src/app/api/tickets/[id]/route.ts index 2cb7dd1..084f837 100644 --- a/src/app/api/tickets/[id]/route.ts +++ b/src/app/api/tickets/[id]/route.ts @@ -90,7 +90,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{ if (fields.length > 0) { fields.push('updated_by = ?') values.push(user.id) - fields.push("updated_at = datetime('now')") + fields.push("updated_at = datetime('now', '+8 hours')") values.push(id) db.prepare(`UPDATE tickets SET ${fields.join(', ')} WHERE id = ?`).run(...values) } diff --git a/src/app/api/tickets/batch/route.ts b/src/app/api/tickets/batch/route.ts index 44f15b7..8e28c42 100644 --- a/src/app/api/tickets/batch/route.ts +++ b/src/app/api/tickets/batch/route.ts @@ -35,7 +35,7 @@ export async function PUT(request: NextRequest) { } if (fields.length === 0) continue - fields.push("updated_at = datetime('now')") + fields.push("updated_at = datetime('now', '+8 hours')") fields.push('updated_by = ?') values.push(user.id) values.push(item.id) diff --git a/src/app/api/users/[id]/route.ts b/src/app/api/users/[id]/route.ts index 0df46da..0013586 100644 --- a/src/app/api/users/[id]/route.ts +++ b/src/app/api/users/[id]/route.ts @@ -15,9 +15,14 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{ const body = await request.json() const db = getDb() - const existing = db.prepare('SELECT id FROM users WHERE id = ?').get(id) + const existing = db.prepare('SELECT id, username FROM users WHERE id = ?').get(id) as { id: number; username: string } | undefined if (!existing) return NextResponse.json({ error: '用户不存在' }, { status: 404 }) + // 禁止修改系统保留用户的角色 + if (body.role && (existing.username === 'admin' || existing.username === 'localadmin')) { + return NextResponse.json({ error: '不能修改系统保留用户的角色' }, { status: 400 }) + } + const fields: string[] = [] const values: unknown[] = [] @@ -28,7 +33,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{ if (body.password) { fields.push('password_hash = ?'); values.push(hashPassword(body.password)) } if (fields.length > 0) { - fields.push("updated_at = datetime('now')") + fields.push("updated_at = datetime('now', '+8 hours')") values.push(id) db.prepare(`UPDATE users SET ${fields.join(', ')} WHERE id = ?`).run(...values) } @@ -52,8 +57,11 @@ export async function DELETE(_request: NextRequest, { params }: { params: Promis if (String(id) === String(user.id)) return NextResponse.json({ error: '不能删除自己' }, { status: 400 }) const db = getDb() - const existing = db.prepare('SELECT id FROM users WHERE id = ?').get(id) + const existing = db.prepare('SELECT id, username FROM users WHERE id = ?').get(id) as { id: number; username: string } | undefined if (!existing) return NextResponse.json({ error: '用户不存在' }, { status: 404 }) + if (existing.username === 'admin' || existing.username === 'localadmin') { + return NextResponse.json({ error: '不能删除系统保留用户' }, { status: 400 }) + } db.prepare('DELETE FROM users WHERE id = ?').run(id) return NextResponse.json({ success: true }) diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts index d09ae85..5a7bf4e 100644 --- a/src/app/api/users/route.ts +++ b/src/app/api/users/route.ts @@ -13,7 +13,10 @@ export async function GET() { if (!hasPermission(user, 'users:read')) return NextResponse.json({ error: '权限不足' }, { status: 403 }) const db = getDb() - const users = db.prepare('SELECT id, username, display_name, email, role, is_active, created_at, updated_at FROM users ORDER BY id').all() + const users = db.prepare(`SELECT id, username, display_name, email, role, is_active, created_at, updated_at, + last_login_at, + CASE WHEN last_active_at IS NOT NULL AND datetime(last_active_at, '+5 minutes') > datetime('now', '+8 hours') THEN 1 ELSE 0 END AS is_online + FROM users ORDER BY id`).all() return NextResponse.json({ users }) } catch (e) { const msg = e instanceof Error ? e.message : '查询失败' @@ -41,7 +44,7 @@ export async function POST(request: NextRequest) { const hash = hashPassword(password) const result = db.prepare( - 'INSERT INTO users (username, password_hash, display_name, email, role) VALUES (?, ?, ?, ?, ?)' + "INSERT INTO users (username, password_hash, display_name, email, role, created_at, updated_at) VALUES (?, ?, ?, ?, ?, datetime('now', '+8 hours'), datetime('now', '+8 hours'))" ).run(username, hash, display_name, email || null, role || 'viewer') const newUser = db.prepare('SELECT id, username, display_name, email, role, is_active, created_at FROM users WHERE id = ?').get(result.lastInsertRowid) diff --git a/src/app/page.tsx b/src/app/page.tsx index 32320dc..28c5ca1 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,12 +1,5 @@ -export const dynamic = 'force-dynamic' - import { redirect } from 'next/navigation' -import { getCurrentUser } from '@/lib/auth' -import { initDatabase } from '@/lib/db-schema' -export default async function Home() { - initDatabase() - const user = await getCurrentUser() - if (user) redirect('/dashboard') - else redirect('/login') +export default function Home() { + redirect('/dashboard') } diff --git a/src/components/tickets/TicketList.tsx b/src/components/tickets/TicketList.tsx index 618ae80..1690131 100644 --- a/src/components/tickets/TicketList.tsx +++ b/src/components/tickets/TicketList.tsx @@ -1,7 +1,7 @@ 'use client' import { useState, useEffect, useCallback, useRef, Suspense } from 'react' import Link from 'next/link' -import { useRouter, useSearchParams } from 'next/navigation' +import { useRouter, useSearchParams, usePathname } from 'next/navigation' import { Button, Badge, Pagination } from '@/components/ui' import { Search, Download, Eye, Pencil, Trash2, Filter, ArrowUpDown, ChevronsUpDown, ChevronUp, ChevronDown, Check, X, ExternalLink } from 'lucide-react' import SelectWithInput from '@/components/ui/SelectWithInput' @@ -148,6 +148,7 @@ interface TicketListInnerProps { function TicketListInner({ onPaginationChange, defaultStatusFilter, showSlaColumn, showActions = true, hideDefaultFilterChips }: TicketListInnerProps) { const router = useRouter() const searchParams = useSearchParams() + const pathname = usePathname() const [tickets, setTickets] = useState([]) const [pagination, setPagination] = useState({ page: 1, pageSize: 20, total: 0, totalPages: 0 }) const [loading, setLoading] = useState(true) @@ -652,12 +653,12 @@ function TicketListInner({ onPaginationChange, defaultStatusFilter, showSlaColum
diff --git a/src/lib/auth.ts b/src/lib/auth.ts index a8b9e8b..166821e 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -6,11 +6,51 @@ import { createToken, verifyToken, type UserPayload } from './jwt' export { createToken, verifyToken, type UserPayload } +import { verifySharedJwt } from './jwt-shared' +import { ldapUserExists } from './ldap' + export async function getCurrentUser(): Promise { const cookieStore = await cookies() + + // 优先 tlyq_session(共享 JWT,LDAP 用户) + const sharedToken = cookieStore.get('tlyq_session')?.value + if (sharedToken) { + const sharedPayload = verifySharedJwt(sharedToken) + if (sharedPayload) { + // Q1: 检查 LLDAP 中用户是否仍存在(已删除则强制退出) + if (!(await ldapUserExists(sharedPayload.username))) { + cookieStore.set('tlyq_session', '', { maxAge: 0, path: '/' }) + cookieStore.set('session_issue', '', { maxAge: 0, path: '/' }) + return null + } + const db = getDb() + const row = db.prepare( + 'SELECT id, username, display_name, role FROM users WHERE username = ? AND is_active = 1' + ).get(sharedPayload.username) as UserPayload | undefined + if (row) { + db.prepare("UPDATE users SET last_active_at = datetime('now', '+8 hours') WHERE id = ?").run(row.id) + return row + } + // SSO 免登录:LLDAP 验证通过但本地无记录 → 自动创建(viewer 角色) + db.prepare( + "INSERT OR IGNORE INTO users (username, display_name, role, is_active, created_at, updated_at) VALUES (?, ?, 'viewer', 1, datetime('now', '+8 hours'), datetime('now', '+8 hours'))" + ).run(sharedPayload.username, sharedPayload.displayName) + const newRow = db.prepare( + 'SELECT id, username, display_name, role FROM users WHERE username = ? AND is_active = 1' + ).get(sharedPayload.username) as UserPayload | undefined + if (newRow) return newRow + } + } + + // 回退 session_issue(本地 JWT,admin 账号或紧急绕过) const token = cookieStore.get('session_issue')?.value if (!token) return null - return verifyToken(token) + const payload = await verifyToken(token) + if (payload) { + const db2 = getDb() + db2.prepare("UPDATE users SET last_active_at = datetime('now', '+8 hours') WHERE id = ?").run(payload.id) + } + return payload } export async function login(username: string, password: string) { @@ -52,6 +92,6 @@ export function verifyApiKey(key: string): ApiKeyInfo | null { .get(keyHash) as { id: number; name: string; permissions: string; expires_at: string | null } | undefined if (!row) return null if (row.expires_at && new Date(row.expires_at) < new Date()) return null - db.prepare("UPDATE api_keys SET last_used_at = datetime('now') WHERE id = ?").run(row.id) + db.prepare("UPDATE api_keys SET last_used_at = datetime('now', '+8 hours') WHERE id = ?").run(row.id) return { id: row.id, name: row.name, permissions: JSON.parse(row.permissions) } } diff --git a/src/lib/db-schema.ts b/src/lib/db-schema.ts index 9297961..c71b2ba 100644 --- a/src/lib/db-schema.ts +++ b/src/lib/db-schema.ts @@ -4,14 +4,14 @@ import bcrypt from 'bcryptjs' export function initDatabase(): void { const db = getDb() const schema = [ - "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, display_name TEXT NOT NULL, email TEXT, role TEXT NOT NULL DEFAULT 'viewer', is_active INTEGER NOT NULL DEFAULT 1, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')));", - "CREATE TABLE IF NOT EXISTS roles (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, display_name TEXT NOT NULL, permissions TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL DEFAULT (datetime('now')));", - "CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, expires_at TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')));", - "CREATE TABLE IF NOT EXISTS tickets (id INTEGER PRIMARY KEY, device_ip TEXT, device_sn TEXT, device_name TEXT, content TEXT, assign_time TEXT, close_time TEXT, duration_minutes INTEGER, availability REAL, process_summary TEXT, conclusion TEXT, fault_category TEXT, fault_subcategory TEXT, parts_replaced TEXT, parts_name TEXT, current_status TEXT NOT NULL DEFAULT 'open', counted_in_sla INTEGER NOT NULL DEFAULT 1, responsibility TEXT, created_by INTEGER REFERENCES users(id), updated_by INTEGER REFERENCES users(id), created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')));", - "CREATE TABLE IF NOT EXISTS ticket_steps (id INTEGER PRIMARY KEY AUTOINCREMENT, ticket_id INTEGER NOT NULL REFERENCES tickets(id) ON DELETE CASCADE, step_order INTEGER NOT NULL, time_node TEXT, handler TEXT, description TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')));", - "CREATE TABLE IF NOT EXISTS reports (id INTEGER PRIMARY KEY AUTOINCREMENT, report_type TEXT NOT NULL, period_start TEXT, period_end TEXT, format TEXT NOT NULL DEFAULT 'pdf', file_path TEXT, file_name TEXT, status TEXT NOT NULL DEFAULT 'pending', error_message TEXT, created_by INTEGER REFERENCES users(id), created_at TEXT NOT NULL DEFAULT (datetime('now')));", - "CREATE TABLE IF NOT EXISTS audit_logs (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER REFERENCES users(id), action TEXT NOT NULL, entity_type TEXT NOT NULL, entity_id INTEGER, details TEXT, ip_address TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')));", - "CREATE TABLE IF NOT EXISTS api_keys (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, key_hash TEXT NOT NULL, permissions TEXT NOT NULL DEFAULT '[\"tickets:read\"]', last_used_at TEXT, expires_at TEXT, is_active INTEGER NOT NULL DEFAULT 1, created_by INTEGER REFERENCES users(id), created_at TEXT NOT NULL DEFAULT (datetime('now')));" + "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, display_name TEXT NOT NULL, email TEXT, role TEXT NOT NULL DEFAULT 'viewer', is_active INTEGER NOT NULL DEFAULT 1, created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')), updated_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));", + "CREATE TABLE IF NOT EXISTS roles (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, display_name TEXT NOT NULL, permissions TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));", + "CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, expires_at TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));", + "CREATE TABLE IF NOT EXISTS tickets (id INTEGER PRIMARY KEY, device_ip TEXT, device_sn TEXT, device_name TEXT, content TEXT, assign_time TEXT, close_time TEXT, duration_minutes INTEGER, availability REAL, process_summary TEXT, conclusion TEXT, fault_category TEXT, fault_subcategory TEXT, parts_replaced TEXT, parts_name TEXT, current_status TEXT NOT NULL DEFAULT 'open', counted_in_sla INTEGER NOT NULL DEFAULT 1, responsibility TEXT, created_by INTEGER REFERENCES users(id), updated_by INTEGER REFERENCES users(id), created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')), updated_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));", + "CREATE TABLE IF NOT EXISTS ticket_steps (id INTEGER PRIMARY KEY AUTOINCREMENT, ticket_id INTEGER NOT NULL REFERENCES tickets(id) ON DELETE CASCADE, step_order INTEGER NOT NULL, time_node TEXT, handler TEXT, description TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));", + "CREATE TABLE IF NOT EXISTS reports (id INTEGER PRIMARY KEY AUTOINCREMENT, report_type TEXT NOT NULL, period_start TEXT, period_end TEXT, format TEXT NOT NULL DEFAULT 'pdf', file_path TEXT, file_name TEXT, status TEXT NOT NULL DEFAULT 'pending', error_message TEXT, created_by INTEGER REFERENCES users(id), created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));", + "CREATE TABLE IF NOT EXISTS audit_logs (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER REFERENCES users(id), action TEXT NOT NULL, entity_type TEXT NOT NULL, entity_id INTEGER, details TEXT, ip_address TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));", + "CREATE TABLE IF NOT EXISTS api_keys (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, key_hash TEXT NOT NULL, permissions TEXT NOT NULL DEFAULT '[\"tickets:read\"]', last_used_at TEXT, expires_at TEXT, is_active INTEGER NOT NULL DEFAULT 1, created_by INTEGER REFERENCES users(id), created_at TEXT NOT NULL DEFAULT (datetime('now', '+8 hours')));" ] for (const sql of schema) db.exec(sql) @@ -29,6 +29,10 @@ export function initDatabase(): void { db.prepare("UPDATE tickets SET ticket_type = 'OEM维修' WHERE ticket_type IS NULL AND fault_category IN ('硬件故障', '网络故障', '存储故障', '电源故障')").run() } catch { /* 迁移失败则保持原样 */ } + // 迁移:添加 last_login_at 和 last_active_at 列 + try { db.exec('ALTER TABLE users ADD COLUMN last_login_at TEXT') } catch { /* 列已存在 */ } + try { db.exec('ALTER TABLE users ADD COLUMN last_active_at TEXT') } catch { /* 列已存在 */ } + // 迁移:metadata 列(报告元数据 JSON) try { db.exec('ALTER TABLE reports ADD COLUMN metadata TEXT') } catch { /* 已存在 */ } @@ -45,7 +49,13 @@ export function initDatabase(): void { if (!existing) { const defaultPassword = process.env.ADMIN_PASSWORD || 'admin123' const hash = bcrypt.hashSync(defaultPassword, 10) - db.prepare('INSERT INTO users (username, password_hash, display_name, role) VALUES (?, ?, ?, ?)').run('admin', hash, '系统管理员', 'admin') + db.prepare("INSERT INTO users (username, password_hash, display_name, role, created_at, updated_at) VALUES (?, ?, ?, ?, datetime('now', '+8 hours'), datetime('now', '+8 hours'))").run('admin', hash, '系统管理员', 'admin') + } + const existingLocalAdmin = db.prepare('SELECT id FROM users WHERE username = ?').get('localadmin') + if (!existingLocalAdmin) { + const localPassword = process.env.LOCALADMIN_PASSWORD || 'admin123' + const localHash = bcrypt.hashSync(localPassword, 10) + db.prepare("INSERT INTO users (username, password_hash, display_name, role, created_at, updated_at) VALUES (?, ?, ?, ?, datetime('now', '+8 hours'), datetime('now', '+8 hours'))").run('localadmin', localHash, '本地管理员', 'admin') } const roles = [ { name: 'admin', display_name: '管理员', permissions: '["*"]' }, diff --git a/src/lib/jwt-shared.ts b/src/lib/jwt-shared.ts new file mode 100644 index 0000000..17b593a --- /dev/null +++ b/src/lib/jwt-shared.ts @@ -0,0 +1,61 @@ +import crypto from 'crypto' + +const JWT_SECRET = process.env.JWT_SECRET || 'change-me-same-across-all-sites' +const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || '' + +export interface SharedSession { + username: string + displayName: string + iat: number + exp: number +} + +function base64url(str: string): string { + return Buffer.from(str).toString('base64url') +} + +export function signSharedJwt( + payload: { username: string; displayName: string }, + expiresIn: number = 7 * 24 * 60 * 60 +): string { + const header = { alg: 'HS256', typ: 'JWT' } + const now = Math.floor(Date.now() / 1000) + const body = { ...payload, iat: now, exp: now + expiresIn } + const segments = [base64url(JSON.stringify(header)), base64url(JSON.stringify(body))] + const signingInput = segments.join('.') + segments.push( + crypto.createHmac('sha256', JWT_SECRET).update(signingInput).digest('base64url') + ) + return segments.join('.') +} + +export function verifySharedJwt(token: string): SharedSession | null { + try { + const parts = token.split('.') + if (parts.length !== 3) return null + const signingInput = parts.slice(0, 2).join('.') + const expectedSig = crypto.createHmac('sha256', JWT_SECRET) + .update(signingInput).digest('base64url') + if (parts[2] !== expectedSig) return null + const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString()) + if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) return null + return { + username: payload.username, + displayName: payload.displayName, + iat: payload.iat, + exp: payload.exp, + } + } catch { return null } +} + +export function sharedCookieConfig(maxAge: number = 7 * 24 * 60 * 60) { + return { + name: 'tlyq_session', + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax' as const, + domain: COOKIE_DOMAIN, + path: '/', + maxAge, + } +} diff --git a/src/lib/ldap.ts b/src/lib/ldap.ts new file mode 100644 index 0000000..262e057 --- /dev/null +++ b/src/lib/ldap.ts @@ -0,0 +1,71 @@ +import { Client, InvalidCredentialsError } from 'ldapts' +import { execFileSync } from 'child_process' + +const LDAP_URL = process.env.LDAP_URL || 'ldap://localhost:3890' +const LDAP_BASE_DN = process.env.LDAP_BASE_DN || 'dc=tlyq,dc=ai' + +// 运行时从 LLDAP 容器动态获取 admin 密码,避免明文存于多个 .env +// 需要容器挂载 /var/run/docker.sock +function getLdapAdminPassword(): string { + try { + return execFileSync('docker', ['exec', 'lldap', 'printenv', 'LLDAP_ADMIN_PASSWORD'], + { timeout: 3000 }).toString().trim() + } catch { return 'admin123' } +} + +export interface LdapResult { + success: boolean + unreachable: boolean + username?: string + displayName?: string +} + +export async function ldapAuth( + username: string, + password: string +): Promise { + const userDn = `uid=${username},ou=people,${LDAP_BASE_DN}` + const client = new Client({ url: LDAP_URL, timeout: 5000 }) + + try { + await client.bind(userDn, password) + try { + const { searchEntries } = await client.search(LDAP_BASE_DN, { + scope: 'sub', + filter: `(uid=${username})`, + attributes: ['displayName'], + timeLimit: 3, + }) + const displayName = (searchEntries[0] as any)?.displayName || username + return { success: true, unreachable: false, username, displayName } + } catch { + return { success: true, unreachable: false, username, displayName: username } + } + } catch (err) { + if (err instanceof InvalidCredentialsError) { + return { success: false, unreachable: false } + } + return { success: false, unreachable: true } + } finally { + await client.unbind() + } +} + +// Q1: 检查 LLDAP 中用户是否存在(用 admin bind 搜索,不在/不可达均返回 true 保证容错) +export async function ldapUserExists(username: string): Promise { + const adminDn = process.env.LDAP_ADMIN_DN || 'uid=admin,ou=people,dc=tlyq,dc=ai' + const adminPass = getLdapAdminPassword() + const client = new Client({ url: LDAP_URL, timeout: 5000 }) + + try { + await client.bind(adminDn, adminPass) + const { searchEntries } = await client.search(LDAP_BASE_DN, { + scope: 'sub', filter: `(uid=${username})`, timeLimit: 3, + }) + return searchEntries.length > 0 + } catch { + return true // LLDAP 不可达 → 不阻断,容错放行 + } finally { + await client.unbind() + } +} diff --git a/src/middleware.ts b/src/middleware.ts index 024f36e..bf067c7 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,81 +1,84 @@ import { NextRequest, NextResponse } from 'next/server' -import { verifyToken } from '@/lib/jwt' + +function decodeJwtPayload(token: string): Record | null { + try { + const parts = token.split('.') + if (parts.length !== 3) return null + let payload = parts[1].replace(/-/g, '+').replace(/_/g, '/') + while (payload.length % 4) payload += '=' + return JSON.parse(atob(payload)) + } catch { return null } +} + +function isValidPayload(payload: Record | null): boolean { + if (!payload) return false + return !(payload.exp && (payload.exp as number) < Math.floor(Date.now() / 1000)) +} function verifyApiKey(key: string): boolean { const allowedKeys = process.env.ALLOWED_API_KEYS || '' if (!allowedKeys) return false - const keys = allowedKeys.split(',').map(k => k.trim()) - return keys.includes(key) + return allowedKeys.split(',').map(k => k.trim()).includes(key) } -export async function middleware(request: NextRequest) { +function buildLoginRedirect(request: NextRequest) { + const { pathname } = request.nextUrl + const loginUrl = new URL('/login', request.url) + const dest = pathname + (request.nextUrl.search || '') + loginUrl.searchParams.set('redirect', dest) + return NextResponse.redirect(loginUrl) +} + +export function middleware(request: NextRequest) { const { pathname } = request.nextUrl - // 清除外部注入的 trust proxy headers(防伪造) - const requestHeaders = new Headers(request.headers) - requestHeaders.delete('x-remote-user') - requestHeaders.delete('x-remote-groups') - - // SSO 代理认证路径:检测 X-Remote-User header + 代理密钥验证 - const remoteUser = request.headers.get('x-remote-user') - const proxyKey = request.headers.get('x-auth-proxy-key') - const isFromNginx = proxyKey === 'internal-auth-key-tlyq-2026' - - if (remoteUser && isFromNginx) { - // logout 路径不设置 SSO session(避免清除后又重新设置) - if (pathname === '/api/auth/logout') return NextResponse.next() - - const response = pathname === '/login' || pathname === '/' - ? NextResponse.redirect(new URL('/tickets', request.url)) - : NextResponse.next() - - response.cookies.set('session', JSON.stringify({ username: remoteUser }), { - httpOnly: true, - sameSite: 'lax', - path: '/', - }) - if (pathname.startsWith('/api/')) { - response.headers.set('x-original-pathname', pathname + (request.nextUrl.search || '')) - } - return response + // 登录/退出路径 + 内部 API 放行(自有 key 认证) + if (pathname.startsWith('/login') || pathname === '/' || + pathname === '/api/auth/login' || pathname === '/api/auth/logout' || + pathname.startsWith('/api/internal/')) { + return NextResponse.next() } - // 回退:现有 JWT 认证路径 - if (pathname.startsWith('/login') || pathname === '/') return NextResponse.next() - if (pathname === '/api/auth/login') return NextResponse.next() - + // API Key 认证(外部系统调用) const authHeader = request.headers.get('authorization') - if (authHeader?.startsWith('Bearer ak_')) { const key = authHeader.slice(7) if (verifyApiKey(key)) return NextResponse.next() if (pathname.startsWith('/api/')) return NextResponse.next() } - const token = request.cookies.get('session_issue')?.value - - function buildLoginRedirect() { - const loginUrl = new URL('/login', request.url) - const dest = pathname + (request.nextUrl.search || '') - loginUrl.searchParams.set('redirect', dest) - const response = NextResponse.redirect(loginUrl) - if (token) response.cookies.delete('session_issue') + // 优先检查 tlyq_session(共享 JWT) + const sharedToken = request.cookies.get('tlyq_session')?.value + const sharedPayload = sharedToken ? decodeJwtPayload(sharedToken) : null + if (isValidPayload(sharedPayload)) { + const response = pathname.startsWith('/api/') ? NextResponse.next() : NextResponse.next() + response.cookies.set('session', JSON.stringify({ username: sharedPayload.username }), { + httpOnly: true, sameSite: 'lax', path: '/', + }) return response } + // 回退 session_issue(本地 JWT) + const localToken = request.cookies.get('session_issue')?.value + const localPayload = localToken ? decodeJwtPayload(localToken) : null + if (pathname.startsWith('/api/')) { - if (!token) return NextResponse.json({ error: '未登录' }, { status: 401 }) - const valid = await verifyToken(token) - if (!valid) return NextResponse.json({ error: '会话已过期' }, { status: 401 }) + if (!isValidPayload(localPayload)) { + return NextResponse.json({ error: '未登录' }, { status: 401 }) + } return NextResponse.next() } - if (!token) return buildLoginRedirect() - const valid = await verifyToken(token) - if (!valid) return buildLoginRedirect() + if (!isValidPayload(localPayload)) { + const response = buildLoginRedirect(request) + if (localToken) response.cookies.delete('session_issue') + return response + } const response = NextResponse.next() - response.headers.set('x-original-pathname', pathname + (request.nextUrl.search || '')) + response.cookies.set('session', JSON.stringify({ username: localPayload.username }), { + httpOnly: true, sameSite: 'lax', path: '/', + }) return response }
{u.username} + + + {u.is_online ? '在线' : '离线'} + + {u.last_login_at ? u.last_login_at : 从未登录} {u.created_at || '-'}
- + {u.username !== 'admin' && u.username !== 'localadmin' && ( + + )}
{t.id} {t.device_ip ? ( - {t.device_ip} + {t.device_ip} ) : '-'} {t.device_name ? ( - {t.device_name} + {t.device_name} ) : '-'} {t.content || '-'}