auth.service.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * @file Provides a service to handle user access and authentication.
  3. * @author Inigo Valentin
  4. * @since 4.0.0
  5. */
  6. const logger = require('pino')();
  7. const Sequelize = require("sequelize");
  8. const sha1 = require('sha1');
  9. const jwt = require('jsonwebtoken');
  10. const config = process.env;
  11. const User = require("../models").users;
  12. /**
  13. * Handles user access and authentication.
  14. */
  15. class AuthService {
  16. /**
  17. * Constructor.
  18. *
  19. * @param db Database connection.
  20. * @constructor
  21. */
  22. constructor(){}
  23. /**
  24. * Logs a user in.
  25. *
  26. * @param req The request received by the server.
  27. * @param res The response to be sent by the server.
  28. * @return The response.
  29. */
  30. async login(req, res){
  31. try {
  32. // Get user input
  33. const email = req.body.email ? req.body.email : "";
  34. const username = req.body.username ? req.body.username : "";
  35. const password = req.body.password;
  36. // Validate user input
  37. if (!(password && (email || username))) return res.status(401).send("Credentials required");
  38. // Validate if user exist in our database
  39. let user;
  40. if (username != "" && email != "") user = await User.findOne({where: {username: username, email: email}});
  41. else user = await User.findOne({where: {[Sequelize.Op.or]: {username: username, email: email}}});
  42. if (user && user.password == sha1(user.salt + password)){
  43. require('dotenv').config()
  44. const {TOKEN_SECRET, TOKEN_ISSUER} = process.env;
  45. const token = jwt.sign({user: user.id}, TOKEN_SECRET, {algorithm: 'HS256', expiresIn: '5h', issuer: TOKEN_ISSUER, subject: user.username})
  46. return res.send({token});
  47. }
  48. return res.status(403).send("Invalid Credentials");
  49. }
  50. catch (err) {
  51. logger.error("Error logging in: " + err);
  52. return res.status(500).send("Error logging in");
  53. }
  54. }
  55. /**
  56. * Validates a token in the request.
  57. *
  58. * @param req The request received by the server.
  59. * @return An object with four values:
  60. * - success: True if the user was authenticated, false otherwise.
  61. * - user: The ID of the authenticated user, or null if no user was authenticated.
  62. * - code: A HTTP status code that can be set on the response: 200, 401, 403 or 500.
  63. * - message: A message describing the HTTP status code.
  64. */
  65. validateToken(req, res) {
  66. const token = req.body.token || req.query.token || req.headers["x-access-token"];
  67. if (!token) return {success: false, user: null, code: 401, message: "A token is required for authentication."};
  68. try {
  69. require('dotenv').config()
  70. const {TOKEN_SECRET, TOKEN_ISSUER} = process.env;
  71. const {exp, iss, user} = jwt.verify(token, TOKEN_SECRET);
  72. if (iss === TOKEN_ISSUER && exp < Date.now()) return {success: true, user: user, code: 200, message: "OK"};
  73. return {success: false, user: null, code: 403, message: "Invalid token."};;
  74. }
  75. catch (err) {
  76. logger.error("Error validating token: " + err);
  77. return {success: false, user: null, code: 403, message: "Authentication error."};;
  78. }
  79. }
  80. }
  81. module.exports = AuthService;