Repository navigation
feat(desktop): browse and moderate every community in the Admin Console - #8027
Draft
wpfleger96 wants to merge 20 commits into
Draft
wpfleger96 wants to merge 20 commits into
wpfleger96 wants to merge 20 commits into
Conversation
wpfleger96
force-pushed
the
hayt/admin-console-communities
branch
2 times, most recently
from
October 1, 2026 20:57
9ad6292 to
ebbb8db
Compare
wpfleger96
pushed a commit
that referenced
this pull request
Oct 1, 2026
Member
Author
wpfleger96
force-pushed
the
hayt/admin-console-communities
branch
from
October 2, 2026 18:39
ebbb8db to
cbba1e5
Compare
wpfleger96
force-pushed
the
duncan/admin-community-reads
branch
from
October 6, 2026 14:47
8a7f3b9 to
cf351a4
Compare
wpfleger96
force-pushed
the
hayt/admin-console-communities
branch
4 times, most recently
from
October 6, 2026 17:20
d92937d to
315af0f
Compare
The community page needs staff reads whose failures stay distinguishable (unsupported route vs absent target vs unknown), and lifts that target the page community and cannot be signed by a different identity on retry. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Each console tab picked its community differently and never said which, so a ban could land in the wrong community. Actions and Restrictions now live on a community page that names its host everywhere; the direct-action controller stays mounted across navigation, so a pending intent and its requestId are only dropped by an explicit Discard, and community reads are fenced by origin, signer, community, target and generation. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The bodyless GET /events/{id} preview carries no key material, so it is listed rather than guarded.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
A Load more answer for search A could land after the user moved to B and overwrite B's pages, cursor and busy state. Each search transition now gets its own identity, and late answers from an earlier one are discarded before any state is set. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…hosen Confirm rebuilt the relay and signer from the list state at that moment, so a lift confirmed during a reload went out with empty expectations and was refused. The intent is now captured from the row's loaded list and sent unchanged. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The Actions section can change community while staying mounted. These tests pin that a late member lookup, event preview or member search from the old community never shows in, or unlocks Review in, the new one. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Group headings alone left a row ambiguous once scrolled past, and the resolve confirm named only the host string. Each row now carries its own community badge, and confirm shows the badge plus the not-connected warning. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The report-kick roster check re-derived the host in TypeScript from the relay URL. It now asks the native side for the connected host, matching the relay-normalized report host, and a failed lookup records nothing instead of throwing after the relay has already resolved the report. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The b3 cursor fell through to page-one rows, so the final Load more rendered a duplicate community and React warned about duplicate keys. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Rows repeated the group heading's badge, and a community page repeated its banner on top of both. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…arch The relay matches a trimmed, case-insensitive host prefix; the pin now follows the same rule instead of showing under unrelated searches. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Member and message previews showed raw ISO timestamps. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Lets the multi-community admin console be tested against plain just dev: communities past one directory page, named members, a ban and timeout per community, grouped reports and feedback, and pre-signed messages for the delete preview. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Rerunning just admin-seed forced fixture reports back to open while an enforcement action could still be attached, stranding Cancel & reopen and letting a pending action re-apply after the reset. The seed now locks admin actions, refuses before any write while a fixture report or action is unfinished, and runs in one transaction. It also resets every fixture restriction, feedback status and message-author channel membership, and links event reports to their channel so Kick works. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
A report claim locks its report row before inserting an action, the reverse of the seed's order, so a claim racing a reseed could deadlock. The seed now takes the fixture report rows with FOR UPDATE NOWAIT right after the action-table lock and refuses with a clear message if one is held. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The ID-prefix match also caught unseeded reports that reuse a fixture-looking ID, which could make the seed refuse over an unrelated row. Select by the upserts' (community, report_event_id) keys instead. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The relay now serves every moderation read in disabled mode, including the community reads, while still refusing writes. The console hid Communities there; it now shows them, with every ban, timeout, delete, add and lift control disabled. Restriction lifts were the one control not gated on canMutate. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The community page renders its section nav only after async reads settle, so the fixed 20ms delay raced on slow CI runners. The review-race test also left a relay read pending forever when mounting outlasted its release, which stalled every later test in the file. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The Staffing tab renders only for an Operator role, and only an authorized probe reports a role, so canMutate is always true there. Community navigation is always provided by the panel, so open is never null. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
The relay returns isStaff: null in disabled auth mode, where it does not read the staff roster. Both readers already treat null as not staff. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96
force-pushed
the
hayt/admin-console-communities
branch
from
October 6, 2026 19:38
315af0f to
6ab34f2
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.





















