package routes import ( "encoding/base64" "encoding/json" "net/http" "testing" "time" "github.com/gofiber/fiber/v2" ) func TestTotpViewRoutes(t *testing.T) { app := fiber.New() TotpViewSetup(app, "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ", "view-password") for _, path := range []string{"/fwh-totp/", "/fwh-totp/code"} { req, _ := http.NewRequest(http.MethodGet, path, nil) res, err := app.Test(req) if err != nil || res.StatusCode != http.StatusUnauthorized { t.Fatalf("unauthorized %s: status %v, err %v", path, res.StatusCode, err) } if res.Header.Get("Cache-Control") != "no-store, max-age=0" { t.Fatalf("missing no-store on %s", path) } } req, _ := http.NewRequest(http.MethodGet, "/fwh-totp/code", nil) req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("fwh:wrong"))) res, err := app.Test(req) if err != nil || res.StatusCode != http.StatusUnauthorized { t.Fatalf("wrong password: status %v, err %v", res.StatusCode, err) } req, _ = http.NewRequest(http.MethodGet, "/fwh-totp/code", nil) req.SetBasicAuth("fwh", "view-password") res, err = app.Test(req) if err != nil || res.StatusCode != http.StatusOK { t.Fatalf("authorized request: status %v, err %v", res.StatusCode, err) } var body struct { Code string `json:"code"` ExpiresAt int64 `json:"expiresAt"` ServerTime int64 `json:"serverTime"` } if err := json.NewDecoder(res.Body).Decode(&body); err != nil { t.Fatal(err) } if len(body.Code) != 6 || body.ExpiresAt-body.ServerTime <= 0 || body.ExpiresAt-body.ServerTime > int64(30*time.Second/time.Millisecond) { t.Fatalf("invalid TOTP response: %+v", body) } for _, path := range []string{"/fwh-totp", "/fwh-totp/"} { req, _ = http.NewRequest(http.MethodGet, path, nil) req.SetBasicAuth("fwh", "view-password") res, err = app.Test(req) if err != nil || res.StatusCode != http.StatusOK || res.Header.Get("Content-Type") != "text/html; charset=utf-8" { t.Fatalf("page request %s: status %v, content-type %q, err %v", path, res.StatusCode, res.Header.Get("Content-Type"), err) } } } func TestTotpViewDisabledWithoutPassword(t *testing.T) { app := fiber.New() TotpViewSetup(app, "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ", "") req, _ := http.NewRequest(http.MethodGet, "/fwh-totp/code", nil) res, err := app.Test(req) if err != nil || res.StatusCode != http.StatusNotFound { t.Fatalf("disabled route: status %v, err %v", res.StatusCode, err) } } func TestMainRoutesDoNotExposeTotpView(t *testing.T) { app := fiber.New() Setup(app) for _, path := range []string{"/fwh-totp/", "/fwh-totp/code"} { req, _ := http.NewRequest(http.MethodGet, path, nil) res, err := app.Test(req) if err != nil || res.StatusCode != http.StatusNotFound { t.Fatalf("main app route %s: status %v, err %v", path, res.StatusCode, err) } } }