feat: refuse to learn a first-contact key from an unpinned server
Adds an opt-in "require a pinned server" setting that gates the one RESOLVE path that currently trusts whatever key a server hands back for a brand-new, hand-typed address — self-certifying addresses and already-known contacts are structurally exempt. A refusal shows an inline recovery card in compose to fetch, compare, and pin the key without losing the draft. Also closes two adjacent gaps: a self-certifying address could silently overwrite an already-trusted contact's key (now asks, showing both fingerprints), and a contact's detail view now names its server and pin state.
This commit is contained in:
parent
84397a3fdd
commit
80aca8a29f
4 changed files with 192 additions and 10 deletions
|
|
@ -145,6 +145,18 @@ export function allPins() {
|
|||
return Object.entries(load().servers || {}).map(([host, key]) => ({ host, key }));
|
||||
}
|
||||
|
||||
// §4/first contact: when true, resolving a never-before-seen recipient's key
|
||||
// from a server that isn't pinned is refused instead of merely toasted after
|
||||
// the envelope is already sealed. Persisted, not in-memory — an in-memory
|
||||
// toggle fails open on every restart, worth little as a security setting.
|
||||
export function requirePinnedServer() {
|
||||
return load().requirePinnedServer ?? false;
|
||||
}
|
||||
|
||||
export function setRequirePinnedServer(value) {
|
||||
update(state => { state.requirePinnedServer = value; });
|
||||
}
|
||||
|
||||
// --- FETCH behavior and cursor (§6.1) -------------------------------------------
|
||||
|
||||
// When true, fetch does not acknowledge (delete) what it retrieves — mail
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue