diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-08-01 23:34:59 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-08-01 23:34:59 +0900 |
| commit | db06c9332776b41b3fef537f9e6d76d38f0463b3 (patch) | |
| tree | b25c8226efa42be3e631cdf2f047c13c1b807889 /frontend/app/.server/auth.ts | |
| parent | 6b600ca0ca50c9322a95858bd7d4b6813a7ba2d5 (diff) | |
| parent | ca4e86c99a935c41b319efea43365221569c7d62 (diff) | |
| download | iosdc-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.ts | 124 |
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", + }); } |
