Skip to content

Commit 9c6956d

Browse files
committed
refactor: move ID parsing from routes to validation schemas and add error handling [skip ci]
1 parent 14a02c0 commit 9c6956d

File tree

9 files changed

+493
-386
lines changed

9 files changed

+493
-386
lines changed

apps/leaderboard-backend/src/routes/api/authRoutes.ts

Lines changed: 129 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -20,65 +20,75 @@ export default new Hono()
2020
* POST /auth/challenge
2121
*/
2222
.post("/challenge", AuthChallengeDescription, AuthChallengeValidation, async (c) => {
23-
const { primary_wallet } = c.req.valid("json")
24-
// Use a hardcoded, Ethereum-style message for leaderboard authentication
25-
const message = `\x19Leaderboard Signed Message:\nHappyChain Leaderboard Authentication Request for ${primary_wallet}`
26-
return c.json({
27-
ok: true,
28-
data: {
29-
message,
30-
primary_wallet,
31-
},
32-
})
23+
try {
24+
const { primary_wallet } = c.req.valid("json")
25+
// Use a hardcoded, Ethereum-style message for leaderboard authentication
26+
const message = `\x19Leaderboard Signed Message:\nHappyChain Leaderboard Authentication Request for ${primary_wallet}`
27+
return c.json({
28+
ok: true,
29+
data: {
30+
message,
31+
primary_wallet,
32+
},
33+
})
34+
} catch (err) {
35+
console.error("Error generating auth challenge:", err)
36+
return c.json({ ok: false, error: "Internal Server Error" }, 500)
37+
}
3338
})
3439

