Repository navigation
refactor(ui): the pages' browser code is Rust on Topcoat's runtime, not script files - #387
Draft
PiquelChips wants to merge 14 commits into
Draft
PiquelChips wants to merge 14 commits into
PiquelChips wants to merge 14 commits into
Conversation
|
Important Review skippedToo many files! This PR contains 114 files, which is 14 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.
|
PiquelChips
force-pushed
the
refactor/rust-frontend-scripts
branch
from
November 6, 2026 12:53
773d7ba to
c9ef31d
Compare
…oard dialog waits for a valid form From review: auth's pages code their passkey options and credentials themselves again, as passkey.js did, so browsers without the JSON helpers keep passkeys; the dashboard opens its dialog only for a form that validates, and goes on when a ceremony does not start again; the cropper drags with the primary pointer only; and the dashboard's page wrapper lays out as if absent.
…nge, and the cropper keeps the square it shows From review: a ceremony that finishes after the dialog closed, or reopened for another change, no longer goes on; the dialog's button waits for its pre-started ceremony; and moving or zooming keeps the square's centre where it stays inside the image, as picture.js did.
From review: closing the picture dialog resized the stage to nothing, and placing the image then kept a centre of 0 / 0, so reopening it lost the square chosen. picture.js's render() skipped that case too.
PiquelChips
force-pushed
the
refactor/rust-frontend-scripts
branch
from
November 6, 2026 12:55
c9ef31d to
a9f4e18
Compare
This was referenced Nov 8, 2026
# Conflicts: # README.md # apps/auth-service/assets/dashboard.js # apps/auth-service/assets/passkey.js # apps/auth-service/src/lib.rs # apps/auth-service/src/web/account.rs # apps/auth-service/src/web/admin/audit.rs # apps/auth-service/src/web/admin/mod.rs # apps/auth-service/src/web/admin/tests.rs # apps/auth-service/src/web/auth/login/mod.rs # apps/auth-service/src/web/auth/login/tests.rs # apps/auth-service/src/web/auth/recovery/tests.rs # apps/auth-service/src/web/settings/tests.rs # crates/ui/src/admin/mod.rs # crates/ui/src/form.rs # crates/ui/src/layout/mod.rs # crates/ui/src/layout/signed_in.rs # crates/ui/src/recovery/mod.rs # docs/architecture/monorepo.md # docs/dev/rust-conventions.md # knip.json # tests/browser/README.md # tests/browser/recovery.spec.ts # tests/browser/settings.spec.ts
…d-scripts # Conflicts: # AGENTS.md # Cargo.lock # README.md # apps/auth-service/assets/passkey.js # apps/auth-service/src/account/mod.rs # apps/auth-service/src/admin/tests/accounts.rs # apps/auth-service/src/admin/types/mod.rs # apps/auth-service/src/assets.rs # apps/auth-service/src/audit/mod.rs # apps/auth-service/src/audit/routes.rs # apps/auth-service/src/cli/console.rs # apps/auth-service/src/cli/mod.rs # apps/auth-service/src/clients/mod.rs # apps/auth-service/src/clients/owned.rs # apps/auth-service/src/clients/tests/origins.rs # apps/auth-service/src/config/keys.rs # apps/auth-service/src/config/mod.rs # apps/auth-service/src/config/tests.rs # apps/auth-service/src/deletion/export/mod.rs # apps/auth-service/src/deletion/export/tests.rs # apps/auth-service/src/deletion/tests.rs # apps/auth-service/src/deliveries/email/mod.rs # apps/auth-service/src/deliveries/email/tests.rs # apps/auth-service/src/deliveries/outbound.rs # apps/auth-service/src/emails/mod.rs # apps/auth-service/src/emails/tests.rs # apps/auth-service/src/federation/identities.rs # apps/auth-service/src/federation/mod.rs # apps/auth-service/src/federation/providers/github.rs # apps/auth-service/src/federation/providers/google.rs # apps/auth-service/src/federation/providers/mod.rs # apps/auth-service/src/federation/tests/protocols.rs # apps/auth-service/src/grants/mod.rs # apps/auth-service/src/history/mod.rs # apps/auth-service/src/history/tests.rs # apps/auth-service/src/keys/mod.rs # apps/auth-service/src/keys/tests.rs # apps/auth-service/src/notifications/mod.rs # apps/auth-service/src/notifications/preferences.rs # apps/auth-service/src/notifications/tests.rs # apps/auth-service/src/oidc/authorize/consent.rs # apps/auth-service/src/oidc/authorize/mod.rs # apps/auth-service/src/oidc/authorize/parameters.rs # apps/auth-service/src/oidc/authorize/pushed.rs # apps/auth-service/src/oidc/error.rs # apps/auth-service/src/oidc/inline.rs # apps/auth-service/src/oidc/logout.rs # apps/auth-service/src/oidc/mod.rs # apps/auth-service/src/oidc/tests/mod.rs # apps/auth-service/src/oidc/token.rs # apps/auth-service/src/passkey/acceptance.rs # apps/auth-service/src/passkey/ceremonies.rs # apps/auth-service/src/passkey/mod.rs # apps/auth-service/src/passkey/related.rs # apps/auth-service/src/passkey/tests/mod.rs # apps/auth-service/src/passkey/types.rs # apps/auth-service/src/pictures/mod.rs # apps/auth-service/src/pictures/tests.rs # apps/auth-service/src/recovery/mod.rs # apps/auth-service/src/recovery/tests/mod.rs # apps/auth-service/src/security/http.rs # apps/auth-service/src/sessions/mod.rs # apps/auth-service/src/sessions/tests.rs # apps/auth-service/src/tests.rs # apps/auth-service/src/web/account.rs # apps/auth-service/src/web/admin/administrators.rs # apps/auth-service/src/web/admin/alerts.rs # apps/auth-service/src/web/admin/announcements.rs # apps/auth-service/src/web/admin/audit.rs # apps/auth-service/src/web/admin/clients.rs # apps/auth-service/src/web/admin/deliveries.rs # apps/auth-service/src/web/admin/handles.rs # apps/auth-service/src/web/admin/invitations.rs # apps/auth-service/src/web/admin/keys.rs # apps/auth-service/src/web/admin/lists.rs # apps/auth-service/src/web/admin/mod.rs # apps/auth-service/src/web/admin/origins.rs # apps/auth-service/src/web/admin/overview.rs # apps/auth-service/src/web/admin/settings.rs # apps/auth-service/src/web/admin/tests.rs # apps/auth-service/src/web/admin/users.rs # apps/auth-service/src/web/auth/handoff.rs # apps/auth-service/src/web/auth/login/mod.rs # apps/auth-service/src/web/auth/oidc.rs # apps/auth-service/src/web/auth/recovery/mod.rs # apps/auth-service/src/web/auth/recovery/tests.rs # apps/auth-service/src/web/developers/app.rs # apps/auth-service/src/web/developers/mod.rs # apps/auth-service/src/web/developers/tests.rs # apps/auth-service/src/web/mod.rs # apps/auth-service/src/web/settings/connected.rs # apps/auth-service/src/web/settings/data.rs # apps/auth-service/src/web/settings/emails.rs # apps/auth-service/src/web/settings/history.rs # apps/auth-service/src/web/settings/notifications.rs # apps/auth-service/src/web/settings/overview.rs # apps/auth-service/src/web/settings/profile.rs # apps/auth-service/src/web/settings/sessions.rs # apps/auth-service/src/web/settings/sign_in.rs # apps/auth-service/src/web/settings/tests.rs # apps/auth-service/src/web/tests.rs # apps/web/assets/policies/privacy.html # apps/web/assets/policies/terms.html # apps/web/src/main.rs # apps/web/src/pages.rs # apps/web/src/site/mod.rs # crates/auth-sdk/examples/notes.rs # crates/auth-sdk/src/axum/bearer.rs # crates/auth-sdk/src/axum/login/mod.rs # crates/auth-sdk/src/client.rs # crates/auth-sdk/src/http.rs # crates/auth-sdk/src/keys.rs # crates/auth-sdk/src/lib.rs # crates/auth-sdk/src/resource.rs # crates/auth-sdk/src/tests.rs # crates/auth-sdk/src/token.rs # crates/auth-sdk/tests/ui/coerced_scope.stderr # crates/auth-sdk/tests/ui/forged_id_token.stderr # crates/auth-sdk/tests/ui/forged_scope.stderr # crates/common/src/clients/mod.rs # crates/common/src/clients/tests.rs # crates/common/src/handle/tests.rs # crates/common/src/protocol/claims.rs # crates/common/src/protocol/metadata.rs # crates/common/tests/sdk_vectors.rs # crates/crypto/src/signing/mod.rs # crates/database/.sqlx/query-45e983401ce66752126d428c6cbeabdfb933c2459aa9b80a5b382a4712716621.json # crates/database/.sqlx/query-a2aa3a6a671a884166e9fd0db54829b12b85ce47ffe7332b002bf7c3ca7e8ba4.json # crates/database/src/connection/tests.rs # crates/database/src/repositories/alerts.rs # crates/database/src/repositories/deliveries/backchannel.rs # crates/database/src/repositories/deliveries/email.rs # crates/database/src/repositories/deliveries/mod.rs # crates/database/src/repositories/events/mod.rs # crates/database/src/repositories/handles/tests.rs # crates/database/src/repositories/notifications/mod.rs # crates/database/src/repositories/oidc/clients.rs # crates/database/src/repositories/passkeys/mod.rs # crates/database/src/repositories/sessions.rs # crates/database/src/repositories/tokens/mod.rs # crates/telemetry/src/lib.rs # crates/ui/src/admin/announcements.rs # crates/ui/src/admin/audit.rs # crates/ui/src/admin/clients.rs # crates/ui/src/admin/events.rs # crates/ui/src/admin/mod.rs # crates/ui/src/clients.rs # crates/ui/src/developers.rs # crates/ui/src/form.rs # crates/ui/src/layout/frames.rs # crates/ui/src/layout/html.rs # crates/ui/src/layout/signed_in.rs # crates/ui/src/lib.rs # crates/ui/src/login/mod.rs # crates/ui/src/oidc.rs # crates/ui/src/recovery/mod.rs # crates/ui/src/settings/connected.rs # crates/ui/src/settings/emails.rs # crates/ui/src/settings/notifications.rs # crates/ui/src/settings/overview.rs # crates/ui/src/settings/sessions.rs # crates/ui/src/settings/sign_in.rs # crates/ui/src/settings/timeline.rs # deny.toml # docs/README.md # docs/dev/architecture/overview.md # docs/dev/architecture/surfaces.md # docs/dev/getting-started.md # docs/dev/operations/administration.md # docs/dev/operations/cli-commands.md # docs/dev/operations/clients.md # docs/dev/operations/deploying.md # docs/dev/operations/secrets.md # docs/dev/operations/telemetry.md # docs/dev/rust-conventions.md # docs/dev/security/audit-history.md # docs/dev/security/audit-key.pub # docs/dev/security/boundaries.md # docs/dev/security/threat-model.md # docs/user/account/connected-apps.md # docs/user/account/email-addresses.md # docs/user/account/security-history.md # docs/user/agents/overview.md # docs/user/agents/skills/sourceorigin-debug-sign-in/SKILL.md # docs/user/agents/skills/sourceorigin-deploy/SKILL.md # docs/user/agents/skills/sourceorigin-dev-setup/SKILL.md # docs/user/agents/skills/sourceorigin-sign-in/SKILL.md # docs/user/agents/sourceorigin-debug-sign-in.md # docs/user/agents/sourceorigin-deploy.md # docs/user/agents/sourceorigin-dev-setup.md # docs/user/apps/deploying-with-piqueld.md # docs/user/apps/how-sign-in-works.md # docs/user/apps/protect-an-api.md # docs/user/apps/register-an-app.md # docs/user/apps/sign-in-rust.md # docs/user/apps/sign-in-typescript.md # infra/auth.Dockerfile # infra/piqueld.toml # infra/telemetry.toml # package.json # packages/auth/src/protocol.ts # tests/browser/admin.spec.ts # tests/browser/browser-client.spec.ts # tests/browser/web.spec.ts # tests/sdk-vectors/sessions/ended.json # tests/sdk-vectors/sessions/other-client.json # tests/sdk-vectors/sessions/other-cookie.json # tests/sdk-vectors/sessions/other-key.json # tests/sdk-vectors/sessions/pending-login-key.json # tests/sdk-vectors/sessions/tampered.json # tests/sdk-vectors/sessions/valid.json # tests/sdk-vectors/sessions/without-refresh-token.json
Main's alert and email-preference lists render forms, whose state needs each iteration's own identity under Topcoat, and its password-manager test read the data attributes the passkey script used, which the signal now captures.
PiquelChips
marked this pull request as draft
November 11, 2026 21:22
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.
Every new browser feature added another plain JavaScript file (
passkey.js,dashboard.js, nowpicture.js), wired to the Rust pages throughdata-*attributes the compiler couldn't check. We have a Rust frontend framework; the pages should use it.Now they do. What the pages do in the browser is Rust in
crates/ui, on Topcoat's runtime: signals hold the state,@submit/@clickhandlers and:hidden/:disabledbindings do the rest. The three scripts are gone.Passkey,Once,Dismissalinform.rsandlayout/parts.rs.Gatein the admin frame, with one delegated click handler.settings/cropper.rs.raw!method per API onBrowserincrates/ui/src/browser.rs.AGENTS.mdnow says so: no more script files.Security policy stays strict. Topcoat's runtime normally needs
'unsafe-eval'(tokio-rs/topcoat#484). We depend on a fork,PiquelChips/topcoat@csp-safe-expressions, where pages carry their expressions as data naming functions in one hashed expressions script.script-srclists that script and the runtime, nothing else, on auth and the dashboard. The fork also has@mount(from tokio-rs/topcoat#550) and fixes for two expression bugs this work hit. Nothing was filed upstream yet.Also: Topcoat main's breaking changes (components take
cx: &Cx), and#[key]on theview!loops whose rows keep state.The JSON ceremony routes are unchanged, and the pages code passkey options and credentials themselves, as
passkey.jsdid, so browsers without WebAuthn's JSON helpers keep passkeys. Forms still work without scripts where they did.Proof:
just validate's checks (Clippy, rustdoc, doc tests, tsc, ESLint, knip, Prettier,cargo deny), all 455 Rust tests with the database ones, and the Playwright suite on a preview: every spec that runs there passed, two failing only when auth's rate limit on repeated sign-ups kicked in, then passing on rerun (4 skipped: invitation, Mailpit and the confidential client's secret aren't on previews).Not covered: the browser test that forced a lapsed passkey confirmation is gone (pages now decide confirm mode on the server, and e2e can't lapse a session); the Rust tests cover the confirm-mode render, and the browser side is the same ceremony code sign-in uses.
Reviewed with review-loop: 4 rounds with 2× GPT 6.1 Sol and Claude Opus 5.5 (Sol from round 2: round 1's Sol reviewers hit a usage limit). Verdict: approved
Note
Written by Claude Opus 5.5 in Claude Code and reviewed by GPT 6.1 Sol and Claude Opus 5.5 (via T3 Code)
🤖 Generated with Claude Code