fix(contorller): env corrections on where to look for the file when running

This commit is contained in:
2025-09-30 19:54:10 -05:00
parent 18e57127e2
commit b84ecbf30c
26 changed files with 2637 additions and 27 deletions

View File

@@ -4,6 +4,8 @@ import { requireAuth } from "../../pkg/middleware/authMiddleware.js";
//admin routes
import users from "./routes/getUserRoles.js";
import grantRoles from "./routes/grantRole.js";
import servers from "./routes/servers/serverRoutes.js";
import { restrictToHosts } from "../../pkg/middleware/restrictToHosts.js";
export const setupAdminRoutes = (app: Express, basePath: string) => {
app.use(
@@ -16,4 +18,11 @@ export const setupAdminRoutes = (app: Express, basePath: string) => {
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
grantRoles
);
app.use(
basePath + "/api/admin/server",
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
restrictToHosts(["usmcd1vms036", "USMCD1VMS036"]), // what servers are allowed to see the server section
servers
);
};

View File

@@ -0,0 +1,74 @@
import { Router } from "express";
import type { Request, Response } from "express";
import {
insertServerDataSchema,
serverData,
} from "../../../../pkg/db/schema/servers.js";
import { db } from "../../../../pkg/db/db.js";
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
import type { DrizzleError } from "drizzle-orm";
import axios from "axios";
import { createLogger } from "../../../../pkg/logger/logger.js";
const router = Router();
router.post("/", async (req: Request, res: Response) => {
// when a new server is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there
//res.status(200).json({ message: "Server added", ip: req.hostname });
const log = createLogger({ module: "admin", subModule: "add server" });
const parsed = insertServerDataSchema.safeParse(req.body);
if (!parsed.success) {
return res.status(400).json({ errors: parsed.error.flatten() });
}
const { data, error } = await tryCatch(
db
.insert(serverData)
.values(parsed.data)
//.onConflictDoNothing()
.returning({
name: serverData.name,
plantToken: serverData.plantToken,
})
);
if (error) {
const err: DrizzleError = error;
return res.status(400).json({
message: `Error adding the server`,
error: err.cause,
});
}
if (req.hostname === "localhost" && process.env.MAIN_SERVER) {
log.info({}, "Running in dev server about to add in a new server");
const { data, error } = await tryCatch(
axios.post(
`${process.env.MAIN_SERVER}/lst/api/admin/server`,
parsed.data,
{
headers: {
"Content-Type": "application/json",
Cookie: req.headers.cookie ?? "",
},
withCredentials: true,
}
)
);
if (error) {
log.error(
{ stack: error },
"There was an error adding the server to Main Server"
);
}
log.info({ stack: data }, "A new Server was just added to the server.");
}
return res
.status(201)
.json({ message: `Server ${data[0]?.name} added`, data: data });
});
export default router;

View File

@@ -0,0 +1,25 @@
import { Router } from "express";
import type { Request, Response } from "express";
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
import { db } from "../../../../pkg/db/db.js";
import { serverData } from "../../../../pkg/db/schema/servers.js";
import { and, asc, eq } from "drizzle-orm";
const router = Router();
router.get("/", async (req: Request, res: Response) => {
const { data, error } = await tryCatch(
db
.select()
.from(serverData)
.where(eq(serverData.active, true))
.orderBy(asc(serverData.name))
);
if (error) {
return res.status(400).json({ error: error });
}
res.status(200).json({ message: "Current Active server", data: data });
});
export default router;

View File

@@ -0,0 +1,12 @@
import { Router } from "express";
import addServer from "./addServer.js";
import getServers from "./getServers.js";
import updateServer from "./updateServer.js";
const router = Router();
router.get("/", getServers);
router.post("/", addServer);
router.patch("/", updateServer);
export default router;

View File

@@ -0,0 +1,11 @@
import { Router } from "express";
import type { Request, Response } from "express";
const router = Router();
router.patch("/", async (req: Request, res: Response) => {
// when a server is updated and is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there, we want to insert with update on conflict.
res.status(200).json({ message: "Server added" });
});
export default router;

View File

@@ -27,7 +27,9 @@ router.get("/", async (req, res) => {
uptime: process.uptime(),
build: statData[0]?.build,
pendingUpdateFile: await checkBuildUpdate(["."]),
lastUpdate: format(statData[0].lastUpdate!, "MM/dd/yyyy HH:mm"),
lastUpdate: statData[0]?.lastUpdate
? format(statData[0].lastUpdate, "MM/dd/yyyy HH:mm")
: "",
});
});

View File

@@ -0,0 +1,49 @@
import {
boolean,
integer,
pgTable,
text,
timestamp,
uniqueIndex,
uuid,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import z from "zod";
export const serverData = pgTable(
"serverData",
{
server_id: uuid("server_id").defaultRandom().primaryKey(),
name: text("name").notNull(),
serverDNS: text("serverDNS").notNull(),
plantToken: text("plantToken").notNull(),
ipAddress: text("ipAddress").notNull(),
greatPlainsPlantCode: integer("greatPlainsPlantCode").notNull(),
streetAddress: text("streetAddress"),
cityState: text("cityState"),
zipcode: integer("zipcode"),
contactEmail: text("contactEmail"),
contactPhone: text("contactPhone"),
customerTiAcc: text("customerTiAcc"),
lstServerPort: integer("lstServerPort").notNull(),
active: boolean("active").default(true),
serverLoc: text("serverLoc").notNull(),
lastUpdated: timestamp("lastUpdated").defaultNow(),
isUpgrading: boolean("isUpgrading").default(false),
},
(table) => [
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
uniqueIndex("plantToken").on(table.plantToken),
]
);
export const selectServerDataSchema = createSelectSchema(serverData);
export const insertServerDataSchema = createInsertSchema(serverData).extend({
contactEmail: z.email().optional(),
// zipcode: z
// .string()
// .regex(/^\d{5}$/)
// .optional(),
});

View File

@@ -0,0 +1,30 @@
import type { Request, Response, NextFunction } from "express";
/**
* Middleware to restrict access only to localhost or a whitelist of hosts.
*/
export function restrictToHosts(allowedHosts: string[] = []) {
return (req: Request, res: Response, next: NextFunction) => {
// `req.ip` gives the remote IP
const ip = req.ip!.replace("::ffff:", ""); // strip IPv6 prefix if present
// Express sets req.hostname from the Host header
const hostname = req.hostname;
const isLocal =
ip === "127.0.0.1" || ip === "::1" || hostname === "localhost";
const isAllowed =
isLocal ||
allowedHosts.includes(ip) ||
allowedHosts.includes(hostname);
if (!isAllowed) {
return res
.status(403)
.json({ error: "Access not allowed from this host" });
}
next();
};
}