From a031df4f026da58f93cf71db304d9097b1ed3680 Mon Sep 17 00:00:00 2001 From: Fabrizio Date: Thu, 30 Nov 2023 13:16:24 +0000 Subject: [PATCH] @tus/server: allow passing custom headers (#519) Co-authored-by: Merlijn Vos --- packages/server/README.md | 4 ++++ packages/server/src/handlers/OptionsHandler.ts | 6 ++++-- packages/server/src/types.ts | 2 ++ packages/server/test/Server.test.ts | 13 +++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/server/README.md b/packages/server/README.md index f1649c9f..a02f2736 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -68,6 +68,10 @@ Return a relative URL as the `Location` header to the client (`boolean`). Allow `Forwarded`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers to override the `Location` header returned by the server (`boolean`). +#### `options.allowedHeaders` + +Additional headers sent in `Access-Control-Allow-Headers` (`string[]`). + #### `options.namingFunction` Control how you want to name files (`(req) => string`) diff --git a/packages/server/src/handlers/OptionsHandler.ts b/packages/server/src/handlers/OptionsHandler.ts index 8b2b5087..00af77f8 100644 --- a/packages/server/src/handlers/OptionsHandler.ts +++ b/packages/server/src/handlers/OptionsHandler.ts @@ -1,5 +1,5 @@ import {BaseHandler} from './BaseHandler' -import {ALLOWED_METHODS, ALLOWED_HEADERS, MAX_AGE} from '../constants' +import {ALLOWED_METHODS, MAX_AGE, HEADERS} from '../constants' import type http from 'node:http' @@ -7,8 +7,10 @@ import type http from 'node:http' // the Tus-Version header. It MAY include the Tus-Extension and Tus-Max-Size headers. export class OptionsHandler extends BaseHandler { async send(_: http.IncomingMessage, res: http.ServerResponse) { + const allowedHeaders = [...HEADERS, ...(this.options.allowedHeaders ?? [])] + res.setHeader('Access-Control-Allow-Methods', ALLOWED_METHODS) - res.setHeader('Access-Control-Allow-Headers', ALLOWED_HEADERS) + res.setHeader('Access-Control-Allow-Headers', allowedHeaders.join(', ')) res.setHeader('Access-Control-Max-Age', MAX_AGE) if (this.store.extensions.length > 0) { res.setHeader('Tus-Extension', this.store.extensions.join(',')) diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts index 1a41313d..3991fb8c 100644 --- a/packages/server/src/types.ts +++ b/packages/server/src/types.ts @@ -10,6 +10,8 @@ export type ServerOptions = { // Allow `Forwarded`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers // to override the `Location` header returned by the server. respectForwardedHeaders?: boolean + // adds custom headers sent in `Access-Control-Allow-Headers`. + allowedHeaders?: string[] // Control how you want to name files. // It is important to make these unique to prevent data loss. Only use it if you really need to. // Default uses `crypto.randomBytes(16).toString('hex')`. diff --git a/packages/server/test/Server.test.ts b/packages/server/test/Server.test.ts index 41db8313..1e8694dd 100644 --- a/packages/server/test/Server.test.ts +++ b/packages/server/test/Server.test.ts @@ -145,6 +145,19 @@ describe('Server', () => { }) }) + it('OPTIONS should return returns custom headers in Access-Control-Allow-Headers', (done) => { + server.options.allowedHeaders = ['Custom-Header'] + + request(listener) + .options('/') + .expect(204, '', (err, res) => { + res.headers.should.have.property('access-control-allow-headers') + res.headers['access-control-allow-headers'].should.containEql('Custom-Header') + server.options.allowedHeaders = [] + done(err) + }) + }) + it('HEAD should 404 non files', (done) => { request(listener) .head('/')