security.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. const crypto = require('crypto')
  2. const uuid = require('uuid/v4')
  3. const jwt = require('jsonwebtoken')
  4. const SECRET = 'scale action palace measure'
  5. const genSeed = uuid
  6. const genKey = ({format = '###-###', alphabet = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789'} = {}) => {
  7. const c = () => alphabet[Math.floor(Math.random() * alphabet.length)]
  8. return format.replace(/#/g, c)
  9. }
  10. const hashPassword = ({password, seed, email}) => {
  11. if (!password) throw new Error('Missing password')
  12. if (!seed) throw new Error('Missing seed')
  13. if (!email) throw new Error('Missing email')
  14. email = email.toLowerCase().trim()
  15. password = password.trim()
  16. const hash = crypto.createHash('sha256')
  17. hash.update(`${password},${seed},${email}`)
  18. const result = hash.digest('base64')
  19. return result
  20. }
  21. const createToken = user => jwt.sign({
  22. email: user.email,
  23. name: user.name,
  24. }, SECRET, { expiresIn: '2 days' })
  25. const validate = token => jwt.verify(token, SECRET, { complete: true })
  26. const authorize = (...claims) => (req, res, next) => {
  27. const reg = /^Bearer (.*)$/.exec(req.headers.authorization)
  28. let decoded
  29. if (reg && (decoded = validate(reg[1]))) {
  30. if (claims.every(claim => decoded[claim])) {
  31. req.identity = decoded.payload
  32. next()
  33. } else {
  34. res.status(403).send('Access denied')
  35. }
  36. } else {
  37. res.status(401).send('Authorization required')
  38. }
  39. }
  40. module.exports = { hashPassword, genSeed, createToken, validate, authorize, genKey }