There's no reason the Garmin token-store root and the SQLite database
file need to live near each other -- they're independent env vars
(GARMIN_TOKENSTORE, GENIUSRUN_DB_PATH) and should stay independently
configurable, including in their defaults. Revert the "next to DBPath"
default introduced in 77f9588 back to a plain ".garmin" relative to
the working directory, so pointing GENIUSRUN_DB_PATH elsewhere never
silently drags the token-store default along with it.
Shorter, more conventional dotdir name than garmin-tokenstores. Restore
the "next to DBPath" join that got dropped when the default was
inlined via getEnvDefault -- an explicit GARMIN_TOKENSTORE still wins
verbatim, but the implicit default must still resolve relative to the
DB file's directory, not the process's CWD.
internal/garmin/client.go's GARMIN_TOKENSTORE env var is now always
set (TokenStorePath can no longer be empty), so the conditional that
only appended it when non-empty is dead code.
Now that GENIUSRUN_FRONTEND_URL exists as a separate config value, keeping
the backend's own origin named "PublicBaseURL" invited exactly the kind of
mixup that caused the OIDC callback 404 in the first place. Renamed
consistently: env var, Config.BackendURL, api.SessionConfig.BackendURL.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lets the OIDC callback redirect to the frontend's real origin instead of
a relative path resolved against the backend's own origin -- needed for
this project's own supported split-origin local dev setup (frontend on
Vite, backend on geniusrund, bridged by CORS).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The wrapper script is embedded in the binary now (internal/garmin), so
there's no script path left to configure. The interpreter path becomes
optional, defaulting to python3 on PATH, matching how other optional
plumbing (e.g. GENIUSRUN_OIDC_REQUIRED_ROLE) is already handled.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per-user profile isolation namespaces each user's mcp-garmin session
cache under {GarminTokenStoreRoot}/{userID} (api.Server.garminFor), but
Load() left GarminTokenStoreRoot ("" when GARMIN_TOKENSTORE is unset)
with no required-var check and no safe default. In that state
garminFor's `if cfg.TokenStorePath != ""` guard skips the per-user
join entirely, so every user's subprocess would fall back to the same
default token cache -- a cross-user Garmin-session collision risk in
any deployment that forgets to set GARMIN_TOKENSTORE.
Default it to a "garmin-tokenstores" directory next to DBPath when
unset, so every deployment gets per-user isolation automatically,
while GARMIN_TOKENSTORE can still override it explicitly. Log the
derived default. Update the field's doc comment (no longer "if set")
and add config_test.go cases covering the default derivation and the
explicit-override precedence.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>