v0.6.80: security hardening, nextjs minor version bump, cloudwatch tools, seo fixes#4608
Conversation
… tx (#4593) * v0.6.29: login improvements, posthog telemetry (#4026) * feat(posthog): Add tracking on mothership abort (#4023) Co-authored-by: Theodore Li <[email protected]> * fix(login): fix captcha headers for manual login (#4025) * fix(signup): fix turnstile key loading * fix(login): fix captcha header passing * Catch user already exists, remove login form captcha * improvement(db): add session statement/lock timeouts; simplify KB doc tx * fix(knowledge): close soft-delete TOCTOU on KB document insert Fix the race the bots flagged: KB delete is soft (`deletedAt = now`) so the FK can't catch a concurrent KB delete between the existence check and the document insert. - Add `insertDocumentsIfKbAlive` helper that gates the insert on `EXISTS(SELECT 1 FROM knowledge_base WHERE id=$kb AND deleted_at IS NULL)` in the same statement via INSERT...SELECT...WHERE EXISTS. Atomic at the MVCC snapshot — no transaction, no row lock. - Use jsonb_to_recordset to declare column types once, avoiding per-param casts for nullable columns. - Wire into both `createDocumentRecords` (bulk) and `createSingleDocument`. - Keep the upfront KB existence check as a fast-path early-out for the common case; the atomic insert is the race guard. --------- Co-authored-by: Waleed <[email protected]> Co-authored-by: Siddharth Ganesan <[email protected]> Co-authored-by: Vikhyath Mondreti <[email protected]>
* fix(seo): use canonical SITE_URL for robots and sitemap * fix(seo): drop /templates from sitemap and guard robots/sitemap in seo test
* improvement(scheduler): drain in chunks instead of a single capped claim Replaces the fixed MAX_CRON_CLAIMS (200) with a chunked drain loop: claim WORKFLOW_CHUNK_SIZE + JOB_CHUNK_SIZE per iteration, process via Promise.allSettled, repeat until both claim queries return empty or MAX_TICK_DURATION_MS elapses. Throughput is no longer bounded by a static per-tick ceiling; it scales until DB or trigger.dev is the limit. Per-iteration chunk size still bounds row-lock set and fan-out concurrency. Extracts processScheduleItem and processJobItem so the loop body stays readable. Existing claim semantics (FOR UPDATE SKIP LOCKED, lastQueuedAt as the claim signal, staleness reclaim) are unchanged. * improvement(scheduler): skip claim once a queue is exhausted and drop workflowUtils non-null assertion Addresses Greptile review on PR #4578: - track per-queue exhaustion when a claim returns fewer than CHUNK_SIZE rows; subsequent iterations skip the claim query for that queue. Saves one DB round-trip per iteration once one queue drains while the other is still working. - narrow workflowUtils to a local const inside the loop body so the schedule processing branch only runs when the import has completed. Removes the misleading non-null assertion.
…ck get_message ts (#4600) * fix(integrations): gdrive trashed search, slack blocks-with-file, slack get_message ts - Google Drive search/list: skip default `trashed = false` when user query already specifies a `trashed = ...` predicate, so trashed-file searches work. - Slack send-message with files: forward `blocks` through to `files.completeUploadExternal` so Block Kit renders when files are attached. - Slack get_message: switch from `conversations.history` (oldest lower-bound returned the next message after) to `conversations.replies` with `ts=` for exact-match lookup, plus a defensive ts-equality guard and clearer error. * fix(google_drive): revert list.ts trashed guard — query is plain text, not gdrive syntax * fix(slack): omit initial_comment when blocks present so Block Kit actually renders on file uploads
…ounds (#4601) * fix(security): harden file access controls, webhook auth, and input bounds * fix(security): extend file access checks to remaining tool routes * fix(logs): address PR review comments on time filter * fix(logs): set end-time milliseconds to 999 for datetime filter strings * fix(files): return 404 instead of 500 on file access denial in utility paths * remove tooltip from resource tabs
* chore(deps): bump next to 16.2.5 for CVE-2026-44578 SSRF fix * chore(deps): bump next to 16.2.6 for full May 2026 security release coverage
…rage quota coverage (#4605) * fix(security): supabase rpc path validation, ssh stream byte cap, storage quota coverage * fix(security): scope execution log writes to owning workflow; add env-var workspace membership guard Closes two cross-tenant vulnerabilities: 1. Workflow log cross-tenant write (route.ts + logging-session.ts): - Route: SELECT before creating LoggingSession to verify executionId belongs to the claimed workflowId; reject with 404 if owned by a different workflow. - LoggingSession: add workflow_id to all UPDATE/SELECT WHERE clauses (raw SQL marker queries, flushAccumulatedCost, loadExistingCost) so writes are a no-op if executionId was somehow injected. 2. Env-var workspace membership guard (environment/utils.ts): - getPersonalAndWorkspaceEnv now calls checkWorkspaceAccess when workspaceId is provided; throws if the userId is not a member, preventing any future caller from reading another workspace's decrypted secrets without explicit membership verification at the call site. * fix(security): remove fileSize > 0 quota bypass gate; exempt logs context from quota * chore: remove extraneous inline comments * fix(security): scope markExecutionAsFailed UPDATE by workflowId; thread workflowId through HITL callers * fix(security): add personal credential ownership check in sharepoint site route; scope markExecutionAsFailed by workflowId * fix: remove logs from user-accessible upload contexts; restore distinct biome .next glob * fix(sharepoint): migrate site route to authorizeCredentialUse The previous fix only checked userId equality for personal credentials and workspace membership (via getUserEntityPermissions) for workspace credentials. authorizeCredentialUse additionally enforces credentialMember access for workspace-scoped credentials, matching the standard pattern used by all other tool selector routes. * fix(logging): make workflowId required in markExecutionAsFailed Making workflowId optional left a footgun — future callers could silently omit it and the WHERE clause would degrade to executionId-only, losing the cross-tenant scoping guarantee. All callers already supply workflowId, so making it required (with string | undefined for the middle params to keep call sites unchanged) closes the gap without touching any caller. * test(security): add tests for cross-tenant log guard, quota bypass fix, and workflowId scoping - log/route.test.ts: verifies cross-tenant executionId guard returns 404 when the execution belongs to a different workflow, and passes for same workflow or fresh executions - multipart/route.test.ts: verifies fileSize:0 no longer bypasses quota check and that the logs context is rejected at the endpoint level - logging-session.test.ts: verifies markExecutionAsFailed scopes by both executionId and workflowId, and that the instance method forwards workflowId * fix(lint): move IconComponent outside ToolInput to fix noNestedComponentDefinitions * fix(logging): scope completeWithCancellation and completeWithPause reads by workflowId Both SELECT queries that check execution status before writing a terminal result were only filtering on executionId. Adds workflowId to the WHERE clause so all seven reads and writes in LoggingSession consistently scope by (workflowId, executionId).
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryHigh Risk Overview Limits & quota: Enforces storage quota checks for multipart upload initiation across contexts (with exemptions) and disallows New capability: Introduces CloudWatch Operational/UI fixes: Refactors schedule execution to claim due schedules/jobs in chunks with a per-tick time budget; fixes robots/sitemap to use Reviewed by Cursor Bugbot for commit 922de38. Configure here. |
Greptile SummaryThis release bundles a broad security hardening pass, a new CloudWatch mute/unmute feature, scheduler throughput improvements, and a date-picker re-render fix across 87 files.
Confidence Score: 5/5The changes are safe to merge — every security fix is narrowly scoped, all markExecutionAsFailed callers were updated for the new required workflowId parameter, and the scheduler refactor maintains the same claim-then-process contract. The PR is a well-executed security pass. File-ownership checks are consistent across all updated routes, the WhatsApp timing fix is guarded correctly, the SQL raw-string replacement is accurate, and the logging-session WHERE-clause additions cover every query in the class. The CloudWatch feature follows existing tool patterns exactly. No functional regressions were identified. No files require special attention. Important Files Changed
Reviews (3): Last reviewed commit: "fix(date-picker): eliminate infinite re-..." | Re-trigger Greptile |
|
@greptile |
|
@cursor review |
…existing selection (#4609) * docs(uploads): clarify QUOTA_EXEMPT_STORAGE_CONTEXTS logs entry in JSDoc * fix(date-picker): eliminate infinite re-render on re-open with existing selection The useEffect that syncs picker state on open had initialStart and initialEnd — Date objects computed on every render — in its dependency array. Because Object.is returns false for any two distinct Date instances, the effect fired on every render when open=true, calling setRangeStart/setRangeEnd and triggering another render, producing an infinite loop that crashed the page. Fix: compute start and end as local variables inside the effect and use the stable string props (props.startDate, props.endDate) as deps instead. Also removes the redundant typeof fileSize === 'number' guard in the multipart quota check — fileSize is z.number() (required) in the contract so it can never be undefined at that point. * refactor(date-picker): comprehensive cleanup and reliable crash fix The previous fix still had derived Date objects in useEffect deps. Object.is(new Date(), new Date()) === false, so any Date in deps causes the effect to run every render, reproducing the infinite loop on re-open with existing time selection. Key changes: - useEffect deps now use only stable primitives (startDate, endDate strings) and compute Date values inside the effect — eliminating the loop - Replace `rest as any` with a FlatDatePickerProps merged type for safe, typed destructuring across the discriminated union - Remove initialStart/initialEnd render-scope variables; compute inline or inside effects to keep derivation local to each use site - Callbacks use destructured props (onChange, onRangeChange, etc.) instead of props.x references - Remove verbose TSDoc on internal callbacks — names are self-documenting - Preserve all existing JSX structure and CalendarMonth logic unchanged
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 922de38. Configure here.
…width (#4611) * fix(gmail): send emails as multipart/alternative so they render full-width * fix(gmail): decode & last in htmlToPlainText to avoid double-decoding compound entities * fix(gmail): encode body parts as base64 and decode numeric HTML entities
…4613) * improvement(gmail): replace custom html-to-text regex with html-to-text library Resolves 4 CodeQL alerts on htmlToPlainText (incomplete tag/entity handling, unsafe regex backtracking). Delegates to the html-to-text npm package already used by the outlook polling trigger and the mail/send route. * improvement(gmail): match outlook selectors config, add nbsp/anchor tests Aligns html-to-text options with apps/sim/lib/webhooks/polling/outlook.ts: suppress anchor hrefs when identical to text, drop bare # anchors, skip img/script/style content. Adds tests for nbsp preservation and anchor behavior.
Uh oh!
There was an error while loading. Please reload this page.