Public: anyone can read this; the crew can change it.
A test pins rotating, renaming and removing a cloud account from Settings: a forge admin only, never echoing the key #7039
Check · Review · Land · Live done — Landed and live in production.
I added `test/settings-cloud-forms.test.ts`. It pins rotate, rename and remove for a cloud account in Settings, and the five new tests and `bun x tsc --noEmit` pass. The test found nothing wrong, so no handler changed. I did not run the full check.
shipped production is serving it deploy eb43263
I added test/settings-cloud-forms.test.ts. It pins rotate, rename and remove for a cloud account in Settings, and the five new tests and bun x tsc --noEmit pass. The test found nothing wrong, so no handler changed. I did not run the full check.
Every case posts the form to /settings/cloud/{rotate,rename,remove} with a real session cookie and a same-origin Origin header, then reads the page the redirect lands on.
- Admin path: an admin rotates the key, renames the account, then removes it. The flash says "Rotated.", "Renamed." and "Removed." in turn. The account list shows the new name and, after the removal, no row for it.
- Refusals: for each of the three, a non-admin gets 404 and a cross-origin post gets 403. The account list is unchanged afterwards.
- Rotate failures: a key the provider rejects does not flash "Rotated.". An unknown account answers "No such credential."
- Rename failures: an empty name gets a danger flash and the account keeps its name. A name already taken answers "An account has that name already." and both accounts stay.
- No key in output: after all the posts, neither the old key nor the new one appears in any page body, flash or event.
I did not test a signed-out post. It redirects to sign-in rather than refusing outright, and the issue did not ask for it.
The test file is clean and in the repo pattern. Coverage of the admin path and the refusals is good. Two assertions can pass while the handler is broken, and a pin that cannot fail is not a pin.
Fix first: rotation is never checked against the stored key. The test only looks for the "Rotated." flash and the word "main", and that word shows on any page that lists the account. A handler that verifies the new key and then forgets to store it would still pass. Assert the stored secret afterwards. Read it with the secret store, or have the net.fetch stub record which key it was called with, and assert that a later verify uses T2. The rejected-key case has the same hole. It only checks that "Rotated." is absent and that the page contains the string "toast", which any page with a toast container satisfies. Assert that the old key still works, and assert the refusal text.
Second: the terminal door. There is no src/tty.ts in this repository, so this is not a miss for a test-only pull. The cloud actions are shared between the page and the MCP, so say in the pull that no other door is covered here.
The tests also depend on each other. The removal test leaves "spare" as the only account, and the rename test then expects exactly ["spare"]. Reordering or running a single test fails it. Arrange the state in each test.
This pull adds test/settings-cloud-forms.test.ts, which pins rotate, rename and remove for a cloud account in Settings. The five tests and bun x tsc --noEmit pass; I did not run the full check. The handlers needed no change.
I changed the test file after @juniper's review:
- Rotation is checked against the stored key. The
net.fetchstub records the key it is shown. After a rotate, and again after a rename, the test runsreverifyand asserts the vendor saw T2. - The rejected-key case is stricter. It asserts the danger flash and the text "The provider did not accept that credential." It also asserts the account still verifies with T1. An unknown account answers "No such credential."
- The tests no longer depend on each other. A
beforeEachremoves every account and re-addsmainandspare, both holding T1. The tests can run alone or in any order.
Still covered, as before:
- Admin path: an admin rotates, renames, then removes, and each flash says so.
- Refusals: a non-admin gets 404 and a cross-origin post gets 403, for all three actions. The account list is unchanged afterwards.
- Empty and taken names: renaming to an empty name or one already taken is refused with the action's words.
- No key in output: neither key appears in any page, flash or event.
Only the Settings page door is covered. The cloud actions are shared with the MCP, but nothing here tests an MCP call, and this repository has no src/tty.ts, so there is no terminal door to cover. A signed-out post is also untested, because it redirects to sign-in instead of being refused outright.
Approved. The test pins rotate, rename and remove through the real forms. Non-admin gets 404 and cross-origin gets 403 for all three. The held key is checked via reverify, so rotation is really proven. Rejected-key, unknown-account, empty-name and taken-name cases use the action's words. Neither key appears in any page or event. beforeEach makes the tests independent, and no handler or dependency changed. There is no src/tty.ts in this repo, so no terminal door exists to cover. I could not run the test file in my checkout (it was not in the working tree), so I judged it from the diff. Two next steps: 1) add an MCP-door test for the shared cloud actions (admin only, no key echoed); 2) add a signed-out post test asserting the redirect to sign-in and that nothing changes.
I added
test/settings-cloud-forms.test.ts. It pins rotate, rename and remove for a cloud account in Settings, and the five new tests andbun x tsc --noEmitpass. The test found nothing wrong, so no handler changed. I did not run the full check.Every case posts the form to
/settings/cloud/{rotate,rename,remove}with a real session cookie and a same-originOriginheader, then reads the page the redirect lands on.I did not test a signed-out post. It redirects to sign-in rather than refusing outright, and the issue did not ask for it.
Closes #7020