package handlers import ( "encoding/json" "net/http" "net/http/httptest" "net/url" "path/filepath" "regexp" "strings" "testing" "teraclone/internal/service" ) func TestWorkspaceIdentityIsPerLoginAndNotAnAuthenticationToken(t *testing.T) { backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/api/v1/auth/logout" { w.WriteHeader(http.StatusOK) return } if r.URL.Path != "/api/v1/auth/login" { http.NotFound(w, r) return } var credentials map[string]string _ = json.NewDecoder(r.Body).Decode(&credentials) role := "administrator" if credentials["username"] == "operator" { role = "port_operator" } _ = json.NewEncoder(w).Encode(map[string]any{"session_token": "private-backend-token", "actor": "test-" + credentials["username"], "role": role}) })) defer backend.Close() app, err := service.NewAppService(filepath.Join(t.TempDir(), "frontend.db")) if err != nil { t.Fatal(err) } defer app.Close() handler, err := NewDeviceHandler(app, backend.URL) if err != nil { t.Fatal(err) } mux := http.NewServeMux() handler.RegisterRoutes(mux) identity := regexp.MustCompile(`data-workspace-id="([a-f0-9]{64})"`) seen := make(map[string]bool) for _, username := range []string{"admin", "operator", "operator"} { request := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(url.Values{"username": {username}, "password": {"test"}}.Encode())) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") response := httptest.NewRecorder() mux.ServeHTTP(response, request) if response.Code != http.StatusSeeOther || len(response.Result().Cookies()) != 1 { t.Fatalf("login failed: %d", response.Code) } cookie := response.Result().Cookies()[0] var previousID string for _, path := range []string{"/", "/port-status", "/"} { pageRequest := httptest.NewRequest(http.MethodGet, path, nil) pageRequest.AddCookie(cookie) page := httptest.NewRecorder() mux.ServeHTTP(page, pageRequest) body := page.Body.String() match := identity.FindStringSubmatch(body) if page.Code != http.StatusOK || len(match) != 2 { t.Fatalf("missing public workspace identity: status=%d", page.Code) } id := match[1] if previousID != "" && id != previousID { t.Fatal("workspace identity changed during page navigation/refresh") } if id == cookie.Value || strings.Contains(body, cookie.Value) || strings.Contains(body, "private-backend-token") { t.Fatal("authentication token leaked into workspace HTML") } if !strings.Contains(body, `data-current-user="`+username+`"`) || page.Header().Get("Cache-Control") != "no-store" { t.Fatal("missing workspace user or cache prevention") } previousID = id } if seen[previousID] { t.Fatal("workspace identity reused after a new login") } seen[previousID] = true logoutRequest := httptest.NewRequest(http.MethodPost, "/logout", nil) logoutRequest.AddCookie(cookie) mux.ServeHTTP(httptest.NewRecorder(), logoutRequest) } }