Compare commits
3 Commits
c246e0384f
...
e136c07928
| Author | SHA1 | Date | |
|---|---|---|---|
| e136c07928 | |||
| c926f15aab | |||
| 39cd93c81e |
@@ -1,3 +1,4 @@
|
|||||||
{"id":"diachron-2vh","title":"Add unit testing to golang programs","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-03T12:31:41.281891462-06:00","created_by":"mw","updated_at":"2026-01-03T12:31:41.281891462-06:00"}
|
{"id":"diachron-2vh","title":"Add unit testing to golang programs","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-03T12:31:41.281891462-06:00","created_by":"mw","updated_at":"2026-01-03T12:31:41.281891462-06:00"}
|
||||||
{"id":"diachron-64w","title":"Add unit testing to express backend","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-03T12:31:30.439206099-06:00","created_by":"mw","updated_at":"2026-01-03T12:31:30.439206099-06:00"}
|
{"id":"diachron-64w","title":"Add unit testing to express backend","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-03T12:31:30.439206099-06:00","created_by":"mw","updated_at":"2026-01-03T12:31:30.439206099-06:00"}
|
||||||
{"id":"diachron-fzd","title":"Add generic 'user' functionality","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-03T12:35:53.73213604-06:00","created_by":"mw","updated_at":"2026-01-03T12:35:53.73213604-06:00"}
|
{"id":"diachron-fzd","title":"Add generic 'user' functionality","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-03T12:35:53.73213604-06:00","created_by":"mw","updated_at":"2026-01-03T12:35:53.73213604-06:00"}
|
||||||
|
{"id":"diachron-ngx","title":"Teach the master and/or build process to send messages with notify-send when builds fail or succeed. Ideally this will be fairly generic.","status":"open","priority":2,"issue_type":"task","created_at":"2026-01-03T14:10:11.773218844-06:00","created_by":"mw","updated_at":"2026-01-03T14:10:11.773218844-06:00"}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
// index.ts
|
// index.ts
|
||||||
//
|
//
|
||||||
// Barrel export for auth module.
|
// Barrel export for auth module.
|
||||||
|
//
|
||||||
|
// NOTE: authRoutes is NOT exported here to avoid circular dependency:
|
||||||
|
// services.ts → auth/index.ts → auth/routes.ts → services.ts
|
||||||
|
// Import authRoutes directly from "./auth/routes" instead.
|
||||||
|
|
||||||
export { hashPassword, verifyPassword } from "./password";
|
export { hashPassword, verifyPassword } from "./password";
|
||||||
export { authRoutes } from "./routes";
|
|
||||||
export { AuthService } from "./service";
|
export { AuthService } from "./service";
|
||||||
export { type AuthStore, InMemoryAuthStore } from "./store";
|
export { type AuthStore, InMemoryAuthStore } from "./store";
|
||||||
export { generateToken, hashToken, SESSION_COOKIE_NAME } from "./token";
|
export { generateToken, hashToken, SESSION_COOKIE_NAME } from "./token";
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import nunjucks from "nunjucks";
|
import nunjucks from "nunjucks";
|
||||||
import { DateTime } from "ts-luxon";
|
import { DateTime } from "ts-luxon";
|
||||||
import { authRoutes } from "./auth";
|
import { authRoutes } from "./auth/routes";
|
||||||
import { contentTypes } from "./content-types";
|
import { contentTypes } from "./content-types";
|
||||||
import { multiHandler } from "./handlers";
|
import { multiHandler } from "./handlers";
|
||||||
import { HttpCode, httpCodes } from "./http-codes";
|
import { HttpCode, httpCodes } from "./http-codes";
|
||||||
@@ -59,6 +59,29 @@ const routes: Route[] = [
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/whoami",
|
||||||
|
methods: ["GET"],
|
||||||
|
handler: async (_call: Call): Promise<Result> => {
|
||||||
|
const me = services.session.getUser();
|
||||||
|
const template = `
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
{{ me }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const result = nunjucks.renderString(template, { me });
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: httpCodes.success.OK,
|
||||||
|
contentType: contentTypes.text.html,
|
||||||
|
result,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/ok",
|
path: "/ok",
|
||||||
methods: ["GET", "POST", "PUT"],
|
methods: ["GET", "POST", "PUT"],
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
// services.ts
|
// services.ts
|
||||||
|
|
||||||
import { AuthService, InMemoryAuthStore } from "./auth";
|
import { AuthService, InMemoryAuthStore } from "../auth";
|
||||||
import { config } from "./config";
|
import { config } from "../config";
|
||||||
import { getLogs, log } from "./logging";
|
import { getLogs, log } from "../logging";
|
||||||
|
import { AnonymousUser, anonymousUser, type User } from "../user";
|
||||||
|
|
||||||
//const database = Client({
|
//const database = Client({
|
||||||
|
|
||||||
@@ -27,16 +28,24 @@ const misc = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const session = {
|
||||||
|
getUser: (): User => {
|
||||||
|
return anonymousUser;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize auth with in-memory store
|
// Initialize auth with in-memory store
|
||||||
const authStore = new InMemoryAuthStore();
|
const authStore = new InMemoryAuthStore();
|
||||||
const auth = new AuthService(authStore);
|
const auth = new AuthService(authStore);
|
||||||
|
|
||||||
|
// Keep this asciibetically sorted
|
||||||
const services = {
|
const services = {
|
||||||
|
auth,
|
||||||
database,
|
database,
|
||||||
logging,
|
logging,
|
||||||
misc,
|
misc,
|
||||||
random,
|
random,
|
||||||
auth,
|
session,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { services };
|
export { services };
|
||||||
@@ -181,8 +181,19 @@ export class User {
|
|||||||
toJSON(): UserData {
|
toJSON(): UserData {
|
||||||
return { ...this.data };
|
return { ...this.data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return `User(id ${this.id})`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For representing "no user" in contexts where user is optional
|
// For representing "no user" in contexts where user is optional
|
||||||
export const AnonymousUser = Symbol("AnonymousUser");
|
export const AnonymousUser = Symbol("AnonymousUser");
|
||||||
|
|
||||||
|
export const anonymousUser = User.create("anonymous@example.com", {
|
||||||
|
id: "-1",
|
||||||
|
displayName: "Anonymous User",
|
||||||
|
// FIXME: set createdAt and updatedAt to start of epoch
|
||||||
|
});
|
||||||
|
|
||||||
export type MaybeUser = User | typeof AnonymousUser;
|
export type MaybeUser = User | typeof AnonymousUser;
|
||||||
|
|||||||
Reference in New Issue
Block a user