Skip to content

fix(admin): hide administration without cached permission evidence - #487

Merged
veryCrunchy merged 6 commits into
mainfrom
fix/cached-admin-permissions
Sep 28, 2026
Merged

veryCrunchy merged 6 commits into
mainfrom
fix/cached-admin-permissions

Conversation

@veryCrunchy

@veryCrunchy veryCrunchy commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Outcome

Regular users no longer see Settings > Administration, Server apps, or its installed-workspace summary. Restored admin routes and action callbacks never expose the catalog or mutation controls without current permission evidence. The ordinary Apps workspace remains available.

Automatic checks run only while the root Settings screen or Server apps is visible and its platform window is visible. Android stop and desktop hide/minimize cancel polling, including an in-flight check. The requested Settings section survives permission revalidation and restoration while admin controls remain hidden. Failed revalidation keeps admin controls hidden and shows a typed recovery state with retry and Back.

A session-scoped repository caches allowed and denied catalog results for five minutes, reuses the verified catalog when opening Server apps, and retires its state on account changes. Revalidation bypasses persisted transport responses. Missing or malformed OCS success metadata cannot grant access.

Advances #187.

Verification

  • Relevant completed checks and remaining limitations are listed below
  • bash tools/check-repository.sh passes in full
  • Added a user-facing changelog fragment
  • No credentials, private server data, machine-local paths, or generated output are included

Passed with JDK 21 on Windows:

  • 47 deterministic focused desktop tests covering administration access, catalog contracts, settings visibility, restored selection, Compose account switching, and transport cache policy.
  • :ui:compileKotlinDesktop, :ui:compileDebugKotlinAndroid, and :androidApp:compileDebugKotlin.
  • :ui:createDistributable and :androidApp:assembleDebug.
  • bash tools/check-kotlin-architecture.sh and git diff --check.
  • Changelog, Markdown links, text hygiene, and the other completed repository checks.

The full repository check could not finish locally: its Linux package metadata test requires dpkg-deb, and the available WSL environment could not start. Release-promotion and desktop-manifest checks were verified separately after adapting the local Windows jq invocation.

Compatibility and risk

Uses the existing app-store OCS catalog and provisioning inventory fallback. Tests use synthetic responses; no live Nextcloud server or installed-app version was validated. The cache is in memory and is cleared on session replacement or process restart. A permission change may take up to the five-minute validity window to affect visibility. Mutations still require the existing authenticated browser handoff and server authorization.

Visual changes

Administration is omitted on compact and desktop Settings layouts without permission. Visibility and restoration policies are covered by deterministic tests. Rendered Compose tests exercise denied, unavailable, and malformed-response recovery at 390x844 and 1280x800, including retry and Back. Android emulator visual and lifecycle validation has not been performed. Platform visibility cancellation and Settings selection restoration are covered by deterministic Compose tests.

@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #487 / NC Native September 27, 2026 22:22 Destroyed
@obiente-cloud

obiente-cloud Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Obiente preview

NC Native · a168863403d9 · Removed

View preview status

View in Obiente

Obiente updates this comment as the preview changes.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T23:53:24.623683Z 471cfd7 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #487 / NC Native September 27, 2026 22:28 Destroyed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4eb5190863

ℹ️ 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".

) { mutableStateOf(NextcloudDestination.Home) }
val administration = rememberAdministrationAccess(
session, platformCapabilityRefreshRequest,
active = destination == NextcloudDestination.Settings || screen == Screen.AdminApps,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop permission polling after leaving Settings

Restrict the Settings case to screen == Screen.Root && destination == NextcloudDestination.Settings. Opening Offline Center, Transfers, Project News, or an installed app from Server apps changes screen but leaves destination set to Settings, so this expression keeps the five-minute ForceNetwork catalog loop active across unrelated screens. Long browsing or transfer sessions will therefore repeatedly download the administrator catalog despite neither Settings nor Server apps being visible, wasting bandwidth and battery.

AGENTS.md reference: AGENTS.md:L256-L258

Useful? React with 👍 / 👎.

if (access.state.checking) {
LoadingMessage("Checking administrator access...")
} else {
LaunchedEffect(access.state) { onBack() }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Surface revalidation failures before navigating back

When an already-open Server apps screen reaches the five-minute expiry, the repository clears the old result while checking and then publishes Forbidden, Unavailable, or InvalidResponse if revalidation fails. This effect immediately calls onBack() for every non-checking, non-admin result, so the result-specific error and retry branches below can never render; permission loss, an offline failure, or a malformed response silently ejects the user to Settings without explaining what happened or what is safe to do next. Keep the catalog fail-closed, but make the typed failure state visible before requiring navigation away.

AGENTS.md reference: AGENTS.md:L447-L449

Useful? React with 👍 / 👎.

@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #487 / NC Native September 27, 2026 23:05 Destroyed
@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #487 / NC Native September 27, 2026 23:11 Destroyed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9b3816d40

ℹ️ 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".

Comment on lines +41 to +44
while (active && isActive) {
repository.refresh { request -> currentExecute(request) }
val age = repository.state.value.checkedAt?.elapsedNow() ?: AdministrationAccessTtl
delay((AdministrationAccessTtl - age).coerceAtLeast(kotlin.time.Duration.ZERO))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pause administration polling while the app is backgrounded

On Android when the activity is stopped, and on desktop when the window is minimized or hidden, the composition and its coroutine can remain active; because active reflects only the current route, leaving the app on Settings or Server apps continues fetching the administrator catalog every five minutes in the background. Include application/window visibility in the polling condition, or move lifecycle-aware scheduling outside this composable, so a screen that is no longer actually visible does not consume network and battery.

AGENTS.md reference: AGENTS.md:L256-L258

Useful? React with 👍 / 👎.

isDesktop = isDesktop,
hasDeviceSettings = platformCapabilities.isNotEmpty(),
hasDesktopAppSettings = hasDesktopAppSettings,
canAdminister = canAdminister,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the selected admin section across permission refreshes

On a two-pane Settings layout, every five-minute revalidation temporarily makes canAdminister false because the repository clears its prior result while checking. Filtering Administration here then resolves the saved selection to Account, and the existing LaunchedEffect at lines 268-271 writes that fallback into selectedSectionName; after a successful check, the administrator is therefore left on Account instead of returning to the section they were using. The same overwrite loses a restored Administration selection during the initial post-recreation check, so retain the requested selection while permission is merely unknown/checking.

AGENTS.md reference: AGENTS.md:L457-L459

Useful? React with 👍 / 👎.

@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #487 / NC Native September 27, 2026 23:49 Destroyed
@obiente-cloud
obiente-cloud Bot temporarily deployed to Obiente Preview / PR #487 / NC Native September 27, 2026 23:53 Destroyed
@veryCrunchy
veryCrunchy merged commit aecdffd into main Sep 28, 2026
6 checks passed

This branch was successfully deployed

No deployments
Obiente Preview / PR #487 / NC Native — a1688634 Deployed Sep 27, 2026 by obiente-cloud[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant