test(auth): more and more auth setup

This commit is contained in:
2025-04-08 06:46:56 -05:00
parent 4371fcc028
commit b630bae50d
10 changed files with 265 additions and 47 deletions

View File

@@ -1,9 +1,14 @@
import { createFileRoute } from '@tanstack/react-router' import ModulesPage from "@/components/admin/modules/ModulePage";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute('/_admin/modules')({ export const Route = createFileRoute("/_admin/modules")({
component: RouteComponent, component: RouteComponent,
}) });
function RouteComponent() { function RouteComponent() {
return <div>Hello "/_admin/modules"!</div> return (
<div>
<ModulesPage />
</div>
);
} }

View File

@@ -0,0 +1,14 @@
import SubModulePage from "@/components/admin/supModules/SubModulePage";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/_admin/subModules")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<SubModulePage />
</div>
);
}

View File

@@ -0,0 +1,25 @@
import { queryOptions } from "@tanstack/react-query";
import axios from "axios";
export function getModules(token: string) {
return queryOptions({
queryKey: ["modules"],
queryFn: () => fetchSettings(token),
enabled: !!token,
//staleTime: 1000,
refetchOnWindowFocus: true,
});
}
const fetchSettings = async (token: string) => {
const { data } = await axios.get("/api/server/modules", {
headers: { Authorization: `Bearer ${token}` },
});
// if we are not localhost ignore the devDir setting.
const url: string = window.location.host.split(":")[0];
let settingsData = data.data;
if (url != "localhost") {
settingsData.filter((n: any) => n.name === "devDir");
}
return settingsData;
};

View File

@@ -0,0 +1,25 @@
import { queryOptions } from "@tanstack/react-query";
import axios from "axios";
export function getSubModules(token: string) {
return queryOptions({
queryKey: ["submodules"],
queryFn: () => fetchSettings(token),
enabled: !!token,
//staleTime: 1000,
refetchOnWindowFocus: true,
});
}
const fetchSettings = async (token: string) => {
const { data } = await axios.get("/api/server/submodules", {
headers: { Authorization: `Bearer ${token}` },
});
// if we are not localhost ignore the devDir setting.
const url: string = window.location.host.split(":")[0];
let settingsData = data.data;
if (url != "localhost") {
settingsData.filter((n: any) => n.name === "devDir");
}
return settingsData;
};

View File

@@ -0,0 +1,26 @@
import { queryOptions } from "@tanstack/react-query";
import axios from "axios";
export function getUserRoles() {
const token = localStorage.getItem("auth_token");
return queryOptions({
queryKey: ["getUsers"],
queryFn: () => fetchUsers(token),
enabled: !!token, // Prevents query if token is null
staleTime: 1000,
//refetchInterval: 2 * 2000,
refetchOnWindowFocus: true,
});
}
const fetchUsers = async (token: string | null) => {
const { data } = await axios.get(`/api/auth/allusersroles`, {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});
// if we are not localhost ignore the devDir setting.
//const url: string = window.location.host.split(":")[0];
return data.data ?? [];
};

View File

@@ -9,6 +9,7 @@ import { areRolesIn } from "./utils/roleCheck.js";
import createUser from "./routes/userAdmin/createUser.js"; import createUser from "./routes/userAdmin/createUser.js";
import allUsers from "./routes/userAdmin/getUsers.js"; import allUsers from "./routes/userAdmin/getUsers.js";
import updateUser from "./routes/userAdmin/updateUser.js"; import updateUser from "./routes/userAdmin/updateUser.js";
import allUserRoles from "./routes/userAdmin/getAllUserRoles.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
@@ -26,6 +27,7 @@ const routes = [
setAccess, setAccess,
createUser, createUser,
allUsers, allUsers,
allUserRoles,
updateUser, updateUser,
] as const; ] as const;

View File

@@ -0,0 +1,24 @@
import { db } from "../../../../../database/dbclient.js";
import { userRoles } from "../../../../../database/schema/userRoles.js";
import { returnRes } from "../../../../globalUtils/routeDefs/returnRes.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js";
export const getAllUsersRoles = async () => {
/**
* returns all users that are in lst
*/
createLog("info", "apiAuthedRoute", "auth", "Get all users");
const { data, error } = await tryCatch(db.select().from(userRoles));
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 };
};

View File

