diff --git a/app/src/internal/logistics/controller/schedulerManager.ts b/app/src/internal/logistics/controller/schedulerManager.ts index 67f3b18..0abb8f4 100644 --- a/app/src/internal/logistics/controller/schedulerManager.ts +++ b/app/src/internal/logistics/controller/schedulerManager.ts @@ -50,7 +50,7 @@ export const schedulerManager = async () => { //console.log(data); if (orderData.length === 0) { - log.info({}, "There are no new orders or incoming to be updated"); + log.debug({}, "There are no new orders or incoming to be updated"); return; } diff --git a/app/src/pkg/db/schema/prodPermission.ts b/app/src/pkg/db/schema/prodPermission.ts new file mode 100644 index 0000000..56d0a8f --- /dev/null +++ b/app/src/pkg/db/schema/prodPermission.ts @@ -0,0 +1,27 @@ +import { + jsonb, + pgTable, + text, + timestamp, + uniqueIndex, + uuid, +} from "drizzle-orm/pg-core"; + +export const prodPermissions = pgTable( + "prodPermissions", + { + prodPerm_id: uuid("prodPerm_id").defaultRandom().primaryKey(), + name: text("name").notNull(), + description: text("description").notNull(), + roles: jsonb("roles").default([]), + rolesLegacy: jsonb("rolesLegacy").default([]), + add_User: text("add_User").default("LST_System").notNull(), + add_Date: timestamp("add_Date").defaultNow(), + upd_user: text("upd_User").default("LST_System").notNull(), + upd_date: timestamp("upd_date").defaultNow(), + }, + (table) => [ + // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`), + uniqueIndex("prodPermName").on(table.name), + ], +); diff --git a/app/src/pkg/middleware/authMiddleware.ts b/app/src/pkg/middleware/authMiddleware.ts index bf858e3..e417cef 100644 --- a/app/src/pkg/middleware/authMiddleware.ts +++ b/app/src/pkg/middleware/authMiddleware.ts @@ -1,90 +1,92 @@ -import type { Request, Response, NextFunction } from "express"; -import { auth } from "../auth/auth.js"; -import { userRoles, type UserRole } from "../db/schema/user_roles.js"; -import { db } from "../db/db.js"; import { eq } from "drizzle-orm"; +import type { NextFunction, Request, Response } from "express"; +import { auth } from "../auth/auth.js"; +import { db } from "../db/db.js"; +import { type UserRole, userRoles } from "../db/schema/user_roles.js"; declare global { - namespace Express { - interface Request { - user?: { - id: string; - email?: string; - roles: Record; - }; - } - } + namespace Express { + interface Request { + user?: { + id: string; + email?: string; + roles: Record; + username?: string | null; + }; + } + } } function toWebHeaders(nodeHeaders: Request["headers"]): Headers { - const h = new Headers(); - for (const [key, value] of Object.entries(nodeHeaders)) { - if (Array.isArray(value)) { - value.forEach((v) => h.append(key, v)); - } else if (value !== undefined) { - h.set(key, value); - } - } - return h; + const h = new Headers(); + for (const [key, value] of Object.entries(nodeHeaders)) { + if (Array.isArray(value)) { + value.forEach((v) => h.append(key, v)); + } else if (value !== undefined) { + h.set(key, value); + } + } + return h; } export const requireAuth = (moduleName?: string, requiredRoles?: string[]) => { - return async (req: Request, res: Response, next: NextFunction) => { - try { - const headers = toWebHeaders(req.headers); + return async (req: Request, res: Response, next: NextFunction) => { + try { + const headers = toWebHeaders(req.headers); - // Get session - const session = await auth.api.getSession({ - headers, - query: { disableCookieCache: true }, - }); + // Get session + const session = await auth.api.getSession({ + headers, + query: { disableCookieCache: true }, + }); - if (!session) { - return res.status(401).json({ error: "No active session" }); - } + if (!session) { + return res.status(401).json({ error: "No active session" }); + } - const userId = session.user.id; + const userId = session.user.id; - // Get roles - const roles = await db - .select() - .from(userRoles) - .where(eq(userRoles.userId, userId)); + // Get roles + const roles = await db + .select() + .from(userRoles) + .where(eq(userRoles.userId, userId)); - // Organize roles by module - const rolesByModule: Record = {}; - for (const r of roles) { - if (!rolesByModule[r.module]) rolesByModule[r.module] = []; - rolesByModule[r.module].push(r.role); - } + // Organize roles by module + const rolesByModule: Record = {}; + for (const r of roles) { + if (!rolesByModule[r.module]) rolesByModule[r.module] = []; + rolesByModule[r.module].push(r.role); + } - req.user = { - id: userId, - email: session.user.email, - roles: rolesByModule, - }; + req.user = { + id: userId, + email: session.user.email, + roles: rolesByModule, + username: session.user.username, + }; - // SystemAdmin override - const hasSystemAdmin = Object.values(rolesByModule) - .flat() - .includes("systemAdmin"); + // SystemAdmin override + const hasSystemAdmin = Object.values(rolesByModule) + .flat() + .includes("systemAdmin"); - // Role check (skip if systemAdmin) - if (requiredRoles?.length && !hasSystemAdmin) { - const moduleRoles = moduleName - ? rolesByModule[moduleName] ?? [] - : Object.values(rolesByModule).flat(); - const hasAccess = moduleRoles.some((role) => - requiredRoles.includes(role) - ); - if (!hasAccess) { - return res.status(403).json({ error: "Forbidden" }); - } - } + // Role check (skip if systemAdmin) + if (requiredRoles?.length && !hasSystemAdmin) { + const moduleRoles = moduleName + ? (rolesByModule[moduleName] ?? []) + : Object.values(rolesByModule).flat(); + const hasAccess = moduleRoles.some((role) => + requiredRoles.includes(role), + ); + if (!hasAccess) { + return res.status(403).json({ error: "Forbidden" }); + } + } - next(); - } catch (err) { - console.error("Auth middleware error:", err); - res.status(500).json({ error: "Auth check failed" }); - } - }; + next(); + } catch (err) { + console.error("Auth middleware error:", err); + res.status(500).json({ error: "Auth check failed" }); + } + }; }; diff --git a/frontend/src/components/ui/scroll-area.tsx b/frontend/src/components/ui/scroll-area.tsx index 9376f59..abeddd7 100644 --- a/frontend/src/components/ui/scroll-area.tsx +++ b/frontend/src/components/ui/scroll-area.tsx @@ -1,56 +1,55 @@ -import * as React from "react" -import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" - -import { cn } from "@/lib/utils" +import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"; +import * as React from "react"; +import { cn } from "../../lib/utils"; function ScrollArea({ - className, - children, - ...props + className, + children, + ...props }: React.ComponentProps) { - return ( - - - {children} - - - - - ) + return ( + + + {children} + + + + + ); } function ScrollBar({ - className, - orientation = "vertical", - ...props + className, + orientation = "vertical", + ...props }: React.ComponentProps) { - return ( - - - - ) + return ( + + + + ); } -export { ScrollArea, ScrollBar } +export { ScrollArea, ScrollBar }; diff --git a/frontend/src/components/ui/table.tsx b/frontend/src/components/ui/table.tsx index 5513a5c..ff102fc 100644 --- a/frontend/src/components/ui/table.tsx +++ b/frontend/src/components/ui/table.tsx @@ -1,114 +1,113 @@ -import * as React from "react" - -import { cn } from "@/lib/utils" +import * as React from "react"; +import { cn } from "../../lib/utils"; function Table({ className, ...props }: React.ComponentProps<"table">) { - return ( -
- - - ) + return ( +
+
+ + ); } function TableHeader({ className, ...props }: React.ComponentProps<"thead">) { - return ( - - ) + return ( + + ); } function TableBody({ className, ...props }: React.ComponentProps<"tbody">) { - return ( - - ) + return ( + + ); } function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { - return ( - tr]:last:border-b-0", - className - )} - {...props} - /> - ) + return ( + tr]:last:border-b-0", + className, + )} + {...props} + /> + ); } function TableRow({ className, ...props }: React.ComponentProps<"tr">) { - return ( - - ) + return ( + + ); } function TableHead({ className, ...props }: React.ComponentProps<"th">) { - return ( -
[role=checkbox]]:translate-y-[2px]", - className - )} - {...props} - /> - ) + return ( + [role=checkbox]]:translate-y-[2px]", + className, + )} + {...props} + /> + ); } function TableCell({ className, ...props }: React.ComponentProps<"td">) { - return ( - [role=checkbox]]:translate-y-[2px]", - className - )} - {...props} - /> - ) + return ( + [role=checkbox]]:translate-y-[2px]", + className, + )} + {...props} + /> + ); } function TableCaption({ - className, - ...props + className, + ...props }: React.ComponentProps<"caption">) { - return ( -
- ) + return ( + + ); } export { - Table, - TableHeader, - TableBody, - TableFooter, - TableHead, - TableRow, - TableCell, - TableCaption, -} + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +}; diff --git a/frontend/src/routes/(logistics)/-components/Shipments.tsx b/frontend/src/routes/(logistics)/-components/Shipments.tsx index db108a0..0d1f201 100644 --- a/frontend/src/routes/(logistics)/-components/Shipments.tsx +++ b/frontend/src/routes/(logistics)/-components/Shipments.tsx @@ -10,7 +10,7 @@ interface ShipmentItemProps { export function ShipmentItem({ shipment, index = 0, - perm = true, + //perm = true, }: ShipmentItemProps) { const { setNodeRef, listeners, attributes, transform } = useDraggable({ id: shipment.orderNumber, diff --git a/frontend/src/routes/(logistics)/logistics/deliverySchedule.tsx b/frontend/src/routes/(logistics)/logistics/deliverySchedule.tsx index a54e5ef..530a81e 100644 --- a/frontend/src/routes/(logistics)/logistics/deliverySchedule.tsx +++ b/frontend/src/routes/(logistics)/logistics/deliverySchedule.tsx @@ -1,9 +1,7 @@ import { createFileRoute } from "@tanstack/react-router"; -import { useEffect, useState } from "react"; + import { coreSocket } from "../../../lib/socket.io/socket"; import "../-components/style.css"; -import moment from "moment"; -import Timeline from "react-calendar-timeline"; export const Route = createFileRoute("/(logistics)/logistics/deliverySchedule")( { @@ -19,9 +17,9 @@ export const Route = createFileRoute("/(logistics)/logistics/deliverySchedule")( function RouteComponent() { // connect to the channel - const [shipments, setShipments] = useState([]) as any; + //const [shipments, setShipments] = useState([]) as any; //const [perm] = useState(true); // will check this for sure with a user permissions - const [loaded, setLoaded] = useState(false); + //const [loaded, setLoaded] = useState(false); // useEffect(() => { // const handleConnect = () => { diff --git a/frontend/src/routes/__root.tsx b/frontend/src/routes/__root.tsx index ae66781..101b728 100644 --- a/frontend/src/routes/__root.tsx +++ b/frontend/src/routes/__root.tsx @@ -11,7 +11,7 @@ import { useEffect } from "react"; import { Toaster } from "sonner"; import Nav from "../components/navBar/Nav"; import SideBarNav from "../components/navBar/SideBarNav"; -import { SidebarProvider, SidebarTrigger } from "../components/ui/sidebar"; +import { SidebarProvider } from "../components/ui/sidebar"; import { userAccess } from "../lib/authClient"; import { SessionGuard } from "../lib/providers/SessionProvider"; import { ThemeProvider } from "../lib/providers/theme-provider"; diff --git a/frontend/src/routes/_adminLayout/admin/_users/users.tsx b/frontend/src/routes/_adminLayout/admin/_users/users.tsx index c3e9a5e..d9fc9c4 100644 --- a/frontend/src/routes/_adminLayout/admin/_users/users.tsx +++ b/frontend/src/routes/_adminLayout/admin/_users/users.tsx @@ -91,6 +91,10 @@ function RouteComponent() { ); }, }), + // password reset will do the email flow + // change password an input for this one so well need inline editing for this dope one + // trash can to delete user + // last login -- need to get working on the server side as well. columnHelper.accessor("roles", { header: () => Roles, cell: ({ row }) => {