Commit Graph

3818 Commits

Author SHA1 Message Date
Baptiste Arnaud
90bc7a94ef
👌 Add time filter to results export and fix CSV download on R2 (#2449)
## Summary
- Move time filter logic from builder analytics to a shared
`@typebot.io/results` package so both analytics and results export can
use it
- Add time filter support to the results export workflow, allowing users
to export only filtered results
- Fix CSV files opening in the browser instead of downloading on R2 by
adding `Content-Type` and `Content-Disposition` metadata to S3 uploads
- Add `metadata` parameter to `S3UploadClient.uploadObject()` for
passing object metadata to R2/S3

## Test plan
- [ ] Export results with a time filter applied and verify only filtered
results are exported
- [ ] Verify the exported CSV file downloads directly instead of opening
in the browser
- [ ] Check that analytics time filter still works correctly after the
shared module refactor

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 15:04:27 +02:00
younesbenallal
f9d2a75127
📝 Update blog posts links (#2445) 2026-04-13 14:25:24 +02:00
younesbenallal
b1457842e1
📝 Add "Whatsapp Automation Chatbot" blog post (#2444) 2026-04-13 14:24:00 +02:00
Baptiste Arnaud
55b290043b
🐛 Fix PostHog tracking by updating cookie domain to typebot.com (#2447)
## Summary
- Update `DEFAULT_COOKIE_DOMAIN` from `typebot.io` to `typebot.com` in
telemetry constants
- Fixes "Failed to execute 'set' on 'CookieStore': Cookie domain must
domain-match current host" error that was preventing all PostHog
pageview tracking since the domain migration

## Test plan
- [ ] Verify PostHog pageviews are being recorded on typebot.com
- [ ] Confirm no cookie domain mismatch errors in browser console

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:08:18 +00:00
Baptiste Arnaud
d3c15f32c8
🐛 Handle GA script load failure to prevent bot from hanging (#2446)
## Summary
- Add `script.onerror` handler in `initGoogleAnalytics` so the promise
resolves even when the GA script fails to load (ad blockers, network
errors), preventing the bot from hanging indefinitely.
- Bump `@typebot.io/js` and `@typebot.io/react` versions to `0.10.2`.

## Test plan
- [ ] Enable a Google Analytics integration block in a bot
- [ ] Block `googletagmanager.com` (e.g. via ad blocker) and verify the
bot still loads
- [ ] Check that `"Failed to load Google Analytics script"` appears in
the console

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:18:57 +02:00
younesbenallal
0969c4e525
📝 Add chatbot automation blog post (#2443)
Some checks failed
Create Tag / create-tag (push) Has been cancelled
Deploy Partykit server / deploy (push) Has been cancelled
Deploy Workflows (Fly.io) / deploy (push) Has been cancelled
2026-04-09 15:24:39 +02:00
Justin René Back
c5a8c85026
🐛 Add prisma.config.ts to Dockerfile (#2442)
Fixes #2441

---------

Co-authored-by: Baptiste Arnaud <baptiste@typebot.io>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:59:30 +02:00
Baptiste Arnaud
7bc1a6f856
🔧 Prepare v3.16.0 release (#2439)
## Summary
- Bump version from 3.15.2 to 3.16.0 and generate changelog covering all
changes since last release
- Fix Docker build for Nx monorepo by adding
`DATABASE_URL=postgresql://` to the `next build` step (Prisma needs it
during page data collection)
- Fix broken blog link in whatsapp-lead-generation post

## Test plan
- [x] Docker image builds successfully for both `builder` and `viewer`
(tested locally)
- [ ] Verify release workflow triggers correctly when tagging `v3.16.0`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 10:52:24 +02:00
Baptiste Arnaud
cf80f81f2c
🐛 Update WordPress embed default lib version from 0.3 to 0.x (#2438)
## Summary
- Update the default embed library version from `0.3` to `0.x` across
the WordPress plugin and builder instructions, so it auto-resolves to
the latest `0.x.x` via jsdelivr
- Update the lib_version validation regex to accept version ranges like
`0.x`

## Test plan
- [ ] Verify
`https://cdn.jsdelivr.net/npm/@typebot.io/js@0.x/dist/web.js` resolves
correctly
- [ ] Check WordPress admin panel shows `0.x` as default
- [ ] Verify builder Popup/Bubble instructions show `0.x` for cloud
users

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 10:24:39 +02:00
Baptiste Arnaud
2c3fc7267a
🐛 Fix stored XSS via javascript: URI in bubble links (GHSA-hqmv-v56g-4m47) (#2435)
## Summary
- Fix stored XSS vulnerability where `javascript:` URIs in text bubble
links, image click links, and toast popup links could execute arbitrary
JS in visitors' browsers
- Add `sanitizeUrl` utility that allowlists only `http:`, `https:`,
`mailto:`, and `tel:` protocols
- Add explicit `typecheck` Nx targets for `builder` and `viewer`
(Next.js projects don't get one inferred by `@nx/js/typescript`)
- Bump `@typebot.io/js` and `@typebot.io/react` to `0.10.1`

## Test plan
- [ ] Create a bot with a text bubble link set to `javascript:alert(1)`
and verify it renders as `#`
- [ ] Same test with an image click link
- [ ] Verify normal `https://` links still work
- [ ] Run `bunx nx typecheck builder` and `bunx nx typecheck viewer`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 17:46:09 +02:00
Baptiste Arnaud
b9530a089b
🐛 Fix authorization bypass in getLinkedTypebots (GHSA-3fr5-999r-84qj) (#2434)
## Summary

- Fix broken authorization check in `getLinkedTypebots` where
`Array.filter()` received an `async` callback, causing the
`isReadTypebotForbidden` predicate to never actually filter out
unauthorized typebots (Promise is always truthy)
- Replace with `Promise.all` + synchronous `.filter()` to properly
evaluate access checks
- Any authenticated user could previously read full bot definitions
(variables, groups, webhooks) from other workspaces via a Typebot Link
block reference

## Test plan

- [ ] Verify that linked typebots the user has access to are still
returned correctly
- [ ] Verify that linked typebots from other workspaces the user does
NOT have access to are no longer returned

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:15:12 +00:00
Baptiste Arnaud
c9422f661f
🔧 Add typecheck CI workflow for pull requests (#2433)
## Summary
- Adds a new GitHub Actions workflow that runs `bunx nx affected -t
typecheck` on every pull request
- Uses the PR base branch as the Nx affected comparison base for
accurate change detection
- Sets up Node 24 + Bun with full git history for proper affected
analysis

## Test plan
- [ ] Open a PR with a type error and verify the check fails
- [ ] Open a PR with no type errors and verify the check passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 17:09:32 +02:00
Baptiste Arnaud
23818bb0e5
🐛 Fix SSRF redirect bypass in HTTP Request and Code blocks (#2432)
## Summary

- **Fix SSRF via open redirect bypass** (GHSA-jxv3-m939-w95c): HTTP
Request block now uses `safeKy` instead of `ky`, and Code block's
sandboxed `fetch` now follows redirects manually with `redirect:
"manual"` + re-validation of each `Location` hop via
`validateHttpReqUrl`.
- **Improved safeKy tests**: redirect bypass tests now run end-to-end
through `safeKy` (not just indirect Location header checks), including
chained redirect scenarios.
- **Skip Vercel preview builds**: `nx-ignore` now exits early with code
0 when `VERCEL_ENV=preview`.

## Test plan

- [x] `bunx nx test @typebot.io/lib` — 76 tests pass (0 fail, 6 skip)
- [x] `NODE_ENV=development bun test packages/lib/src/safeKy.test.ts` —
8 tests pass (redirect bypass verified end-to-end)
- [x] `bunx nx typecheck @typebot.io/bot-engine` — passes
- [x] `bunx nx typecheck @typebot.io/variables` — passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 16:41:25 +02:00
Baptiste Arnaud
d6bcc26f27
🐛 Fix cross-workspace credential theft via preview endpoint (#2430)
## Summary
- **Fixes
[GHSA-cq66-9cwr-x8jr](https://github.com/baptisteArno/typebot.io/security/advisories/GHSA-cq66-9cwr-x8jr)**
— the previous fix for GHSA-4xc5-wfwc-jw47 was incomplete: the
bot-engine runtime still allowed any authenticated user to exfiltrate
credentials from any workspace via the preview endpoint by passing
`workspaceId: ""`
- Invert the falsy check in `getCredentials()` so that missing or empty
`workspaceId` **denies** access instead of skipping validation
- Add `z.string().min(1)` on the typebot schema's `workspaceId` to
reject empty strings at the Zod validation layer
- Tighten `getGoogleSpreadsheet` param type from `string | undefined` to
`string`

## Test plan
- [x] Typecheck passes on `credentials`, `bot-engine`, `whatsapp`
- [x] All tests pass (lint, bot-engine, whatsapp, results, lib,
rich-text, emails, builder)
- [ ] Verify that preview mode still works correctly with valid
workspaceId
- [ ] Verify that forged blocks, Google Sheets, and streaming endpoints
still load credentials for legitimate users

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 16:21:17 +02:00
Baptiste Arnaud
73162634e6
🐛 Fix cross-typebot result data access (GHSA-f475-7m4x-m6mx) (#2431)
## Summary
- Adds a `typebotId` filter to the `findResult` Prisma query, preventing
a user from loading result data (answers, variables) belonging to a
different typebot via a foreign `resultId` in the `startChat` endpoint.
- Addresses security advisory GHSA-f475-7m4x-m6mx.

## Test plan
- [x] Typecheck passes (`bunx nx typecheck bot-engine`)
- [x] All affected tests pass (bot-engine, results, builder, etc.)
- [ ] Verify that `startChat` with a `resultId` from another typebot no
longer returns that result's data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 16:11:02 +02:00
younesbenallal
4568263a83
📝 Add "WhatsApp lead generation" blog post (#2426) 2026-04-07 16:08:14 +02:00
Baptiste Arnaud
cc9839f2e7
🔧 Migrate S3 uploads from presigned POST to presigned PUT (#2429)
## Changes

- **Presigned POST → PUT**: Replace `generatePresignedPostPolicy` with
`generatePresignedPutUrl` across all upload endpoints (builder + viewer
v1/v2/v3). This makes uploads compatible with Cloudflare R2 which
doesn't support the S3 POST Object API. Frontend consumers now use `PUT`
with raw file body + `Content-Type`/`Cache-Control` headers instead of
`POST` with FormData.
- **XSS mitigation**: Block dangerous content types (SVG, HTML, XML, JS)
in the builder `generateUploadUrl` endpoint. Restrict frontend `accept`
attributes from `image/*` to an explicit list of safe raster types
(`png, jpeg, gif, webp, avif, bmp, tiff`). Addresses
GHSA-jj87-c343-26vp.
- **Fix file upload URL validation**: `isURL` with `require_tld: true`
rejected `localhost` and `NEXTAUTH_URL` proxy URLs for private files.
Now uses a trusted host allowlist (`localhost`, `NEXTAUTH_URL`,
`S3_PUBLIC_CUSTOM_DOMAIN`) to skip TLD requirement.
- **Docs**: Update S3 CORS policy from `POST` to `PUT`, add Cloudflare
R2 to supported providers list.
- **Bump**: `@typebot.io/js` and `@typebot.io/react` → `0.10.0`

## Verification

- Tested avatar upload on builder with R2 bucket (PUT succeeds, image
displays)
- Verified CORS preflight passes after R2 bucket config
- Confirmed `generateUploadUrl` rejects `image/svg+xml` with 400
- All unit tests pass (`nx affected -t test`)
- Typecheck passes on all affected packages

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:34:35 +02:00
Baptiste Arnaud
a33051755f
🐛 Fix SSRF vulnerabilities in forge block handlers (#2428)
## Summary

Introduces `safeKy` — a `ky` instance with built-in SSRF validation
(`validateHttpReqUrl`) — and applies it to all server-side fetch calls
where the URL originates from user input.

## Changes

- **`packages/lib/src/ky.ts`**: Added `safeKy` export — a `ky` instance
that validates URLs against private IPs, loopback, cloud metadata
endpoints, and other SSRF vectors before making the request. The
existing `ky` instance is unchanged for trusted internal API calls.
-
**`packages/forge/blocks/openai/src/handlers/createTranscriptionHandler.ts`**:
Replaced raw `fetch(options.url)` with `safeKy.get(options.url)` — this
was the vulnerability reported in GHSA-h3v3-c6cq-q763.
- **`packages/forge/blocks/gmail/src/helpers/buildEmail.ts`**: `ky.get`
→ `safeKy.get` for attachment URL downloads.
-
**`packages/forge/blocks/openai/src/helpers/splitUserTextMessageIntoOpenAIBlocks.ts`**:
`ky.get` → `safeKy.get` for image URL detection.
-
**`packages/forge/blocks/blink/src/handlers/sendFeedEventHandler.ts`**:
`ky.head` → `safeKy.head` for attachment metadata fetching (keeps `ky`
for the Blink API call).
- **`packages/ai/src/splitUserTextMessageIntoBlocks.ts`**: `ky.get` →
`safeKy.get` for image URL detection.
- **`packages/whatsapp/src/getOrUploadMedia.ts`**: `ky.get` →
`safeKy.get` for media downloads (keeps `ky` for WhatsApp API uploads).
- **`packages/lib/src/safeKy.test.ts`**: Tests verifying `safeKy` blocks
loopback, private IPs, cloud metadata, and non-HTTP protocols.

## Verification

- `bunx nx typecheck` passes on all affected packages
(`@typebot.io/openai-block`, `@typebot.io/gmail-block`,
`@typebot.io/blink-block`, `@typebot.io/ai`, `@typebot.io/whatsapp`)
- `bunx nx test @typebot.io/lib` — 70 tests pass (66 existing + 4 new
`safeKy` tests)
- All pre-commit hook tests pass
- Manual QA: test with public URLs to confirm functionality is
preserved, then test with `http://127.0.0.1` or `http://169.254.169.254`
to confirm SSRF is blocked

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:37:34 +02:00
Baptiste Arnaud
aa3b619979
🐛 Fix file upload in builder preview mode (#2427)
## Summary

- Add `generateUploadUrlProcedure` to the `fileUploadBuilderRouter` so
the builder's API exposes the `/v3/generate-upload-url` endpoint
- Since `apiHost` now points to the builder origin, file upload requests
from the bot preview were hitting a missing endpoint (previously routed
to the viewer)

## Verification

- Test a bot in the builder preview that has a file upload block
- Confirm the upload request to `/api/v3/generate-upload-url` succeeds
and file uploads work

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 09:52:34 +00:00
Baptiste Arnaud
30e071da71
🔧 Fix cleanArchivedData script performance
Some checks failed
Create Tag / create-tag (push) Has been cancelled
Deploy Partykit server / deploy (push) Has been cancelled
Deploy Workflows (Fly.io) / deploy (push) Has been cancelled
2026-04-02 10:06:00 +02:00
Baptiste Arnaud
bd6f3cc5fe
🐛 Fix robots.txt for new domain
Some checks failed
Create Tag / create-tag (push) Has been cancelled
Deploy Partykit server / deploy (push) Has been cancelled
Deploy Workflows (Fly.io) / deploy (push) Has been cancelled
2026-03-30 08:39:10 +02:00
Baptiste Arnaud
b8021f978a
🐛 Fix editables overflow 2026-03-27 12:31:47 +01:00
Baptiste Arnaud
a56dc49b2a
🐛 Fix import typebots 2026-03-27 11:07:49 +01:00
Baptiste Arnaud
cb2430ba84
🔧 Move to typebot.com 2026-03-26 17:10:02 +01:00
Baptiste Arnaud
7d432813a9
🐛 Fix space icon picking and optimistic updates 2026-03-26 16:33:46 +01:00
Baptiste Arnaud
4eff08df9c
🐛 Fix IconPicker loading state 2026-03-26 16:33:22 +01:00
Baptiste Arnaud
ca41bf7238
🔧 Improve frontend skills 2026-03-26 16:29:13 +01:00
Baptiste Arnaud
a0be7a4a39
💅 Improve IconPicker loading 2026-03-26 16:27:00 +01:00
Baptiste Arnaud
1541877836
👌 Introduce Spaces 2026-03-25 18:17:05 +01:00
Baptiste Arnaud
1191f666db
🔧 Improve misc components and Folder editable 2026-03-25 17:58:41 +01:00
Baptiste Arnaud
e7ae260aaf
🔧 Improve default image compression 2026-03-25 17:04:25 +01:00
Baptiste Arnaud
d6b010eb84
♻️ Add UploadButton component 2026-03-25 16:48:20 +01:00
Baptiste Arnaud
acd2f2971b
🔧 Remove "baseUrl": "." from tsconfigs 2026-03-25 16:40:12 +01:00
Baptiste Arnaud
991a2b7dc8
♻️ Move DebouncedTextInput to packages UI 2026-03-25 16:26:15 +01:00
Baptiste Arnaud
2e34c7c1e7
💅 Fix dots icons, bolder 2026-03-25 11:26:32 +01:00
Baptiste Arnaud
7c73b663c8
♻️ Refacto Editables in a common component 2026-03-25 10:57:36 +01:00
Baptiste Arnaud
d04605c8ea
♻️ Remove shared-primitives package 2026-03-25 10:43:35 +01:00
Baptiste Arnaud
c67548cd62
♻️ Improve EmojiOrImageIcon structure 2026-03-25 10:36:35 +01:00
Baptiste Arnaud
569ef709e6
♻️ Add search input in UI emoji picker component 2026-03-25 10:26:52 +01:00
Baptiste Arnaud
455803efc5
♻️ Move IconPicker to UI package 2026-03-25 10:22:19 +01:00
Baptiste Arnaud
d0d33d1f94
️ Add new OpenAI and Anthropic models 2026-03-25 09:00:18 +01:00
Baptiste Arnaud
62e5bf639d
🐛 Fix builder preview AI streaming 2026-03-25 08:51:43 +01:00
Baptiste Arnaud
07a2c83bf2
🔧 Update UI skill 2026-03-24 17:14:33 +01:00
Baptiste Arnaud
ece99ba625
♻️ Move editable components to shared UI package 2026-03-24 16:48:49 +01:00
Baptiste Arnaud
a2ee915628
🐛 Fix UI skill name 2026-03-24 15:25:11 +01:00
Baptiste Arnaud
78da6fa4d3
🐛 Fix embeds crash (importing external modules) 2026-03-24 15:16:46 +01:00
Baptiste Arnaud
2539c0307c
🔧 Improve UI skill 2026-03-24 15:04:09 +01:00
Baptiste Arnaud
e9186003a6
🔧 Upgrade Effect packages 2026-03-24 14:51:38 +01:00
Baptiste Arnaud
3f6ef991d4
🔧 Add UI skill shortcuts 2026-03-24 13:09:33 +01:00
Baptiste Arnaud
aa97084285
🐛 Remove builder html sanitizer 2026-03-23 18:51:10 +01:00