diff --git a/main.go b/main.go index b4ac37f..8fb2236 100644 --- a/main.go +++ b/main.go @@ -71,6 +71,7 @@ type Server struct { github githubApp authMu sync.Mutex auth map[string]*githubAuth // by session ID + showLocal bool // SHOW_LOCAL=true allows uploading local folders } func init() { @@ -93,6 +94,7 @@ func NewServer(workspace string) *Server { indexSlots: make(chan struct{}, maxIndexing), github: githubAppFromEnv(), auth: map[string]*githubAuth{}, + showLocal: os.Getenv("SHOW_LOCAL") == "true", } } @@ -138,7 +140,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { case r.Method == http.MethodOptions: w.WriteHeader(http.StatusNoContent) case path == "/api/health" && r.Method == http.MethodGet: - writeJSON(w, 200, map[string]any{"ok": true, "version": "0.1.0"}) + writeJSON(w, 200, map[string]any{"ok": true, "version": "0.1.0", "localFolders": s.showLocal}) case path == "/api/jobs" && r.Method == http.MethodPost: s.createJob(w, r) case strings.HasPrefix(path, "/api/jobs/"): @@ -164,6 +166,14 @@ func (s *Server) createJob(w http.ResponseWriter, r *http.Request) { writeError(w, 400, "Invalid job request") return } + switch { + case request.Kind == "local" && !s.showLocal: + writeError(w, 403, "Local folders are disabled on this server") + return + case request.Kind != "local" && request.Kind != "github": + writeError(w, 400, "Invalid job request") + return + } owner := sessionID(w, r) url := "" if request.Kind == "github" { diff --git a/main_test.go b/main_test.go index a85e211..54f8310 100644 --- a/main_test.go +++ b/main_test.go @@ -107,6 +107,7 @@ func (c client) json(method, path, body string, wantStatus int, out any) { func newTestServer(t *testing.T) (*Server, client) { server := NewServer(filepath.Join(t.TempDir(), "codenavigator")) + server.showLocal = true // most tests index local folders ts := httptest.NewServer(server) t.Cleanup(ts.Close) return server, client{t, ts.URL, nil}.stranger() @@ -240,7 +241,7 @@ func TestRoutesAndHeaders(t *testing.T) { t.Fatalf("preflight = %d %v", res.StatusCode, res.Header) } - for path, contentType := range map[string]string{"/": "text/html", "/api.mjs": "text/javascript", "/styles.css": "text/css", "/config.js": "text/javascript", "/inter-latin.woff2": "font/woff2"} { + for path, contentType := range map[string]string{"/": "text/html", "/api.mjs": "text/javascript", "/styles.css": "text/css", "/config.js": "text/javascript", "/fonts/archivo-black.woff2": "font/woff2"} { res, err := http.Get(c.url + path) if err != nil { t.Fatal(err) @@ -434,3 +435,28 @@ func TestProgressStreamSendsKeepAlivesWhileQueued(t *testing.T) { t.Fatalf("stream ended without a snapshot: %+v", job) } } + +func TestLocalFoldersDisabledByDefault(t *testing.T) { + t.Setenv("SHOW_LOCAL", "") + server := NewServer(filepath.Join(t.TempDir(), "codenavigator")) + ts := httptest.NewServer(server) + defer ts.Close() + c := client{t, ts.URL, nil}.stranger() + var health map[string]any + c.json("GET", "/api/health", "", 200, &health) + if health["localFolders"] != false { + t.Fatalf("health = %v", health) + } + c.json("POST", "/api/jobs", `{"kind":"local"}`, 403, nil) + c.json("POST", "/api/jobs", `{"kind":"mystery"}`, 400, nil) + + t.Setenv("SHOW_LOCAL", "true") + enabled := httptest.NewServer(NewServer(filepath.Join(t.TempDir(), "codenavigator"))) + defer enabled.Close() + on := client{t, enabled.URL, nil}.stranger() + on.json("GET", "/api/health", "", 200, &health) + if health["localFolders"] != true { + t.Fatalf("health with SHOW_LOCAL=true = %v", health) + } + on.json("POST", "/api/jobs", `{"kind":"local"}`, 201, nil) +} diff --git a/web/inter-latin.woff2 b/web/inter-latin.woff2 deleted file mode 100644 index d15208d..0000000 Binary files a/web/inter-latin.woff2 and /dev/null differ