Commit Graph
5 Commits
Author SHA1 Message Date
thePR0M3TH3ANandClaude Opus 4.8 6bdf28fb30 [upload] Auto-unlock storage in the upload modal for a kept-unlocked session (#51)
The upload modal only READ storage's unlock state (isUnlocked) on load/open/refresh
— it never auto-unlocked the way the profile Storage pane does. So after a refresh
with "keep unlocked" ticked, the upload modal still opened with storage Locked even
though the signer had been restored.

Add UploadModal.maybeAutoUnlockStorage(pubkey), called on load(), open(), and
refreshState(): if storage is locked but a decrypt-capable signer is already present
(e.g. a kept-unlocked nsec restored on refresh), unlock silently. Guarded two ways:
  - only when the account ALREADY exists (new storageService.hasStoredAccount) so it
    never auto-creates storage for magnet/URL-only uploaders, and
  - only when the signer is already available, so it never triggers a fresh
    permission prompt on modal open.

Tests: storageService.hasStoredAccount (false before setup, true after unlock,
never creates an account, survives lock). Lint + build green.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-01 20:20:57 -04:00
thePR0M3TH3ANandClaude Opus 4.8 200e5cec80 test(storage): assert credentials never persist in plaintext at rest
Pre-launch credential-security regression: scans the ENTIRE serialized account
record (meta + encrypted blob) for the secret/access-key strings and asserts
they never appear in plaintext, that listConnections() doesn't expose them, that
they round-trip while unlocked, and that they're unreachable once locked. The
prior check only compared the cipher field to JSON.stringify(payload), which
wouldn't catch a secret leaking into plaintext meta.

Audit conclusion: credential storage is sound — envelope encryption (AES-GCM-256
payload, fresh per-encrypt IV; master key encrypted to-self via the Nostr signer,
NIP-44 preferred / NIP-04 fallback), in-memory master key cleared on logout, no
secret logging, legacy plaintext migrated then cleared.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-17 05:35:02 -04:00
thePR0M3TH3AN 44dfcc363b Improve storage unlock permission and decrypt error handling 2026-02-08 14:38:21 -05:00
google-labs-jules[bot] ea026552ce Fix: Enforce single default storage connection
Previously, `StorageService.saveConnection` allowed multiple connections to be marked as `defaultForUploads: true` because it did not unset the flag on existing connections. This caused `loadFromStorage` (which uses `find`) to potentially pick up an old, invalid connection instead of the newly configured one, leading to a loop where the user is asked to configure credentials again.

This change modifies `saveConnection` to iterate through existing connections and unset `defaultForUploads` if the new connection is being saved as the default. This ensures the "default" invariant is maintained.

Added a unit test case to verify this behavior.
2026-01-25 17:40:16 +00:00
google-labs-jules[bot] fa10f943e1 test(ai): add unit tests for storageService and appState (agent) 2026-01-24 11:44:16 +00:00