diff --git a/claude_code_remaining_fixes_prompt.txt b/claude_code_remaining_fixes_prompt.txt new file mode 100644 index 0000000..70c19bc --- /dev/null +++ b/claude_code_remaining_fixes_prompt.txt @@ -0,0 +1,66 @@ +Work in the `platform` repo and use the existing Gitea issues as the source of truth. + +Repo: +- `yusiboyz/platform` + +Primary tracking issue: +- `#1 Production Security and Readiness Remediation` + +Current status from latest audit: +- Fixed: `#2` registration disable, frontend proxy auth, Trips share protection, Fitness authz repair, gateway cookie hardening, budget dependency fix +- Partial/Open: `#2`, `#5`, `#6`, `#7`, `#9`, `#10` + +Your job: +- Read issue `#1` and child issues `#2` through `#10` +- Re-verify the repo state before changing anything +- Then fix the remaining open items in priority order +- Make code changes directly +- After each issue-sized change, verify it and post a concise Gitea comment with: + - what changed + - files touched + - verification performed + - what still remains, if anything +- Close only issues whose acceptance criteria are fully satisfied + +Priority order: +1. `#6 Repository Hygiene: Remove Tracked Secrets and Runtime Databases` +2. `#7 Transport Security: Finish Cookie Hardening, TLS Verification, and Proxy Controls` +3. `#2 Auth Boundary: Registration and Default Credentials` +4. `#5 Gateway Trust Model: Protect Internal Services and Service-Level Data` +5. `#10 Deployment Hardening: Containers, Health Checks, and Production Readiness` +6. `#9 Performance Hardening: Cache and De-risk Summary Endpoints` + +Specific required fixes: +- `#6` + - Stop tracking live `.env` and `.db` artifacts + - Add or correct ignore rules + - Replace tracked secrets with safe example/config templates where needed + - Clearly separate code changes from any manual secret rotation steps +- `#7` + - Remove insecure internal TLS config that disables hostname/cert verification + - Keep secure cookie behavior consistent across login/logout and relevant services +- `#2` + - Enforce fail-fast startup for missing required auth secrets where appropriate + - Remove remaining weak/default credential behavior from runtime config paths +- `#5` + - Reduce gateway service-global trust where feasible + - Tighten internal service auth expectations and documentation + - Remove or protect remaining overly permissive internal/debug surfaces +- `#10` + - Harden remaining Dockerfiles, especially Node services + - Add health checks and non-root users where missing +- `#9` + - Address the worst full-scan summary endpoints first + - Prefer targeted, minimal performance fixes over broad refactors + +Constraints: +- Do not revert unrelated user changes +- Keep changes minimal and production-oriented +- Do not claim something is fixed unless code and verification support it +- If a fix requires an ops action outside the repo, note it explicitly in the issue comment and final summary + +Final output format: +- `Completed:` issue numbers fully resolved +- `Partial:` issue numbers partially resolved and what remains +- `Blocked:` issue numbers blocked and why +- `Manual ops actions:` exact actions still required outside code diff --git a/frontend-v2/Dockerfile b/frontend-v2/Dockerfile index 9ae0438..e77d5f5 100644 --- a/frontend-v2/Dockerfile +++ b/frontend-v2/Dockerfile @@ -1,15 +1,22 @@ +FROM node:20-alpine AS builder + +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY . . +RUN npm run build + FROM node:20-alpine WORKDIR /app - -COPY package*.json ./ -RUN npm install - -COPY . . - -RUN npm run build +COPY --from=builder /app/build ./build +COPY --from=builder /app/package.json ./ +COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 +ENV NODE_ENV=production +HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD wget -qO- http://localhost:3000/ || exit 1 + +USER node CMD ["node", "build"] - diff --git a/gateway/config.py b/gateway/config.py index 2c28e90..bdc168f 100644 --- a/gateway/config.py +++ b/gateway/config.py @@ -68,5 +68,3 @@ _internal_ssl_ctx = ssl.create_default_context() _internal_ssl_ctx.check_hostname = False _internal_ssl_ctx.verify_mode = ssl.CERT_NONE -# Legacy alias — to be removed once all callers are updated -_ssl_ctx = _internal_ssl_ctx diff --git a/gateway/proxy.py b/gateway/proxy.py index 6b80a59..e77707b 100644 --- a/gateway/proxy.py +++ b/gateway/proxy.py @@ -6,7 +6,7 @@ import json import urllib.request import urllib.error -from config import _ssl_ctx +from config import _internal_ssl_ctx from database import get_db @@ -17,7 +17,7 @@ def proxy_request(target_url, method, headers, body=None, timeout=120): for k, v in headers.items(): req.add_header(k, v) - with urllib.request.urlopen(req, context=_ssl_ctx, timeout=timeout) as resp: + with urllib.request.urlopen(req, context=_internal_ssl_ctx, timeout=timeout) as resp: resp_body = resp.read() resp_headers = dict(resp.headers) return resp.status, resp_headers, resp_body diff --git a/services/budget/Dockerfile b/services/budget/Dockerfile index 37dccd6..75eda74 100644 --- a/services/budget/Dockerfile +++ b/services/budget/Dockerfile @@ -2,13 +2,17 @@ FROM node:20-alpine WORKDIR /app -COPY package.json ./ -RUN npm install --production +COPY package.json package-lock.json ./ +RUN npm ci --production COPY server.js ./ -RUN mkdir -p /app/data +RUN mkdir -p /app/data && chown -R node:node /app/data EXPOSE 3001 +ENV NODE_ENV=production +HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD wget -qO- http://localhost:3001/health || exit 1 + +USER node CMD ["node", "server.js"] diff --git a/services/budget/server.js b/services/budget/server.js index 6d5c0cc..e35689d 100644 --- a/services/budget/server.js +++ b/services/budget/server.js @@ -11,6 +11,9 @@ const app = express(); app.use(cors()); app.use(express.json()); +// Health check (before auth middleware) +app.get('/health', (req, res) => res.json({ status: 'ok', ready })); + // API key auth middleware — require X-API-Key header on all routes const SERVICE_API_KEY = process.env.SERVICE_API_KEY || ''; if (SERVICE_API_KEY) { diff --git a/services/inventory/Dockerfile b/services/inventory/Dockerfile index 54ccd10..f71c0cf 100644 --- a/services/inventory/Dockerfile +++ b/services/inventory/Dockerfile @@ -2,17 +2,15 @@ FROM node:18-alpine WORKDIR /app -# Copy package files COPY package*.json ./ +RUN npm install --production -# Install dependencies -RUN npm install +COPY server.js ./ -# Copy application files -COPY . . - -# Expose port EXPOSE 3000 +ENV NODE_ENV=production -# Start the application +HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD wget -qO- http://localhost:3000/health || exit 1 + +USER node CMD ["node", "server.js"] diff --git a/services/inventory/server.js b/services/inventory/server.js index 4dfeb17..5387cdc 100755 --- a/services/inventory/server.js +++ b/services/inventory/server.js @@ -27,6 +27,9 @@ app.use(express.json()); // Allow form-encoded payloads from NocoDB webhook buttons app.use(express.urlencoded({ extended: true })); +// Health check (before auth middleware) +app.get('/health', (req, res) => res.json({ status: 'ok' })); + // API key auth middleware — require X-API-Key header on all routes const SERVICE_API_KEY = process.env.SERVICE_API_KEY || ''; if (SERVICE_API_KEY) {