strong-error-handler 5.0.2 → 5.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- name: "CodeQL"
1
+ name: CodeQL
2
2
 
3
3
  on:
4
4
  push:
@@ -9,20 +9,36 @@ on:
9
9
  schedule:
10
10
  - cron: '0 13 * * 6'
11
11
 
12
+ permissions: {}
13
+
12
14
  jobs:
13
15
  analyze:
14
16
  name: Analyze
15
17
  runs-on: ubuntu-latest
18
+ permissions:
19
+ security-events: write
20
+ actions: read
16
21
 
17
22
  steps:
23
+ - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
24
+ with:
25
+ disable-sudo: true
26
+ egress-policy: block
27
+ allowed-endpoints: >
28
+ api.github.com:443
29
+ github.com:443
30
+
18
31
  - name: Checkout repository
19
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
32
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
33
+ with:
34
+ persist-credentials: false
20
35
 
21
36
  - name: Initialize CodeQL
22
- uses: github/codeql-action/init@v2
37
+ uses: github/codeql-action/init@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
23
38
  with:
24
- languages: 'javascript'
25
- config-file: ./.github/codeql/codeql-config.yml
39
+ languages: javascript-typescript
40
+ config-file: .github/codeql/codeql-config.yml
26
41
 
27
42
  - name: Perform CodeQL Analysis
28
- uses: github/codeql-action/analyze@v2
43
+ uses: github/codeql-action/analyze@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
44
+
@@ -9,34 +9,49 @@ on:
9
9
  schedule:
10
10
  - cron: '0 2 * * 1' # At 02:00 on Monday
11
11
 
12
- env:
13
- NODE_OPTIONS: --max-old-space-size=4096
12
+ permissions: {}
14
13
 
15
14
  jobs:
16
15
  test:
17
16
  name: Test
18
- timeout-minutes: 15
17
+ timeout-minutes: 5
19
18
  strategy:
20
19
  matrix:
21
20
  os: [ubuntu-latest]
22
- node-version: [16, 18]
21
+ node-version:
22
+ - 16
23
+ - 18
24
+ - 20
25
+ - 21
23
26
  include:
24
27
  - os: macos-latest
25
- node-version: 16 # LTS
28
+ node-version: 20 # LTS
29
+ - os: windows-latest
30
+ node-version: 20 # LTS
26
31
  fail-fast: false
27
32
  runs-on: ${{ matrix.os }}
28
33
  steps:
29
- - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
34
+ - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
35
+ if: ${{ matrix.os == 'ubuntu-latest' }}
30
36
  with:
31
- fetch-depth: 0
37
+ disable-sudo: true
38
+ egress-policy: block
39
+ allowed-endpoints: >
40
+ api.github.com:443
41
+ github.com:443
42
+ nodejs.org:443
43
+ registry.npmjs.org:443
44
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
45
+ with:
46
+ persist-credentials: false
32
47
  - name: Use Node.js ${{ matrix.node-version }}
33
- uses: actions/setup-node@v3
48
+ uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
34
49
  with:
35
50
  node-version: ${{ matrix.node-version }}
51
+ cache: npm
36
52
  - name: Bootstrap project
37
- run: |
38
- npm ci --ignore-scripts
39
- - uses: Yuri6037/Action-FakeTTY@v1.1
53
+ run: npm ci --ignore-scripts --prefer-offline
54
+ - uses: Yuri6037/Action-FakeTTY@1abc69c7d530815855caedcd73842bae5687c1a6 # v1.1
40
55
  - name: Run tests
41
56
  run: faketty npm test --ignore-scripts
42
57
 
@@ -44,31 +59,102 @@ jobs:
44
59
  name: Code Lint
45
60
  runs-on: ubuntu-latest
46
61
  steps:
47
- - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
48
- - name: Use Node.js 16
49
- uses: actions/setup-node@v3
62
+ - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
63
+ with:
64
+ disable-sudo: true
65
+ egress-policy: block
66
+ allowed-endpoints: >
67
+ api.github.com:443
68
+ github.com:443
69
+ nodejs.org:443
70
+ registry.npmjs.org:443
71
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
72
+ with:
73
+ persist-credentials: false
74
+ - name: Use Node.js 20
75
+ uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
50
76
  with:
