[eric] fix packaged Mac boot: splash icon path, ship OAuth-only .env, exempt tools oauth callback from auth

This commit is contained in:
ciregenz
2026-04-26 01:17:01 -07:00
parent d8f69bb23d
commit ee91092284
10 changed files with 772 additions and 223 deletions
+39
View File
@@ -91,6 +91,15 @@ if (-not (Test-Path (Join-Path $UvBinDir 'uvx.exe'))) {
}
Write-Host ""
# --- Step 0a: Sync the splash icon ---
# electron-builder excludes `build/` from the shipped asar (it's the icon-
# source directory used to generate .ico). The splash window needs to read
# the icon at runtime, so we keep a copy at electron\splash\icon.png which
# IS shipped. See electron/main.js comment at iconPngPath for context.
Copy-Item -Force `
(Join-Path $ProjectRoot 'electron\build\icon.png') `
(Join-Path $ProjectRoot 'electron\splash\icon.png')
# --- Step 0b: Bundle npm MCP servers via esbuild ---
# Each bundle compiles down to a single ~5-15 MB CommonJS file under
# backend\mcp-bundles\, runs on Electron's bundled Node at runtime
@@ -289,6 +298,36 @@ function Copy-Excluded($Source, $Dest, $Exclude) {
Copy-Excluded `
(Join-Path $ProjectRoot 'backend') (Join-Path $Staging 'backend') `
@{ Dirs = @('__pycache__','.venv','tools','tests'); Files = @('*.pyc','.env','.env.*') }
# Generate a SAFE production .env containing ONLY OAuth provider credentials.
# Drops APPLE_*/GH_TOKEN/BACKEND_PORT/etc. so signing keys + personal tokens
# never ship to users. Per-user API keys (Anthropic/OpenAI/Gemini) come from
# the in-app Settings UI. Backend's tools_lib.py:34 auto-loads this file.
$ShipEnvKeys = @(
'GOOGLE_OAUTH_CLIENT_ID','GOOGLE_OAUTH_CLIENT_SECRET',
'NOTION_OAUTH_CLIENT_ID','NOTION_OAUTH_CLIENT_SECRET',
'AIRTABLE_OAUTH_CLIENT_ID','AIRTABLE_OAUTH_CLIENT_SECRET',
'HUBSPOT_OAUTH_CLIENT_ID','HUBSPOT_OAUTH_CLIENT_SECRET',
'DISCORD_OAUTH_CLIENT_ID','DISCORD_OAUTH_CLIENT_SECRET',
'DISCORD_BOT_TOKEN'
)
$DevEnvPath = Join-Path $ProjectRoot 'backend\.env'
$ShipEnvPath = Join-Path $Staging 'backend\.env'
if (Test-Path $DevEnvPath) {
$kept = Get-Content $DevEnvPath | Where-Object {
$line = $_
$keep = $false
foreach ($k in $ShipEnvKeys) {
if ($line -match "^$k=") { $keep = $true; break }
}
$keep
}
Set-Content -Path $ShipEnvPath -Value $kept
Write-Host "Staged OAuth credentials: $($kept.Count) keys (release secrets + personal API keys excluded)"
} else {
Write-Host "WARNING: backend\.env not found — packaged build will have no OAuth credentials configured."
Set-Content -Path $ShipEnvPath -Value '' -NoNewline
}
New-Item -ItemType Directory -Force -Path (Join-Path $Staging 'backend\data\tools') | Out-Null
Copy-Excluded `
+29
View File
@@ -97,6 +97,13 @@ else
fi
echo ""
# Step 0a: Sync the splash icon. electron-builder excludes `build/` from
# the shipped asar (it's the icon-source directory used to generate .icns/.ico),
# so the splash window can't read build/icon.png at runtime. We keep a copy
# at electron/splash/icon.png which IS shipped. See electron/main.js comment
# at iconPngPath for context.
cp "$PROJECT_ROOT/electron/build/icon.png" "$PROJECT_ROOT/electron/splash/icon.png"
# Step 0b: Bundle npm MCP servers via esbuild
# Each bundle compiles down to a single ~5-15 MB CommonJS file under
# backend/mcp-bundles/, runs on Electron's bundled Node at runtime
@@ -283,6 +290,28 @@ rsync -a \
--exclude='tests' --exclude='**/tests' \
--exclude='.env' --exclude='.env.*' --exclude='**/.env' --exclude='**/.env.*' \
"$PROJECT_ROOT/backend/" "$STAGING_DIR/backend/"
# Generate a SAFE production .env containing ONLY the OAuth provider
# credentials (the "OpenSwarm public OAuth app" identifiers — these are
# the desktop-app pattern where the client secret isn't truly secret).
# We deliberately DROP everything else from the dev .env:
# - APPLE_ID / APPLE_APP_SPECIFIC_PASSWORD / APPLE_TEAM_ID (signing creds — must NOT ship)
# - GH_TOKEN (release upload token — must NOT ship)
# - BACKEND_PORT / DISCORD_BOT_PERMISSIONS (dev-only or trivially recomputable)
# Backend's tools_lib.py:34 calls load_dotenv() on this path at startup,
# so the OAuth flows pick these up automatically. Per-user API keys
# (Anthropic, OpenAI, Gemini) come from the user's Settings UI, not from .env.
SHIP_ENV_KEYS='^(GOOGLE_OAUTH_CLIENT_ID|GOOGLE_OAUTH_CLIENT_SECRET|NOTION_OAUTH_CLIENT_ID|NOTION_OAUTH_CLIENT_SECRET|AIRTABLE_OAUTH_CLIENT_ID|AIRTABLE_OAUTH_CLIENT_SECRET|HUBSPOT_OAUTH_CLIENT_ID|HUBSPOT_OAUTH_CLIENT_SECRET|DISCORD_OAUTH_CLIENT_ID|DISCORD_OAUTH_CLIENT_SECRET|DISCORD_BOT_TOKEN)='
if [[ -f "$PROJECT_ROOT/backend/.env" ]]; then
# Only emit lines whose key matches the allow-list. Comment lines and
# blank lines are dropped (they're not needed in the shipped file).
grep -E "$SHIP_ENV_KEYS" "$PROJECT_ROOT/backend/.env" > "$STAGING_DIR/backend/.env" || true
KEY_COUNT=$(wc -l < "$STAGING_DIR/backend/.env" | tr -d ' ')
echo "Staged OAuth credentials: $KEY_COUNT keys (release secrets + personal API keys excluded)"
else
echo "WARNING: backend/.env not found — packaged build will have no OAuth credentials configured."
: > "$STAGING_DIR/backend/.env"
fi
# Create empty tools directory so the app has a place to write
mkdir -p "$STAGING_DIR/backend/data/tools"