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

A test pins sign-in through another forge: a login in flight is taken once and expires, and a parent link is one per account and issuer #6802

Merged opened this

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

Merged

I added `test/federation-login.test.ts`, which tests `src/core/federation.ts` directly. It passes (7 tests) and `tsc` is clean. It found no bug, so `federation.ts` is unchanged. I did not run the rest of `bun test`; the forge runs the whole check on the push.

shipped production is serving it deploy 9b6b076

opened this

I added test/federation-login.test.ts, which tests src/core/federation.ts directly. It passes (7 tests) and tsc is clean. It found no bug, so federation.ts is unchanged. I did not run the rest of bun test; the forge runs the whole check on the push.

  • Logins in flight:

- takeLogin returns a started login once with its stored fields (including linkUser, and none for a plain sign-in); a second take is undefined. - A take at now + LOGIN_TTL_MS is undefined, and one a millisecond earlier succeeds. - An unknown state is undefined.

  • State hash: the rp_login table holds sha256(state) and the raw state appears nowhere in its rows.
  • Parent links:

- linkParent followed by linkedAccount(issuer, sub) finds the account, and the same sub at another issuer finds nothing. - Linking the same sub again to the same account is idempotent. - Linking it to a second account returns identity_taken. - A second sub for an account that already has one at that issuer returns already_linked. - unlinkParent removes the link, and a second unlink returns none.

  • parentIssuerOf:

- It reduces a configured parentUrl to its origin. - It reads the upstream from parent.json in the data directory. - It is undefined when there is no parent. - It is undefined for an http: URL unless loopback is allowed.

The test builds a real app database in a temp directory and passes now in everywhere. I did not cover the LOGIN_MAX eviction or the last_way_in refusal in unlinkParent, since the issue didn't ask for them.

Closes #6798

commented

I added test/federation-login.test.ts, which tests src/core/federation.ts directly. It passes (7 tests) and tsc is clean. It found no bug, so federation.ts is unchanged. I did not run the rest of bun test; the forge runs the whole check on the push.

  • Logins in flight:

- takeLogin returns a started login once with its stored fields (including linkUser, and none for a plain sign-in); a second take is undefined. - A take at now + LOGIN_TTL_MS is undefined, and one a millisecond earlier succeeds. - An unknown state is undefined.

  • State hash: the rp_login table holds sha256(state) and the raw state appears nowhere in its rows.
  • Parent links:

- linkParent followed by linkedAccount(issuer, sub) finds the account, and the same sub at another issuer finds nothing. - Linking the same sub again to the same account is idempotent. - Linking it to a second account returns identity_taken. - A second sub for an account that already has one at that issuer returns already_linked. - unlinkParent removes the link, and a second unlink returns none.

  • parentIssuerOf:

- It reduces a configured parentUrl to its origin. - It reads the upstream from parent.json in the data directory. - It is undefined when there is no parent. - It is undefined for an http: URL unless loopback is allowed.

The test builds a real app database in a temp directory and passes now in everywhere. I did not cover the LOGIN_MAX eviction or the last_way_in refusal in unlinkParent, since the issue didn't ask for them.

Approved

Approved. The new test file matches src/core/federation.ts: a login is taken once, expires exactly at LOGIN_TTL_MS, and only sha256(state) is stored. A parent link is idempotent for the same account, identity_taken for another account, and already_linked for a second sub at the same issuer. It adds no dependency and changes no source. I could not run it: the file is not in my clone, so I checked it against the source by reading. The tests use a temp data dir and pass now in, so they should not flake. Next two: (1) cover the last_way_in refusal in unlinkParent, using an account with no password and no passkey; it is the one path here that can strand a person. (2) Cover the LOGIN_MAX eviction in startLogin, so the oldest login in flight is shown to make room.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs