source: src/lib/auth.ts@ 90f7842

Last change on this file since 90f7842 was 90f7842, checked in by Stefan-Saveski <stefansaveski19@…>, 9 months ago

fix: Update API endpoints to use production URL for user data retrieval and authentication

  • Property mode set to 100644
File size: 3.0 KB
RevLine 
[b67f274]1export type AuthTokens = {
2 accessToken: string;
3 refreshToken: string;
4};
5
6type StoredToken = {
7 value: string;
8 expiresAt: number; // epoch ms
9};
10
11const STORAGE_KEYS = {
12 access: 'iknow.auth.access',
13 refresh: 'iknow.auth.refresh',
14} as const;
15
16const ACCESS_TOKEN_TTL_MS = 60 * 60 * 1000; // 1 hour
17const REFRESH_TOKEN_TTL_MS = 30 * 24 * 60 * 60 * 1000; // ~1 month (30 days)
18
19function isBrowser() {
20 return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
21}
22
23function readStoredToken(key: string): StoredToken | null {
24 if (!isBrowser()) return null;
25 const raw = window.localStorage.getItem(key);
26 if (!raw) return null;
27
28 try {
29 const parsed = JSON.parse(raw) as StoredToken;
30 if (!parsed?.value || typeof parsed.expiresAt !== 'number') {
31 window.localStorage.removeItem(key);
32 return null;
33 }
34
35 if (Date.now() >= parsed.expiresAt) {
36 window.localStorage.removeItem(key);
37 return null;
38 }
39
40 return parsed;
41 } catch {
42 window.localStorage.removeItem(key);
43 return null;
44 }
45}
46
47function writeStoredToken(key: string, value: string, ttlMs: number) {
48 if (!isBrowser()) return;
49 const payload: StoredToken = {
50 value,
51 expiresAt: Date.now() + ttlMs,
52 };
53 window.localStorage.setItem(key, JSON.stringify(payload));
54}
55
56export function setAuthTokens(tokens: AuthTokens) {
57 writeStoredToken(STORAGE_KEYS.access, tokens.accessToken, ACCESS_TOKEN_TTL_MS);
58 writeStoredToken(STORAGE_KEYS.refresh, tokens.refreshToken, REFRESH_TOKEN_TTL_MS);
59}
60
61export function getAccessToken(): string | null {
62 return readStoredToken(STORAGE_KEYS.access)?.value ?? null;
63}
64
65export function getRefreshToken(): string | null {
66 return readStoredToken(STORAGE_KEYS.refresh)?.value ?? null;
67}
68
69export function clearAuthTokens() {
70 if (!isBrowser()) return;
71 window.localStorage.removeItem(STORAGE_KEYS.access);
72 window.localStorage.removeItem(STORAGE_KEYS.refresh);
73}
74
75export async function login(params: { email: string; password: string }) {
[90f7842]76 const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL ?? 'https://iknow-api.onrender.com';
[b67f274]77
78 const response = await fetch(`${baseUrl}/api/auth/login`, {
79 method: 'POST',
80 headers: {
81 'Content-Type': 'application/json',
82 },
83 body: JSON.stringify({
84 email: params.email,
85 password: params.password,
86 GenerateRefreshToken: true,
87 }),
88 });
89
90 if (!response.ok) {
91 let message = `Login failed (${response.status})`;
92 try {
93 const text = await response.text();
94 if (text) message = text;
95 } catch {
96 // ignore
97 }
98 throw new Error(message);
99 }
100
101 const data = (await response.json()) as {
102 token?: { accessToken?: string; refreshToken?: string };
103 };
104
105 const accessToken = data?.token?.accessToken;
106 const refreshToken = data?.token?.refreshToken;
107
108 if (!accessToken || !refreshToken) {
109 throw new Error('Login response did not contain tokens.');
110 }
111
112 const tokens: AuthTokens = { accessToken, refreshToken };
113 setAuthTokens(tokens);
114 return tokens;
115}
Note: See TracBrowser for help on using the repository browser.