aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/app/.server/auth.ts
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-08-01 23:34:59 +0900
committernsfisis <nsfisis@gmail.com>2024-08-01 23:34:59 +0900
commitdb06c9332776b41b3fef537f9e6d76d38f0463b3 (patch)
treeb25c8226efa42be3e631cdf2f047c13c1b807889 /frontend/app/.server/auth.ts
parent6b600ca0ca50c9322a95858bd7d4b6813a7ba2d5 (diff)
parentca4e86c99a935c41b319efea43365221569c7d62 (diff)
downloadiosdc-japan-2024-albatross-db06c9332776b41b3fef537f9e6d76d38f0463b3.tar.gz
iosdc-japan-2024-albatross-db06c9332776b41b3fef537f9e6d76d38f0463b3.tar.zst
iosdc-japan-2024-albatross-db06c9332776b41b3fef537f9e6d76d38f0463b3.zip
Merge branch 'feat/auth'
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",
+ });
}