From cf74ada3c2b1b7043f134240232b0dba79bf515d Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 26 May 2026 12:25:31 -0700 Subject: [PATCH] [eric] auth: generate installation_id at backend startup so first-launch sign-in always has a non-empty install_id; bump 1.1.66 - installation_id was created lazily on the first analytics submission; 1.1.64 removed the workflows startup poller, which was the early backend ping that used to generate it, so on a clean install the sign-in window built its google/email oauth url with an empty install_id and the cloud rejected the start - now generated in main.py at the same pre-bind moment as the auth token, so GET /api/settings carries it from the very first fetch (no dependency on analytics timing) - idempotent uuid4 hex, only written when missing; lazy path kept as fallback; platform-agnostic so mac is unchanged except the id exists slightly earlier Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/main.py | 18 ++++++++++++++++++ electron/package.json | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/backend/main.py b/backend/main.py index ad65599c..f4c76cf4 100644 --- a/backend/main.py +++ b/backend/main.py @@ -54,6 +54,24 @@ init_auth_token() # proxied-request error bodies) gets redacted before hitting handlers. install_token_scrubber() +# Generate the per-install id (installation_id) at the same pre-bind moment +# as the auth token. It is otherwise created lazily on the first analytics +# submission, so on a clean install the sign-in window can render and build +# its Google/email OAuth URL (which embeds install_id) before that +# submission fires, producing an empty install_id that the cloud rejects. +# Generating here guarantees the very first GET /api/settings already +# carries it. Platform-agnostic; wrapped so a settings hiccup never blocks +# startup, and the lazy path stays as a fallback. +try: + import uuid as _uuid + from backend.apps.settings.store import load_settings as _load_boot_settings, save_settings as _save_boot_settings + _boot_settings = _load_boot_settings() + if not getattr(_boot_settings, "installation_id", None): + _boot_settings.installation_id = _uuid.uuid4().hex + _save_boot_settings(_boot_settings) +except Exception: + pass + # CORS: previously wide open (`allow_origins=["*"]`), which combined with # `allow_credentials=True` was a security footgun, any external origin diff --git a/electron/package.json b/electron/package.json index 8c071a07..bf7b6d92 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,6 +1,6 @@ { "name": "openswarm", - "version": "1.1.65", + "version": "1.1.66", "description": "OpenSwarm — AI Agent Orchestrator", "author": "openswarm-ai", "main": "main.js",