intial setting and auth intergrated
This commit is contained in:
@@ -54,7 +54,8 @@ const signin = z.union([
|
||||
const r = Router();
|
||||
|
||||
r.post("/", async (req, res) => {
|
||||
let login: unknown;
|
||||
let login: unknown | any;
|
||||
|
||||
try {
|
||||
const validated = signin.parse(req.body);
|
||||
if ("email" in validated) {
|
||||
@@ -92,6 +93,15 @@ r.post("/", async (req, res) => {
|
||||
password: validated.password,
|
||||
},
|
||||
headers: fromNodeHeaders(req.headers),
|
||||
asResponse: true,
|
||||
});
|
||||
|
||||
login.headers.forEach((value: string, key: string) => {
|
||||
if (key.toLowerCase() === "set-cookie") {
|
||||
res.append("set-cookie", value);
|
||||
} else {
|
||||
res.setHeader(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,27 +2,55 @@ import { fromNodeHeaders } from "better-auth/node";
|
||||
import type { NextFunction, Request, Response } from "express";
|
||||
import { auth } from "../utils/auth.utils.js";
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
user?: {
|
||||
id: string;
|
||||
email?: string;
|
||||
roles?: string | null | undefined; //Record<string, string[]>;
|
||||
username?: string | null | undefined;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// function toWebHeaders(nodeHeaders: Request["headers"]): Headers {
|
||||
// const h = new Headers();
|
||||
// for (const [key, value] of Object.entries(nodeHeaders)) {
|
||||
// if (Array.isArray(value)) {
|
||||
// value.forEach((v) => h.append(key, v));
|
||||
// } else if (value !== undefined) {
|
||||
// h.set(key, value);
|
||||
// }
|
||||
// }
|
||||
// return h;
|
||||
// }
|
||||
|
||||
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),
|
||||
//query: { disableCookieCache: true },
|
||||
});
|
||||
|
||||
if (!session) {
|
||||
//return res.status(401).json({ error: "Unauthorized" });
|
||||
console.info("not auth of course");
|
||||
return res.status(401).json({ error: "Unauthorized" });
|
||||
}
|
||||
|
||||
// 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.",
|
||||
);
|
||||
//console.log(session);
|
||||
|
||||
req.user = {
|
||||
id: session.user.id,
|
||||
email: session.user.email,
|
||||
roles: session.user.role,
|
||||
username: session.user.username,
|
||||
};
|
||||
|
||||
next();
|
||||
} catch {
|
||||
return res.status(401).json({ error: "Unauthorized" });
|
||||
|
||||
@@ -58,7 +58,7 @@ export const prodQuery = async (queryToRun: string, name: string) => {
|
||||
return {
|
||||
success: true,
|
||||
message: `Query results for: ${name}`,
|
||||
data: result.recordset,
|
||||
data: result.recordset ?? [],
|
||||
};
|
||||
} catch (error: unknown) {
|
||||
const err = error as SqlError;
|
||||
|
||||
44
backend/system/settings.route.ts
Normal file
44
backend/system/settings.route.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { type Response, Router } from "express";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import { settings } from "../db/schema/settings.schema.js";
|
||||
|
||||
import { apiReturn } from "../utils/returnHelper.utils.js";
|
||||
import { tryCatch } from "../utils/trycatch.utils.js";
|
||||
|
||||
// export const updateSetting = async (setting: Setting) => {
|
||||
// // TODO: when the setting is a feature setting we will need to have it run each kill switch on the crons well just stop them and during a reset it just wont start them
|
||||
// // TODO: when the setting is a system we will need to force an app restart
|
||||
// // TODO: when the setting is standard we don't do anything.
|
||||
// };
|
||||
|
||||
const r = Router();
|
||||
|
||||
r.get("/", async (_, res: Response) => {
|
||||
const { data: sName, error: sError } = await tryCatch(
|
||||
db.select().from(settings),
|
||||
);
|
||||
|
||||
if (sError) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "system",
|
||||
subModule: "settings",
|
||||
message: `There was an error getting the settings `,
|
||||
data: [sError],
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "system",
|
||||
subModule: "settings",
|
||||
message: `All current settings`,
|
||||
data: sName ?? [],
|
||||
status: 200,
|
||||
});
|
||||
});
|
||||
|
||||
export default r;
|
||||
0
backend/system/settingsBase.controller.ts
Normal file
0
backend/system/settingsBase.controller.ts
Normal file
@@ -1,7 +0,0 @@
|
||||
import type { Setting } from "../db/schema/settings.schema.js";
|
||||
|
||||
export const updateSetting = async (setting: Setting) => {
|
||||
// TODO: when the setting is a feature setting we will need to have it run each kill switch on the crons well just stop them and during a reset it just wont start them
|
||||
// TODO: when the setting is a system we will need to force an app restart
|
||||
// TODO: when the setting is standard we don't do anything.
|
||||
};
|
||||
93
backend/system/settingsUpdate.route.ts
Normal file
93
backend/system/settingsUpdate.route.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { type Request, type Response, Router } from "express";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import { settings } from "../db/schema/settings.schema.js";
|
||||
|
||||
import { apiReturn } from "../utils/returnHelper.utils.js";
|
||||
import { tryCatch } from "../utils/trycatch.utils.js";
|
||||
|
||||
// export const updateSetting = async (setting: Setting) => {
|
||||
// // TODO: when the setting is a feature setting we will need to have it run each kill switch on the crons well just stop them and during a reset it just wont start them
|
||||
// // TODO: when the setting is a system we will need to force an app restart
|
||||
// // TODO: when the setting is standard we don't do anything.
|
||||
// };
|
||||
|
||||
const r = Router();
|
||||
|
||||
r.patch("/:name", async (req: Request, res: Response) => {
|
||||
const { name } = req.params;
|
||||
const updates: Record<string, unknown | null> = {};
|
||||
// lets see if we even have a setting name
|
||||
|
||||
const { data: sName, error: sError } = await tryCatch(
|
||||
db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, name ?? "")),
|
||||
);
|
||||
|
||||
if (sError) {
|
||||
return apiReturn(res, {
|
||||
success: false,
|
||||
level: "error",
|
||||
module: "system",
|
||||
subModule: "settings",
|
||||
message: `There was an error checking the name of the setting`,
|
||||
data: [sError],
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
// if (sName?.length === 0) {
|
||||
// return apiReturn(res, {
|
||||
// success: false,
|
||||
// level: "error",
|
||||
// module: "system",
|
||||
// subModule: "settings",
|
||||
// message: `The setting "${name}" dose not appear to be a valid setting please check the name and try again. `,
|
||||
// data: [],
|
||||
// status: 400,
|
||||
// });
|
||||
// }
|
||||
|
||||
// manage the actual setting. we will still do an upsert just in case we strangely get past everything
|
||||
|
||||
if (req.body?.value !== undefined) {
|
||||
updates.value = req.body.value;
|
||||
}
|
||||
|
||||
if (req.body?.description !== undefined) {
|
||||
updates.description = req.body.description;
|
||||
}
|
||||
|
||||
if (req.body?.moduleName !== undefined) {
|
||||
updates.moduleName = req.body.moduleName;
|
||||
}
|
||||
|
||||
if (req.body?.active !== undefined) {
|
||||
updates.active = req.body.active === "true";
|
||||
}
|
||||
|
||||
if (req.body?.roles !== undefined) {
|
||||
updates.roles = req.body.roles;
|
||||
}
|
||||
|
||||
if (req.body?.settingType !== undefined) {
|
||||
updates.settingType = req.body.settingType;
|
||||
}
|
||||
|
||||
updates.upd_user = req.user?.username || "lst_user";
|
||||
updates.upd_date = sql`NOW()`;
|
||||
|
||||
return apiReturn(res, {
|
||||
success: true,
|
||||
level: "info",
|
||||
module: "system",
|
||||
subModule: "settings",
|
||||
message: `Setting "${name}" Was just updated. `,
|
||||
data: [updates],
|
||||
status: 400,
|
||||
});
|
||||
});
|
||||
|
||||
export default r;
|
||||
@@ -1,9 +1,14 @@
|
||||
import { requireAuth } from "backend/middleware/auth.middleware.js";
|
||||
import type { Express } from "express";
|
||||
import getSettings from "./settings.route.js";
|
||||
import updSetting from "./settingsUpdate.route.js";
|
||||
import stats from "./stats.route.js";
|
||||
|
||||
export const setupSystemRoutes = (baseUrl: string, app: Express) => {
|
||||
//stats will be like this as we dont need to change this
|
||||
app.use(`${baseUrl}/api/stats`, stats);
|
||||
app.use(`${baseUrl}/api/settings`, getSettings);
|
||||
app.use(`${baseUrl}/api/settings`, requireAuth, updSetting);
|
||||
|
||||
// all other system should be under /api/system/*
|
||||
};
|
||||
|
||||
@@ -4,12 +4,12 @@ import {
|
||||
admin,
|
||||
apiKey,
|
||||
createAuthMiddleware,
|
||||
customSession,
|
||||
//customSession,
|
||||
jwt,
|
||||
lastLoginMethod,
|
||||
username,
|
||||
} from "better-auth/plugins";
|
||||
import { eq } from "drizzle-orm";
|
||||
//import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/db.controller.js";
|
||||
import * as rawSchema from "../db/schema/auth.schema.js";
|
||||
import { allowedOrigins } from "./cors.utils.js";
|
||||
@@ -31,20 +31,15 @@ export const auth = betterAuth({
|
||||
provider: "pg",
|
||||
schema,
|
||||
}),
|
||||
user: {
|
||||
additionalFields: {
|
||||
role: {
|
||||
type: "string",
|
||||
required: false,
|
||||
input: false,
|
||||
},
|
||||
lastLogin: {
|
||||
type: "date",
|
||||
required: true,
|
||||
input: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
// user: {
|
||||
// additionalFields: {
|
||||
// role: {
|
||||
// type: "string",
|
||||
// //required: false,
|
||||
// input: false,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
plugins: [
|
||||
jwt({ jwt: { expirationTime: "1h" } }),
|
||||
apiKey(),
|
||||
@@ -53,26 +48,27 @@ export const auth = betterAuth({
|
||||
username({
|
||||
minUsernameLength: 5,
|
||||
usernameValidator: (username) => {
|
||||
if (username === "admin") {
|
||||
if (username === "admin" || username === "root") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
customSession(async ({ user, session }) => {
|
||||
const roles = await db
|
||||
.select({ roles: rawSchema.user.role })
|
||||
.from(rawSchema.user)
|
||||
.where(eq(rawSchema.user.id, session.id));
|
||||
return {
|
||||
roles,
|
||||
user: {
|
||||
...user,
|
||||
//newField: "newField",
|
||||
},
|
||||
session,
|
||||
};
|
||||
}),
|
||||
|
||||
// customSession(async ({ user, session }) => {
|
||||
// const roles = await db
|
||||
// .select({ roles: rawSchema.user.role })
|
||||
// .from(rawSchema.user)
|
||||
// .where(eq(rawSchema.user.id, session.id));
|
||||
// return {
|
||||
// roles,
|
||||
// user: {
|
||||
// ...user,
|
||||
// //newField: "newField",
|
||||
// },
|
||||
// session,
|
||||
// };
|
||||
// }),
|
||||
],
|
||||
trustedOrigins: allowedOrigins,
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Response } from "express";
|
||||
import { createLogger } from "../logger/logger.controller.js";
|
||||
|
||||
interface Data {
|
||||
interface Data<T = unknown[]> {
|
||||
success: boolean;
|
||||
module: "system" | "ocp" | "routes" | "datamart" | "utils" | "opendock";
|
||||
subModule:
|
||||
@@ -14,10 +14,11 @@ interface Data {
|
||||
| "auth"
|
||||
| "datamart"
|
||||
| "jobs"
|
||||
| "apt";
|
||||
| "apt"
|
||||
| "settings";
|
||||
level: "info" | "error" | "debug" | "fatal";
|
||||
message: string;
|
||||
data?: unknown[];
|
||||
data?: T;
|
||||
notify?: boolean;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user