53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import { NextFunction, Request, Response } from "express";
|
|
import Account from "../model/user"
|
|
import { importJWK, SignJWT, jwtVerify } from "jose";
|
|
|
|
|
|
let key;
|
|
|
|
async function setKeyFromEnv() {
|
|
key = await importJWK(JSON.parse(process.env.FM_PRIVATE_KEY));
|
|
}
|
|
|
|
async function getJWT(user: Account){
|
|
let jwt = await new SignJWT()
|
|
.setSubject(user.id)
|
|
.setProtectedHeader({ alg: 'HS256' })
|
|
.setIssuedAt()
|
|
.sign(key);
|
|
|
|
return jwt
|
|
}
|
|
|
|
async function requireAuth(req: Request, res: Response, next: NextFunction) {
|
|
try {
|
|
const token = req.cookies.jwt; // Or req.headers.authorization
|
|
if (!token) {
|
|
return res.status(401).json({ error: 'Unauthorized: No token provided' });
|
|
}
|
|
const jwt= await jwtVerify(token, key);
|
|
const user = await Account.findOne({where: { id: jwt.payload.sub}});
|
|
if (!user) {
|
|
return res.status(401).json({ error: 'Unauthorized: User not found' });
|
|
}
|
|
//TODO extend req instead of using res.locals
|
|
res.locals.user = user;
|
|
next();
|
|
} catch (err) {
|
|
return res.status(401).json({ error: 'Unauthorized: Invalid token' });
|
|
}
|
|
}
|
|
|
|
function requireRole(role: string) {
|
|
return async (req: Request, res: Response, next: NextFunction) => {
|
|
// First, run requireAuth to ensure the user is authenticated
|
|
await requireAuth(req, res, () => {
|
|
if (res.locals.role !== role) {
|
|
return res.status(403).json({ error: 'Forbidden: Insufficient permissions' });
|
|
}
|
|
next(); // User is authenticated and has the required role
|
|
});
|
|
};
|
|
}
|
|
|
|
export {getJWT, setKeyFromEnv, requireAuth} |