Skip to content

Let the email configuration dialog read and save its own settings - #3167

Open
cquirosj wants to merge 2 commits into
smtp-password-write-onlyfrom
smtp-password-write-only-dialog-state
Open

cquirosj wants to merge 2 commits into
smtp-password-write-onlyfrom
smtp-password-write-only-dialog-state

Conversation

@cquirosj

@cquirosj cquirosj commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Builds on

The email configuration dialog never shows the stored SMTP password, and nothing outside the dialog keeps it, with any ServiceControl version.

Behavior

  • The dialog reads the current settings from ServiceControl each time it opens, so it shows changes made elsewhere since the page loaded.
  • The password field always starts empty. Leaving it empty keeps the stored password; typing a new one replaces it. Removing the account also removes the password.
  • If the settings can't be loaded, the dialog says so and can't be saved. This also fixes a problem Explain that the stored SMTP password is never shown #3164 introduced: it reloaded all settings into the page each time the dialog opened, and if that request failed, the switch dropped to OFF and the dialog opened with an empty form. Now only the dialog loads its settings, so a failed load can't change the switch.

Older ServiceControl versions backward compatibility

ServiceControl before 6.21.2 returns the stored password, and a save replaces it with whatever is sent, including an empty value. Since the password field starts empty, a routine edit such as changing the To address would erase the stored password, and health check emails would silently stop authenticating.

To prevent that, on these versions the dialog keeps the password from the settings it reads when it opens. It's held in memory only, never shown, and sent back if the field is left empty. It's dropped when the dialog closes.

ServiceControl 6.21.2 and later (Particular/ServiceControl#5980) don't return the password and keep the stored one when an empty password is sent, so the dialog has nothing to hold and sends the empty password. No version check is involved: the dialog sends back whatever ServiceControl returned, which is nothing on 6.21.2 and later.

Implementation note

The dialog reads and saves its own settings through ServiceControl's API, and everything it holds is dropped when it closes. The Pinia store keeps only page-level state: whether notifications are enabled and the permissions, plus the toggle and test-notification actions. The dialog's tests answer its requests through the mock server and check what is sent to ServiceControl.

Reviewer Checklist

  • Components are broken down into sensible and maintainable sub-components.
  • Styles are scoped to the component using it. If multiple components need to share CSS, then a .css file is created containing the shared CSS and imported into component scoped style sections.
  • Naming is consistent with existing code, and adequately describes the component or function being introduced
  • Only functions utilizing Vue state or lifecycle hooks are named as composables (i.e., starting with 'use');
  • No module-level state is being introduced. If so, request the PR author to move the state to the corresponding Pinia store.

@cquirosj cquirosj changed the title ♻️ Load the email settings in the dialog instead of keeping them in the store Load the email settings in the dialog instead of keeping them in the store Oct 19, 2026
@cquirosj
cquirosj force-pushed the smtp-password-write-only-dialog-state branch from 149bf28 to e80633e Compare October 19, 2026 18:44
@cquirosj
cquirosj marked this pull request as ready for review October 19, 2026 18:56
@cquirosj
cquirosj requested a review from ramonsmits October 19, 2026 19:02
@cquirosj
cquirosj force-pushed the smtp-password-write-only-dialog-state branch 2 times, most recently from 9d53e1a to 637f2f4 Compare October 19, 2026 19:27
@cquirosj
cquirosj added this pull request to stack #3169 October 19, 2026 19:29
Comment thread src/Frontend/src/stores/HealthChecksStore.ts Outdated
@cquirosj cquirosj changed the title Load the email settings in the dialog instead of keeping them in the store Let the email configuration dialog read and save its own settings Oct 20, 2026
…he store

The store now keeps only page-level state: whether email notifications are
enabled, and the permissions. The configuration dialog loads the settings it
edits each time it opens, and they are dropped when it closes. The SMTP
password is never copied from the response.

ServiceControl versions before 6.21.2 replace the stored password with an empty
one. When the password field is left empty, the stored password is read and
sent back with the save request, so it is kept. If it cannot be read, the save
fails instead of erasing it.

If the settings cannot be loaded, the dialog says so and cannot be saved. The
on/off switch is no longer changed by opening the dialog.
The dialog now does the whole job itself: it reads the settings from
ServiceControl when it opens, keeps them while it is open, writes them back
when saved, and drops everything when it closes. The store keeps only
page-level state: whether notifications are enabled, and the permissions.

Older ServiceControl versions are supported without checking the version.
Versions before 6.21.2 return the stored password, so the dialog keeps it,
never shown, and sends it back when the password is left empty. Versions from
6.21.2 return none, so an empty password is sent and they keep the stored one.

The dialog's tests now answer its requests through the mock server and check
what is sent to ServiceControl.
import logger from "@/logger";

// The dialog reads the settings from ServiceControl when it opens, edits them here, and writes them back when saved.
// Nothing outlives the dialog: closing it drops everything below.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment can be a bit misleading: 'closing' the dialog doesn't drop everything below, it's the v-if in the parent causing the component to no longer be part of the virtual DOM that causes this entire component state to be discarded.

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.

3 participants