ProjectTokenGenerator.coffee 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  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 = ''
  15. crypto.randomBytes(length).map(
  16. (b) -> result += alphabet[b % alphabet.length]
  17. )
  18. return result
  19. # Generate a 12-char token with only characters from TOKEN_ALPHA,
  20. # suitable for use as a read-only token for a project
  21. readOnlyToken: () ->
  22. return ProjectTokenGenerator._randomString(
  23. 12,
  24. ProjectTokenGenerator.TOKEN_ALPHA
  25. )
  26. # Generate a longer token, with a numeric prefix,
  27. # suitable for use as a read-and-write token for a project
  28. readAndWriteToken: () ->
  29. numerics = ProjectTokenGenerator._randomString(
  30. 10,
  31. ProjectTokenGenerator.TOKEN_NUMERICS
  32. )
  33. token = ProjectTokenGenerator._randomString(
  34. 12,
  35. ProjectTokenGenerator.TOKEN_ALPHA
  36. )
  37. fullToken = "#{numerics}#{token}"
  38. return fullToken