## What changed
- add an optional Capture setting for image-only File Upload blocks with
None, Back camera, and Front camera choices
- persist the standard `environment` and `user` values and apply them
through the runtime file input `capture` attribute
- preserve existing behavior when capture is unset, including the legacy
Android accept workaround
- normalize extension-based image allowlists for capture while keeping
server-side validation fail-closed
- update schemas, generated OpenAPI specs, embed package versions, and
focused tests
- install Playwright Chromium during Codex worktree setup and ignore
local Revue session state
## Validation
- pre-commit affected format, lint, link, test, and OpenAPI targets:
passed
- affected tests across 14 projects under `.env.dev.example`: passed
- typecheck for builder, viewer, JS embed, File Input, input schemas,
lib, and bot engine: passed
- targeted Viewer Playwright file-upload capture test: passed (2 tests)
- targeted schema, allowlist, runtime helper, and upload validation
suites: passed
## Browser behavior
The standard capture attribute is a browser hint. Supported mobile
browsers may open the selected camera directly; desktop and unsupported
browsers may continue to show a regular file chooser.
## What changed
- Detect image extensions in file upload allowlists using the shared
`extensionFromMimeType` table.
- Add the corresponding image MIME hints while preserving the original
extensions and the existing `capture=camera` Android workaround.
- Normalize casing and leading dots, deduplicate equivalent entries, and
prefer valid dotted extensions regardless of input order.
- Add focused unit coverage for image-only, mixed, non-image, duplicate,
and casing scenarios.
- Bump the JavaScript and React embed packages to `0.10.6` and ignore
local Revue comments.
## Why
The Android camera workaround was only enabled when the configured
allowlist already contained an `image/*` MIME type. Bots configured with
image extensions such as `.jpg`, `.jpeg`, and `.png` therefore never
received the workaround.
## Impact
Android users can access the existing camera option when a file upload
block is configured with image extensions. Browser hints are enriched
only on the client; server-side validation remains based on the block's
original options.
The `capture=camera` token remains a non-standard Android-specific
workaround and may continue to vary across browsers.
## Validation
- `bunx nx test @typebot.io/js` — 7 tests passed
- `bunx nx typecheck @typebot.io/js`
- `bunx nx format-and-lint`
- `git diff --check`
The repository-wide pre-commit affected test suite could not complete
locally because unrelated packages required missing environment
variables and existing SSRF tests failed. The targeted package tests,
typecheck, and repository formatting checks passed.
## Summary
- Restores OpenAPI docs generation, lost in the oRPC migration: new
`generate-openapi` nx targets regenerate
`apps/docs/openapi/{builder,viewer}.json` offline from the oRPC routers,
reusing the exact options served by the live `/api/openapi.json`
endpoints. Both specs are regenerated in this PR (builder.json was stale
since March).
- Fixes spec generation crashing on the spaces router (Effect Schema had
no JSON Schema converter — this also breaks the live builder
`/api/openapi.json` today) and sanitizes an `AppendValue(s)` component
name that made Mintlify silently render every builder API page empty.
- Keeps the docs from going stale again: pre-commit regenerates affected
specs and auto-stages them, CI fails PRs with stale specs, and a new
check requires lockstep `@typebot.io/js` / `@typebot.io/react` version
bumps whenever embed files change.
## Test plan
- [x] `bunx nx generate-openapi builder viewer` produces valid OpenAPI
3.1 files matching the live endpoints (works without env: isolated-vm
stubbed, dummy DATABASE_URL auto-matched to the generated Prisma client)
- [x] All 34 `openapi:` references in `apps/docs/api-reference/*.mdx`
resolve against the new specs; pages verified rendering in `mintlify
dev` (params, unions, curl samples)
- [x] Embeds version check: fails when js or react files change without
both bumps, passes on the historical 0.10.5 bump commit, ignores
unrelated changes
- [x] Pre-commit pipeline (lint, tests, generation, embeds check) passes
end to end
- [ ] Confirm the "Check OpenAPI docs are up to date" step passes on
this PR
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
## What changed
- Upgraded Next.js from 16.1.6 to 16.2.9 across the Next-consuming
packages and lockfile.
- Hardened builder response headers by disabling the powered-by header,
adding CSP directives, setting same-origin CORS for non-API pages, and
applying no-store headers to public entry assets/routes.
- Blocked OPTIONS, TRACE, and TRACK in the builder proxy with a 405
response and an explicit Allow header.
## Why
This addresses TAC scan findings around framework disclosure, cache
behavior, response hardening, and risky HTTP methods on builder routes.
## Validation
- `bunx nx typecheck builder` passed.
- `bunx nx typecheck` currently fails on an unrelated landing-page
telemetry header typing issue at
`apps/landing-page/src/features/telemetry/server/trackPageView.ts:85`
(`"Set-Cookie"` is not in `TypedHeaders<ResponseHeaderMap>`).
- Removed deprecated viewer upload URL V1/V2 routes and handlers.
- Hardened V3 upload paths by validating session-derived path segments.
- Updated API docs and OpenAPI output to advertise only V3
generate-upload-url.
- Added file-input upload URL test coverage and package test wiring.
- Restrict Send Email attachments to valid Typebot upload URLs.
- Resolve private Typebot upload URLs to short-lived storage URLs before
sending.
- Enable Nodemailer local file access protection for Send Email
messages.
- Fix WhatsApp public media upload keys to avoid a duplicated public
prefix.
- Add regression tests for rejected attachment origins and valid Typebot
uploads.
- Add failed-attempt tracking to verification tokens in Prisma schemas
and the PostgreSQL migration.
- Record invalid email login code attempts with an atomic counter and
retire active login tokens after five failures.
- Mark Auth.js email login verification tokens separately from other
verification-token flows.
- Use cryptographically secure random six-digit email login codes.
- Add auth package Vitest coverage, including parallel failed-attempt
handling.
- Added a scoped custom-domain lookup before provider deletion.
- Used the verified stored domain name for provider and database
deletion.
- Added regression tests for denied cross-workspace deletion attempts
and valid deletion.
- Return a no-op response for Stripe subscription updates when the
customer is no longer tied to a workspace.
- Validate user profile string fields against database limits before
Prisma updates.
- Return a bad request for imported typebots missing the legacy start
block or group.
- Truncate saved answer content to the MySQL TEXT byte limit before
persisting.
- Cap WhatsApp interactive body text at Meta's 1024-character limit and
add conversion tests.
- Fix WhatsApp audio media conversion for file upload inputs so saved
variables receive the uploaded file URL.
- Keep existing audio reply behavior for text input audio clips and
other non-file inputs.
- Add focused WhatsApp conversion tests for file-upload audio and
preserved audio responses.
- Reduces expired chat session delete chunks to keep cleanup
transactions smaller.
- Forces old chat session lookups to use the primary database before
deletion.
- Adds structured progress, timing, and error logging to expired data
cleanup steps.
- Added a shared S3 config guard that requires bucket, endpoint, access
key, and secret key.
- Skipped S3 copy, delete, and URL replacement operations when storage
is not fully configured.
- Moved typebot, workspace, and results cleanup callers to rely on
guarded S3 helpers.
- Added tests for incomplete and complete S3 config detection.
## Summary
- Keeps video bubbles above the absolute typing/background layer in the
embedded chat renderer.
- Applies the same stacking approach to direct video URLs and embedded
video iframes.
- Bumps `@typebot.io/js` and `@typebot.io/react` from `0.10.4` to
`0.10.5`.
## Root cause
Chrome could place the full-size absolute `bubble-typing` layer over
video bubbles because the media content shared the same stacking level.
That made the overlay sit above the HTML video element in builder embed
preview.
## Validation
- `bunx nx typecheck @typebot.io/react`
- `bunx nx build @typebot.io/react --configuration=development`
- `bunx nx format-and-lint`
- Commit hook: `nx affected -t
format-and-lint,lint-repo,check-broken-links,test --parallel=4`
Note: I could not visually verify the exact provided local typebot URL
in this workspace because it returns `Typebot not found` locally.
- Fallback to the saved WhatsApp credential name when Meta phone lookup
fails for an existing stored credential.
- Keep new Meta token setup validation strict so setup errors still
surface.
- Adds a WhatsApp webhook forwarding URL field directly in the deploy
UI.
- Moves forwarding enablement to an explicit "Forward webhooks" switch
and keeps forwarded events independent from that switch.
- Normalizes legacy URL-only settings through Zod while preserving
explicit disabled configs.
- Restricts forwarding URLs to HTTP(S) and aligns the production update
script with the shared schema.
- Flushes debounced URL inputs on blur and covers legacy, disabled,
empty-event, and invalid-protocol cases in tests.
- Add WhatsApp settings to enable forwarding and choose all events,
error statuses, or marketing statuses.
- Forward selected Meta webhook payloads while preserving legacy
errorAndMarketingStatusWebhookForwardUrl behavior.
- Add regression coverage for legacy URLs, disabled configs, and
all-events forwarding.
- Added a viewer ORPC Sentry filter for expected production WhatsApp
webhook validation failures.
- Kept invalid webhook secret, signature, and payload responses flowing
back to callers without reporting them to Sentry.
- Keep CORS headers on upload proxy error responses.
- Surface failed audio/file uploads as Typebot errors instead of leaving
the recorder stuck.
- Prevent recorded-audio Send clicks from submitting the host page form
in embedded bots.
- Prevent duplicate embed uploads while an upload is already in flight.
- Disable recorder abort while recorded audio is being processed or
uploaded.
- Bump @typebot.io/js and @typebot.io/react to 0.10.4.
- Fixed the OpenAI chat completion handler to explicitly use the AI SDK
chat model for custom base URLs.
- Added regression coverage to verify OpenAI-compatible requests target
`/chat/completions` with the expected payload.
- 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.
- Copy .agents/skills from the repository root during Conductor
workspace setup.
- Copy .claude/skills from the repository root during Conductor
workspace setup.
- Ensure both skill directories exist before copying ignored skill
files.
- 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.
- Block IPv6 unspecified addresses in the shared SSRF IP validator.
- Add validator regressions for compressed and expanded IPv6 unspecified
literals.
- Add a safeKy regression that verifies [::] requests are rejected
before reaching a local IPv6 wildcard listener.
- 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`.
- 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.
- 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.
- 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.
- Limit the PartyKit deploy workflow to pushes that change
`packages/partykit`.
- Remove the broken `turbo-ignore` gate and deploy through the Nx
target.
- Validate that WhatsApp preview webhook test sessions belong to the
authorized typebot before resuming them.
- Require the preview session to still be waiting on the requested
webhook block.
- Share WhatsApp preview phone normalization between preview creation
and test webhook execution.
- 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.
- Add a production script to update the WhatsApp status webhook forward
URL on draft and published typebot settings.
- Register the script in `@typebot.io/scripts` and add the settings
project reference needed for typechecking.
- Ignore local `typebot-prod-db` skill folders for agent tooling.
- 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>
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>
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>