feat: recall an already-registered address without REGISTER
This commit is contained in:
parent
a244dab94e
commit
a24c143fd0
2 changed files with 42 additions and 1 deletions
|
|
@ -94,7 +94,7 @@
|
|||
<section>
|
||||
<h3><span id="step-server" class="step" data-n="1">1</span> your server</h3>
|
||||
<p class="hint">Pin the key of the server that will hold your mail. Get it from its operator over a
|
||||
channel you already trust — registering and fetching both refuse an unpinned server (SPEC.md §4).</p>
|
||||
channel you already trust — registering, recalling and fetching all refuse an unpinned server (SPEC.md §4).</p>
|
||||
<form id="pin-form">
|
||||
<label>host<input name="host" placeholder="example.org" spellcheck="false" required></label>
|
||||
<label>public key<input name="key" placeholder="base32" spellcheck="false" required></label>
|
||||
|
|
@ -111,6 +111,16 @@
|
|||
<label>invite token<input name="token" placeholder="if required"></label>
|
||||
<button class="filled">register</button>
|
||||
</form>
|
||||
<details>
|
||||
<summary>already registered elsewhere?</summary>
|
||||
<p class="hint">Restoring a seed brings back the identity, not the memory of what address it was
|
||||
registered under in a different browser — the server was never asked. Recall it here: this
|
||||
looks the address up and checks it resolves to this identity's key, without registering anything.</p>
|
||||
<form id="recall-form">
|
||||
<label>address<input name="address" placeholder="alice@example.org" spellcheck="false" required></label>
|
||||
<button>recall</button>
|
||||
</form>
|
||||
</details>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
|
|
|||
|
|
@ -883,6 +883,37 @@ $("register-form").onsubmit = async (event) => {
|
|||
}
|
||||
};
|
||||
|
||||
// Restoring a seed brings back the identity, not the memory of what address a
|
||||
// *different* browser registered it under — "account" is local-only state,
|
||||
// never asked of the server. This binds it without REGISTER: RESOLVE the
|
||||
// address and require it name this exact key, so a typo or someone else's
|
||||
// address can't silently misfile outgoing Reply-To / fetch under it.
|
||||
$("recall-form").onsubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
const form = event.target;
|
||||
try {
|
||||
const me = store.identity();
|
||||
if (!me) throw new SmolError("no identity yet");
|
||||
const addr = parseAddress(form.address.value.trim());
|
||||
const opened = await connect(addr, { requirePin: true });
|
||||
let current;
|
||||
try {
|
||||
({ identity: current } = await resolveOp(opened.session, addr.user));
|
||||
} finally {
|
||||
opened.session.stream.close();
|
||||
}
|
||||
if (!timingSafeEqual(current, me.publicKey))
|
||||
throw new SmolError(`${addr.short} resolves to a different key — not this identity`);
|
||||
store.setAccount(addr);
|
||||
status(`recalled ${addr.short}\nshare: ${addr.uri(me.publicKey)}`);
|
||||
renderAccount();
|
||||
renderSettings();
|
||||
form.reset();
|
||||
} catch (err) {
|
||||
status(err.message, true);
|
||||
}
|
||||
};
|
||||
|
||||
async function rotateIdentity() {
|
||||
const me = store.identity();
|
||||
const addr = accountAddress();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue