Commit Graph

2622 Commits

Author SHA1 Message Date
Baptiste Arnaud
382a13c2fa
📝 Move database recommendation in self-hosting docs (#2516)
Some checks failed
Create Tag / create-tag (push) Has been cancelled
Deploy Workflows (Fly.io) / deploy (push) Has been cancelled
Monthly job / clean (push) Has been cancelled
- Moved the database recommendation under the "Ready to self-host?"
section.
2026-05-28 15:10:02 +00:00
Baptiste Arnaud
f170033be0
📝 Recommend Neon in self-hosting docs (#2515)
- Add Neon as the recommended production Postgres provider in
self-hosting docs, with a non-affiliate note.
- Link database recommendations to `https://typebot.com/neon`.
- Ignore `.context` files from Biome checks.
2026-05-28 17:02:54 +02:00
younesbenallal
f420be5166
📝 Add blog partner links (#2506) 2026-05-28 17:01:45 +02:00
younesbenallal
8433793edd
📝 Add WhatsApp chatbot blog posts (#2505) 2026-05-28 17:01:03 +02:00
Baptiste Arnaud
08cb6ea10f
🐛 Fix missing result columns in CSV export (#2513)
Some checks failed
Create Tag / create-tag (push) Has been cancelled
Deploy Workflows (Fly.io) / deploy (push) Has been cancelled
- Append missing result headers to saved column orders so newly added
response blocks stay visible.
- Reuse the normalized column order for selected-results CSV export
instead of a local missing-header fallback.
- Add regression coverage for default, saved, and legacy column orders.
2026-05-25 11:33:23 +02:00
Baptiste Arnaud
b4a7aab16d
🐛 Fix landing page Discord URL (#2512)
- Fix the landing page Discord redirect to use typebot.io.
- Ignore local Typebot agent and Claude skill directories.
2026-05-25 09:22:52 +00:00
Baptiste Arnaud
9d6708bbee
🐛 Fix upload proxy public URL (#2508)
- Prevent signed upload proxy URLs from using internal request origins
in self-hosted reverse-proxy setups.
- Resolve runtime upload proxy URLs from `NEXT_PUBLIC_VIEWER_URL` and
builder upload proxy URLs from `NEXTAUTH_URL`.
- Add regression coverage for internal container origins like
`https://2e862faf612f:3000`.
2026-05-22 15:56:26 +02:00
Baptiste Arnaud
5f01ecff64
📝 Update manual deploy docs for Nx (#2507)
- Update the manual self-hosting deploy guide for the current Nx/Bun
workflow.
- Replace stale PM2 commands with repo-root Nx start commands for
builder and viewer.
- Expand the Nginx sample to cover separate builder and viewer domains
and streaming support.
2026-05-22 13:39:21 +00:00
Baptiste Arnaud
a64e82b612
🐛 Fix unsafe upload URL generation (#2502)
- Replace direct browser presigned PUT uploads with signed Typebot
upload proxy URLs.
- Generate or validate upload object keys server-side while preserving
legacy v1/v2/v3 file-input upload contracts.
- Keep builder slot uploads stable for replaceable assets and use
generated names for runtime file uploads.
- Store active file-input MIME types as safe attachment downloads while
keeping safe image uploads inline.
- Update upload clients and docs to support both raw PUT proxy uploads
and form-data uploads.
2026-05-21 18:37:04 +02:00
Baptiste Arnaud
c0ffd825e2
🐛 Fix Google Sheets OAuth callback authorization (#2501)
- Secure Google Sheets OAuth state with a signed payload, expiry, user
binding, and HttpOnly nonce cookie.
- Enforce workspace and typebot write authorization before generating
consent URLs and before callback side effects.
- Scope Google Sheets credential creation and typebot updates in a
transaction, and clear the OAuth state cookie after callback.
- Add OAuth state verification to the Forge popup flow and centralize
OAuth block definition lookup.
- Add tests for signed Google Sheets OAuth state parsing and redirect
sanitization.
2026-05-21 17:31:47 +02:00
Baptiste Arnaud
e296c870bc
🐛 Fix WhatsApp webhook verification (#2498)
- Verify Meta WhatsApp webhooks with optional app secrets while
preserving soft compatibility for existing credentials.
- Add optional 360Dialog webhook secret validation and update flows for
existing WhatsApp credentials.
- Validate Meta WABA and phone number access, then auto-subscribe the
Meta app to the WABA during setup.
- Clear and disable WhatsApp integration when the active credentials are
removed, including published bot state.
- Preserve raw webhook request bodies, document preview app secret
configuration, and add focused webhook verification tests.
- Update related tooling, Biome ignore rules, opensrc guidance, and
small formatting/type-safety cleanup.
2026-05-21 16:45:32 +02:00
Baptiste Arnaud
091db9e06f
📝 Add auth failure troubleshooting section to self-hosting docs (#2495)
- Added an "Authentication fails or users are randomly logged out"
section to `apps/docs/self-hosting/troubleshoot.mdx` covering the common
causes (rotated `NEXTAUTH_SECRET` / `ENCRYPTION_SECRET`, builder/viewer
secret mismatch, mismatched `NEXTAUTH_URL`, unreachable or reset
database).
- Pointed users to tail the builder logs to surface the actual NextAuth
/ Prisma error behind the generic "Check server logs" message.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 07:46:17 +00:00
マーティンズJR
b72a37438f
🐛 Fix Pexels video picker infinite loading loop (#2479)
The Pexels picker could repeatedly fetch the same/empty pages when
changing filters such as Square and scrolling to the bottom. This
happened because the intersection observer kept firing while the last
item stayed visible, pagination did not track whether more results were
available, and duplicated videos could be appended.

This patch:
- uses Pexels 1-based pagination
- tracks whether more videos are available from total_results
- prevents concurrent observer fetches
- resets pagination on search/filter changes
- deduplicates videos by id

before:


https://github.com/user-attachments/assets/f5ca5675-b958-41a7-a4b8-fc92a5576a89


after:


https://github.com/user-attachments/assets/590fc103-9dc9-4a85-b95e-3d1d9f9eefb6

---------

Co-authored-by: Baptiste Arnaud <baptiste@typebot.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 08:23:51 +02:00
ghisson
fa7cc8c3f2
👌 (openai) Add Ask Model file search controls (#2483)
Add chunk count and score threshold options to Ask Model, pass them to
the OpenAI file_search tool, and constrain Score threshold to the 0-1
range in the builder.

---------

Co-authored-by: ghisson <ghisson@LAPTOP-DQ8OKN2P>
Co-authored-by: ghisson <ghisson@LAPTOP-DQ8OKN2P.localdomain>
2026-05-21 08:02:44 +02:00
Baptiste Arnaud
89682dd4ad
🐛 Sanitize CSV exports against formula injection (#2493)
- Added `sanitizeCsvCell` helper that escapes values starting with `=`,
`+`, `-`, `@`, `\t`, or `\r` with a leading apostrophe to prevent
CSV/formula injection (CWE-1236) in spreadsheet apps.
- Applied sanitization to both server-side CSV streams
(`streamAllResultsToCsv`, `streamAllResultsToCsvV2`) for cells and
headers.
- Applied sanitization to client-side exports (`SelectionToolbar`,
`ExportAllResultsDialog`) for cells and header keys.
2026-05-19 18:46:54 +02:00
Baptiste Arnaud
fdcc1784c9
🔧 Hash API tokens (#2492)
- Store newly created API tokens as SHA-256 hashes while returning the
raw token once.
- Authenticate bearer tokens against both hashed and legacy plaintext
records, then lazily hash legacy records on successful use.
- Seed Playwright API tokens as hashes.
- Add Conductor setup and run scripts for local workspaces.
2026-05-19 18:17:11 +02:00
Baptiste Arnaud
6f289f647f
🔒️ Upgrade vulnerable deps (ai v5, nodemailer v8, otel sdk-node 0.217) (#2491)
## Summary

Fixes 18 open Dependabot alerts and migrates affected code to the new
major versions:

- `@opentelemetry/sdk-node` → `^0.217.0` (Prometheus exporter DoS,
GHSA-q7rr-3cgh-j5r3)
- `nodemailer` → `^8.0.5` across all manifests + root override
(GHSA-vvjj-xcjg-gr5g, GHSA-c7w3-x93f-qmm8)
- `ai` → `^5.0.52` (GHSA-rwvc-j5jr-mgvh); legacy 3.x dep removed from
`packages/deprecated/legacy` and replaced with a small in-tree
`OpenAIStream` + `StreamingTextResponse` shim
- Provider SDKs aligned to v5 peer: `@ai-sdk/openai`, `anthropic`,
`groq`, `mistral`, `perplexity`, `deepseek`, `togetherai`, `openRouter`,
`dify-ai-provider`

### AI SDK v4 → v5 migration

- `parseTools`: `parameters` renamed to `inputSchema`
- `runChatCompletion` / `runChatCompletionStream`: `maxSteps` replaced
by `stopWhen(stepCountIs(maxSteps))`;
`usage.{prompt,completion,total}Tokens` replaced by
`totalUsage.{input,output,total}Tokens`
- New `toLegacyDataStream` helper that re-emits the v4 data-stream
protocol (`0:text`, `3:error`, `9:tool_call`, …) so existing consumers
in `embeds/js` and the OpenAI `askAssistant` / `askModel` handlers keep
working
- `compatibility: "strict"` removed from `createOpenAI` (option dropped
in v5)
- `formatDataStreamPart` / `processDataStream` imports moved to
`@ai-sdk/ui-utils` (legacy package pinned at 1.2.11)

### E2E test follow-up

Second commit fixes Playwright tests that broke once the env-resolved
URLs / new SDK surface kicked in:
- `fileUpload`: assert exported URL contains `parseS3PublicBaseUrl()`
(not `S3_ENDPOINT`) so it works with `S3_PUBLIC_CUSTOM_DOMAIN`; verify
post-deletion via cache-busted `request.get` instead of a CDN-cached new
tab.
- `ssrf`: assert on the actual "Security validation failed" log emitted
by the pre-flight check; fixture now maps `response.statusCode` into a
`Status` variable so `Status: …` assertions resolve.
- Root `dev` script includes `@typebot.io/partykit` so the webhook
listener e2e test can hit PartyKit on `:1999`.

Also fixes a pre-existing broken anchor link in `whatsapp-ai-agent.mdx`
that blocked the landing-page link checker.

## Test plan

- [ ] `bunx nx test` passes
- [ ] `bunx nx typecheck` passes
- [ ] `bunx nx affected -t
format-and-lint,lint-repo,check-broken-links,test --parallel=4` passes
(pre-commit)
- [ ] `bun run dev` boots builder, viewer, workflows **and** PartyKit
- [ ] Viewer Playwright suite: `fileUpload.spec.ts`, `ssrf.spec.ts`,
`webhookListener.spec.ts` all green
- [ ] Manual smoke: OpenAI `askAssistant` block streams correctly in the
embed (v4 data-stream protocol preserved)
- [ ] Manual smoke: Anthropic / Mistral / Groq blocks still execute
end-to-end
- [ ] Manual smoke: send a test email through a workspace SMTP block
(nodemailer v8)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 16:30:36 +02:00
younesbenallal
77fd228c96
📝 Update blog content (#2489)
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-05-15 11:35:29 +02:00
younesbenallal
367de01a5d
📝 Added faq dir + cover image to articles (#2485)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-15 11:34:37 +02:00
Baptiste Arnaud
67c7c86b1a
Revert Google Sheets picker fixes (#2486, #2487) (#2488)
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
- Revert #2487 (trigger_onepick OAuth param) and #2486 (setAppId +
NEXT_PUBLIC_GOOGLE_SHEETS_APP_ID env var) which broke the Google Sheets
picker in production.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-12 17:12:31 +02:00
Baptiste Arnaud
babe333c0e
🐛 Add trigger_onepick OAuth param for Google Sheets picker (#2487)
- Add `trigger_onepick=true` parameter to the Google Sheets OAuth
consent URL, required by Google for the `drive.file` scope since the
April 21, 2026 enforcement; without it the picker iframe returns 401.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 16:55:21 +02:00
Baptiste Arnaud
8e67415766
🐛 Fix Google Sheets picker 401 by setting Cloud Project AppId (#2486)
- Call `PickerBuilder.setAppId()` with the Cloud Project number when
building the Google Sheets picker (required by Google when the OAuth
flow uses the `drive.file` scope, otherwise the picker iframe returns
401).
- Add new optional client env var `NEXT_PUBLIC_GOOGLE_SHEETS_APP_ID` in
`packages/env`.
- Document the new variable and setup step in
`apps/docs/self-hosting/configuration.mdx`.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 16:30:43 +02:00
younesbenallal
85a1c37ba7
📝 Add new blog posts batch (#2484) 2026-05-11 17:06:37 +02:00
Baptiste Arnaud
30682a258a
📝 Document status page and analytics completion criteria (#2480)
- Added a new "Is there a status page?" entry to the FAQ pointing to
status.typebot.io.
- Added a "Definitions" section to the analytics doc explaining Views,
Starts, Completions (no input remaining + at least one answer + no
pending client-side action expecting a dedicated reply) and the
per-block drop-off rate.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 11:10:10 +02:00
Baptiste Arnaud
3e98f921d6
📝 Document VAT ID for B2B reverse charge (#2473)
- Add a new "Add a VAT ID for B2B reverse charge" section to
`apps/docs/workspace/subscription.mdx`
- Document the steps to add a VAT ID through the Stripe billing portal
- Clarify that the reverse charge only applies to future invoices, not
retroactively
- Note that without a VAT ID, destination VAT is charged as for a
standard B2C customer

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 08:39:16 +02:00
Baptiste Arnaud
60a77f0296
📝 Document graph edge pitfall and theme republish requirement (#2471)
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
- Add a "Common pitfalls" section to `apps/docs/editor/graph.mdx`
warning that a block without an outgoing edge stops the flow.
- Add a note in `apps/docs/theme/overview.mdx` clarifying that toggling
Typebot branding (or any theme change) requires a republish to go live.

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 09:59:48 +00:00
Baptiste Arnaud
b9002d8bc1
📝 Add Pro-only callout, workspace switcher doc, external messaging guide (#2470)
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
- Add a Pro-only `<Note>` callout at the top of
`deploy/web/custom-domain.mdx`
- Add a "Switch workspace" section in `workspace.mdx` covering the
workspace dropdown
- Add a FAQ entry "I don't see my bots after login" pointing to the
workspace switcher
- Add new guide `guides/external-messaging-apps.mdx` on integrating
Typebot with external messaging apps (KakaoTalk, LINE, Telegram, etc.)
via the HTTP API
- Register the new guide in `mint.json`

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 08:13:54 +00:00
Baptiste Arnaud
050f9061d3
🐛 Fix transcript compute crash on choice items with session-var display condition (#2468)
- Add `skipDisplayConditionCheck` option to
`injectVariableValuesInButtonsInputBlock` and
`injectVariableValuesInPictureChoiceBlock` to skip runtime
display-condition filtering
- Propagate the flag from `validateAndParseInputMessage` when
`skipValidation` is true, so transcript compute no longer filters out
the item the user actually chose
- Show an error state in `ResultDialog` when the transcript query fails
instead of rendering an empty container
- Add a unit test reproducing the bug (choice item with
`displayCondition` on an unset session variable)
- Add `bunf​ig.toml` + `test-preload.ts` for `bot-engine` to mock
`isolated-vm` and set `SKIP_ENV_CHECK` at test time

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 17:32:18 +02:00
Baptiste Arnaud
91d2a986d9
🐛 Fix missing workspace membership check in getSheets endpoint (#2467)
- Add `context: { user }` parameter to `handleGetSheets` to access the
authenticated user
- Fetch the workspace and validate access with `isReadWorkspaceFobidden`
before calling `getGoogleSpreadsheet`
- Aligns `handleGetSheets` with the existing security pattern used by
`handleGetSpreadsheetName` and `handleGetAccessToken` in the same router

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:55:34 +02:00
Baptiste Arnaud
70b7fdfe79
📝 Fill common docs gaps (logs, user commands, downgrade, persistent input) (#2466)
- Clarify that logs are per-result and not a global activity feed in
`results/overview.mdx`
- Add `guides/user-commands.mdx` with a concrete Reply event + Jump +
Return recipe for `restart` / `help` commands
- Cross-link Reply event vs Command event in `editor/events/reply.mdx`
and `editor/events/command.mdx`
- Add FAQ entry explaining that a persistent text input is not native,
with keyword and custom-UI workarounds
- Restructure `workspace/subscription.mdx` with a Steps-based
cancel/downgrade flow and explicit Free plan limits (200 chats, 1 seat)
- Register the new user-commands guide in `mint.json` navigation

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 10:24:19 +02:00
Baptiste Arnaud
da165dfebc
📝 Remove urgent support section from help docs (#2464)
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
- Remove the "If this is urgent" section and link to
`typebot.co/urgent-support` from the how-to-get-help docs page

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 15:09:43 +02:00
Baptiste Arnaud
b25c41b02b
🐛 Fix SSRF bypass via DNS rebinding in HTTP request and script fetch flows (#2461)
- Add `createSafeDispatcher` with a `validatingLookup` that checks
resolved IPs at TCP connection time, preventing DNS rebinding TOCTOU
attacks (GHSA-hgqq-whf5-mrrf)
- Pass the safe undici dispatcher in `safeFetchWithoutChunkedEncoding`
(`ky.ts`) and in the isolated VM fetch wrapper (`executeFunction.ts`)
- Export `parseIPAddress`, `validateIPAddress` and `ParsedIP` from
`validateHttpReqUrl.ts` for reuse in the dispatcher
- Add unit tests for `validatingLookup` and E2E test bot/spec for SSRF
scenarios
- Add `@types/bun` to `packages/lib` tsconfig

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 09:28:06 +00:00
Baptiste Arnaud
7ae4c007d0
🐛 Fix credential access control and remove vulnerable S3 upload endpoint (#2459)
- Bind credential updates to workspace ownership in
`handleUpdateOAuthCredentials` to prevent cross-workspace OAuth
credential takeover (GHSA-3788-7276-x4j4)
- Require write access in `handleGetAccessToken` to prevent guest
members from obtaining Google Sheets OAuth tokens (GHSA-qjpp-9cqc-jhh8)
- Require write access in `handleListModels` to prevent guest members
from exfiltrating OpenAI API keys (GHSA-gc3v-9whw-6wjh)
- Remove deprecated unauthenticated upload endpoint that allowed
arbitrary S3 object writes (GHSA-m7f5-3wcm-x2c4)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 10:39:54 +02:00
Baptiste Arnaud
20d11a5678
Add Ask Model action using OpenAI Responses API (#2455)
## Summary

- **New "Ask Model" action** in the OpenAI block using the Responses API
(`openai.responses.stream()`), supporting multi-turn conversations via
`previous_response_id`, built-in tools (file search with vector store
IDs, web search, code interpreter), custom function calling, and
streaming.
- **Deprecated "Ask Assistant"** action: hidden from the action dropdown
(still functional for existing typebots), with Sentry tracking for
production usage monitoring.
- **Updated template** (`openai-assistant-chat.json`) to use the new Ask
Model action with `gpt-5.4`.
- **Merged `chatModels` + `reasoningModels`** into a single `models`
list in constants.
- **Updated docs** replacing Ask Assistant documentation with Ask Model.

## Test plan
- [ ] Create a typebot with OpenAI → "Ask Model", configure model +
message + instructions, verify streaming works
- [ ] Test multi-turn: verify Response ID variable persists across
exchanges
- [ ] Test built-in tools: web search toggle, vector store IDs tag
input, code interpreter toggle
- [ ] Test custom function calling loop
- [ ] Verify "Ask Assistant" still works for existing typebots but is
hidden from the dropdown for new ones
- [ ] Verify the template loads correctly in the builder

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 14:02:35 +00:00
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
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
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
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
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
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