diff --git a/README.md b/README.md index fc9cfc2..cfa282b 100644 --- a/README.md +++ b/README.md @@ -298,6 +298,14 @@ Danach: `lp ` in die Adresszeile, Enter – landet bei eindeutigem Treffer direkt beim Dienst, sonst auf der LaunchPad-Startseite mit bereits eingetragenem Suchbegriff. +**Android:** Firefox für Android unterstützt Schlagwort-Suchen (auch keine +synchronisierten Desktop-Kürzel) grundsätzlich nicht – eine bekannte +Firefox-Einschränkung, kein LaunchPad-Problem. Auf Android funktioniert die +Chrome-Anleitung oben unverändert. Alternative für jeden Browser: die +LaunchPad-Seite über „Zum Startbildschirm hinzufügen" als App-Symbol +ablegen (LaunchPad ist als PWA installierbar) – ein Fingertipp genügt dann +bis zum Suchfeld. + ## Deployment auf unterschiedlichen Geräten Läuft überall, wo Docker Compose verfügbar ist. Ein paar konkrete Wege: diff --git a/apps/backend/src/scanner/apiDetector.ts b/apps/backend/src/scanner/apiDetector.ts index d1dee9e..41b1ae7 100644 --- a/apps/backend/src/scanner/apiDetector.ts +++ b/apps/backend/src/scanner/apiDetector.ts @@ -62,7 +62,11 @@ function fetchRaw(url: string, timeoutMs = 2500): Promise * Hinweis-Scanner, kein Sicherheits-/Pentesting-Werkzeug. */ const CANDIDATE_PATHS: { path: string; type: string }[] = [ - // Generische REST-/OpenAPI-/GraphQL-Konventionen + // Generische REST-/OpenAPI-/GraphQL-Konventionen - bewusst nur Pfade, die + // auf eine tatsächlich NUTZBARE/dokumentierte API hindeuten. Reine + // Status-/Health-/Metrik-Endpunkte (/health, /metrics, /actuator, ...) + // wurden bewusst rausgenommen: die bestätigen nur "hier läuft Software", + // sind aber keine API, mit der man tatsächlich etwas anfangen kann. { path: "/openapi.json", type: "OpenAPI" }, { path: "/openapi.yaml", type: "OpenAPI" }, { path: "/swagger.json", type: "OpenAPI (Swagger)" }, @@ -72,7 +76,6 @@ const CANDIDATE_PATHS: { path: string; type: string }[] = [ { path: "/swagger/index.html", type: "Swagger-UI" }, { path: "/swagger-ui", type: "Swagger-UI" }, { path: "/redoc", type: "OpenAPI (ReDoc)" }, - { path: "/docs", type: "API-Dokumentation" }, { path: "/graphql", type: "GraphQL" }, { path: "/graphiql", type: "GraphQL" }, { path: "/api/graphql", type: "GraphQL" }, @@ -84,17 +87,8 @@ const CANDIDATE_PATHS: { path: string; type: string }[] = [ { path: "/rest", type: "REST-API" }, { path: "/rpc", type: "JSON-RPC" }, { path: "/jsonrpc", type: "JSON-RPC" }, - { path: "/api/status", type: "REST-API" }, - { path: "/api/system", type: "REST-API" }, - { path: "/api/info", type: "REST-API" }, - { path: "/api/version", type: "REST-API" }, - { path: "/api/config", type: "REST-API" }, - { path: "/actuator", type: "Spring-Boot-Actuator" }, - { path: "/actuator/health", type: "Spring-Boot-Actuator" }, - { path: "/metrics", type: "Metriken (Prometheus-Format)" }, - { path: "/healthz", type: "Health-Endpunkt" }, - { path: "/health", type: "Health-Endpunkt" }, - // Konkrete, in Homelabs verbreitete Software + // Konkrete, in Homelabs verbreitete Software - jeweils ein Endpunkt IHRER + // eigenen echten API (nicht nur ein Status-Ping), deshalb behalten. { path: "/api/config/core", type: "Home Assistant API" }, // erfordert Auth, meldet sich aber als API { path: "/api2/json/version", type: "Proxmox API" }, { path: "/api/status", type: "Portainer API" }, @@ -102,7 +96,6 @@ const CANDIDATE_PATHS: { path: string; type: string }[] = [ { path: "/admin/api.php", type: "Pi-hole API" }, { path: "/System/Info/Public", type: "Jellyfin API" }, { path: "/identity", type: "Plex API" }, - { path: "/api/health", type: "Grafana API" }, { path: "/api/self", type: "Unifi-Controller API" }, { path: "/api/v2/server/about", type: "Nextcloud API" }, { path: "/ocs/v1.php/cloud/capabilities", type: "Nextcloud API" }, diff --git a/apps/frontend/src/routes/admin/ScannerPage.tsx b/apps/frontend/src/routes/admin/ScannerPage.tsx index 9da6601..6f3fdd7 100644 --- a/apps/frontend/src/routes/admin/ScannerPage.tsx +++ b/apps/frontend/src/routes/admin/ScannerPage.tsx @@ -129,7 +129,13 @@ function NameChangesReview({ ); } -function NewServicesList({ newServices }: { newServices: Service[] }) { +function NewServicesList({ + newServices, + onResolve, +}: { + newServices: Service[]; + onResolve: (id: string) => void; +}) { if (newServices.length === 0) return null; return ( @@ -139,8 +145,19 @@ function NewServicesList({ newServices }: { newServices: Service[] }) {

@@ -375,7 +392,20 @@ function ApiScannerCard() {