Commit Graph

2 Commits

Author SHA1 Message Date
r-zakarya c58424d58c feat(sync): include avatar in sync snapshot + auto-backup (multi-device)
The profile picture (users.avatar_b64, cosmetic/unencrypted) travelled only
in the manual export. Now it's also in buildSyncSnapshot and the auto-backup
container, so a new device / a restore picks it up.

- Restore is ADDITIVE (mirrors the import path): applyRemoteSnapshot adopts
  remote.avatar_b64 only when the local device has no avatar — never clobbers
  a locally-set picture. No per-avatar timestamp to arbitrate, so changing an
  existing avatar doesn't propagate (cosmetic, accepted).
- +2 merge tests (adopt-when-empty, don't-clobber-when-set). 65/65 green.
- Server /avatar endpoint unchanged (already accepts {avatar_b64}).

Closes the avatar item of CODE_AUDIT §4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 20:06:31 +01:00
r-zakarya 4fd768d4cf refactor(js): extract auto-backup module from app.js monofile (§3.1)
Fifth slice of the app.js split. Moves the scheduled encrypted-backup
feature (config, retention, runAutoBackupNow/runAutoBackupIfDue) to
js/app.backup.js. Pure declarations + two consts, no top-level side effects
→ loads before app.js; uses encryptExportPayload (app.import.js), Bridge,
api, state via shared global scope at call time.

- Byte-for-byte identical extraction; no duplicate const; no top-level
  backup reference left in app.js; syntax OK on all six app parts.
- index.html + BuildAssets whitelist + harness APP_PARTS updated; assets
  regenerated (manifest embeds all 7 ordered JS files).
- 55/55 tests green.

app.js: 11936 → 9900 lines — now under 10k. Five modules extracted
(~2000 lines): argon2 → crypto → totp → import → backup → app → sync.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 16:46:01 +01:00