1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
import { createSignal } from "solid-js";
import { api } from "../api";
import type { User } from "../types/user";
interface AuthResponse {
token: string;
user: User;
}
interface MessageResponse {
message: string;
}
interface ErrorResponse {
error: string;
}
const [user, setUser] = createSignal<User | null>(null);
const [token, setToken] = createSignal<string | null>(localStorage.getItem("token"));
const [loading, setLoading] = createSignal(true);
async function initialize() {
const stored = token();
if (!stored) {
setLoading(false);
return;
}
try {
const response = await api<User>("/auth/me", { token: stored });
if (response.ok) {
setUser(response.data);
} else {
localStorage.removeItem("token");
setToken(null);
}
} catch {
localStorage.removeItem("token");
setToken(null);
}
setLoading(false);
}
async function login(username: string, password: string): Promise<string | null> {
const response = await api<AuthResponse | ErrorResponse>("/auth/login", {
method: "POST",
body: { username, password },
});
if (response.ok) {
const data = response.data as AuthResponse;
localStorage.setItem("token", data.token);
setToken(data.token);
setUser(data.user);
return null;
}
return (response.data as ErrorResponse).error;
}
async function register(username: string, email: string, password: string, displayName: string): Promise<string | null> {
const response = await api<MessageResponse | ErrorResponse>("/auth/register", {
method: "POST",
body: { username, email, password, display_name: displayName },
});
if (response.ok) return null;
return (response.data as ErrorResponse).error;
}
async function verify(verificationToken: string, type: string): Promise<string | null> {
const response = await api<MessageResponse | ErrorResponse>("/auth/verify", {
method: "POST",
body: { token: verificationToken, type },
});
if (response.ok) return null;
return (response.data as ErrorResponse).error;
}
async function reactivate(email: string): Promise<string | null> {
const response = await api<MessageResponse | ErrorResponse>("/auth/reactivate", {
method: "POST",
body: { email },
});
if (response.ok) return null;
return (response.data as ErrorResponse).error;
}
async function heartbeat() {
const stored = token();
if (stored) {
await api("/auth/heartbeat", { method: "POST", token: stored });
}
}
async function logout() {
const stored = token();
if (stored) {
await api("/auth/logout", { method: "POST", token: stored });
}
localStorage.removeItem("token");
setToken(null);
setUser(null);
}
export const auth = { user, token, loading, initialize, login, register, verify, reactivate, heartbeat, logout };
|