@@ -11,7 +11,19 @@ export const roleCheck = async (user_id: string | undefined) => {
if (!user_id) { if (!user_id) {
throw Error("Missing user_id"); throw Error("Missing user_id");
} }
let returnRoles: any = [];
// get the user roles by the user_id // get the user roles by the user_id
returnRoles = await db
.select({
user_id: userRoles.user_id,
role_id: userRoles.role_id,
module_id: userRoles.module_id,
role: userRoles.role,
})
.from(userRoles)
.where(eq(userRoles.user_id, user_id));
if (returnRoles[0]?.role.includes("systemAdmin")) {
const roles = await db const roles = await db
.select({ .select({
user_id: userRoles.user_id, user_id: userRoles.user_id,
@@ -23,4 +35,7 @@ export const roleCheck = async (user_id: string | undefined) => {
.where(eq(userRoles.user_id, user_id)); .where(eq(userRoles.user_id, user_id));
return roles; return roles;
}
return returnRoles;
}; };

View File

@@ -3,7 +3,7 @@ pass over a users uuid and return all modules they have permission too.
in the login route we attach it to user under roles. in the login route we attach it to user under roles.
*/ */
import {eq} from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import { db } from "../../../../../database/dbclient.js"; import { db } from "../../../../../database/dbclient.js";
import { userRoles } from "../../../../../database/schema/userRoles.js"; import { userRoles } from "../../../../../database/schema/userRoles.js";
import { users } from "../../../../../database/schema/users.js"; import { users } from "../../../../../database/schema/users.js";
@@ -11,13 +11,30 @@ import {modules} from "../../../../../database/schema/modules.js";
import { roles } from "../../../../../database/schema/roles.js"; import { roles } from "../../../../../database/schema/roles.js";
import { setSysAdmin } from "./setSysAdmin.js"; import { setSysAdmin } from "./setSysAdmin.js";
export const setUserAccess = async (username: string, moduleName: string, roleName: string, override?: string) => { export const setUserAccess = async (
username: string,
moduleName: string,
roleName: string,
override?: string
) => {
// get the user roles by the user_id // get the user roles by the user_id
const user = await db.select().from(users).where(eq(users.username, username)); const user = await db
const module = await db.select().from(modules).where(eq(modules.name, moduleName)); .select()
.from(users)
.where(eq(users.username, username));
const module = await db
.select()
.from(modules)
.where(eq(modules.name, moduleName));
if (process.env.SECRETOVERRIDECODE != override && roleName === "systemAdmin") { if (
return {success: false, message: "The override code provided is invalid."}; process.env.SECRETOVERRIDECODE != override &&
roleName === "systemAdmin"
) {
return {
success: false,
message: "The override code provided is invalid.",
};
} }
const role = await db.select().from(roles).where(eq(roles.name, roleName)); const role = await db.select().from(roles).where(eq(roles.name, roleName));
@@ -37,9 +54,12 @@ export const setUserAccess = async (username: string, moduleName: string, roleNa
// set the user // set the user
try { try {
const userRole = await db const userRole = await db.insert(userRoles).values({
.insert(userRoles) user_id: user[0].user_id,
.values({user_id: user[0].user_id, role_id: role[0].role_id, module_id: module[0].module_id, role: roleName}); role_id: role[0].role_id,
module_id: module[0].module_id,
role: roleName,
});
//.returning({user: users.username, email: users.email}); //.returning({user: users.username, email: users.email});
// return c.json({message: "User Registered", user}, 200); // return c.json({message: "User Registered", user}, 200);
@@ -48,10 +68,38 @@ export const setUserAccess = async (username: string, moduleName: string, roleNa
message: `${username} has been granted access to ${moduleName} with the role ${roleName}`, message: `${username} has been granted access to ${moduleName} with the role ${roleName}`,
}; };
} catch (error) { } catch (error) {
await changeRole(
roleName,
user[0].user_id,
module[0].module_id,
role[0].role_id
);
return { return {
success: false, success: true,
message: `There was an error granting ${username} access to ${moduleName} with the role ${roleName}`, message: `${username} access on ${moduleName} has been changed to ${roleName}`,
data: error,
}; };
} }
}; };
const changeRole = async (
role: any,
userID: any,
moduleID: any,
roleID: any
) => {
await db
.delete(userRoles)
.where(
and(
eq(userRoles.user_id, userID),
eq(userRoles.module_id, moduleID)
)
);
const userRole = await db.insert(userRoles).values({
user_id: userID,
role_id: roleID,
module_id: moduleID,
role: role,
});
};

View File

@@ -0,0 +1,34 @@
import { z, createRoute, OpenAPIHono } from "@hono/zod-openapi";
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
import { authMiddleware } from "../../middleware/authMiddleware.js";
import hasCorrectRole from "../../middleware/roleCheck.js";
import { getAllUsersRoles } from "../../controllers/userAdmin/getAllUserRoles.js";
const app = new OpenAPIHono();
app.openapi(
createRoute({
tags: ["Auth:admin"],
summary: "Gets Users Roles",
method: "get",
path: "/allusersroles",
middleware: [
authMiddleware,
hasCorrectRole(["admin", "systemAdmin"], "admin"),
],
responses: responses(),
}),
async (c) => {
// apit hit
//apiHit(c, {endpoint: "api/auth/register"});
const allUsers: any = await getAllUsersRoles();
return c.json({
success: allUsers?.success,
message: allUsers?.message,
data: allUsers?.data,
});
}
);
export default app;