<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packages/meshbay-hub/src/meshbay_hub/api/users.py, branch 0.17</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.17</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.17'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-10-01T11:37:38Z</updated>
<entry>
<title>fix(hub): a username is unique whatever its case</title>
<updated>2026-10-01T11:37:38Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-01T11:37:38Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=7ca80a47dd8ff529951f59ef586c511e4debb057'/>
<id>urn:sha1:7ca80a47dd8ff529951f59ef586c511e4debb057</id>
<content type='text'>
Registration refuses a name that differs from an existing one only by case;
accounts that already do keep their names, and a pending retry needs the exact
name (F-26).

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(hub): a stranger who knows your name locks only browsers you never used</title>
<updated>2026-10-01T09:47:39Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-10-01T09:47:39Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=752b160c7c5e671e0db8f402a52fac27bb85ab06'/>
<id>urn:sha1:752b160c7c5e671e0db8f402a52fac27bb85ab06</id>
<content type='text'>
A sign-in from a browser that presented no token is answered with one
(known_browser, kept hashed, twenty per account); a later sign-in presenting it
counts failures on its own row, which nobody else can spend. Passphrase checks
inside an open session (change, e-mail, deletion, device, pepper) count on the
account's own row, so a locked name no longer stops its owner there either; /me
reports that row. Reset and erasure forget the browsers (F-15).

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(hub): the pepper and a device key take the passphrase, not a token</title>
<updated>2026-09-30T19:04:39Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T19:04:39Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=0ed56d3a1b4f71cf622d3e27edc87a15ef33c185'/>
<id>urn:sha1:0ed56d3a1b4f71cf622d3e27edc87a15ef33c185</id>
<content type='text'>
POST /me/bundle-pepper (was GET) and POST /users/devices require auth_key.
A refreshed or lifted token could otherwise fetch the pepper, or register a
device whose every sign-in carries it. Both callers have just been given the
passphrase.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: browser access, decided in the desktop application</title>
<updated>2026-09-30T15:13:40Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T15:13:40Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=b1ebcdeb9082457972c41a47e77494902335d262'/>
<id>urn:sha1:b1ebcdeb9082457972c41a47e77494902335d262</id>
<content type='text'>
Off for an account made there: its identities stay on the device and nothing is
left on nodes. Turned on from the Profile page behind a native confirmation;
each node is settled when its group next opens. The hub keeps a mirror a
browser reads to say why a group will not open; it grants nothing.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: bundles sealed per node under the passphrase and the hub's pepper</title>
<updated>2026-09-30T13:06:14Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T13:06:14Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=91297944791a36f30302ef8c86dd69ebeb177671'/>
<id>urn:sha1:91297944791a36f30302ef8c86dd69ebeb177671</id>
<content type='text'>
The session key is M = HKDF(Argon2(passphrase) || pepper, account id); each
node's bundle key and the playlist key derive from it. Bundles are MBK3, bound
to account and node; MBK1/MBK2 are refused by name, never replaced silently.
Playlists move to key v2 and are re-sealed over unreadable node copies.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(hub): a bundle pepper per account, handed only to a proven session</title>
<updated>2026-09-30T11:55:59Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T11:55:59Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=a55d40b74bda77dff6ec565abdd551607fc665d6'/>
<id>urn:sha1:a55d40b74bda77dff6ec565abdd551607fc665d6</id>
<content type='text'>
Sealed at rest and bound to the account; returned by sign-in, device sign-in,
a passphrase change and GET /me/bundle-pepper, never by a refresh, to a node
token, in a token or in a log. Erasure clears it.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix: only the owner decides who hosts a group, and nobody is made a member unasked</title>
<updated>2026-09-30T09:49:56Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-30T09:49:56Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=d3ad243c4ae3a273f623bd5fc631e3266aa4d0e4'/>
<id>urn:sha1:d3ad243c4ae3a273f623bd5fc631e3266aa4d0e4</id>
<content type='text'>
- hub: a node may host a group only if its account owns it or the owner
  approved that node (new `group_hosts`). Membership was the ceiling, and
  every member holds the group key, so any member's node could register as a
  host and be the one clients kept. A node claiming a group it may not host
  is recorded as a request; the owner is notified once and approves or
  refuses it (GET/POST/DELETE /v1/groups/{id}/hosts[/{node_id}]), which
  takes effect on a connected node at once.
- hub: an owner adding a username creates an invitation (new
  `group_invitations`), accepted or declined by the invitee
  (/v1/groups/invitations, /{id}/invitation/accept|decline). Until then the
  group is not listed, not dialled, not searched and not in any token.
  Invitation links, open joins and group creation still make members
  directly: they are the account's own act.
- hub: the MNP token names only the group it is minted for (group_id is now
  required), so a node operator no longer learns a member's other groups.
- SPA: invitations on the home page; invited people and host requests in
  the group's settings; the transport sends group_id. Ten catalogues.
- Browser probes for both screens, run in Chrome and Firefox.
- Design §5.2, §7.2, §7.3, AV32, AV33; protocol §6.3; user guide.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor: remove the public-content swarm</title>
<updated>2026-09-28T19:35:20Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-28T19:35:20Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=91505face56f7ee6817408e52bad7902add75f09'/>
<id>urn:sha1:91505face56f7ee6817408e52bad7902add75f09</id>
<content type='text'>
Nodes registered the hashes of their public groups on the hub and nothing
ever read them back. Routes, model and node registration removed; a
migration drops swarm_sources. No node sends the hub a content hash now.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<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>
<entry>
<title>feat(hub): invitation-link tickets bound to a verified address</title>
<updated>2026-09-23T15:46:48Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-23T15:46:48Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=998f9c69308ee88fac36cfb77dfb6d07c6fa926a'/>
<id>urn:sha1:998f9c69308ee88fac36cfb77dfb6d07c6fa926a</id>
<content type='text'>
group_invite_links holds sha256(ticket) and the invitee's address blind
index; redeeming grants membership to that account only. Owner-only
create/list/cancel (a node token may create, never mail), 20 outstanding
per group, optional mail written by the hub itself and capped at 10 per
sender per day (mail.invite_link_daily_cap). MESHBAY_DESIGN.md §3.4 now
carries the whole link design.

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