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

A signed-out 404 offers sign-in that comes back to the same address #4115

Merged opened this

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

Merged

A signed-out visitor who gets a 404 on a GET now sees a "Sign in" button next to "Go home". It leads to `/signin?next=` with the requested path and query. A signed-in 404 and any non-GET 404 render as before. Type check and 186 tests across the related suites pass locally; I haven't run the full check, which the forge does on this push.

shipped production is serving it deploy 93e874d

opened this

A signed-out visitor who gets a 404 on a GET now sees a "Sign in" button next to "Go home". It leads to /signin?next= with the requested path and query. A signed-in 404 and any non-GET 404 render as before. Type check and 186 tests across the related suites pass locally; I haven't run the full check, which the forge does on this push.

What changed

  • notFoundPage (src/web/chrome.ts): The button reuses the existing signInHref, so behind a platform edge it points at the edge login instead of /signin.
  • No leak: The button shows whether or not the thing exists, so a hidden private repository and a missing one still read the same.
  • New tests (test/web-ui.test.ts):

- A signed-out GET of a private repository carries the right next. - A signed-in 404 has no sign-in link. - safeNext refuses //evil.example, https://… and backslash paths.

  • Check failure fixed: The failing test, /go/:code redirects a signed-out phone, and dead codes are one 404, compares an unknown code's 404 with an expired code's 404. Each page now echoes its own address in the sign-in link. That is the same kind of echo the test already scrubs for the manifest link, so that test, and the raw-route one, now scrub next= as well. I changed the tests, not the behaviour. The failing test's source never changed; the new button is what made the two pages differ.

Left out

  • Non-GET 404s get no link.
  • Where the visitor lands after signing in is still decided by the existing flow.

Continues #4115

commented

A signed-out visitor who gets a 404 on a GET now sees a "Sign in" button next to "Go home". It leads to /signin?next= with the requested path and query. A signed-in 404 and any non-GET 404 render as before. Type check and 186 tests across the related suites pass locally; I haven't run the full check, which the forge does on this push.

What changed

  • notFoundPage (src/web/chrome.ts): The button reuses the existing signInHref, so behind a platform edge it points at the edge login instead of /signin.
  • No leak: The button shows whether or not the thing exists, so a hidden private repository and a missing one still read the same.
  • New tests (test/web-ui.test.ts):

- A signed-out GET of a private repository carries the right next. - A signed-in 404 has no sign-in link. - safeNext refuses //evil.example, https://… and backslash paths.

  • Check failure fixed: The failing test, /go/:code redirects a signed-out phone, and dead codes are one 404, compares an unknown code's 404 with an expired code's 404. Each page now echoes its own address in the sign-in link. That is the same kind of echo the test already scrubs for the manifest link, so that test, and the raw-route one, now scrub next= as well. I changed the tests, not the behaviour. The failing test's source never changed; the new button is what made the two pages differ.

Left out

  • Non-GET 404s get no link.
  • Where the visitor lands after signing in is still decided by the existing flow.
commented

The check that parked this failed on a test that was too strict. It wasn't a bug in the feature. The fix is already on the branch and pushed.

What was wrong: The new Sign in button echoes the requested address in its link. The /go/:code test compares two 404 pages byte for byte, one for a code nobody issued and one for an expired code. Its scrub removed the nonce and the manifest link, but not the typed code now in /signin?next=%2Fgo%2F<code>. So the two pages differed only by the visitor's own typed address, and the test failed on that.

What changed:

  • Feature: A signed-out GET 404 now offers "Sign in" to /signin?next=<the requested path and query>. A signed-in 404, or a 404 on a non-GET, is unchanged. The link appears for both a hidden and a missing thing, so it doesn't reveal whether either exists.
  • Tests: In test/web-ui.test.ts, one test covers the signed-out link and its next, the hidden-vs-missing equality, and the signed-in case with no link. Another checks that safeNext refuses other origins.
  • Existing tests changed: The comparison in test/web-origins.test.ts now also drops the echoed next= value, which is the visitor's own typed address, as it already did for the manifest link. The comparison in the raw-route test in test/web-ui.test.ts got the same scrub. In both, the test was wrong, not the behaviour.

Checked: bun x tsc --noEmit is clean, and test/web-origins.test.ts plus test/web-ui.test.ts pass (52 tests). I also started a run of the other suites that assert on the 404 page. It hit the timeout and its result isn't in, so any other test that compares 404 bodies would still show up in the forge's check.

Approved

Approved. Preview check: a signed-out GET of /kim/secret?tab=x&y=1 returns 404 with "Go home" (primary) and "Sign in" (plain btn) as two <a> links. Sign in goes to /signin?next=%2Fkim%2Fsecret%3Ftab%3Dx%26y%3D1, so the query comes back intact. It is one accent, plain links, and works with JS off. The link shows for hidden and missing things alike, so the 404 still tells nothing. Signed-in and non-GET 404s are unchanged. It reuses signInHref, so it follows the edge login. The two scrub changes to existing tests are justified: the echoed next= is the visitor own address. Two things to do next: (1) the long scrub line in test/web-ui.test.ts is not formatted like its neighbours, so wrap it; (2) the encodeURIComponent(asked).replaceAll("&","&amp;") in the new test is a no-op because & is already %26, so drop it to avoid misleading the next reader.

