From 5469a0dc5c8556fab5b6e0d660e612acc17ebc51 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Fri, 20 Feb 2026 11:05:03 -0600 Subject: [PATCH] scaler updates --- backend/configs/scaler.config.ts | 16 +++- backend/middleware/auth.middleware.ts | 30 ++++++ backend/prodSql/prodSql.routes.ts | 15 ++- backend/scaler/cronerStatusChange.spec.ts | 94 +++++++++++++++++++ backend/scaler/prodSqlRestart.spec.ts | 1 + ...sChange.ts => cronerStatusChange.route.ts} | 2 +- backend/utils/utils.routes.ts | 2 +- 7 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 backend/middleware/auth.middleware.ts create mode 100644 backend/scaler/cronerStatusChange.spec.ts rename backend/utils/{cronerStatusChange.ts => cronerStatusChange.route.ts} (96%) diff --git a/backend/configs/scaler.config.ts b/backend/configs/scaler.config.ts index 7c4967b..26c99bd 100644 --- a/backend/configs/scaler.config.ts +++ b/backend/configs/scaler.config.ts @@ -10,6 +10,7 @@ import { apiReference } from "@scalar/express-api-reference"; // const port = 3000; import type { OpenAPIV3_1 } from "openapi-types"; import { cronerActiveJobs } from "../scaler/cronerActiveJobs.spec.js"; +import { cronerStatusChange } from "../scaler/cronerStatusChange.spec.js"; import { prodLoginSpec } from "../scaler/login.spec.js"; import { prodRestartSpec } from "../scaler/prodSqlRestart.spec.js"; import { prodStartSpec } from "../scaler/prodSqlStart.spec.js"; @@ -50,6 +51,11 @@ export const openApiBase: OpenAPIV3_1.Document = { scheme: "basic", description: "Basic authentication using username and password", }, + cookieAuth: { + type: "apiKey", + in: "cookie", + name: "better-auth.session_token", + }, }, // schemas: { // Error: { @@ -61,7 +67,12 @@ export const openApiBase: OpenAPIV3_1.Document = { // }, // },. }, - + // security: [ + // { + // cookieAuth: [], + // basicAuth: [], + // }, + // ], tags: [ { name: "Auth", @@ -109,6 +120,7 @@ export const setupApiDocsRoutes = (baseUrl: string, app: Express) => { ...prodRegisterSpec, //...mergedDatamart, ...cronerActiveJobs, + ...cronerStatusChange, // Add more specs here as you build features }, @@ -144,7 +156,7 @@ export const setupApiDocsRoutes = (baseUrl: string, app: Express) => { // Clojure clojure: ["clj_http"], // C# - csharp: ["httpclient", "restsharp"], + // csharp: ["httpclient", "restsharp"], // Dart dart: ["http"], // F# diff --git a/backend/middleware/auth.middleware.ts b/backend/middleware/auth.middleware.ts new file mode 100644 index 0000000..0a01c21 --- /dev/null +++ b/backend/middleware/auth.middleware.ts @@ -0,0 +1,30 @@ +import { fromNodeHeaders } from "better-auth/node"; +import type { NextFunction, Request, Response } from "express"; +import { auth } from "../utils/auth.utils.js"; + +export const requireAuth = async ( + req: Request, + res: Response, + next: NextFunction, +) => { + // TODO: add the real auth stuff in later. + try { + const session = await auth.api.getSession({ + headers: fromNodeHeaders(req.headers), + }); + + if (!session) { + //return res.status(401).json({ error: "Unauthorized" }); + console.info("not auth of course"); + } + + // attach session to request for later use + (req as any).session = session; + console.info( + "Just passing the middleware and reminder that we need to add the real stuff in.", + ); + next(); + } catch { + return res.status(401).json({ error: "Unauthorized" }); + } +}; diff --git a/backend/prodSql/prodSql.routes.ts b/backend/prodSql/prodSql.routes.ts index cb7e554..4feca8e 100644 --- a/backend/prodSql/prodSql.routes.ts +++ b/backend/prodSql/prodSql.routes.ts @@ -1,10 +1,17 @@ -import type { Express } from "express"; +import { type Express, Router } from "express"; +import { requireAuth } from "../middleware/auth.middleware.js"; import restart from "./prodSqlRestart.route.js"; import start from "./prodSqlStart.route.js"; import stop from "./prodSqlStop.route.js"; export const setupProdSqlRoutes = (baseUrl: string, app: Express) => { //setup all the routes - app.use(`${baseUrl}/api/system/prodSql`, start); - app.use(`${baseUrl}/api/system/prodSql`, stop); - app.use(`${baseUrl}/api/system/prodSql`, restart); + // Apply auth to entire router + const router = Router(); + router.use(requireAuth); + + router.use(start); + router.use(stop); + router.use(restart); + + app.use(`${baseUrl}/api/system/prodSql`, router); }; diff --git a/backend/scaler/cronerStatusChange.spec.ts b/backend/scaler/cronerStatusChange.spec.ts new file mode 100644 index 0000000..1706ac2 --- /dev/null +++ b/backend/scaler/cronerStatusChange.spec.ts @@ -0,0 +1,94 @@ +import type { OpenAPIV3_1 } from "openapi-types"; + +export const cronerStatusChange: OpenAPIV3_1.PathsObject = { + "/api/utils/croner/{status}": { + patch: { + summary: "Pauses or Resume the Job", + description: + "When sending start or stop with job name it will resume or stop the job", + tags: ["Utils"], + + parameters: [ + { + name: "status", + in: "path", + required: true, + description: "Status change", + schema: { + type: "string", + }, + example: "start", + }, + { + name: "limit", + in: "query", + required: false, // 👈 optional + description: "Maximum number of records to return", + schema: { + type: "integer", + minimum: 1, + maximum: 100, + }, + example: 10, + }, + ], + requestBody: { + required: true, + content: { + "application/json": { + schema: { + type: "object", + required: ["name"], + properties: { + name: { + type: "string", + example: "start", + }, + }, + }, + }, + }, + }, + + responses: { + "200": { + description: "Successful response", + content: { + "application/json": { + schema: { + type: "object", + properties: { + success: { type: "boolean", example: true }, + data: { + type: "object", + example: { + name: "exampleName", + value: "some value", + }, + }, + }, + }, + }, + }, + }, + "400": { + description: "Bad request", + content: { + "application/json": { + schema: { + type: "object", + properties: { + success: { type: "boolean", example: false }, + message: { + type: "string", + example: "Invalid name parameter", + }, + }, + }, + }, + }, + }, + }, + }, + }, +}; diff --git a/backend/scaler/prodSqlRestart.spec.ts b/backend/scaler/prodSqlRestart.spec.ts index 7ec22bc..8e5f30d 100644 --- a/backend/scaler/prodSqlRestart.spec.ts +++ b/backend/scaler/prodSqlRestart.spec.ts @@ -3,6 +3,7 @@ import type { OpenAPIV3_1 } from "openapi-types"; export const prodRestartSpec: OpenAPIV3_1.PathsObject = { "/api/system/prodSql/restart": { post: { + //security: [], summary: "Prod restart sql connection", description: "Attempts to restart the sql connection.", tags: ["System"], diff --git a/backend/utils/cronerStatusChange.ts b/backend/utils/cronerStatusChange.route.ts similarity index 96% rename from backend/utils/cronerStatusChange.ts rename to backend/utils/cronerStatusChange.route.ts index 5b91b4d..c2fa762 100644 --- a/backend/utils/cronerStatusChange.ts +++ b/backend/utils/cronerStatusChange.route.ts @@ -40,7 +40,7 @@ r.patch("/:status", async (req, res) => { level: "info", module: "utils", subModule: "jobs", - message: `${name} was restarted`, + message: `${body.name} was restarted`, data: getAllJobs(), status: 200, }); diff --git a/backend/utils/utils.routes.ts b/backend/utils/utils.routes.ts index 92ded56..8b9fadf 100644 --- a/backend/utils/utils.routes.ts +++ b/backend/utils/utils.routes.ts @@ -1,6 +1,6 @@ import type { Express } from "express"; import getActiveJobs from "./cronerActiveJobs.route.js"; -import jobStatusChange from "./cronerStatusChange.js"; +import jobStatusChange from "./cronerStatusChange.route.js"; export const setupUtilsRoutes = (baseUrl: string, app: Express) => { app.use(`${baseUrl}/api/utils/croner`, getActiveJobs); app.use(`${baseUrl}/api/utils/croner`, jobStatusChange);