51
- node-version: 16
77
+ node-version: 20
78
+ cache: 'npm'
52
79
  - name: Bootstrap project
53
80
  run: |
54
- npm ci --ignore-scripts
81
+ npm ci \
82
+ --ignore-scripts \
83
+ --prefer-offline
55
84
  - name: Verify code linting
56
- run: npm run lint
85
+ run: npm run lint --ignore-scripts
57
86
 
58
87
  commit-lint:
59
88
  name: Commit Lint
60
89
  runs-on: ubuntu-latest
61
90
  if: ${{ github.event.pull_request }}
62
91
  steps:
63
- - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
92
+ - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
93
+ with:
94
+ disable-sudo: true
95
+ egress-policy: block
96
+ allowed-endpoints: >
97
+ github.com:443
98
+ registry.npmjs.org:443
99
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
64
100
  with:
65
101
  fetch-depth: 0
66
- - name: Use Node.js 16
67
- uses: actions/setup-node@v3
102
+ persist-credentials: false
103
+ - name: Use Node.js 20
104
+ uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
105
+ with:
106
+ node-version: 20
107
+ cache: npm
108
+ - name: Bootstrap project
109
+ run: |
110
+ npm ci \
111
+ --ignore-scripts \
112
+ --prefer-offline
113
+ - name: Verify commit linting
114
+ run: |
115
+ npm exec \
116
+ --no-install \
117
+ --package=@commitlint/cli \
118
+ -- \
119
+ commitlint \
120
+ --from=origin/master \
121
+ --to=HEAD \
122
+ --verbose
123
+
124
+ lockfile-lint:
125
+ name: Lockfile Lint
126
+ runs-on: ubuntu-latest
127
+ steps:
128
+ - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
68
129
  with:
69
- node-version: 16
130
+ disable-sudo: true
131
+ egress-policy: block
132
+ allowed-endpoints: >
133
+ github.com:443
134
+ registry.npmjs.org:443
135
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
136
+ with:
137
+ persist-credentials: false
138
+ - name: Use Node.js 20
139
+ uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
140
+ with:
141
+ node-version: 20
142
+ cache: npm
70
143
  - name: Bootstrap project
71
144
  run: |
72
- npm ci --ignore-scripts
145
+ npm ci \
146
+ --ignore-scripts \
147
+ --prefer-offline
73
148
  - name: Verify commit linting
74
- run: npx commitlint --from origin/master --to HEAD --verbose
149
+ run: |
150
+ npm exec \
151
+ --no-install \
152
+ --package=lockfile-lint \
153
+ -- \
154
+ lockfile-lint \
155
+ --path=package-lock.json \
156
+ --allowed-hosts=npm \
157
+ --validate-https \
158
+ --validate-integrity \
159
+ --validate-package-names
160
+
@@ -0,0 +1,78 @@
1
+ # Based on `scorecard.yml` Github Actions starter workflow:
2
+ # https://github.com/actions/starter-workflows/blob/b1df8a546ed4d0f27d46aaf2f8ac1118bc522638/code-scanning/scorecard.yml
3
+
4
+ # This is separate from the CI workflow due to certain restrictions imposed by the GitHub Action action:
5
+ # https://github.com/ossf/scorecard-action/tree/99cc02c8ee27bab5f5f41e79066e0de91d313dec#workflow-restrictions
6
+ # For consistency, we should keep it a separate workflow across all our Github repositories, regardless if it's actually needed.
7
+
8
+ name: OSSF Scorecard
9
+ on:
10
+ # For Branch-Protection check. Only the default branch is supported. See
11
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
12
+ branch_protection_rule: {}
13
+ # To guarantee Maintained check is occasionally updated. See
14
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
15
+ schedule:
16
+ - cron: '30 6 * * 5'
17
+ push:
18
+ branches: [master]
19
+
20
+ # Declare default permissions as read only.
21
+ # permissions: read-all
22
+ permissions: {}
23
+
24
+ jobs:
25
+ analysis:
26
+ name: Scorecard analysis
27
+ runs-on: ubuntu-latest
28
+ permissions:
29
+ # Needed to upload the results to code-scanning dashboard.
30
+ security-events: write
31
+ # Needed to publish results and get a badge (see publish_results below).
32
+ id-token: write
33
+
34
+ steps:
35
+ - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
36
+ if: ${{ matrix.os == 'ubuntu-latest' }}
37
+ with:
38
+ disable-sudo: true
39
+ egress-policy: block
40
+ allowed-endpoints: >
41
+ api.github.com:443
42
+ api.osv.dev:443
43
+ api.securityscorecards.dev:443
44
+ fulcio.sigstore.dev:443
45
+ github.com:443
46
+ oss-fuzz-build-logs.storage.googleapis.com:443
47
+ rekor.sigstore.dev:443
48
+ tuf-repo-cdn.sigstore.dev:443
49
+ www.bestpractices.dev:443
50
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
51
+ with:
52
+ persist-credentials: false
53
+
54
+ - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
55
+ with:
56
+ results_file: results.sarif
57
+ results_format: sarif
58
+ # Public repositories:
59
+ # - Publish results to OpenSSF REST API for easy access by consumers
60
+ # - Allows the repository to include the Scorecard badge.
61
+ # - See https://github.com/ossf/scorecard-action#publishing-results.
62
+ # For private repositories:
63
+ # - `publish_results` will always be set to `false`, regardless
64
+ # of the value entered here.
65
+ publish_results: true
66
+
67
+ # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
68
+ # format to the repository Actions tab.
69
+ - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
70
+ with:
71
+ name: OSSF Scorecard SARIF file
72
+ path: results.sarif
73
+ retention-days: 90
74
+
75
+ # Upload the results to GitHub's code scanning dashboard.
76
+ - uses: github/codeql-action/upload-sarif@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
77
+ with:
78
+ sarif_file: results.sarif
package/CHANGES.md CHANGED
@@ -1,3 +1,55 @@
1
+ 2023-12-07, Version 5.0.5
2
+ =========================
3
+
4
+ * chore: update github/codeql-action action to v2.22.9 (renovate[bot])
5
+
6
+ * chore: update step-security/harden-runner action to v2.6.1 (renovate[bot])
7
+
8
+ * chore: add badges (Rifa Achrinza)
9
+
10
+ * ci: further harden workflows (Rifa Achrinza)
11
+
12
+ * ci: fix Scorecard issues (Rifa Achrinza)
13
+
14
+ * chore: lock file maintenance (renovate[bot])
15
+
16
+ * chore: update dependency eslint to ^8.55.0 (renovate[bot])
17
+
18
+ * chore: update github/codeql-action action to v2.22.8 (renovate[bot])
19
+
20
+ * chore: update commitlint monorepo to ^18.4.3 (renovate[bot])
21
+
22
+ * chore: update dependency eslint to ^8.54.0 (renovate[bot])
23
+
24
+ * chore: update commitlint monorepo to ^18.4.2 (renovate[bot])
25
+
26
+ * chore: update github/codeql-action action to v2.22.7 (renovate[bot])
27
+
28
+ * chore: update github/codeql-action action to v2.22.6 (renovate[bot])
29
+
30
+ * chore: update commitlint monorepo (renovate[bot])
31
+
32
+ * fix(cve-2023-29827): replace EJS with Handlebars to resolve security warning (KalleV)
33
+
34
+ * ci: align CI configuration (Rifa Achrinza)
35
+
36
+ * chore: update dependency @types/express to ^4.17.21 (renovate[bot])
37
+
38
+ * chore: update dependency eslint to ^8.53.0 (renovate[bot])
39
+
40
+ * chore: update dependency @commitlint/config-conventional to ^18.1.0 (renovate[bot])
41
+
42
+ * chore: update dependency @commitlint/config-conventional to v18 (renovate[bot])
43
+
44
+ * chore: update dependency eslint to ^8.52.0 (renovate[bot])
45
+
46
+ * chore: update dependency @commitlint/config-conventional to ^17.8.1 (renovate[bot])
47
+
48
+ * chore: update dependency @types/express to ^4.17.20 (renovate[bot])
49
+
50
+ * chore: update dependency http-status to ^1.7.3 (renovate[bot])
51
+
52
+
1
53
  2023-10-16, Version 5.0.2
