Files
diachron/express/basic/login.ts
Michael Wolf 1c1eeddcbe Add basic login screen with form-based authentication
Adds /login route with HTML template that handles GET (show form) and
POST (authenticate). On successful login, sets session cookie and
redirects to /. Also adds framework support for redirects and cookies
in route handlers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:07:02 -06:00

63 lines
1.6 KiB
TypeScript

import { SESSION_COOKIE_NAME } from "../auth/token";
import { tokenLifetimes } from "../auth/types";
import { services } from "../services";
import type { Call, Result, Route } from "../types";
import { html, redirect, render } from "../util";
const loginHandler = async (call: Call): Promise<Result> => {
if (call.method === "GET") {
const c = await render("basic/login", {});
return html(c);
}
// POST - handle login
const { email, password } = call.request.body;
if (!email || !password) {
const c = await render("basic/login", {
error: "Email and password are required",
email,
});
return html(c);
}
const result = await services.auth.login(email, password, "cookie", {
userAgent: call.request.get("User-Agent"),
ipAddress: call.request.ip,
});
if (!result.success) {
const c = await render("basic/login", {
error: result.error,
email,
});
return html(c);
}
// Success - set cookie and redirect to home
const redirectResult = redirect("/");
redirectResult.cookies = [
{
name: SESSION_COOKIE_NAME,
value: result.token,
options: {
httpOnly: true,
secure: false, // Set to true in production with HTTPS
sameSite: "lax",
maxAge: tokenLifetimes.session,
path: "/",
},
},
];
return redirectResult;
};
const loginRoute: Route = {
path: "/login",
methods: ["GET", "POST"],
handler: loginHandler,
};
export { loginRoute };