From 72f88be5feddeb15348e952a0b590612ab9d1ce2 Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Sun, 19 Oct 2025 21:35:16 +0200 Subject: [PATCH] Docs: Update /pkg/service/http/... -> /pkg/http/... Signed-off-by: Michael Mayer --- AGENTS.md | 4 ++-- CODEMAP.md | 10 +++++----- internal/api/README.md | 2 +- internal/commands/README.md | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 01ac626cb..9230db85c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -274,7 +274,7 @@ Note: Across our public documentation, official images, and in production, the c ### HTTP Download — Security Checklist - Use the shared safe HTTP helper instead of ad‑hoc `net/http` code: - - Package: `pkg/service/http/safe` → `safe.Download(destPath, url, *safe.Options)`. + - Package: `pkg/http/safe` → `safe.Download(destPath, url, *safe.Options)`. - Default policy in this repo: allow only `http/https`, enforce timeouts and max size, write to a `0600` temp file then rename. - SSRF protection (mandatory unless explicitly needed for tests): - Set `AllowPrivate=false` to block private/loopback/multicast/link‑local ranges. @@ -419,7 +419,7 @@ Note: Across our public documentation, official images, and in production, the c - Keep bootstrap code decoupled: avoid importing `internal/service/cluster/node/*` from `internal/config` or the cluster root, let nodes talk to the Portal over HTTP(S), and rely on constants from `internal/service/cluster/const.go`. - Config init order: load `options.yml` (`c.initSettings()`), run `EarlyExt().InitEarly(c)`, connect/register the DB, then invoke `Ext().Init(c)`. -- Theme endpoint: `GET /api/v1/cluster/theme` streams a zip from `conf.ThemePath()`; only reinstall when `app.js` is missing and always use the header helpers in `pkg/service/http/header`. +- Theme endpoint: `GET /api/v1/cluster/theme` streams a zip from `conf.ThemePath()`; only reinstall when `app.js` is missing and always use the header helpers in `pkg/http/header`. - Registration flow: send `rotate=true` only for MySQL/MariaDB nodes without credentials, treat 401/403/404 as terminal, include `ClientID` + `ClientSecret` when renaming an existing node, and persist only newly generated secrets or DB settings. - Registry & DTOs: use the client-backed registry (`NewClientRegistryWithConfig`)—the file-backed version is legacy—and treat migration as complete only after swapping callsites, building, and running focused API/CLI tests. Nodes are keyed by UUID v7 (`/api/v1/cluster/nodes/{uuid}`), the registry interface stays UUID-first (`Get`, `FindByNodeUUID`, `FindByClientID`, `RotateSecret`, `DeleteAllByUUID`), CLI lookups resolve `uuid → ClientID → name`, and DTOs normalize `Database.{Name,User,Driver,RotatedAt}` while exposing `ClientSecret` only during creation/rotation. `nodes rm --all-ids` cleans duplicate client rows, admin responses may include `AdvertiseUrl`/`Database`, client/user sessions stay redacted, registry files live under `conf.PortalConfigPath()/nodes/` (mode 0600), and `ClientData` no longer stores `NodeUUID`. - Provisioner & DSN: database/user names use UUID-based HMACs (`photoprism_d`, `photoprism_u`); `BuildDSN` accepts a `driver` but falls back to MySQL format with a warning when unsupported. diff --git a/CODEMAP.md b/CODEMAP.md index dab134fd3..160b67657 100644 --- a/CODEMAP.md +++ b/CODEMAP.md @@ -40,7 +40,7 @@ High-Level Package Map (Go) - `internal/service` — cluster/portal, maps, hub, webdav - `internal/event` — logging, pub/sub, audit - `internal/ffmpeg`, `internal/thumb`, `internal/meta`, `internal/form`, `internal/mutex` — media, thumbs, metadata, forms, coordination -- `pkg/*` — reusable utilities (must never import from `internal/*`), e.g. `pkg/clean`, `pkg/enum`, `pkg/fs`, `pkg/txt`, `pkg/service/http/header` +- `pkg/*` — reusable utilities (must never import from `internal/*`), e.g. `pkg/clean`, `pkg/enum`, `pkg/fs`, `pkg/txt`, `pkg/http/header` Templates & Static Assets - Entry HTML lives in `assets/templates/index.gohtml`, which includes the splash markup from `app.gohtml` and the SPA loader from `app.js.gohtml`. @@ -109,7 +109,7 @@ Cluster / Portal Logging & Events - Logger and event hub: `internal/event/*`; `event.Log` is the shared logger. -- HTTP headers/constants: `pkg/service/http/header/*` — always prefer these in handlers and tests. +- HTTP headers/constants: `pkg/http/header/*` — always prefer these in handlers and tests. Server Startup Flow (happy path) 1) `photoprism start` (CLI) → `internal/commands/start.go` @@ -170,7 +170,7 @@ Security & Hot Spots (Where to Look) - Sizes & names: `internal/thumb/sizes.go`, `internal/thumb/names.go`, `internal/thumb/filter.go`; face/marker crop helpers live in `internal/thumb/crop` (e.g., `ParseThumb`, `IsCroppedThumb`). - Safe HTTP downloader: - - Shared utility: `pkg/service/http/safe` (`Download`, `Options`). + - Shared utility: `pkg/http/safe` (`Download`, `Options`). - Protections: scheme allow‑list (http/https), pre‑DNS + per‑redirect hostname/IP validation, final peer IP check, size and timeout enforcement, temp file `0600` + rename. - Avatars: wrapper `internal/thumb/avatar.SafeDownload` applies stricter defaults (15s, 10 MiB, `AllowPrivate=false`, image‑focused `Accept`). - Tests: `go test ./pkg/http/safe -count=1` (includes redirect SSRF cases); avatars: `go test ./internal/thumb/avatar -count=1`. @@ -181,7 +181,7 @@ Performance & Limits Conventions & Rules of Thumb - Respect package boundaries: code in `pkg/*` must not import `internal/*`. -- Prefer constants/helpers from `pkg/service/http/header` over string literals. +- Prefer constants/helpers from `pkg/http/header` over string literals. - Never log secrets; compare tokens constant‑time. - Don’t import Portal internals from cluster instance/service bootstraps; use HTTP. - Prefer small, hermetic unit tests; isolate filesystem paths with `t.TempDir()` and env like `PHOTOPRISM_STORAGE_PATH`. @@ -222,7 +222,7 @@ Frequently Touched Files (by topic) - Cluster: `internal/service/cluster/*` - Theme support: `internal/service/cluster/theme/version.go` exposes `DetectVersion`, used by bootstrap, CLI, and API handlers to compare portal vs node theme revisions (prefers `fs.VersionTxtFile`, falls back to `app.js` mtime). - Registration sanitizes `AppName`, `AppVersion`, and `Theme` with `clean.TypeUnicode`; defaults for app metadata come from `config.About()` / `config.Version()`. `cluster.RegisterResponse` now includes a `Theme` hint when the portal has a newer bundle so nodes can decide whether to download immediately. -- Headers: `pkg/service/http/header/*` +- Headers: `pkg/http/header/*` Downloads (CLI) & yt-dlp helpers - CLI command & core: diff --git a/internal/api/README.md b/internal/api/README.md index 0dc2d4b0b..956b6f7da 100644 --- a/internal/api/README.md +++ b/internal/api/README.md @@ -39,7 +39,7 @@ The API package exposes PhotoPrism’s HTTP endpoints via Gin handlers. Each fil ## Testing Strategy - Build tests around the API harness (`NewApiTest`) to obtain a configured Gin router, config, and dependencies. This isolates filesystem paths and avoids polluting global state. -- Wrap requests with helper functions (for example, `PerformRequestJSON`, `PerformAuthenticatedRequest`) to capture status codes, headers, and payloads. Assert headers using constants from `pkg/service/http/header`. +- Wrap requests with helper functions (for example, `PerformRequestJSON`, `PerformAuthenticatedRequest`) to capture status codes, headers, and payloads. Assert headers using constants from `pkg/http/header`. - When handlers interact with the database, initialize fixtures through config helpers such as `config.NewTestConfig("api")` or `config.NewMinimalTestConfigWithDb("api", t.TempDir())` depending on fixture needs. - Stub external dependencies (`httptest.Server`) for remote calls and set `AllowPrivate=true` explicitly when the test server binds to loopback addresses. - Structure tests with table-driven subtests (`t.Run("CaseName", ...)`) and use PascalCase names. Provide cleanup functions (`t.Cleanup`) to remove temporary files or databases created during tests. diff --git a/internal/commands/README.md b/internal/commands/README.md index 28c0a31f0..2516d097a 100644 --- a/internal/commands/README.md +++ b/internal/commands/README.md @@ -18,7 +18,7 @@ The `commands` package hosts the CLI implementation for the PhotoPrism binary. C - Follow the overwrite policy used by media helpers: require explicit confirmation (`force` flags) before replacing non-empty files. Where replacements are expected, open destinations with `O_WRONLY|O_CREATE|O_TRUNC`. - Use shared logging through `event.Log` rather than direct `fmt` printing. Sensitive information such as secrets or tokens must never be logged. - When integrating configuration options, call the accessors on `*config.Config` (for example, `conf.ClusterUUID()`) rather than mutating option structs directly. -- For HTTP interactions, depend on the safe download helpers in `pkg/service/http/safe` or the specialized wrappers in `internal/thumb/avatar` to inherit timeout, size, and SSRF protection defaults. +- For HTTP interactions, depend on the safe download helpers in `pkg/http/safe` or the specialized wrappers in `internal/thumb/avatar` to inherit timeout, size, and SSRF protection defaults. ## Configuration & Flags Integration @@ -48,7 +48,7 @@ The `commands` package hosts the CLI implementation for the PhotoPrism binary. C - Stub external binaries such as `yt-dlp` with lightweight shell scripts that honor `--dump-single-json` and `--print` requests. Support environment variables like `YTDLP_ARGS_LOG`, `YTDLP_OUTPUT_FILE`, and `YTDLP_DUMMY_CONTENT` to capture arguments, create deterministic artifacts, and avoid duplicate detection in importer flows. - Disable FFmpeg during tests that focus on command construction by setting `conf.Options().FFmpegBin = "/bin/false"` and `conf.Settings().Index.Convert = false`. -- When asserting HTTP responses, rely on header constants from `pkg/service/http/header` (for example, `header.ContentTypeZip`) to keep expectations aligned with middleware. +- When asserting HTTP responses, rely on header constants from `pkg/http/header` (for example, `header.ContentTypeZip`) to keep expectations aligned with middleware. - For role and scope checks, reuse helpers in `internal/auth/acl` such as `acl.ParseRole`, `acl.ScopePermits`, and `acl.ScopeAttrPermits` instead of duplicating logic inside commands. ## Preflight Checklist