Skip to content

fix: apply admin password and SMTP changes without a manual restart - #83

Merged
MattDHill merged 1 commit into
masterfrom
fix/set-admin-password-restart
Jul 27, 2026
Merged

fix: apply admin password and SMTP changes without a manual restart#83
MattDHill merged 1 commit into
masterfrom
fix/set-admin-password-restart

Conversation

@MattDHill

Copy link
Copy Markdown
Member

Bumps 1.156.0:41.156.0:5.

Set Admin Password

The action wrote pendingAdminPassword to store.json and returned. main read the store with .once(), so nothing reacted, and the apply-admin-password oneshot that actually sets the password only runs at startup — so the new password silently didn't work until the user restarted Synapse by hand.

The action now calls sdk.restart(effects). Applying the password needs both the Synapse image (for hash_password) and a running PostgreSQL, so it stays in the oneshot rather than moving into the action; on a stopped service restart is a no-op and the password is applied at the next start, which is why the action still allows any status.

This also drops a stray whole-store .const() the oneshot registered right after clearing the field. It only ran on boots that had a pending password, so store reactivity came and went depending on the previous boot.

SMTP

Same root cause, plus SMTP lived inside the config action — where an SMTP-only change left homeserver.yaml byte-identical, so it never tripped main's watch either.

Split out into a manage-smtp action following the packaging guide's Set Up SMTP / Email recipe:

  • the action writes only the selection to store.json
  • main watches that field with .const(), and when the selection is system also watches sdk.getSystemSmtp(effects).const() — so both a user change and a change to StartOS's own SMTP settings restart Synapse

The store read is scoped to smtp rather than whole-store because the oneshot clears pendingAdminPassword in the same file; that field is read with a scoped .once().

Two behavior changes fall out:

  • main renders the email block before it const-reads homeserver.yaml. The original ordering merged after the const read, which would throw Canceled: write after const on the first start after any SMTP change once the field became reactive.
  • Disabling SMTP now writes email: null. Previously main only wrote the block when the selection was not disabled, so turning SMTP off left the old credentials in homeserver.yaml indefinitely. Verified against ghcr.io/element-hq/synapse that EmailConfig.read_config does email_config = config.get("email"); if email_config is None: email_config = {}, so null reads as an absent key.

No migration needed: main renders from the store on every start, so an install that set SMTP under :4 gets it applied by the upgrade restart.

Removes Create Bot User

Duplicates what the bundled Ketesa admin dashboard already does from its Users tab. Nothing consumes it — the only reference across Start9Labs and Start9-Community is a fully commented-out block in openclaw-startos.

Test plan

  1. Install the s9pk and complete setup (Set Server Address/URL, then Set Admin Password). Start Synapse and confirm you can log into the Admin Dashboard as admin.
  2. Password, running: with Synapse running, run Set Admin Password. Confirm the service restarts on its own, then log into the Admin Dashboard with the new password — without restarting manually.
  3. Password, stopped: stop Synapse, run Set Admin Password, confirm it stays stopped and returns credentials. Start it and confirm the new password works.
  4. SMTP custom: with Synapse running, run Configure SMTP → Custom with a real SMTP server. Confirm the service restarts, and that start-cli package attach synapse -n synapse-sub -- cat /data/homeserver.yaml shows the email block. Trigger a password reset from a Matrix client and confirm the mail arrives.
  5. SMTP system: run Configure SMTP → System. Confirm the restart and the rendered credentials. Then change your StartOS system SMTP settings and confirm Synapse restarts on its own and picks up the new values with no further action.
  6. SMTP disabled: run Configure SMTP → Disabled. Confirm the restart and that homeserver.yaml now has email: null, and that Synapse starts healthy.
  7. Config unaffected: run Config, change Max Upload Size, confirm the restart and the new limit. Confirm the form no longer shows SMTP fields.
  8. Bot user: confirm Create Bot User is gone from the Actions list, and that creating a user from the Admin Dashboard Users tab still works.
  9. Appservices: register and delete an appservice to confirm those actions are untouched.

…1.156.0:4 → 1.156.0:5

Set Admin Password wrote pendingAdminPassword to store.json and returned. main
read the store with .once(), so nothing reacted, and the apply-admin-password
oneshot that actually sets the password only runs at startup — the new password
did not work until the user restarted by hand. The action now calls
sdk.restart(effects). Dropped the stray whole-store .const() the oneshot
registered after clearing the field: it only ran on boots that had a pending
password, so store reactivity came and went.

SMTP had the same problem and was also folded into the Config action, where an
SMTP-only change left homeserver.yaml byte-identical and so never tripped main's
watch. Split it into a manage-smtp action per the packaging guide's Set Up SMTP
recipe: the action writes only the selection to store.json, and main watches that
field with .const() plus getSystemSmtp().const() when the selection is system, so
both a user change and a host credential change restart Synapse. The store read is
scoped rather than whole-store because the oneshot clears pendingAdminPassword in
the same file.

main renders the email block before it const-reads homeserver.yaml, so the write
is not a write-after-const — the original ordering would have thrown Canceled:
write after const on the first start after any SMTP change once the field became
reactive. Disabling SMTP now writes email: null, which Synapse reads as an absent
key; previously main only wrote when the selection was not disabled, so stale
credentials survived being turned off.

Also removes the Create Bot User action, which duplicates what the bundled Ketesa
admin dashboard already does from its Users tab. Nothing consumes it — the only
reference in either registry is a fully commented-out block in openclaw-startos.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@MattDHill
MattDHill merged commit 0143000 into master Jul 27, 2026
3 checks passed
@MattDHill
MattDHill deleted the fix/set-admin-password-restart branch July 27, 2026 04:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant