diff --git a/config/presets/middleware.json b/config/presets/middleware.json index b0bbad02e..44b26222d 100644 --- a/config/presets/middleware.json +++ b/config/presets/middleware.json @@ -3,27 +3,8 @@ "@graph": [ { "@id": "urn:solid-server:default:Middleware", - "@type": "ParallelHandler", - "ParallelHandler:_handlers": [ - { - "@type": "CorsHandler", - "CorsHandler:_options_methods": [ - "GET", - "HEAD", - "OPTIONS", - "POST", - "PUT", - "PATCH", - "DELETE" - ], - "CorsHandler:_options_credentials": true, - "CorsHandler:_options_exposedHeaders": [ - "Accept-Patch", - "Location", - "MS-Author-Via", - "Updates-Via" - ] - }, + "@type": "SequenceHandler", + "SequenceHandler:_handlers": [ { "@type": "HeaderHandler", "HeaderHandler:_headers": [ @@ -42,6 +23,25 @@ "WebSocketAdvertiser:_baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" } + }, + { + "@type": "CorsHandler", + "CorsHandler:_options_methods": [ + "GET", + "HEAD", + "OPTIONS", + "POST", + "PUT", + "PATCH", + "DELETE" + ], + "CorsHandler:_options_credentials": true, + "CorsHandler:_options_exposedHeaders": [ + "Accept-Patch", + "Location", + "MS-Author-Via", + "Updates-Via" + ] } ] } diff --git a/src/server/middleware/CorsHandler.ts b/src/server/middleware/CorsHandler.ts index 23365a695..6bf8c4e61 100644 --- a/src/server/middleware/CorsHandler.ts +++ b/src/server/middleware/CorsHandler.ts @@ -22,6 +22,7 @@ interface SimpleCorsOptions { /** * Handler that sets CORS options on the response. + * In case of an OPTIONS request this handler will close the connection after adding its headers. * * Solid, ยง7.1: "A data pod MUST implement the CORS protocol [FETCH] such that, to the extent possible, * the browser allows Solid apps to send any request and combination of request headers to the data pod, diff --git a/test/integration/Middleware.test.ts b/test/integration/Middleware.test.ts index 323260043..76acbdbf7 100644 --- a/test/integration/Middleware.test.ts +++ b/test/integration/Middleware.test.ts @@ -62,7 +62,7 @@ describe('An Express server with middleware', (): void => { })); }); - it('returns CORS headers for an OPTIONS request.', async(): Promise => { + it('returns all relevant headers for an OPTIONS request.', async(): Promise => { const res = await request(server) .options('/') .set('Access-Control-Allow-Credentials', 'true') @@ -73,7 +73,13 @@ describe('An Express server with middleware', (): void => { expect(res.header).toEqual(expect.objectContaining({ 'access-control-allow-origin': '*', 'access-control-allow-headers': 'content-type', + 'updates-via': 'wss://example.pod/', + 'x-powered-by': 'Community Solid Server', })); + const { vary } = res.header; + expect(vary).toMatch(/(^|,)\s*Accept\s*(,|$)/iu); + expect(vary).toMatch(/(^|,)\s*Authorization\s*(,|$)/iu); + expect(vary).toMatch(/(^|,)\s*Origin\s*(,|$)/iu); const corsMethods = res.header['access-control-allow-methods'].split(',') .map((method: string): string => method.trim()); const allowedMethods = [ 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE' ];