46 lines
1.5 KiB
TypeScript
46 lines
1.5 KiB
TypeScript
import {type MiddlewareHandler} from "hono";
|
|
import jwt from "jsonwebtoken";
|
|
|
|
const {sign, verify} = jwt;
|
|
|
|
export const authMiddleware: MiddlewareHandler = async (c, next) => {
|
|
const authHeader = c.req.header("Authorization");
|
|
|
|
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
return c.json({error: "Unauthorized"}, 401);
|
|
}
|
|
|
|
const token = authHeader.split(" ")[1];
|
|
|
|
try {
|
|
const decoded = verify(token, process.env.JWT_SECRET!, {ignoreExpiration: false}) as {
|
|
userId: number;
|
|
exp: number;
|
|
};
|
|
|
|
const currentTime = Math.floor(Date.now() / 1000); // Get current timestamp
|
|
const timeLeft = decoded.exp - currentTime;
|
|
|
|
// If the token has less than REFRESH_THRESHOLD seconds left, refresh it
|
|
let newToken = null;
|
|
|
|
if (timeLeft < parseInt(process.env.REFRESH_THRESHOLD!)) {
|
|
newToken = sign({userId: decoded.userId}, process.env.JWT_SECRET!, {
|
|
expiresIn: parseInt(process.env.EXPIRATION_TIME!),
|
|
});
|
|
c.res.headers.set("Authorization", `Bearer ${newToken}`);
|
|
}
|
|
|
|
c.set("user", {id: decoded.userId});
|
|
await next();
|
|
|
|
// If a new token was generated, send it in response headers
|
|
if (newToken) {
|
|
console.log("token was refreshed");
|
|
c.res.headers.set("X-Refreshed-Token", newToken);
|
|
}
|
|
} catch (err) {
|
|
return c.json({error: "Invalid token"}, 401);
|
|
}
|
|
};
|