Encrypted messaging app
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.

108 lines
2.5 KiB

  1. package Auth
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "time"
  6. "git.tovijaeschke.xyz/tovi/Envelope/Backend/Database"
  7. "git.tovijaeschke.xyz/tovi/Envelope/Backend/Models"
  8. )
  9. type Credentials struct {
  10. Username string `json:"username"`
  11. Password string `json:"password"`
  12. }
  13. type loginResponse struct {
  14. Status string `json:"status"`
  15. Message string `json:"message"`
  16. AsymmetricPublicKey string `json:"asymmetric_public_key"`
  17. AsymmetricPrivateKey string `json:"asymmetric_private_key"`
  18. UserID string `json:"user_id"`
  19. Username string `json:"username"`
  20. }
  21. func makeLoginResponse(w http.ResponseWriter, code int, message, pubKey, privKey string, user Models.User) {
  22. var (
  23. status string = "error"
  24. returnJson []byte
  25. err error
  26. )
  27. if code > 200 && code < 300 {
  28. status = "success"
  29. }
  30. returnJson, err = json.MarshalIndent(loginResponse{
  31. Status: status,
  32. Message: message,
  33. AsymmetricPublicKey: pubKey,
  34. AsymmetricPrivateKey: privKey,
  35. UserID: user.ID.String(),
  36. Username: user.Username,
  37. }, "", " ")
  38. if err != nil {
  39. http.Error(w, "Error", http.StatusInternalServerError)
  40. return
  41. }
  42. // Return updated json
  43. w.WriteHeader(code)
  44. w.Write(returnJson)
  45. }
  46. func Login(w http.ResponseWriter, r *http.Request) {
  47. var (
  48. creds Credentials
  49. userData Models.User
  50. session Models.Session
  51. expiresAt time.Time
  52. err error
  53. )
  54. err = json.NewDecoder(r.Body).Decode(&creds)
  55. if err != nil {
  56. makeLoginResponse(w, http.StatusInternalServerError, "An error occurred", "", "", userData)
  57. return
  58. }
  59. userData, err = Database.GetUserByUsername(creds.Username)
  60. if err != nil {
  61. makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
  62. return
  63. }
  64. if !CheckPasswordHash(creds.Password, userData.Password) {
  65. makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
  66. return
  67. }
  68. // TODO: Revisit before production
  69. expiresAt = time.Now().Add(12 * time.Hour)
  70. session = Models.Session{
  71. UserID: userData.ID,
  72. Expiry: expiresAt,
  73. }
  74. err = Database.CreateSession(&session)
  75. if err != nil {
  76. makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
  77. return
  78. }
  79. http.SetCookie(w, &http.Cookie{
  80. Name: "session_token",
  81. Value: session.ID.String(),
  82. Expires: expiresAt,
  83. })
  84. makeLoginResponse(
  85. w,
  86. http.StatusOK,
  87. "Successfully logged in",
  88. userData.AsymmetricPublicKey,
  89. userData.AsymmetricPrivateKey,
  90. userData,
  91. )
  92. }