From efc630f5f8dba2583f57fac74f596905240ff6e8 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Wed, 9 Apr 2025 17:47:02 -0500 Subject: [PATCH] refactor(auth): added module and submodule access to the user --- .../src/components/admin/user/UserPage.tsx | 29 +--- .../admin/user/components/ModuleAccess.tsx | 12 +- .../admin/user/components/ModuleForm.tsx | 146 +++++++++--------- .../admin/user/components/UserCard.tsx | 15 +- frontend/src/lib/store/useGetRoles.ts | 18 ++- frontend/src/utils/querys/admin/users.tsx | 2 +- frontend/src/utils/userAccess.ts | 35 ++++- .../auth/controllers/userAdmin/getUsers.ts | 46 ++++-- .../controllers/userRoles/setUserRoles.ts | 18 ++- .../auth/routes/userAdmin/setUserRoles.ts | 2 +- 10 files changed, 181 insertions(+), 142 deletions(-) diff --git a/frontend/src/components/admin/user/UserPage.tsx b/frontend/src/components/admin/user/UserPage.tsx index 01df3ea..6338fc2 100644 --- a/frontend/src/components/admin/user/UserPage.tsx +++ b/frontend/src/components/admin/user/UserPage.tsx @@ -1,9 +1,3 @@ -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; import { getUsers } from "@/utils/querys/admin/users"; import { useQuery } from "@tanstack/react-query"; import UserCard from "./components/UserCard"; @@ -22,22 +16,13 @@ export default function UserPage() { return (
- - {data.map((u: any) => { - return ( - - - {u.username} - - -
- -
-
-
- ); - })} -
+ {data.map((u: any) => { + return ( +
+ +
+ ); + })}
); } diff --git a/frontend/src/components/admin/user/components/ModuleAccess.tsx b/frontend/src/components/admin/user/components/ModuleAccess.tsx index 6b69e6c..42e9a59 100644 --- a/frontend/src/components/admin/user/components/ModuleAccess.tsx +++ b/frontend/src/components/admin/user/components/ModuleAccess.tsx @@ -19,11 +19,13 @@ export default function ModuleAccess(data: any) {
{modules?.map((m: any) => { return ( - +
+ +
); })}
diff --git a/frontend/src/components/admin/user/components/ModuleForm.tsx b/frontend/src/components/admin/user/components/ModuleForm.tsx index 1096a6d..827d9c5 100644 --- a/frontend/src/components/admin/user/components/ModuleForm.tsx +++ b/frontend/src/components/admin/user/components/ModuleForm.tsx @@ -1,4 +1,3 @@ -import { LstCard } from "@/components/extendedUI/LstCard"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { @@ -10,21 +9,26 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; -import { getUserRoles } from "@/utils/querys/admin/userRoles"; + import { useForm } from "@tanstack/react-form"; -import { useQuery } from "@tanstack/react-query"; + import axios from "axios"; import { toast } from "sonner"; export default function ModuleForm(props: any) { - const { refetch } = useQuery(getUserRoles()); const token = localStorage.getItem("auth_token"); + const role = + props.user?.moduleRoles?.filter( + (m: any) => m.module_id === props.module.module_id + )[0]?.role ?? " "; const form = useForm({ - defaultValues: { role: props.i.role }, + defaultValues: { + role: role, + }, onSubmit: async ({ value }) => { - const data = { - username: props.username, - module: props.i.name, + const data: any = { + username: props.user.username, + module: props.module.name, role: value.role, }; console.log(data); @@ -37,7 +41,7 @@ export default function ModuleForm(props: any) { if (res.data.success) { toast.success(res.data.message); - refetch(); + props.refetch(); form.reset(); } else { res.data.message; @@ -49,71 +53,67 @@ export default function ModuleForm(props: any) { }); return ( -
- -

Module: {props.i.name}

- -

Current role:

-
{ - e.preventDefault(); - e.stopPropagation(); +
+ { + e.preventDefault(); + e.stopPropagation(); + }} + className="flex flex-row" + > + {}}} + children={(field) => { + return ( +
+ + +
+ ); }} - > - {}}} - children={(field) => { - return ( -
- - -
- ); - }} - /> -
- -
- - + /> +
+ +
+
); } diff --git a/frontend/src/components/admin/user/components/UserCard.tsx b/frontend/src/components/admin/user/components/UserCard.tsx index 7ccd4a5..8646012 100644 --- a/frontend/src/components/admin/user/components/UserCard.tsx +++ b/frontend/src/components/admin/user/components/UserCard.tsx @@ -22,13 +22,12 @@ import axios from "axios"; import { toast } from "sonner"; import { CardHeader } from "@/components/ui/card"; +import ModuleAccess from "./ModuleAccess"; export default function UserCard(data: any) { const token = localStorage.getItem("auth_token"); const { refetch } = useQuery(getUsers()); - //console.log(modules); - //console.log(data.user); //console.log(userRoles); const form = useForm({ ...userFormOptions(data.user), @@ -268,13 +267,17 @@ export default function UserCard(data: any) { ); }} /> +
+ +
-
- -
-
+
+ + + +
); } diff --git a/frontend/src/lib/store/useGetRoles.ts b/frontend/src/lib/store/useGetRoles.ts index 0222776..0744b04 100644 --- a/frontend/src/lib/store/useGetRoles.ts +++ b/frontend/src/lib/store/useGetRoles.ts @@ -19,12 +19,18 @@ export const useGetUserRoles = create()((set) => ({ try { //const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`); const token = localStorage.getItem("auth_token"); - const response = await axios.get("/api/auth/getuseraccess", { - headers: { Authorization: `Bearer ${token}` }, - }); - const data: FetchModulesResponse = response.data; //await response.json(); - //console.log(data); - set({ userRoles: data.data }); + if (token) { + const response = await axios.get("/api/auth/getuseraccess", { + headers: { Authorization: `Bearer ${token}` }, + }); + const data: FetchModulesResponse = response.data; //await response.json(); + + //console.log(data); + set({ userRoles: data.data }); + } else { + //console.log(data); + set({ userRoles: [] }); + } } catch (error) { console.error("Failed to fetch settings:", error); } diff --git a/frontend/src/utils/querys/admin/users.tsx b/frontend/src/utils/querys/admin/users.tsx index 29f893d..a86e46e 100644 --- a/frontend/src/utils/querys/admin/users.tsx +++ b/frontend/src/utils/querys/admin/users.tsx @@ -8,7 +8,7 @@ export function getUsers() { queryFn: () => fetchUsers(token), enabled: !!token, // Prevents query if token is null staleTime: 1000, - //refetchInterval: 2 * 2000, + refetchInterval: 2 * 2000, refetchOnWindowFocus: true, }); } diff --git a/frontend/src/utils/userAccess.ts b/frontend/src/utils/userAccess.ts index 7dd7a16..3295eca 100644 --- a/frontend/src/utils/userAccess.ts +++ b/frontend/src/utils/userAccess.ts @@ -1,25 +1,44 @@ -import {Modules} from "@/types/modules"; -import {User} from "@/types/users"; +import { Modules } from "@/types/modules"; +import { User } from "@/types/users"; // user will need access to the module. // users role will determine there visual access -export function hasAccess(user: User | null, moduleName: string | null, modules: Modules[]): boolean { +export function hasAccess( + user: User | null, + moduleName: string | null, + modules: Modules[] +): boolean { // get the modules for the id const filteredModule = modules?.filter((f) => f.name === moduleName); - //console.log(filteredModule[0].module_id); + //console.log(filteredModule[0]); // userroles and filter out by the module id, - return user?.roles.find((role) => role.module_id === filteredModule[0].module_id) ? true : false; + const roleCheck: any = user?.roles.find( + (role) => role.module_id === filteredModule[0].module_id + ); + + if (filteredModule[0].roles.includes(roleCheck?.role)) { + return true; + } + //if(filteredModule[0].roles.includes(roleCheck.)) + return false; } -export function hasPageAccess(user: User | null, role: any, module_id: string): boolean { +export function hasPageAccess( + user: User | null, + role: any, + module_id: string +): boolean { if (role.includes("viewer")) return true; if (!user) return false; // get only the module in the user profile + //console.log(user); const userRole = user?.roles.filter((role) => role.module_id === module_id); + console.log(userRole[0]?.role); + // if (role.includes(userRole[0]?.role)) { - if (role.includes(userRole[0]?.role)) return true; - + // return true}; + if (userRole.length !== 0) return true; return false; } diff --git a/server/services/auth/controllers/userAdmin/getUsers.ts b/server/services/auth/controllers/userAdmin/getUsers.ts index 5421522..4a53bc9 100644 --- a/server/services/auth/controllers/userAdmin/getUsers.ts +++ b/server/services/auth/controllers/userAdmin/getUsers.ts @@ -1,24 +1,42 @@ import { db } from "../../../../../database/dbclient.js"; +import { userRoles } from "../../../../../database/schema/userRoles.js"; import { users } from "../../../../../database/schema/users.js"; import { returnRes } from "../../../../globalUtils/routeDefs/returnRes.js"; import { tryCatch } from "../../../../globalUtils/tryCatch.js"; import { createLog } from "../../../logger/logger.js"; export const getAllUsers = async () => { - /** - * returns all users that are in lst - */ - createLog("info", "apiAuthedRoute", "auth", "Get all users"); - const { data, error } = await tryCatch(db.select().from(users)); + /** + * returns all users that are in lst + */ + createLog("info", "apiAuthedRoute", "auth", "Get all users"); - if (error) { - returnRes( - false, - "There was an error getting users", - new Error("No user exists.") - ); - } + // get all users + const { data, error } = await tryCatch(db.select().from(users)); - returnRes(true, "All users.", data); - return { success: true, message: "All users", data }; + // add there modules they are in + const { data: m, error: em } = await tryCatch(db.select().from(userRoles)); + + const user: any = data; + const userData = user.map((i: any) => { + // module in + const module = m?.filter((x: any) => x.user_id === i.user_id); + + if (module) { + return { ...i, moduleRoles: module }; + } else { + return; + } + }); + + if (error) { + returnRes( + false, + "There was an error getting users", + new Error("No user exists.") + ); + } + + //returnRes(true, "All users.", data); + return { success: true, message: "All users", data: userData }; }; diff --git a/server/services/auth/controllers/userRoles/setUserRoles.ts b/server/services/auth/controllers/userRoles/setUserRoles.ts index 3f7414f..e27af52 100644 --- a/server/services/auth/controllers/userRoles/setUserRoles.ts +++ b/server/services/auth/controllers/userRoles/setUserRoles.ts @@ -54,12 +54,18 @@ export const setUserAccess = async ( // set the user try { - const userRole = await db.insert(userRoles).values({ - user_id: user[0].user_id, - role_id: role[0].role_id, - module_id: module[0].module_id, - role: roleName, - }); + const userRole = await db + .insert(userRoles) + .values({ + user_id: user[0].user_id, + role_id: role[0].role_id, + module_id: module[0].module_id, + role: roleName, + }) + .onConflictDoUpdate({ + target: userRoles.user_id, + set: { role_id: role[0].role_id, role: roleName }, + }); //.returning({user: users.username, email: users.email}); // return c.json({message: "User Registered", user}, 200); diff --git a/server/services/auth/routes/userAdmin/setUserRoles.ts b/server/services/auth/routes/userAdmin/setUserRoles.ts index 51f457f..eedfc84 100644 --- a/server/services/auth/routes/userAdmin/setUserRoles.ts +++ b/server/services/auth/routes/userAdmin/setUserRoles.ts @@ -59,7 +59,7 @@ app.openapi( { success: access.success, message: access.message, - data: access.data, + data: [], //access?.data, }, 200 );