You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

jwt.js 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict'
  2. const JWT = require('jsonwebtoken')
  3. const crypto = require('crypto')
  4. const hashToken = async token => {
  5. const salt = process.env.APP_SESSION_SALT
  6. try {
  7. return crypto.createHmac('sha256', salt).update(token).digest('hex')
  8. } catch (err) {
  9. throw new Error(err.message)
  10. }
  11. }
  12. const createToken = (data, expiration = 600) => {
  13. const key = process.env.APP_SECRET
  14. const obj = {}
  15. Object.assign(obj, { ...data })
  16. return JWT.sign(obj, key, { expiresIn: expiration })
  17. }
  18. const validateToken = token => {
  19. const key = process.env.APP_SECRET
  20. try {
  21. return JWT.verify(token, key)
  22. } catch (err) {
  23. return { payload: null, message: err.message }
  24. }
  25. }
  26. module.exports = options => {
  27. return {
  28. key: options.jwtKey,
  29. verifyOptions: {
  30. algorithms: ['HS256'],
  31. },
  32. // TODO: Naming conventions need to be reversed again??
  33. validate: async (decoded, request, h) => {
  34. const sessionTokenFromHeaders = request.headers.authorization
  35. const hashedSessionTokenFromHeaders = await hashToken(
  36. sessionTokenFromHeaders,
  37. )
  38. const activeSession =
  39. request.server.app.activeSessions[hashedSessionTokenFromHeaders]
  40. if (!activeSession)
  41. throw new Error(
  42. `No session found for ${hashedSessionTokenFromHeaders}`,
  43. )
  44. const sessionToken = activeSession.sessionToken
  45. const accessToken = activeSession.accessToken
  46. const validatedSessionToken = validateToken(sessionToken)
  47. const validatedAccessToken = validateToken(accessToken)
  48. if (!validatedAccessToken.payload) {
  49. console.log('accessToken no longer valid, reissuing... ')
  50. activeSession.accessToken = createToken(
  51. { payload: validatedSessionToken.payload },
  52. // NOTE: Expiration of new sessionToken set for 200 seconds (testing)
  53. 100,
  54. )
  55. }
  56. try {
  57. const validatedJwt = JWT.verify(
  58. sessionToken,
  59. process.env.APP_SECRET,
  60. )
  61. return { isValid: true, credentials: validatedJwt.email }
  62. } catch (err) {
  63. return { isValid: false, error: err.message }
  64. }
  65. },
  66. }
  67. }