102 lines
3.1 KiB
TypeScript
102 lines
3.1 KiB
TypeScript
import { Router, Request, Response } from 'express'
|
||
import { v4 as uuidv4 } from 'uuid'
|
||
import db from '../db.js'
|
||
import { sessionAuth } from '../middleware/auth.js'
|
||
|
||
const router = Router()
|
||
|
||
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD || 'newapi-admin'
|
||
|
||
// POST /api/auth/login
|
||
router.post('/login', async (req: Request, res: Response) => {
|
||
const { userId, accessToken, siteId } = req.body
|
||
|
||
if (!userId || !accessToken || !siteId) {
|
||
res.json({ success: false, message: '请填写完整信息' })
|
||
return
|
||
}
|
||
|
||
const site = db.prepare('SELECT * FROM sites WHERE id = ?').get(siteId) as any
|
||
if (!site) {
|
||
res.json({ success: false, message: '站点不存在' })
|
||
return
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`${site.url}/api/user/self`, {
|
||
headers: {
|
||
'Authorization': accessToken,
|
||
'New-Api-User': String(userId),
|
||
}
|
||
})
|
||
const result = await response.json() as any
|
||
|
||
if (!result.success) {
|
||
res.json({ success: false, message: result.message || '认证失败,请检查用户ID和令牌' })
|
||
return
|
||
}
|
||
|
||
const userInfo = result.data
|
||
if (userInfo.id !== Number(userId)) {
|
||
res.json({ success: false, message: '用户ID与令牌不匹配' })
|
||
return
|
||
}
|
||
|
||
const sessionId = uuidv4()
|
||
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
|
||
|
||
db.prepare(
|
||
'INSERT INTO sessions (id, user_id, access_token, site_id, site_url, user_info, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?)'
|
||
).run(sessionId, userId, accessToken, siteId, site.url, JSON.stringify(userInfo), expiresAt)
|
||
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
sessionToken: sessionId,
|
||
userInfo,
|
||
site: { id: site.id, name: site.name, url: site.url }
|
||
}
|
||
})
|
||
} catch (error: any) {
|
||
res.json({ success: false, message: `无法连接站点: ${error.message}` })
|
||
}
|
||
})
|
||
|
||
// POST /api/auth/logout
|
||
router.post('/logout', sessionAuth, (req: Request, res: Response) => {
|
||
db.prepare('DELETE FROM sessions WHERE id = ?').run(req.session!.id)
|
||
res.json({ success: true })
|
||
})
|
||
|
||
// GET /api/auth/me
|
||
router.get('/me', sessionAuth, (req: Request, res: Response) => {
|
||
const site = db.prepare('SELECT id, name, url FROM sites WHERE id = ?').get(req.session!.site_id)
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
userInfo: JSON.parse(req.session!.user_info),
|
||
site,
|
||
isAdmin: !!(req.session as any).is_admin
|
||
}
|
||
})
|
||
})
|
||
|
||
// POST /api/auth/elevate — promote to dashboard admin
|
||
router.post('/elevate', sessionAuth, (req: Request, res: Response) => {
|
||
const { password } = req.body
|
||
if (password !== ADMIN_PASSWORD) {
|
||
res.json({ success: false, message: '管理密码错误' })
|
||
return
|
||
}
|
||
db.prepare('UPDATE sessions SET is_admin = 1 WHERE id = ?').run(req.session!.id)
|
||
res.json({ success: true, message: '已升格为管理员' })
|
||
})
|
||
|
||
// POST /api/auth/demote — revoke dashboard admin
|
||
router.post('/demote', sessionAuth, (req: Request, res: Response) => {
|
||
db.prepare('UPDATE sessions SET is_admin = 0 WHERE id = ?').run(req.session!.id)
|
||
res.json({ success: true, message: '已取消管理员权限' })
|
||
})
|
||
|
||
export default router
|