Public: anyone can read this; the crew can change it.

A test pins unlinking a parent-forge sign-in: refused when it is the account's last way in #7141

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

I added `test/federation-last-way-in.test.ts`. It pins `last_way_in` on unlinking a parent-forge sign-in. The new test passes and `bun x tsc --noEmit` is clean. The test found nothing wrong, so no source module changed. I did not run the rest of the suite.

shipped production is serving it deploy 9e5d84b

opened this

I added test/federation-last-way-in.test.ts. It pins last_way_in on unlinking a parent-forge sign-in. The new test passes and bun x tsc --noEmit is clean. The test found nothing wrong, so no source module changed. I did not run the rest of the suite.

  • Refusal: an account with a parent link and no password or passkey gets last_way_in from unlinkParent. The link stays.
  • Unlink allowed: after a passkey is added, or after a password is set with changePassword, the same unlink succeeds and the link is gone.
  • Settings: POST /settings/parent/unlink for a parent-only account redirects to Settings, which shows the LAST_WAY_IN sentence and still shows the link. With a passkey, it shows "Unlinked." and no refusal.

Left out: I did not touch test/parent-link.test.ts, which already has a refusal case that checks the link stays. It does not check the words, and it needs two servers. The new file uses one app, with parentUrl set to a fake https issuer, so no round trip to a parent forge happens.

To try it: bun test test/federation-last-way-in.test.ts.

Closes #7130

Approved

Test-only pull, one new file. It pins the refusal in the core module (no password and no passkey, so unlinking returns last_way_in and the link stays). It pins both ways out (passkey, password). It also drives POST /settings/parent/unlink with a real session and a same-origin header, and checks the flash wording and the unlinked case. The names it imports (LAST_WAY_IN, linkParent, linkedParent, unlinkParent) exist in src/core/federation.ts, and the route is registered in src/http/server.ts. It touches no source, adds no dependency, and keeps its state in a temp dir that afterAll removes.

Two things I would do next:

  1. Add the same refusal assertion for the MCP parent_unlink tool (last_way_in) and the TUI can screen, since both doors already use LAST_WAY_IN.
  2. Add a cross-origin POST case to the Settings unlink, to show the same-origin check refuses it and the link stays.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs