Compare commits

..

12 Commits

23 changed files with 2908 additions and 113 deletions

View File

@@ -0,0 +1,13 @@
CREATE TABLE "prodPermissions" (
"prodPerm_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text NOT NULL,
"description" text NOT NULL,
"roles" jsonb DEFAULT '[]'::jsonb,
"rolesLegacy" jsonb DEFAULT '[]'::jsonb,
"add_User" text DEFAULT 'LST_System' NOT NULL,
"add_Date" timestamp DEFAULT now(),
"upd_User" text DEFAULT 'LST_System' NOT NULL,
"upd_date" timestamp DEFAULT now()
);
--> statement-breakpoint
CREATE UNIQUE INDEX "prodPermName" ON "prodPermissions" USING btree ("name");

File diff suppressed because it is too large Load Diff

View File

@@ -456,6 +456,13 @@
"when": 1748464203006, "when": 1748464203006,
"tag": "0064_aberrant_blindfold", "tag": "0064_aberrant_blindfold",
"breakpoints": true "breakpoints": true
},
{
"idx": 65,
"version": "7",
"when": 1749492130639,
"tag": "0065_nappy_talos",
"breakpoints": true
} }
] ]
} }

View File

@@ -0,0 +1,38 @@
import {
text,
pgTable,
timestamp,
uuid,
uniqueIndex,
jsonb,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
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),
]
);
// Schema for inserting a user - can be used to validate API requests
// export const insertUsersSchema = createInsertSchema(prodPermissions, {
// name: z
// .string()
// .min(3, { message: "Role name must be longer than 3 characters" }),
// });
// Schema for selecting a Expenses - can be used to validate API responses
export const selectUsersSchema = createSelectSchema(prodPermissions);

View File

