File size: 1,414 Bytes
2bcdd5f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import express from "express";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import crypto from "crypto";
import { User } from "../models/User.js";
import { loginLimiter } from "../middleware/rateLimit.js";
import { JWT_CONFIG, PASSWORD_POLICY } from "../config/security.js";

const r = express.Router();

r.post("/register", async (req, res) => {
  if (!req.body.password || req.body.password.length < PASSWORD_POLICY.minLength)
    return res.status(400).json({ error: "Weak password" });

  const hash = await bcrypt.hash(req.body.password, 10);
  await User.create({ email: req.body.email, passwordHash: hash });
  res.json({ ok: true });
});

r.post("/login", loginLimiter, async (req, res) => {
  const user = await User.findOne({ email: req.body.email });
  if (!user) return res.sendStatus(401);

  const ok = await bcrypt.compare(req.body.password, user.passwordHash);
  await new Promise((r) => setTimeout(r, 500));
  if (!ok) return res.sendStatus(401);

  const accessToken = jwt.sign(
    { id: user.id, role: user.role },
    process.env.JWT_SECRET,
    { expiresIn: "15m", ...JWT_CONFIG }
  );

  const refresh = crypto.randomBytes(64).toString("hex");
  user.refreshTokens.push({
    hash: await bcrypt.hash(refresh, 10),
    ip: req.ip,
    userAgent: req.headers["user-agent"],
  });
  await user.save();

  res.json({ accessToken, refreshToken: refresh });
});

export default r;