Stack: #8011 → this PR. This PR targets
main, so until #8011 merges its diff also shows #8011'scrates/commits. Onlydesktop/belongs to this PR.The Admin Console only ever saw the community the desktop happened to be connected to. With #8011's community reads, the console can now browse every community on the relay and, for signed staff, moderate any of them by name without switching connections. 🤖
What changes
admin_list_communities,admin_search_members,admin_get_member,admin_get_event). Every request validates the explicit community host and NIP-98-signs the real method and URL. Failures come back as a structured error (status,bodyComplete,bodyEmpty,code), so the UI can tell an older relay's empty 404, a codedevent_not_foundand a transport failure apart, and never says "not found" unless the relay did.admin_lift_restrictionsends the page's community host, not the active relay's. It freezes the relay and signer the intent was reviewed under, and refuses to send if either has changed.DirectActionsProviderholds the frozen intent, so switching communities or tabs mid-confirm doesn't lose it. Only Discard drops it. A signer change remounts the controller and drops it.MemberSearchResult, also used by Add Member), showing the truncated npub so members with the same name can be told apart. Delete accepts a note link and previews the message before Review. Relay staff are blocked before Review.BUZZ_ADMIN_AUTH=disabledthe Communities tab and community pages still render, and report badges still open them, but every ban, timeout, delete, add-member and lift control is disabled. The settings badge says the console is read-only and that acting needsnip98. Staffing stays hidden.requestId, Retry,notSentand the key-backup guard.just admin-seedfor multi-community testing. Besides the local community, it seedsbeta.localhost:3000,gamma.localhost:3000and 50 filler communities, with named members, a ban and a timeout in each named community, a report with Kick available, and a message for the delete preview. Rerunning it restores all of that to the starting state. It refuses, writing nothing, while a moderation action is unfinished on a seeded report.GET /events/{id}preview is added to the events-URL egress inventory. It sends no body, so it carries no key material.Tests
Native (Rust):
empty_404_and_405_read_as_complete_and_empty,coded_404_carries_the_relay_code,truncated_and_over_cap_bodies_are_incomplete,transport_failure_has_no_status: the structured read error tells an older relay, a coded refusal, a cut-off body and a transport failure apart.a_401_retry_is_signed_by_the_same_keys,lift_signs_the_send_and_401_retry_with_the_checked_keys: the 401 retry never switches keys.read_urls_validate_the_explicit_host_and_encode_the_query,lift_url_sends_the_page_host_not_the_active_relay,list_url_carries_host_and_cursor_and_refuses_a_changed_relay,lift_refuses_before_sending_on_signer_change_or_bad_host: requests target the explicit host and refuse to send after a relay or signer change.jsdom:
actions-pending-nav: a pending intent survives a community change, and only Discard drops it.actions-fenced-lookup,fenced-load: a late lookup for an old key never shows under, or unlocks, the new one.actions-same-ids: the same pubkey and event id are read separately in each community.actions-community-change-drops-member,actions-page-host,actions-success,actions-identity: the form acts only in the page's community, and confirm sends the frozen intent.actions-preview-errors,actions-delete-link,actions-staff-target,actions-disabled-auth: preview errors, delete by note link, the staff block, and community pages rendering read-only with every action control disabled under disabled admin auth.communities-directory,communities-unsupported,community-badge,community-badge-disabled-auth: the directory, older relays, and report badges, which open community pages under disabled admin auth too.restrictions-lift-signer-change. The existing restriction tests now run on the community page and useadmin_lift_restriction.Mutation checks: removing the pending-navigation guard turns
actions-pending-navred, and dropping the host from the fence key turnsactions-fenced-lookup,actions-same-idsandfenced-loadred. Ungating restriction lifts oncanMutateturnsactions-disabled-authred.