@@ -1,19 +1,72 @@
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip"; import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import axios from "axios";
import { RotateCcw } from "lucide-react"; import { RotateCcw } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
export default function RestartServer(data: any) {
const token = localStorage.getItem("auth_token");
const [disable, setDisable] = useState(false);
const handleRestartServer = async (plant: string) => {
toast.success(`${plant} is being restarted please wait.`);
setDisable(true);
let data: any = {
processType: "restart",
plantToken: plant,
};
const url: string = window.location.host.split(":")[0];
if (url === "localhost" || url === "usmcd1vms036") {
data = { ...data, remote: "true" };
}
//console.log(data);
try {
const res = await axios.post("/api/server/serviceprocess", data, {
headers: { Authorization: `Bearer ${token}` },
});
//console.log(res);
if (res.status === 200) {
setTimeout(() => {
toast.success(`${plant} Has beed restarted.`);
setDisable(false);
}, 3000);
}
} catch (error) {
console.log(error);
}
};
export default function RestartServer() {
return ( return (
<div> <div>
<TooltipProvider> <TooltipProvider>
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<Button variant={"outline"} size={"icon"}> <Button
variant={"outline"}
size={"icon"}
disabled={disable}
onClick={() =>
handleRestartServer(data.plantData.plantToken)
}
>
<RotateCcw /> <RotateCcw />
</Button> </Button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>
<p>Restart Server ... Needs added still</p> <p>
Restart Server, note you might see the screen error
out for a second
</p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>

View File

@@ -171,11 +171,17 @@ export default function ServerPage() {
server={server} server={server}
token={token as string} token={token as string}
/> />
<StartServer />
<StartServer
plantData={server}
/>
<StopServer <StopServer
plantData={server} plantData={server}
/> />
<RestartServer />
<RestartServer
plantData={server}
/>
</div> </div>
)} )}
</TableCell> </TableCell>

View File

@@ -1,19 +1,71 @@
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip"; import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import axios from "axios";
import { Play } from "lucide-react"; import { Play } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
export default function StartServer() { export default function StartServer(data: any) {
const token = localStorage.getItem("auth_token");
const [disable, setDisable] = useState(false);
const handleStartServer = async (plant: string) => {
toast.success(`${plant} is being started please wait.`);
setDisable(true);
let data: any = {
processType: "start",
plantToken: plant,
};
const url: string = window.location.host.split(":")[0];
if (url === "localhost" || url === "usmcd1vms036") {
data = { ...data, remote: "true" };
}
//console.log(data);
try {
const res = await axios.post("/api/server/serviceprocess", data, {
headers: { Authorization: `Bearer ${token}` },
});
//console.log(res);
if (res.status === 200) {
setTimeout(() => {
toast.success(`${plant} Has beed started.`);
setDisable(false);
}, 3000);
}
} catch (error: any) {
if (error.status === 429) {
toast.error(error.response.data.message);
setDisable(false);
}
}
};
return ( return (
<div> <div>
<TooltipProvider> <TooltipProvider>
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<Button variant={"outline"} size={"icon"}> <Button
variant={"outline"}
size={"icon"}
disabled={disable}
onClick={() =>
handleStartServer(data.plantData.plantToken)
}
>
<Play /> <Play />
</Button> </Button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>
<p>Start Server ... Needs added still</p> <p>Start Server</p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>

View File

@@ -7,24 +7,40 @@ import {
} from "@/components/ui/tooltip"; } from "@/components/ui/tooltip";
import axios from "axios"; import axios from "axios";
import { Octagon } from "lucide-react"; import { Octagon } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
export default function StopServer(plantData: any) { export default function StopServer(data: any) {
const token = localStorage.getItem("auth_token"); const token = localStorage.getItem("auth_token");
const [disable, setDisable] = useState(false);
const handleStopServer = async (plant: string) => { const handleStopServer = async (plant: string) => {
toast.success(`${plant} is being stopped please wait.`);
setDisable(true);
let data: any = { let data: any = {
processType: "stop", processType: "stop",
plantToken: plant, plantToken: plant,
}; };
const url: string = window.location.host.split(":")[0]; const url: string = window.location.host.split(":")[0];
if (url === "localhost") { if (url === "localhost" || url === "usmcd1vms036") {
data = { ...data, remote: "true" }; data = { ...data, remote: "true" };
} }
//console.log(data);
try { try {
const res = await axios.post("/api/server/serviceprocess", data, { const res = await axios.post("/api/server/serviceprocess", data, {
headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
}); });
console.log(res); //console.log(res);
if (res.status === 200) {
setTimeout(() => {
toast.success(`${plant} Has beed stopped.`);
setDisable(false);
}, 3000);
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@@ -37,15 +53,16 @@ export default function StopServer(plantData: any) {
<Button <Button
variant="destructive" variant="destructive"
size={"icon"} size={"icon"}
disabled={disable}
onClick={() => onClick={() =>
handleStopServer(plantData.plantToken) handleStopServer(data.plantData.plantToken)
} }
> >
<Octagon /> <Octagon />
</Button> </Button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent> <TooltipContent>
<p>Stop Server ... Needs added still</p> <p>Stop Server</p>
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>

View File

@@ -35,7 +35,7 @@
} }
}, },
"admConfig": { "admConfig": {
"build": 369, "build": 377,
"oldBuild": "backend-0.1.3.zip" "oldBuild": "backend-0.1.3.zip"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -0,0 +1,77 @@
import { Hono } from "hono";
import { type Context, type Next } from "hono";
const app = new Hono();
// --- In-Memory Store for Rate Limits ---
// This Map will store when each user/key last accessed a rate-limited endpoint.
// Key: string (e.g., 'ip_address' or 'user_id_endpoint')
// Value: number (timestamp of last access in milliseconds)
const rateLimitStore = new Map<string, number>();
// --- Configuration ---
const FIFTEEN_MINUTES_MS = 5 * 60 * 1000; // 15 minutes in milliseconds
// --- Rate Limiting Middleware ---
export const simpleRateLimit = async (c: Context, next: Next) => {
// 1. Define a unique key for the rate limit
// For simplicity, we'll use a placeholder for user identification.
// In a real app:
// - If unauthenticated: Use c.req.header('x-forwarded-for') or c.req.ip (if configured/available)
// - If authenticated: Get user ID from c.req.user or similar after authentication middleware
const userIdentifier = c.req.header("x-forwarded-for") || "anonymous_user"; // Basic IP-like identifier
// You can also make the key specific to the route to have different limits per route
const routeKey = `${userIdentifier}:${c.req.path}`;
const now = Date.now();
const lastAccessTime = rateLimitStore.get(routeKey);
if (lastAccessTime) {
const timeElapsed = now - lastAccessTime;
if (timeElapsed < FIFTEEN_MINUTES_MS) {
// Limit exceeded
const timeRemainingMs = FIFTEEN_MINUTES_MS - timeElapsed;
const timeRemainingSeconds = Math.ceil(timeRemainingMs / 1000);
c.status(429); // HTTP 429: Too Many Requests
return c.json({
error: "Too Many Requests",
message: `Please wait ${timeRemainingSeconds} seconds before trying again.`,
retryAfter: timeRemainingSeconds, // Standard header for rate limiting clients
});
}
}
// If no previous access, or the 15 minutes have passed, allow the request
// and update the last access time.
rateLimitStore.set(routeKey, now);
// Continue to the next middleware or route handler
await next();
};
// --- Apply the Middleware to Specific Routes ---
app.get("/", (c) => {
return c.text("Welcome! This is a public endpoint.");
});
// This endpoint will be rate-limited
app.get("/privileged", simpleRateLimit, (c) => {
return c.text("You successfully accessed the privileged endpoint!");
});
// Another rate-limited endpoint
app.post("/submit-data", simpleRateLimit, async (c) => {
// In a real app, you'd process form data or JSON here
return c.text("Data submitted successfully (rate-limited).");
});
// Example of an endpoint that is NOT rate-limited
app.get("/health", (c) => {
return c.text("Server is healthy!");
});
export default app;

View File

@@ -28,6 +28,7 @@ import notify from "./services/notifications/notifyService.js";
import eom from "./services/eom/eomService.js"; import eom from "./services/eom/eomService.js";
import dataMart from "./services/dataMart/dataMartService.js"; import dataMart from "./services/dataMart/dataMartService.js";
import qualityRequest from "./services/quality/qualityService.js"; import qualityRequest from "./services/quality/qualityService.js";
import produser from "./services/prodUser/prodUser.js";
// create the main prodlogin here // create the main prodlogin here
const username = "lst_user"; const username = "lst_user";
@@ -106,6 +107,7 @@ const routes = [
eom, eom,
dataMart, dataMart,
qualityRequest, qualityRequest,
produser,
] as const; ] as const;
const appRoutes = routes.forEach((route) => { const appRoutes = routes.forEach((route) => {

View File

@@ -4,7 +4,10 @@ param (
[string]$appPath, [string]$appPath,
[string]$command, # just the command like run start or what ever you have in npm. [string]$command, # just the command like run start or what ever you have in npm.
[string]$description, [string]$description,
[string]$remote [string]$remote,
[string]$server,
[string]$username,
[string]$admpass
) )
# Example string to run with the parameters in it. # Example string to run with the parameters in it.
@@ -15,16 +18,79 @@ param (
$nssmPath = $AppPath + "\nssm.exe" $nssmPath = $AppPath + "\nssm.exe"
$npmPath = "C:\Program Files\nodejs\npm.cmd" # Path to npm.cmd $npmPath = "C:\Program Files\nodejs\npm.cmd" # Path to npm.cmd
# Convert the plain-text password to a SecureString
$securePass = ConvertTo-SecureString $admpass -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential($username, $securePass)
if($remote -eq "true"){ if($remote -eq "true"){
# if(-not $username -or -not $admpass){
# Write-host "Missing adm account info please try again."
# exit 1
# }
$plantFunness = { $plantFunness = {
param ($service, $processType, $location) param ($service, $processType, $location)
# Call your PowerShell script inside plantFunness # Call your PowerShell script inside plantFunness
& "$($location)\dist\server\scripts\services.ps1" -serviceName $service -option $processType -appPath $location # & "$($location)\dist\server\scripts\services.ps1" -serviceName $service -option $processType -appPath $location
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "Error: This script must be run as Administrator."
exit 1
} }
Invoke-Command -ComputerName $server -ScriptBlock $plantFunness -ArgumentList $service, $option, $appPath -Credential $credentials if(-not $service -or -not $processType){
Write-host "The service name or option is missing please enter one of them and try again."
exit 1
} }
if ($processType -eq "start"){
write-host "Starting $($service)."
Start-Service $service
}
if ($processType -eq "stop"){
write-host "Stoping $($service)."
Stop-Service $service
}
if ($processType -eq "restart"){
write-host "Stoping $($service) to be restarted"
Stop-Service $service
Start-Sleep 3 # so we give it enough time to fully stop
write-host "Starting $($service)"
Start-Service $service
}
if ($processType -eq "prodStop"){
if(-not $location){
Write-host "The path to the app is missing please add it in and try again."
exit 1
}
& $nssmPath stop $service
write-host "Removing $($service)"
#& $nssmPath remove $serviceName confirm
sc.exe config $service start= disabled
}
if ($processType -eq "prodStart"){
if(-not $location){
Write-host "The path to the app is missing please add it in and try again."
exit 1
}
& $nssmPath start $service
write-host "Removing $($service)"
#& $nssmPath remove $serviceName confirm
sc.exe config $service start= auto
}
}
Invoke-Command -ComputerName $server -ScriptBlock $plantFunness -ArgumentList $serviceName, $option, $appPath -Credential $credentials
} else {
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "Error: This script must be run as Administrator." Write-Host "Error: This script must be run as Administrator."
exit 1 exit 1
@@ -119,4 +185,7 @@ if($option -eq "install"){
& $nssmPath start $serviceName & $nssmPath start $serviceName
} }
} }
}

View File

@@ -58,7 +58,7 @@ export const updatePrinters = async () => {
port: prodPrinterInfo[i].port, port: prodPrinterInfo[i].port,
remark: prodPrinterInfo[i].remark, remark: prodPrinterInfo[i].remark,
upd_date: sql`NOW()`, upd_date: sql`NOW()`,
printDelay: "90", // need to remove in a couple weeks //printDelay: "90", // need to remove in a couple weeks
}, },
}) })
); );

View File

@@ -0,0 +1 @@
export const addProdRole = async (data: any) => {};

View File

@@ -0,0 +1,150 @@
import axios from "axios";
import { db } from "../../../../database/dbclient.js";
import { prodPermissions } from "../../../../database/schema/prodPermissions.js";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
import { query } from "../../sqlServer/prodSqlServer.js";
import { userCheck } from "../../sqlServer/querys/prodUser/usercheck.js";
import { prodEndpointCreation } from "../../../globalUtils/createUrl.js";
export const prodUser = async (data: any) => {
// get the prodPermissions so we can make sure we have one in here
const { data: prodPerm, error: pe } = await tryCatch(
db.select().from(prodPermissions)
);
// create url
const grantUrl = await prodEndpointCreation(
`/public/v1.0/Administration/User/${data.username}/Grant`
);
const newurl = await prodEndpointCreation(
`/public/v1.0/Administration/User`
);
const revoke = await prodEndpointCreation(
`/public/v1.0/Administration/User/${data.username}/Revoke`
);
if (pe) {
console.log(pe);
return {
succes: false,
message: "There was an error getting the base prod permissions",
data: pe,
};
}
// check if we sent over a valid permissions fole over
const permRoleCheck = prodPerm.filter((n: any) => n.name === data.role);
if (permRoleCheck.length === 0) {
return {
succes: false,
message: `Role: ${data.role}, dose note exist please check the role you have selected and try again.`,
data: [],
};
}
// dose this user already exist?
const quc = userCheck.replace("[userName]", data.username);
const { data: usercheck, error: userError } = (await tryCatch(
query(quc, "Checks for existing user")
)) as any;
if (userError) {
console.log(userError);
}
if (usercheck?.data.length === 0) {
// create the user
const newUser: any = {
userId: data.username,
remark: data.remark,
languageCode: "en",
active: true,
roles: permRoleCheck[0].roles,
rolesLegacy: permRoleCheck[0].rolesLegacy,
};
const { data: newU, error: newE } = await tryCatch(
axios.post(newurl, newUser, {
headers: {
Authorization: `Basic ${btoa(
`matthes01:99Monsters200Scary!`
)}`,
"Content-Type": "application/json",
},
})
);
if (newE) {
console.log(newE);
}
return {
succes: true,
message: `${data.username} was just created or updated.`,
data: [],
};
} else {
// revoke and readd
const revokePerms: any = {
roles:
JSON.parse(usercheck.data[0].roles.replaceAll("\\", "\\\\")) ||
[],
rolesLegacy: JSON.parse(usercheck.data[0].legacyRoles) || [],
};
const { data: newU, error: newE } = (await tryCatch(
axios.patch(revoke, revokePerms, {
headers: {
Authorization: `Basic ${btoa(
`matthes01:99Monsters200Scary!`
)}`,
"Content-Type": "application/json",
},
})
)) as any;
if (newE) {
console.log(newE.response.data);
return {
succes: false,
message: `${data.username} encountered an error updating..`,
data: newE.response.data,
};
}
// add the new roles to the user.
const grantRole: any = {
roles: permRoleCheck[0].roles,
rolesLegacy: permRoleCheck[0].rolesLegacy,
};
const { data: grant, error: grante } = (await tryCatch(
axios.patch(grantUrl, grantRole, {
headers: {
Authorization: `Basic ${btoa(
`matthes01:99Monsters200Scary!`
)}`,
"Content-Type": "application/json",
},
})
)) as any;
if (grante) {
console.log(newE.response.data);
return {
succes: false,
message: `${data.username} encountered an error updating..`,
data: newE.response.data,
};
}
}
return {
succes: true,
message: `${data.username} was just created or updated.`,
data: [],
};
};

View File

@@ -0,0 +1,23 @@
import { OpenAPIHono } from "@hono/zod-openapi";
import produser from "./routes/produser.js";
import createProdRole from "./routes/addProdRole.js";
import { prodRoles } from "./utils/prodRoles.js";
const app = new OpenAPIHono();
const routes = [produser, createProdRole] as const;
const appRoutes = routes.forEach((route) => {
app.route("/produser", route);
});
app.all("/produser/*", (c) => {
return c.json({
success: false,
message: "You have encounters a prodUser route that dose not exist.",
});
});
setTimeout(() => {
prodRoles();
}, 2000);
export default app;

View File

@@ -0,0 +1,43 @@
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../globalUtils/routeDefs/responses.js";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
import { apiHit } from "../../../globalUtils/apiHits.js";
import { prodUser } from "../controller/produser.js";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["admin"],
summary: "Creates a new prod role",
method: "post",
path: "/prodrole",
responses: responses(),
}),
async (c) => {
const { data: body, error: be } = await tryCatch(c.req.json());
if (be) {
return c.json({
success: false,
message: "Missing data.",
});
}
const { data, error } = await tryCatch(prodUser(body));
apiHit(c, { endpoint: "/prodrole" });
if (error) {
return c.json({
success: false,
message: "Error creating new role.",
});
}
return c.json({
success: data.succes,
message: data.message,
data: data.data,
});
}
);
export default app;

