source: frontend/src/lib/api.js@ 2e0035f

Last change on this file since 2e0035f was 2e0035f, checked in by Acko <lavurovski.a65@…>, 8 days ago

Initial Commit

  • Property mode set to 100644
File size: 1.7 KB
Line 
1// Thin wrapper over fetch: attaches the JWT, unwraps JSON, surfaces the
2// backend's error message instead of a bare "500".
3
4const TOKEN_KEY = 'nutritioneer.token'
5const USER_KEY = 'nutritioneer.user'
6
7export const auth = {
8 token: () => localStorage.getItem(TOKEN_KEY),
9 user: () => {
10 const raw = localStorage.getItem(USER_KEY)
11 return raw ? JSON.parse(raw) : null
12 },
13 save: (res) => {
14 localStorage.setItem(TOKEN_KEY, res.token)
15 localStorage.setItem(USER_KEY, JSON.stringify({
16 email: res.email, username: res.username, role: res.role
17 }))
18 },
19 clear: () => {
20 localStorage.removeItem(TOKEN_KEY)
21 localStorage.removeItem(USER_KEY)
22 }
23}
24
25async function request(method, path, body) {
26 const headers = { 'Content-Type': 'application/json' }
27 const token = auth.token()
28 if (token) headers.Authorization = `Bearer ${token}`
29
30 const res = await fetch(`/api${path}`, {
31 method,
32 headers,
33 body: body === undefined ? undefined : JSON.stringify(body)
34 })
35
36 if (res.status === 204) return null
37
38 const text = await res.text()
39 const data = text ? JSON.parse(text) : null
40
41 if (res.status === 401) {
42 // A 401 while signing in means the credentials were rejected. Only treat
43 // it as an expired session if we actually sent a token.
44 if (token) {
45 auth.clear()
46 throw new Error(data?.message || 'Session expired, please sign in again')
47 }
48 throw new Error(data?.message || 'Invalid email or password')
49 }
50
51 if (!res.ok) throw new Error(data?.message || `Request failed (${res.status})`)
52 return data
53}
54
55export const api = {
56 get: (p) => request('GET', p),
57 post: (p, b) => request('POST', p, b),
58 patch: (p, b) => request('PATCH', p, b),
59 del: (p) => request('DELETE', p)
60}
Note: See TracBrowser for help on using the repository browser.