Files
lst/lstV2/server/index.ts

303 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
import { serve } from "@hono/node-server";
import { serveStatic } from "@hono/node-server/serve-static";
import { OpenAPIHono } from "@hono/zod-openapi";
import { cors } from "hono/cors";
import { html } from "hono/html";
import { logger } from "hono/logger";
import os from "os";
import auth from "./services/auth/authService.js";
import dataMart from "./services/dataMart/dataMartService.js";
import eom from "./services/eom/eomService.js";
// custom routes
import scalar from "./services/general/route/scalar.js";
import { createLog } from "./services/logger/logger.js";
import loggerService from "./services/logger/loggerService.js";
import logistics from "./services/logistics/logisticsService.js";
import { sendEmail } from "./services/notifications/controller/sendMail.js";
import notify from "./services/notifications/notifyService.js";
import ocme from "./services/ocme/ocmeService.js";
import ocpService from "./services/ocp/ocpService.js";
import printers from "./services/printers/printerService.js";
import produser from "./services/prodUser/prodUser.js";
import qualityRequest from "./services/quality/qualityService.js";
import rfid from "./services/rfid/rfidService.js";
import {
getSettings,
serverSettings,
} from "./services/server/controller/settings/getSettings.js";
import system from "./services/server/systemServer.js";
import sqlService from "./services/sqlServer/sqlService.js";
import tcpServer from "./services/tcpServer/tcpServer.js";
// create the main prodlogin here
const username = "lst_user";
const password = "Alpla$$Prod";
export const lstAuth = btoa(`${username}:${password}`);
// checking to make sure we have the settings intialized
// const { data: settingsData, error: settingError } = await tryCatch(
// db.select().from(settings)
// );
// if (settingError) {
// throw Error("Error getting settings from the db. critical error.");
// }
const serverIntialized: any = await getSettings();
export const installed =
serverIntialized.length === 0 && process.env.NODE_ENV !== "development"
? false
: true;
createLog("info", "LST", "server", `Server is installed: ${installed}`);
const app = new OpenAPIHono({ strict: false });
// middle ware
if (process.env.NODE_ENV === "development") {
app.use("*", logger());
}
app.use(
"*",
cors({
origin: [
"http://localhost:3000",
"http://localhost:5173",
"http://localhost:4000",
"http://localhost:4200",
], // Allow all origins
allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
//exposeHeaders: ["Content-Length", "X-Kuma-Revision"],
credentials: true, // Allow credentials if needed
maxAge: 600,
}),
);
// Middleware to normalize route case
// app.use("*", async (c, next) => {
// // const lowercasedUrl = c.req.url.toLowerCase();
// console.log("Incoming Request:", c.req.url, c.req.method);
// // // If the URL is already lowercase, continue as usual
// // if (c.req.url === lowercasedUrl) {
// await next();
// // }
// // // Otherwise, re-route internally
// // return c.redirect(lowercasedUrl, 308); // 308 preserves the HTTP method
// });
app.doc("/api/ref", {
openapi: "3.0.0",
info: {
version: "2.0.0",
title: "LST API",
},
});
const routes = [
scalar,
auth,
// apiHits,
system,
tcpServer,
sqlService,
logistics,
rfid,
printers,
loggerService,
ocpService,
notify,
eom,
dataMart,
qualityRequest,
produser,
] as const;
const appRoutes = routes.forEach((route) => {
app.route("/api/", route);
});
app.route("/ocme/", ocme);
//--------------- lst v1 proxy ----------------------\\
// app.all("/api/v1/*", (c) => {
// const path = c.req.path.replace("/api/v1/", ""); // Extract the subpath
// const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params
// return proxy(`http://localhost:4900/${path}${query}`, {
// headers: {
// ...c.req.header(),
// "X-Forwarded-For": "127.0.0.1",
// "X-Forwarded-Host": c.req.header("host"),
// },
// });
// });
// app.all("/system/*", (c) => {
// const path = c.req.path.replace("/system/", ""); // Extract the subpath
// const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params
// return proxy(`http://localhost:4200/${path}${query}`, {
// headers: {
// ...c.req.header(),
// "X-Forwarded-For": "127.0.0.1",
// "X-Forwarded-Host": c.req.header("host"),
// },
// });
// });
//---------------------------------------------------\\
// the catch all api route
app.all("/api/*", (c) => c.json({ error: "API route not found" }, 404));
const newPageDoc = `
<!doctype html>
<h1>Hello!</h1>
`;
app.all("*", (c) => {
const testServers = ["test1", "test2", "test3"];
const server = serverIntialized.filter((n: any) => n.name === "plantToken");
let url = "";
if (c.req.url.includes("localhost")) {
url = `http://localhost:5500/lst/app/old${c.req.path}`;
} else if (testServers.includes(server[0].value)) {
const dbServer = serverIntialized.filter((n: any) => n.name === "dbServer");
url = `https://${dbServer[0].value}.alpla.net/lst/app/old${c.req.path}`;
} else {
url = `https://${server[0].value}prod.alpla.net/lst/app/old${c.req.path}`;
}
const target = url;
const waitSeconds = 10;
return c.html(html`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Lst Moved</title>
<style>
body{font-family:sans-serif;display:flex;flex-direction:column;
align-items:center;justify-content:center;height:100vh;}
button{margin-top:1rem;padding:0.6rem 1.2rem;font-size:1rem;cursor:pointer;}
</style>
</head>
<body>
<h1>Weve moved!</h1>
<p>With new security and updating to mobile version the app had to be moved. You will be redirected to.</p>
<p><a href="${target}">${target}</a></p>
<p>Redirecting in <span id="countdown">${waitSeconds}</span> seconds…</p>
<button id="goNow">Go now</button>
<script>
let s = ${waitSeconds};
const el = document.getElementById('countdown');
const btn = document.getElementById('goNow');
const timer = setInterval(()=>{
s--;
el.textContent = s;
if(s <= 0){ clearInterval(timer); window.location.href='${target}'; }
},1000);
btn.addEventListener('click',()=>{
clearInterval(timer); window.location.href='${target}';
});
</script>
</body>
</html>`);
});
// app.all("/*", (c) => {
// console.log(c.req.path);
// return c.html(html`${newPageDoc}`);
// });
// front end static files
//app.use("/*", serveStatic({ root: "./frontend/dist" }));
//app.use("*", serveStatic({ path: "./frontend/dist/index.html" }));
// Handle app exit signals
process.on("SIGINT", async () => {
console.log("\nGracefully shutting down...");
//await closePool();
process.exit(0);
});
process.on("SIGTERM", async () => {
console.log("Received termination signal, closing database...");
//await closePool();
process.exit(0);
});
process.on("uncaughtException", async (err) => {
console.log("Uncaught Exception:", err);
//await closePool();
const emailData = {
email: "blake.matthes@alpla.com", // should be moved to the db so it can be reused.
subject: `${os.hostname()} has just encountered a crash.`,
template: "serverCrash",
context: {
error: err,
plant: `${os.hostname()}`,
},
};
await sendEmail(emailData);
//process.exit(1);
});
process.on("beforeExit", async () => {
console.log("Process is about to exit...");
//await closePool();
process.exit(0);
});
const port =
process.env.NODE_ENV === "development"
? process.env.VITE_SERVER_PORT
: process.env.PROD_PORT;
const ocmeport = process.env.OCME_PORT;
serve(
{
fetch: app.fetch,
port: Number(port),
hostname: "0.0.0.0",
},
(info) => {
createLog(
"info",
"LST",
"server",
`Server is running on http://${info.address}:${info.port}`,
);
},
);
/**
* Only for ocme until we get them switched over to the single port setup.
*/
// const setting = await db.select().from(settings);
const setting = serverSettings;
const isActive = setting.filter((n) => n.name === "ocmeService");
if (ocmeport && isActive[0]?.value === "1") {
serve(
{
fetch: app.fetch,
port: Number(ocmeport),
hostname: "0.0.0.0",
},
(info) => {
createLog(
"info",
"LST",
"server",
`Ocme section is listening on http://${info.address}:${info.port}`,
);
},
);
}
export type AppRoutes = typeof appRoutes;