View File

@@ -0,0 +1,45 @@
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../globalUtils/routeDefs/responses.js";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
import { apiHit } from "../../../globalUtils/apiHits.js";
import { prodUser } from "../controller/produser.js";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["admin"],
summary:
"Runs a full crud on the user plus added icons if pc name provided and is online",
method: "post",
path: "/produser",
responses: responses(),
}),
async (c) => {
const { data: body, error: be } = await tryCatch(c.req.json());
if (be) {
return c.json({
success: false,
message: "Missing data.",
});
}
const { data, error } = await tryCatch(prodUser(body));
apiHit(c, { endpoint: "/newuser" });
if (error) {
console.log(error);
return c.json({
success: false,
message: "Error processing create user.",
});
}
return c.json({
success: data.succes,
message: data.message,
data: data.data,
});
}
);
export default app;

View File

@@ -0,0 +1,53 @@
/**
* check if the modules are in and if not add them.
* this will only run on a server start up
*/
import { sql } from "drizzle-orm";
import { db } from "../../../../database/dbclient.js";
import { prodPermissions } from "../../../../database/schema/prodPermissions.js";
import { createLog } from "../../logger/logger.js";
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
const newProdRoles: any = [
{
name: "planning",
description: "Planning viewer only",
roles: ["OperationsPlanning\\ProductionScheduling\\ProductionViewer"],
rolesLegacy: [3],
},
];
export const prodRoles = async () => {
// get the roles
for (let i = 0; i < newProdRoles.length; i++) {
try {
const newRole = await db
.insert(prodPermissions)
.values(newProdRoles[i])
.onConflictDoUpdate({
target: prodPermissions.name,
set: {
name: newProdRoles[i].name,
description: newProdRoles[i].description,
roles: newProdRoles[i].roles,
rolesLegacy: newProdRoles[i].rolesLegacy,
upd_date: sql`NOW()`,
},
}) // this will only update the ones that are new :D
.returning({ name: prodPermissions.name });
} catch (error) {
console.log(error);
createLog(
"error",
"lst",
"server",
"There was an error adding new modules to the db"
);
}
}
createLog(
"info",
"lst",
"server",
"Modules were just added due to missing them on server startup"
);
};

View File

@@ -2,7 +2,6 @@ import { spawn } from "child_process";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { tryCatch } from "../../../../globalUtils/tryCatch.js"; import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { db } from "../../../../../database/dbclient.js"; import { db } from "../../../../../database/dbclient.js";
import { settings } from "../../../../../database/schema/settings.js";
import { createLog } from "../../../logger/logger.js"; import { createLog } from "../../../logger/logger.js";
import { serverData } from "../../../../../database/schema/serverData.js"; import { serverData } from "../../../../../database/schema/serverData.js";
import os from "os"; import os from "os";
@@ -33,6 +32,12 @@ export const serviceControl = async (
scriptPath = `${process.env.DEVFOLDER}\\dist\\server\\scripts\\services.ps1`; scriptPath = `${process.env.DEVFOLDER}\\dist\\server\\scripts\\services.ps1`;
} }
console.log(serverInfo[0].serverDNS);
const username = process.env.ADMUSER as string;
const password = process.env.ADMPASSWORD as string;
console.log(username, password);
const args = [ const args = [
"-NoProfile", "-NoProfile",
"-ExecutionPolicy", "-ExecutionPolicy",
@@ -47,6 +52,12 @@ export const serviceControl = async (
serverInfo[0].serverLoc as string, serverInfo[0].serverLoc as string,
"-remote", "-remote",
remote ?? "", remote ?? "",
"-server",
serverInfo[0].serverDNS as string,
"-username",
username,
"-admpass",
password,
]; ];
const scriptProcess = spawn("powershell", args); const scriptProcess = spawn("powershell", args);

View File

@@ -5,6 +5,7 @@ import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import hasCorrectRole from "../../../auth/middleware/roleCheck.js"; import hasCorrectRole from "../../../auth/middleware/roleCheck.js";
import { serviceControl } from "../../controller/server/serviceControl.js"; import { serviceControl } from "../../controller/server/serviceControl.js";
import { apiHit } from "../../../../globalUtils/apiHits.js"; import { apiHit } from "../../../../globalUtils/apiHits.js";
import { simpleRateLimit } from "../../../../globalUtils/rateLimiter.js";
// Define the request body schema // Define the request body schema
const requestSchema = z.object({ const requestSchema = z.object({
@@ -21,7 +22,11 @@ app.openapi(
summary: "Starts, Stops, Restarts the server.", summary: "Starts, Stops, Restarts the server.",
method: "post", method: "post",
path: "/serviceprocess", path: "/serviceprocess",
middleware: [authMiddleware, hasCorrectRole(["systemAdmin"], "admin")], middleware: [
authMiddleware,
hasCorrectRole(["systemAdmin"], "admin"),
simpleRateLimit,
],
request: { request: {
body: { body: {
@@ -34,7 +39,7 @@ app.openapi(
}), }),
async (c) => { async (c) => {
const { data, error } = await tryCatch(c.req.json()); const { data, error } = await tryCatch(c.req.json());
//apiHit(c, { endpoint: `/serviceprocess`, lastBody: data }); //apiHit(c, { endpoint: "/bookin", lastBody: data });
if (error) { if (error) {
return c.json({ return c.json({
success: false, success: false,

View File

@@ -27,6 +27,6 @@ SELECT
[AlplaPROD_test1].[dbo].[T_EtikettenGedruckt] l on [AlplaPROD_test1].[dbo].[T_EtikettenGedruckt] l on
x.LfdNrJeArtikelKunde = l.LfdNr x.LfdNrJeArtikelKunde = l.LfdNr
where x.Add_Date between dateadd(hour, -1, getDate()) and getDate() where x.Add_Date between dateadd(hour, -1, getDate()) and getDate() -- this is looking only in the last hour
order by [ProduktionsDatum] order by [ProduktionsDatum]
`; `;

View File

@@ -0,0 +1,17 @@
export const userCheck = `
SELECT *,
'[' + STUFF((
SELECT ',' + '"' + REPLACE(REPLACE(ur.name, '\', '\\'), '"', '\"') + '"'
FROM [test1_AlplaPROD2.0_Read].[user].[Roles] (nolock) ur
WHERE ur.userid = u.id
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'
), 1, 1, '') + ']' AS roles,
'[' + STUFF((
SELECT ',' + cast(ulr.roleid as nvarchar(max))
FROM [test1_AlplaPROD2.0_Read].[user].[LegacyRoles] (nolock) ulr
WHERE ulr.userid = u.id
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'
), 1, 1, '') + ']' AS legacyRoles
FROM [test1_AlplaPROD2.0_Read].[user].[User] (nolock) u
where Loginname = '[userName]'
`;