working auth
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
// lib/auth-client.ts
|
||||
|
||||
const API_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080";
|
||||
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user