(req: http.IncomingMessage, res: http.ServerResponse)
| 424 | // ─── Auth endpoints ─── |
| 425 | |
| 426 | private handleSetup(req: http.IncomingMessage, res: http.ServerResponse): void { |
| 427 | if (!this.needsSetup) { |
| 428 | res.writeHead(400, { "Content-Type": "application/json" }); |
| 429 | res.end(JSON.stringify({ error: "Password already set" })); |
| 430 | return; |
| 431 | } |
| 432 | this.readBody(req, (body) => { |
| 433 | try { |
| 434 | const { password } = JSON.parse(body); |
| 435 | if (!password || password.length < 4) { |
| 436 | res.writeHead(400, { "Content-Type": "application/json" }); |
| 437 | res.end(JSON.stringify({ error: "Password must be at least 4 characters" })); |
| 438 | return; |
| 439 | } |
| 440 | this.auth.passwordHash = this.hashPassword(password); |
| 441 | this.saveAuth(); |
| 442 | const token = this.createSession(); |
| 443 | res.writeHead(200, { |
| 444 | "Content-Type": "application/json", |
| 445 | "Set-Cookie": `${this.cookieName}=${token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400`, |
| 446 | }); |
| 447 | res.end(JSON.stringify({ ok: true, message: "Password set successfully" })); |
| 448 | } catch (err) { |
| 449 | res.writeHead(400, { "Content-Type": "application/json" }); |
| 450 | res.end(JSON.stringify({ error: String(err) })); |
| 451 | } |
| 452 | }); |
| 453 | } |
| 454 | |
| 455 | private handleLogin(req: http.IncomingMessage, res: http.ServerResponse): void { |
| 456 | this.readBody(req, (body) => { |
no test coverage detected