aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/.server/auth.ts
blob: a4811e2fd6f245aa07d68aa558d03585d774659b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import type { Session } from "@remix-run/server-runtime";
import { jwtDecode } from "jwt-decode";
import { Authenticator } from "remix-auth";
import { FormStrategy } from "remix-auth-form";
import { apiPostLogin } from "./api/client";
import { components } from "./api/schema";
import { sessionStorage } from "./session";

const authenticator = new Authenticator<string>(sessionStorage);

authenticator.use(
	new FormStrategy(async ({ form }) => {
		const username = String(form.get("username"));
		const password = String(form.get("password"));
		return (await apiPostLogin(username, password)).token;
	}),
	"default",
);

export type User = components["schemas"]["User"];

export async function login(request: Request): Promise<never> {
	return await authenticator.authenticate("default", request, {
		successRedirect: "/dashboard",
		failureRedirect: "/login",
	});
}

export async function logout(request: Request | Session): Promise<never> {
	return await authenticator.logout(request, { redirectTo: "/" });
}

export async function ensureUserLoggedIn(
	request: Request | Session,
): Promise<{ user: User; token: string }> {
	const token = await authenticator.isAuthenticated(request, {
		failureRedirect: "/login",
	});
	const user = jwtDecode<User>(token);
	return { user, token };
}

export async function ensureAdminUserLoggedIn(
	request: Request | Session,
): Promise<{ user: User; token: string }> {
	const { user, token } = await ensureUserLoggedIn(request);
	if (!user.is_admin) {
		throw new Error("Forbidden");
	}
	return { user, token };
}

export async function ensureUserNotLoggedIn(
	request: Request | Session,
): Promise<null> {
	return await authenticator.isAuthenticated(request, {
		successRedirect: "/dashboard",
	});
}