simple-fs-server/routes/login.tsx

96 lines
2.7 KiB
TypeScript

import { Head, asset } from "$fresh/runtime.ts";
import { HandlerContext, PageProps } from "$fresh/server.ts";
import { setCookie } from "http/cookie.ts";
import { Status } from "http/http_status.ts";
import { connectDB } from "../src/user/db.ts";
import { getUser, verifyUser } from "../src/user/user.ts";
import { create as createJWT } from "djwt";
import { prepareSecretKey } from "../util/secret.ts";
import LoginForm from "../islands/Login.tsx";
async function GET(_req: Request, ctx: HandlerContext) {
return await ctx.render();
}
async function POST(req: Request, _ctx: HandlerContext): Promise<Response> {
const url = new URL(req.url);
const form = await req.formData();
const username = form.get("username");
const password = form.get("password");
if (username && password) {
const DB = await connectDB();
const user = await getUser(DB, username.toString());
if (user) {
const SECRET_KEY = await prepareSecretKey();
if (await verifyUser(user, password.toString())) {
const headers = new Headers();
const jwt = await createJWT({ alg: "HS512", typ: "JWT" }, {
username: user.name,
}, SECRET_KEY);
setCookie(headers, {
name: "auth",
value: jwt,
httpOnly: true,
sameSite: "Strict",
maxAge: 60 * 60 * 24 * 7,
domain: url.hostname,
path: "/",
secure: url.protocol === "https:",
});
let redirect = "/";
if (url.searchParams.has("redirect")) {
redirect = url.searchParams.get("redirect")!;
}
headers.set("Location", redirect);
return new Response(null, {
status: Status.SeeOther, // See Other
headers: headers,
});
}
}
}
return new Response(
`<!DOCTYPE html><html>
<head> <title> Login Failed </title> </head>
<body>
<h1> Login Failed </h1>
<p> <a href="/"> Back to Home </a> </p>
<script>
document.location.href = "/login?failed=true&redirect=${
url.searchParams.get("redirect")
}";
</script>
</body>
</html>`,
{
headers: {
"Content-Type": "text/html",
},
status: Status.Unauthorized,
},
);
}
export const handler = {
GET,
POST,
};
export default function Login(props: PageProps) {
const redirect = props.url.searchParams.get("redirect");
const failed = props.url.searchParams.get("failed") === "true";
return (
<>
<Head>
<title>Simple file server - Login</title>
<link rel="stylesheet" href={asset("/base.css")} />
</Head>
<div class="">
<LoginForm redirect={redirect ?? "/"} failed={failed} />
</div>
</>
);
}