In the spec, there’s nothing that inherently prevents one from changing their username, yet the very idea of it seems to be very much opposed by most of the community — or, at least, the Mastodon team. So I’m trying to understand why is that.
Here’s my understanding of the problem:
The uniqueness of an AP object, internet-wide, is determined by its id a.k.a. @id. This is supposed to remain constant throughout the object lifetime.
The rest of the fields in an object can be changed, added, or removed with an Update containing that object, as long as the id remains the same. These fields include url and preferredUsername for actors.
So, as long as the id remains unchanged, there isn’t technically anything preventing one from changing their username.
Some implementations (again, Mastodon) use the username for both the id and the url. This means that Mastodon users won’t ever be able to change their usernames.
But, this would be effortless to implement in Smithereen — I already use database row IDs to generate my id URLs. It should already work as intended if another server does it this way.
So what is it, then, that prevents us from having changeable usernames?
As you note, many implementations (including Mastodon and Pleroma) use the username as part of their IDs, which limits them in this way.
However, for a host that doesn’t do this I imagine usernames chould change. Worth testing to see how other implementations react if you do that
So far as I can tell, it should be fine to change usernames. The only thing that would break is previous mentions of a user and potentially follows…
One way around that could be to store previous usernames and set up redirects to the new ones, but you’d have to consider whether to keep those old usernames reserved forever or if you allow the next person who comes along and uses them to take over and remove the redirect. Allowing new users to take over old usernames in this way presents the problem that now anyone following the previous owner is now following this new person they don’t know, and in the case of Mastodon (and probably many other implementations), the server wouldn’t know to replace the follow with the new username!
So I can understand why it could be a problem to allow changing usernames, but it doesn’t seem like an insurmountable problem is you think it through enough!
As you said, there are essentially three things one could call a ‘username’
The activitypub ID.
The name property
The username property
Of these, only the activitypub id has to always stay the same to identify the user. Feel free to change the others any way you like. If you allow something like taking over old users names, just remember to not let them take the same AP id. Misskey uses random IDs.
The mentions problem can be solved by the receiving side storing the mentions as its internal user IDs (that don’t change) and then substituting the appropriate link at rendering time. You have to sanitize any incoming HTML anyway, so why not process it a bit more?
This is also what VKontakte does internally: mentions are stored as [id1708231|Gregory] with the numeric ID, but this becomes a link to that user’s current username upon rendering.
Yes, I mean url. My understanding is that id is internal and never ever surfaced to the users (thus it may contain any kind of sufficiently unique gibberish — database row IDs, UUIDs, random characters, whatever), and url is where there’s a user-visible web page with the profile of that actor.
In theory, nothing prevents you from changing usernames.
However, doing this is not compatible with Mastodon. Indeed, Mastodon uses the username + domain pair (the acct: URI, really) as the authoritative identifier, not the ActivityPub id. This pre-dates ActivityPub and it’s one of my main gripes with Mastodon, but unfortunately it’s unlikely to ever get better, as it is too deeply ingrained in both its UX and database design…
A Move activity, like all ActivityPub stuff, references an ActivityPub id, which I suppose here, wouldn’t change, so I’m not sure how that could help (the Move would just serialize a move from one’s identifier… to the same identifier?)
What would currently happen in Mastodon is that it’ll re-fetch the remote actor definition, find the new username, and then… create a new user with the same uri (oof)…
Changing the preferredUsername of an actor seems to work ok with Mastodon in my testing:
Maybe I’m missing something though! Looking at my video again, I notice that the record id of the Mastodon account is actually changing, suggesting the old one is being replaced, instead of being updated, as Clare alluded here perhaps
Nevertheless, it still seems to work? Content associations, follow relationships etc all seem to remain in tact. Am I missing some issue with this?
Note that this Discourse feature (i.e. allowing you to change the preferredUsername) is currently in a draft PR:
Further to the above, I’ve written an integration test for mastodon showing that a change in the remote actor username does not affect the processing of activities:
(the test passes)
I might write a few more tests demonstrating the other things in my video this coming week. If anyone sees any potential blockers in Mastodon for changing the preferredUsername of a remote actor I’m all ears.
Ok, I’ve added an integration test for the search case in my video too
What is happening (in Mastodon) is that the ActivityPub::ProcessAccountService anticipates that there may be duplicates when resolving handles from WebFinger (i.e. this scenario) and merges any accounts with duplicate uri values, i.e. duplicate ActivityPub ids. See
So, yes, a new account record is created, however the existing one is merged into the new one, along with its various relationships (i.e. what you see in the video).
This suggests to me that Mastodon can handle a remote actor changing their preferredUsername. I’m going to let this sit for a bit still before merging this functionality into Discourse’s plugin, just in case anyone thinks I’ve missed something.
I saw that Mastodon inserts a mention containing the old username when replying. Don’t know if there are other side-effects.
Also, Mastodon is only one AP implementation among hundreds. Other services may handle the change differently.
Indeed! Nevertheless, I feel like a greater understanding about what will happen in Mastodon if you change an actor’s username is relatively pertinent for this particular case.
@Claire has kindly followed up on my PR and hopefully will be reviewing the finalised version soon. I’ll update this topic if / when it’s merged.
For those who are not familiar with rspec, these are the cases tested in the integration tests (i.e. this describes what happens in Mastodon from the perspective of the remote instance)
with a POST to the inbox
when remote actor username has changed
with a follow
when the remote actor is already following the actor
posts an acceptance to the remote actors inbox
does not increase the number of follows
does not change the local record of the remote actor
does not increase the number of accounts
with an update note
updates the Note
does not change the local record of the remote actor
with an update actor
does not update the remote actors username
does not increase the number of accounts
with a create note
creates the note
does not change the local record of the remote actor
Search API
with token
GET /api/v2/search
when searching accounts
when a remote actor username has changed
does not increase the number of accounts
merges the old account with the new account
Note that when remote actor username has changed means:
There is an existing local record (in Mastodon) of the remote actor with the old username.
The remote actor’s username has been changed on its remote instance.
Just a note that in addition to the integration tests, I’ve added preferredUsername support to Update > Actor in Mastodon in this PR, which is currently under review
If accepted it will allow other services to register preferredUsername changes in Mastodon.
Mastodon uses the username@domain couple as one of the primary identifiers, and the only one for which uniqueness is enforced; Mastodon does handle this identifier changing for remote accounts whose protocol identifier stays the same, but the code path for this is inefficient and not widely tested