3540
/**
3641
* Verify signature and create session
3742
* POST /auth/verify
3843
*/
3944
.post("/verify", AuthVerifyDescription, AuthVerifyValidation, async (c) => {
40-
const { primary_wallet, message, signature } = c.req.valid("json")
41-
const { authRepo, userRepo } = c.get("repos")
42-
43-
// Verify signature directly using the utility function
44-
const isValid = await verifySignature(primary_wallet as Address, message as Hex, signature as Hex)
45-
46-
if (!isValid) {
47-
return c.json({ ok: false, error: "Invalid signature" }, 401)
48-
}
49-
50-
const user = await userRepo.findByWalletAddress(primary_wallet, true)
51-
if (!user) {
52-
return c.json({ ok: false, error: "User not found" }, 404)
53-
}
54-
55-
const session = await authRepo.createSession(user.id, primary_wallet)
56-
if (!session) {
57-
return c.json({ ok: false, error: "Failed to create session" }, 500)
58-
}
59-
60-
setCookie(c, "session_id", session.id, {
61-
httpOnly: true,
62-
secure: true,
63-
domain: "localhost",
64-
sameSite: "Lax",
65-
path: "/",
66-
maxAge: Number.parseInt(env.SESSION_EXPIRY, 10),
67-
})
68-
69-
// Return success with session ID and user info
70-
return c.json({
71-
ok: true,
72-
data: {
73-
session_id: session.id,
74-
user: {
75-
id: user.id,
76-
username: user.username,
77-
primary_wallet: user.primary_wallet,
78-
wallets: user.wallets,
45+
try {
46+
const { primary_wallet, message, signature } = c.req.valid("json")
47+
const { authRepo, userRepo } = c.get("repos")
48+
49+
// Verify signature directly using the utility function
50+
const isValid = await verifySignature(primary_wallet as Address, message as Hex, signature as Hex)
51+
52+
if (!isValid) {
53+
return c.json({ ok: false, error: "Invalid signature" }, 401)
54+
}
55+
56+
const user = await userRepo.findByWalletAddress(primary_wallet, true)
57+
if (!user) {
58+
return c.json({ ok: false, error: "User not found" }, 404)
59+
}
60+
61+
const session = await authRepo.createSession(user.id, primary_wallet)
62+
if (!session) {
63+
return c.json({ ok: false, error: "Failed to create session" }, 500)
64+
}
65+
66+
setCookie(c, "session_id", session.id, {
67+
httpOnly: true,
68+
secure: true,
69+
domain: "localhost",
70+
sameSite: "Lax",
71+
path: "/",
72+
maxAge: Number.parseInt(env.SESSION_EXPIRY, 10),
73+
})
74+
75+
// Return success with session ID and user info
76+
return c.json({
77+
ok: true,
78+
data: {
79+
session_id: session.id,
80+
user: {
81+
id: user.id,
82+
username: user.username,
83+
primary_wallet: user.primary_wallet,
84+
wallets: user.wallets,
85+
},
7986
},
80-
},
81-
})
87+
})
88+
} catch (err) {
89+
console.error("Error verifying auth signature:", err)
90+
return c.json({ ok: false, error: "Internal Server Error" }, 500)
91+
}
8292
})
8393

8494
/**
@@ -87,27 +97,32 @@ export default new Hono()
8797
* @security BearerAuth
8898
*/
8999
.get("/me", AuthMeDescription, requireAuth, async (c) => {
90-
const { userRepo } = c.get("repos")
91-
const userId = c.get("userId")
92-
93-
const user = await userRepo.findById(userId)
94-
95-
if (!user) {
96-
return c.json({ ok: false, error: "User not found" }, 404)
97-
}
98-
99-
return c.json({
100-
ok: true,
101-
data: {
102-
session_id: c.get("sessionId") as string,
103-
user: {
104-
id: user.id,
105-
username: user.username,
106-
primary_wallet: user.primary_wallet,
107-
wallets: user.wallets,
100+
try {
101+
const { userRepo } = c.get("repos")
102+
const userId = c.get("userId")
103+
104+
const user = await userRepo.findById(userId)
105+
106+
if (!user) {
107+
return c.json({ ok: false, error: "User not found" }, 404)
108+
}
109+
110+
return c.json({
111+
ok: true,
112+
data: {
113+
session_id: c.get("sessionId") as string,
114+
user: {
115+
id: user.id,
116+
username: user.username,
117+
primary_wallet: user.primary_wallet,
118+
wallets: user.wallets,
119+
},
108120
},
109-
},
110-
})
121+
})
122+
} catch (err) {
123+
console.error("Error retrieving user session info:", err)
124+
return c.json({ ok: false, error: "Internal Server Error" }, 500)
125+
}
111126
})
112127

113128
/**
@@ -116,28 +131,33 @@ export default new Hono()
116131
* @security BearerAuth
117132
*/
118133
.post("/logout", AuthLogoutDescription, requireAuth, async (c) => {
119-
const sessionId = c.get("sessionId")
120-
const { authRepo } = c.get("repos")
121-
122-
const success = await authRepo.deleteSession(sessionId as AuthSessionTableId)
123-
124-
if (!success) {
125-
return c.json({ ok: false, error: "Failed to delete session" }, 500)
134+
try {
135+
const sessionId = c.get("sessionId")
136+
const { authRepo } = c.get("repos")
137+
138+
const success = await authRepo.deleteSession(sessionId as AuthSessionTableId)
139+
140+
if (!success) {
141+
return c.json({ ok: false, error: "Failed to delete session" }, 500)
142+
}
143+
144+
// Delete the session cookie
145+
deleteCookie(c, "session_id", {
146+
path: "/",
147+
secure: true,
148+
domain: "localhost",
149+
})
150+
151+
return c.json({
152+
ok: true,
153+
data: {
154+
message: "Logged out successfully",
155+
},
156+
})
157+
} catch (err) {
158+
console.error("Error logging out user:", err)
159+
return c.json({ ok: false, error: "Internal Server Error" }, 500)
126160
}
127-
128-
// Delete the session cookie
129-
deleteCookie(c, "session_id", {
130-
path: "/",
131-
secure: true,
132-
domain: "localhost",
133-
})
134-
135-
return c.json({
136-
ok: true,
137-
data: {
138-
message: "Logged out successfully",
139-
},
140-
})
141161
})
142162

143163
/**
@@ -146,16 +166,21 @@ export default new Hono()
146166
* @security BearerAuth
147167
*/
148168
.get("/sessions", AuthSessionsDescription, requireAuth, async (c) => {
149-
const { authRepo } = c.get("repos")
150-
const userId = c.get("userId")
151-
152-
const sessions = await authRepo.getUserSessions(userId)
153-
154-
return c.json({
155-
ok: true,
156-
data: sessions.map((s) => ({
157-
...s,
158-
is_current: s.id === c.get("sessionId"),
159-
})),
160-
})
169+
try {
170+
const { authRepo } = c.get("repos")
171+
const userId = c.get("userId")
172+
173+
const sessions = await authRepo.getUserSessions(userId)
174+
175+
return c.json({
176+
ok: true,
177+
data: sessions.map((s) => ({
178+
...s,
179+
is_current: s.id === c.get("sessionId"),
180+
})),
181+
})
182+
} catch (err) {
183+
console.error("Error retrieving user sessions:", err)
184+
return c.json({ ok: false, error: "Internal Server Error" }, 500)
185+
}
161186
})

apps/leaderboard-backend/src/routes/api/gamesRoutes.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default new Hono()
5656
const { id } = c.req.valid("param")
5757
const { gameRepo } = c.get("repos")
5858

59-
const gameId = Number.parseInt(id, 10) as GameTableId
59+
const gameId = id as GameTableId
6060
const game = await gameRepo.findById(gameId)
6161
if (!game) {
6262
return c.json({ ok: false, error: "Game not found" }, 404)
@@ -153,7 +153,7 @@ export default new Hono()
153153
const { gameRepo } = c.get("repos")
154154

155155
// Check if game exists
156-
const gameId = Number.parseInt(id, 10) as GameTableId
156+
const gameId = id as GameTableId
157157
const game = await gameRepo.findById(gameId)
158158
if (!game) {
159159
return c.json({ ok: false, error: "Game not found" }, 404)
@@ -197,7 +197,7 @@ export default new Hono()
197197
const { gameRepo, userRepo } = c.get("repos")
198198

199199
// Check if game exists
200-
const gameId = Number.parseInt(id, 10) as GameTableId
200+
const gameId = id as GameTableId
201201
const game = await gameRepo.findById(gameId)
202202
if (!game) {
203203
return c.json({ ok: false, error: "Game not found" }, 404)
@@ -233,7 +233,7 @@ export default new Hono()
233233
const { gameRepo } = c.get("repos")
234234

235235
// Check if game exists
236-
const gameId = Number.parseInt(id, 10) as GameTableId
236+
const gameId = id as GameTableId
237237
const game = await gameRepo.findById(gameId)
238238
if (!game) {
239239
return c.json({ ok: false, error: "Game not found" }, 404)
@@ -264,7 +264,7 @@ export default new Hono()
264264
const { gameRepo, userRepo } = c.get("repos")
265265

266266
// Check if game exists
267-
const gameId = Number.parseInt(id, 10) as GameTableId
267+
const gameId = id as GameTableId
268268
const game = await gameRepo.findById(gameId)
269269
if (!game) {
270270
return c.json({ ok: false, error: "Game not found" }, 404)

apps/leaderboard-backend/src/routes/api/guildsRoutes.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export default new Hono()
9393
const { guildRepo } = c.get("repos")
9494
const includeMembers = c.req.query("include_members") === "true"
9595

96-
const guildId = Number.parseInt(id, 10) as GuildTableId
96+
const guildId = id as GuildTableId
9797
const guild = await guildRepo.findById(guildId, includeMembers)
9898
if (!guild) {
9999
return c.json({ ok: false, error: "Guild not found" }, 404)
@@ -127,7 +127,7 @@ export default new Hono()
127127
const { guildRepo } = c.get("repos")
128128

129129
// Check if guild exists
130-
const guildId = Number.parseInt(id, 10) as GuildTableId
130+
const guildId = id as GuildTableId
131131
const guild = await guildRepo.findById(guildId)
132132
if (!guild) {
133133
return c.json({ ok: false, error: "Guild not found" }, 404)
@@ -164,7 +164,7 @@ export default new Hono()
164164
const { guildRepo } = c.get("repos")
165165

166166
// Check if guild exists
167-
const guildId = Number.parseInt(id, 10) as GuildTableId
167+
const guildId = id as GuildTableId
168168
const guild = await guildRepo.findById(guildId)
169169
if (!guild) {
170170
return c.json({ ok: false, error: "Guild not found" }, 404)
@@ -202,7 +202,7 @@ export default new Hono()
202202
const { guildRepo, userRepo } = c.get("repos")
203203

204204
// Ensure guild exists
205-
const guildId = Number.parseInt(id, 10) as GuildTableId
205+
const guildId = id as GuildTableId
206206
const guild = await guildRepo.findById(guildId)
207207
if (!guild) {
208208
return c.json({ ok: false, error: "Guild not found" }, 404)
@@ -267,8 +267,8 @@ export default new Hono()
267267
const { guildRepo } = c.get("repos")
268268

269269
// Check if guild exists
270-
const guildId = Number.parseInt(id, 10) as GuildTableId
271-
const userId = Number.parseInt(member_id, 10) as UserTableId
270+
const guildId = id as GuildTableId
271+
const userId = member_id as UserTableId
272272
const guild = await guildRepo.findById(guildId)
273273
if (!guild) {
274274
return c.json({ ok: false, error: "Guild not found" }, 404)
@@ -314,8 +314,8 @@ export default new Hono()
314314
const { guildRepo } = c.get("repos")
315315

316316
// Check if guild exists
317-
const guildId = Number.parseInt(id, 10) as GuildTableId
318-
const userId = Number.parseInt(member_id, 10) as UserTableId
317+
const guildId = id as GuildTableId
318+
const userId = member_id as UserTableId
319319
const guild = await guildRepo.findById(guildId)
320320
if (!guild) {
321321
return c.json({ ok: false, error: "Guild not found" }, 404)

0 commit comments

Comments
 (0)