diff --git a/src/components/EditStaff/EditStaff.tsx b/src/components/EditStaff/EditStaff.tsx index 0d62e28..4c032cc 100644 --- a/src/components/EditStaff/EditStaff.tsx +++ b/src/components/EditStaff/EditStaff.tsx @@ -311,7 +311,7 @@ const EditStaff: React.FC = async () => { label: t(`Join Position`), type: "combo-Obj", options: positionCombo, - value: data[key].id ?? "", + value: data[key]?.id ?? "", required: true, } as Field; case "departDate": diff --git a/src/components/StaffSearch/StaffSearchWrapper.tsx b/src/components/StaffSearch/StaffSearchWrapper.tsx index c581ca8..59f9dc1 100644 --- a/src/components/StaffSearch/StaffSearchWrapper.tsx +++ b/src/components/StaffSearch/StaffSearchWrapper.tsx @@ -9,15 +9,22 @@ import { fetchPositionCombo } from "@/app/api/positions/actions"; import { fetchGradeCombo } from "@/app/api/grades/actions"; import { fetchSkillCombo } from "@/app/api/skill/actions"; import { fetchSalaryCombo } from "@/app/api/salarys/actions"; +import { Session, getServerSession } from "next-auth"; +import { authOptions } from "@/config/authConfig"; // import { preloadStaff } from "@/app/api/staff"; interface SubComponents { Loading: typeof StaffSearchLoading; } +interface SessionWithAbilities extends Session { + abilities?: string[] +} + const StaffSearchWrapper: React.FC & SubComponents = async () => { const staff = await fetchStaff(); - console.log(staff); + const session = await getServerSession(authOptions) as SessionWithAbilities; + console.log(session.abilities); return ; }; diff --git a/src/config/authConfig.ts b/src/config/authConfig.ts index e0c2860..e10f60d 100644 --- a/src/config/authConfig.ts +++ b/src/config/authConfig.ts @@ -3,10 +3,17 @@ import CredentialsProvider from "next-auth/providers/credentials"; import { LOGIN_API_PATH } from "./api"; export interface SessionWithTokens extends Session { + abilities?: any[]; accessToken?: string; refreshToken?: string; } + +export interface ability { + actionSubjectCombo: string; +} + + export const authOptions: AuthOptions = { debug: process.env.NODE_ENV === "development", providers: [ @@ -48,10 +55,12 @@ export const authOptions: AuthOptions = { const sessionWithToken: SessionWithTokens = { ...session, // Add the data from the token to the session + abilities: (token.abilities as ability[]).map((item: ability) => item.actionSubjectCombo) as string[], accessToken: token.accessToken as string | undefined, refreshToken: token.refreshToken as string | undefined, }; - + + // console.log(sessionWithToken) return sessionWithToken; }, }, diff --git a/src/middleware.ts b/src/middleware.ts index 85204dd..adf79a4 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,6 +1,50 @@ import { NextRequestWithAuth, withAuth } from "next-auth/middleware"; -import { authOptions } from "@/config/authConfig"; +import { ability, authOptions } from "@/config/authConfig"; import { NextFetchEvent, NextResponse } from "next/server"; +import { getToken } from "next-auth/jwt"; +import { ConnectingAirportsOutlined } from "@mui/icons-material"; +import { getServerSession } from "next-auth"; + +// abilities +export const [ + VIEW_USER, + MAINTAIN_USER, + MAINTAIN_TIMESHEET, + VIEW_TASK_TEMPLATE, + VIEW_GROUP, + VIEW_MASTERDATA, + MAINTAIN_MASTERDATA, + VIEW_DASHBOARD_SELF, + VIEW_DASHBOARD_ALL, + IMPORT_INVOICE, + MAINTAIN_GROUP, + GENERATE_REPORTS, + VIEW_STAFF_PROFILE, + IMPORT_RECEIPT, + MAINTAIN_TASK_TEMPLATE, + MAINTAIN_TIMESHEET_7DAYS, + VIEW_PROJECT, + MAINTAIN_PROJECT, +] = [ + 'VIEW_USER', + 'MAINTAIN_USER', + 'MAINTAIN_TIMESHEET', + 'VIEW_TASK_TEMPLATE', + 'VIEW_GROUP', + 'VIEW_MASTERDATA', + 'MAINTAIN_MASTERDATA', + 'VIEW_DASHBOARD_SELF', + 'VIEW_DASHBOARD_ALL', + 'IMPORT_INVOICE', + 'MAINTAIN_GROUP', + 'GENERATE_REPORTS', + 'VIEW_STAFF_PROFILE', + 'IMPORT_RECEIPT', + 'MAINTAIN_TASK_TEMPLATE', + 'MAINTAIN_TIMESHEET_7DAYS', + 'VIEW_PROJECT', + 'MAINTAIN_PROJECT' +] const PRIVATE_ROUTES = [ "/analytics", @@ -14,15 +58,12 @@ const PRIVATE_ROUTES = [ ]; const LANG_QUERY_PARAM = "lang"; -const authMiddleware = withAuth({ - pages: authOptions.pages, -}); - export default async function middleware( req: NextRequestWithAuth, event: NextFetchEvent, ) { const langPref = req.nextUrl.searchParams.get(LANG_QUERY_PARAM); + const token = await getToken({ req: req, secret: process.env.SECRET }); if (langPref) { // Redirect to same url without the lang query param + set cookies const newUrl = new URL(req.nextUrl); @@ -31,6 +72,70 @@ export default async function middleware( response.cookies.set("i18next", langPref); return response; } + + // const session = await getServerSession(authOptions); + // console.log(session); + + let abilities: string[] = [] + if (token) { + abilities = (token.abilities as ability[]).map((item: ability) => item.actionSubjectCombo); + } + + const authMiddleware = withAuth({ + pages: authOptions.pages, + callbacks: { + authorized: ({req, token}) => { + let isAuth = Boolean(token); + if (req.nextUrl.pathname.startsWith('/settings')) { + isAuth = [VIEW_MASTERDATA, MAINTAIN_MASTERDATA].some((ability) => abilities.includes(ability)); + } + if (req.nextUrl.pathname.startsWith('/settings/user')) { + isAuth = [MAINTAIN_USER, VIEW_USER].some((ability) => abilities.includes(ability)); + } + if (req.nextUrl.pathname.startsWith('/analytics')) { + isAuth = [GENERATE_REPORTS].some((ability) => abilities.includes(ability)); + } + if (req.nextUrl.pathname.startsWith('/settings/staff/edit')) { + isAuth = [VIEW_STAFF_PROFILE].some((ability) => abilities.includes(ability)); + } + return isAuth + } + } + }); + + + // for (const obj of abilities) { + // switch (obj.actionSubjectCombo.toLowerCase()) { + // case "maintain_user": + // // appendRoutes(settings) + // break; + // case "maintain_group": + // // appendRoutes("/testing-maintain_user") + // break; + // case "view_user": + // // appendRoutes("/testing-maintain_user") + // break; + // case "view_group": + // // appendRoutes("/testing-maintain_user") + // break; + // } + // } + +// console.log("TESTING_ROUTES: ") +// console.log(TESTING_ROUTES) + +// TESTING_ROUTES.some((route) => { +// if (req.nextUrl.pathname.startsWith(route)) { +// console.log("////////////////start//////////////// ") +// console.log("TESTING_ROUTES:") +// console.log("route:") +// console.log(route) +// console.log("pathname:") +// console.log(req.nextUrl.pathname) +// console.log("////////////////end////////////////") +// } +// return (req.nextUrl.pathname.startsWith(route)) +// }) // Matcher for using the auth middleware return PRIVATE_ROUTES.some((route) => req.nextUrl.pathname.startsWith(route))