@fabasoad/sarif-to-slack 1.0.0 → 1.2.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/dist/SarifToSlackClient.d.ts.map +1 -1
- package/dist/SarifToSlackClient.js +8 -10
- package/dist/index.cjs +148 -111
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -3
- package/dist/model/Color.d.ts +18 -5
- package/dist/model/Color.d.ts.map +1 -1
- package/dist/model/Color.js +23 -37
- package/dist/model/Finding.js +3 -3
- package/dist/model/FindingArray.d.ts +2 -0
- package/dist/model/FindingArray.d.ts.map +1 -0
- package/dist/model/FindingArray.js +24 -0
- package/dist/model/SendIf.d.ts +116 -0
- package/dist/model/SendIf.d.ts.map +1 -0
- package/dist/model/SendIf.js +176 -0
- package/dist/model/SlackMessage.d.ts +23 -0
- package/dist/model/SlackMessage.d.ts.map +1 -0
- package/dist/model/SlackMessage.js +99 -0
- package/dist/representations/Representation.js +3 -3
- package/dist/sarif-to-slack.d.ts +28 -7
- package/dist/types.d.ts +3 -132
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -117
- package/etc/sarif-to-slack.api.md +3 -1
- package/package.json +1 -1
- package/src/SarifToSlackClient.ts +7 -11
- package/src/index.ts +12 -4
- package/src/model/Color.ts +43 -46
- package/src/model/Finding.ts +3 -3
- package/src/model/{FindingsArray.ts → FindingArray.ts} +3 -3
- package/src/model/SendIf.ts +175 -0
- package/src/{SlackMessageBuilder.ts → model/SlackMessage.ts} +31 -6
- package/src/processors/CodeQLProcessor.ts +1 -1
- package/src/representations/CompactGroupByRepresentation.ts +1 -1
- package/src/representations/CompactGroupByRunRepresentation.ts +1 -1
- package/src/representations/CompactGroupBySarifRepresentation.ts +1 -1
- package/src/representations/CompactGroupByToolNameRepresentation.ts +1 -1
- package/src/representations/CompactTotalRepresentation.ts +1 -1
- package/src/representations/Representation.ts +4 -4
- package/src/types.ts +5 -136
- package/src/utils/Comparators.ts +1 -1
- package/tests/integration/SendSarifToSlack.spec.ts +11 -12
- package/dist/SlackMessageBuilder.d.ts +0 -2
- package/dist/SlackMessageBuilder.d.ts.map +0 -1
- package/dist/SlackMessageBuilder.js +0 -91
- package/dist/model/FindingsArray.d.ts +0 -2
- package/dist/model/FindingsArray.d.ts.map +0 -1
- package/dist/model/FindingsArray.js +0 -24
package/src/model/Color.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SecurityLevel, SecuritySeverity } from '../types'
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import Finding from './Finding'
|
|
3
|
+
import FindingArray from './FindingArray'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* This class represents a color in hex format.
|
|
@@ -20,7 +20,7 @@ export class Color {
|
|
|
20
20
|
*/
|
|
21
21
|
public constructor(color?: string) {
|
|
22
22
|
this._color = this.mapColor(color)
|
|
23
|
-
this.
|
|
23
|
+
this.assertHexColor()
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -30,7 +30,7 @@ export class Color {
|
|
|
30
30
|
return this._color
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
private
|
|
33
|
+
private assertHexColor(): void {
|
|
34
34
|
if (this._color != null) {
|
|
35
35
|
const hexColorRegex = /^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
|
|
36
36
|
|
|
@@ -64,7 +64,6 @@ export class Color {
|
|
|
64
64
|
type ColorGroupCommon = {
|
|
65
65
|
none?: Color,
|
|
66
66
|
unknown?: Color,
|
|
67
|
-
empty?: Color,
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
/**
|
|
@@ -95,30 +94,37 @@ export type ColorGroupBySeverity = ColorGroupCommon & {
|
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
/**
|
|
98
|
-
* Represents configuration of the color scheme. {@link ColorOptions.byLevel}
|
|
99
|
-
*
|
|
100
|
-
*
|
|
97
|
+
* Represents configuration of the color scheme. If both {@link ColorOptions.byLevel}
|
|
98
|
+
* and {@link ColorOptions.bySeverity} are defined, then {@link ColorOptions.bySeverity}
|
|
99
|
+
* takes precedence.
|
|
101
100
|
* @public
|
|
102
101
|
*/
|
|
103
102
|
export type ColorOptions = {
|
|
103
|
+
/**
|
|
104
|
+
* Default color if specific color was not found. It is a fallback option.
|
|
105
|
+
*/
|
|
106
|
+
default?: Color,
|
|
107
|
+
/**
|
|
108
|
+
* Color scheme for the findings where certain level is presented.
|
|
109
|
+
*/
|
|
104
110
|
byLevel?: ColorGroupByLevel,
|
|
111
|
+
/**
|
|
112
|
+
* Color scheme for the findings where certain severity is presented.
|
|
113
|
+
*/
|
|
105
114
|
bySeverity?: ColorGroupBySeverity,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function isColorOptions(color?: Color | ColorOptions): color is ColorOptions {
|
|
113
|
-
return color != null
|
|
115
|
+
/**
|
|
116
|
+
* Color when no findings are found.
|
|
117
|
+
*/
|
|
118
|
+
empty?: Color,
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
function identifyColorCommon<K extends keyof Finding>(
|
|
117
|
-
findings:
|
|
122
|
+
findings: FindingArray,
|
|
118
123
|
prop: K,
|
|
119
124
|
none: Finding[K],
|
|
120
125
|
unknown: Finding[K],
|
|
121
|
-
color: ColorGroupCommon
|
|
126
|
+
color: ColorGroupCommon,
|
|
127
|
+
defaultColor?: Color
|
|
122
128
|
): string | undefined {
|
|
123
129
|
if (color.none != null && findings.findByProperty(prop, none) != null) {
|
|
124
130
|
return color.none.value
|
|
@@ -128,14 +134,10 @@ function identifyColorCommon<K extends keyof Finding>(
|
|
|
128
134
|
return color.unknown.value
|
|
129
135
|
}
|
|
130
136
|
|
|
131
|
-
|
|
132
|
-
return color.empty.value
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return undefined
|
|
137
|
+
return defaultColor?.value
|
|
136
138
|
}
|
|
137
139
|
|
|
138
|
-
function identifyColorBySeverity(findings:
|
|
140
|
+
function identifyColorBySeverity(findings: FindingArray, color: ColorGroupBySeverity, defaultColor?: Color): string | undefined {
|
|
139
141
|
if (color.critical != null && findings.findByProperty('severity', SecuritySeverity.Critical) != null) {
|
|
140
142
|
return color.critical.value
|
|
141
143
|
}
|
|
@@ -152,10 +154,10 @@ function identifyColorBySeverity(findings: FindingsArray, color: ColorGroupBySev
|
|
|
152
154
|
return color.low.value
|
|
153
155
|
}
|
|
154
156
|
|
|
155
|
-
return identifyColorCommon(findings, 'severity', SecuritySeverity.None, SecuritySeverity.Unknown, color)
|
|
157
|
+
return identifyColorCommon(findings, 'severity', SecuritySeverity.None, SecuritySeverity.Unknown, color, defaultColor)
|
|
156
158
|
}
|
|
157
159
|
|
|
158
|
-
function identifyColorByLevel(findings:
|
|
160
|
+
function identifyColorByLevel(findings: FindingArray, color: ColorGroupByLevel, defaultColor?: Color): string | undefined {
|
|
159
161
|
if (color.error != null && findings.findByProperty('level', SecurityLevel.Error) != null) {
|
|
160
162
|
return color.error.value
|
|
161
163
|
}
|
|
@@ -168,34 +170,29 @@ function identifyColorByLevel(findings: FindingsArray, color: ColorGroupByLevel)
|
|
|
168
170
|
return color.note.value
|
|
169
171
|
}
|
|
170
172
|
|
|
171
|
-
return identifyColorCommon(findings, 'level', SecurityLevel.None, SecurityLevel.Unknown, color)
|
|
173
|
+
return identifyColorCommon(findings, 'level', SecurityLevel.None, SecurityLevel.Unknown, color, defaultColor)
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
/**
|
|
175
177
|
* Makes an ultimate decision on what color should be Slack message. The decision
|
|
176
|
-
* is based on the provided {@param
|
|
177
|
-
*
|
|
178
|
-
* @param
|
|
178
|
+
* is based on the provided {@param colorOpts} parameter and {@param findings}
|
|
179
|
+
* list.
|
|
180
|
+
* @param findings An instance of {@link FindingArray} object.
|
|
181
|
+
* @param colorOpts An instance of {@link ColorOptions} type.
|
|
179
182
|
* @internal
|
|
180
183
|
*/
|
|
181
|
-
export function identifyColor(findings:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
184
|
+
export function identifyColor(findings: FindingArray, colorOpts?: ColorOptions): string | undefined {
|
|
185
|
+
let result: string | undefined = colorOpts?.bySeverity
|
|
186
|
+
? identifyColorBySeverity(findings, colorOpts.bySeverity, colorOpts.default)
|
|
187
|
+
: undefined
|
|
185
188
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
+
result ??= colorOpts?.byLevel
|
|
190
|
+
? identifyColorByLevel(findings, colorOpts.byLevel, colorOpts.default)
|
|
191
|
+
: result
|
|
189
192
|
|
|
190
|
-
|
|
191
|
-
if (color.bySeverity != null) {
|
|
192
|
-
return identifyColorBySeverity(findings, color.bySeverity)
|
|
193
|
-
}
|
|
193
|
+
result ??= findings.length === 0 ? colorOpts?.empty?.value : result
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
return identifyColorByLevel(findings, color.byLevel)
|
|
197
|
-
}
|
|
198
|
-
}
|
|
195
|
+
result ??= colorOpts?.default?.value
|
|
199
196
|
|
|
200
|
-
return
|
|
197
|
+
return result
|
|
201
198
|
}
|
package/src/model/Finding.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type FindingOptions = {
|
|
|
18
18
|
* This interface represents a finding from SARIF file.
|
|
19
19
|
* @internal
|
|
20
20
|
*/
|
|
21
|
-
export interface Finding {
|
|
21
|
+
export default interface Finding {
|
|
22
22
|
get sarifPath(): string,
|
|
23
23
|
get runId(): number,
|
|
24
24
|
get toolName(): string,
|
|
@@ -33,7 +33,7 @@ export interface Finding {
|
|
|
33
33
|
* @internal
|
|
34
34
|
*/
|
|
35
35
|
export function createFinding(opts: FindingOptions): Finding {
|
|
36
|
-
return new
|
|
36
|
+
return new FindingImpl(opts)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -42,7 +42,7 @@ export function createFinding(opts: FindingOptions): Finding {
|
|
|
42
42
|
* create a new {@link Finding}.
|
|
43
43
|
* @private
|
|
44
44
|
*/
|
|
45
|
-
class
|
|
45
|
+
class FindingImpl implements Finding {
|
|
46
46
|
private readonly _runMetadata: RunData
|
|
47
47
|
private readonly _result: Result
|
|
48
48
|
private readonly _sarifPath: string
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import ExtendedArray from '../utils/ExtendedArray'
|
|
1
|
+
import Finding from './Finding'
|
|
3
2
|
import { SecurityLevel, SecuritySeverity } from '../types'
|
|
3
|
+
import ExtendedArray from '../utils/ExtendedArray'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* This class represents an array of {@link Finding} objects and adds additional
|
|
7
7
|
* useful methods to it.
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
|
-
export default class
|
|
10
|
+
export default class FindingArray extends ExtendedArray<Finding> {
|
|
11
11
|
|
|
12
12
|
public hasSeverityOrHigher(severity: SecuritySeverity): boolean {
|
|
13
13
|
return Object
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This enum represents the condition on when message should be sent. If this
|
|
3
|
+
* condition is satisfied then message is sent, otherwise - message is not sent.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export enum SendIf {
|
|
7
|
+
/**
|
|
8
|
+
* Send message only if there is at least one finding with "Critical" severity.
|
|
9
|
+
* Since it is the higher possible severity, it is the same as "Critical" or
|
|
10
|
+
* higher.
|
|
11
|
+
*/
|
|
12
|
+
SeverityCritical,
|
|
13
|
+
/**
|
|
14
|
+
* Send message only if there is at least one finding with "High" severity.
|
|
15
|
+
*/
|
|
16
|
+
SeverityHigh,
|
|
17
|
+
/**
|
|
18
|
+
* Send message only if there is at least one finding with "High" severity or
|
|
19
|
+
* higher, that includes "High" and "Critical".
|
|
20
|
+
*/
|
|
21
|
+
SeverityHighOrHigher,
|
|
22
|
+
/**
|
|
23
|
+
* Send message only if there is at least one finding with "Medium" severity.
|
|
24
|
+
*/
|
|
25
|
+
SeverityMedium,
|
|
26
|
+
/**
|
|
27
|
+
* Send message only if there is at least one finding with "Medium" severity
|
|
28
|
+
* or higher, that includes "Medium", "High" and "Critical".
|
|
29
|
+
*/
|
|
30
|
+
SeverityMediumOrHigher,
|
|
31
|
+
/**
|
|
32
|
+
* Send message only if there is at least one finding with "Low" severity.
|
|
33
|
+
*/
|
|
34
|
+
SeverityLow,
|
|
35
|
+
/**
|
|
36
|
+
* Send message only if there is at least one finding with "Low" severity or
|
|
37
|
+
* higher, that includes "Low", "Medium", "High" and "Critical".
|
|
38
|
+
*/
|
|
39
|
+
SeverityLowOrHigher,
|
|
40
|
+
/**
|
|
41
|
+
* Send message only if there is at least one finding with "None" severity.
|
|
42
|
+
*/
|
|
43
|
+
SeverityNone,
|
|
44
|
+
/**
|
|
45
|
+
* Send message only if there is at least one finding with "None" severity or
|
|
46
|
+
* higher, that includes "None", "Low", "Medium", "High" and "Critical".
|
|
47
|
+
*/
|
|
48
|
+
SeverityNoneOrHigher,
|
|
49
|
+
/**
|
|
50
|
+
* Send message only if there is at least one finding with "Unknown" severity.
|
|
51
|
+
*/
|
|
52
|
+
SeverityUnknown,
|
|
53
|
+
/**
|
|
54
|
+
* Send message only if there is at least one finding with "Unknown" severity
|
|
55
|
+
* or higher, that includes "Unknown", "None", "Low", "Medium", "High" and "Critical".
|
|
56
|
+
*/
|
|
57
|
+
SeverityUnknownOrHigher,
|
|
58
|
+
/**
|
|
59
|
+
* Send message only if there is at least one finding with "Error" level.
|
|
60
|
+
* Since it is the higher possible level, it is the same as "Error" or higher.
|
|
61
|
+
*/
|
|
62
|
+
LevelError,
|
|
63
|
+
/**
|
|
64
|
+
* Send message only if there is at least one finding with "Warning" level.
|
|
65
|
+
*/
|
|
66
|
+
LevelWarning,
|
|
67
|
+
/**
|
|
68
|
+
* Send message only if there is at least one finding with "Warning" level or
|
|
69
|
+
* higher, that includes "Warning" and "Error".
|
|
70
|
+
*/
|
|
71
|
+
LevelWarningOrHigher,
|
|
72
|
+
/**
|
|
73
|
+
* Send message only if there is at least one finding with "Note" level.
|
|
74
|
+
*/
|
|
75
|
+
LevelNote,
|
|
76
|
+
/**
|
|
77
|
+
* Send message only if there is at least one finding with "Note" level or
|
|
78
|
+
* higher, that includes "Note", "Warning" and "Error.
|
|
79
|
+
*/
|
|
80
|
+
LevelNoteOrHigher,
|
|
81
|
+
/**
|
|
82
|
+
* Send message only if there is at least one finding with "None" level.
|
|
83
|
+
*/
|
|
84
|
+
LevelNone,
|
|
85
|
+
/**
|
|
86
|
+
* Send message only if there is at least one finding with "None" level or
|
|
87
|
+
* higher, that includes "None", "Note", "Warning" and "Error.
|
|
88
|
+
*/
|
|
89
|
+
LevelNoneOrHigher,
|
|
90
|
+
/**
|
|
91
|
+
* Send message only if there is at least one finding with "Unknown" level.
|
|
92
|
+
*/
|
|
93
|
+
LevelUnknown,
|
|
94
|
+
/**
|
|
95
|
+
* Send message only if there is at least one finding with "Unknown" level or
|
|
96
|
+
* higher, that includes "Unknown", "None", "Note", "Warning" and "Error.
|
|
97
|
+
*/
|
|
98
|
+
LevelUnknownOrHigher,
|
|
99
|
+
/**
|
|
100
|
+
* Always send a message.
|
|
101
|
+
*/
|
|
102
|
+
Always,
|
|
103
|
+
/**
|
|
104
|
+
* Send a message if at least 1 vulnerability is found.
|
|
105
|
+
*/
|
|
106
|
+
Some,
|
|
107
|
+
/**
|
|
108
|
+
* Send a message only if no vulnerabilities are found.
|
|
109
|
+
*/
|
|
110
|
+
Empty,
|
|
111
|
+
/**
|
|
112
|
+
* Never send a message.
|
|
113
|
+
*/
|
|
114
|
+
Never,
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Returns log message based on the provided {@param sendIf} parameter.
|
|
119
|
+
* @param sendIf An instance of {@link SendIf} enum.
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
export function sendIfLogMessage(sendIf: SendIf): string {
|
|
123
|
+
switch (sendIf) {
|
|
124
|
+
case SendIf.SeverityCritical:
|
|
125
|
+
return 'No message sent: no findings with "Critical" severity.'
|
|
126
|
+
case SendIf.SeverityHigh:
|
|
127
|
+
return 'No message sent: no findings with "High" severity.'
|
|
128
|
+
case SendIf.SeverityHighOrHigher:
|
|
129
|
+
return 'No message sent: no findings with "High" or higher severity.'
|
|
130
|
+
case SendIf.SeverityMedium:
|
|
131
|
+
return 'No message sent: no findings with "Medium" severity.'
|
|
132
|
+
case SendIf.SeverityMediumOrHigher:
|
|
133
|
+
return 'No message sent: no findings with "Medium" or higher severity.'
|
|
134
|
+
case SendIf.SeverityLow:
|
|
135
|
+
return 'No message sent: no findings with "Low" severity.'
|
|
136
|
+
case SendIf.SeverityLowOrHigher:
|
|
137
|
+
return 'No message sent: no findings with "Low" or higher severity.'
|
|
138
|
+
case SendIf.SeverityNone:
|
|
139
|
+
return 'No message sent: no findings with "None" severity.'
|
|
140
|
+
case SendIf.SeverityNoneOrHigher:
|
|
141
|
+
return 'No message sent: no findings with "None" or higher severity.'
|
|
142
|
+
case SendIf.SeverityUnknown:
|
|
143
|
+
return 'No message sent: no findings with "Unknown" severity.'
|
|
144
|
+
case SendIf.SeverityUnknownOrHigher:
|
|
145
|
+
return 'No message sent: no findings with "Unknown" or higher severity.'
|
|
146
|
+
case SendIf.LevelError:
|
|
147
|
+
return 'No message sent: no findings with "Error" level.'
|
|
148
|
+
case SendIf.LevelWarning:
|
|
149
|
+
return 'No message sent: no findings with "Warning" level.'
|
|
150
|
+
case SendIf.LevelWarningOrHigher:
|
|
151
|
+
return 'No message sent: no findings with "Warning" or higher level.'
|
|
152
|
+
case SendIf.LevelNote:
|
|
153
|
+
return 'No message sent: no findings with "Note" level.'
|
|
154
|
+
case SendIf.LevelNoteOrHigher:
|
|
155
|
+
return 'No message sent: no findings with "Note" or higher level.'
|
|
156
|
+
case SendIf.LevelNone:
|
|
157
|
+
return 'No message sent: no findings with "None" level.'
|
|
158
|
+
case SendIf.LevelNoneOrHigher:
|
|
159
|
+
return 'No message sent: no findings with "None" or higher level.'
|
|
160
|
+
case SendIf.LevelUnknown:
|
|
161
|
+
return 'No message sent: no findings with "Unknown" level.'
|
|
162
|
+
case SendIf.LevelUnknownOrHigher:
|
|
163
|
+
return 'No message sent: no findings with "Unknown" or higher level.'
|
|
164
|
+
case SendIf.Always:
|
|
165
|
+
return 'Message always sent.'
|
|
166
|
+
case SendIf.Some:
|
|
167
|
+
return 'No message sent: findings are not found.'
|
|
168
|
+
case SendIf.Empty:
|
|
169
|
+
return 'No message sent: some findings are found.'
|
|
170
|
+
case SendIf.Never:
|
|
171
|
+
return 'No message sent: sending is disabled.'
|
|
172
|
+
default:
|
|
173
|
+
return 'Unknown SendIf value.'
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -2,26 +2,51 @@ import { AnyBlock } from '@slack/types'
|
|
|
2
2
|
import { ContextBlock, HeaderBlock } from '@slack/types/dist/block-kit/blocks'
|
|
3
3
|
import { TextObject } from '@slack/types/dist/block-kit/composition-objects'
|
|
4
4
|
import { IncomingWebhook } from '@slack/webhook'
|
|
5
|
-
import { FooterType
|
|
6
|
-
import
|
|
7
|
-
import
|
|
5
|
+
import { FooterType } from '../types'
|
|
6
|
+
import Representation from '../representations/Representation'
|
|
7
|
+
import { version } from '../metadata.json'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Options for the SlackMessageBuilder.
|
|
11
11
|
* @internal
|
|
12
12
|
*/
|
|
13
|
-
export type
|
|
13
|
+
export type SlackMessageOptions = {
|
|
14
14
|
username?: string
|
|
15
15
|
iconUrl?: string
|
|
16
16
|
color?: string
|
|
17
17
|
representation: Representation,
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Interface for a Slack message that can be sent.
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export interface SlackMessage {
|
|
25
|
+
/**
|
|
26
|
+
* Sends the Slack message.
|
|
27
|
+
* @returns A promise that resolves to the response from the Slack webhook.
|
|
28
|
+
*/
|
|
29
|
+
send: () => Promise<string>
|
|
30
|
+
withActor(actor?: string): void
|
|
31
|
+
withFooter(text?: string, type?: FooterType): void
|
|
32
|
+
withHeader(header?: string): void
|
|
33
|
+
withRun(): void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new instance of {@link SlackMessage} class.
|
|
38
|
+
* @param url Slack webhook URL
|
|
39
|
+
* @param opts An instance of {@link SlackMessageOptions} type.
|
|
40
|
+
*/
|
|
41
|
+
export function createSlackMessage(url: string, opts: SlackMessageOptions): SlackMessage {
|
|
42
|
+
return new SlackMessageImpl(url, opts)
|
|
43
|
+
}
|
|
44
|
+
|
|
20
45
|
/**
|
|
21
46
|
* Class for building and sending Slack messages based on SARIF logs.
|
|
22
47
|
* @internal
|
|
23
48
|
*/
|
|
24
|
-
|
|
49
|
+
class SlackMessageImpl implements SlackMessage {
|
|
25
50
|
private readonly _webhook: IncomingWebhook
|
|
26
51
|
private readonly _gitHubServerUrl: string
|
|
27
52
|
private readonly _color?: string
|
|
@@ -32,7 +57,7 @@ export class SlackMessageBuilder implements SlackMessage {
|
|
|
32
57
|
private _actor?: string
|
|
33
58
|
private _runId?: string
|
|
34
59
|
|
|
35
|
-
constructor(url: string, opts:
|
|
60
|
+
constructor(url: string, opts: SlackMessageOptions) {
|
|
36
61
|
this._webhook = new IncomingWebhook(url, {
|
|
37
62
|
username: opts.username || 'SARIF results',
|
|
38
63
|
icon_url: opts.iconUrl
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SarifModel } from '../types'
|
|
2
|
-
import
|
|
2
|
+
import Finding from '../model/Finding'
|
|
3
3
|
import { findingsComparatorByKey } from '../utils/Comparators'
|
|
4
|
-
import
|
|
4
|
+
import FindingArray from '../model/FindingArray'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The most base abstract class for the representation. Every representation class
|
|
@@ -17,10 +17,10 @@ export default abstract class Representation {
|
|
|
17
17
|
.findings
|
|
18
18
|
.map((f: Finding): Finding => f.clone())
|
|
19
19
|
.sort(findingsComparatorByKey(findingSortKey))
|
|
20
|
-
.reduce((arr:
|
|
20
|
+
.reduce((arr: FindingArray, f: Finding): FindingArray => {
|
|
21
21
|
arr.push(f)
|
|
22
22
|
return arr
|
|
23
|
-
}, new
|
|
23
|
+
}, new FindingArray())
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
protected bold(text: string): string {
|
package/src/types.ts
CHANGED
|
@@ -1,22 +1,7 @@
|
|
|
1
1
|
import { Run } from 'sarif'
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Interface for a Slack message that can be sent.
|
|
7
|
-
* @public
|
|
8
|
-
*/
|
|
9
|
-
export interface SlackMessage {
|
|
10
|
-
/**
|
|
11
|
-
* Sends the Slack message.
|
|
12
|
-
* @returns A promise that resolves to the response from the Slack webhook.
|
|
13
|
-
*/
|
|
14
|
-
send: () => Promise<string>
|
|
15
|
-
withActor(actor?: string): void
|
|
16
|
-
withFooter(text?: string, type?: FooterType): void
|
|
17
|
-
withHeader(header?: string): void
|
|
18
|
-
withRun(): void
|
|
19
|
-
}
|
|
2
|
+
import { ColorOptions } from './model/Color'
|
|
3
|
+
import FindingArray from './model/FindingArray'
|
|
4
|
+
import { SendIf } from './model/SendIf'
|
|
20
5
|
|
|
21
6
|
/**
|
|
22
7
|
* Enum representing log levels for the service.
|
|
@@ -221,122 +206,6 @@ export type SarifOptions = {
|
|
|
221
206
|
extension?: SarifFileExtension,
|
|
222
207
|
}
|
|
223
208
|
|
|
224
|
-
/**
|
|
225
|
-
* This enum represents the condition on when message should be sent. If this
|
|
226
|
-
* condition is satisfied then message is sent, otherwise - message is not sent.
|
|
227
|
-
* @public
|
|
228
|
-
*/
|
|
229
|
-
export enum SendIf {
|
|
230
|
-
/**
|
|
231
|
-
* Send message only if there is at least one finding with "Critical" severity.
|
|
232
|
-
* Since it is the higher possible severity, it is the same as "Critical" or
|
|
233
|
-
* higher.
|
|
234
|
-
*/
|
|
235
|
-
SeverityCritical,
|
|
236
|
-
/**
|
|
237
|
-
* Send message only if there is at least one finding with "High" severity.
|
|
238
|
-
*/
|
|
239
|
-
SeverityHigh,
|
|
240
|
-
/**
|
|
241
|
-
* Send message only if there is at least one finding with "High" severity or
|
|
242
|
-
* higher, that includes "High" and "Critical".
|
|
243
|
-
*/
|
|
244
|
-
SeverityHighOrHigher,
|
|
245
|
-
/**
|
|
246
|
-
* Send message only if there is at least one finding with "Medium" severity.
|
|
247
|
-
*/
|
|
248
|
-
SeverityMedium,
|
|
249
|
-
/**
|
|
250
|
-
* Send message only if there is at least one finding with "Medium" severity
|
|
251
|
-
* or higher, that includes "Medium", "High" and "Critical".
|
|
252
|
-
*/
|
|
253
|
-
SeverityMediumOrHigher,
|
|
254
|
-
/**
|
|
255
|
-
* Send message only if there is at least one finding with "Low" severity.
|
|
256
|
-
*/
|
|
257
|
-
SeverityLow,
|
|
258
|
-
/**
|
|
259
|
-
* Send message only if there is at least one finding with "Low" severity or
|
|
260
|
-
* higher, that includes "Low", "Medium", "High" and "Critical".
|
|
261
|
-
*/
|
|
262
|
-
SeverityLowOrHigher,
|
|
263
|
-
/**
|
|
264
|
-
* Send message only if there is at least one finding with "None" severity.
|
|
265
|
-
*/
|
|
266
|
-
SeverityNone,
|
|
267
|
-
/**
|
|
268
|
-
* Send message only if there is at least one finding with "None" severity or
|
|
269
|
-
* higher, that includes "None", "Low", "Medium", "High" and "Critical".
|
|
270
|
-
*/
|
|
271
|
-
SeverityNoneOrHigher,
|
|
272
|
-
/**
|
|
273
|
-
* Send message only if there is at least one finding with "Unknown" severity.
|
|
274
|
-
*/
|
|
275
|
-
SeverityUnknown,
|
|
276
|
-
/**
|
|
277
|
-
* Send message only if there is at least one finding with "Unknown" severity
|
|
278
|
-
* or higher, that includes "Unknown", "None", "Low", "Medium", "High" and "Critical".
|
|
279
|
-
*/
|
|
280
|
-
SeverityUnknownOrHigher,
|
|
281
|
-
/**
|
|
282
|
-
* Send message only if there is at least one finding with "Error" level.
|
|
283
|
-
* Since it is the higher possible level, it is the same as "Error" or higher.
|
|
284
|
-
*/
|
|
285
|
-
LevelError,
|
|
286
|
-
/**
|
|
287
|
-
* Send message only if there is at least one finding with "Warning" level.
|
|
288
|
-
*/
|
|
289
|
-
LevelWarning,
|
|
290
|
-
/**
|
|
291
|
-
* Send message only if there is at least one finding with "Warning" level or
|
|
292
|
-
* higher, that includes "Warning" and "Error".
|
|
293
|
-
*/
|
|
294
|
-
LevelWarningOrHigher,
|
|
295
|
-
/**
|
|
296
|
-
* Send message only if there is at least one finding with "Note" level.
|
|
297
|
-
*/
|
|
298
|
-
LevelNote,
|
|
299
|
-
/**
|
|
300
|
-
* Send message only if there is at least one finding with "Note" level or
|
|
301
|
-
* higher, that includes "Note", "Warning" and "Error.
|
|
302
|
-
*/
|
|
303
|
-
LevelNoteOrHigher,
|
|
304
|
-
/**
|
|
305
|
-
* Send message only if there is at least one finding with "None" level.
|
|
306
|
-
*/
|
|
307
|
-
LevelNone,
|
|
308
|
-
/**
|
|
309
|
-
* Send message only if there is at least one finding with "None" level or
|
|
310
|
-
* higher, that includes "None", "Note", "Warning" and "Error.
|
|
311
|
-
*/
|
|
312
|
-
LevelNoneOrHigher,
|
|
313
|
-
/**
|
|
314
|
-
* Send message only if there is at least one finding with "Unknown" level.
|
|
315
|
-
*/
|
|
316
|
-
LevelUnknown,
|
|
317
|
-
/**
|
|
318
|
-
* Send message only if there is at least one finding with "Unknown" level or
|
|
319
|
-
* higher, that includes "Unknown", "None", "Note", "Warning" and "Error.
|
|
320
|
-
*/
|
|
321
|
-
LevelUnknownOrHigher,
|
|
322
|
-
/**
|
|
323
|
-
* Always send a message.
|
|
324
|
-
*/
|
|
325
|
-
Always,
|
|
326
|
-
/**
|
|
327
|
-
* Send a message if at least 1 vulnerability is found.
|
|
328
|
-
*/
|
|
329
|
-
Some,
|
|
330
|
-
/**
|
|
331
|
-
* Send a message only if no vulnerabilities are found.
|
|
332
|
-
*/
|
|
333
|
-
Empty,
|
|
334
|
-
/**
|
|
335
|
-
* Never send a message.
|
|
336
|
-
*/
|
|
337
|
-
Never,
|
|
338
|
-
}
|
|
339
|
-
|
|
340
209
|
/**
|
|
341
210
|
* Options for the SarifToSlackClient.
|
|
342
211
|
* @public
|
|
@@ -346,7 +215,7 @@ export type SarifToSlackClientOptions = {
|
|
|
346
215
|
sarif: SarifOptions,
|
|
347
216
|
username?: string,
|
|
348
217
|
iconUrl?: string,
|
|
349
|
-
color?:
|
|
218
|
+
color?: ColorOptions,
|
|
350
219
|
log?: LogOptions,
|
|
351
220
|
header?: IncludeAwareWithValueOptions,
|
|
352
221
|
footer?: FooterOptions,
|
|
@@ -405,5 +274,5 @@ export type RunData = {
|
|
|
405
274
|
export type SarifModel = {
|
|
406
275
|
sarifFiles: string[],
|
|
407
276
|
runs: RunData[],
|
|
408
|
-
findings:
|
|
277
|
+
findings: FindingArray,
|
|
409
278
|
}
|