2
54
  =========================
3
55
 
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # strong-error-handler
2
2
 
3
+ [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8058/badge)](https://www.bestpractices.dev/projects/8058)
4
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/loopbackio/strong-error-handler/badge)](https://securityscorecards.dev/viewer/?uri=github.com/loopbackio/strong-error-handler)
5
+ [![Continuous Integration](https://github.com/loopbackio/strong-error-handler/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/loopbackio/strong-error-handler/actions/workflows/continuous-integration.yml)
6
+ [![CodeQL](https://github.com/loopbackio/strong-error-handler/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/loopbackio/strong-error-handler/actions/workflows/codeql-analysis.yml)
7
+
3
8
  This package is an error handler for use in both development (debug) and production environments.
4
9
 
5
10
  In production mode, `strong-error-handler` omits details from error responses to prevent leaking sensitive information:
package/lib/send-html.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  'use strict';
7
- const ejs = require('ejs');
7
+ const handlebars = require('handlebars');
8
8
  const fs = require('fs');
9
9
  const path = require('path');
10
10
 
@@ -16,6 +16,13 @@ const compiledTemplates = {
16
16
 
17
17
  module.exports = sendHtml;
18
18
 
19
+ /**
20
+ * Sends HTML response to the client.
21
+ *
22
+ * @param {Object} res - The response object.
23
+ * @param {Object} data - The data object to be rendered in the HTML.
24
+ * @param {Object} options - The options object.
25
+ */
19
26
  function sendHtml(res, data, options) {
20
27
  const toRender = {options, data};
21
28
  // TODO: ability to call non-default template functions from options
@@ -23,6 +30,35 @@ function sendHtml(res, data, options) {
23
30
  sendResponse(res, body);
24
31
  }
25
32
 
33
+ /**
34
+ * Returns the content of a Handlebars partial file as a string.
35
+ * @param {string} name - The name of the Handlebars partial file.
36
+ * @returns {string} The content of the Handlebars partial file as a string.
37
+ */
38
+ function partial(name) {
39
+ const partialPath = path.resolve(assetDir, `${name}.hbs`);
40
+ const partialContent = fs.readFileSync(partialPath, 'utf8');
41
+ return partialContent;
42
+ }
43
+
44
+ handlebars.registerHelper('partial', partial);
45
+
46
+ /**
47
+ * Checks if the given property is a standard property.
48
+ * @param {string} prop - The property to check.
49
+ * @param {Object} options - The Handlebars options object.
50
+ * @returns {string} - The result of the Handlebars template.
51
+ */
52
+ function standardProps(prop, options) {
53
+ const standardProps = ['name', 'statusCode', 'message', 'stack'];
54
+ if (standardProps.indexOf(prop) === -1) {
55
+ return options.fn(this);
56
+ }
57
+ return options.inverse(this);
58
+ }
59
+
60
+ handlebars.registerHelper('standardProps', standardProps);
61
+
26
62
  /**
27
63
  * Compile and cache the file with the `filename` key in options
28
64
  *
@@ -32,15 +68,23 @@ function sendHtml(res, data, options) {
32
68
  function compileTemplate(filepath) {
33
69
  const options = {cache: true, filename: filepath};
34
70
  const fileContent = fs.readFileSync(filepath, 'utf8');
35
- return ejs.compile(fileContent, options);
71
+ return handlebars.compile(fileContent, options);
36
72
  }
37
73
 
38
- // loads and cache default error templates
74
+ /**
75
+ * Loads the default error handlebars template from the asset directory and compiles it.
76
+ * @returns {Function} The compiled handlebars template function.
77
+ */
39
78
  function loadDefaultTemplates() {
40
- const defaultTemplate = path.resolve(assetDir, 'default-error.ejs');
79
+ const defaultTemplate = path.resolve(assetDir, 'default-error.hbs');
41
80
  return compileTemplate(defaultTemplate);
42
81
  }
43
82
 
83
+ /**
84
+ * Sends an HTML response with the given body to the provided response object.
85
+ * @param {Object} res - The response object to send the HTML response to.
86
+ * @param {string} body - The HTML body to send in the response.
87
+ */
44
88
  function sendResponse(res, body) {
45
89
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
46
90
  res.end(body);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "strong-error-handler",
3
3
  "description": "Error handler for use in development and production environments.",
4
4
  "license": "MIT",
5
- "version": "5.0.2",
5
+ "version": "5.0.5",
6
6
  "engines": {
7
7
  "node": ">=16"
8
8
  },
@@ -19,19 +19,21 @@
19
19
  "dependencies": {
20
20
  "accepts": "^1.3.8",
21
21
  "debug": "^4.3.4",
22
- "ejs": "^3.1.9",
23
22
  "fast-safe-stringify": "^2.1.1",
24
- "http-status": "^1.7.0",
23
+ "handlebars": "^4.7.8",
24
+ "http-status": "^1.7.3",
25
25
  "js2xmlparser": "^5.0.0",
26
26
  "strong-globalize": "^6.0.6"
27
27
  },
28
28
  "devDependencies": {
29
- "@commitlint/config-conventional": "^17.8.0",
30
- "@types/express": "^4.17.19",
29
+ "@commitlint/cli": "^18.4.3",
30
+ "@commitlint/config-conventional": "^18.4.3",
31
+ "@types/express": "^4.17.21",
31
32
  "chai": "^4.3.10",
32
- "eslint": "^8.51.0",
33
+ "eslint": "^8.55.0",
33
34
  "eslint-config-loopback": "^13.1.0",
34
35
  "express": "^4.18.2",
36
+ "lockfile-lint": "^4.12.1",
35
37
  "mocha": "^10.2.0",
36
38
  "supertest": "^6.3.3"
37
39
  },
@@ -0,0 +1,25 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8" />
4
+ <title>{{ data.name }}{{#unless data.name}}{{ data.message }}{{/unless}}</title>
5
+ <style>
6
+ {{partial 'style'}}
7
+ </style>
8
+ </head>
9
+ <body>
10
+ <div id="wrapper">
11
+ <h1>{{ data.name }}</h1>
12
+ <h2>
13
+ <em>{{ data.statusCode }}</em> {{ data.message }}
14
+ </h2>
15
+ {{#each data}}
16
+ {{#standardProps @key}}
17
+ <div><b>{{@key}}</b>: {{this}}</div>
18
+ {{/standardProps}}
19
+ {{/each}}
20
+ {{#if data.stack}}
21
+ <pre id="stacktrace">{{{data.stack}}}</pre>
22
+ {{/if}}
23
+ </div>
24
+ </body>
25
+ </html>
@@ -1,25 +0,0 @@
1
- <html>
2
- <head>
3
- <meta charset='utf-8'>
4
- <title><%= data.name || data.message %></title>
5
- <style><%- include('style.css') %></style>
6
- </head>
7
- <body>
8
- <div id="wrapper">
9
- <h1><%= data.name %></h1>
10
- <h2><em><%= data.statusCode %></em> <%= data.message %></h2>
11
- <%
12
- // display all the non-standard properties
13
- var standardProps = ['name', 'statusCode', 'message', 'stack'];
14
- for (var prop in data) {
15
- if (standardProps.indexOf(prop) == -1 && data[prop]) { %>
16
- <div><b><%= prop %></b>: <%= data[prop] %></div>
17
- <% }
18
- }
19
- if (data.stack) { %>
20
- <pre id="stacktrace"><%- data.stack %></pre>
21
- <% }
22
- %>
23
- </div>
24
- </body>
25
- </html>
File without changes