fix: align nginx with production smoke gate
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
} from '../../scripts/generate-host-config.mjs';
|
||||
|
||||
const jsonLdHash = 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
|
||||
const releaseManifestDigest = 'd'.repeat(64);
|
||||
const productionSite: SiteConfig = {
|
||||
environment: 'production',
|
||||
canonicalUrl: 'https://portfolio.example.test/',
|
||||
@@ -38,6 +39,7 @@ describe('generated Nginx static-host contract', () => {
|
||||
alternateHosts: ['www.portfolio.example.test'],
|
||||
tlsCertificatePath: '/etc/portfolio/tls/fullchain.pem',
|
||||
tlsKeyPath: '/etc/portfolio/tls/privkey.pem',
|
||||
manifestDigest: releaseManifestDigest,
|
||||
});
|
||||
|
||||
for (const file of manifest.files) expect(config).toContain(`~^/${file.path.replaceAll('.', '\\.')}$`);
|
||||
@@ -62,6 +64,7 @@ describe('generated Nginx static-host contract', () => {
|
||||
alternateHosts: ['www.portfolio.example.test'],
|
||||
tlsCertificatePath: '/etc/portfolio/tls/fullchain.pem',
|
||||
tlsKeyPath: '/etc/portfolio/tls/privkey.pem',
|
||||
manifestDigest: releaseManifestDigest,
|
||||
});
|
||||
|
||||
expect(config).toContain('listen 80;');
|
||||
@@ -80,12 +83,18 @@ describe('generated Nginx static-host contract', () => {
|
||||
alternateHosts: [],
|
||||
tlsCertificatePath: '/etc/portfolio/tls/fullchain.pem',
|
||||
tlsKeyPath: '/etc/portfolio/tls/privkey.pem',
|
||||
manifestDigest: releaseManifestDigest,
|
||||
});
|
||||
|
||||
expect(config).toContain("default-src 'self'; script-src 'self' 'sha256-");
|
||||
expect(config).toContain("img-src 'self' data:");
|
||||
expect(config).toContain("connect-src 'none'");
|
||||
expect(config).toContain('add_header Strict-Transport-Security "max-age=31536000" always;');
|
||||
expect(config).toContain(`add_header X-Portfolio-Manifest-Digest "${releaseManifestDigest}" always;`);
|
||||
expect(config).toContain('gzip on;');
|
||||
expect(config).toContain('gzip_min_length 1;');
|
||||
expect(config).toContain('gzip_vary on;');
|
||||
expect(config).toContain('gzip_types text/css application/javascript application/json image/svg+xml;');
|
||||
expect(config).not.toContain('includeSubDomains');
|
||||
expect(config).not.toContain('X-Robots-Tag');
|
||||
expect(config).not.toMatch(/unsafe-inline|unsafe-eval|sourceMappingURL|\.map(?:\s|$)/u);
|
||||
@@ -104,6 +113,19 @@ describe('generated Nginx static-host contract', () => {
|
||||
expect(config).toContain('private, no-store');
|
||||
expect(config).not.toContain('Strict-Transport-Security');
|
||||
expect(config).not.toContain('sitemap.xml');
|
||||
expect(config).not.toContain('X-Portfolio-Manifest-Digest');
|
||||
});
|
||||
|
||||
it('rejects production configuration without the signed manifest digest', () => {
|
||||
expect(() => renderNginxConfig({
|
||||
site: productionSite,
|
||||
jsonLdCspHash: jsonLdHash,
|
||||
artifactManifest: manifest,
|
||||
documentRoot: '/srv/portfolio/current',
|
||||
alternateHosts: [],
|
||||
tlsCertificatePath: '/etc/portfolio/tls/fullchain.pem',
|
||||
tlsKeyPath: '/etc/portfolio/tls/privkey.pem',
|
||||
})).toThrow(/manifest digest/i);
|
||||
});
|
||||
|
||||
it.each([
|
||||
@@ -149,6 +171,7 @@ describe('generated Nginx static-host contract', () => {
|
||||
|
||||
expect(example).toContain('__CANONICAL_HOST__');
|
||||
expect(example).toContain('__JSON_LD_CSP_HASH__');
|
||||
expect(example).toContain('__MANIFEST_DIGEST__');
|
||||
expect(example).not.toContain('portfolio.example.test');
|
||||
expect(example).not.toMatch(/server_name\s+[a-z0-9.-]+\.[a-z]{2,}/iu);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user