你的重置密码验证码是:${code},10 分钟内有效。如非本人操作请忽略。
`, }) } + +export async function sendRegisterCode(to: string, code: string) { + await createTransporter().sendMail({ + from: '"MikiVL 笔记"你的注册验证码是:${code},10 分钟内有效。如非本人操作请忽略。
`, + }) +} diff --git a/server/middleware/auth.ts b/server/middleware/auth.ts index eab6905..cb09fe0 100644 --- a/server/middleware/auth.ts +++ b/server/middleware/auth.ts @@ -1,5 +1,7 @@ import { createMiddleware } from 'hono/factory' import jwt from 'jsonwebtoken' +import { db, users } from '../db' +import { eq } from 'drizzle-orm' export type JwtPayload = { userId: string; username: string } @@ -25,3 +27,21 @@ export const requireAuth = createMiddleware(async (c, next) => { return c.json({ error: 'Token 无效或已过期' }, 401) } }) + +export const requireAdmin = createMiddleware(async (c, next) => { + const header = c.req.header('Authorization') + if (!header?.startsWith('Bearer ')) { + return c.json({ error: '未登录' }, 401) + } + const token = header.slice(7) + try { + const payload = jwt.verify(token, process.env.JWT_SECRET!) as JwtPayload + const [user] = db.select({ role: users.role }).from(users).where(eq(users.id, payload.userId)).all() + if (!user || user.role !== 'admin') return c.json({ error: '权限不足' }, 403) + c.set('userId', payload.userId) + c.set('username', payload.username) + await next() + } catch { + return c.json({ error: 'Token 无效或已过期' }, 401) + } +}) diff --git a/server/routes/admin.ts b/server/routes/admin.ts new file mode 100644 index 0000000..ced4f42 --- /dev/null +++ b/server/routes/admin.ts @@ -0,0 +1,94 @@ +import { Hono } from 'hono' +import { eq } from 'drizzle-orm' +import { db, users, comments, inviteCodes, siteContent } from '../db' +import { requireAdmin } from '../middleware/auth' + +export const adminRouter = new Hono() +adminRouter.use('*', requireAdmin) + +function nanoid() { + return Math.random().toString(36).slice(2, 11) + Date.now().toString(36) +} + +// 站点内容读取 +adminRouter.get('/site-content', (c) => { + const rows = db.select().from(siteContent).all() + const result: Record{item.content}
+