totpViewRoutes_test.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package routes
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "net/http"
  6. "testing"
  7. "time"
  8. "github.com/gofiber/fiber/v2"
  9. )
  10. func TestTotpViewRoutes(t *testing.T) {
  11. app := fiber.New()
  12. TotpViewSetup(app, "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ", "view-password")
  13. for _, path := range []string{"/fwh-totp/", "/fwh-totp/code"} {
  14. req, _ := http.NewRequest(http.MethodGet, path, nil)
  15. res, err := app.Test(req)
  16. if err != nil || res.StatusCode != http.StatusUnauthorized {
  17. t.Fatalf("unauthorized %s: status %v, err %v", path, res.StatusCode, err)
  18. }
  19. if res.Header.Get("Cache-Control") != "no-store, max-age=0" {
  20. t.Fatalf("missing no-store on %s", path)
  21. }
  22. }
  23. req, _ := http.NewRequest(http.MethodGet, "/fwh-totp/code", nil)
  24. req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("fwh:wrong")))
  25. res, err := app.Test(req)
  26. if err != nil || res.StatusCode != http.StatusUnauthorized {
  27. t.Fatalf("wrong password: status %v, err %v", res.StatusCode, err)
  28. }
  29. req, _ = http.NewRequest(http.MethodGet, "/fwh-totp/code", nil)
  30. req.SetBasicAuth("fwh", "view-password")
  31. res, err = app.Test(req)
  32. if err != nil || res.StatusCode != http.StatusOK {
  33. t.Fatalf("authorized request: status %v, err %v", res.StatusCode, err)
  34. }
  35. var body struct {
  36. Code string `json:"code"`
  37. ExpiresAt int64 `json:"expiresAt"`
  38. ServerTime int64 `json:"serverTime"`
  39. }
  40. if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
  41. t.Fatal(err)
  42. }
  43. if len(body.Code) != 6 || body.ExpiresAt-body.ServerTime <= 0 || body.ExpiresAt-body.ServerTime > int64(30*time.Second/time.Millisecond) {
  44. t.Fatalf("invalid TOTP response: %+v", body)
  45. }
  46. for _, path := range []string{"/fwh-totp", "/fwh-totp/"} {
  47. req, _ = http.NewRequest(http.MethodGet, path, nil)
  48. req.SetBasicAuth("fwh", "view-password")
  49. res, err = app.Test(req)
  50. if err != nil || res.StatusCode != http.StatusOK || res.Header.Get("Content-Type") != "text/html; charset=utf-8" {
  51. t.Fatalf("page request %s: status %v, content-type %q, err %v", path, res.StatusCode, res.Header.Get("Content-Type"), err)
  52. }
  53. }
  54. }
  55. func TestTotpViewDisabledWithoutPassword(t *testing.T) {
  56. app := fiber.New()
  57. TotpViewSetup(app, "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ", "")
  58. req, _ := http.NewRequest(http.MethodGet, "/fwh-totp/code", nil)
  59. res, err := app.Test(req)
  60. if err != nil || res.StatusCode != http.StatusNotFound {
  61. t.Fatalf("disabled route: status %v, err %v", res.StatusCode, err)
  62. }
  63. }
  64. func TestMainRoutesDoNotExposeTotpView(t *testing.T) {
  65. app := fiber.New()
  66. Setup(app)
  67. for _, path := range []string{"/fwh-totp/", "/fwh-totp/code"} {
  68. req, _ := http.NewRequest(http.MethodGet, path, nil)
  69. res, err := app.Test(req)
  70. if err != nil || res.StatusCode != http.StatusNotFound {
  71. t.Fatalf("main app route %s: status %v, err %v", path, res.StatusCode, err)
  72. }
  73. }
  74. }