/* eslint-disable @typescript-eslint/consistent-type-assertions */ import type { Context } from "koa"; import type { FormData } from "@sealcode/sealgen"; import { Form, Controls, fieldsToShape } from "@sealcode/sealgen"; import html from "../html.js"; import { Fields } from "@sealcode/sealgen"; import { hasShape, predicates } from "@sealcode/ts-predicates"; import { AdminURL } from "./urls.js"; export const actionName = "Login"; const fields = { username: new Fields.Text(true), password: new Fields.Text(true), }; export const LoginShape = fieldsToShape(fields); export default new (class LoginForm extends Form { defaultSuccessMessage = "Logged in"; fields = fields; controls = [ new Controls.FormHeader(`Log in`), new Controls.SimpleInput(fields.username, { label: "Username:", type: "text", }), new Controls.SimpleInput(fields.password, { label: "Password:", type: "password", }), ]; // eslint-disable-next-line @typescript-eslint/no-unused-vars async canAccess(_: Context) { return { canAccess: true, message: "" }; } async onSubmit(ctx: Context) { const body = ctx.$body; if ( !hasShape({ username: predicates.string, password: predicates.string }, body) ) { throw new Error("Missing username or password"); } const session_id = await ctx.$app.collections.sessions.login( body.username, body.password ); ctx.cookies.set("sealious-session", session_id, { maxAge: 1000 * 60 * 60 * 24 * 7, secure: ctx.request.protocol === "https", overwrite: true, }); } async onSuccess() { return { action: "redirect", url: AdminURL, messages: [], }; } async render(ctx: Context, data: FormData, show_field_errors: boolean) { return html({ ctx, title: "Form", description: "", body: super.render(ctx, data, show_field_errors) as Promise, }); } })();