44 lines
1.1 KiB
TypeScript
44 lines
1.1 KiB
TypeScript
|
|
const AUTH_API_BASE = '/api/v1';
|
||
|
|
|
||
|
|
export interface TokenResponse {
|
||
|
|
access_token: string;
|
||
|
|
token_type: string;
|
||
|
|
expires_in: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface MeResponse {
|
||
|
|
user_id: string;
|
||
|
|
username: string;
|
||
|
|
role: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function loginRequest(
|
||
|
|
username: string,
|
||
|
|
password: string,
|
||
|
|
): Promise<TokenResponse> {
|
||
|
|
const body = new URLSearchParams();
|
||
|
|
body.set('username', username);
|
||
|
|
body.set('password', password);
|
||
|
|
|
||
|
|
const res = await fetch(`${AUTH_API_BASE}/auth/token`, {
|
||
|
|
method: 'POST',
|
||
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
|
|
body: body.toString(),
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!res.ok) {
|
||
|
|
const payload = await res.json().catch(() => ({})) as { detail?: string };
|
||
|
|
throw new Error(payload.detail ?? `Login failed (${res.status})`);
|
||
|
|
}
|
||
|
|
|
||
|
|
return res.json() as Promise<TokenResponse>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getMeRequest(token: string): Promise<MeResponse> {
|
||
|
|
const res = await fetch(`${AUTH_API_BASE}/auth/me`, {
|
||
|
|
headers: { Authorization: `Bearer ${token}` },
|
||
|
|
});
|
||
|
|
if (!res.ok) throw new Error(`Unauthorised (${res.status})`);
|
||
|
|
return res.json() as Promise<MeResponse>;
|
||
|
|
}
|