Files
nuitdelinfo2023/api/modules/token.js
2023-12-07 20:35:55 +01:00

52 lines
1.6 KiB
JavaScript

/* eslint-disable no-undef */
import jwt from 'jsonwebtoken';
import { Level } from 'level';
import { respondWithStatus } from './requestHandler';
import { pool } from './database';
// Set up LevelDB instance
const db = new Level('./tokensDB');
// Generate a new JWT
const generateToken = async (userId, password) => {
const token = jwt.sign({ userId: userId, password: password }, process.env.JWT_SECRET, { expiresIn: '7d' });
await db.put(token);
return token;
};
// Middleware to verify the JWT and set req.userId
const verifyToken = async (req, res, next) => {
const token = req.headers.authorization;
if (!token) return await respondWithStatus(res, 401, 'No token provided');
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.userId = decoded.userId;
const [rows] = await pool.execute(
'SELECT * FROM users WHERE id = ? LIMIT 1', [req.userId],
);
if (!rows.length) return await respondWithStatus(res, 404, 'User not found!');
const passwordMatch = await Bun.password.verify(decoded.password, rows[0].password);
if (!passwordMatch) return await respondWithStatus(res, 401, 'Token is invalid');
const now = Date.now().valueOf() / 1000;
if (decoded.exp - now < 36000) {
const newToken = generateToken(req.userId, decoded.password);
res.cookie('token', newToken, {
expires: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000),
httpOnly: true,
secure: true,
sameSite: 'strict',
});
res.set('Authorization', newToken);
}
next();
}
catch (error) {
return await respondWithStatus(res, 401, 'Invalid user');
}
};
export { generateToken, verifyToken };