fix(companion): prevent localhost URL from being baked into production extension builds (#26032)
* fix(companion): separate dev and prod build scripts to prevent localhost in production - Add ext:build-dev and ext:build-prod scripts with clear separation - Add BUILD_FOR_STORE flag to force production URL in store builds - Add visual build indicators (store / dev) for clarity - Prevent EXPO_PUBLIC_COMPANION_DEV_URL from leaking into production builds * update commands to work for ci * update version --------- Co-authored-by: Volnei Munhoz <volnei@cal.com>
This commit is contained in:
co-authored by
Volnei Munhoz
parent
f291c1c4e7
commit
c8a8c37b45
@@ -56,6 +56,9 @@ export default defineContentScript({
|
||||
iframeContainer.style.pointerEvents = "none";
|
||||
|
||||
const iframe = document.createElement("iframe");
|
||||
// URL is determined at build time:
|
||||
// - ext:build-dev → uses EXPO_PUBLIC_COMPANION_DEV_URL (localhost)
|
||||
// - ext:build-prod → uses https://companion.cal.com
|
||||
const COMPANION_URL =
|
||||
(import.meta.env.EXPO_PUBLIC_COMPANION_DEV_URL as string) || "https://companion.cal.com";
|
||||
iframe.src = COMPANION_URL;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "cal-companion",
|
||||
"displayName": "Cal.com Companion",
|
||||
"version": "1.7.1",
|
||||
"version": "1.7.3",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "expo start",
|
||||
@@ -9,10 +9,14 @@
|
||||
"ios": "expo run:ios",
|
||||
"web": "expo start --web",
|
||||
"ext:build": "wxt build",
|
||||
"ext:build-prod": "BUILD_FOR_STORE=true wxt build",
|
||||
"build:firefox": "wxt build -b firefox",
|
||||
"build:firefox-prod": "BUILD_FOR_STORE=true wxt build -b firefox",
|
||||
"build:safari": "wxt build -b safari",
|
||||
"build:safari-prod": "BUILD_FOR_STORE=true wxt build -b safari",
|
||||
"ext": "wxt",
|
||||
"ext:zip": "wxt zip",
|
||||
"ext:zip-prod": "BUILD_FOR_STORE=true wxt zip",
|
||||
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
|
||||
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
|
||||
"prepare": "cd .. && husky companion/.husky"
|
||||
|
||||
+70
-56
@@ -1,7 +1,8 @@
|
||||
import { defineConfig } from "wxt";
|
||||
|
||||
const devUrl = process.env.EXPO_PUBLIC_COMPANION_DEV_URL;
|
||||
const isLocalDev = Boolean(devUrl && devUrl.includes("localhost"));
|
||||
// BUILD_FOR_STORE=true is set by ext:build-prod, ext:zip-prod, etc.
|
||||
// Forces production URL (https://companion.cal.com) and excludes localhost permissions
|
||||
const isBuildForStore = process.env.BUILD_FOR_STORE === "true";
|
||||
|
||||
export default defineConfig({
|
||||
hooks: {
|
||||
@@ -19,7 +20,7 @@ export default defineConfig({
|
||||
outDir: ".output",
|
||||
manifest: {
|
||||
name: "Cal.com Companion",
|
||||
version: "1.7.1",
|
||||
version: "1.7.3",
|
||||
description: "Your calendar companion for quick booking and scheduling",
|
||||
permissions: ["activeTab", "storage", "identity"],
|
||||
host_permissions: [
|
||||
@@ -27,10 +28,11 @@ export default defineConfig({
|
||||
"https://api.cal.com/*",
|
||||
"https://app.cal.com/*",
|
||||
"https://mail.google.com/*",
|
||||
...(isLocalDev ? ["http://localhost:*/*"] : []),
|
||||
// Include localhost permission for dev builds (needed for iframe to load)
|
||||
...(!isBuildForStore ? ["http://localhost:*/*"] : []),
|
||||
],
|
||||
content_security_policy: {
|
||||
extension_pages: isLocalDev
|
||||
extension_pages: !isBuildForStore
|
||||
? "script-src 'self'; object-src 'self'; frame-src 'self' https://companion.cal.com http://localhost:*"
|
||||
: "script-src 'self'; object-src 'self'; frame-src 'self' https://companion.cal.com",
|
||||
},
|
||||
@@ -48,57 +50,69 @@ export default defineConfig({
|
||||
"128": "icon-128.png",
|
||||
},
|
||||
},
|
||||
vite: () => ({
|
||||
resolve: {
|
||||
alias: {
|
||||
"react-native": "react-native-web",
|
||||
},
|
||||
},
|
||||
define: {
|
||||
global: "globalThis",
|
||||
__DEV__: JSON.stringify(false),
|
||||
"import.meta.env.EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_COMPANION_DEV_URL": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_COMPANION_DEV_URL || ""
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_CACHE_GC_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CACHE_GC_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_BOOKINGS_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_BOOKINGS_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_EVENT_TYPES_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_EVENT_TYPES_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_SCHEDULES_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_SCHEDULES_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_USER_PROFILE_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_USER_PROFILE_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
...(process.env.NODE_ENV !== "production" && process.env.EXPO_PUBLIC_CAL_API_KEY
|
||||
? {
|
||||
"import.meta.env.EXPO_PUBLIC_CAL_API_KEY": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CAL_API_KEY
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: ["react-native-web"],
|
||||
esbuildOptions: {
|
||||
loader: {
|
||||
".js": "jsx",
|
||||
vite: () => {
|
||||
// Determine companion URL based on build type
|
||||
const devUrl = isBuildForStore ? "" : process.env.EXPO_PUBLIC_COMPANION_DEV_URL || "";
|
||||
const isLocalDev = Boolean(devUrl && devUrl.includes("localhost"));
|
||||
|
||||
// Log build mode for clarity
|
||||
if (isBuildForStore) {
|
||||
console.log("\n🏪 STORE BUILD: Using https://companion.cal.com\n");
|
||||
} else if (isLocalDev) {
|
||||
console.log(`\n🔧 DEV BUILD: Using ${devUrl}\n`);
|
||||
}
|
||||
|
||||
return {
|
||||
resolve: {
|
||||
alias: {
|
||||
"react-native": "react-native-web",
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
define: {
|
||||
global: "globalThis",
|
||||
__DEV__: JSON.stringify(false),
|
||||
"import.meta.env.EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CALCOM_OAUTH_CLIENT_ID
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CALCOM_OAUTH_REDIRECT_URI
|
||||
),
|
||||
// Use devUrl which respects BUILD_FOR_STORE flag
|
||||
"import.meta.env.EXPO_PUBLIC_COMPANION_DEV_URL": JSON.stringify(devUrl),
|
||||
"import.meta.env.EXPO_PUBLIC_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_CACHE_GC_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CACHE_GC_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_BOOKINGS_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_BOOKINGS_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_EVENT_TYPES_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_EVENT_TYPES_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_SCHEDULES_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_SCHEDULES_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
"import.meta.env.EXPO_PUBLIC_USER_PROFILE_CACHE_STALE_TIME_MINUTES": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_USER_PROFILE_CACHE_STALE_TIME_MINUTES
|
||||
),
|
||||
...(process.env.NODE_ENV !== "production" && process.env.EXPO_PUBLIC_CAL_API_KEY
|
||||
? {
|
||||
"import.meta.env.EXPO_PUBLIC_CAL_API_KEY": JSON.stringify(
|
||||
process.env.EXPO_PUBLIC_CAL_API_KEY
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: ["react-native-web"],
|
||||
esbuildOptions: {
|
||||
loader: {
|
||||
".js": "jsx",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user