@fabasoad/sarif-to-slack 0.2.5 → 1.0.0
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.
- package/.github/workflows/release.yml +1 -1
- package/.github/workflows/security.yml +0 -1
- package/.github/workflows/send-sarif-to-slack.yml +145 -73
- package/.gitleaksignore +8 -0
- package/.pre-commit-config.yaml +3 -3
- package/.tool-versions +1 -1
- package/dist/Logger.js +4 -1
- package/dist/SarifToSlackClient.d.ts +33 -0
- package/dist/SarifToSlackClient.d.ts.map +1 -0
- package/dist/SarifToSlackClient.js +178 -0
- package/dist/SlackMessageBuilder.js +34 -82
- package/dist/System.d.ts +1 -3
- package/dist/System.d.ts.map +1 -1
- package/dist/System.js +10 -3
- package/dist/index.cjs +840 -472
- package/dist/index.d.ts +35 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -12
- package/dist/model/Color.d.ts +70 -0
- package/dist/model/Color.d.ts.map +1 -0
- package/dist/model/Color.js +119 -0
- package/dist/model/Finding.d.ts +2 -0
- package/dist/model/Finding.d.ts.map +1 -0
- package/dist/model/Finding.js +93 -0
- package/dist/model/FindingsArray.d.ts +2 -0
- package/dist/model/FindingsArray.d.ts.map +1 -0
- package/dist/model/FindingsArray.js +24 -0
- package/dist/processors/CodeQLProcessor.d.ts +2 -0
- package/dist/processors/CodeQLProcessor.d.ts.map +1 -0
- package/dist/processors/CodeQLProcessor.js +17 -0
- package/dist/processors/CommonProcessor.d.ts +2 -0
- package/dist/processors/CommonProcessor.d.ts.map +1 -0
- package/dist/processors/CommonProcessor.js +84 -0
- package/dist/processors/ProcessorFactory.d.ts +2 -0
- package/dist/processors/ProcessorFactory.d.ts.map +1 -0
- package/dist/processors/ProcessorFactory.js +22 -0
- package/dist/processors/SnykProcessor.d.ts +2 -0
- package/dist/processors/SnykProcessor.d.ts.map +1 -0
- package/dist/processors/SnykProcessor.js +18 -0
- package/dist/representations/CompactGroupByRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRepresentation.js +58 -0
- package/dist/representations/CompactGroupByRunPerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRunPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRunPerLevelRepresentation.js +13 -0
- package/dist/representations/CompactGroupByRunPerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRunPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRunPerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactGroupByRunRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByRunRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByRunRepresentation.js +39 -0
- package/dist/representations/CompactGroupBySarifPerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupBySarifPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupBySarifPerLevelRepresentation.js +13 -0
- package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupBySarifPerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactGroupBySarifRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupBySarifRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupBySarifRepresentation.js +40 -0
- package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByToolNamePerLevelRepresentation.js +13 -0
- package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByToolNamePerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactGroupByToolNameRepresentation.d.ts +2 -0
- package/dist/representations/CompactGroupByToolNameRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactGroupByToolNameRepresentation.js +39 -0
- package/dist/representations/CompactTotalPerLevelRepresentation.d.ts +2 -0
- package/dist/representations/CompactTotalPerLevelRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactTotalPerLevelRepresentation.js +13 -0
- package/dist/representations/CompactTotalPerSeverityRepresentation.d.ts +2 -0
- package/dist/representations/CompactTotalPerSeverityRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactTotalPerSeverityRepresentation.js +13 -0
- package/dist/representations/CompactTotalRepresentation.d.ts +2 -0
- package/dist/representations/CompactTotalRepresentation.d.ts.map +1 -0
- package/dist/representations/CompactTotalRepresentation.js +25 -0
- package/dist/representations/Representation.d.ts +2 -0
- package/dist/representations/Representation.d.ts.map +1 -0
- package/dist/representations/Representation.js +28 -0
- package/dist/representations/RepresentationFactory.d.ts +2 -0
- package/dist/representations/RepresentationFactory.d.ts.map +1 -0
- package/dist/representations/RepresentationFactory.js +37 -0
- package/dist/sarif-to-slack.d.ts +337 -85
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types.d.ts +215 -51
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +225 -33
- package/dist/utils/Comparators.d.ts +2 -0
- package/dist/utils/Comparators.d.ts.map +1 -0
- package/dist/utils/Comparators.js +18 -0
- package/dist/utils/ExtendedArray.d.ts +2 -0
- package/dist/utils/ExtendedArray.d.ts.map +1 -0
- package/dist/utils/ExtendedArray.js +11 -0
- package/dist/utils/FileUtils.d.ts +2 -0
- package/dist/utils/FileUtils.d.ts.map +1 -0
- package/dist/utils/FileUtils.js +51 -0
- package/dist/utils/SarifUtils.js +20 -54
- package/etc/sarif-to-slack.api.md +161 -99
- package/jest.config.json +2 -2
- package/package.json +7 -7
- package/scripts/save-metadata.sh +12 -10
- package/src/Logger.ts +4 -0
- package/src/SarifToSlackClient.ts +202 -0
- package/src/SlackMessageBuilder.ts +35 -115
- package/src/System.ts +9 -2
- package/src/index.ts +47 -20
- package/src/model/Color.ts +201 -0
- package/src/model/Finding.ts +137 -0
- package/src/model/FindingsArray.ts +27 -0
- package/src/processors/CodeQLProcessor.ts +19 -0
- package/src/processors/CommonProcessor.ts +103 -0
- package/src/processors/ProcessorFactory.ts +23 -0
- package/src/processors/SnykProcessor.ts +19 -0
- package/src/representations/CompactGroupByRepresentation.ts +67 -0
- package/src/representations/CompactGroupByRunPerLevelRepresentation.ts +14 -0
- package/src/representations/CompactGroupByRunPerSeverityRepresentation.ts +14 -0
- package/src/representations/CompactGroupByRunRepresentation.ts +44 -0
- package/src/representations/CompactGroupBySarifPerLevelRepresentation.ts +15 -0
- package/src/representations/CompactGroupBySarifPerSeverityRepresentation.ts +15 -0
- package/src/representations/CompactGroupBySarifRepresentation.ts +45 -0
- package/src/representations/CompactGroupByToolNamePerLevelRepresentation.ts +15 -0
- package/src/representations/CompactGroupByToolNamePerSeverityRepresentation.ts +15 -0
- package/src/representations/CompactGroupByToolNameRepresentation.ts +44 -0
- package/src/representations/CompactTotalPerLevelRepresentation.ts +14 -0
- package/src/representations/CompactTotalPerSeverityRepresentation.ts +14 -0
- package/src/representations/CompactTotalRepresentation.ts +27 -0
- package/src/representations/Representation.ts +35 -0
- package/src/representations/RepresentationFactory.ts +49 -0
- package/src/types.ts +270 -53
- package/src/utils/Comparators.ts +19 -0
- package/src/utils/ExtendedArray.ts +11 -0
- package/src/utils/FileUtils.ts +60 -0
- package/src/utils/SarifUtils.ts +20 -72
- package/test-data/sarif/codeql-python.sarif +1448 -1
- package/test-data/sarif/codeql-typescript.sarif +3474 -1
- package/test-data/sarif/grype-github-actions.sarif +65 -0
- package/test-data/sarif/osv-scanner-composer.sarif +972 -0
- package/test-data/sarif/osv-scanner-container.sarif +2278 -0
- package/test-data/sarif/osv-scanner-gomodules.sarif +813 -0
- package/test-data/sarif/osv-scanner-hex.sarif +147 -0
- package/test-data/sarif/osv-scanner-maven.sarif +171 -0
- package/test-data/sarif/osv-scanner-npm.sarif +627 -0
- package/test-data/sarif/osv-scanner-pip.sarif +206 -0
- package/test-data/sarif/osv-scanner-pipenv.sarif +243 -0
- package/test-data/sarif/osv-scanner-pnpm.sarif +174 -0
- package/test-data/sarif/osv-scanner-poetry.sarif +1893 -0
- package/test-data/sarif/osv-scanner-rubygems.sarif +402 -0
- package/test-data/sarif/osv-scanner-uv.sarif +206 -0
- package/test-data/sarif/osv-scanner-yarn.sarif +5207 -0
- package/test-data/sarif/runs-0.sarif +5 -0
- package/test-data/sarif/runs-2-tools-2-results-0.sarif +1 -1
- package/test-data/sarif/runs-2-tools-2.sarif +1 -1
- package/test-data/sarif/runs-3-tools-2-results-0.sarif +1 -1
- package/test-data/sarif/runs-3-tools-2.sarif +1 -1
- package/test-data/sarif/tmp/codeql-csharp.sarif +1 -0
- package/test-data/sarif/tmp/grype-container.sarif +1774 -0
- package/test-data/sarif/tmp/runs-1-tools-1-results-0.sarif +18 -0
- package/test-data/sarif/tmp/runs-2-tools-2.sarif +686 -0
- package/test-data/sarif/trivy-iac.sarif +1 -1
- package/tests/integration/SendSarifToSlack.spec.ts +95 -27
- package/tsconfig.json +2 -0
- package/dist/Processors.d.ts +0 -2
- package/dist/Processors.d.ts.map +0 -1
- package/dist/Processors.js +0 -61
- package/dist/SarifToSlackService.d.ts +0 -39
- package/dist/SarifToSlackService.d.ts.map +0 -1
- package/dist/SarifToSlackService.js +0 -104
- package/dist/metadata.d.ts +0 -2
- package/dist/metadata.d.ts.map +0 -1
- package/dist/metadata.js +0 -11
- package/dist/model/SarifModelPerRun.d.ts +0 -2
- package/dist/model/SarifModelPerRun.d.ts.map +0 -1
- package/dist/model/SarifModelPerRun.js +0 -90
- package/dist/model/SarifModelPerSarif.d.ts +0 -2
- package/dist/model/SarifModelPerSarif.d.ts.map +0 -1
- package/dist/model/SarifModelPerSarif.js +0 -102
- package/dist/model/types.d.ts +0 -2
- package/dist/model/types.d.ts.map +0 -1
- package/dist/model/types.js +0 -49
- package/dist/utils/SortUtils.d.ts +0 -2
- package/dist/utils/SortUtils.d.ts.map +0 -1
- package/dist/utils/SortUtils.js +0 -20
- package/src/Processors.ts +0 -68
- package/src/SarifToSlackService.ts +0 -117
- package/src/metadata.ts +0 -10
- package/src/model/SarifModelPerRun.ts +0 -120
- package/src/model/SarifModelPerSarif.ts +0 -126
- package/src/model/types.ts +0 -50
- package/src/utils/SortUtils.ts +0 -33
- package/tests/Processors.spec.ts +0 -76
|
@@ -7,33 +7,48 @@ on: # yamllint disable-line rule:truthy
|
|
|
7
7
|
sarif:
|
|
8
8
|
description: SARIF to send
|
|
9
9
|
required: true
|
|
10
|
-
default: "
|
|
10
|
+
default: "OSV Scanner Yarn (Critical: 17, High: 39, Medium: 31, Low: 4, Unknown: 6)"
|
|
11
11
|
type: choice
|
|
12
12
|
options:
|
|
13
|
-
- "CodeQL C# (
|
|
14
|
-
- "CodeQL Go (
|
|
15
|
-
- "CodeQL Python (
|
|
16
|
-
- "CodeQL Ruby (
|
|
17
|
-
- "CodeQL TypeScript (
|
|
18
|
-
- "Grype Container (
|
|
19
|
-
- "
|
|
20
|
-
- "
|
|
21
|
-
- "
|
|
22
|
-
- "
|
|
23
|
-
- "
|
|
24
|
-
- "
|
|
25
|
-
- "
|
|
26
|
-
- "
|
|
27
|
-
- "
|
|
28
|
-
- "
|
|
29
|
-
- "
|
|
30
|
-
- "
|
|
31
|
-
- "
|
|
32
|
-
- "
|
|
33
|
-
- "Snyk
|
|
34
|
-
- "
|
|
35
|
-
- "
|
|
36
|
-
- "
|
|
13
|
+
- "CodeQL C# (High: 1)"
|
|
14
|
+
- "CodeQL Go (Critical: 1)"
|
|
15
|
+
- "CodeQL Python (Medium: 1)"
|
|
16
|
+
- "CodeQL Ruby (Critical: 3, High: 1)"
|
|
17
|
+
- "CodeQL TypeScript (Critical: 1)"
|
|
18
|
+
- "Grype Container (Critical: 4, High: 6, Medium: 20, Low: 9)"
|
|
19
|
+
- "Grype GitHub Actions (High: 1)"
|
|
20
|
+
- "OSV Scanner Composer (Critical: 5, High: 4, Medium: 7)"
|
|
21
|
+
- "OSV Scanner Container (Critical: 2, High: 7, Medium: 7, Low: 6, Unknown: 26)"
|
|
22
|
+
- "OSV Scanner Gomodules (Critical: 1, High: 6, Medium: 9)"
|
|
23
|
+
- "OSV Scanner Hex (Unknown: 2)"
|
|
24
|
+
- "OSV Scanner Maven (Critical: 1, Unknown: 1)"
|
|
25
|
+
- "OSV Scanner NPM (High: 4, Medium: 5, Unknown: 1)"
|
|
26
|
+
- "OSV Scanner Pip (High: 2, Unknown: 1)"
|
|
27
|
+
- "OSV Scanner Pipenv (High: 4)"
|
|
28
|
+
- "OSV Scanner PNPM (High: 2)"
|
|
29
|
+
- "OSV Scanner Poetry (High: 21, Medium: 13, Low: 2, Unknown: 1)"
|
|
30
|
+
- "OSV Scanner Rubygems (High: 4, Medium: 2)"
|
|
31
|
+
- "OSV Scanner UV (High: 2, Unknown: 1)"
|
|
32
|
+
- "OSV Scanner Yarn (Critical: 17, High: 39, Medium: 31, Low: 4, Unknown: 6)"
|
|
33
|
+
- "Snyk Composer (Critical: 4, High: 7, Medium: 5, Low: 1, None: 3)"
|
|
34
|
+
- "Snyk Container (High: 1, None: 3)"
|
|
35
|
+
- "Snyk Gomodules (High: 4, Medium: 4)"
|
|
36
|
+
- "Snyk Gradle (Critical: 2, Medium: 1, None: 1)"
|
|
37
|
+
- "Snyk Hex (Critical: 1)"
|
|
38
|
+
- "Snyk Maven (Critical: 2, Medium: 1, None: 1)"
|
|
39
|
+
- "Snyk NPM (High: 2, Medium: 6, Low: 2, None: 4)"
|
|
40
|
+
- "Snyk Nuget (High: 1)"
|
|
41
|
+
- "Snyk Pip (Medium: 1)"
|
|
42
|
+
- "Snyk PNPM (High: 1)"
|
|
43
|
+
- "Snyk Poetry (High: 5, Medium: 21, Low: 2, None: 1)"
|
|
44
|
+
- "Snyk Rubygems (High: 1, Medium: 5)"
|
|
45
|
+
- "Snyk Sbt (Medium: 1, None: 2)"
|
|
46
|
+
- "Snyk Swift (Medium: 2)"
|
|
47
|
+
- "Snyk Yarn (High: 19, Medium: 16, Low: 3, None: 11)"
|
|
48
|
+
- "Trivy IaC (High: 1, Low: 1)"
|
|
49
|
+
- "Wiz Container (Critical: 48, High: 209, Medium: 245, Low: 70)"
|
|
50
|
+
- "Wiz IaC (Medium: 5, Low: 5)"
|
|
51
|
+
- "Runs: 0"
|
|
37
52
|
- "Runs: 1, Extensions: 1, Results: 0"
|
|
38
53
|
- "Runs: 1, Extensions: 1, Results > 0"
|
|
39
54
|
- "Runs: 1, Tools: 1, Results: 0"
|
|
@@ -44,36 +59,63 @@ on: # yamllint disable-line rule:truthy
|
|
|
44
59
|
- "Runs: 3, Tools: 2, Results > 0"
|
|
45
60
|
- "Runs: 3, Tools: 2, Results: 0"
|
|
46
61
|
- "All"
|
|
47
|
-
|
|
48
|
-
description: "
|
|
62
|
+
representation:
|
|
63
|
+
description: "Representation:"
|
|
49
64
|
required: false
|
|
50
|
-
default: "
|
|
65
|
+
default: "compact-group-by-tool-name-per-severity"
|
|
51
66
|
type: choice
|
|
52
67
|
options:
|
|
53
|
-
- "
|
|
54
|
-
- "
|
|
55
|
-
- "
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
- "compact-group-by-run-per-level"
|
|
69
|
+
- "compact-group-by-run-per-severity"
|
|
70
|
+
- "compact-group-by-tool-name-per-level"
|
|
71
|
+
- "compact-group-by-tool-name-per-severity"
|
|
72
|
+
- "compact-group-by-sarif-per-level"
|
|
73
|
+
- "compact-group-by-sarif-per-severity"
|
|
74
|
+
- "compact-total-per-level"
|
|
75
|
+
- "compact-total-per-severity"
|
|
76
|
+
log-level:
|
|
77
|
+
description: "Log level:"
|
|
58
78
|
required: false
|
|
59
|
-
default: "
|
|
79
|
+
default: "info"
|
|
60
80
|
type: choice
|
|
61
81
|
options:
|
|
62
|
-
- "
|
|
63
|
-
- "
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
- "silly"
|
|
83
|
+
- "trace"
|
|
84
|
+
- "debug"
|
|
85
|
+
- "info"
|
|
86
|
+
- "warning"
|
|
87
|
+
- "error"
|
|
88
|
+
- "fatal"
|
|
89
|
+
send-if:
|
|
90
|
+
description: "Send if:"
|
|
66
91
|
required: false
|
|
67
|
-
default:
|
|
92
|
+
default: "always"
|
|
68
93
|
type: choice
|
|
69
94
|
options:
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
95
|
+
- "severity-critical"
|
|
96
|
+
- "severity-high"
|
|
97
|
+
- "severity-high-or-higher"
|
|
98
|
+
- "severity-medium"
|
|
99
|
+
- "severity-medium-or-higher"
|
|
100
|
+
- "severity-low"
|
|
101
|
+
- "severity-low-or-higher"
|
|
102
|
+
- "severity-none"
|
|
103
|
+
- "severity-none-or-higher"
|
|
104
|
+
- "severity-unknown"
|
|
105
|
+
- "severity-unknown-or-higher"
|
|
106
|
+
- "level-error"
|
|
107
|
+
- "level-warning"
|
|
108
|
+
- "level-warning-or-higher"
|
|
109
|
+
- "level-note"
|
|
110
|
+
- "level-note-or-higher"
|
|
111
|
+
- "level-none"
|
|
112
|
+
- "level-none-or-higher"
|
|
113
|
+
- "level-unknown"
|
|
114
|
+
- "level-unknown-or-higher"
|
|
115
|
+
- "always"
|
|
116
|
+
- "some"
|
|
117
|
+
- "empty"
|
|
118
|
+
- "never"
|
|
77
119
|
color:
|
|
78
120
|
description: "Slack message color (hex):"
|
|
79
121
|
required: false
|
|
@@ -120,60 +162,90 @@ jobs:
|
|
|
120
162
|
runs-on: ubuntu-latest
|
|
121
163
|
steps:
|
|
122
164
|
- name: Checkout ${{ github.repository }}
|
|
123
|
-
uses: actions/checkout@
|
|
165
|
+
uses: actions/checkout@v5
|
|
124
166
|
- name: Determine SARIF file
|
|
125
167
|
id: sarif-file
|
|
126
168
|
env:
|
|
127
169
|
INPUT_SARIF: "${{ inputs.sarif }}"
|
|
128
170
|
run: |
|
|
129
|
-
if [ "${INPUT_SARIF}" = "CodeQL C# (
|
|
171
|
+
if [ "${INPUT_SARIF}" = "CodeQL C# (High: 1)1)" ]; then
|
|
130
172
|
value="codeql-csharp.sarif"
|
|
131
|
-
elif [ "${INPUT_SARIF}" = "CodeQL Go (
|
|
173
|
+
elif [ "${INPUT_SARIF}" = "CodeQL Go (Critical: 1)" ]; then
|
|
132
174
|
value="codeql-go.sarif"
|
|
133
|
-
elif [ "${INPUT_SARIF}" = "CodeQL Python (
|
|
175
|
+
elif [ "${INPUT_SARIF}" = "CodeQL Python (Medium: 1)" ]; then
|
|
134
176
|
value="codeql-python.sarif"
|
|
135
|
-
elif [ "${INPUT_SARIF}" = "CodeQL Ruby (
|
|
177
|
+
elif [ "${INPUT_SARIF}" = "CodeQL Ruby (Critical: 3, High: 1)" ]; then
|
|
136
178
|
value="codeql-ruby.sarif"
|
|
137
|
-
elif [ "${INPUT_SARIF}" = "CodeQL TypeScript (
|
|
179
|
+
elif [ "${INPUT_SARIF}" = "CodeQL TypeScript (Critical: 1)" ]; then
|
|
138
180
|
value="codeql-typescript.sarif"
|
|
139
|
-
elif [ "${INPUT_SARIF}" = "Grype Container (
|
|
181
|
+
elif [ "${INPUT_SARIF}" = "Grype Container (Critical: 4, High: 6, Medium: 20, Low: 9)" ]; then
|
|
140
182
|
value="grype-container.sarif"
|
|
141
|
-
elif [ "${INPUT_SARIF}" = "
|
|
183
|
+
elif [ "${INPUT_SARIF}" = "Grype GitHub Actions (High: 1)" ]; then
|
|
184
|
+
value="grype-github-actions.sarif"
|
|
185
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Composer (Critical: 5, High: 4, Medium: 7)" ]; then
|
|
186
|
+
value="osv-scanner-composer.sarif"
|
|
187
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Container (Critical: 2, High: 7, Medium: 7, Low: 6, Unknown: 26)" ]; then
|
|
188
|
+
value="osv-scanner-container.sarif"
|
|
189
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Gomodules (Critical: 1, High: 6, Medium: 9)" ]; then
|
|
190
|
+
value="osv-scanner-gomodules.sarif"
|
|
191
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Hex (Unknown: 2)" ]; then
|
|
192
|
+
value="osv-scanner-hex.sarif"
|
|
193
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Maven (Critical: 1, Unknown: 1)" ]; then
|
|
194
|
+
value="osv-scanner-maven.sarif"
|
|
195
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner NPM (High: 4, Medium: 5, Unknown: 1)" ]; then
|
|
196
|
+
value="osv-scanner-npm.sarif"
|
|
197
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Pip (High: 2, Unknown: 1)" ]; then
|
|
198
|
+
value="osv-scanner-pip.sarif"
|
|
199
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Pipenv (High: 4)" ]; then
|
|
200
|
+
value="osv-scanner-pipenv.sarif"
|
|
201
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner PNPM (High: 2)" ]; then
|
|
202
|
+
value="osv-scanner-pnpm.sarif"
|
|
203
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Poetry (High: 21, Medium: 13, Low: 2, Unknown: 1)" ]; then
|
|
204
|
+
value="osv-scanner-poetry.sarif"
|
|
205
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Rubygems (High: 4, Medium: 2)" ]; then
|
|
206
|
+
value="osv-scanner-rubygems.sarif"
|
|
207
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner UV (High: 2, Unknown: 1)" ]; then
|
|
208
|
+
value="osv-scanner-uv.sarif"
|
|
209
|
+
elif [ "${INPUT_SARIF}" = "OSV Scanner Yarn (Critical: 17, High: 39, Medium: 31, Low: 4, Unknown: 6)" ]; then
|
|
210
|
+
value="osv-scanner-yarn.sarif"
|
|
211
|
+
elif [ "${INPUT_SARIF}" = "Snyk Composer (Critical: 4, High: 7, Medium: 5, Low: 1, None: 3)" ]; then
|
|
142
212
|
value="snyk-composer.sarif"
|
|
143
|
-
elif [ "${INPUT_SARIF}" = "Snyk Container (
|
|
213
|
+
elif [ "${INPUT_SARIF}" = "Snyk Container (High: 1, None: 3)" ]; then
|
|
144
214
|
value="snyk-container.sarif"
|
|
145
|
-
elif [ "${INPUT_SARIF}" = "Snyk Gomodules (
|
|
215
|
+
elif [ "${INPUT_SARIF}" = "Snyk Gomodules (High: 4, Medium: 4)" ]; then
|
|
146
216
|
value="snyk-gomodules.sarif"
|
|
147
|
-
elif [ "${INPUT_SARIF}" = "Snyk Gradle (
|
|
217
|
+
elif [ "${INPUT_SARIF}" = "Snyk Gradle (Critical: 2, Medium: 1, None: 1)" ]; then
|
|
148
218
|
value="snyk-gradle.sarif"
|
|
149
|
-
elif [ "${INPUT_SARIF}" = "Snyk Hex (
|
|
219
|
+
elif [ "${INPUT_SARIF}" = "Snyk Hex (Critical: 1)" ]; then
|
|
150
220
|
value="snyk-hex.sarif"
|
|
151
|
-
elif [ "${INPUT_SARIF}" = "Snyk Maven (
|
|
221
|
+
elif [ "${INPUT_SARIF}" = "Snyk Maven (Critical: 2, Medium: 1, None: 1)" ]; then
|
|
152
222
|
value="snyk-maven.sarif"
|
|
153
|
-
elif [ "${INPUT_SARIF}" = "Snyk NPM (
|
|
223
|
+
elif [ "${INPUT_SARIF}" = "Snyk NPM (High: 2, Medium: 6, Low: 2, None: 4)" ]; then
|
|
154
224
|
value="snyk-npm.sarif"
|
|
155
|
-
elif [ "${INPUT_SARIF}" = "Snyk Nuget (
|
|
225
|
+
elif [ "${INPUT_SARIF}" = "Snyk Nuget (High: 1)" ]; then
|
|
156
226
|
value="snyk-nuget.sarif"
|
|
157
|
-
elif [ "${INPUT_SARIF}" = "Snyk Pip (
|
|
227
|
+
elif [ "${INPUT_SARIF}" = "Snyk Pip (Medium: 1)" ]; then
|
|
158
228
|
value="snyk-pip.sarif"
|
|
159
|
-
elif [ "${INPUT_SARIF}" = "Snyk PNPM (
|
|
229
|
+
elif [ "${INPUT_SARIF}" = "Snyk PNPM (High: 1)" ]; then
|
|
160
230
|
value="snyk-pnpm.sarif"
|
|
161
|
-
elif [ "${INPUT_SARIF}" = "Snyk Poetry (
|
|
231
|
+
elif [ "${INPUT_SARIF}" = "Snyk Poetry (High: 5, Medium: 21, Low: 2, None: 1)" ]; then
|
|
162
232
|
value="snyk-poetry.sarif"
|
|
163
|
-
elif [ "${INPUT_SARIF}" = "Snyk Rubygems (
|
|
233
|
+
elif [ "${INPUT_SARIF}" = "Snyk Rubygems (High: 1, Medium: 5)" ]; then
|
|
164
234
|
value="snyk-rubygems.sarif"
|
|
165
|
-
elif [ "${INPUT_SARIF}" = "Snyk Sbt (
|
|
235
|
+
elif [ "${INPUT_SARIF}" = "Snyk Sbt (Medium: 1, None: 2)" ]; then
|
|
166
236
|
value="snyk-sbt.sarif"
|
|
167
|
-
elif [ "${INPUT_SARIF}" = "Snyk Swift (
|
|
237
|
+
elif [ "${INPUT_SARIF}" = "Snyk Swift (Medium: 2)" ]; then
|
|
168
238
|
value="snyk-swift.sarif"
|
|
169
|
-
elif [ "${INPUT_SARIF}" = "Snyk Yarn (
|
|
239
|
+
elif [ "${INPUT_SARIF}" = "Snyk Yarn (High: 19, Medium: 16, Low: 3, None: 11)" ]; then
|
|
170
240
|
value="snyk-yarn.sarif"
|
|
171
|
-
elif [ "${INPUT_SARIF}" = "Trivy IaC (
|
|
241
|
+
elif [ "${INPUT_SARIF}" = "Trivy IaC (High: 1, Low: 1)" ]; then
|
|
172
242
|
value="trivy-iac.sarif"
|
|
173
|
-
elif [ "${INPUT_SARIF}" = "Wiz Container (
|
|
243
|
+
elif [ "${INPUT_SARIF}" = "Wiz Container (Critical: 48, High: 209, Medium: 245, Low: 70)" ]; then
|
|
174
244
|
value="wiz-container.sarif"
|
|
175
|
-
elif [ "${INPUT_SARIF}" = "Wiz IaC (
|
|
245
|
+
elif [ "${INPUT_SARIF}" = "Wiz IaC (Medium: 5, Low: 5)" ]; then
|
|
176
246
|
value="wiz-iac.sarif"
|
|
247
|
+
elif [ "${INPUT_SARIF}" = "Runs: 0" ]; then
|
|
248
|
+
value="runs-0.sarif"
|
|
177
249
|
elif [ "${INPUT_SARIF}" = "Runs: 1, Extensions: 1, Results: 0" ]; then
|
|
178
250
|
value="runs-1-extensions-1-results-0.sarif"
|
|
179
251
|
elif [ "${INPUT_SARIF}" = "Runs: 1, Extensions: 1, Results > 0" ]; then
|
|
@@ -215,6 +287,6 @@ jobs:
|
|
|
215
287
|
SARIF_TO_SLACK_FOOTER: "${{ inputs.footer }}"
|
|
216
288
|
SARIF_TO_SLACK_ACTOR: "${{ inputs.actor }}"
|
|
217
289
|
SARIF_TO_SLACK_INCLUDE_RUN: "${{ inputs.include-run }}"
|
|
218
|
-
|
|
219
|
-
|
|
290
|
+
SARIF_TO_SLACK_REPRESENTATION: "${{ inputs.representation }}"
|
|
291
|
+
SARIF_TO_SLACK_SEND_IF: "${{ inputs.send-if }}"
|
|
220
292
|
run: make test/integration
|
package/.gitleaksignore
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1347
|
|
2
|
+
test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1348
|
|
3
|
+
test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1351
|
|
4
|
+
test-data/sarif/osv-scanner-poetry.sarif:curl-auth-user:1352
|
|
5
|
+
test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4181
|
|
6
|
+
test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4182
|
|
7
|
+
test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4185
|
|
8
|
+
test-data/sarif/osv-scanner-yarn.sarif:aws-access-token:4186
|
package/.pre-commit-config.yaml
CHANGED
|
@@ -60,7 +60,7 @@ repos:
|
|
|
60
60
|
- --hook-args=--log-level debug
|
|
61
61
|
stages: ["pre-push"]
|
|
62
62
|
- repo: https://github.com/google/osv-scanner
|
|
63
|
-
rev: v2.1
|
|
63
|
+
rev: v2.2.1
|
|
64
64
|
hooks:
|
|
65
65
|
- id: osv-scanner
|
|
66
66
|
args:
|
|
@@ -84,11 +84,11 @@ repos:
|
|
|
84
84
|
rev: v1.7.7
|
|
85
85
|
hooks:
|
|
86
86
|
- id: actionlint
|
|
87
|
-
args: ["-pyflakes="]
|
|
87
|
+
args: ["-pyflakes=", "-shellcheck="]
|
|
88
88
|
stages: ["pre-commit"]
|
|
89
89
|
# Other
|
|
90
90
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
91
|
-
rev:
|
|
91
|
+
rev: v6.0.0
|
|
92
92
|
hooks:
|
|
93
93
|
- id: check-merge-conflict
|
|
94
94
|
- id: check-json
|
package/.tool-versions
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
nodejs 24.
|
|
1
|
+
nodejs 24.5.0
|
package/dist/Logger.js
CHANGED
|
@@ -30,5 +30,8 @@ export default class Logger {
|
|
|
30
30
|
static debug(...args) {
|
|
31
31
|
Logger.instance.debug(...args);
|
|
32
32
|
}
|
|
33
|
+
static trace(...args) {
|
|
34
|
+
Logger.instance.trace(...args);
|
|
35
|
+
}
|
|
33
36
|
}
|
|
34
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVcsTUFBTSxJQUFJLFFBQVEsRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFjLE1BQU0sU0FBUyxDQUFBO0FBRTlDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sTUFBTTtJQUNqQixNQUFNLENBQUMsaUJBQWlCLEdBQWEsUUFBUSxDQUFDLElBQUksQ0FBQTtJQUNsRCxNQUFNLENBQUMsb0JBQW9CLEdBQVcsK0NBQStDLENBQUE7SUFDckYsTUFBTSxDQUFDLG1CQUFtQixHQUFZLElBQUksQ0FBQTtJQUUxQyxNQUFNLENBQUMsUUFBUSxDQUFtQjtJQUVuQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQWlCO1FBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDckIsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQztnQkFDN0IsSUFBSSxFQUFFLDBCQUEwQjtnQkFDaEMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLElBQUksTUFBTSxDQUFDLGlCQUFpQixDQUFDO2dCQUNoSCxJQUFJLEVBQUUsUUFBUTtnQkFDZCxpQkFBaUIsRUFBRSxLQUFLO2dCQUN4QixpQkFBaUIsRUFBRSxJQUFJLEVBQUUsUUFBUSxJQUFJLE1BQU0sQ0FBQyxvQkFBb0I7Z0JBQ2hFLGVBQWUsRUFBRSxJQUFJLEVBQUUsT0FBTyxJQUFJLE1BQU0sQ0FBQyxtQkFBbUI7YUFDN0QsQ0FBQyxDQUFBO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFTSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBZTtRQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFTSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBZTtRQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBZTtRQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQ2hDLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBZTtRQUNwQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQ2hDLENBQUMifQ==
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SarifToSlackClientOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Service to convert SARIF files to Slack messages and send them.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare class SarifToSlackClient {
|
|
7
|
+
private _message?;
|
|
8
|
+
private _sarifModel?;
|
|
9
|
+
private _sendIf;
|
|
10
|
+
private constructor();
|
|
11
|
+
private static createRunIdGenerator;
|
|
12
|
+
static create(opts: SarifToSlackClientOptions): Promise<SarifToSlackClient>;
|
|
13
|
+
private static buildModel;
|
|
14
|
+
/**
|
|
15
|
+
* The main function to initialize a list of {@link SlackMessage} objects based
|
|
16
|
+
* on the given SARIF file(s).
|
|
17
|
+
* @param sarifModel An instance of {@link SarifModel} object.
|
|
18
|
+
* @param opts An instance of {@link SarifToSlackClientOptions} object.
|
|
19
|
+
* @returns A map where key is the SARIF file and value is an instance of
|
|
20
|
+
* {@link SlackMessage} object
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
private static initialize;
|
|
24
|
+
/**
|
|
25
|
+
* Sends a Slack message.
|
|
26
|
+
* @returns A promise that resolves when the message has been sent.
|
|
27
|
+
* @throws Error if a Slack message was not prepared for the given SARIF path.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
send(): Promise<void>;
|
|
31
|
+
private get shouldSendMessage();
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=SarifToSlackClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SarifToSlackClient.d.ts","sourceRoot":"","sources":["../src/SarifToSlackClient.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,yBAAyB,EAK1B,MAAM,SAAS,CAAA;AAShB;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,CAAc;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAY;IAEhC,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO;IAKP,OAAO,CAAC,MAAM,CAAE,oBAAoB;WAOhB,MAAM,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC;mBAWnE,UAAU;IAgC/B;;;;;;;;OAQG;mBACkB,UAAU;IAyB/B;;;;;OAKG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAelC,OAAO,KAAK,iBAAiB,GAyD5B;CACF"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import Logger from './Logger';
|
|
3
|
+
import { SlackMessageBuilder } from './SlackMessageBuilder';
|
|
4
|
+
import { SecurityLevel, SecuritySeverity, SendIf } from './types';
|
|
5
|
+
import System from './System';
|
|
6
|
+
import { extractListOfFiles } from './utils/FileUtils';
|
|
7
|
+
import { createRepresentation } from './representations/RepresentationFactory';
|
|
8
|
+
import { createFinding } from './model/Finding';
|
|
9
|
+
import { findToolComponent, findToolComponentDriver } from './utils/SarifUtils';
|
|
10
|
+
import { identifyColor } from './model/Color';
|
|
11
|
+
import FindingsArray from './model/FindingsArray';
|
|
12
|
+
/**
|
|
13
|
+
* Service to convert SARIF files to Slack messages and send them.
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export class SarifToSlackClient {
|
|
17
|
+
_message;
|
|
18
|
+
_sarifModel;
|
|
19
|
+
_sendIf = SendIf.Always;
|
|
20
|
+
constructor(log) {
|
|
21
|
+
Logger.initialize(log);
|
|
22
|
+
System.initialize();
|
|
23
|
+
}
|
|
24
|
+
static *createRunIdGenerator() {
|
|
25
|
+
let runId = 1;
|
|
26
|
+
while (true) {
|
|
27
|
+
yield runId++;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
static async create(opts) {
|
|
31
|
+
const instance = new SarifToSlackClient(opts.log);
|
|
32
|
+
Logger.trace('opts', opts);
|
|
33
|
+
instance._sendIf = opts.sendIf ?? instance._sendIf;
|
|
34
|
+
instance._sarifModel = await SarifToSlackClient.buildModel(opts.sarif);
|
|
35
|
+
Logger.trace('instance._sarifModel', instance._sarifModel);
|
|
36
|
+
instance._message = await SarifToSlackClient.initialize(instance._sarifModel, opts);
|
|
37
|
+
Logger.trace('instance._message', instance._message);
|
|
38
|
+
return instance;
|
|
39
|
+
}
|
|
40
|
+
static async buildModel(sarifOpts) {
|
|
41
|
+
const sarifFiles = extractListOfFiles(sarifOpts);
|
|
42
|
+
if (sarifFiles.length === 0) {
|
|
43
|
+
throw new Error(`No SARIF files found at the provided path: ${sarifOpts.path}`);
|
|
44
|
+
}
|
|
45
|
+
const model = { sarifFiles, runs: [], findings: new FindingsArray() };
|
|
46
|
+
const runIdGenerator = SarifToSlackClient.createRunIdGenerator();
|
|
47
|
+
for (const sarifPath of sarifFiles) {
|
|
48
|
+
const sarifJson = await fs.readFile(sarifPath, 'utf8');
|
|
49
|
+
const sarifLog = JSON.parse(sarifJson);
|
|
50
|
+
for (const run of sarifLog.runs) {
|
|
51
|
+
const runId = runIdGenerator.next();
|
|
52
|
+
let runMetadata = undefined;
|
|
53
|
+
for (const result of run.results ?? []) {
|
|
54
|
+
runMetadata = {
|
|
55
|
+
id: runId.value,
|
|
56
|
+
run,
|
|
57
|
+
toolName: findToolComponent(run, result).name
|
|
58
|
+
};
|
|
59
|
+
model.findings.push(createFinding({ sarifPath, result, runMetadata }));
|
|
60
|
+
}
|
|
61
|
+
runMetadata ??= {
|
|
62
|
+
id: runId.value, run, toolName: findToolComponentDriver(run).name
|
|
63
|
+
};
|
|
64
|
+
model.runs.push(runMetadata);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return model;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The main function to initialize a list of {@link SlackMessage} objects based
|
|
71
|
+
* on the given SARIF file(s).
|
|
72
|
+
* @param sarifModel An instance of {@link SarifModel} object.
|
|
73
|
+
* @param opts An instance of {@link SarifToSlackClientOptions} object.
|
|
74
|
+
* @returns A map where key is the SARIF file and value is an instance of
|
|
75
|
+
* {@link SlackMessage} object
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
static async initialize(sarifModel, opts) {
|
|
79
|
+
const message = new SlackMessageBuilder(opts.webhookUrl, {
|
|
80
|
+
username: opts.username,
|
|
81
|
+
iconUrl: opts.iconUrl,
|
|
82
|
+
color: identifyColor(sarifModel.findings, opts.color),
|
|
83
|
+
representation: createRepresentation(sarifModel, opts.representation),
|
|
84
|
+
});
|
|
85
|
+
if (opts.header?.include) {
|
|
86
|
+
message.withHeader(opts.header?.value);
|
|
87
|
+
}
|
|
88
|
+
if (opts.footer?.include) {
|
|
89
|
+
message.withFooter(opts.footer?.value, opts.footer?.type);
|
|
90
|
+
}
|
|
91
|
+
if (opts.actor?.include) {
|
|
92
|
+
message.withActor(opts.actor?.value);
|
|
93
|
+
}
|
|
94
|
+
if (opts.run?.include) {
|
|
95
|
+
message.withRun();
|
|
96
|
+
}
|
|
97
|
+
return message;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Sends a Slack message.
|
|
101
|
+
* @returns A promise that resolves when the message has been sent.
|
|
102
|
+
* @throws Error if a Slack message was not prepared for the given SARIF path.
|
|
103
|
+
* @public
|
|
104
|
+
*/
|
|
105
|
+
async send() {
|
|
106
|
+
if (this._sarifModel == null) {
|
|
107
|
+
throw new Error('Could not parse SARIF file(s).');
|
|
108
|
+
}
|
|
109
|
+
if (this.shouldSendMessage) {
|
|
110
|
+
if (this._message == null) {
|
|
111
|
+
throw new Error('Slack message was not prepared.');
|
|
112
|
+
}
|
|
113
|
+
const text = await this._message.send();
|
|
114
|
+
Logger.info('Message sent. Status:', text);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
Logger.info('Message was not sent based on the sendIf parameter:', SendIf[this._sendIf]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
get shouldSendMessage() {
|
|
121
|
+
if (this._sendIf == null) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
switch (this._sendIf) {
|
|
125
|
+
case SendIf.SeverityCritical:
|
|
126
|
+
return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Critical) != null;
|
|
127
|
+
case SendIf.SeverityHigh:
|
|
128
|
+
return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.High) != null;
|
|
129
|
+
case SendIf.SeverityHighOrHigher:
|
|
130
|
+
return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.High);
|
|
131
|
+
case SendIf.SeverityMedium:
|
|
132
|
+
return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Medium) != null;
|
|
133
|
+
case SendIf.SeverityMediumOrHigher:
|
|
134
|
+
return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.Medium);
|
|
135
|
+
case SendIf.SeverityLow:
|
|
136
|
+
return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Low) != null;
|
|
137
|
+
case SendIf.SeverityLowOrHigher:
|
|
138
|
+
return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.Low);
|
|
139
|
+
case SendIf.SeverityNone:
|
|
140
|
+
return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.None) != null;
|
|
141
|
+
case SendIf.SeverityNoneOrHigher:
|
|
142
|
+
return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.None);
|
|
143
|
+
case SendIf.SeverityUnknown:
|
|
144
|
+
return this._sarifModel?.findings.findByProperty('severity', SecuritySeverity.Unknown) != null;
|
|
145
|
+
case SendIf.SeverityUnknownOrHigher:
|
|
146
|
+
return !!this._sarifModel?.findings.hasSeverityOrHigher(SecuritySeverity.Unknown);
|
|
147
|
+
case SendIf.LevelError:
|
|
148
|
+
return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Error) != null;
|
|
149
|
+
case SendIf.LevelWarning:
|
|
150
|
+
return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Warning) != null;
|
|
151
|
+
case SendIf.LevelWarningOrHigher:
|
|
152
|
+
return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.Warning);
|
|
153
|
+
case SendIf.LevelNote:
|
|
154
|
+
return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Note) != null;
|
|
155
|
+
case SendIf.LevelNoteOrHigher:
|
|
156
|
+
return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.Note);
|
|
157
|
+
case SendIf.LevelNone:
|
|
158
|
+
return this._sarifModel?.findings.findByProperty('level', SecurityLevel.None) != null;
|
|
159
|
+
case SendIf.LevelNoneOrHigher:
|
|
160
|
+
return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.None);
|
|
161
|
+
case SendIf.LevelUnknown:
|
|
162
|
+
return this._sarifModel?.findings.findByProperty('level', SecurityLevel.Unknown) != null;
|
|
163
|
+
case SendIf.LevelUnknownOrHigher:
|
|
164
|
+
return !!this._sarifModel?.findings.hasLevelOrHigher(SecurityLevel.Unknown);
|
|
165
|
+
case SendIf.Always:
|
|
166
|
+
return true;
|
|
167
|
+
case SendIf.Some:
|
|
168
|
+
return (this._sarifModel?.findings.length ?? 0) > 0;
|
|
169
|
+
case SendIf.Empty:
|
|
170
|
+
return (this._sarifModel?.findings.length ?? 0) === 0;
|
|
171
|
+
case SendIf.Never:
|
|
172
|
+
return false;
|
|
173
|
+
default:
|
|
174
|
+
throw new Error(`Unknown sendIf parameter: ${this._sendIf}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2FyaWZUb1NsYWNrQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NhcmlmVG9TbGFja0NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxJQUFJLEVBQUUsRUFBRSxNQUFNLElBQUksQ0FBQTtBQUVuQyxPQUFPLE1BQU0sTUFBTSxVQUFVLENBQUE7QUFDN0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFDM0QsT0FBTyxFQU1MLGFBQWEsRUFDYixnQkFBZ0IsRUFDaEIsTUFBTSxFQUVQLE1BQU0sU0FBUyxDQUFBO0FBQ2hCLE9BQU8sTUFBTSxNQUFNLFVBQVUsQ0FBQTtBQUM3QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUN0RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUM5RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDL0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLHVCQUF1QixFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDL0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUM3QyxPQUFPLGFBQWEsTUFBTSx1QkFBdUIsQ0FBQTtBQUVqRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBQ3JCLFFBQVEsQ0FBZTtJQUN2QixXQUFXLENBQWE7SUFFeEIsT0FBTyxHQUFXLE1BQU0sQ0FBQyxNQUFNLENBQUE7SUFFdkMsWUFBb0IsR0FBZ0I7UUFDbEMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUN0QixNQUFNLENBQUMsVUFBVSxFQUFFLENBQUE7SUFDckIsQ0FBQztJQUVPLE1BQU0sQ0FBQyxDQUFDLG9CQUFvQjtRQUNsQyxJQUFJLEtBQUssR0FBVyxDQUFDLENBQUE7UUFDckIsT0FBTyxJQUFJLEVBQUUsQ0FBQztZ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
|