ProjectTokenGenerator.coffee 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. crypto = require 'crypto'
  2. # This module mirrors the token generation in Overleaf (`random_token.rb`),
  3. # for the purposes of implementing token-based project access, like the
  4. # 'unlisted-projects' feature in Overleaf
  5. module.exports = ProjectTokenGenerator =
  6. # (From Overleaf `random_token.rb`)
  7. # Letters (not numbers! see generate_token) used in tokens. They're all
  8. # consonants, to avoid embarassing words (I can't think of any that use only
  9. # a y), and lower case "l" is omitted, because in many fonts it is
  10. # indistinguishable from an upper case "I" (and sometimes even the number 1).
  11. TOKEN_ALPHA: 'bcdfghjkmnpqrstvwxyz'
  12. TOKEN_NUMERICS: '123456789'
  13. _randomString: (length, alphabet) ->
  14. result = crypto.randomBytes(length).toJSON().data.map(
  15. (b) -> alphabet[b % alphabet.length]
  16. ).join('')
  17. return result
  18. # Generate a 12-char token with only characters from TOKEN_ALPHA,
  19. # suitable for use as a read-only token for a project
  20. readOnlyToken: () ->
  21. return ProjectTokenGenerator._randomString(
  22. 12,
  23. ProjectTokenGenerator.TOKEN_ALPHA
  24. )
  25. # Generate a longer token, with a numeric prefix,
  26. # suitable for use as a read-and-write token for a project
  27. readAndWriteToken: () ->
  28. numerics = ProjectTokenGenerator._randomString(
  29. 10,
  30. ProjectTokenGenerator.TOKEN_NUMERICS
  31. )
  32. token = ProjectTokenGenerator._randomString(
  33. 12,
  34. ProjectTokenGenerator.TOKEN_ALPHA
  35. )
  36. fullToken = "#{numerics}#{token}"
  37. return fullToken