diff --git a/server/utils/requestUtils.js b/server/utils/requestUtils.js index f2672d977..afac4fcc0 100644 --- a/server/utils/requestUtils.js +++ b/server/utils/requestUtils.js @@ -1,12 +1,21 @@ /** * Whether the request was made over HTTPS. - * Uses Express `req.secure` and a strict `x-forwarded-proto === 'https'` check. + * Uses Express `req.secure` and `x-forwarded-proto` * * @param {import('express').Request} req * @returns {boolean} */ function isRequestSecure(req) { - return req.secure || req.get('x-forwarded-proto') === 'https' + if (req.secure) return true + const xfp = (req.get('x-forwarded-proto') || '').toLowerCase() + // Nginx Proxy Manager sends "http, https"; see https://github.com/advplyr/audiobookshelf/pull/4635 + return ( + xfp === 'https' || + xfp + .split(',') + .map((s) => s.trim()) + .includes('https') + ) } /** diff --git a/test/server/utils/requestUtils.test.js b/test/server/utils/requestUtils.test.js index ee01af5a0..589c6f1cd 100644 --- a/test/server/utils/requestUtils.test.js +++ b/test/server/utils/requestUtils.test.js @@ -19,10 +19,10 @@ describe('requestUtils', () => { expect(isRequestSecure(mockReq({ secure: false }))).to.equal(false) }) - it('isRequestSecure uses strict x-forwarded-proto check', () => { + it('isRequestSecure uses x-forwarded-proto', () => { expect(isRequestSecure(mockReq({ xForwardedProto: 'https' }))).to.equal(true) expect(isRequestSecure(mockReq({ xForwardedProto: 'http' }))).to.equal(false) - expect(isRequestSecure(mockReq({ xForwardedProto: 'http, https' }))).to.equal(false) + expect(isRequestSecure(mockReq({ xForwardedProto: 'http, https' }))).to.equal(true) }) it('getRequestProtocol returns https or http', () => {