Skip to content

fix(identity): sync default sender identity per account (#507)#606

Merged
rathlinus merged 1 commit into
bulwarkmail:mainfrom
hildebrandttk:feat/sync-default-identity-507
Jul 13, 2026
Merged

fix(identity): sync default sender identity per account (#507)#606
rathlinus merged 1 commit into
bulwarkmail:mainfrom
hildebrandttk:feat/sync-default-identity-507

Conversation

@hildebrandttk

Copy link
Copy Markdown
Contributor

Summary

The default sender identity (preferredPrimaryId) lived only in the browser-local identity-storage store and was never written to the synced settings, so the choice was lost on clearing site data / switching browsers and never appeared in exported settings.

Persist it in the synced settings store, keyed per account (preferredIdentityIds: Record<accountId, identityId>), mirroring the existing per-account allMailFolderIds. Per-account keying is required because JMAP identity ids are account-scoped and would otherwise collide across accounts / the unified mailbox.

This supersedes the earlier username-keyed fix that had landed on main: the username-keyed map, loadIdentities() fallback write, and the applyPreferredIdentityOrdering store action (plus its settings-store hook) are removed so a single account-keyed mechanism remains.

Changes

  • settings-store: preferredIdentityIds (accountId -> identityId) in state, defaults, export, import (non-record guard), rehydrate coercion, v6 migration.

  • auth-store: applyPreferredIdentity(accountId?) reorders the active account's identities once synced settings load, and performs the one-time migration of the pre-[Bug]: Default identity (preferredPrimaryId) persists only in browser localStorage, not synced settings — lost on a new browser / after clearing site data #507 browser-local default into the synced map (keyed by accountId). Invoked from every loadFromServer().finally() (login / OAuth / SSO / switch / restore). loadIdentities() now only applies the local fallback ordering.

  • identity-manager-modal: the star action writes the choice by activeAccountId.

  • identity-store: preferredPrimaryId kept as a local (sync-off) fallback.

  • tests: per-account independence, export/import round-trip, import guard, and applyPreferredIdentity reorder / active-account gating / local-default migration.

Related Issues

Closes #507

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactor / code quality improvement
  • Chore / dependency update / CI change

Checklist

  • I have read the Contributing Guide
  • My code follows the project's code style and conventions
  • I have run npm run typecheck && npm run lint and there are no errors
  • The build passes (npm run build)
  • I have tested my changes locally
  • I have added or updated documentation if needed
  • I have updated translations (locales/) if my changes affect user-facing text
  • I have included screenshots or a screen recording for UI changes

Screenshots / Demo

Notes for Reviewers

)

The default sender identity (`preferredPrimaryId`) lived only in the
browser-local `identity-storage` store and was never written to the synced
settings, so the choice was lost on clearing site data / switching browsers and
never appeared in exported settings.

Persist it in the synced settings store, keyed **per account**
(`preferredIdentityIds: Record<accountId, identityId>`), mirroring the existing
per-account `allMailFolderIds`. Per-account keying is required because JMAP
identity ids are account-scoped and would otherwise collide across accounts /
the unified mailbox.

This supersedes the earlier username-keyed fix that had landed on main: the
username-keyed map, `loadIdentities()` fallback write, and the
`applyPreferredIdentityOrdering` store action (plus its settings-store hook)
are removed so a single account-keyed mechanism remains.

- settings-store: `preferredIdentityIds` (accountId -> identityId) in state,
  defaults, export, import (non-record guard), rehydrate coercion, v6 migration.
- auth-store: `applyPreferredIdentity(accountId?)` reorders the active account's
  identities once synced settings load, and performs the one-time migration of
  the pre-bulwarkmail#507 browser-local default into the synced map (keyed by accountId).
  Invoked from every `loadFromServer().finally()` (login / OAuth / SSO / switch
  / restore). `loadIdentities()` now only applies the local fallback ordering.
- identity-manager-modal: the star action writes the choice by `activeAccountId`.
- identity-store: `preferredPrimaryId` kept as a local (sync-off) fallback.
- tests: per-account independence, export/import round-trip, import guard, and
  applyPreferredIdentity reorder / active-account gating / local-default
  migration.
@rathlinus
rathlinus merged commit 01e5cd6 into bulwarkmail:main Jul 13, 2026
@hildebrandttk
hildebrandttk deleted the feat/sync-default-identity-507 branch July 14, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants