Create src/routes/auth.js
Browse files- src/routes/auth.js +45 -0
src/routes/auth.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import express from "express";
|
| 2 |
+
import bcrypt from "bcrypt";
|
| 3 |
+
import jwt from "jsonwebtoken";
|
| 4 |
+
import crypto from "crypto";
|
| 5 |
+
import { User } from "../models/User.js";
|
| 6 |
+
import { loginLimiter } from "../middleware/rateLimit.js";
|
| 7 |
+
import { JWT_CONFIG, PASSWORD_POLICY } from "../config/security.js";
|
| 8 |
+
|
| 9 |
+
const r = express.Router();
|
| 10 |
+
|
| 11 |
+
r.post("/register", async (req, res) => {
|
| 12 |
+
if (!req.body.password || req.body.password.length < PASSWORD_POLICY.minLength)
|
| 13 |
+
return res.status(400).json({ error: "Weak password" });
|
| 14 |
+
|
| 15 |
+
const hash = await bcrypt.hash(req.body.password, 10);
|
| 16 |
+
await User.create({ email: req.body.email, passwordHash: hash });
|
| 17 |
+
res.json({ ok: true });
|
| 18 |
+
});
|
| 19 |
+
|
| 20 |
+
r.post("/login", loginLimiter, async (req, res) => {
|
| 21 |
+
const user = await User.findOne({ email: req.body.email });
|
| 22 |
+
if (!user) return res.sendStatus(401);
|
| 23 |
+
|
| 24 |
+
const ok = await bcrypt.compare(req.body.password, user.passwordHash);
|
| 25 |
+
await new Promise((r) => setTimeout(r, 500));
|
| 26 |
+
if (!ok) return res.sendStatus(401);
|
| 27 |
+
|
| 28 |
+
const accessToken = jwt.sign(
|
| 29 |
+
{ id: user.id, role: user.role },
|
| 30 |
+
process.env.JWT_SECRET,
|
| 31 |
+
{ expiresIn: "15m", ...JWT_CONFIG }
|
| 32 |
+
);
|
| 33 |
+
|
| 34 |
+
const refresh = crypto.randomBytes(64).toString("hex");
|
| 35 |
+
user.refreshTokens.push({
|
| 36 |
+
hash: await bcrypt.hash(refresh, 10),
|
| 37 |
+
ip: req.ip,
|
| 38 |
+
userAgent: req.headers["user-agent"],
|
| 39 |
+
});
|
| 40 |
+
await user.save();
|
| 41 |
+
|
| 42 |
+
res.json({ accessToken, refreshToken: refresh });
|
| 43 |
+
});
|
| 44 |
+
|
| 45 |
+
export default r;
|