nix-cache: redirect http to https

This commit is contained in:
Abel Luck 2026-02-26 14:45:11 +01:00
parent ea675c8818
commit d91f1491f1
3 changed files with 25 additions and 12 deletions

View file

@ -14,7 +14,7 @@
packages = forAllSystems (pkgs: {
nix-cache = pkgs.buildNpmPackage {
pname = "nix-cache";
version = "0.1.0";
version = "0.1.2";
src = ./nix-cache;
npmDepsHash = "sha256-bIujU7pZa1ExCZOMOoxsTeLDSF1GuPN/oMSgiMhY/04=";
buildPhase = ''

View file

@ -85,6 +85,12 @@ export default {
return new Response(null, { headers: { allow: allowedMethods.join(', ') } });
}
const url = new URL(request.url);
if (url.protocol !== 'https:') {
url.protocol = 'https:';
return Response.redirect(url.toString(), 301);
}
const authenticated = await authenticate(request, env);
if (!authenticated) {
return new Response('Unauthorized', {
@ -93,7 +99,6 @@ export default {
});
}
const url = new URL(request.url);
if (url.pathname === '/') {
url.pathname = '/index.html';
}

View file

@ -54,15 +54,23 @@ async function makeJWT(overrides: Record<string, unknown> = {}): Promise<string>
}
describe('nix-cache auth', () => {
it('HTTP request redirects to HTTPS', async () => {
const request = new IncomingRequest('http://example.com/nix-cache-info');
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
expect(response.status).toBe(301);
expect(response.headers.get('location')).toBe('https://example.com/nix-cache-info');
});
it('OPTIONS without auth returns 200', async () => {
const request = new IncomingRequest('http://example.com/', { method: 'OPTIONS' });
const request = new IncomingRequest('https://example.com/', { method: 'OPTIONS' });
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
expect(response.status).toBe(200);
});
it('GET with no Authorization header returns 401', async () => {
const request = new IncomingRequest('http://example.com/nix-cache-info');
const request = new IncomingRequest('https://example.com/nix-cache-info');
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
expect(response.status).toBe(401);
@ -70,7 +78,7 @@ describe('nix-cache auth', () => {
});
it('GET with unrecognized auth scheme returns 401', async () => {
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: 'Token xyz' },
});
const ctx = createExecutionContext();
@ -80,7 +88,7 @@ describe('nix-cache auth', () => {
it('GET with Bearer + valid JWT passes auth', async () => {
const token = await makeJWT();
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: `Bearer ${token}` },
});
const ctx = createExecutionContext();
@ -91,7 +99,7 @@ describe('nix-cache auth', () => {
it('GET with Basic auth :token format passes auth', async () => {
const token = await makeJWT();
const basic = btoa(':' + token);
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: `Basic ${basic}` },
});
const ctx = createExecutionContext();
@ -102,7 +110,7 @@ describe('nix-cache auth', () => {
it('GET with Basic auth user:token format passes auth', async () => {
const token = await makeJWT();
const basic = btoa('user:' + token);
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: `Basic ${basic}` },
});
const ctx = createExecutionContext();
@ -111,7 +119,7 @@ describe('nix-cache auth', () => {
});
it('GET with invalid Bearer token returns 401', async () => {
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: 'Bearer garbage-token' },
});
const ctx = createExecutionContext();
@ -121,7 +129,7 @@ describe('nix-cache auth', () => {
it('GET with expired JWT returns 401', async () => {
const token = await makeJWT({ exp: Math.floor(Date.now() / 1000) - 3600 });
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: `Bearer ${token}` },
});
const ctx = createExecutionContext();
@ -131,7 +139,7 @@ describe('nix-cache auth', () => {
it('GET with JWT missing groups claim returns 401', async () => {
const token = await makeJWT({ groups: undefined });
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: `Bearer ${token}` },
});
const ctx = createExecutionContext();
@ -141,7 +149,7 @@ describe('nix-cache auth', () => {
it('GET with JWT where groups does not contain required group returns 401', async () => {
const token = await makeJWT({ groups: ['some-other-group'] });
const request = new IncomingRequest('http://example.com/nix-cache-info', {
const request = new IncomingRequest('https://example.com/nix-cache-info', {
headers: { Authorization: `Bearer ${token}` },
});
const ctx = createExecutionContext();