Skip to content

fix(atproto): address the take-ownership reset by DID, not by email - #603

Merged
tompscanlan merged 1 commit into
mainfrom
fix/take-ownership-reset-by-did
Sep 1, 2026
Merged

tompscanlan merged 1 commit into
mainfrom
fix/take-ownership-reset-by-did

Conversation

@tompscanlan

Copy link
Copy Markdown
Contributor

The problem

Take ownership sends a PDS password reset so the user can set their own password. It addressed that reset by the OpenMeet email address.

Nothing keeps the OpenMeet address in step with the email on the AT Protocol account. Changing an OpenMeet email through the ordinary profile path never writes the PDS side, so the two addresses can drift apart.

com.atproto.server.requestPasswordReset sends to whichever account owns the address it is given. Two things follow from that:

  1. If the OpenMeet address had drifted and another account owned it, the user received a working reset code for an account that was not theirs. Completing that reset changes the other account's password.
  2. If no account owned the address, the reset failed with an unclear error and take ownership was simply broken for that user.

The DID is the identity. The email is not, so it should not be the identifier.

The change

In initiateTakeOwnership:

  • The account is resolved from the identity DID through com.atproto.admin.getAccountInfo, and the reset is sent to the address on that account. A reset can now only reach the account the DID owns.
  • No account for the DID returns a 404. An account with no email address returns a 400. Neither reports success any more, which is the case that used to return 200 while sending nothing.
  • The response reports the address the reset actually went to. Users whose PDS account still carries a generated @openmeet.net address will now see that address instead of a silent success. Delivery for those accounts is still broken and is not fixed here.
  • The OpenMeet email is no longer required to start take ownership, since it is no longer the identifier.
  • A mismatch between the two addresses is logged as a warning, keyed by DID. The addresses themselves are not logged.

The response shape is unchanged. Only the source of the value moved.

Not in this change

syncEmailToPds is still not called from the profile update path, and it still swallows failures into a warning. That is where the drift comes from. This change makes drift harmless at the reset. It does not stop drift happening.

Testing

  • 29 tests pass in atproto-identity-recovery.service.spec.ts, 124 across src/atproto-identity/.
  • Four cases cover the change. The important one sets the OpenMeet email to an address the user does not own on the PDS and asserts the reset goes to the account address instead. The others cover no account for the DID, an account with no email, and the ordinary path.
  • eslint is clean on both changed files.
  • tsc --noEmit output is identical to the same run on main. The repository has pre-existing errors in spec and e2e files. This change adds none, and there are no errors in the files it touches.
  • End to end tests were not run. There is no live check against production in this change.

Take ownership sent a PDS password reset to the OpenMeet email address.
Nothing keeps that address in step with the email on the AT Protocol
account. Changing an OpenMeet email never writes the PDS side, so the two
can drift apart.

com.atproto.server.requestPasswordReset sends to whichever account owns
the address it is given. If the OpenMeet address had drifted and another
account owned it, the user got a working reset code for an account that
was not theirs. If no account owned it, the reset failed with an unclear
error.

The account is now resolved from the identity DID through
com.atproto.admin.getAccountInfo, and the reset is sent to the address on
that account. A missing account or a missing address now fails with a
clear error instead of reporting success, and the response reports the
address the reset actually went to.

The OpenMeet email is no longer required to start take ownership, since
it is no longer the identifier. A mismatch between the two addresses is
logged as a warning, without the addresses themselves.
@tompscanlan
tompscanlan merged commit 6d378af into main Sep 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant