<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packages/meshbay-hub/tests/test_email_change_requires_passphrase.py, branch main</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=main</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-09-25T15:24:16Z</updated>
<entry>
<title>fix(hub): require the passphrase to change the e-mail on file</title>
<updated>2026-09-25T15:24:16Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-25T12:28:03Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=6b9b5394c5ec01c5de01b7bf23bc161792f38278'/>
<id>urn:sha1:6b9b5394c5ec01c5de01b7bf23bc161792f38278</id>
<content type='text'>
A member hands its hub access token to every node it connects to (the MNP
handshake), so a node operator holds a live bearer token for that member.
PATCH /v1/users/me {email} needed only that token, and the confirmation code
goes to the new address — so an operator could point the account's e-mail at
their own inbox, confirm it, and then use the passphrase-reset path to take the
account over. This is the immediate mitigation of that chain; the full fix
(a node-audience token distinct from the API session token) follows.

Changing the address now requires the passphrase-derived auth_key, verified
through the same throttle as a passphrase change or an account deletion — the
hub still never sees the passphrase. A PATCH that does not change the address is
unaffected. The profile page prompts for the passphrase and derives auth_key
with the existing MeshBayKeys.deriveAuthKey, as the delete and change-password
flows already do.

test_email_change_requires_passphrase.py: refused without / with a wrong
passphrase, proceeds with the right one, and a no-email PATCH still works; red
before, green after. test_mail_is_not_a_relay.py updated to pass the auth_key.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
