import { atom } from "jotai"; import { APIClient } from "./ApiClient"; export enum CreateAccountResult { TooManyRequests, BadInputData, MailAlreadyExists, Success, Error, } export enum PasswordLoginResult { TooManyRequests, InvalidCredentials, Success, Error, } export interface CheckResetTokenResponse { name: string; } const TokenStateKey = "auth-token"; export class AuthApi { /** * Check out whether user is signed in or not */ static get SignedIn(): boolean { return sessionStorage.getItem(TokenStateKey) !== null; } static authStatus = atom(this.SignedIn); /** * Get user auth token */ static get AuthToken(): string { if (!this.SignedIn) throw new Error("User is not authenticated!"); return sessionStorage.getItem(TokenStateKey)!; } /** * Create a new account */ static async CreateAccount( name: string, mail: string ): Promise { const res = await APIClient.exec({ uri: "/auth/create_account", method: "POST", allowFail: true, jsonData: { name: name, email: mail, }, }); switch (res.status) { case 429: return CreateAccountResult.TooManyRequests; case 400: return CreateAccountResult.BadInputData; case 409: return CreateAccountResult.MailAlreadyExists; case 200: case 201: return CreateAccountResult.Success; default: return CreateAccountResult.Error; } } /** * Authenticate using an email and a password * * @param mail The email address to use * @param password The password to use */ static async LoginWithPassword( mail: string, password: string ): Promise { const res = await APIClient.exec({ uri: "/auth/password_login", method: "POST", allowFail: true, jsonData: { mail: mail, password: password, }, }); switch (res.status) { case 429: return PasswordLoginResult.TooManyRequests; case 401: return PasswordLoginResult.InvalidCredentials; case 200: case 201: sessionStorage.setItem(TokenStateKey, res.data.token); return PasswordLoginResult.Success; default: return PasswordLoginResult.Error; } } /** * Start OpenID login * * @param id The ID of the OIDC provider to use */ static async StartOpenIDLogin(id: string): Promise<{ url: string }> { return ( await APIClient.exec({ uri: "/auth/start_openid_login", method: "POST", jsonData: { provider: id }, }) ).data; } /** * Finish OpenID login */ static async FinishOpenIDLogin(code: string, state: string): Promise { const res: { user_id: number; token: string } = ( await APIClient.exec({ uri: "/auth/finish_openid_login", method: "POST", jsonData: { code: code, state: state }, }) ).data; sessionStorage.setItem(TokenStateKey, res.token); } /** * Sign out */ static async SignOut(): Promise { await APIClient.exec({ uri: "/auth/logout", method: "GET", }); sessionStorage.removeItem(TokenStateKey); } /** * Request to reset password */ static async RequestResetPassword(mail: string): Promise { await APIClient.exec({ uri: "/auth/request_reset_password", method: "POST", jsonData: { mail: mail }, }); } /** * Check reset password token */ static async CheckResetPasswordToken( token: string ): Promise { return ( await APIClient.exec({ uri: "/auth/check_reset_password_token", method: "POST", jsonData: { token: token }, }) ).data; } /** * Reset password */ static async ResetPassword( token: string, newPassword: string ): Promise { await APIClient.exec({ uri: "/auth/reset_password", method: "POST", jsonData: { token: token, password: newPassword }, }); } }