75 lines
2 KiB
TypeScript
75 lines
2 KiB
TypeScript
import { authStrings } from "./strings";
|
|
|
|
export interface AuthActionResult {
|
|
ok: boolean;
|
|
twoFactor?: boolean;
|
|
challenge?: string;
|
|
error?: string;
|
|
}
|
|
|
|
// Mirrors AuthError.userMessage in ios/Mercury/Features/Auth/AuthRepository.swift,
|
|
// keyed by the `{error:{code,message}}` envelope the Go backend writes
|
|
// (internal/transport/api/respond.go, auth_handlers.go, twofa_handlers.go).
|
|
const ERROR_MESSAGE_BY_CODE: Record<string, string> = {
|
|
invalid_credentials: authStrings.errors.invalidCredentials,
|
|
email_taken: authStrings.errors.emailTaken,
|
|
invalid_code: authStrings.errors.invalidCode,
|
|
invalid_challenge: authStrings.errors.invalidCode,
|
|
};
|
|
|
|
function messageForCode(code: string | undefined): string {
|
|
if (code && ERROR_MESSAGE_BY_CODE[code]) return ERROR_MESSAGE_BY_CODE[code];
|
|
return authStrings.errors.unknown;
|
|
}
|
|
|
|
async function postAuth(
|
|
path: "login" | "register" | "forgot" | "2fa",
|
|
body: unknown,
|
|
): Promise<AuthActionResult> {
|
|
let res: Response;
|
|
try {
|
|
res = await fetch(`/api/auth/${path}`, {
|
|
method: "POST",
|
|
credentials: "same-origin",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(body),
|
|
});
|
|
} catch {
|
|
return { ok: false, error: authStrings.errors.network };
|
|
}
|
|
|
|
const data = await res.json().catch(() => ({}));
|
|
|
|
if (!res.ok) {
|
|
return { ok: false, error: messageForCode(data?.error?.code) };
|
|
}
|
|
if (data?.twoFactor) {
|
|
return { ok: false, twoFactor: true, challenge: data.challenge };
|
|
}
|
|
return { ok: true };
|
|
}
|
|
|
|
export function submitLogin(
|
|
email: string,
|
|
password: string,
|
|
): Promise<AuthActionResult> {
|
|
return postAuth("login", { email, password });
|
|
}
|
|
|
|
export function submitRegister(
|
|
email: string,
|
|
password: string,
|
|
): Promise<AuthActionResult> {
|
|
return postAuth("register", { email, password });
|
|
}
|
|
|
|
export function submit2FA(
|
|
challenge: string,
|
|
code: string,
|
|
): Promise<AuthActionResult> {
|
|
return postAuth("2fa", { challenge, code });
|
|
}
|
|
|
|
export function submitForgot(email: string): Promise<AuthActionResult> {
|
|
return postAuth("forgot", { email });
|
|
}
|