Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesPull RequestsActionsSecurityInsightsSettings
✨ AI
More
Blame · Line-by-line history

auth.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

auth.tsBlame68 lines · 1 contributor
5c83cccClaude1import { fetchJSON, saveToken, removeToken, PAT_STORE_KEY } from './client';
2import * as SecureStore from 'expo-secure-store';
3import { useSettingsStore } from '../store/settingsStore';
4import type { AuthUser } from '../store/authStore';
5
6export interface MeResponse {
7 id: number;
8 username: string;
9 email: string;
10 avatarUrl: string | null;
11 bio: string | null;
12 createdAt: string;
13}
14
15/**
16 * Validates a PAT token against the given host by calling GET /api/users/me.
17 * The host is temporarily set in the settings store before the call.
18 * Returns the user profile on success; throws ApiError on failure.
19 */
20export async function validateToken(host: string, token: string): Promise<AuthUser> {
21 // Temporarily point the store at the target host so client.ts builds the
22 // correct URL. The final host is persisted by the caller (useAuth hook).
23 useSettingsStore.getState().setHost(host);
24
25 // Provide the token inline since it is not yet saved to SecureStore.
26 const response = await fetch(`${host.replace(/\/$/, '')}/api/users/me`, {
27 headers: {
28 Authorization: `Bearer ${token}`,
29 Accept: 'application/json',
30 },
31 });
32
33 if (!response.ok) {
34 let msg = `HTTP ${response.status}`;
35 try {
36 const body = (await response.json()) as Record<string, unknown>;
37 if (typeof body.error === 'string') msg = body.error;
38 } catch {
39 // ignore parse failures
40 }
41 throw new Error(msg);
42 }
43
44 const data = (await response.json()) as MeResponse;
45 return {
46 id: data.id,
47 username: data.username,
48 email: data.email,
49 avatarUrl: data.avatarUrl ?? null,
50 bio: data.bio ?? null,
51 createdAt: data.createdAt,
52 };
53}
54
55/** Persists the token to SecureStore. */
56export async function persistToken(token: string): Promise<void> {
57 await saveToken(token);
58}
59
60/** Removes the saved token from SecureStore. */
61export async function clearToken(): Promise<void> {
62 await removeToken();
63}
64
65/** Retrieves the current user profile from the API. */
66export async function fetchMe(): Promise<AuthUser> {
67 return fetchJSON<AuthUser>('/api/users/me');
68}