v0.6.52: data retention, docs updates, slack manifest generator, security hardening, contact page, 404 page, access control, SES, SNS#4249
v0.6.52: data retention, docs updates, slack manifest generator, security hardening, contact page, 404 page, access control, SES, SNS#4249waleedlatif1 wants to merge 18 commits intomainfrom
Conversation
…nd auth flows (SSRF + open-redirect hardening) (#4236) * fix(workday): validate tenantUrl to prevent SSRF in SOAP client * fix(workday): use validation.sanitized in buildWsdlUrl * fix(security): enforce URL validation across connectors, providers, auth - Azure OpenAI/Anthropic: validate user-supplied azureEndpoint with validateUrlWithDNS to block SSRF to private IPs, localhost (in hosted mode), and dangerous ports. - ServiceNow connector: enforce ServiceNow domain allowlist via validateServiceNowInstanceUrl before calling the instance URL. - Obsidian connector: validate vaultUrl with validateUrlWithDNS and reuse the resolved IP via secureFetchWithPinnedIPAndRetry to block DNS rebinding between validation and request. - Signup + verify flows: pass redirect/callbackUrl/redirectAfter and stored inviteRedirectUrl through validateCallbackUrl; drop unsafe values and log a warning. - lib/knowledge/documents/utils.ts: add secureFetchWithPinnedIPAndRetry wrapper around secureFetchWithPinnedIP (used by Obsidian). * fix(obsidian): use isomorphic SSRF validation to unblock client build The Obsidian connector is reachable from client bundles via `connectors/registry.ts` (the knowledge UI reads metadata like `.icon`/`.name`). Importing `validateUrlWithDNS` / `secureFetchWithPinnedIP` from `input-validation.server` pulled `dns/promises`, `http`, `https`, `net` into client chunks, breaking the Turbopack build: Module not found: Can't resolve 'dns/promises' ./apps/sim/lib/core/security/input-validation.server.ts [Client Component Browser] ./apps/sim/connectors/obsidian/obsidian.ts [Client Component Browser] ./apps/sim/connectors/registry.ts [Client Component Browser] Once that file polluted a browser context, Turbopack also failed to resolve the Node builtins in its legitimate server-route imports, cascading the error across App Routes and Server Components. Fix: switch the Obsidian connector to the isomorphic `validateExternalUrl` + `fetchWithRetry` helpers, matching the pattern used by every other connector in the registry. This keeps the core SSRF protections: - hosted Sim: blocks localhost, private IPs, HTTP (HTTPS enforced) - self-hosted Sim: allows localhost + HTTP, still blocks non-loopback private IPs and dangerous ports (22, 25, 3306, 5432, 6379, 27017, 9200) Drops the DNS-rebinding defense specifically (the IP-pinned fetch chain). The trade-off is acceptable because the vault URL is entered by the workspace admin — not arbitrary untrusted input — and hosted deployments already force the plugin to be exposed through a public URL (tunnel/port-forward), making rebinding a narrow threat. Also reverts the `secureFetchWithPinnedIPAndRetry` wrapper in `lib/knowledge/documents/utils.ts` (no longer needed, and its `.server` import was the original source of the client-bundle pollution). * fix(servicenow): propagate URL validation errors in getDocument Match listDocuments behavior — invalid instance URL should surface as a configuration error rather than being swallowed into a "document not found" null response during sync. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(obsidian): drop allowHttp to restore HTTPS enforcement in hosted mode allowHttp: true permitted plaintext HTTP for all hosts in all deployment modes, contradicting the documented policy. The default validateExternalUrl behavior already allows http://localhost in self-hosted mode (the actual Obsidian Local REST API use case) via the built-in carve-out, while correctly rejecting HTTP for public hosts in hosted mode — which prevents leaking the Bearer access token over plaintext. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* feat(slack): add manifest copying * Try using wizard modal * clean up modal * feat(ui): Add wizard emcn component * Made modal subblock more generic * Fix test * Address greptile comments * fix handle copy behavior * Add secret input emcn type * Lint code
#4230) * workspace re-org checkpoint * admin route reconciliation * checkpoint consistency fixes * prep merge * regen migration * checkpoint * code cleanup * update docs * add feature for owner to leave + admin route * address comments * fix new account race * address comments
…rise SSO docs (#4238) * improvement(sso): fix provider lookup, migrate UI to emcn, add enterprise SSO docs * fix(sso): add org membership guard on providers route, fix idpMetadata round-trip * fix(sso): add org membership guard on register route, fix SP entityID, remove fullError leak * fix(sso): fix SAML script callbackUrl and SP entityID to use app base URL * fix(sso): correct SAML callback URL path in script header comment * fix(sso): restrict SSO provider read/write to org owners and admins * docs(sso): restructure page, fix provider guide accuracy, add external doc links * fix(sso): correct SAML callback path and generate idpMetadata from cert+entryPoint * fix(sso): always require NEXT_PUBLIC_APP_URL for SAML SP metadata entityID * fix(sso): scope provider query to org only when organizationId is provided * fix(sso): escape XML special chars in script idpMetadata generation * fix(sso): final audit corrections — saml mapping, xml escaping, self-hosted org guard * fix(sso): redact oidc client secret in providers response, add self-hosted org admin guard * fix(sso): scope redacted-secret lookup to caller's org or userId * fix(sso): null out oidcConfig on parse failure to prevent unredacted secret leak * fix(sso): use issuer as entityID in auto-generated idp metadata xml
…stripe test mocks (#4239) * fix(billing): close TOCTOU race in subscription transfer, centralize stripe test mocks * more mocks * fix(testing): provide complete Stripe.Event defaults in createMockStripeEvent * fix(testing): make dbChainMock .for('update') chainable with .limit() * fix(billing): gate subscription transfer noop behind membership check Previously the 'already belongs to this organization' early return fired before the org/member lookups, letting any authenticated caller probe sub-to-org pairings without being a member of the target org. Move the noop check after the admin/owner verification so unauthorized callers hit the 403 first.
* feat(jobs): Add data retention jobs Add 3 cron-triggered cleanup jobs dispatched via Trigger.dev (or inline fallback): - cleanup-soft-deletes: hard-deletes soft-deleted workspace resources past retention - cleanup-logs: deletes expired workflow execution logs + S3 files - cleanup-tasks: deletes expired copilot chats, runs, feedback, inbox tasks Enterprise admins can configure per-workspace retention via Settings > Data Retention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> # Conflicts: # packages/db/migrations/meta/0192_snapshot.json # packages/db/migrations/meta/_journal.json # packages/db/schema.ts * Cleanup orphaned using ids, not timestamp sorting * fix lint
…edit modal (#4240) * improvement(knowledge): show selector with saved option in connector edit modal * fix(kb-connectors): clear canonical siblings when non-canonical dep changes; share selector field * refactor(kb-connectors): extract canonical-field logic into useConnectorConfigFields hook * fix(kb-connectors): only merge changed fields into sourceConfig on edit save Avoids writing spurious empty-string keys for untouched optional fields when another field triggers a save. * refactor(kb-connectors): tighten state primitives in modals - edit modal: replace useMemo([]) + eslint-disable with useState lazy initializer for initialSourceConfig — same mount-once semantics without the escape hatch. - add modal: drop useCallback on handleConnectNewAccount (no observer saw the reference) and inline the one call site.
…tion updates (#4241) * improvement(enterprise): slack wizard UI, enterprise docs, data retention updates * improvement(docs): add enterprise screenshots to sso, access-control, whitelabeling pages * form * fix(enterprise): address PR review — h-full for recently-deleted, shared SettingRow, toast UX, stale form fix, emcn tokens * fix(whitelabeling): scope drop zone to thumbnail only, not full upload row * fix(whitelabeling): remove drop image text from drag overlay * fix(config): add DATA_RETENTION_ENABLED to env schema to fix build type error * fix(testing): add isDataRetentionEnabled to feature flags mock * improvement(docs): remove redundant requirements section from data-retention page * improvement(docs): remove requirements sections from all enterprise doc pages * improvement(docs): add screenshot to audit-logs page * fix(data-retention): bypass enterprise gate when billing is disabled for self-hosted
* feat(log): Add wrapper function for standardized logging * Add all routes to wrapper, handle background execution * fix lint * fix test * fix test missing url * fix lint * fix tests * fix build * fix(build): unmangle generic in admin outbox requeue route Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…on (#4242) * feat(contact): add contact page, migrate help/demo forms to useMutation * improvement(contact): address greptile review feedback - Map contact topic to help email type for accurate confirmation emails - Drop Zod schema details from 400 response on public /api/contact - Wire aria-describedby + aria-invalid in LandingField for both forms - Reset helpMutation on modal reopen to match demo-request pattern * improvement(landing): extract shared LandingField component
…ations routes (#4243) * fix(layout): use plain inline script for PublicEnvScript to set env before chunks eval on error pages * fix(landing): handle runtime env race on error-page renders React skips SSR on unhandled server errors and re-renders on the client (see vercel/next.js#63980, #82456). Root-layout scripts — including the runtime env script that populates window.__ENV — are inserted but not executed on that client re-render, so any client module that reads env at module evaluation crashes the render into a blank "Application error" overlay instead of rendering the styled 404. This replaces the earlier PublicEnvScript tweak with the architectural fix: - auth-client.ts: fall back to window.location.origin when getBaseUrl() throws on the client. Auth endpoints are same-origin, so this is the correct baseURL on the client. Server-side we still throw on genuine misconfig. - loading.tsx under /models/[provider], /models/[provider]/[model], and /integrations/[slug]: establishes a Suspense boundary below the root layout so a page-level notFound() no longer invalidates the layout's SSR output (the fix endorsed by Next.js maintainers in #63980). - layout.tsx: revert disableNextScript — the research showed this doesn't actually fix error-page renders. The real fix is above. * improvement(landing): use emcn Loader in scoped loading.tsx, trim auth-client comment Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…gn scoped 404s with root (#4246) * improvement(landing): scope navbar/footer shell to (shell) route group, align scoped 404s with root Move integrations and models page routes into a `(shell)` route group so the Navbar+Footer layout wraps pages but not `not-found.tsx`. This lets scoped 404s render the same `<AuthBackground>` + Navbar treatment as the root `/` 404, instead of appearing inside the landing CTA footer. Extract the shared 404 markup into `<NotFoundView>` so root, integrations, and models 404s share a single source of truth. Route URLs are unchanged — route groups are URL-transparent. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(landing): convert relative imports to absolute in integrations (shell) page Build failed because the move into the (shell) route group invalidated relative `./components/...` and `./data/...` imports. CLAUDE.md mandates absolute imports throughout — switching these resolves the Turbopack build errors. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* improvement(access-control): migrate to workspace scope * fix edge cases * update docs * prep merge * regen migrations * address comments * add ws id, user constraint * address more comments * address ui comments * address more comments
…S/CloudWatch/DynamoDB (#4245) * feat(integrations): add AWS SES, IAM Identity Center, and enhanced IAM/STS/CloudWatch/DynamoDB integrations - Add AWS SES v2 integration with 9 operations (send email, templated, bulk, templates, account) - Add AWS IAM Identity Center integration with 12 operations (account assignments, permission sets, users, groups) - Add 3 new IAM tools: list-attached-role-policies, list-attached-user-policies, simulate-principal-policy - Fix DynamoDB duplicate subBlock IDs, add operation-scoped field names, add subblock migrations - Add authMode: AuthMode.ApiKey to DynamoDB block - Fix CloudWatch routes: toError, client.destroy(), withRouteHandler, auth outside try - Fix STS/DynamoDB/IAM routes: nullable Zod schemas, withRouteHandler adoption - Fix Identity Center: list_instances pagination, list_groups instanceArn condition - Add subblock migrations for renamed DynamoDB fields (key, filterExpression, etc.) - Apply withRouteHandler to all new and existing AWS tool routes * docs(ses): add manual intro section to SES docs * fix(dynamodb): add legacy fallbacks in params for subblock migration compatibility Workflows saved with the old shared IDs (key, filterExpression, etc.) that migrate to get-scoped slots via subblock-migrations still work correctly on update/delete/scan/put operations via fallback lookups in tools.config.params. * feat(contact): add contact page, migrate help/demo forms to useMutation (#4242) * feat(contact): add contact page, migrate help/demo forms to useMutation * improvement(contact): address greptile review feedback - Map contact topic to help email type for accurate confirmation emails - Drop Zod schema details from 400 response on public /api/contact - Wire aria-describedby + aria-invalid in LandingField for both forms - Reset helpMutation on modal reopen to match demo-request pattern * improvement(landing): extract shared LandingField component * fix(landing): resolve error-page crash on invalid /models and /integrations routes (#4243) * fix(layout): use plain inline script for PublicEnvScript to set env before chunks eval on error pages * fix(landing): handle runtime env race on error-page renders React skips SSR on unhandled server errors and re-renders on the client (see vercel/next.js#63980, #82456). Root-layout scripts — including the runtime env script that populates window.__ENV — are inserted but not executed on that client re-render, so any client module that reads env at module evaluation crashes the render into a blank "Application error" overlay instead of rendering the styled 404. This replaces the earlier PublicEnvScript tweak with the architectural fix: - auth-client.ts: fall back to window.location.origin when getBaseUrl() throws on the client. Auth endpoints are same-origin, so this is the correct baseURL on the client. Server-side we still throw on genuine misconfig. - loading.tsx under /models/[provider], /models/[provider]/[model], and /integrations/[slug]: establishes a Suspense boundary below the root layout so a page-level notFound() no longer invalidates the layout's SSR output (the fix endorsed by Next.js maintainers in #63980). - layout.tsx: revert disableNextScript — the research showed this doesn't actually fix error-page renders. The real fix is above. * improvement(landing): use emcn Loader in scoped loading.tsx, trim auth-client comment Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * fix(iam): correct MissingContextValues mapping in simulatePrincipalPolicy * fix(aws): add conditionExpression migration fallback for DynamoDB delete, fix SES pageSize min * fix(aws): deep validation fixes across SES, IAM, Identity Center, DynamoDB integrations - IAM: replace non-existent StatementId with SourcePolicyType in simulatePrincipalPolicy - IAM: add .int() constraint to list-users/roles/policies/groups Zod schemas - IAM: remove redundant manual requestId from all 21 IAM route handlers - SES: add .refine() body validation to create-template route - SES: make bulk email destination templateData optional, only include ReplacementEmailContent when present - SES: fix pageSize guard to if (pageSize != null) to correctly forward 0 - SES: add max(100) to list-templates pageSize, revert list-identities to min(0) per SDK - STS: fix logger.error calls to use structured metadata pattern - Identity Center: remove deprecated account.Status fallback, use account.State only - DynamoDB: convert empty interface extends to type aliases, remove redundant error field, fix barrel to absolute imports * regen docs * fix(iam): add .int() constraint to maxSessionDuration in create-role route * fix(ses): forward pageSize=0 correctly in listIdentities util * fix(aws): add gradient background to IdentityCenterIcon, fix listTemplates pageSize guard --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
… fixes (#4248) * improvement(contact): add Turnstile CAPTCHA, honeypot, and robustness fixes - Add Cloudflare Turnstile with graceful degradation: when the widget fails to load (ad blockers, iOS privacy, corporate DNS), submissions fall through to a tighter rate-limit bucket rather than hard-blocking - Add honeypot field to filter automated submissions without user impact - Add separate CAPTCHA_UNAVAILABLE_RATE_LIMIT bucket (3/min) for the no-captcha path so spam via ad-blocker bypass remains expensive - Pass expectedHostname to verifyTurnstileToken to close cross-site token reuse gap - Add SITE_HOSTNAME as module-level constant (avoid URL parsing per req) - Wire onExpire/onError/onUnsupported callbacks so token expiry during slow form-filling falls back gracefully instead of showing a captcha error - Add getResponsePromise(30_000) timeout to prevent indefinite hang on network blips - Add size: 'invisible' to Turnstile options (required for execute mode) - Move turnstile.ts to lib/core/security/ alongside csp/encryption/input-validation - Switch all CSS to --landing-* variables throughout contact form - Move error display inline next to label with truncation in LandingField - Add labelClassName prop to LandingField for context-specific overrides - Simplify contact page to single-column max-w-[640px] layout * fix(contact): fall through to no-captcha rate limit on Cloudflare transport errors * chore(contact): remove extraneous comments from route * fix(contact): remove forced min-height on success state, let content flow naturally * fix(contact): cast CONTACT_TOPIC_OPTIONS to satisfy Combobox mutable type * fix(contact): disable submit during CAPTCHA resolution window, add relative to form
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Introduces new landing contact surface: Hardens redirect safety by validating callback/redirect URLs in signup and email verification flows (logging and discarding unsafe values), and tweaks Adds new integration icons/mappings ( Reviewed by Cursor Bugbot for commit 34cfc26. Configure here. |
…SRF (#4250) * fix(aws): add validateAwsRegion to all AWS route schemas to prevent SSRF * fix(validation): add mx and eu-isoe prefixes to validateAwsRegion regex * test(validation): add mx-central-1, eu-isoe-west-1, and us-iso-west-1 region test cases * fix(aws): eliminate double validateAwsRegion call and fix regex alternation order - Replace double-call .refine() pattern with single-call + static message across all 61 AWS routes - Reorder regex alternation to put longer prefixes first (eu-isoe before eu, us-isob/us-iso/us-gov before us) for engine-agnostic correctness
#4252) * fix(deps): bump drizzle-orm to 0.45.2 (GHSA-gpj5-g38j-94v9) Resolves Dependabot alert #98. Drizzle ORM <0.45.2 improperly escaped quoted SQL identifiers, allowing SQL injection via untrusted input passed to APIs like sql.identifier() or .as(). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore(mcp): adopt native SDK types after @modelcontextprotocol/sdk 1.25.3 bump Replace hand-written schema/annotation shapes with the SDK's exported Tool, JSONRPCResultResponse, and Tool['annotations'] types so changes upstream flow through automatically. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * refactor(types): use drizzle $inferSelect for row types Replace hand-written interfaces that duplicated schema shape with typeof table.$inferSelect aliases for webhook, workflow, and workspaceFiles rows. Also simplify metadata insert/update to use .returning() instead of field-by-field copies. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(uploads): fall through to INSERT if restore-deleted row races a hard delete If a hard delete races between the initial SELECT and the restore UPDATE, .returning() yields no row. Previously the function would return undefined and silently violate the Promise<FileMetadataRecord> contract. Now the function falls through to the INSERT path, which already handles uniqueness races via the 23505 catch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore(uploads): align metadata.ts with global standards Replace dynamic uuid import with generateId() per @sim/utils/id convention, narrow the error catch off `any`, and convert the inline comment to TSDoc. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.