Account migration import for organization accounts#321
Conversation
Account migration (advertising `alsoKnownAs` aliases so an account can be the destination of a Mastodon-style Move) was authorized only for the signed-in account itself. Since organizations cannot sign in, their accepted admins could never manage the organization's migration aliases. Make `getAuthorizedMigrationAccount` reuse `viewerCanManageAccountSettings`, which already authorizes the personal account holder and accepted admins of an organization account, matching how `updateAccount` and `deleteAccount` are gated. A nonexistent account now returns `NotAuthorizedError` (rather than leaking existence via `InvalidInputError`), consistent with the mutation input descriptions. Assisted-by: Claude Code:claude-opus-4-8 Assisted-by: Codex:gpt-5.5
The account settings page rendered the "Account migration" card only in the personal-account branch. Add the same card to the organization branch so an organization's accepted admins can prepare it as a Move destination. It reuses the existing AccountMigrationAliasesForm and the aliases already selected by the page query, so no new query or strings are needed. Assisted-by: Claude Code:claude-opus-4-8
|
Warning Review limit reached
More reviews will be available in 11 minutes and 2 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughMigration alias mutations now allow viewers who manage an organization account to add or remove aliases, return ChangesAccount migration aliases
Sequence Diagram(s)sequenceDiagram
participant AccountMigrationAliasesForm
participant addAccountMigrationAliasMutation
participant removeAccountMigrationAliasMutation
participant getAuthorizedMigrationAccount
participant viewerCanManageAccountSettings
AccountMigrationAliasesForm->>addAccountMigrationAliasMutation: submit accountId and alias
addAccountMigrationAliasMutation->>getAuthorizedMigrationAccount: load account and actor by id
getAuthorizedMigrationAccount->>viewerCanManageAccountSettings: check manage access
viewerCanManageAccountSettings-->>getAuthorizedMigrationAccount: allowed or denied
getAuthorizedMigrationAccount-->>addAccountMigrationAliasMutation: account or NotAuthorizedError
AccountMigrationAliasesForm->>removeAccountMigrationAliasMutation: remove alias
removeAccountMigrationAliasMutation->>getAuthorizedMigrationAccount: load account and actor by id
getAuthorizedMigrationAccount->>viewerCanManageAccountSettings: check manage access
viewerCanManageAccountSettings-->>getAuthorizedMigrationAccount: allowed or denied
getAuthorizedMigrationAccount-->>removeAccountMigrationAliasMutation: account or NotAuthorizedError
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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 enables organization admins to manage account migration aliases for organization accounts. It updates the authorization logic in getAuthorizedMigrationAccount to allow personal holders or organization admins to manage migration settings, while preventing information leakage for nonexistent account IDs by returning a NotAuthorizedError. Additionally, it adds the "Account migration" settings card to the organization settings page and updates the GraphQL schema descriptions and tests accordingly. Feedback suggests refactoring the settings page to avoid duplicating the "Account migration" card between the personal and organization views.
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.
Actionable comments posted: 1
🤖 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 `@web-next/src/routes/`(root)/[handle]/settings/account.tsx:
- Around line 590-592: The reused authorization copy in
AccountMigrationAliasesForm is still hardcoded for personal accounts, so update
the NotAuthorizedError toast text used by the add/remove alias paths to say
“accounts you can manage” instead of “only for your own account.” Make the
change in the AccountMigrationAliasesForm flow so the organization entry point
uses the corrected wording consistently wherever the authorization failure
message is shown.
🪄 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: 55a84081-e1d1-46f1-b665-95fc7a9957a8
📒 Files selected for processing (4)
graphql/account.test.tsgraphql/account.tsgraphql/schema.graphqlweb-next/src/routes/(root)/[handle]/settings/account.tsx
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6bddecced0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
The accountId input descriptions already note that organization admins may manage migration aliases, but the mutation-level descriptions for addAccountMigrationAlias and removeAccountMigrationAlias still said the alias belonged to the authenticated viewer's own local account. That left the generated schema docs implying organization-admin calls are unsupported even though the resolvers now allow them. Reword both descriptions to cover any account the viewer can manage and regenerate graphql/schema.graphql. hackers-pub#321 (comment) Assisted-by: Claude Code:claude-opus-4-8
Adding the migration card to the organization branch of the account settings Switch left it duplicated verbatim with the personal branch. Extract it into a shared AccountMigrationCard component used by both branches. Keeping it as a component (rather than splitting the Switch into two around a shared card) preserves the personal branch's existing viewer gating without rendering the card outside that boundary. hackers-pub#321 (comment) Assisted-by: Claude Code:claude-opus-4-8
The account migration form is now shared by organization accounts, but its NotAuthorizedError toast still read "only for your own account" in both the add and remove paths. That is misleading for organization admins, who can manage migration for accounts they do not own. Reword it to "accounts you can manage" and update the locale catalogs. hackers-pub#321 (comment) Assisted-by: Claude Code:claude-opus-4-8
|
@codex review |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request extends the account migration alias feature to allow organization administrators to manage migration aliases for organization accounts. It updates the GraphQL mutations addAccountMigrationAlias and removeAccountMigrationAlias to authorize organization admins, adds corresponding integration tests, and updates the frontend settings page to display the migration card for both personal and organization accounts. The feedback suggests aligning the newly introduced AccountMigrationCard component with the repository's style guide by defining an interface for its props and using props destructuring.
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.
🧹 Nitpick comments (1)
web-next/src/routes/(root)/[handle]/settings/account.tsx (1)
1598-1616: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse an interface for the new card props.
AccountMigrationCardis a new component in this diff, and the repo TS guideline asks for component props to use interfaces instead of an inline object type.Suggested change
+interface AccountMigrationCardProps { + account: AccountPageAccount; +} + -function AccountMigrationCard(props: { account: AccountPageAccount }) { +function AccountMigrationCard(props: AccountMigrationCardProps) {As per coding guidelines, "Use interfaces for component props (e.g., ButtonProps)."
🤖 Prompt for 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. In `@web-next/src/routes/`(root)/[handle]/settings/account.tsx around lines 1598 - 1616, AccountMigrationCard currently defines its props with an inline object type, which violates the component props guideline. Introduce a named interface for the props used by AccountMigrationCard (referencing AccountPageAccount for the account field), update the function signature to use that interface, and keep the component behavior unchanged.Source: Coding guidelines
🤖 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.
Nitpick comments:
In `@web-next/src/routes/`(root)/[handle]/settings/account.tsx:
- Around line 1598-1616: AccountMigrationCard currently defines its props with
an inline object type, which violates the component props guideline. Introduce a
named interface for the props used by AccountMigrationCard (referencing
AccountPageAccount for the account field), update the function signature to use
that interface, and keep the component behavior unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 48cda296-1fe2-4e62-bb40-fa7bdd724356
📒 Files selected for processing (8)
graphql/account.tsgraphql/schema.graphqlweb-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
✅ Files skipped from review due to trivial changes (3)
- web-next/src/locales/ja-JP/messages.po
- web-next/src/locales/ko-KR/messages.po
- graphql/schema.graphql
🚧 Files skipped from review as they are similar to previous changes (1)
- graphql/account.ts
|
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". |
Give AccountMigrationCard a named AccountMigrationCardProps interface instead of an inline object type, matching the style guide and the other prop interfaces in this file (AccountMigrationAliasesFormProps, AccountDeletionFormProps). Props are still accessed via props.account rather than destructured, since destructuring breaks reactivity in Solid. hackers-pub#321 (comment) Assisted-by: Claude Code:claude-opus-4-8
|
@codex review |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request extends the account migration alias feature to support organization accounts, allowing organization administrators to manage migration aliases. It updates the backend authorization logic to check if the viewer can manage the account, prevents leaking account existence by returning NotAuthorizedError for nonexistent accounts, and updates the GraphQL schema and translations accordingly. On the frontend, the migration settings are extracted into a reusable AccountMigrationCard component. The reviewer noted that this new component should use props destructuring instead of accessing properties directly from the props object, as specified in the repository style guide.
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.
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. 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". |
Why
Organization accounts are first-class ActivityPub actors (
Organization) with their own followers, but the Mastodon-style account migration import added in #319 was offered to personal accounts only. An organization moving from another fediverse server should be able to point its old account at Hackers' Pub just like a person can, so this lifts that restriction.The migration machinery was already kind-agnostic: the model functions edit the actor row by account, federation/person.ts already advertises
alsoKnownAsforOrganizationactors, and the inboxMovehandler validates aliases the same way for any actor. Only two places assumed the account could sign in:Server authorization in graphql/account.ts required the alias to belong to the signed-in account itself. Organizations never sign in, so their admins could never reach it. It now reuses the existing
viewerCanManageAccountSettingshelper, which already authorizes the personal holder and an organization's accepted admins. Routing migration through the same helper keeps it consistent with profile updates and account deletion (admins only) instead of introducing a separate permission rule.The settings UI in web-next/src/routes/(root)/[handle]/settings/account.tsx rendered the migration card only for personal accounts; it now appears for organizations too, reusing the same form.
While reordering the authorization check, I also made a well-formed but nonexistent account id return the same
NotAuthorizedErroras an unauthorized one, so the error no longer reveals whether an account exists.How I tested
NotAuthorizedError, and a nonexistent id is rejected without leaking existence.deno task check(type check, lint, and Relay codegen across web-next)AI assistance
Implemented with Claude Code (claude-opus-4-8) and reviewed with Codex (gpt-5.5); see the
Assisted-bytrailers on the commits.