diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 4ca12d4..e37b96e 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -55,10 +55,15 @@ bash ./scripts/dev-server-init.sh This completes the bootstrap wizard (default domain `example.org`, no TLS certificate request — safe for local/offline use), creates a real -`devadmin@example.org` admin account, and sets the server's default OAuth -access token lifetime to 3 hours. It's idempotent — safe to re-run, it -no-ops once the server is already bootstrapped. You only need to re-run it -after `docker compose down -v` (which wipes the volumes). +`devadmin@example.org` admin account, sets the server's default OAuth +access token lifetime to 3 hours, and points the `x:Application` record +serving `/admin`/`/account` at this fork's description and release URL +(cosmetic — otherwise Settings > Web Applications' "Active WebUI" card +shows Stalwart's default "Stalwart Web Interface" / upstream release URL, +even though what's actually running is this fork served by Vite). It's +idempotent — safe to re-run, it no-ops once the server is already +bootstrapped. You only need to re-run it after `docker compose down -v` +(which wipes the volumes). ## 3. Get an access token diff --git a/scripts/dev-server-init.ps1 b/scripts/dev-server-init.ps1 index b165e81..7cfa0f4 100644 --- a/scripts/dev-server-init.ps1 +++ b/scripts/dev-server-init.ps1 @@ -119,4 +119,29 @@ try { } | Out-Null } catch {} +# Cosmetic only: Stalwart seeds a default "Stalwart Web Interface" / +# stalwartlabs/webui entry for the x:Application record serving /admin and +# /account (see Settings > Web Applications' "Active WebUI" card). Point it +# at this fork so that card isn't misleading in local dev too. +Write-Host "Pointing the active WebUI's description at this fork..." +try { + $appResult = Invoke-Jmap @{ + using = @("urn:ietf:params:jmap:core", "urn:stalwart:jmap") + methodCalls = @(, @("x:Application/query", @{ accountId = $accountId }, "0")) + } + $appId = $appResult.methodResponses[0][1].ids[0] + if ($appId) { + Invoke-Jmap @{ + using = @("urn:ietf:params:jmap:core", "urn:stalwart:jmap") + methodCalls = @(, @("x:Application/set", @{ + accountId = $accountId + update = @{ $appId = @{ + description = "Stalwart WebUI Fork" + resourceUrl = "https://github.com/LinkPhoenix/stalwart-webui-fork/releases/latest/download/webui.zip" + } } + }, "0")) + } | Out-Null + } +} catch {} + Write-Host "Done. $DevAdminName@$DevDomain / $DevAdminSecret is ready - run scripts/dev-token.ps1 to get a token." diff --git a/scripts/dev-server-init.sh b/scripts/dev-server-init.sh index b02f3ed..9ca811a 100644 --- a/scripts/dev-server-init.sh +++ b/scripts/dev-server-init.sh @@ -61,5 +61,16 @@ else jmap "{\"using\":[\"urn:ietf:params:jmap:core\",\"urn:stalwart:jmap\"],\"methodCalls\":[[\"x:OidcProvider/set\",{\"accountId\":\"$ACCOUNT_ID\",\"update\":{\"singleton\":{\"accessTokenExpiry\":$DEFAULT_TOKEN_EXPIRY_MS}}},\"0\"]]}" > /dev/null jmap "{\"using\":[\"urn:ietf:params:jmap:core\",\"urn:stalwart:jmap\"],\"methodCalls\":[[\"x:Action/set\",{\"accountId\":\"$ACCOUNT_ID\",\"create\":{\"a1\":{\"@type\":\"ReloadSettings\"}}},\"0\"]]}" > /dev/null 2>&1 || true + # Cosmetic only: Stalwart seeds a default "Stalwart Web Interface" / + # stalwartlabs/webui entry for the x:Application record serving /admin + # and /account (see Settings > Web Applications' "Active WebUI" card). + # Point it at this fork so that card isn't misleading in local dev too. + echo "Pointing the active WebUI's description at this fork..." + APP_RESULT=$(jmap "{\"using\":[\"urn:ietf:params:jmap:core\",\"urn:stalwart:jmap\"],\"methodCalls\":[[\"x:Application/query\",{\"accountId\":\"$ACCOUNT_ID\"},\"0\"]]}") || true + APP_ID=$(printf '%s' "$APP_RESULT" | grep -o '"ids":\["[^"]*"' | cut -d'"' -f4) + if [ -n "$APP_ID" ]; then + jmap "{\"using\":[\"urn:ietf:params:jmap:core\",\"urn:stalwart:jmap\"],\"methodCalls\":[[\"x:Application/set\",{\"accountId\":\"$ACCOUNT_ID\",\"update\":{\"$APP_ID\":{\"description\":\"Stalwart WebUI Fork\",\"resourceUrl\":\"https://github.com/LinkPhoenix/stalwart-webui-fork/releases/latest/download/webui.zip\"}}},\"0\"]]}" > /dev/null 2>&1 || true + fi + echo "Done. devadmin@$DEV_DOMAIN / $DEVADMIN_SECRET is ready — run scripts/dev-token.sh to get a token." fi diff --git a/src/components/lists/DynamicList.tsx b/src/components/lists/DynamicList.tsx index fc62e3e..d55227f 100644 --- a/src/components/lists/DynamicList.tsx +++ b/src/components/lists/DynamicList.tsx @@ -590,7 +590,7 @@ export function DynamicList({ viewName }: DynamicListProps) { objectName ?? 'x:Application', accountId, {}, - ['id', 'description', 'enabled', 'urlPrefix'], + ['id', 'description', 'enabled', 'urlPrefix', 'resourceUrl'], ); if (cancelled) return; const active = result.list.find((item) => isActiveWebApplication(item)); @@ -1573,6 +1573,19 @@ export function DynamicList({ viewName }: DynamicListProps) { {t('webApplications.version', 'Version')}: {__APP_VERSION__} + {typeof activeWebApp.resourceUrl === 'string' && activeWebApp.resourceUrl && ( +
+ {t('webApplications.resourceUrl', 'Source')}: + + {activeWebApp.resourceUrl} + +
+ )} )}