chore: upgrade Node.js runtime to v24 across codebase #419
Reference in New Issue
Block a user
Delete Branch "fix/auth-frontend-remediation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
All Dockerfiles and main CI pipelines already used node:24. This PR aligns the remaining stragglers.
Test Plan
- Token now includes HMAC binding to session ID - Validates session binding on verification - Adds CSRF_SECRET configuration requirement - Requires authentication for CSRF token endpoint - 51 new tests covering session binding security Security: CSRF tokens are now cryptographically tied to user sessions, preventing token reuse across sessions and mitigating session fixation attacks. Token format: {random_part}:{hmac(random_part + user_id, secret)} Refs #338 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>New package providing CLI tools that work with both Gitea and GitHub: Commands: - mosaic-issue-{create,list,view,assign,edit,close,reopen,comment} - mosaic-pr-{create,list,view,merge,review,close} - mosaic-milestone-{create,list,close} Features: - Auto-detects platform (Gitea vs GitHub) from git remote - Unified interface regardless of platform - Available via `pnpm exec mosaic-*` in monorepo context Updated docs/claude/orchestrator.md: - Added CLI Tools section with usage examples - Updated issue creation to use package commands This makes Mosaic Stack fully self-contained for orchestration tooling. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>Two fixes for CI test failures: 1. secret-scanner.service.spec.ts - "unreadable files" test: - The test uses chmod 0o000 to make a file unreadable - In CI (Docker), tests run as root where chmod doesn't prevent reads - Fix: Detect if running as root with process.getuid() and adjust expectations accordingly (root can still read the file) 2. demo/kanban/page.tsx - Build failure during static generation: - KanbanBoard component uses useToast() hook from @mosaic/ui - During Next.js static generation, ToastProvider context is not available - Fix: Wrap page content with ToastProvider to provide context Quality gates verified locally: - lint: pass - typecheck: pass - orchestrator tests: 612 passing - web tests: 650 passing (23 skipped) - web build: pass (/demo/kanban now prerendered successfully) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>SEC-WEB-27: Replace weak email.includes('@') check with RFC 5322-aligned programmatic validation (isValidEmail). Uses character-level domain label validation to avoid ReDoS vulnerabilities from complex regex patterns. SEC-WEB-28: Replace unsafe 'as WorkspaceMemberRole' type casts with runtime validation (toWorkspaceMemberRole) that checks against known enum values and falls back to MEMBER for invalid inputs. Applied in both InviteMember.tsx and MemberList.tsx. Adds 43 tests covering validation logic, InviteMember component, and MemberList component behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Link all Docker container packages to the mosaic/stack repository using Gitea's package API. This makes packages visible on the repository page and shows which repo they came from. API endpoint: /packages/{owner}/container/{name}/-/link/{repo_name} Links created for: - mosaic/api - mosaic/web - mosaic/postgres - mosaic/openbao - mosaic/orchestrator Each package will now show up in the repository's packages tab.Woodpecker interprets $ as variable substitution in YAML, so we need to use $$ to escape it and pass a literal $ to the shell script. Changed from a for loop to explicit function calls with escaped variables: - Use $$ instead of $ for all shell variables - Function-based approach for cleaner variable passing - Each package explicitly called: link_package "stack-api" etc. This fixes the variable expansion issue where ${package} was empty, resulting in URLs like "container//-/link/stack" (double slash). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Build step now depends on lint, typecheck, test, and security-audit so Docker images cannot be pushed when quality gates fail. Also corrects docker-compose.prod.yml image names to match pipeline (stack-api, stack-web, stack-postgres) and replaces hardcoded :latest with ${IMAGE_TAG:-latest}. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Add explicit @Inject("DOCKER_CLIENT") token to the Docker constructor parameter in DockerSandboxService. The @Optional() decorator alone was not suppressing the NestJS resolution error for the external dockerode class, causing the orchestrator container to crash on startup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>- docker/postgres/Dockerfile: build gosu from source with Go 1.26 via multi-stage build (eliminates 1 CRITICAL + 5 HIGH Go stdlib CVEs) - apps/{api,web,orchestrator}/Dockerfile: remove npm from production images (eliminates 5 HIGH CVEs in npm's bundled cross-spawn/glob/tar) - .trivyignore: trimmed from 16 to 5 CVEs (OpenBao only — 4 false positives from Go pseudo-version + 1 real Go stdlib waiting on upstream) Fixes #363 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Add SpeechController with POST /api/speech/transcribe for audio transcription and GET /api/speech/health for provider status. Uses AudioValidationPipe for file upload validation and returns results in standard { data: T } envelope. Includes 10 unit tests covering transcribe with options, error propagation, and all health status combinations. Fixes #392 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>BetterAuth defaulted basePath to /api/auth but NestJS controller routes to /auth/* (no global prefix). The auth client also pointed at the web frontend origin instead of the API server, and LoginButton used a nonexistent GET /auth/signin/authentik endpoint. - Set basePath: "/auth" in BetterAuth server config - Point auth client baseURL to API_BASE_URL with matching basePath - Add genericOAuthClient plugin to auth client - Use signIn.oauth2({ providerId: "authentik" }) in LoginButton Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>