Repository navigation
fix: preserve browser during permission refresh - #272
Merged
Merged
Conversation
Use the first completed policy load to gate dashboard content so a forced Browser refresh cannot unmount its own page and start another refresh. Keep navigation stable while retaining authorization checks when the refreshed policy arrives. Add component regressions for refresh stability, permission failures and revocation, identity changes, navigation, and administrator readiness.
Closed
1 task done
1 task done
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.
Pull Request
Description
Non-admin users entering Browser repeatedly lost the page because its forced bucket refresh also refreshed permissions, and the dashboard guard unmounted its children whenever permissions were loading. Completing that refresh mounted Browser again and restarted the cycle.
Gate the dashboard, sidebar, and first accessible route on completion of the initial policy load. Background refreshes retain the mounted page and navigation; a returned policy still re-evaluates route access. Keep the forced bucket/usage refresh and the provider's loading state for local indicators.
Type of Change
Testing
All local quality gates passed with Node 22:
pnpm install --frozen-lockfile pnpm type-check pnpm lint pnpm format:check pnpm test:run # 776 passedAdded 13 deterministic component tests using the real PermissionsProvider, DashboardAuthGuard, Browser page, and first-route hook with mocked I/O/presentation boundaries. They cover successful/denied policy-status probes, initial authorization, refresh revocation/failure, credential and API-client changes, logout/stale responses, administrators, readiness, manual refresh, and navigation. The regression tests failed against the original guard before the fix.
Automated Chromium checks against the local Next.js application with intercepted API/S3 responses confirmed:
Checklist
Related Issues
Closes #271
Screenshots (if applicable)
Actual local Console runtime with mocked non-admin API/S3 responses, not a live RustFS deployment. Each before/after pair captures the same pending background permission refresh: desktop 1440 × 900, mobile 390 × 844. Before, the refresh removes the application shell; after, the page and navigation remain mounted while usage refreshes.
Additional loaded, empty, error, and mobile states
Additional Notes
Independent Reviewer/Simplifier and UX audits found no blocking issues. The provider's identity epoch/reset logic and API-layer 401/403 logout handling are unchanged; ordinary policy-refresh failures still clear the policy and deny the protected route. Backend IAM remains authoritative while a background refresh retains the previous UI permission snapshot.
Screenshot assets are on the separate
cxymds/evidence/issue-271-permission-refreshbranch. The application diff contains only three permission-readiness changes and their regression tests. No live RustFS or OIDC end-to-end test was performed.