Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions scripts/live-promise-spot-check.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ function landingPageLdExpectations(path, pageName) {
// query intact, so canonicals, robots.txt, and sitemap.xml stay apex-only.
// Redirects are checked with `redirect: "manual"` so the 301 itself is
// observable instead of being silently followed.
// The static-asset check exists because wrangler.jsonc must route every
// request through the Worker (`run_worker_first: true`); an asset path served
// 200 from www means the config regressed to a path list that bypasses the
// Worker redirect.
export function canonicalHostSpotChecks(baseUrl) {
const apex = new URL(baseUrl);
const wwwOrigin = `https://www.${apex.hostname}`;
Expand Down Expand Up @@ -460,6 +464,34 @@ export function canonicalHostSpotChecks(baseUrl) {
reason: "static asset path must 301 onto the apex host"
}
]
},
{
path: "www.seofixkit.com/.well-known/security.txt",
name: "www.seofixkit.com well-known paths redirect onto the apex host",
url: `${wwwOrigin}/.well-known/security.txt`,
redirectManual: true,
acceptStatuses: [301],
expectedHeaders: [
{
name: "location",
value: `${baseUrl}/.well-known/security.txt`,
reason: "static assets must never be served from www"
}
]
},
{
path: "www.seofixkit.com/unknown-spa-path",
name: "www.seofixkit.com SPA-fallback paths redirect onto the apex host",
url: `${wwwOrigin}/unknown-spa-path`,
redirectManual: true,
acceptStatuses: [301],
expectedHeaders: [
{
name: "location",
value: `${baseUrl}/unknown-spa-path`,
reason: "SPA fallback must never serve the shell from www"
}
]
}
];
}
Expand Down
10 changes: 8 additions & 2 deletions scripts/live-promise-spot-check.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ test("live spot-check covers the public machine surfaces", () => {
test("live spot-check covers the www-to-apex canonical redirect", () => {
assert.deepEqual(
canonicalHostSpotChecks(origin).map((check) => check.path),
["www.seofixkit.com/", "www.seofixkit.com/check", "www.seofixkit.com/favicon.svg"]
[
"www.seofixkit.com/",
"www.seofixkit.com/check",
"www.seofixkit.com/favicon.svg",
"www.seofixkit.com/.well-known/security.txt",
"www.seofixkit.com/unknown-spa-path"
]
);
for (const check of canonicalHostSpotChecks(origin)) {
assert.equal(check.redirectManual, true, "redirect checks must observe the 301 itself");
Expand All @@ -125,7 +131,7 @@ test("live spot-check covers the www-to-apex canonical redirect", () => {

test("live spot-check passes against the shipped public page copy", async () => {
const results = await spotCheckPublicPages({ baseUrl: origin, fetcher: pageFetcher() });
assert.equal(results.length, 22);
assert.equal(results.length, 24);
for (const result of results) {
assert.deepEqual(result.failures, [], `${result.path} must pass: ${result.name}`);
}
Expand Down
17 changes: 13 additions & 4 deletions worker/index.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,19 @@ test("Worker dispatch 301-redirects www.seofixkit.com onto the apex host", async
assert.equal(sitemap.status, 301);
assert.equal(sitemap.headers.get("location"), "https://seofixkit.com/sitemap.xml");

// Static assets must 301 too: with wrangler.jsonc "run_worker_first": true
// every www request reaches this Worker (the array form let asset paths
// bypass the Worker and be served 200 straight from the asset CDN).
for (const assetPath of ["/favicon.svg", "/security.txt", "/assets/index-abc123.css"]) {
// Static-asset and SPA-fallback paths must 301 too: with wrangler.jsonc
// "run_worker_first": true every www request reaches this Worker. The old
// array form let asset paths bypass the Worker and be served 200 straight
// from the asset CDN, and SPA-fallback paths never reached it at all, both
// of which leak a second host into canonicals/sitemap indexing.
for (const assetPath of [
"/favicon.svg",
"/security.txt",
"/assets/index-abc123.css",
"/.well-known/security.txt",
"/assets/waitlist-hero.jpg",
"/some-random-client-path"
]) {
const asset = await worker.fetch(new Request(`https://www.seofixkit.com${assetPath}`), env, fakeCtx());
assert.equal(asset.status, 301, `www ${assetPath} must 301`);
assert.equal(asset.headers.get("location"), `https://seofixkit.com${assetPath}`);
Expand Down
Loading