v0.6.13: emcn standardization, granola and ketch integrations, security hardening, connectors improvements#3802
v0.6.13: emcn standardization, granola and ketch integrations, security hardening, connectors improvements#3802waleedlatif1 merged 15 commits intomainfrom
Conversation
* chore: fix conflicts * chore: fix conflicts * chore: pause marquee * chore: fix conflicts * chore: fix conflicts * chore: address review comments * chore: fix conflicts * chore: other bug fixes * chore: fix conflicts * chore: fix radius * chore: fix review changes * chore: fix conflicts * chore: revert other * chore: fix conflicts * chore: fix review changes * chore: fix conflicts * chore: fix review changes * chore: fix button state * chore: fix button state * chore: fix review changes * chore: fix lint * chore: fix conflicts * chore: add metadata * chore: fix things * chore: fix overwritten states * chore: fix warnings * chore: fix button state * chore: fix review changes * chore: fix review changes * chore: fix hover state * chore: fix popover * chore: fix review changes * chore: fix review changes
* chore: fix conflicts * chore: update contents * chore: fix review changes
* chore(config): clean up bun, turbo, and next.js config * chore(ci): bump bun to 1.3.11 in dockerfiles and workflows
* chore: fix cn * chore: fix scale
* feat(granola): add Granola meeting notes integration * fix(granola): use string comparison for includeTranscript to avoid truthy string bug * fix(granola): add missing get_note output fields to block definition * regen docs
* feat(ketch): add Ketch privacy consent integration * fix(ketch): add response.ok guards and fix registry ordering * fix(ketch): include errorMessage in error response output for all tools * fix(ketch): wire optional purposes filter for get_consent operation
…es (#3792) * fix: prevent auth bypass via user-controlled context query param in file serve The /api/files/serve endpoint trusted a user-supplied `context` query parameter to skip authentication. An attacker could append `?context=profile-pictures` to any file URL and download files without auth. Now the public access gate checks the key prefix instead of the query param, and `og-images/` is added to `inferContextFromKey`. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: use randomized heredoc delimiter in SSH execute-script route Prevents accidental heredoc termination if script content contains the delimiter string on its own line. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: escape workingDirectory in SSH execute-command route Use escapeShellArg() with single quotes for the workingDirectory parameter, consistent with all other SSH routes (execute-script, create-directory, delete-file, move-rename). Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: harden chat/form deployment auth (OTP brute-force, CSPRNG, HMAC tokens) - Add brute-force protection to OTP verification with attempt tracking (CWE-307) - Replace Math.random() with crypto.randomInt() for OTP generation (CWE-338) - Replace unsigned Base64 auth tokens with HMAC-SHA256 signed tokens (CWE-327) - Use shared isEmailAllowed utility in OTP route instead of inline duplicate - Simplify Redis OTP update to single KEEPTTL call Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: harden SSRF protections and input validation across API routes Add DNS-based SSRF validation for MCP server URLs, secure OIDC discovery with IP-pinned fetch, strengthen OTP/chat/form input validation, sanitize 1Password vault parameters, and tighten deployment security checks. Co-Authored-By: Claude Opus 4.6 <[email protected]> * lint * fix(file-serve): remove user-controlled context param from authenticated path The `?context` query param was still being passed to `handleCloudProxy` in the authenticated code path, allowing any logged-in user to spoof context as `profile-pictures` and bypass ownership checks in `verifyFileAccess`. Now always use `inferContextFromKey` from the server-controlled key prefix. * fix: handle legacy OTP format in decodeOTPValue for deploy-time compat Add guard for OTP values without colon separator (pre-deploy format) to avoid misparse that would lock out users with in-flight OTPs. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(mcp): distinguish DNS resolution failures from SSRF policy blocks DNS lookup failures now throw McpDnsResolutionError (502) instead of McpSsrfError (403), so transient DNS hiccups surface as retryable upstream errors rather than confusing permission rejections. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: make OTP attempt counting atomic to prevent TOCTOU race Redis path: use Lua script for atomic read-increment-conditional-delete. DB path: use optimistic locking (UPDATE WHERE value = currentValue) with re-read fallback on conflict. Prevents concurrent wrong guesses from each counting as a single attempt. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: check attempt count before OTP comparison to prevent bypass Reject OTPs that have already reached max failed attempts before comparing the code, closing a race window where a correct guess could bypass brute-force protection. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: validate OIDC discovered endpoints against SSRF The discovery URL itself was SSRF-validated, but endpoint URLs returned in the discovery document (tokenEndpoint, userInfoEndpoint, jwksEndpoint) were stored without validation. A malicious OIDC issuer on a public IP could return internal network URLs in the discovery response. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: remove duplicate OIDC endpoint SSRF validation block Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: validate OIDC discovered endpoints and pin DNS for 1Password Connect - SSRF-validate all endpoint URLs returned by OIDC discovery documents before storing them (authorization, token, userinfo, jwks endpoints) - Pin DNS resolution in 1Password Connect requests using secureFetchWithPinnedIP to prevent TOCTOU DNS rebinding attacks Co-Authored-By: Claude Opus 4.6 <[email protected]> * lint * fix: replace KEEPTTL with TTL+EX for Redis <6.0 compat, add DB retry loop - Lua script now reads TTL and uses SET...EX instead of KEEPTTL - DB optimistic locking now retries up to 3 times on conflict Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: address review feedback on OTP atomicity and 1Password fetch - Replace Redis KEEPTTL with TTL+SET EX for Redis <6.0 compatibility - Add retry loop to DB optimistic lock path so concurrent OTP attempts are actually counted instead of silently dropped - Remove unreachable fallback fetch in 1Password Connect; make validateConnectServerUrl return non-nullable string Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: treat Lua nil return as locked when OTP key is missing When the Redis key is deleted/expired between getOTP and incrementOTPAttempts, the Lua script returns nil. Handle this as 'locked' instead of silently treating it as 'incremented'. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: handle Lua nil as locked OTP and add SSRF check to MCP env resolution - Treat Redis Lua nil return (expired/deleted key) as 'locked' instead of silently treating it as a successful increment - Add validateMcpServerSsrf to MCP service resolveConfigEnvVars so env-var URLs are SSRF-validated after resolution at execution time Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: narrow resolvedIP type guard instead of non-null assertion Replace urlValidation.resolvedIP! with proper type narrowing by adding !urlValidation.resolvedIP to the guard clause, so TypeScript can infer the string type without a fragile assertion. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: bind auth tokens to deployment password for immediate revocation Include a SHA-256 hash of the encrypted password in the HMAC-signed token payload. Changing the deployment password now immediately invalidates all existing auth cookies, restoring the pre-HMAC behavior. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: bind auth tokens to deployment password and remove resolvedIP non-null assertion - Include SHA-256 hash of encryptedPassword in HMAC token payload so changing a deployment's password immediately invalidates all sessions - Pass encryptedPassword through setChatAuthCookie/setFormAuthCookie and validateAuthToken at all call sites - Replace non-null assertion on resolvedIP with proper narrowing guard Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: update test assertions for new encryptedPassword parameter Tests now expect the encryptedPassword arg passed to validateAuthToken and setDeploymentAuthCookie after the password-binding change. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: format long lines in chat/form test assertions Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: pass encryptedPassword through OTP route cookie generation Select chat.password in PUT handler DB query and pass it to setChatAuthCookie so OTP-issued tokens include the correct password slot for subsequent validation. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
* fix(light): tag dropdown, code highlight * remove more hardcoded vals
…l connectors (#3793) * fix(knowledge): enqueue connector docs per-batch to survive sync timeouts * fix(connectors): convert all connectors to contentDeferred pattern and fix validation issues All 10 connectors now use contentDeferred: true in listDocuments, returning lightweight metadata stubs instead of downloading content during listing. Content is fetched lazily via getDocument only for new/changed documents, preventing Trigger.dev task timeouts on large syncs. Connector-specific fixes from validation audit: - Google Drive: metadata-based contentHash, orderBy for deterministic pagination, precise maxFiles, byte-length size check with truncation warning - OneDrive: metadata-based contentHash, orderBy for deterministic pagination - SharePoint: metadata-based contentHash, byte-length size check - Dropbox: metadata-based contentHash using content_hash field - Notion: code/equation block extraction, empty page fallback to title, reduced CHILD_PAGE_CONCURRENCY to 5, syncContext parameter - Confluence: syncContext caching for cloudId, reduced label concurrency to 5 - Gmail: use joinTagArray for label tags - Obsidian: syncRunId-based stub hash for forced re-fetch, mtime-based hash in getDocument, .trim() on vaultUrl, lightweight validateConfig - Evernote: retryOptions threaded through apiFindNotesMetadata and apiGetNote - GitHub: added contentDeferred: false to getDocument, syncContext parameter Infrastructure: - sync-engine: added syncRunId to syncContext for Obsidian change detection - confluence/utils: replaced raw fetch with fetchWithRetry, added retryOptions - oauth: added supportsRefreshTokenRotation: false for Dropbox - Updated add-connector and validate-connector skills with contentDeferred docs Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(connectors): address PR review comments - metadata merge, retryOptions, UTF-8 safety - Sync engine: merge metadata from getDocument during deferred hydration, so Gmail/Obsidian/Confluence tags and metadata survive the stub→full transition - Evernote: pass retryOptions {retries:3, backoff:500} from listDocuments and getDocument callers into apiFindNotesMetadata and apiGetNote - Google Drive + SharePoint: safe UTF-8 truncation that walks back to the last complete character boundary instead of splitting multi-byte chars Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(evernote): use correct RetryOptions property names maxRetries/initialDelayMs instead of retries/backoff to match the RetryOptions interface from lib/knowledge/documents/utils. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(sync-engine): merge title from getDocument and skip unchanged docs after hydration - Merge title from getDocument during deferred hydration so Gmail documents get the email Subject header instead of the snippet text - After hydration, compare the hydrated contentHash against the stored DB hash — if they match, skip the update. This prevents Obsidian (and any connector with a force-refresh stub hash) from re-uploading and re-processing unchanged documents every sync Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(sync-engine): dedup externalIds, enable deletion reconciliation, merge sourceUrl Three sync engine gaps identified during audit: 1. Duplicate externalId guard: if a connector returns the same externalId across pages (pagination overlap), skip the second occurrence to prevent unique constraint violations on add and double-uploads on update. 2. Deletion reconciliation: previously required explicit fullSync or syncMode='full', meaning docs deleted from the source accumulated in the KB forever. Now runs on all non-incremental syncs (which return ALL docs). Includes a safety threshold: if >50% of existing docs (and >5 docs) would be deleted, skip and warn — protects against partial listing failures. Explicit fullSync bypasses the threshold. 3. sourceUrl merge: hydration now picks up sourceUrl from getDocument, falling back to the stub's sourceUrl if getDocument doesn't set one. Co-Authored-By: Claude Opus 4.6 <[email protected]> * lint * fix(connectors): confluence version metadata fallback and google drive maxFiles guard - Confluence: use `version?.number` directly (undefined) in metadata instead of `?? ''` (empty string) to prevent Number('') = 0 passing NaN check in mapTags. Hash still uses `?? ''` for string interpolation. - Google Drive: add early return when previouslyFetched >= maxFiles to prevent effectivePageSize <= 0 which violates the API's pageSize requirement (1-1000). Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(connectors): blogpost labels and capped listing deletion reconciliation - Confluence: fetchLabelsForPages now tries both /pages/{id}/labels and /blogposts/{id}/labels, preventing label loss when getDocument hydrates blogpost content (previously returned empty labels on 404). - Sync engine: skip deletion reconciliation when listing was capped (maxFiles/maxThreads). Connectors signal this via syncContext.listingCapped. Prevents incorrect deletion of docs beyond the cap that still exist in source. fullSync override still forces deletion for explicit cleanup. - Google Drive & Gmail: set syncContext.listingCapped = true when cap is hit. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(connectors): set syncContext.listingCapped in all connectors with caps OneDrive, Dropbox, SharePoint, Confluence (v2 + CQL), and Notion (3 listing functions) now set syncContext.listingCapped = true when their respective maxFiles/maxPages limit is hit. Without this, the sync engine's deletion reconciliation would run against an incomplete listing and incorrectly hard-delete documents that exist in the source but fell outside the cap window. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(evernote): thread retryOptions through apiListTags and apiListNotebooks All calls to apiListTags and apiListNotebooks in both listDocuments and getDocument now pass retryOptions for consistent retry protection across all Thrift RPC calls. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
…earch (#3800) * feat(search): add tables, files, knowledge bases, and jobs to cmd-k search * fix(search): address PR feedback — drop files/jobs, add onSelect to memo * fix(search): add files back with per-file deep links, keep jobs out * fix(search): remove onSelect from memo comparator to match existing pattern
* Change modal field to be company size * Adjust dropdown options * Fix lint --------- Co-authored-by: Theodore Li <[email protected]>
* improvement(terminal): prevent canvas crashes * checkpoint * make persistence execution scoped not debounce * revert feature flags * address bugbot comments * fix test * fix * fix type * fix abortion of manual run * fix type errors * fix diff comment * fix chat history query * fix comment * Ignore previously executed tool call ids * fix eval input color * fix copilot run workflow * fix tests --------- Co-authored-by: Theodore Li <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Docs add new tool pages for Landing/auth UI polish standardizes many components to CSS variables ( Demo request flow tightens the schema to reject personal email domains, renames the “number of users” field to Written by Cursor Bugbot for commit ed56451. Configure here. |
… UI polish (#3803) * feat(generic): add generic resource tab, refactor home structure, and UI polish * reverted hardcoded ff * fix build * styling consistency * styling * fix(auth): extract shared auth button class and align SSO primary style - Extract AUTH_SUBMIT_BTN constant to (auth)/components/auth-button-classes.ts, replacing 10 copy-pasted identical className strings across 7 files - Update SSOLoginButton primary variant to use AUTH_SUBMIT_BTN instead of hardcoded purple gradient, making it consistent with all other auth form submit buttons - Fix missing isEphemeralResource import in lib/copilot/resources.ts (was re-exported but not available in local scope) * fix(auth): replace inline button class in chat auth components with AUTH_SUBMIT_BTN * fix send button hover state
Uh oh!
There was an error while loading. Please reload this page.