diff --git a/middleware/csp.js b/middleware/csp.js index b96f01c1ac..a6b0d9a431 100644 --- a/middleware/csp.js +++ b/middleware/csp.js @@ -4,6 +4,7 @@ const { contentSecurityPolicy } = require('helmet') const isArchivedVersion = require('../lib/is-archived-version') const versionSatisfiesRange = require('../lib/version-satisfies-range') +const AZURE_STORAGE_URL = 'githubdocs.azureedge.net' // module.exports = contentSecurityPolicy({ module.exports = async (req, res, next) => { @@ -18,13 +19,15 @@ module.exports = async (req, res, next) => { fontSrc: [ "'self'", 'data:', - 'github-images.s3.amazonaws.com' + 'github-images.s3.amazonaws.com', + AZURE_STORAGE_URL ], imgSrc: [ "'self'", 'data:', 'github.githubassets.com', 'github-images.s3.amazonaws.com', + AZURE_STORAGE_URL, 'placehold.it', '*.githubusercontent.com', 'github.com' diff --git a/middleware/set-fastly-cache-headers.js b/middleware/set-fastly-cache-headers.js index 5059487198..2463e63ea5 100644 --- a/middleware/set-fastly-cache-headers.js +++ b/middleware/set-fastly-cache-headers.js @@ -1,45 +1,8 @@ -const FASTLY_TTL = process.env.FASTLY_TTL || String(60 * 60 * 24) // 24 hours -const STALE_TTL = String(60 * 10) // 10 minutes - module.exports = (req, res, next) => { - const BYPASS_FASTLY = process.env.TEST_BYPASS_FASTLY === 'true' - - // Bypass Fastly caching for all rendered pages - if (BYPASS_FASTLY) { - // Disallow both Fastly AND the browser from caching HTML pages - res.set({ - 'surrogate-control': 'private, no-store', - 'cache-control': 'private, no-store' - }) - return next() - } - + // Disallow both Fastly AND the browser from caching HTML pages res.set({ - - // Say you want Fastly to cache your content but you don't want it cached by browsers. - // The best way to do this would be to send Fastly both the Cache-Control header as you want - // it to go to the browsers, and use Surrogate-Control to tell us how long to cache for. - - // Fastly does not currently respect no-store or no-cache directives. - // Including either or both of these in a Cache-Control header has no effect on - // Fastly's caching decision, unless you alter this behavior using custom VCL. - - // https://docs.fastly.com/en/guides/configuring-caching - 'cache-control': 'no-store, must-revalidate', - - // This header gets stripped and is only visible to Fastly caches. - // https://docs.fastly.com/en/guides/serving-stale-content#manually-enabling-serve-stale - 'surrogate-control': `max-age=${FASTLY_TTL}, stale-if-error=${STALE_TTL}, stale-while-revalidate=${STALE_TTL}`, - - // Fastly provides a Soft Purge feature that allows you to mark content as outdated (stale) instead of permanently - // purging and thereby deleting it from Fastly's caches. Objects invalidated with Soft Purge will be treated as - // outdated (stale) while Fastly fetches a new version from origin. - // - // Use of a surrogate key is required for soft purging - // https://docs.fastly.com/en/guides/soft-purges - // https://docs.fastly.com/en/guides/getting-started-with-surrogate-keys - 'surrogate-key': 'all-the-things' + 'surrogate-control': 'private, no-store', + 'cache-control': 'private, no-store' }) - - next() + return next() } diff --git a/tests/rendering/server.js b/tests/rendering/server.js index 5686efca73..c4f59fa6ac 100644 --- a/tests/rendering/server.js +++ b/tests/rendering/server.js @@ -5,6 +5,7 @@ const { describeViaActionsOnly } = require('../helpers/conditional-runs') const path = require('path') const { loadPages } = require('../../lib/pages') const builtAssets = require('../../lib/built-asset-urls') +const AZURE_STORAGE_URL = 'githubdocs.azureedge.net' describe('server', () => { jest.setTimeout(60 * 1000) @@ -45,12 +46,14 @@ describe('server', () => { expect(csp.get('font-src').includes("'self'")).toBe(true) expect(csp.get('font-src').includes('github-images.s3.amazonaws.com')).toBe(true) + expect(csp.get('font-src').includes(AZURE_STORAGE_URL)).toBe(true) expect(csp.get('connect-src').includes("'self'")).toBe(true) expect(csp.get('connect-src').includes('*.algolia.net')).toBe(true) expect(csp.get('connect-src').includes('*.algolianet.com')).toBe(true) expect(csp.get('img-src').includes("'self'")).toBe(true) + expect(csp.get('img-src').includes(AZURE_STORAGE_URL)).toBe(true) expect(csp.get('img-src').includes('github-images.s3.amazonaws.com')).toBe(true) expect(csp.get('script-src').includes("'self'")).toBe(true) @@ -59,16 +62,7 @@ describe('server', () => { expect(csp.get('style-src').includes("'unsafe-inline'")).toBe(true) }) - test('sets Fastly cache control headers', async () => { - const res = await get('/en') - expect(res.headers['cache-control']).toBe('no-store, must-revalidate') - expect(res.headers['surrogate-control']).toBe('max-age=86400, stale-if-error=600, stale-while-revalidate=600') - expect(res.headers['surrogate-key']).toBe('all-the-things') - }) - - test('sets Fastly cache control headers to bypass if enabled', async () => { - process.env.TEST_BYPASS_FASTLY = 'true' - + test('sets Fastly cache control headers to bypass pages', async () => { const res = await get('/en') expect(res.headers['cache-control']).toBe('private, no-store') expect(res.headers['surrogate-control']).toBe('private, no-store')