frontend added and socket io

This commit is contained in:
2026-03-16 18:07:23 -05:00
parent 81dc575b4f
commit 5db2a7fe75
45 changed files with 11947 additions and 5546 deletions

View File

@@ -1,3 +1,5 @@
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { toNodeHandler } from "better-auth/node";
import express from "express";
import morgan from "morgan";
@@ -20,14 +22,33 @@ const createApp = async () => {
baseUrl = "/lst";
}
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// well leave this active so we can monitor it to validate
app.use(morgan("tiny"));
app.set("trust proxy", true);
app.all(`${baseUrl}api/auth/*splat`, toNodeHandler(auth));
app.use(express.json());
app.use(lstCors());
app.all(`${baseUrl}/api/auth/*splat`, toNodeHandler(auth));
app.use(express.json());
setupRoutes(baseUrl, app);
app.use(
baseUrl + "/app",
express.static(join(__dirname, "../frontend/dist")),
);
app.get(baseUrl + "/app/*splat", (_, res) => {
res.sendFile(join(__dirname, "../frontend/dist/index.html"));
});
app.all("*foo", (_, res) => {
res.status(400).json({
message:
"You have encountered a route that dose not exist, please check the url and try again",
});
});
log.info("Lst app created");
return { app, baseUrl };
};

View File

