diff --git a/public/_worker.js b/public/_worker.js new file mode 100644 index 0000000..f20c1c6 --- /dev/null +++ b/public/_worker.js @@ -0,0 +1,15 @@ +const CANONICAL_HOST = 'auto-research-private.pages.dev'; + +export default { + async fetch(request, env) { + const url = new URL(request.url); + + if (url.hostname !== CANONICAL_HOST) { + url.protocol = 'https:'; + url.host = CANONICAL_HOST; + return Response.redirect(url.toString(), 307); + } + + return env.ASSETS.fetch(request); + }, +}; diff --git a/tests/pages-access-guard.test.mjs b/tests/pages-access-guard.test.mjs new file mode 100644 index 0000000..9df16a6 --- /dev/null +++ b/tests/pages-access-guard.test.mjs @@ -0,0 +1,28 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import worker from '../public/_worker.js'; + +const canonical = 'auto-research-private.pages.dev'; + +function assets() { + return { + ASSETS: { + fetch: async (request) => new Response(`asset:${new URL(request.url).pathname}`), + }, + }; +} + +test('canonical Pages hostname serves the requested static asset', async () => { + const response = await worker.fetch(new Request(`https://${canonical}/journal/2.json`), assets()); + assert.equal(response.status, 200); + assert.equal(await response.text(), 'asset:/journal/2.json'); +}); + +test('deployment and branch hostnames redirect through the Access-protected canonical hostname', async () => { + const response = await worker.fetch( + new Request('https://c8f7dbf7.auto-research-private.pages.dev/progress/example/?view=full'), + assets(), + ); + assert.equal(response.status, 307); + assert.equal(response.headers.get('location'), `https://${canonical}/progress/example/?view=full`); +});