feat(call): optional Element Call origin via config.json elementCallUrl (#43)
CI / Build & Quality Checks (pull_request) Successful in 3m31s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 12s
CI / Playwright smoke (e2e) (pull_request) Successful in 12m27s

Groundwork for serving the call page from its own origin
(call.chat.lotusguild.org). Inert until config.json sets `elementCallUrl`:
without it the bundled same-origin page is used exactly as today.

- callPageUrl: resolves `elementCallUrl` — absolute https only (http only on
  localhost for development); anything else, and the desktop app, fall back
  to the bundled page so a bad value can't break calls. Set once from the
  loaded client config.
- CallEmbed builds the widget URL from it; the widget origin (used by the
  message guard and Capability Delegation) follows automatically.
- Soundboard: a host blob: URL can't be fetched from another origin, so
  io.lotus.inject_audio now also carries the clip's bytes (`audio`). Forks
  that predate it ignore the field and use `url`, so this is safe on the
  released fork.

Needs element-call's lotus-call-origin branch (host-origin message check +
inject_audio bytes) released and pinned before `elementCallUrl` is set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
Lotus CI
2026-09-26 23:24:24 -04:00
co-authored by Claude Opus 5.5
parent df395776b4
commit 4dcc5176e2
7 changed files with 134 additions and 28 deletions
+22 -17
View File
@@ -36,6 +36,7 @@ import { applyCustomAccent, removeCustomAccent } from '../utils/accentColor';
import { zIndices } from '../styles/zIndex';
import { OIDC_CALLBACK_PATH } from './paths';
import { OidcCallback } from './auth/oidc/OidcCallback';
import { resolveCallPageUrl, setCallPageUrl } from '../plugins/call/callPageUrl';
// The emoji families (Twemoji when "Twitter emoji" is on, Twemoji flags on
// Windows — see SystemEmojiFeature) must sit before the generic family, or the
@@ -220,23 +221,27 @@ function App() {
<ConfigConfigError error={err} retry={retry} ignore={ignore} />
)}
>
{(clientConfig) => (
<ClientConfigProvider value={clientConfig}>
<QueryClientProvider client={queryClient}>
<JotaiProvider>
<AppearanceEffects />
<TauriEffects />
<DesktopChrome>
<RouterProvider router={createRouter(clientConfig, screenSize)} />
</DesktopChrome>
<SeasonalEffect />
<NightLightOverlay />
<LotusToastContainer />
</JotaiProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</ClientConfigProvider>
)}
{(clientConfig) => {
// [Gitea #43] Idempotent: where the call page is loaded from.
setCallPageUrl(resolveCallPageUrl(clientConfig.elementCallUrl, isTauri()));
return (
<ClientConfigProvider value={clientConfig}>
<QueryClientProvider client={queryClient}>
<JotaiProvider>
<AppearanceEffects />
<TauriEffects />
<DesktopChrome>
<RouterProvider router={createRouter(clientConfig, screenSize)} />
</DesktopChrome>
<SeasonalEffect />
<NightLightOverlay />
<LotusToastContainer />
</JotaiProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</ClientConfigProvider>
);
}}
</ClientConfigLoader>
</FeatureCheck>
</ScreenSizeProvider>