您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

123 行
3.4 KiB

  1. import { NextRequestWithAuth, withAuth } from "next-auth/middleware";
  2. import { ability, authOptions } from "@/config/authConfig";
  3. import { NextFetchEvent, NextResponse } from "next/server";
  4. import { getToken } from "next-auth/jwt";
  5. // user groups
  6. export const [
  7. SUPER_ADMIN,
  8. TOP_MANAGEMENT,
  9. TEAM_LEAD,
  10. NORMAL_STAFF,
  11. SUPPORTING_STAFF
  12. ] = [
  13. "Super Admin",
  14. "Top Management",
  15. "Team Leader",
  16. "Normal Staff",
  17. "Supporting Staff"
  18. ]
  19. // abilities
  20. export const [
  21. VIEW_USER,
  22. MAINTAIN_USER,
  23. MAINTAIN_TIMESHEET,
  24. VIEW_TASK_TEMPLATE,
  25. VIEW_GROUP,
  26. VIEW_MASTERDATA,
  27. MAINTAIN_MASTERDATA,
  28. VIEW_DASHBOARD_SELF,
  29. VIEW_DASHBOARD_ALL,
  30. IMPORT_INVOICE,
  31. MAINTAIN_GROUP,
  32. GENERATE_REPORTS,
  33. VIEW_STAFF_PROFILE,
  34. IMPORT_RECEIPT,
  35. MAINTAIN_TASK_TEMPLATE,
  36. MAINTAIN_TIMESHEET_7DAYS,
  37. VIEW_PROJECT,
  38. MAINTAIN_PROJECT,
  39. ] = [
  40. 'VIEW_USER',
  41. 'MAINTAIN_USER',
  42. 'MAINTAIN_TIMESHEET',
  43. 'VIEW_TASK_TEMPLATE',
  44. 'VIEW_GROUP',
  45. 'VIEW_MASTERDATA',
  46. 'MAINTAIN_MASTERDATA',
  47. 'VIEW_DASHBOARD_SELF',
  48. 'VIEW_DASHBOARD_ALL',
  49. 'IMPORT_INVOICE',
  50. 'MAINTAIN_GROUP',
  51. 'GENERATE_REPORTS',
  52. 'VIEW_STAFF_PROFILE',
  53. 'IMPORT_RECEIPT',
  54. 'MAINTAIN_TASK_TEMPLATE',
  55. 'MAINTAIN_TIMESHEET_7DAYS',
  56. 'VIEW_PROJECT',
  57. 'MAINTAIN_PROJECT'
  58. ]
  59. const PRIVATE_ROUTES = [
  60. "/analytics",
  61. "/dashboard",
  62. "/home",
  63. "/invoice",
  64. "/projects",
  65. "/tasks",
  66. "/settings",
  67. "/staffReimbursement",
  68. ];
  69. const LANG_QUERY_PARAM = "lang";
  70. export default async function middleware(
  71. req: NextRequestWithAuth,
  72. event: NextFetchEvent,
  73. ) {
  74. const langPref = req.nextUrl.searchParams.get(LANG_QUERY_PARAM);
  75. // const token = await getToken({ req: req, secret: process.env.SECRET });
  76. if (langPref) {
  77. // Redirect to same url without the lang query param + set cookies
  78. const newUrl = new URL(req.nextUrl);
  79. newUrl.searchParams.delete(LANG_QUERY_PARAM);
  80. const response = NextResponse.redirect(newUrl);
  81. response.cookies.set("i18next", langPref);
  82. return response;
  83. }
  84. const authMiddleware = withAuth({
  85. pages: authOptions.pages,
  86. callbacks: {
  87. authorized: ({req, token}) => {
  88. let isAuth = Boolean(token);
  89. if (!Boolean(token)) {
  90. return Boolean(token)
  91. }
  92. const abilities = (token!.abilities as ability[]).map((item: ability) => item.actionSubjectCombo);
  93. if (req.nextUrl.pathname.startsWith('/settings')) {
  94. isAuth = [VIEW_MASTERDATA, MAINTAIN_MASTERDATA].some((ability) => abilities.includes(ability));
  95. }
  96. if (req.nextUrl.pathname.startsWith('/settings/user')) {
  97. isAuth = [MAINTAIN_USER, VIEW_USER].some((ability) => abilities.includes(ability));
  98. }
  99. if (req.nextUrl.pathname.startsWith('/settings/staff/user')) {
  100. isAuth = [MAINTAIN_USER, VIEW_USER].some((ability) => abilities.includes(ability));
  101. }
  102. if (req.nextUrl.pathname.startsWith('/analytics')) {
  103. isAuth = [GENERATE_REPORTS].some((ability) => abilities.includes(ability));
  104. }
  105. if (req.nextUrl.pathname.startsWith('/settings/staff/edit')) {
  106. isAuth = [VIEW_STAFF_PROFILE].some((ability) => abilities.includes(ability));
  107. }
  108. return isAuth
  109. }
  110. }
  111. });
  112. // Matcher for using the auth middleware
  113. return PRIVATE_ROUTES.some((route) => req.nextUrl.pathname.startsWith(route))
  114. ? await authMiddleware(req, event) // Let auth middleware handle response
  115. : NextResponse.next(); // Return normal response
  116. }