commented

A signed-out visitor who hits a 404 on a GET now sees a "Sign in" button next to "Go home". The button leads to /signin?next= with the requested path and query. Nothing new was said on the issue, and the branch needed no changes this run.

On this run's checks, the suites that assert on the 404 page pass (110 tests across six files). bun x tsc --noEmit and the web-origins and web-ui suites were clean when I last ran them.

What changed

  • notFoundPage (src/web/chrome.ts): The button reuses the existing signInHref(ctx). Behind a platform edge, that helper sends the visitor to the edge login (or to /signup for an edge-made account) instead of /signin.
  • What stays the same: A signed-in 404 and any 404 on a non-GET render as before. The button shows whether or not the thing exists, so a hidden private repository and a missing one still render the same page apart from the echoed address.
  • New tests (test/web-ui.test.ts):

- A signed-out GET of a private repository's link carries the right next. - Hidden and missing pages are identical once the echoed address is scrubbed. - A signed-in 404 has no sign-in link. - safeNext refuses other origins.

  • Existing tests changed:

- What: The 404-body comparisons in test/web-origins.test.ts (the /go/:code dead-code test, which failed the check last time) and in the raw-route test in test/web-ui.test.ts now also scrub the echoed next= value. - Why: That value is the visitor's own typed address, so the test was wrong, not the behaviour.

Not done

  • Mutations: Non-GET 404s get no link, as the issue says.
  • Where the visitor lands: That is left to the existing sign-in flow, which I didn't touch.

Try it: Open a private repository's URL while signed out, click Sign in, and you land back on that address once signed in.

commented

A signed-out visitor who gets a 404 on a GET now sees a "Sign in" button next to "Go home". The button goes to /signin?next= with the requested path and query. This run changed nothing: the branch is clean, pushed, and level with origin, and main hasn't moved. I didn't re-run bun x tsc --noEmit or any tests this run. The last run passed: the 404-related suites (110 tests), the origins and web-ui suites, and the type check.

What changed

  • notFoundPage (src/web/chrome.ts): The button reuses the existing signInHref(ctx). Behind a platform edge, that helper sends the visitor to the edge login (or to /signup for an edge-made account) instead of /signin.
  • What stays the same: A signed-in 404 and any 404 on a non-GET render as before. The button shows whether or not the thing exists, so a hidden private repository and a missing one still render the same page apart from the echoed address.
  • New tests (test/web-ui.test.ts):

- The signed-out link carries the right next. - Hidden and missing pages match once the echoed address is scrubbed. - A signed-in 404 has no sign-in link. - safeNext refuses other origins.

  • Existing tests changed:

- What: The 404-body comparisons in test/web-origins.test.ts (the /go/:code test that failed the check) and in the raw-route test in test/web-ui.test.ts now also scrub the echoed next= value. - Why: That value is the visitor's own typed address, so the tests were wrong, not the behaviour.

Not done

  • Non-GET 404s get no link, as the issue says.
  • Where the visitor lands after signing in is left to the existing sign-in flow.

Try it: Open a private repository's URL while signed out, click Sign in, and you land back on that address once signed in.

commented

A signed-out visitor who gets a 404 on a GET now sees a "Sign in" button next to "Go home". The button goes to /signin?next= with the requested path and query, so signing in brings them back to the same address. This run changed nothing: the branch is clean, pushed, and level with origin. I didn't re-run bun x tsc --noEmit or any tests this run. The last run passed the type check, the origins and web-ui suites, and the six other suites that assert on the 404 page.

What changed

  • notFoundPage (src/web/chrome.ts): The button reuses the existing signInHref(ctx). Behind a platform edge, that helper sends the visitor to the edge login (or to /signup for an edge-made account) instead of /signin.
  • What stays the same: A signed-in 404 and any 404 on a non-GET render as before. The button shows whether or not the thing exists, so a hidden private repository and a missing one still render the same page apart from the echoed address.
  • New tests (test/web-ui.test.ts):

- The signed-out link carries the right next. - Hidden and missing pages match once the echoed address is scrubbed. - A signed-in 404 has no sign-in link. - safeNext refuses other origins.

  • Existing tests changed:

- What: The 404-body comparisons in test/web-origins.test.ts (the /go/:code test that failed the check) and in the raw-route test in test/web-ui.test.ts now also scrub the echoed next= value. - Why: That value is the visitor's own typed address, so the tests were wrong, not the behaviour.

Not done

  • Non-GET 404s get no link, as the issue says.
  • Where the visitor lands after signing in is left to the existing sign-in flow.

Try it: Open a private repository's URL while signed out, click Sign in, and you land back on that address once signed in.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs