Commit Graph

1066 Commits

Author SHA1 Message Date
0xjjjjjj
7adadd5c88 fix: use data-cy selector for sidebar backdrop in e2e tests
The aria-hidden="true" selector matched 27 elements (icons, etc.)
causing cy.click() to fail. Add data-cy="sidebar-backdrop" to the
overlay div and target that specifically in tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:01:31 -07:00
0xjjjjjj
fab19ed5aa fix: use correct DashboardMetrics shape in mobile sidebar e2e stubs
The dashboard page accesses metrics.throughput.primary.points which
requires the full DashboardMetrics type structure. The original stub
returned a flat object with wrong fields, causing TypeError in all
authenticated tests. Also adds stubs for boards, agents, activity,
gateways, and board-groups APIs that the dashboard and boards pages
query on load.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 09:41:49 -07:00
Abhimanyu Saharan
162b820880 Merge branch 'master' into fix/mobile-responsive 2026-03-08 12:58:59 +05:30
Abhimanyu Saharan
fe6ff69d5c Merge pull request #253 from 0xjjjjjj/fix/dockerfile-chown-only
perf: replace chown -R with COPY --chown in Dockerfiles
2026-03-08 12:58:37 +05:30
0xjjjjjj
fad1e99329 test: add Cypress e2e tests for mobile sidebar behavior
Cover auth negative, viewport responsiveness, toggle open/close,
backdrop dismiss, navigation auto-close, and Escape key dismiss.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:42:05 -08:00
0xjjjjjj
3bc4dcaf55 fix: normalize sidebar width to 260px, add responsive padding to approvals
Align desktop sidebar width (was w-64/256px) with header column and
grid template (both 260px). Apply missing p-4 md:p-6 responsive
padding to the global approvals page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:28:58 -08:00
0xjjjjjj
74792593b2 fix: reset sidebar state on navigation to prevent ghost re-open
Use React's canonical "store info from previous renders" pattern:
conditional setState during render resets sidebar when pathname
changes, preventing the sidebar from re-opening on back-navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:28:55 -08:00
0xjjjjjj
2519af2395 fix: use derived state for sidebar close on navigation
Replace useRef-based previous pathname tracking (which violated
react-hooks/refs) with a derived state pattern. Sidebar state stores
{open, path} and sidebarOpen is computed as a pure expression,
avoiding both set-state-in-effect and refs-during-render lint errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:20:37 -08:00
0xjjjjjj
9396be6fc0 fix: chown /app directory after user creation
Ensure the /app WORKDIR itself is owned by appuser (not just copied
files), preventing runtime failures if the app writes to /app directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:45:25 -08:00
0xjjjjjj
42368f84bf perf: replace chown -R with COPY --chown in both Dockerfiles
Move user/group creation before COPY statements so --chown flag can
set ownership at copy time, avoiding the slow recursive chown on
overlay2 filesystems (docker/for-linux#388).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:38:09 -08:00
0xjjjjjj
f0ab3e315b fix: address Copilot review — z-index, Escape key, signed-out UX
- Raise header to z-50 so toggle button stays clickable above backdrop
- Use document keydown listener for Escape instead of onKeyDown on backdrop
- Only render hamburger toggle when signed in
- Make SignedOutPanel col-span responsive (col-span-1 on mobile)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:19:39 -08:00
0xjjjjjj
7a0eb7b24a fix: avoid setState in useEffect for sidebar close on navigation
Use ref-based previous pathname check instead of useEffect + setState,
which triggers the react-hooks/set-state-in-effect lint rule.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:18:08 -08:00
0xjjjjjj
e85e714076 fix: bump mobile sidebar z-index above sticky page headers
Sidebar and backdrop were z-30, same as sticky page headers (live feed,
boards, etc.), causing the hamburger menu to render behind page content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:11:22 -08:00
0xjjjjjj
ea0149bd88 fix: mobile-responsive layout for dashboard and board views
Add hamburger menu with off-canvas sidebar drawer on mobile.
Responsive padding, full-width panels, and stacked layouts
for screens under 768px (md breakpoint).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:11:22 -08:00
Abhimanyu Saharan
fa445127d9 Merge pull request #242 from abhi1693/abhi1693/fix/security-review-hardening
fix(security): Replay PR 207 with follow-up fixes
2026-03-08 00:18:01 +05:30
Abhimanyu Saharan
793c8983cb fix(ci): sort rate limit test imports 2026-03-08 00:06:45 +05:30
Abhimanyu Saharan
cc3024acc3 fix(security): Address PR review feedback 2026-03-08 00:01:23 +05:30
Abhimanyu Saharan
b3cb604776 Merge branch 'master' into abhi1693/fix/security-review-hardening 2026-03-07 23:47:27 +05:30
Abhimanyu Saharan
6d2ff60a82 fix(security): Stop logging raw trusted proxy entries 2026-03-07 23:47:00 +05:30
Abhimanyu Saharan
46bc9a02c6 fix(security): Keep short agent token prefixes in logs
Restore the existing short token-prefix logging behavior for agent auth failures while keeping the optional bearer-path rate-limit fix. Update tests and docs so the replacement branch reflects the intended logging policy.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-07 23:43:32 +05:30
Abhimanyu Saharan
fb8a932923 fix(security): Close review follow-up gaps
Rate-limit the optional agent bearer path after user auth resolution so mixed user/agent routes no longer leave an unthrottled PBKDF2 path. Stop logging token prefixes on agent auth failures and require a locally supplied token for backend/.env.test instead of committing one.

Update tests and docs to cover agent bearer fallback, configurable webhook signature headers, and the operator-facing security settings added by the hardening work.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-07 23:40:50 +05:30
Hugh Brown
355bed1b40 Update backend/app/api/board_webhooks.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
370256a4fd Update backend/.env.test
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
e80cf9f3c8 fix: suppress mypy no-untyped-call for redis.asyncio.from_url
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
e053fd4a46 fix: share a single async Redis client per URL to avoid duplicate connection pools
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
a30b94c887 fix: redact credentials from Redis URL in rate-limit error messages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
c5716897d7 fix: add BASE_URL to migration check env vars in Makefile
The BASE_URL validation added to Settings breaks the CI migration check
which only sets AUTH_MODE, LOCAL_AUTH_TOKEN, and DATABASE_URL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
5989adedea Apply ruff reformatting 2026-03-07 23:35:10 +05:30
Hugh Brown
bafc736e03 test: make Settings construction hermetic in security header tests
Use _env_file=None and explicit base_url so tests don't depend on
global env vars or .env file loading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
6af02f6b75 fix: align in-memory rate limiter to count blocked attempts like Redis
Always append the timestamp before checking the count so that sustained
spam extends the window, matching the Redis backend's zadd-before-zcard
semantics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
6b55b52a68 refactor: switch RedisRateLimiter to async redis.asyncio client
Replace sync redis.Redis with redis.asyncio to avoid blocking the
event loop during rate-limit checks. Make RateLimiter.is_allowed async
across both backends and update all call sites to await.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
b4bbe1c657 fix: chain Alembic migrations to avoid multiple heads
Set a9b1c2d3e4f7.down_revision = "a1b2c3d4e5f6" so the activity_events
migration depends on the webhook_secret migration, creating a linear
chain instead of two heads from the same parent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
0a749db2c4 Remove unused imports 2026-03-07 23:35:10 +05:30
Hugh Brown
3f333e1592 Add isort fix 2026-03-07 23:35:10 +05:30
Hugh Brown
dc25a9df6b fix: fail fast when RATE_LIMIT_BACKEND=redis but no Redis URL is configured
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
f1bcf72810 feat: add trusted client-IP extraction from proxy headers
Add get_client_ip() helper that inspects Forwarded and X-Forwarded-For
headers only when the direct peer is in TRUSTED_PROXIES (comma-separated
IPs/CIDRs). Replaces raw request.client.host in rate-limit and webhook
source_ip to prevent all traffic collapsing behind a reverse proxy IP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
24e40f1153 docs: update operations README for configurable rate-limit backend
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
494bf4649e docs: update api.md and authentication.md for Redis rate-limit backend and token logging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
72241d6870 Correct import order 2026-03-07 23:35:10 +05:30
Hugh Brown
81d16a324b docs: update security.md for Redis rate-limit backend and token logging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
77f73872eb fix: scope optional agent auth rate limiting to X-Agent-Token header only
Prevents normal user requests with Authorization: Bearer from being
throttled by the agent auth limiter in the shared require_user_or_agent
dependency path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
ac69c6b7b8 fix: normalize and validate signature_header in webhook schemas
Strip whitespace (blank → None) and reject non-ASCII-token characters
to prevent impossible header lookups that would fail all signed requests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
fe310b50dc Apply black fixes 2026-03-07 23:35:10 +05:30
Hugh Brown
fc9fc1661c feat: add Redis-backed rate limiter with configurable backend
Add RedisRateLimiter using sorted-set sliding window alongside the
existing InMemoryRateLimiter. Users choose via RATE_LIMIT_BACKEND
(memory|redis) with RATE_LIMIT_REDIS_URL falling back to RQ_REDIS_URL.
Redis backend validates connectivity at startup and fails open on
transient errors during requests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
ee825fb2d5 docs: fix gateway token description in openclaw_gateway_ws.md to match actual behavior
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
528a2483b7 feat: add configurable signature_header for webhook HMAC verification
Not all webhook providers use X-Hub-Signature-256 or X-Webhook-Signature.
Add an optional signature_header field so users can specify which header
carries the HMAC signature. When set, that exact header is checked;
when unset, the existing auto-detect fallback is preserved. The custom
header is also excluded from stored/exposed payload headers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
ce18fe4f0c fix: apply rate limiting to optional agent auth path
get_agent_auth_context_optional was not rate-limited, allowing
brute-force token guessing via routes that use require_user_or_agent.
Now applies agent_auth_limiter when a token is actually presented.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
84a5d8677e docs: update security.md to reflect current gateway token behavior
The has_token redaction was reverted to avoid a frontend breaking
change. Update docs to match: tokens are currently returned in API
responses, redaction is planned for a future PR. Also note the
configurable payload size limit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
a66765a514 Apply ruff fixes 2026-03-07 23:35:10 +05:30
Hugh Brown
0896b0772d Import linting 2026-03-07 23:35:10 +05:30