@@ -96,6 +96,18 @@ r.post("/", async (req, res) => {
asResponse: true,
});
if (login.status === 401) {
return apiReturn(res, {
success: false,
level: "error", //connect.success ? "info" : "error",
module: "routes",
subModule: "auth",
message: `Incorrect username or password please try again`,
data: [],
status: 401, //connect.success ? 200 : 400,
});
}
login.headers.forEach((value: string, key: string) => {
if (key.toLowerCase() === "set-cookie") {
res.append("set-cookie", value);

View File

@@ -1,5 +1,5 @@
import { APIError } from "better-auth";
import { count, sql } from "drizzle-orm";
import { count, eq, sql } from "drizzle-orm";
import { Router } from "express";
import z from "zod";
import { db } from "../db/db.controller.js";
@@ -58,7 +58,10 @@ r.post("/", async (req, res) => {
// if we have no users yet lets make this new one the admin
if (userCount === 0) {
// make this user an admin
await db.update(user).set({ role: "admin", updatedAt: sql`NOW()` });
await db
.update(user)
.set({ role: "admin", updatedAt: sql`NOW()` })
.where(eq(user.id, newUser.user.id));
}
apiReturn(res, {

View File

@@ -28,14 +28,17 @@ const dbStream = new Writable({
const levelName = pinoLogLevels[obj.level] || "unknown";
const res = await tryCatch(
db.insert(logs).values({
level: levelName,
module: obj?.module?.toLowerCase(),
subModule: obj?.subModule?.toLowerCase(),
hostname: obj?.hostname?.toLowerCase(),
message: obj.msg,
stack: obj?.stack,
}),
db
.insert(logs)
.values({
level: levelName,
module: obj?.module?.toLowerCase(),
subModule: obj?.subModule?.toLowerCase(),
hostname: obj?.hostname?.toLowerCase(),
message: obj.msg,
stack: obj?.stack,
})
.returning(),
);
if (res.error) {
@@ -43,9 +46,9 @@ const dbStream = new Writable({
}
if (obj.room) {
emitToRoom(obj.room, obj);
emitToRoom(obj.room, res.data ? res.data[0] : obj);
}
emitToRoom("logs", obj);
emitToRoom("logs", res.data ? res.data[0] : obj);
callback();
} catch (err) {
console.error("DB log insert error:", err);

View File

@@ -1,6 +1,6 @@
import { systemSettings } from "backend/server.js";
import { io, type Socket } from "socket.io-client";
import { createLogger } from "../logger/logger.controller.js";
import { systemSettings } from "../server.js";
import { getToken, odToken } from "./opendock.utils.js";
const log = createLogger({ module: "opendock", subModule: "releaseMonitor" });

View File

@@ -17,13 +17,4 @@ export const setupRoutes = (baseUrl: string, app: Express) => {
setupAuthRoutes(baseUrl, app);
setupUtilsRoutes(baseUrl, app);
setupOpendockRoutes(baseUrl, app);
// routes that get activated if the module is set to activated.
app.all("*foo", (_, res) => {
res.status(400).json({
message:
"You have encountered a route that dose not exist, please check the url and try again",
});
});
};

View File

@@ -1,6 +1,6 @@
import type { RoomId } from "./types.socket.js";
export const MAX_HISTORY = 20;
export const MAX_HISTORY = 50;
export const FLUSH_INTERVAL = 100; // 50ms change higher if needed
export const roomHistory = new Map<RoomId, unknown[]>();

View File

@@ -1,6 +1,5 @@
import { logs } from "backend/db/schema/logs.schema.js";
import { desc } from "drizzle-orm";
import { db } from "../db/db.controller.js";
import { logs } from "../db/schema/logs.schema.js";
import type { RoomId } from "./types.socket.js";
type RoomDefinition<T = unknown> = {
@@ -14,10 +13,10 @@ export const roomDefinition: Record<RoomId, RoomDefinition> = {
const rows = await db
.select()
.from(logs)
.orderBy(desc(logs.createdAt))
.orderBy(logs.createdAt)
.limit(limit);
return rows.reverse();
return rows; //.reverse();
} catch (e) {
console.error("Failed to seed logs:", e);
return [];
@@ -27,6 +26,7 @@ export const roomDefinition: Record<RoomId, RoomDefinition> = {
labels: {
seed: async (limit) => {
console.info(limit);
return [];
},
},

View File

@@ -4,6 +4,7 @@ import type { Server as HttpServer } from "node:http";
import { instrument } from "@socket.io/admin-ui";
import { Server } from "socket.io";
import { createLogger } from "../logger/logger.controller.js";
import { allowedOrigins } from "../utils/cors.utils.js";
import { registerEmitter } from "./roomEmitter.socket.js";
import { createRoomEmitter, preseedRoom } from "./roomService.socket.js";
@@ -15,7 +16,7 @@ export const setupSocketIORoutes = (baseUrl: string, server: HttpServer) => {
const io = new Server(server, {
path: `${baseUrl}/api/socket.io`,
cors: {
origin: ["http://localhost:3000", "https://admin.socket.io"],
origin: allowedOrigins,
credentials: true,
},
});
@@ -38,7 +39,7 @@ export const setupSocketIORoutes = (baseUrl: string, server: HttpServer) => {
// get room seeded
const history = await preseedRoom(rn);
log.info({}, `User joined ${rn}: ${s.id}`);
// send the intial data
s.emit("room-update", {
roomId: rn,
@@ -46,6 +47,11 @@ export const setupSocketIORoutes = (baseUrl: string, server: HttpServer) => {
initial: true,
});
});
s.on("leave-room", (room) => {
s.leave(room);
log.info({}, `${s.id} left room: ${room}`);
});
});
io.on("disconnect", (s) => {

View File

@@ -2,8 +2,8 @@ import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import {
admin,
apiKey,
createAuthMiddleware,
// apiKey,
// createAuthMiddleware,
//customSession,
jwt,
lastLoginMethod,
@@ -31,6 +31,7 @@ export const auth = betterAuth({
provider: "pg",
schema,
}),
trustedOrigins: allowedOrigins,
// user: {
// additionalFields: {
// role: {
@@ -42,7 +43,7 @@ export const auth = betterAuth({
// },
plugins: [
jwt({ jwt: { expirationTime: "1h" } }),
apiKey(),
//apiKey(),
admin(),
lastLoginMethod(),
username({
@@ -70,7 +71,6 @@ export const auth = betterAuth({
// };
// }),
],
trustedOrigins: allowedOrigins,
emailAndPassword: {
enabled: true,
@@ -118,16 +118,16 @@ export const auth = betterAuth({
secure: false,
httpOnly: true,
},
hooks: {
after: createAuthMiddleware(async (ctx) => {
if (ctx.path.startsWith("/login")) {
const newSession = ctx.context.newSession;
if (newSession) {
// something here later
}
}
}),
},
// hooks: {
// after: createAuthMiddleware(async (ctx) => {
// if (ctx.path.startsWith("/login")) {
// const newSession = ctx.context.newSession;
// if (newSession) {
// // something here later
// }
// }
// }),
// },
events: {
// async onSignInSuccess({ user }: { user: User }) {
// await db

View File

@@ -12,6 +12,9 @@ export const allowedOrigins = [
"https://admin.socket.io",
"https://electron-socket-io-playground.vercel.app",
`${process.env.URL}`,
`http://${process.env.PROD_SERVER}:3000`,
`http://${process.env.PROD_SERVER}:3100`, // temp
`http://usmcd1olp082:3000`,
];
export const lstCors = () => {
return cors({