Mastodon-style account migration import#319
Conversation
Expose actor aliases through ActivityPub and GraphQL, and add typed mutations for local accounts to add or remove previous actor IRIs used by Mastodon-style account migration. Reuse the normal actor Update fan-out so followers can observe alias changes. Assisted-by: Codex:gpt-5.5
Add account settings controls for preparing an inbound account migration, including Relay mutations, localized guidance, and the account query data needed to render previous accounts. The guidance explains that Hackers' Pub only prepares the new account; the actual move still starts from the old server. Assisted-by: Codex:gpt-5.5
Update account migration alias mutations with SQL expressions that modify the current actor alias array at update time. This prevents overlapping add and remove requests from resurrecting or dropping aliases based on stale GraphQL snapshots. Add a regression test that removes an alias while a remote actor lookup is still in progress. Assisted-by: Codex:gpt-5.5
|
@codex review |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds ActivityPub account migration alias management. A new ChangesAccount Migration Aliases
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request implements ActivityPub account migration aliases (alsoKnownAs) to support Mastodon-style account moves, adding GraphQL mutations to add and remove aliases, updating federation and database models, and introducing a settings UI with localized strings. The review feedback highlights several critical improvement opportunities, including adding defensive nullish coalescing checks to prevent runtime crashes when aliases is null or undefined, normalizing hostnames to lowercase in Fediverse handles to avoid cache misses, and changing the mobile input field's inputmode to "email" to improve the user experience when typing handles.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull request overview
This pull request adds end-to-end support for Mastodon-style account migration imports by letting users attach “previous account” actor IRIs to their local actor’s alsoKnownAs list, exposing those aliases via GraphQL, updating the ActivityPub actor document, and providing a settings UI to manage aliases.
Changes:
- Add
Actor.aliasesto the GraphQL API plusaddAccountMigrationAlias/removeAccountMigrationAliasmutations, with concurrency-safe DB updates and regression tests. - Publish stored aliases in the ActivityPub
Personactor document and reuse a sharedsendAccountActorUpdatehelper to notify followers. - Add an account settings UI for managing migration aliases, including localized copy for all supported
web-nextlocales.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| web-next/src/routes/(root)/[handle]/settings/account.tsx | Adds “Account migration” settings card with UI to add/remove previous-account aliases via Relay mutations. |
| web-next/src/locales/en-US/messages.po | Adds localized strings for the new migration UI and updates source references. |
| web-next/src/locales/ja-JP/messages.po | Adds localized strings for the new migration UI and updates source references. |
| web-next/src/locales/ko-KR/messages.po | Adds localized strings for the new migration UI and updates source references. |
| web-next/src/locales/zh-CN/messages.po | Adds localized strings for the new migration UI and updates source references. |
| web-next/src/locales/zh-TW/messages.po | Adds localized strings for the new migration UI and updates source references. |
| models/account.ts | Extracts and exports sendAccountActorUpdate and reuses it from updateAccount. |
| graphql/actor.ts | Exposes Actor.aliases as [URL!]! backed by the actorTable.aliases column. |
| graphql/account.ts | Implements alias resolution + add/remove mutations, including federation lookup and follower update delivery. |
| graphql/schema.graphql | Updates generated schema with Actor.aliases and the new migration alias mutations/types. |
| graphql/account.test.ts | Adds coverage for alias querying, add/remove behavior, error typing, and update delivery behavior. |
| federation/person.ts | Includes stored aliases in the local ActivityPub actor document. |
| federation/actor.test.ts | Adds ActivityPub actor document test coverage for aliases exposure. |
| deno.lock | Updates npm dependency resolution entries (likely from tooling/codegen). |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@graphql/account.test.ts`:
- Around line 1463-1465: The inline type assertion in the toPlainJson call
contains duplicate property key declarations within the type literal, which
causes TypeScript compilation errors. Locate the type assertion in the
toPlainJson call around the addAccountMigrationAlias property and remove any
duplicate key declarations from the type literal object. Ensure each property
key appears only once in the type literal. Apply the same fix to all other
instances mentioned around line 1483-1485 where similar duplicate property
signatures exist in inline type assertions.
In `@web-next/src/routes/`(root)/[handle]/settings/account.tsx:
- Around line 178-181: The Title component only updates page metadata and does
not render a visible heading in the DOM, which removes the page-level h1 heading
needed for accessibility and semantic HTML structure. Add a visible or
screen-reader-only h1 heading element before the SettingsTabs component in the
JSX. This h1 should display the account settings title and maintain proper
heading hierarchy, either as a visible heading or using a screen-reader-only
utility class if you want to hide it visually while keeping it available to
assistive technologies.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8a462a80-4b31-4a03-980f-668351c435ab
⛔ Files ignored due to path filters (1)
deno.lockis excluded by!**/*.lock
📒 Files selected for processing (13)
federation/actor.test.tsfederation/person.tsgraphql/account.test.tsgraphql/account.tsgraphql/actor.tsgraphql/schema.graphqlmodels/account.tsweb-next/src/locales/en-US/messages.poweb-next/src/locales/ja-JP/messages.poweb-next/src/locales/ko-KR/messages.poweb-next/src/locales/zh-CN/messages.poweb-next/src/locales/zh-TW/messages.poweb-next/src/routes/(root)/[handle]/settings/account.tsx
Lowercase the host part of account migration handles before looking up cached actors or doing federation lookup. This keeps mixed-case domains from missing an actor row that is already stored under the canonical lowercase host. hackers-pub#319 (comment) Assisted-by: Codex:gpt-5.5
Add a screen-reader-only page heading to restore the account settings heading hierarchy, and use the email keyboard hint for the old-account field so mobile users can type fediverse handles more easily. hackers-pub#319 (comment) hackers-pub#319 (comment) Assisted-by: Codex:gpt-5.5
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements support for ActivityPub account migration aliases (alsoKnownAs), allowing users to prepare their local accounts as destinations for Mastodon-style moves. It introduces new GraphQL mutations (addAccountMigrationAlias and removeAccountMigrationAlias), updates the database models and federation logic to propagate these changes, and adds a dedicated settings UI in the SolidStart stack. Feedback on the changes highlights critical runtime issues: Drizzle ORM's Relational Query API is incorrectly queried using Prisma-like nested objects instead of callback functions in several files, and potential TypeError crashes exist in graphql/actor.ts and federation/person.ts if the aliases field is null or undefined in the database.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
What changed
This PR adds the Hackers' Pub side of importing an account from another fediverse server, following the Mastodon account migration flow.
Users can now add a previous account from the account settings page by entering a handle or actor/profile URL. Hackers' Pub resolves that value to the previous actor IRI, stores it on the local actor's
aliases, and publishes it asalsoKnownAsin the ActivityPub actor document.The GraphQL API now exposes
Actor.aliasesand provides add/remove mutations for migration aliases in graphql/account.ts. Alias edits update the current database row instead of rewriting a stale in-memory array, so overlapping add and remove requests do not resurrect or drop aliases.The ActivityPub actor document in federation/person.ts now includes the stored aliases. Account actor update delivery is shared through models/account.ts, so migration alias changes notify followers in the same shape as other account updates.
The new account settings UI in web-next/src/routes/(root)/[handle]/settings/account.tsx explains the flow in plain steps: add the old account in Hackers' Pub, configure the move on the old server, and let the old server send the
Moveactivity. The new UI copy is included in all supported web-next locale catalogs.How I tested
pnpm extractmise run build:web-nextdeno task check && deno task test