Skip to content

Fix #426–#437: ui catalog, homeUrl, CSP providers, UserContext.permissions, scaffold and settings fixes - #438

Merged
antosubash merged 21 commits into
mainfrom
feat/issue-batch-426-437
Oct 11, 2026
Merged

antosubash merged 21 commits into
mainfrom
feat/issue-batch-426-437

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Fixes the twelve issues reported while building Kuri on simple_module 0.0.35. Design: docs/superpowers/specs/2026-10-11-issue-batch-426-437-design.md, plan: docs/superpowers/plans/2026-10-11-issue-batch-426-437.md.

Changes

# Fix
#426 The ui catalog moves from packages/ui/locales into simple_module_hosting/ui_locales/ and is always registered, so scaffolded apps stop rendering raw ui.* keys. Doctor's locale checks read the new location.
#427 New homeUrl shared prop. Users publishes its landing URL; the host falls back to Dashboard, then / (covers Keycloak installs). useHomeUrl() accepts same-origin paths only. Used by AdminLayout, SidebarLayout, PublicLayout, Error, Landing, AcceptInvite, ResetPassword.
#428 Default footer is © {year} {appName}; BRAND_LICENSE removed.
#429 Scaffolded app.tsx calls initTheme() and wires title via formatTitle/setTitleAppName.
#430 Settings picker hides zero-field modules (unless they have manage_url) and opens on the first one shown.
#431 Generated module test uses effective_route_paths.
#432 s3_signature_version setting (default s3v4, validated to s3v4/s3) passed as botocore Config.
#433 import-from-env layers .env under os.environ (real env wins), with a naming hint when nothing matched.
#434 CspSourceRegistry.add_provider(fn): settings-driven origins evaluated per response, cached by value, failing closed to the static policy. Sources must be printable ASCII (punycode for IDNs), so an admin-edited value can never break header encoding. Apps without providers keep the precomputed header.
#435 view_prefix="" is both "no views" and "mounted at /", so the host now records modules whose view router actually got routes (sm.view_prefixes); the login fallback and dashboard links use it.
#436 UserContext.permissions, round-tripped through the session (old cookies decode to []) and merged by both resolvers; * is always dropped.
#437 Sign-in error rendered with role="alert".

Also: a RUF071 suppression with a reason in _route_guard.py (the new ruff flags an intended character-wise prefix; main fails make lint without it), and the import-from-env tests are isolated from a developer's .env.

Verification

  • make lint ✓ · make test ✓ (3952 Python, 536 JS) · make doctor 0 errors · npm run build ✓
  • Full e2e suite against a live server: 49 passed, including the new tests/e2e/test_shell_home_and_signin.py
  • Browser QA: 13/13 checks passed, 0 bugs. Report: https://claude.ai/artifact/PJ18jzzxsjEwXijLetwEnq
  • Code review: 4 passes until clean; a background security review finding on CSP source encoding was fixed

Out of scope: #317 (needs the external design deck).

Closes #426, closes #427, closes #428, closes #429, closes #430, closes #431, closes #432, closes #433, closes #434, closes #435, closes #436, closes #437

https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4

The ui namespace was registered only when <project_root>/packages/ui/locales
existed, which is true only inside the framework monorepo, so every scaffolded
app rendered raw ui.* keys. The catalog now lives in the hosting package and is
registered unconditionally.

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
register_csp_sources runs before DB settings hydrate and the policy was frozen
at boot. registry.add_provider(fn) lets a module return (directive, source)
pairs from in-memory state on each response; finished policies are cached by
the pairs returned, invalid pairs and raising providers fail closed to the
static policy, and an app with no providers keeps the precomputed header.

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
…#436)

A principal can carry permissions directly (an API token scoped to one
permission) instead of encoding them as roles. Round-tripped through the
session (old cookies decode to []), merged by both the async and the sync
resolver, and the wildcard is always dropped so a token or IdP claim can never
grant everything.

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
…e on a provider build

A provider reading an admin-edited setting could return a source the regex
accepted but the header encoder cannot carry (non-ASCII, control bytes), which
would 500 every response, including the settings page needed to fix it.

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
view_prefix="" is both the default (no views) and "mounted at /", so the
truthiness check skipped root-mounted modules and is-not-None would have matched
every API-only one. wire_module_routes now records each module whose view
router actually received routes (app.state.sm.view_prefixes), and the login
fallback and dashboard stats read that map, turning "" into /.

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
- doctor's locale checks read the ui catalog from its new home (#426)
- host supplies a homeUrl default (Dashboard, else /) for installs without the
  users module, so Keycloak installs keep their home link (#427)
- document that CSP sources are ASCII (punycode for IDNs) (#434)

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
- error, landing, accept-invite and reset-password pages follow homeUrl too (#427)
- reject an unknown s3_signature_version at config time (#432)

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
- useHomeUrl accepts same-origin paths only, else / (#427)
- default footer caption has no trailing space for a blank app name (#428)

Claude-Session: https://claude.ai/code/session_01NJyEUshNM4K1e66dRgbyj4
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 568d214
Status: ✅  Deploy successful!
Preview URL: https://3e89e4de.simple-module-python.pages.dev
Branch Preview URL: https://feat-issue-batch-426-437.simple-module-python.pages.dev

View logs

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 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
🔒 Security Review ✅ Completed 2026-10-11T17:38:57.306226Z 568d214 PR opened
ℹ️ 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.

@antosubash
antosubash merged commit 8f48ef4 into main Oct 11, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment