b1d5fbefcba02fdc6c19fef85cec1c4e82fc8dea
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0c063c23fb |
harden(421,559): percent-encode access_token in IPTV URLs, redact from logs, no-store on tokened manifests (#574)
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 7m45s
Build ErsatzTV Image / Functional E2E (curl contracts) (push) Successful in 14m19s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 18m27s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m10s
Co-authored-by: Timothy <timothy.look@gmail.com> Co-committed-by: Timothy <timothy.look@gmail.com> |
||
|
|
2609b4ce59 |
fix: add cross-origin resource policy header
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 7s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 7s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 19s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 1m29s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m15s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 5m26s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Docs update reminder (push) Has been skipped
Build ErsatzTV Image / decisions.md append-only (push) Has been skipped
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Failing after 7s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 3m44s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been skipped
Fixes #330 Co-Authored-By: Codex <noreply@openai.com> |
||
|
|
682dceec8f |
fix(api): #286 review — allowlist non-/api routes in the versioning test; base-url-aware deprecation Link
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 9s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 9s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 3m5s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 2m6s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 4m11s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 8m2s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Docs update reminder (push) Has been skipped
Build ErsatzTV Image / decisions.md append-only (push) Has been skipped
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Has been skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Has been skipped
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 3m49s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 7m12s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 5m43s
Cold-fork + Codex review of PR #326: - ApiRouteVersioningTests: iterate IRouteTemplateProvider (covers a template-less [HttpGet] paired with an action-level [Route]) and assert any non-/api route against an explicit KnownNonApiRoutes allowlist instead of silently skipping — an accidental absolute non-/api route (which would also escape ApiAuthorizationFilter's /api-scoped gate) now fails the test. - ApiVersionRewriteMiddleware: root the deprecation Link at Request.PathBase so it stays correct under ETV_BASE_URL (</etv/docs>, not host-root </docs>). refs #286 #197 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ef2bd65c27 |
feat(api): #286 — mount the whole /api surface at /api/v1
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 10s
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 10s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 1m12s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 3m4s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 8m17s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 10m36s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Version every /api route to /api/v1 (251 controller routes + ~24 Location
headers + the scanner callback URL + the Startup request-log literal),
uniform across the machine API, auth, scanner and scripted-build surfaces.
Add ApiVersionRewriteMiddleware: a legacy unversioned /api/* request is
rewritten (NOT redirected) to /api/v1/* in-pipeline — method, body, auth
headers and query survive — carrying RFC 8594 Deprecation/Sunset headers,
so curl / the future MCP server / bookmarks keep working. An already-
versioned path passes through; a future /api/v2 is never forced to v1.
Standardize the route convention (leading-slash absolute route per method,
no class-[Route] — except the two Scanner/Scripted controllers whose ~all
actions share a parametrized {id} prefix), enforced by ApiRouteVersioningTests
(^/api/v\d+/ over the whole Controllers.Api surface; browser-nav
/auth/oidc/login is out of scope).
Regenerate v1.json (160 paths, all /api/v1)/endpoint-index/v1.d.ts; sweep 945
SPA request literals + the test mocks (regex + positional URL parsers). /api/v1
is additive-only after freeze; the legacy-rewrite shim sunsets in ~2 releases
(owner decision) with removal tracked as a Phase-3 follow-up.
Docs: decisions.md 2026-07-13, api-conventions §1/§9, rest-api/spa-conventions/
blazor-route-parity/e2e-local/domain-model.
fixes #286
refs #197
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
873b3e54a5 |
security(#319): enforcing CSP + Permissions-Policy on the host
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 11s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 11s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 13s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 1m48s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 3m49s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 8m16s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Completes the CSP the #279 baseline-headers middleware deferred. Surfaced by the #314 ZAP baseline (missing CSP/Permissions-Policy WARNs); a #197 exit item. SecurityHeadersMiddleware now also sets Permissions-Policy (deny-all for camera/mic/geolocation/payment/usb) and an enforcing Content-Security-Policy on every response EXCEPT /docs (Scalar) and /openapi — those rely on inline bootstrap scripts/styles a strict policy would break (baseline headers still apply; hardening that admin surface is a #197 follow-up). CSP: default-src 'self'; script-src 'self' + the hash of the SPA's inline theme-bootstrap script (no 'unsafe-inline'/'unsafe-eval'); style-src adds 'unsafe-inline' (React inline styles) + fonts.googleapis.com; font-src adds fonts.gstatic.com; img-src adds data:/blob:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'. The Google Fonts allowance (the SPA CSS @imports the Geist web font) was caught by live-E2E, which the static recon missed. A guard test hashes the committed web/index.html inline script and fails if it drifts from the middleware constant (the built wwwroot/app is gitignored/absent in CI, and Vite copies the inline script verbatim). Verified: full test pass, live-E2E (SPA renders clean, zero CSP violations), curl (CSP present on /app + /api, absent on /docs + /openapi). Docs: docs/decisions.md entry. fixes #319 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
c55a7fda36 |
security(#197): constant-time API-key compare, clamp playout paging, baseline security headers
Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 7s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m15s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 6m15s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Build ErsatzTV Image / Docs update reminder (push) Has been skipped
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 8m13s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 9m43s
Build ErsatzTV Image / Build & push image (amd64) (push) Has been cancelled
Posture-independent safe hardening from the #197 cold API security review (the clear-cut fixes that don't depend on the fail-closed/CORS/versioning posture design, which is tracked separately): - ApiKeyAuthorizationFilter: compare X-Api-Key with CryptographicOperations.FixedTimeEquals instead of ordinal string.Equals (removes the response-timing oracle on the write key). [S10] - PlayoutController: clamp pageNum/pageSize on GET /api/playouts and /api/playouts/{id}/items to Math.Clamp(_, 1, 100), matching the documented api-conventions §1 convention every other paged endpoint already follows — these two were passing the raw value straight to EF Take(). [S8] - SecurityHeadersMiddleware: emit X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin on every response (nosniff backstops the artwork content-type MIME-sniffing risk). CSP/HSTS deferred to the #197 posture design (CSP needs SPA validation; HSTS is proxy/TLS-owned). [S10] Refs #197. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |