This commit is contained in:
Jason Ross
2026-03-31 21:28:12 -05:00
parent 350e43bbfb
commit e34fdde7d6
15 changed files with 170 additions and 49 deletions
+13
View File
@@ -0,0 +1,13 @@
node_modules/
dist/
.turbo/
.env
.env.*
secrets.env
*.db
*.db-*
*.sqlite
*.sqlite*
data/
coverage/
.DS_Store
+7
View File
@@ -5,6 +5,13 @@
"type": "module",
"license": "AGPL-3.0-only",
"packageManager": "pnpm@10.6.3",
"pnpm": {
"onlyBuiltDependencies": [
"argon2",
"better-sqlite3",
"esbuild"
]
},
"engines": {
"node": ">=22"
},
+12 -1
View File
@@ -1,16 +1,27 @@
import { existsSync, mkdirSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import Database from "better-sqlite3";
import type { AdminUserRecord, InviteRecord } from "./types.js";
// Keep local development aligned with the compose-mounted ./data directory.
const workspaceSqlitePath = resolve(
dirname(fileURLToPath(import.meta.url)),
"..",
"..",
"..",
"data",
"admin.db"
);
function resolveSqlitePath(): string {
if (existsSync("/data")) {
return "/data/admin.db";
}
return resolve(process.cwd(), "data", "admin.db");
return workspaceSqlitePath;
}
export const sqlitePath = resolveSqlitePath();
+1
View File
@@ -20,6 +20,7 @@ async function main(): Promise<void> {
await connectMongo();
const app = express();
app.set("trust proxy", 1);
app.use(
helmet({
+10 -4
View File
@@ -7,6 +7,14 @@ import { sqlite } from "../db/sqlite.js";
const SQLiteStore = connectSqlite3(session);
export const SESSION_COOKIE_NAME = "stoat-admin.sid";
const SESSION_COOKIE_SECURE =
new URL(env.ADMIN_WEB_ORIGIN).protocol === "https:";
export const SESSION_COOKIE_OPTIONS = {
path: "/",
httpOnly: true,
sameSite: "strict",
secure: SESSION_COOKIE_SECURE
} as const;
export const sessionMiddleware = session({
name: SESSION_COOKIE_NAME,
@@ -21,10 +29,8 @@ export const sessionMiddleware = session({
}
}),
cookie: {
maxAge: 2 * 60 * 60 * 1000,
httpOnly: true,
sameSite: "strict",
secure: false
...SESSION_COOKIE_OPTIONS,
maxAge: 2 * 60 * 60 * 1000
}
});
+6 -2
View File
@@ -4,7 +4,11 @@ import { z } from "zod";
import { statements } from "../db/sqlite.js";
import { asyncHandler } from "../lib/async-handler.js";
import { requireAuth, SESSION_COOKIE_NAME } from "../middleware/auth.js";
import {
requireAuth,
SESSION_COOKIE_NAME,
SESSION_COOKIE_OPTIONS
} from "../middleware/auth.js";
const loginSchema = z.object({
username: z.string().min(1),
@@ -56,7 +60,7 @@ authRouter.post(
});
});
res.clearCookie(SESSION_COOKIE_NAME);
res.clearCookie(SESSION_COOKIE_NAME, SESSION_COOKIE_OPTIONS);
res.status(200).json({ success: true });
})
);
+4
View File
@@ -32,7 +32,11 @@ async function promptForMissing(
}
async function main(): Promise<void> {
const rawArgs = process.argv.slice(2);
const normalizedArgs = rawArgs[0] === "--" ? rawArgs.slice(1) : rawArgs;
const parsed = parseArgs({
args: normalizedArgs,
options: {
username: {
type: "string"