Files
2026-01-23 21:40:16 -05:00

116 lines
2.7 KiB
TypeScript

// lib/auth-client.ts
const API_BASE_URL =
process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
export type AuthUser = {
id: number;
email: string;
displayName?: string | null;
role: string;
};
export type AuthPayload = {
accessToken: string;
refreshToken?: string;
userId: number;
email: string;
displayName?: string | null;
role: string;
};
export type RegisterInput = {
email: string;
password: string;
displayName?: string;
};
export type LoginInput = {
email: string;
password: string;
};
const AUTH_STORAGE_KEY = "armory-auth";
export function storeAuth(payload: AuthPayload) {
if (typeof window === "undefined") return;
const user: AuthUser = {
id: payload.userId,
email: payload.email,
displayName: payload.displayName,
role: payload.role,
};
const toStore = {
user,
accessToken: payload.accessToken,
refreshToken: payload.refreshToken ?? null,
};
window.localStorage.setItem(AUTH_STORAGE_KEY, JSON.stringify(toStore));
}
export function loadStoredAuth():
| { user: AuthUser; accessToken: string; refreshToken: string | null }
| null {
if (typeof window === "undefined") return null;
try {
const raw = window.localStorage.getItem(AUTH_STORAGE_KEY);
if (!raw) return null;
const parsed = JSON.parse(raw);
if (!parsed.user || !parsed.accessToken) return null;
return {
user: parsed.user as AuthUser,
accessToken: parsed.accessToken as string,
refreshToken: parsed.refreshToken ?? null,
};
} catch {
return null;
}
}
export function clearStoredAuth() {
if (typeof window === "undefined") return;
window.localStorage.removeItem(AUTH_STORAGE_KEY);
}
async function handleAuthResponse(res: Response): Promise<AuthPayload> {
if (!res.ok) {
let message = `Request failed (${res.status})`;
try {
const body = await res.json();
if (body?.message) message = body.message;
} catch {
// ignore
}
throw new Error(message);
}
return (await res.json()) as AuthPayload;
}
export async function apiRegister(input: RegisterInput): Promise<AuthPayload> {
const res = await fetch(`${API_BASE_URL}/api/auth/register`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(input),
});
return handleAuthResponse(res);
}
export async function apiLogin(input: LoginInput): Promise<AuthPayload> {
const res = await fetch(`${API_BASE_URL}/api/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(input),
});
return handleAuthResponse(res);
}