An extremely simple user-authentication service.

app.moon 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. lapis = require "lapis"
  2. bcrypt = require "bcrypt"
  3. import Users from require "models"
  4. import api, abort, assert_model from require "helpers"
  5. class extends lapis.Application
  6. -- finds user by name or id (or creates by name), and returns the user,
  7. -- unless a password is not specified (or incorrect), or the password is too weak
  8. [authenticate: "/0/auth"]: respond_to {
  9. POST: api( =>
  10. -- find user by name or id if specified
  11. local user
  12. if @params.name
  13. user = Users\find name: @params.name
  14. elseif @params.id
  15. user = Users\find id: @params.id
  16. abort "Incorrect user name, id, or password." unless user
  17. -- if a user by that name exists, see if the password is correct
  18. if user
  19. unless bcrypt.verify(@params.password, user.digest)
  20. abort "Incorrect user name, id, or password."
  21. -- else create a user
  22. elseif @params.password
  23. assert_valid(@params, {
  24. { "name", exists: true, min_length: 1, max_length: 255, matches_pattern: "%w+" }
  25. { "password", exists: true, min_length: 8, max_length: 255 }
  26. })
  27. -- TODO passwords should be checked against known breached passwords
  28. user = assert_model Users\create {
  29. name: @params.name
  30. digest: bcrypt.digest(@params.password, config.digest_rounds)
  31. }
  32. -- if a password wasn't specified...
  33. else
  34. abort "Must specify name or id, and password."
  35. return name: user.name, id: user.id
  36. )
  37. }
  38. -- finds user by id and returns their name
  39. [name: "/0/:id[%d]"]: {
  40. GET: api(=>
  41. if user = Users\find id: @params.id
  42. return name: user.name
  43. else
  44. abort "Incorrect user id."
  45. )
  46. }