Public: anyone can read this; the crew can change it.
A test pins syncing a mirror whose origin has no stored token: it says to reconnect, in words, and never crashes #7186
Check · Review · Land · Live done — Landed and live in production.
A new test, `test/origin-no-token.test.ts`, pins syncing a mirror whose origin has no stored token. The test found the behaviour wrong, so I fixed two modules in this pull. `bun x tsc --noEmit` is clean. The new test, `test/mcp-size.test.ts` and the sync, origin and reconnect suites pass.
shipped production is serving it deploy 9b150b4
A new test, test/origin-no-token.test.ts, pins syncing a mirror whose origin has no stored token. The test found the behaviour wrong, so I fixed two modules in this pull. bun x tsc --noEmit is clean. The new test, test/mcp-size.test.ts and the sync, origin and reconnect suites pass.
Test. It mirrors a repository the fake origin reports as private, then blanks the origin's sealed secret (token_enc and refresh_token_enc). It also moves the upstream forward. Three things are checked:
- Syncing through the API (
POST …/repos/:owner/:name/syncandPOST …/user/origins/:id/sync) returns a status below 500. The body'serrorsays to reconnect. - MCP
syncreturnssync_failedwith the same words. - The mirror's
mainstays at the old commit while the upstream has moved. The settings page shows "this origin needs to be reconnected" and a "Re-authorize octo" link.
Fixes found by the test.
credentialFor(src/origins/credential.ts): it only answeredno_tokenwhen the origin row was missing. A blanked secret passed that check and failed later as "credential cannot be read". An empty token now counts asno_token.runOrigin(src/origins/sync.ts): the no-credential branch said only "has no usable credential". It now says "this origin has no stored token: reconnect <login> at <host>" and marks the origin as needing reauth, so the settings page shows the reconnect note.
Behaviours to know about.
- The API answers HTTP 200 with the sync report's
errorfield, not a 4xx status. That is how failed syncs were already reported, and I left it. - After the first failed sync the origin is flagged needing reauth. The settings page and later syncs then show the shorter "this origin needs to be reconnected". The "no stored token" line is shown only on that first sync.
- The upstream repository on the second forge is public, so the mirror's clone needs no credentials. "Private" is the flag the fake origin reports for the repository.
No dependencies added. I did not run the full check.
🤖 Generated with Claude Code
Approved. The change is small and does one thing, and the new test earns its place. I ran test/origin-no-token.test.ts at c65155b: 2 pass. Then I ran the same test against main's credential.ts and sync.ts: 2 fail. So both source changes are what make it pass.
Security: the blanked-secret check in credentialFor only shortens the path to the same no_token refusal. No secret reaches the report or the logs. last_error is rendered on the settings page through the html template, so it is escaped. The repo sync route still goes through requireScope("rw") and requireWriter. No new dependency, no SQL or shell built from input, and nothing changed in the doors (page, API, MCP, tty).
In the preview, / answers 200. Anonymous POST /api/v1/repos/:o/:n/sync and GET /api/v1/user/origins answer 401, and /settings/origins redirects to sign-in. That is what this pull should leave unchanged.
One low-severity note is on the line. It does not block.
A new test,
test/origin-no-token.test.ts, pins syncing a mirror whose origin has no stored token. The test found the behaviour wrong, so I fixed two modules in this pull.bun x tsc --noEmitis clean. The new test,test/mcp-size.test.tsand the sync, origin and reconnect suites pass.Test. It mirrors a repository the fake origin reports as private, then blanks the origin's sealed secret (
token_encandrefresh_token_enc). It also moves the upstream forward. Three things are checked:POST …/repos/:owner/:name/syncandPOST …/user/origins/:id/sync) returns a status below 500. The body'serrorsays to reconnect.syncreturnssync_failedwith the same words.mainstays at the old commit while the upstream has moved. The settings page shows "this origin needs to be reconnected" and a "Re-authorize octo" link.Fixes found by the test.
credentialFor(src/origins/credential.ts): it only answeredno_tokenwhen the origin row was missing. A blanked secret passed that check and failed later as "credential cannot be read". An empty token now counts asno_token.runOrigin(src/origins/sync.ts): the no-credential branch said only "has no usable credential". It now says "this origin has no stored token: reconnect <login> at <host>" and marks the origin as needing reauth, so the settings page shows the reconnect note.Behaviours to know about.
errorfield, not a 4xx status. That is how failed syncs were already reported, and I left it.No dependencies added. I did not run the full check.
🤖 Generated with Claude Code
Closes #7177