aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/.server/auth.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/app/.server/auth.ts')
-rw-r--r--frontend/app/.server/auth.ts124
1 files changed, 35 insertions, 89 deletions
diff --git a/frontend/app/.server/auth.ts b/frontend/app/.server/auth.ts
index 0c7742a..a4811e2 100644
--- a/frontend/app/.server/auth.ts
+++ b/frontend/app/.server/auth.ts
@@ -6,108 +6,54 @@ import { apiPostLogin } from "./api/client";
import { components } from "./api/schema";
import { sessionStorage } from "./session";
-export const authenticator = new Authenticator<string>(sessionStorage);
-
-async function login(username: string, password: string): Promise<string> {
- return (await apiPostLogin(username, password)).token;
-}
+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 login(username, password);
+ return (await apiPostLogin(username, password)).token;
}),
"default",
);
export type User = components["schemas"]["User"];
-export async function isAuthenticated(
- request: Request | Session,
- options?: {
- successRedirect?: never;
- failureRedirect?: never;
- headers?: never;
- },
-): Promise<{ user: User; token: string } | null>;
-export async function isAuthenticated(
- request: Request | Session,
- options: {
- successRedirect: string;
- failureRedirect?: never;
- headers?: HeadersInit;
- },
-): Promise<null>;
-export async function isAuthenticated(
- request: Request | Session,
- options: {
- successRedirect?: never;
- failureRedirect: string;
- headers?: HeadersInit;
- },
-): Promise<{ user: User; token: string }>;
-export async function isAuthenticated(
+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,
- options: {
- successRedirect: string;
- failureRedirect: string;
- headers?: HeadersInit;
- },
-): Promise<null>;
-export async function isAuthenticated(
+): 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,
- options:
- | {
- successRedirect?: never;
- failureRedirect?: never;
- headers?: never;
- }
- | {
- successRedirect: string;
- failureRedirect?: never;
- headers?: HeadersInit;
- }
- | {
- successRedirect?: never;
- failureRedirect: string;
- headers?: HeadersInit;
- }
- | {
- successRedirect: string;
- failureRedirect: string;
- headers?: HeadersInit;
- } = {},
-): Promise<{ user: User; token: string } | null> {
- // This function's signature should be compatible with `authenticator.isAuthenticated` but TypeScript does not infer it correctly.
- let jwt;
- const { successRedirect, failureRedirect, headers } = options;
- if (successRedirect && failureRedirect) {
- jwt = await authenticator.isAuthenticated(request, {
- successRedirect,
- failureRedirect,
- headers,
- });
- } else if (!successRedirect && failureRedirect) {
- jwt = await authenticator.isAuthenticated(request, {
- failureRedirect,
- headers,
- });
- } else if (successRedirect && !failureRedirect) {
- jwt = await authenticator.isAuthenticated(request, {
- successRedirect,
- headers,
- });
- } else {
- jwt = await authenticator.isAuthenticated(request);
+): Promise<{ user: User; token: string }> {
+ const { user, token } = await ensureUserLoggedIn(request);
+ if (!user.is_admin) {
+ throw new Error("Forbidden");
}
+ return { user, token };
+}
- if (!jwt) {
- return null;
- }
- const user = jwtDecode<User>(jwt);
- return {
- user,
- token: jwt,
- };
+export async function ensureUserNotLoggedIn(
+ request: Request | Session,
+): Promise<null> {
+ return await authenticator.isAuthenticated(request, {
+ successRedirect: "/dashboard",
+ });
}