Skip to content

Instantly share code, notes, and snippets.

@dueka
Created May 11, 2023 11:26
Show Gist options
  • Save dueka/d01cd4021b30fb91a56220c954f6f7e7 to your computer and use it in GitHub Desktop.
Save dueka/d01cd4021b30fb91a56220c954f6f7e7 to your computer and use it in GitHub Desktop.
authMiddleware
// This class represents an authentication middleware used in a web application.
export class AuthMiddleware extends BaseRouterMiddleware {
protected appUtils: AppUtils;
protected loginSessionService: LoginSessionService;
constructor(appRouter: Router) {
super(appRouter);
}
// Initializes the necessary services for authentication.
protected initServices() {
this.appUtils = new AppUtils();
this.loginSessionService = new LoginSessionService();
}
// Middleware function for authentication.
public authGuard = (req: Request, res: Response, next: any) => {
// Extract the JWT token from the authorization header.
const payload = req.headers.authorization || '';
let jwt = '';
if (payload) {
if (payload.split(" ").length > 1) {
jwt = payload.split(" ")[1];
}
}
// Verify the token using the appUtils verifyToken method.
this.appUtils.verifyToken(jwt, (error, decoded) => {
if (error) {
// Handle token verification errors.
if (error instanceof TokenExpiredError)
return this.sendErrorResponse(res, error, this.errorResponseMessage.SESSION_EXPIRED, 401);
return this.sendErrorResponse(res, error, this.errorResponseMessage.INVALID_TOKEN, 401);
} else {
const data = decoded.data || {};
const query = { uuid: data.uuid, _id: data.id, user: data.user, status: BIT.ON };
// Find and populate the login session from the query.
this.loginSessionService.findOneAndPopulate(query)
.then(async (loginSession) => {
if (loginSession?._id) {
// Check if the login session is expired.
if (loginSession.validity_end_date <= new Date()) {
loginSession.expired = true;
loginSession.status = BIT.OFF;
await loginSession.save();
const error = new Error("Session expired");
return this.sendErrorResponse(res, error, this.errorResponseMessage.SESSION_EXPIRED, 401);
}
const user = loginSession.user;
const canIgnoreStatus = (req.url === API_PATH+"/me/password" && req.method === "PATCH") || (req.url === API_PATH+"/me/logout" && req.method === "PATCH");
// Check if a password update is required for the user.
if (user.require_new_password && !canIgnoreStatus) {
const error = new Error("Password update required");
return this.sendErrorResponse(res, error, this.errorResponseMessage.PASSWORD_UPDATE_REQUIRED, 401);
}
// Add user, employee, and login session information to the data bag.
this.requestService.addToDataBag(USER_LABEL, user);
this.requestService.addToDataBag(EMPLOYEE_LABEL, loginSession.employee);
this.requestService.addToDataBag(LOGIN_SESSION_LABEL, loginSession);
this.checkUserStatus(res, canIgnoreStatus, next);
} else {
const error = new Error("Unable to validate user from token");
this.sendErrorResponse(res, error, this.errorResponseMessage.INVALID_TOKEN_USER, 401);
}
})
.catch((error) => {
this.sendErrorResponse(res, error, this.errorResponseMessage.UNABLE_TO_COMPLETE_REQUEST, 401);
})
}
})
}
export default AuthMiddleware;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment