middlewares.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { Hono } from 'hono'
  2. import { cors } from 'hono/cors'
  3. import type { Context as HonoContext } from 'hono'
  4. import { Auth } from '@d8d-appcontainer/auth'
  5. import type { User as AuthUser } from '@d8d-appcontainer/auth'
  6. // 扩展AuthUser类型
  7. declare module '@d8d-appcontainer/auth' {
  8. interface User {
  9. id: number
  10. username: string
  11. role: 'admin' | 'student' | 'fan' | 'teacher'
  12. student_expires_at?: string | null
  13. }
  14. }
  15. import { APIClient } from '@d8d-appcontainer/api'
  16. import type { SystemSettingRecord } from '../client/share/types.ts'
  17. import debug from "debug"
  18. const log = {
  19. auth: debug('auth:server')
  20. }
  21. // 定义自定义上下文类型
  22. export interface Variables {
  23. auth: Auth
  24. user?: AuthUser
  25. apiClient: APIClient
  26. moduleDir: string
  27. systemSettings?: SystemSettingRecord
  28. }
  29. // 认证中间件
  30. export const withAuth = async (c: HonoContext<{ Variables: Variables }>, next: () => Promise<void>) => {
  31. try {
  32. const auth = c.get('auth')
  33. const apiClient = c.get('apiClient');
  34. const token = c.req.header('Authorization')?.replace('Bearer ', '')
  35. if (token) {
  36. const userData = await auth.verifyToken(token)
  37. if (userData) {
  38. // 实时查询当前用户的角色
  39. const userRole = await apiClient.database.table('users')
  40. .where('id', userData.id)
  41. .select('role')
  42. .first()
  43. userData.role = userRole.role;
  44. c.set('user', userData)
  45. await next()
  46. return
  47. }
  48. }
  49. return c.json({ error: '未授权' }, 401)
  50. } catch (error) {
  51. log.auth('认证失败:', error)
  52. return c.json({ error: '无效凭证' }, 401)
  53. }
  54. }
  55. // 导出withAuth类型定义
  56. export type WithAuth = typeof withAuth;
  57. // 环境变量设置中间件
  58. export const setEnvVariables = (apiClient: APIClient, moduleDir: string, auth: Auth) => {
  59. return async (c: HonoContext<{ Variables: Variables }>, next: () => Promise<void>) => {
  60. c.set('apiClient', apiClient)
  61. c.set('moduleDir', moduleDir)
  62. c.set('auth', auth)
  63. c.set('systemSettings', await initSystemSettings(apiClient))
  64. await next()
  65. }
  66. }
  67. // CORS中间件
  68. export const corsMiddleware = cors()
  69. // 初始化系统设置
  70. const initSystemSettings = async (apiClient: APIClient) => {
  71. try {
  72. const systemSettings = await apiClient.database.table('system_settings')
  73. .select()
  74. // 将系统设置转换为键值对形式
  75. const settings = systemSettings.reduce((acc: Record<string, any>, setting: any) => {
  76. acc[setting.key] = setting.value
  77. return acc
  78. }, {}) as SystemSettingRecord
  79. return settings
  80. } catch (error) {
  81. log.auth('获取系统设置失败:', error)
  82. return {} as SystemSettingRecord
  83. }
  84. }