Split services into core and request

This commit is contained in:
2026-01-17 16:19:32 -06:00
parent e59bb35ac9
commit 8a7682e953
12 changed files with 76 additions and 73 deletions

View File

@@ -1,7 +1,5 @@
## high importance
- [ ] nix services/ and split it up into core/ request/
- [ ] Add unit tests all over the place.
- ⚠️ Huge task - needs breakdown before starting

View File

@@ -7,9 +7,11 @@ import { Session } from "./auth";
import { cli } from "./cli";
import { contentTypes } from "./content-types";
import { runWithContext } from "./context";
import { core } from "./core";
import { httpCodes } from "./http-codes";
import { request } from "./request";
import { routes } from "./routes";
import { services } from "./services";
// import { URLPattern } from 'node:url';
import {
AuthenticationRequired,
@@ -31,7 +33,7 @@ const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
services.logging.log({ source: "logging", text: ["1"] });
core.logging.log({ source: "logging", text: ["1"] });
const processedRoutes: { [K in Method]: ProcessedRoute[] } = {
GET: [],
POST: [],
@@ -50,9 +52,9 @@ routes.forEach((route: Route, _idx: number, _allRoutes: Route[]) => {
const methodList = route.methods;
const handler: InternalHandler = async (
request: ExpressRequest,
expressRequest: ExpressRequest,
): Promise<Result> => {
const method = massageMethod(request.method);
const method = massageMethod(expressRequest.method);
console.log("method", method);
@@ -60,17 +62,17 @@ routes.forEach((route: Route, _idx: number, _allRoutes: Route[]) => {
// XXX: Worth asserting this?
}
console.log("request.originalUrl", request.originalUrl);
console.log("request.originalUrl", expressRequest.originalUrl);
// Authenticate the request
const auth = await services.auth.validateRequest(request);
const auth = await request.auth.validateRequest(expressRequest);
const req: Call = {
pattern: route.path,
path: request.originalUrl,
path: expressRequest.originalUrl,
method,
parameters: { one: 1, two: 2 },
request,
request: expressRequest,
user: auth.user,
session: new Session(auth.session, auth.user),
};

View File

@@ -5,7 +5,7 @@
import { z } from "zod";
import { contentTypes } from "../content-types";
import { httpCodes } from "../http-codes";
import { services } from "../services";
import { request } from "../request";
import type { Call, Result, Route } from "../types";
import {
forgotPasswordInputParser,
@@ -39,7 +39,7 @@ const loginHandler = async (call: Call): Promise<Result> => {
const body = call.request.body;
const { email, password } = loginInputParser.parse(body);
const result = await services.auth.login(email, password, "cookie", {
const result = await request.auth.login(email, password, "cookie", {
userAgent: call.request.get("User-Agent"),
ipAddress: call.request.ip,
});
@@ -72,9 +72,9 @@ const loginHandler = async (call: Call): Promise<Result> => {
// POST /auth/logout
const logoutHandler = async (call: Call): Promise<Result> => {
const token = services.auth.extractToken(call.request);
const token = request.auth.extractToken(call.request);
if (token) {
await services.auth.logout(token);
await request.auth.logout(token);
}
return jsonResponse(httpCodes.success.OK, { message: "Logged out" });
@@ -87,7 +87,7 @@ const registerHandler = async (call: Call): Promise<Result> => {
const { email, password, displayName } =
registerInputParser.parse(body);
const result = await services.auth.register(
const result = await request.auth.register(
email,
password,
displayName,
@@ -128,7 +128,7 @@ const forgotPasswordHandler = async (call: Call): Promise<Result> => {
const body = call.request.body;
const { email } = forgotPasswordInputParser.parse(body);
const result = await services.auth.createPasswordResetToken(email);
const result = await request.auth.createPasswordResetToken(email);
// Always return success (don't reveal if email exists)
if (result) {
@@ -159,7 +159,7 @@ const resetPasswordHandler = async (call: Call): Promise<Result> => {
const body = call.request.body;
const { token, password } = resetPasswordInputParser.parse(body);
const result = await services.auth.resetPassword(token, password);
const result = await request.auth.resetPassword(token, password);
if (!result.success) {
return errorResponse(
@@ -195,7 +195,7 @@ const verifyEmailHandler = async (call: Call): Promise<Result> => {
);
}
const result = await services.auth.verifyEmail(token);
const result = await request.auth.verifyEmail(token);
if (!result.success) {
return errorResponse(httpCodes.clientErrors.BadRequest, result.error);

View File

@@ -1,8 +1,8 @@
import { SESSION_COOKIE_NAME } from "../auth/token";
import { tokenLifetimes } from "../auth/types";
import { services } from "../services";
import type { Call, Result, Route } from "../types";
import { request } from "../request";
import { html, redirect, render } from "../request/util";
import type { Call, Result, Route } from "../types";
const loginHandler = async (call: Call): Promise<Result> => {
if (call.method === "GET") {
@@ -21,7 +21,7 @@ const loginHandler = async (call: Call): Promise<Result> => {
return html(c);
}
const result = await services.auth.login(email, password, "cookie", {
const result = await request.auth.login(email, password, "cookie", {
userAgent: call.request.get("User-Agent"),
ipAddress: call.request.ip,
});

View File

@@ -1,13 +1,13 @@
import { SESSION_COOKIE_NAME } from "../auth/token";
import { services } from "../services";
import type { Call, Result, Route } from "../types";
import { request } from "../request";
import { redirect } from "../request/util";
import type { Call, Result, Route } from "../types";
const logoutHandler = async (call: Call): Promise<Result> => {
// Extract token from cookie and invalidate the session
const token = services.auth.extractToken(call.request);
const token = request.auth.extractToken(call.request);
if (token) {
await services.auth.logout(token);
await request.auth.logout(token);
}
// Clear the cookie and redirect to login

View File

@@ -1,7 +1,7 @@
import { DateTime } from "ts-luxon";
import { services } from "../services";
import type { Call, Result, Route } from "../types";
import { request } from "../request";
import { html, render } from "../request/util";
import type { Call, Result, Route } from "../types";
import { loginRoute } from "./login";
import { logoutRoute } from "./logout";
@@ -20,8 +20,8 @@ const routes: Record<string, Route> = {
path: "/",
methods: ["GET"],
handler: async (_call: Call): Promise<Result> => {
const auth = services.auth;
const me = services.session.getUser();
const _auth = request.auth;
const me = request.session.getUser();
const email = me.toString();
const c = await render("basic/home", { email });

View File

@@ -1,20 +1,16 @@
// services.ts
import { AuthService } from "../auth";
import { getCurrentUser } from "../context";
import { db, migrate, migrationStatus, PostgresAuthStore } from "../database";
import nunjucks from "nunjucks";
import { db, migrate, migrationStatus } from "../database";
import { getLogs, log } from "../logging";
import type { MaybeUser } from "../user";
import nunjucks from 'nunjucks'
// FIXME: This doesn't belong here; move it somewhere else.
const conf = {
templateEngine: () => {
templateEngine: () => {
return {
renderTemplate: (template: string, context: object) => {
return nunjucks.renderString(template, context);
},
}
}
};
},
};
const database = {
@@ -40,25 +36,13 @@ const misc = {
},
};
const session = {
getUser: (): MaybeUser => {
return getCurrentUser();
},
};
// Initialize auth with PostgreSQL store
const authStore = new PostgresAuthStore();
const auth = new AuthService(authStore);
// Keep this asciibetically sorted
const services = {
auth,
const core = {
conf,
database,
logging,
misc,
random,
session,
};
export { services };
export { core };

View File

@@ -1,11 +1,11 @@
import { contentTypes } from "./content-types";
import { core } from "./core";
import { httpCodes } from "./http-codes";
import { services } from "./services";
import type { Call, Handler, Result } from "./types";
const multiHandler: Handler = async (call: Call): Promise<Result> => {
const code = httpCodes.success.OK;
const rn = services.random.randomNumber();
const rn = core.random.randomNumber();
const retval: Result = {
code,

25
express/request/index.ts Normal file
View File

@@ -0,0 +1,25 @@
import { AuthService } from "../auth";
import { getCurrentUser } from "../context";
import { PostgresAuthStore } from "../database";
import type { MaybeUser } from "../user";
import { html, redirect, render } from "./util";
const util = { html, redirect, render };
const session = {
getUser: (): MaybeUser => {
return getCurrentUser();
},
};
// Initialize auth with PostgreSQL store
const authStore = new PostgresAuthStore();
const auth = new AuthService(authStore);
const request = {
auth,
session,
util,
};
export { request };

View File

@@ -1,24 +1,23 @@
import { contentTypes } from "../content-types";
import { core } from "../core";
import { executionContext } from "../execution-context";
import { httpCodes } from "../http-codes";
import type { RedirectResult, Result } from "../types";
import {services} from '../services'
import { loadFile } from "../util";
import { request } from "./index";
import{loadFile}from'../util'
type NoUser={
type NoUser = {
[key: string]: unknown;
} & {
user?: never;
}
};
const render = async (path: string, ctx?: NoUser): Promise<string> => {
const fullPath = `${executionContext.diachron_root}/templates/${path}.html.njk`;
const template = await loadFile(fullPath);
const user = services.session.getUser();
const context = {user, ...ctx}
const engine = services.conf.templateEngine()
const user = request.session.getUser();
const context = { user, ...ctx };
const engine = core.conf.templateEngine();
const retval = engine.renderTemplate(template, context);
return retval;
@@ -43,4 +42,4 @@ const redirect = (location: string): RedirectResult => {
};
};
export { render, html, redirect };
export { html, redirect, render };

View File

@@ -5,9 +5,9 @@ import { DateTime } from "ts-luxon";
import { authRoutes } from "./auth/routes";
import { routes as basicRoutes } from "./basic/routes";
import { contentTypes } from "./content-types";
import { core } from "./core";
import { multiHandler } from "./handlers";
import { httpCodes } from "./http-codes";
import { services } from "./services";
import type { Call, Result, Route } from "./types";
// FIXME: Obviously put this somewhere else
@@ -35,7 +35,7 @@ const routes: Route[] = [
handler: async (_call: Call): Promise<Result> => {
console.log("starting slow request");
await services.misc.sleep(2);
await core.misc.sleep(2);
console.log("finishing slow request");
const retval = okText("that was slow");

View File

@@ -1,5 +1,4 @@
import { readFile } from "node:fs/promises";
import nunjucks from "nunjucks";
// FIXME: Handle the error here
const loadFile = async (path: string): Promise<string> => {
@@ -9,8 +8,4 @@ const loadFile = async (path: string): Promise<string> => {
return data;
};
export {
loadFile,
}
export { loadFile };