From f83c13cf415802358e26065c8f2808549f7f2bac Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Fri, 3 Apr 2026 15:09:50 -0700 Subject: [PATCH 1/2] Allow iframe embedding and fix remote config defaults Add agentName and sandboxId to APP_CONFIG_DEFAULTS so they are no longer silently dropped when received from the sandbox config endpoint. Fix the type guard in getAppConfig() to allow undefined defaults to be overwritten by typed remote values. Set Content-Security-Policy: frame-ancestors * on /embed and /test/popup routes so these pages can be loaded in iframes on third-party sites. Required for the Cloud embed widget feature. --- app-config.ts | 2 ++ lib/env.ts | 5 +++-- next.config.ts | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app-config.ts b/app-config.ts index 345e00c..c15843f 100644 --- a/app-config.ts +++ b/app-config.ts @@ -1,6 +1,8 @@ import type { AppConfig } from './lib/types'; export const APP_CONFIG_DEFAULTS: AppConfig = { + sandboxId: undefined, + agentName: undefined, supportsChatInput: true, supportsVideoInput: true, supportsScreenShare: true, diff --git a/lib/env.ts b/lib/env.ts index c7990a5..060639f 100644 --- a/lib/env.ts +++ b/lib/env.ts @@ -38,8 +38,9 @@ export const getAppConfig = cache( if (entry === null) continue; if ( key in config && - typeof config[key as keyof AppConfig] === entry.type && - typeof config[key as keyof AppConfig] === typeof entry.value + (config[key as keyof AppConfig] === undefined || + typeof config[key as keyof AppConfig] === entry.type) && + typeof entry.value === entry.type ) { // @ts-expect-error I'm not sure quite how to appease TypeScript, but we've thoroughly checked types above config[key as keyof AppConfig] = entry.value as AppConfig[keyof AppConfig]; diff --git a/next.config.ts b/next.config.ts index cacbe5a..48f52e5 100644 --- a/next.config.ts +++ b/next.config.ts @@ -3,6 +3,10 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { /* config options here */ devIndicators: false, + async headers() { + const iframeHeaders = [{ key: 'Content-Security-Policy', value: 'frame-ancestors *' }]; + return [{ source: '/embed', headers: iframeHeaders }]; + }, }; export default nextConfig; From 220f574b1776787dccc441942181c89fa9ba9f0a Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Fri, 3 Apr 2026 15:20:21 -0700 Subject: [PATCH 2/2] Upgrade Next.js to 15.5.14 to fix CVE-2025-66478 Vercel blocks deployments on vulnerable Next.js versions. --- next.config.ts | 5 ++- package.json | 2 +- pnpm-lock.yaml | 82 +++++++++++++++++++++++++------------------------- 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/next.config.ts b/next.config.ts index 48f52e5..85b0bb8 100644 --- a/next.config.ts +++ b/next.config.ts @@ -4,7 +4,10 @@ const nextConfig: NextConfig = { /* config options here */ devIndicators: false, async headers() { - const iframeHeaders = [{ key: 'Content-Security-Policy', value: 'frame-ancestors *' }]; + const iframeHeaders = [ + { key: 'X-Frame-Options', value: 'ALLOWALL' }, + { key: 'Content-Security-Policy', value: 'frame-ancestors *' }, + ]; return [{ source: '/embed', headers: iframeHeaders }]; }, }; diff --git a/package.json b/package.json index e1a9a85..8d3a757 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "livekit-client": "^2.13.3", "livekit-server-sdk": "^2.13.0", "motion": "^12.16.0", - "next": "15.4.7", + "next": "15.5.14", "next-themes": "^0.4.6", "react": "^19.0.0", "react-dom": "^19.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4636b52..11d079f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,8 +57,8 @@ importers: specifier: ^12.16.0 version: 12.16.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) next: - specifier: 15.4.7 - version: 15.4.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: 15.5.14 + version: 15.5.14(react-dom@19.1.1(react@19.1.1))(react@19.1.1) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -479,56 +479,56 @@ packages: '@napi-rs/wasm-runtime@0.2.10': resolution: {integrity: sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==} - '@next/env@15.4.7': - resolution: {integrity: sha512-PrBIpO8oljZGTOe9HH0miix1w5MUiGJ/q83Jge03mHEE0E3pyqzAy2+l5G6aJDbXoobmxPJTVhbCuwlLtjSHwg==} + '@next/env@15.5.14': + resolution: {integrity: sha512-aXeirLYuASxEgi4X4WhfXsShCFxWDfNn/8ZeC5YXAS2BB4A8FJi1kwwGL6nvMVboE7fZCzmJPNdMvVHc8JpaiA==} '@next/eslint-plugin-next@15.3.5': resolution: {integrity: sha512-BZwWPGfp9po/rAnJcwUBaM+yT/+yTWIkWdyDwc74G9jcfTrNrmsHe+hXHljV066YNdVs8cxROxX5IgMQGX190w==} - '@next/swc-darwin-arm64@15.4.7': - resolution: {integrity: sha512-2Dkb+VUTp9kHHkSqtws4fDl2Oxms29HcZBwFIda1X7Ztudzy7M6XF9HDS2dq85TmdN47VpuhjE+i6wgnIboVzQ==} + '@next/swc-darwin-arm64@15.5.14': + resolution: {integrity: sha512-Y9K6SPzobnZvrRDPO2s0grgzC+Egf0CqfbdvYmQVaztV890zicw8Z8+4Vqw8oPck8r1TjUHxVh8299Cg4TrxXg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.4.7': - resolution: {integrity: sha512-qaMnEozKdWezlmh1OGDVFueFv2z9lWTcLvt7e39QA3YOvZHNpN2rLs/IQLwZaUiw2jSvxW07LxMCWtOqsWFNQg==} + '@next/swc-darwin-x64@15.5.14': + resolution: {integrity: sha512-aNnkSMjSFRTOmkd7qoNI2/rETQm/vKD6c/Ac9BZGa9CtoOzy3c2njgz7LvebQJ8iPxdeTuGnAjagyis8a9ifBw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.4.7': - resolution: {integrity: sha512-ny7lODPE7a15Qms8LZiN9wjNWIeI+iAZOFDOnv2pcHStncUr7cr9lD5XF81mdhrBXLUP9yT9RzlmSWKIazWoDw==} + '@next/swc-linux-arm64-gnu@15.5.14': + resolution: {integrity: sha512-tjlpia+yStPRS//6sdmlVwuO1Rioern4u2onafa5n+h2hCS9MAvMXqpVbSrjgiEOoCs0nJy7oPOmWgtRRNSM5Q==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.4.7': - resolution: {integrity: sha512-4SaCjlFR/2hGJqZLLWycccy1t+wBrE/vyJWnYaZJhUVHccpGLG5q0C+Xkw4iRzUIkE+/dr90MJRUym3s1+vO8A==} + '@next/swc-linux-arm64-musl@15.5.14': + resolution: {integrity: sha512-8B8cngBaLadl5lbDRdxGCP1Lef8ipD6KlxS3v0ElDAGil6lafrAM3B258p1KJOglInCVFUjk751IXMr2ixeQOQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@15.4.7': - resolution: {integrity: sha512-2uNXjxvONyRidg00VwvlTYDwC9EgCGNzPAPYbttIATZRxmOZ3hllk/YYESzHZb65eyZfBR5g9xgCZjRAl9YYGg==} + '@next/swc-linux-x64-gnu@15.5.14': + resolution: {integrity: sha512-bAS6tIAg8u4Gn3Nz7fCPpSoKAexEt2d5vn1mzokcqdqyov6ZJ6gu6GdF9l8ORFrBuRHgv3go/RfzYz5BkZ6YSQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.4.7': - resolution: {integrity: sha512-ceNbPjsFgLscYNGKSu4I6LYaadq2B8tcK116nVuInpHHdAWLWSwVK6CHNvCi0wVS9+TTArIFKJGsEyVD1H+4Kg==} + '@next/swc-linux-x64-musl@15.5.14': + resolution: {integrity: sha512-mMxv/FcrT7Gfaq4tsR22l17oKWXZmH/lVqcvjX0kfp5I0lKodHYLICKPoX1KRnnE+ci6oIUdriUhuA3rBCDiSw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.4.7': - resolution: {integrity: sha512-pZyxmY1iHlZJ04LUL7Css8bNvsYAMYOY9JRwFA3HZgpaNKsJSowD09Vg2R9734GxAcLJc2KDQHSCR91uD6/AAw==} + '@next/swc-win32-arm64-msvc@15.5.14': + resolution: {integrity: sha512-OTmiBlYThppnvnsqx0rBqjDRemlmIeZ8/o4zI7veaXoeO1PVHoyj2lfTfXTiiGjCyRDhA10y4h6ZvZvBiynr2g==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.4.7': - resolution: {integrity: sha512-HjuwPJ7BeRzgl3KrjKqD2iDng0eQIpIReyhpF5r4yeAHFwWRuAhfW92rWv/r3qeQHEwHsLRzFDvMqRjyM5DI6A==} + '@next/swc-win32-x64-msvc@15.5.14': + resolution: {integrity: sha512-+W7eFf3RS7m4G6tppVTOSyP9Y6FsJXfOuKzav1qKniiFm3KFByQfPEcouHdjlZmysl4zJGuGLQ/M9XyVeyeNEg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2425,8 +2425,8 @@ packages: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - next@15.4.7: - resolution: {integrity: sha512-OcqRugwF7n7mC8OSYjvsZhhG1AYSvulor1EIUsIkbbEbf1qoE5EbH36Swj8WhF4cHqmDgkiam3z1c1W0J1Wifg==} + next@15.5.14: + resolution: {integrity: sha512-M6S+4JyRjmKic2Ssm7jHUPkE6YUJ6lv4507jprsSZLulubz0ihO2E+S4zmQK3JZ2ov81JrugukKU4Tz0ivgqqQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -3514,34 +3514,34 @@ snapshots: '@tybys/wasm-util': 0.9.0 optional: true - '@next/env@15.4.7': {} + '@next/env@15.5.14': {} '@next/eslint-plugin-next@15.3.5': dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.4.7': + '@next/swc-darwin-arm64@15.5.14': optional: true - '@next/swc-darwin-x64@15.4.7': + '@next/swc-darwin-x64@15.5.14': optional: true - '@next/swc-linux-arm64-gnu@15.4.7': + '@next/swc-linux-arm64-gnu@15.5.14': optional: true - '@next/swc-linux-arm64-musl@15.4.7': + '@next/swc-linux-arm64-musl@15.5.14': optional: true - '@next/swc-linux-x64-gnu@15.4.7': + '@next/swc-linux-x64-gnu@15.5.14': optional: true - '@next/swc-linux-x64-musl@15.4.7': + '@next/swc-linux-x64-musl@15.5.14': optional: true - '@next/swc-win32-arm64-msvc@15.4.7': + '@next/swc-win32-arm64-msvc@15.5.14': optional: true - '@next/swc-win32-x64-msvc@15.4.7': + '@next/swc-win32-x64-msvc@15.5.14': optional: true '@nodelib/fs.scandir@2.1.5': @@ -5498,9 +5498,9 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - next@15.4.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + next@15.5.14(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@next/env': 15.4.7 + '@next/env': 15.5.14 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001727 postcss: 8.4.31 @@ -5508,14 +5508,14 @@ snapshots: react-dom: 19.1.1(react@19.1.1) styled-jsx: 5.1.6(react@19.1.1) optionalDependencies: - '@next/swc-darwin-arm64': 15.4.7 - '@next/swc-darwin-x64': 15.4.7 - '@next/swc-linux-arm64-gnu': 15.4.7 - '@next/swc-linux-arm64-musl': 15.4.7 - '@next/swc-linux-x64-gnu': 15.4.7 - '@next/swc-linux-x64-musl': 15.4.7 - '@next/swc-win32-arm64-msvc': 15.4.7 - '@next/swc-win32-x64-msvc': 15.4.7 + '@next/swc-darwin-arm64': 15.5.14 + '@next/swc-darwin-x64': 15.5.14 + '@next/swc-linux-arm64-gnu': 15.5.14 + '@next/swc-linux-arm64-musl': 15.5.14 + '@next/swc-linux-x64-gnu': 15.5.14 + '@next/swc-linux-x64-musl': 15.5.14 + '@next/swc-win32-arm64-msvc': 15.5.14 + '@next/swc-win32-x64-msvc': 15.5.14 sharp: 0.34.3 transitivePeerDependencies: - '@babel/core'