index.cjs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. "use strict"
  2. Object.defineProperties(exports, {__esModule: {value: true}, [Symbol.toStringTag]: {value: "Module"}})
  3. const dangerouslyDisableDefaultSrc = Symbol("dangerouslyDisableDefaultSrc")
  4. const DEFAULT_DIRECTIVES = {
  5. "default-src": ["'self'"],
  6. "base-uri": ["'self'"],
  7. "font-src": ["'self'", "https:", "data:"],
  8. "form-action": ["'self'"],
  9. "frame-ancestors": ["'self'"],
  10. "img-src": ["'self'", "data:"],
  11. "object-src": ["'none'"],
  12. "script-src": ["'self'"],
  13. "script-src-attr": ["'none'"],
  14. "style-src": ["'self'", "https:", "'unsafe-inline'"],
  15. "upgrade-insecure-requests": []
  16. }
  17. const getDefaultDirectives = () => Object.assign({}, DEFAULT_DIRECTIVES)
  18. const dashify = str => str.replace(/[A-Z]/g, capitalLetter => "-" + capitalLetter.toLowerCase())
  19. const isDirectiveValueInvalid = directiveValue => /;|,/.test(directiveValue)
  20. const has = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
  21. function normalizeDirectives(options) {
  22. const defaultDirectives = getDefaultDirectives()
  23. const {useDefaults = true, directives: rawDirectives = defaultDirectives} = options
  24. const result = new Map()
  25. const directiveNamesSeen = new Set()
  26. const directivesExplicitlyDisabled = new Set()
  27. for (const rawDirectiveName in rawDirectives) {
  28. if (!has(rawDirectives, rawDirectiveName)) {
  29. continue
  30. }
  31. if (rawDirectiveName.length === 0 || /[^a-zA-Z0-9-]/.test(rawDirectiveName)) {
  32. throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(rawDirectiveName)}`)
  33. }
  34. const directiveName = dashify(rawDirectiveName)
  35. if (directiveNamesSeen.has(directiveName)) {
  36. throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(directiveName)}`)
  37. }
  38. directiveNamesSeen.add(directiveName)
  39. const rawDirectiveValue = rawDirectives[rawDirectiveName]
  40. let directiveValue
  41. if (rawDirectiveValue === null) {
  42. if (directiveName === "default-src") {
  43. throw new Error("Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.")
  44. }
  45. directivesExplicitlyDisabled.add(directiveName)
  46. continue
  47. } else if (typeof rawDirectiveValue === "string") {
  48. directiveValue = [rawDirectiveValue]
  49. } else if (!rawDirectiveValue) {
  50. throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`)
  51. } else if (rawDirectiveValue === dangerouslyDisableDefaultSrc) {
  52. if (directiveName === "default-src") {
  53. directivesExplicitlyDisabled.add("default-src")
  54. continue
  55. } else {
  56. throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(directiveName)} as if it were default-src; simply omit the key`)
  57. }
  58. } else {
  59. directiveValue = rawDirectiveValue
  60. }
  61. for (const element of directiveValue) {
  62. if (typeof element === "string" && isDirectiveValueInvalid(element)) {
  63. throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`)
  64. }
  65. }
  66. result.set(directiveName, directiveValue)
  67. }
  68. if (useDefaults) {
  69. Object.entries(defaultDirectives).forEach(([defaultDirectiveName, defaultDirectiveValue]) => {
  70. if (!result.has(defaultDirectiveName) && !directivesExplicitlyDisabled.has(defaultDirectiveName)) {
  71. result.set(defaultDirectiveName, defaultDirectiveValue)
  72. }
  73. })
  74. }
  75. if (!result.size) {
  76. throw new Error("Content-Security-Policy has no directives. Either set some or disable the header")
  77. }
  78. if (!result.has("default-src") && !directivesExplicitlyDisabled.has("default-src")) {
  79. throw new Error("Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.")
  80. }
  81. return result
  82. }
  83. function getHeaderValue(req, res, normalizedDirectives) {
  84. let err
  85. const result = []
  86. normalizedDirectives.forEach((rawDirectiveValue, directiveName) => {
  87. let directiveValue = ""
  88. for (const element of rawDirectiveValue) {
  89. directiveValue += " " + (element instanceof Function ? element(req, res) : element)
  90. }
  91. if (!directiveValue) {
  92. result.push(directiveName)
  93. } else if (isDirectiveValueInvalid(directiveValue)) {
  94. err = new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`)
  95. } else {
  96. result.push(`${directiveName}${directiveValue}`)
  97. }
  98. })
  99. return err ? err : result.join(";")
  100. }
  101. const contentSecurityPolicy = function contentSecurityPolicy(options = {}) {
  102. const headerName = options.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy"
  103. const normalizedDirectives = normalizeDirectives(options)
  104. return function contentSecurityPolicyMiddleware(req, res, next) {
  105. const result = getHeaderValue(req, res, normalizedDirectives)
  106. if (result instanceof Error) {
  107. next(result)
  108. } else {
  109. res.setHeader(headerName, result)
  110. next()
  111. }
  112. }
  113. }
  114. contentSecurityPolicy.getDefaultDirectives = getDefaultDirectives
  115. contentSecurityPolicy.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc
  116. const ALLOWED_POLICIES$2 = new Set(["require-corp", "credentialless"])
  117. function getHeaderValueFromOptions$7({policy = "require-corp"}) {
  118. if (ALLOWED_POLICIES$2.has(policy)) {
  119. return policy
  120. } else {
  121. throw new Error(`Cross-Origin-Embedder-Policy does not support the ${JSON.stringify(policy)} policy`)
  122. }
  123. }
  124. function crossOriginEmbedderPolicy(options = {}) {
  125. const headerValue = getHeaderValueFromOptions$7(options)
  126. return function crossOriginEmbedderPolicyMiddleware(_req, res, next) {
  127. res.setHeader("Cross-Origin-Embedder-Policy", headerValue)
  128. next()
  129. }
  130. }
  131. const ALLOWED_POLICIES$1 = new Set(["same-origin", "same-origin-allow-popups", "unsafe-none"])
  132. function getHeaderValueFromOptions$6({policy = "same-origin"}) {
  133. if (ALLOWED_POLICIES$1.has(policy)) {
  134. return policy
  135. } else {
  136. throw new Error(`Cross-Origin-Opener-Policy does not support the ${JSON.stringify(policy)} policy`)
  137. }
  138. }
  139. function crossOriginOpenerPolicy(options = {}) {
  140. const headerValue = getHeaderValueFromOptions$6(options)
  141. return function crossOriginOpenerPolicyMiddleware(_req, res, next) {
  142. res.setHeader("Cross-Origin-Opener-Policy", headerValue)
  143. next()
  144. }
  145. }
  146. const ALLOWED_POLICIES = new Set(["same-origin", "same-site", "cross-origin"])
  147. function getHeaderValueFromOptions$5({policy = "same-origin"}) {
  148. if (ALLOWED_POLICIES.has(policy)) {
  149. return policy
  150. } else {
  151. throw new Error(`Cross-Origin-Resource-Policy does not support the ${JSON.stringify(policy)} policy`)
  152. }
  153. }
  154. function crossOriginResourcePolicy(options = {}) {
  155. const headerValue = getHeaderValueFromOptions$5(options)
  156. return function crossOriginResourcePolicyMiddleware(_req, res, next) {
  157. res.setHeader("Cross-Origin-Resource-Policy", headerValue)
  158. next()
  159. }
  160. }
  161. function parseMaxAge$1(value = 0) {
  162. if (value >= 0 && Number.isFinite(value)) {
  163. return Math.floor(value)
  164. } else {
  165. throw new Error(`Expect-CT: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`)
  166. }
  167. }
  168. function getHeaderValueFromOptions$4(options) {
  169. const directives = [`max-age=${parseMaxAge$1(options.maxAge)}`]
  170. if (options.enforce) {
  171. directives.push("enforce")
  172. }
  173. if (options.reportUri) {
  174. directives.push(`report-uri="${options.reportUri}"`)
  175. }
  176. return directives.join(", ")
  177. }
  178. function expectCt(options = {}) {
  179. const headerValue = getHeaderValueFromOptions$4(options)
  180. return function expectCtMiddleware(_req, res, next) {
  181. res.setHeader("Expect-CT", headerValue)
  182. next()
  183. }
  184. }
  185. function originAgentCluster() {
  186. return function originAgentClusterMiddleware(_req, res, next) {
  187. res.setHeader("Origin-Agent-Cluster", "?1")
  188. next()
  189. }
  190. }
  191. const ALLOWED_TOKENS = new Set(["no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url", ""])
  192. function getHeaderValueFromOptions$3({policy = ["no-referrer"]}) {
  193. const tokens = typeof policy === "string" ? [policy] : policy
  194. if (tokens.length === 0) {
  195. throw new Error("Referrer-Policy received no policy tokens")
  196. }
  197. const tokensSeen = new Set()
  198. tokens.forEach(token => {
  199. if (!ALLOWED_TOKENS.has(token)) {
  200. throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(token)}`)
  201. } else if (tokensSeen.has(token)) {
  202. throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(token)}`)
  203. }
  204. tokensSeen.add(token)
  205. })
  206. return tokens.join(",")
  207. }
  208. function referrerPolicy(options = {}) {
  209. const headerValue = getHeaderValueFromOptions$3(options)
  210. return function referrerPolicyMiddleware(_req, res, next) {
  211. res.setHeader("Referrer-Policy", headerValue)
  212. next()
  213. }
  214. }
  215. const DEFAULT_MAX_AGE = 180 * 24 * 60 * 60
  216. function parseMaxAge(value = DEFAULT_MAX_AGE) {
  217. if (value >= 0 && Number.isFinite(value)) {
  218. return Math.floor(value)
  219. } else {
  220. throw new Error(`Strict-Transport-Security: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`)
  221. }
  222. }
  223. function getHeaderValueFromOptions$2(options) {
  224. if ("maxage" in options) {
  225. throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?")
  226. }
  227. if ("includeSubdomains" in options) {
  228. console.warn('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)')
  229. }
  230. if ("setIf" in options) {
  231. console.warn("Strict-Transport-Security middleware no longer supports the `setIf` parameter. See the documentation and <https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware> if you need help replicating this behavior.")
  232. }
  233. const directives = [`max-age=${parseMaxAge(options.maxAge)}`]
  234. if (options.includeSubDomains === undefined || options.includeSubDomains) {
  235. directives.push("includeSubDomains")
  236. }
  237. if (options.preload) {
  238. directives.push("preload")
  239. }
  240. return directives.join("; ")
  241. }
  242. function strictTransportSecurity(options = {}) {
  243. const headerValue = getHeaderValueFromOptions$2(options)
  244. return function strictTransportSecurityMiddleware(_req, res, next) {
  245. res.setHeader("Strict-Transport-Security", headerValue)
  246. next()
  247. }
  248. }
  249. function xContentTypeOptions() {
  250. return function xContentTypeOptionsMiddleware(_req, res, next) {
  251. res.setHeader("X-Content-Type-Options", "nosniff")
  252. next()
  253. }
  254. }
  255. function xDnsPrefetchControl(options = {}) {
  256. const headerValue = options.allow ? "on" : "off"
  257. return function xDnsPrefetchControlMiddleware(_req, res, next) {
  258. res.setHeader("X-DNS-Prefetch-Control", headerValue)
  259. next()
  260. }
  261. }
  262. function xDownloadOptions() {
  263. return function xDownloadOptionsMiddleware(_req, res, next) {
  264. res.setHeader("X-Download-Options", "noopen")
  265. next()
  266. }
  267. }
  268. function getHeaderValueFromOptions$1({action = "sameorigin"}) {
  269. const normalizedAction = typeof action === "string" ? action.toUpperCase() : action
  270. switch (normalizedAction) {
  271. case "SAME-ORIGIN":
  272. return "SAMEORIGIN"
  273. case "DENY":
  274. case "SAMEORIGIN":
  275. return normalizedAction
  276. default:
  277. throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(action)}`)
  278. }
  279. }
  280. function xFrameOptions(options = {}) {
  281. const headerValue = getHeaderValueFromOptions$1(options)
  282. return function xFrameOptionsMiddleware(_req, res, next) {
  283. res.setHeader("X-Frame-Options", headerValue)
  284. next()
  285. }
  286. }
  287. const ALLOWED_PERMITTED_POLICIES = new Set(["none", "master-only", "by-content-type", "all"])
  288. function getHeaderValueFromOptions({permittedPolicies = "none"}) {
  289. if (ALLOWED_PERMITTED_POLICIES.has(permittedPolicies)) {
  290. return permittedPolicies
  291. } else {
  292. throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(permittedPolicies)}`)
  293. }
  294. }
  295. function xPermittedCrossDomainPolicies(options = {}) {
  296. const headerValue = getHeaderValueFromOptions(options)
  297. return function xPermittedCrossDomainPoliciesMiddleware(_req, res, next) {
  298. res.setHeader("X-Permitted-Cross-Domain-Policies", headerValue)
  299. next()
  300. }
  301. }
  302. function xPoweredBy() {
  303. return function xPoweredByMiddleware(_req, res, next) {
  304. res.removeHeader("X-Powered-By")
  305. next()
  306. }
  307. }
  308. function xXssProtection() {
  309. return function xXssProtectionMiddleware(_req, res, next) {
  310. res.setHeader("X-XSS-Protection", "0")
  311. next()
  312. }
  313. }
  314. function getMiddlewareFunctionsFromOptions(options) {
  315. var _a, _b, _c, _d, _e, _f, _g, _h
  316. const result = []
  317. switch (options.contentSecurityPolicy) {
  318. case undefined:
  319. case true:
  320. result.push(contentSecurityPolicy())
  321. break
  322. case false:
  323. break
  324. default:
  325. result.push(contentSecurityPolicy(options.contentSecurityPolicy))
  326. break
  327. }
  328. switch (options.crossOriginEmbedderPolicy) {
  329. case undefined:
  330. case true:
  331. result.push(crossOriginEmbedderPolicy())
  332. break
  333. case false:
  334. break
  335. default:
  336. result.push(crossOriginEmbedderPolicy(options.crossOriginEmbedderPolicy))
  337. break
  338. }
  339. switch (options.crossOriginOpenerPolicy) {
  340. case undefined:
  341. case true:
  342. result.push(crossOriginOpenerPolicy())
  343. break
  344. case false:
  345. break
  346. default:
  347. result.push(crossOriginOpenerPolicy(options.crossOriginOpenerPolicy))
  348. break
  349. }
  350. switch (options.crossOriginResourcePolicy) {
  351. case undefined:
  352. case true:
  353. result.push(crossOriginResourcePolicy())
  354. break
  355. case false:
  356. break
  357. default:
  358. result.push(crossOriginResourcePolicy(options.crossOriginResourcePolicy))
  359. break
  360. }
  361. switch (options.expectCt) {
  362. case undefined:
  363. case false:
  364. break
  365. case true:
  366. result.push(expectCt())
  367. break
  368. default:
  369. result.push(expectCt(options.expectCt))
  370. break
  371. }
  372. switch (options.originAgentCluster) {
  373. case undefined:
  374. case true:
  375. result.push(originAgentCluster())
  376. break
  377. case false:
  378. break
  379. default:
  380. console.warn("Origin-Agent-Cluster does not take options. Remove the property to silence this warning.")
  381. result.push(originAgentCluster())
  382. break
  383. }
  384. switch (options.referrerPolicy) {
  385. case undefined:
  386. case true:
  387. result.push(referrerPolicy())
  388. break
  389. case false:
  390. break
  391. default:
  392. result.push(referrerPolicy(options.referrerPolicy))
  393. break
  394. }
  395. if ("strictTransportSecurity" in options && "hsts" in options) {
  396. throw new Error("Strict-Transport-Security option was specified twice. Remove `hsts` to silence this warning.")
  397. }
  398. const strictTransportSecurityOption = (_a = options.strictTransportSecurity) !== null && _a !== void 0 ? _a : options.hsts
  399. switch (strictTransportSecurityOption) {
  400. case undefined:
  401. case true:
  402. result.push(strictTransportSecurity())
  403. break
  404. case false:
  405. break
  406. default:
  407. result.push(strictTransportSecurity(strictTransportSecurityOption))
  408. break
  409. }
  410. if ("xContentTypeOptions" in options && "noSniff" in options) {
  411. throw new Error("X-Content-Type-Options option was specified twice. Remove `noSniff` to silence this warning.")
  412. }
  413. const xContentTypeOptionsOption = (_b = options.xContentTypeOptions) !== null && _b !== void 0 ? _b : options.noSniff
  414. switch (xContentTypeOptionsOption) {
  415. case undefined:
  416. case true:
  417. result.push(xContentTypeOptions())
  418. break
  419. case false:
  420. break
  421. default:
  422. console.warn("X-Content-Type-Options does not take options. Remove the property to silence this warning.")
  423. result.push(xContentTypeOptions())
  424. break
  425. }
  426. if ("xDnsPrefetchControl" in options && "dnsPrefetchControl" in options) {
  427. throw new Error("X-DNS-Prefetch-Control option was specified twice. Remove `dnsPrefetchControl` to silence this warning.")
  428. }
  429. const xDnsPrefetchControlOption = (_c = options.xDnsPrefetchControl) !== null && _c !== void 0 ? _c : options.dnsPrefetchControl
  430. switch (xDnsPrefetchControlOption) {
  431. case undefined:
  432. case true:
  433. result.push(xDnsPrefetchControl())
  434. break
  435. case false:
  436. break
  437. default:
  438. result.push(xDnsPrefetchControl(xDnsPrefetchControlOption))
  439. break
  440. }
  441. if ("xDownloadOptions" in options && "ieNoOpen" in options) {
  442. throw new Error("X-Download-Options option was specified twice. Remove `ieNoOpen` to silence this warning.")
  443. }
  444. const xDownloadOptionsOption = (_d = options.xDownloadOptions) !== null && _d !== void 0 ? _d : options.ieNoOpen
  445. switch (xDownloadOptionsOption) {
  446. case undefined:
  447. case true:
  448. result.push(xDownloadOptions())
  449. break
  450. case false:
  451. break
  452. default:
  453. console.warn("X-Download-Options does not take options. Remove the property to silence this warning.")
  454. result.push(xDownloadOptions())
  455. break
  456. }
  457. if ("xFrameOptions" in options && "frameguard" in options) {
  458. throw new Error("X-Frame-Options option was specified twice. Remove `frameguard` to silence this warning.")
  459. }
  460. const xFrameOptionsOption = (_e = options.xFrameOptions) !== null && _e !== void 0 ? _e : options.frameguard
  461. switch (xFrameOptionsOption) {
  462. case undefined:
  463. case true:
  464. result.push(xFrameOptions())
  465. break
  466. case false:
  467. break
  468. default:
  469. result.push(xFrameOptions(xFrameOptionsOption))
  470. break
  471. }
  472. if ("xPermittedCrossDomainPolicies" in options && "permittedCrossDomainPolicies" in options) {
  473. throw new Error("X-Permitted-Cross-Domain-Policies option was specified twice. Remove `permittedCrossDomainPolicies` to silence this warning.")
  474. }
  475. const xPermittedCrossDomainPoliciesOption = (_f = options.xPermittedCrossDomainPolicies) !== null && _f !== void 0 ? _f : options.permittedCrossDomainPolicies
  476. switch (xPermittedCrossDomainPoliciesOption) {
  477. case undefined:
  478. case true:
  479. result.push(xPermittedCrossDomainPolicies())
  480. break
  481. case false:
  482. break
  483. default:
  484. result.push(xPermittedCrossDomainPolicies(xPermittedCrossDomainPoliciesOption))
  485. break
  486. }
  487. if ("xPoweredBy" in options && "hidePoweredBy" in options) {
  488. throw new Error("X-Powered-By option was specified twice. Remove `hidePoweredBy` to silence this warning.")
  489. }
  490. const xPoweredByOption = (_g = options.xPoweredBy) !== null && _g !== void 0 ? _g : options.hidePoweredBy
  491. switch (xPoweredByOption) {
  492. case undefined:
  493. case true:
  494. result.push(xPoweredBy())
  495. break
  496. case false:
  497. break
  498. default:
  499. console.warn("X-Powered-By does not take options. Remove the property to silence this warning.")
  500. result.push(xPoweredBy())
  501. break
  502. }
  503. if ("xXssProtection" in options && "xssFilter" in options) {
  504. throw new Error("X-XSS-Protection option was specified twice. Remove `xssFilter` to silence this warning.")
  505. }
  506. const xXssProtectionOption = (_h = options.xXssProtection) !== null && _h !== void 0 ? _h : options.xssFilter
  507. switch (xXssProtectionOption) {
  508. case undefined:
  509. case true:
  510. result.push(xXssProtection())
  511. break
  512. case false:
  513. break
  514. default:
  515. console.warn("X-XSS-Protection does not take options. Remove the property to silence this warning.")
  516. result.push(xXssProtection())
  517. break
  518. }
  519. return result
  520. }
  521. const helmet = Object.assign(
  522. function helmet(options = {}) {
  523. var _a
  524. // People should be able to pass an options object with no prototype,
  525. // so we want this optional chaining.
  526. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  527. if (((_a = options.constructor) === null || _a === void 0 ? void 0 : _a.name) === "IncomingMessage") {
  528. throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.")
  529. }
  530. const middlewareFunctions = getMiddlewareFunctionsFromOptions(options)
  531. return function helmetMiddleware(req, res, next) {
  532. let middlewareIndex = 0
  533. ;(function internalNext(err) {
  534. if (err) {
  535. next(err)
  536. return
  537. }
  538. const middlewareFunction = middlewareFunctions[middlewareIndex]
  539. if (middlewareFunction) {
  540. middlewareIndex++
  541. middlewareFunction(req, res, internalNext)
  542. } else {
  543. next()
  544. }
  545. })()
  546. }
  547. },
  548. {
  549. contentSecurityPolicy,
  550. crossOriginEmbedderPolicy,
  551. crossOriginOpenerPolicy,
  552. crossOriginResourcePolicy,
  553. expectCt,
  554. originAgentCluster,
  555. referrerPolicy,
  556. strictTransportSecurity,
  557. xContentTypeOptions,
  558. xDnsPrefetchControl,
  559. xDownloadOptions,
  560. xFrameOptions,
  561. xPermittedCrossDomainPolicies,
  562. xPoweredBy,
  563. xXssProtection,
  564. // Legacy aliases
  565. dnsPrefetchControl: xDnsPrefetchControl,
  566. xssFilter: xXssProtection,
  567. permittedCrossDomainPolicies: xPermittedCrossDomainPolicies,
  568. ieNoOpen: xDownloadOptions,
  569. noSniff: xContentTypeOptions,
  570. frameguard: xFrameOptions,
  571. hidePoweredBy: xPoweredBy,
  572. hsts: strictTransportSecurity
  573. }
  574. )
  575. exports.contentSecurityPolicy = contentSecurityPolicy
  576. exports.crossOriginEmbedderPolicy = crossOriginEmbedderPolicy
  577. exports.crossOriginOpenerPolicy = crossOriginOpenerPolicy
  578. exports.crossOriginResourcePolicy = crossOriginResourcePolicy
  579. exports.default = helmet
  580. exports.dnsPrefetchControl = xDnsPrefetchControl
  581. exports.expectCt = expectCt
  582. exports.frameguard = xFrameOptions
  583. exports.hidePoweredBy = xPoweredBy
  584. exports.hsts = strictTransportSecurity
  585. exports.ieNoOpen = xDownloadOptions
  586. exports.noSniff = xContentTypeOptions
  587. exports.originAgentCluster = originAgentCluster
  588. exports.permittedCrossDomainPolicies = xPermittedCrossDomainPolicies
  589. exports.referrerPolicy = referrerPolicy
  590. exports.strictTransportSecurity = strictTransportSecurity
  591. exports.xContentTypeOptions = xContentTypeOptions
  592. exports.xDnsPrefetchControl = xDnsPrefetchControl
  593. exports.xDownloadOptions = xDownloadOptions
  594. exports.xFrameOptions = xFrameOptions
  595. exports.xPermittedCrossDomainPolicies = xPermittedCrossDomainPolicies
  596. exports.xPoweredBy = xPoweredBy
  597. exports.xXssProtection = xXssProtection
  598. exports.xssFilter = xXssProtection
  599. module.exports = helmet
  600. module.exports.default = helmet