Repository navigation
Conversation
…bmail bulwarkmail#143 Port of the webmail's masked addresses (lib/stalwart/masked-email.ts, components/settings/masked-addresses-section.tsx). On a Stalwart server that offers them, Settings > Security lists the account's masked addresses ten to a page. One can be copied, given a description, turned off so new mail to it is rejected, or deleted for good after a confirm, and a new one created with an optional website and description. The section stays hidden where the server has none (another server, or Stalwart Community before 1.1.1) and for a sign-in the server gives no account settings. A delete whose answer never came is not sent again until the list has been read afresh. The strings are the webmail's masked_addresses block, in every locale.
wmcparla
force-pushed
the
feat/masked-addresses
branch
from
November 14, 2026 23:10
a633197 to
61e5938
Compare
wmcparla
marked this pull request as ready for review
November 14, 2026 23:25
Member
|
Thanks for this. Masked addresses landed on main in 19bae84 through the catch-up with the webmail, so I'm closing this one as superseded. Main's section works like yours: hidden when the server doesn't offer masked addresses (including Stalwart's Enterprise-only refusal), with a line when the session may not list them. I took your keyboard handling into ca85c7e, so the create form and the description field stay above the keyboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The app gets the webmail's masked addresses (#143). On a Stalwart server that offers them, Settings > Security ends with a Masked addresses section: the account's addresses ten to a page, each with Copy and Edit (describe it, disable or enable it, delete it for good after a confirm), and a form to create one with an optional website and description.
It ports the webmail's
lib/stalwart/masked-email.tsandcomponents/settings/masked-addresses-section.tsx, and follows them unless noted below.Changes
src/lib/masked-email.ts): the webmail's manager, kept whole.x:MaskedEmail/query(filtered to the account) and/getin batches withinmaxObjectsInGet, and is either complete or an error: a changed total or query state, a repeated or unasked-for id, a record of another account or a malformed one all fail it.null, which Stalwart requires.deleteUnconfirmed) until a fresh list has shown whether the address is still there.src/api/masked-email.ts): the webmail goes through its server-side passthrough; the app asks Stalwart itself withurn:stalwart:jmapinusing, asapi/account-security.tsdoes. The manager is bound to the login and account active when it is made (servedLoginOf,loginMovedFrom) and sends nothing once another one is active.MaskedAddressesSection.tsx, shown fromAccountSecuritySettingswhen the Stalwart sections are):SettingsKeyboardContext, and Done on the keyboard saves or creates.urn:inbuxa:jmap:registry, withenabledforenable): the app talks to no Inbuxa registry anywhere else;settings-search.test.ts), and this section is there on some servers only.settings.security.masked_addressesblock, copied into each vendoredlocales/<lang>/common.jsonat the place the webmail has it. A latersync-localeswrites the same text.Related issues
Closes #143
Type of change
Checklist
npm run typecheckand there are no errors (native has nolintscript)npm run buildin native; an x86_64 release APK,assembleGithubRelease -PallowDebugSignedRelease=true, builds and runs)locales/) if my changes affect user-facing text (the webmail's own translations;npm run i18n:checkpasses)Tests:
npx vitest run: 7183 passed, 163 skipped (the live Stalwart suites).npx tsc --noEmitandnpm run i18n:checkare clean. New:src/lib/__tests__/masked-email.test.ts: the webmail'smasked-email.test.tsandmasked-email-destroy.test.tsagainst a scripted server (paging, batch size, every malformed or foreign answer, the Enterprise-only refusal, null for empty text, the delete states, another login becoming active).src/api/__tests__/masked-email.test.ts: the capability gate, the request shape, method errors by type, an expired sign-in told from a request with no answer.src/components/settings/__tests__/masked-addresses.test.ts: which line follows which failure, and the page clamp.On a device (Android 16 emulator, phone):
enable, noaccountIdon a record,updated: {id: null}, an empty description refused, null accepted).src/api/masked-email.tsanswered from memory the way Stalwart's source does, local only), 35 checks, all pass: create with and without website and description, the form emptied afterwards, copy, describe (Save off until the text changes), disable and enable, delete with Cancel and with confirm, ten rows a page with Previous and Next, the page of a new address shown, the last page emptied falling back to the one before, over quota, rate limit, a refused create, update and delete, and an unanswered delete (off until Refresh, which shows the address gone).forbiddenthe code looks for.Screenshots
The addresses are the stand-in's.
🤖 Generated with Claude Code