Skip to content

Commit 774ed22

Browse files
author
testcafe-build-bot
committed
🔄 synced local '.github/scripts/security-checker.mjs' with remote 'scripts/security-checker.mjs'
1 parent 5c4055a commit 774ed22

File tree

1 file changed

+52
-48
lines changed

1 file changed

+52
-48
lines changed

‎.github/scripts/security-checker.mjs‎

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ const ALERT_TYPES = {
1414
codeq: 'codeql',
1515
}
1616

17-
const UPDATE_TYPE = {
18-
addAlertToIssue: 'addAlertToIssue',
19-
closeTask: 'closeTask'
20-
}
21-
2217
class SecurityChecker {
2318
constructor(github, context, issueRepo) {
2419
this.github = github;
@@ -29,7 +24,7 @@ class SecurityChecker {
2924
};
3025
}
3126

32-
async check() {
27+
async check () {
3328
const dependabotAlerts = await this.getDependabotAlerts();
3429
const codeqlAlerts = await this.getCodeqlAlerts();
3530
const existedIssues = await this.getExistedIssues();
@@ -41,13 +36,13 @@ class SecurityChecker {
4136
await this.createCodeqlIssues(codeqlAlerts);
4237
}
4338

44-
async getDependabotAlerts() {
39+
async getDependabotAlerts () {
4540
const { data } = await this.github.rest.dependabot.listAlertsForRepo({ state: STATES.open, ...this.context });
4641

4742
return data;
4843
}
4944

50-
async getCodeqlAlerts() {
45+
async getCodeqlAlerts () {
5146
try {
5247
const { data } = await this.github.rest.codeScanning.listAlertsForRepo({ state: STATES.open, ...this.context });
5348

@@ -61,7 +56,7 @@ class SecurityChecker {
6156
}
6257
}
6358

64-
async getExistedIssues() {
59+
async getExistedIssues () {
6560
const { data: existedIssues } = await this.github.rest.issues.listForRepo({
6661
owner: this.context.owner,
6762
repo: this.issueRepo,
@@ -72,7 +67,7 @@ class SecurityChecker {
7267
return existedIssues;
7368
}
7469

75-
createAlertDictionary(existedIssues) {
70+
createAlertDictionary (existedIssues) {
7671
return existedIssues.reduce((res, issue) => {
7772
const [, url, type] = issue.body.match(/(https:.*\/(dependabot|code-scanning)\/(\d+))/);
7873

@@ -86,40 +81,51 @@ class SecurityChecker {
8681
res.set(issue.title, { issue, type, cveId, ghsaId });
8782
}
8883
else
89-
res.set(issue.title, { issue, type })
90-
84+
res.set(issue.title, { issue, type });
9185

9286
return res;
9387
}, new Map());
9488
}
9589

96-
async closeSpoiledIssues() {
97-
const regExpAlertNumber = new RegExp(`(?<=\`${this.context.repo}\` - https:.*/dependabot/)\\d+`);
90+
async closeSpoiledIssues () {
91+
const regExpAlertNumbers = new RegExp(`(?<=\`${this.context.repo}\` - https:.*/dependabot/)\\d+`,'g');
92+
9893
for (const alert of this.alertDictionary.values()) {
9994

10095
if (alert.type === ALERT_TYPES.dependabot) {
101-
const alertNumber = alert.issue.body.match(regExpAlertNumber);
96+
const alertNumbers = alert.issue.body.match(regExpAlertNumbers);
10297

103-
if (!alertNumber)
98+
if (!alertNumbers)
10499
continue;
105100

106-
const isAlertOpened = await this.isDependabotAlertOpened(alertNumber);
101+
const updates = {};
102+
let changedBody = alert.issue.body;
107103

108-
if (isAlertOpened)
109-
continue;
104+
for (let alertNumber of alertNumbers) {
105+
const isAlertOpened = await this.isDependabotAlertOpened(alertNumber);
110106

111-
await this.updateIssue(alert, UPDATE_TYPE.closeTask);
107+
if (isAlertOpened)
108+
continue;
109+
110+
changedBody = changedBody.replace(new RegExp(`\\[ \\](?= \`${this.context.repo}\` - https:.*/dependabot/${alertNumber})`), '[x]');
111+
}
112+
113+
updates.body = changedBody;
114+
updates.state = !changedBody.match(/\[ \]/) ? STATES.closed : STATES.open;
115+
updates.issue_number = alert.issue.number;
116+
117+
await this.updateIssue(updates);
112118
}
113119
}
114120
}
115121

116-
async isDependabotAlertOpened(alertNumber) {
122+
async isDependabotAlertOpened (alertNumber) {
117123
const alert = await this.getDependabotAlertInfo(alertNumber);
118124

119125
return alert.state === STATES.open;
120126
}
121127

122-
async getDependabotAlertInfo(alertNumber) {
128+
async getDependabotAlertInfo (alertNumber) {
123129
try {
124130
const { data } = await this.github.rest.dependabot.getAlert({ alert_number: alertNumber, ...this.context });
125131

@@ -133,24 +139,7 @@ class SecurityChecker {
133139
}
134140
}
135141

136-
async updateIssue(alert, type) {
137-
const updates = {};
138-
139-
if (type === UPDATE_TYPE.addAlertToIssue) {
140-
const { issue } = this.alertDictionary.get(alert.security_advisory.summary);
141-
142-
updates.issue_number = issue.number;
143-
updates.body = issue.body.replace(/(?<=Repositories:)[\s\S]*?(?=####|$)/g, (match) => {
144-
return match + `- [ ] \`${this.context.repo}\` - ${alert.html_url}\n`;
145-
});
146-
}
147-
148-
if (type === UPDATE_TYPE.closeTask) {
149-
updates.body = alert.issue.body.replace(new RegExp(`\\[ \\](?= \`${this.context.repo}\`)`), '[x]');
150-
updates.state = !updates.body.match(/\[ \]/) ? STATES.closed : STATES.open;
151-
updates.issue_number = alert.issue.number;
152-
}
153-
142+
async updateIssue (updates) {
154143
return this.github.rest.issues.update({
155144
owner: this.context.owner,
156145
repo: this.issueRepo,
@@ -159,10 +148,10 @@ class SecurityChecker {
159148
}
160149

161150

162-
async createDependabotlIssues(dependabotAlerts) {
151+
async createDependabotlIssues (dependabotAlerts) {
163152
for (const alert of dependabotAlerts) {
164153
if (this.needAddAlertToIssue(alert)) {
165-
await this.updateIssue(alert, UPDATE_TYPE.addAlertToIssue);
154+
await this.addAlertToIssue(alert);
166155
}
167156
else if (this.needCreateIssue(alert)) {
168157
await this.createIssue({
@@ -179,16 +168,31 @@ class SecurityChecker {
179168
}
180169
}
181170

182-
needAddAlertToIssue(alert) {
183-
const existedIssue = this.alertDictionary.get(alert.security_advisory.summary);
171+
needAddAlertToIssue (alert) {
172+
const regExpAlertNumber = new RegExp(`(?<=\`${this.context.repo}\` - https:.*/dependabot/)${alert.html_url.match(/(?<=https:.*\/)\d+/)}`);
173+
const existedIssue = this.alertDictionary.get(alert.security_advisory.summary);
174+
const alertNumber = existedIssue?.issue.body.match(regExpAlertNumber);
175+
const isAlertExisted = existedIssue?.issue.body.includes(`\`${this.context.repo}\``);
184176

185177
return existedIssue
186178
&& existedIssue.cveId === alert.security_advisory.cve_id
187179
&& existedIssue.ghsaId === alert.security_advisory.ghsa_id
188-
&& !existedIssue.issue.body.includes(`\`${this.context.repo}\``);
180+
&& (!isAlertExisted || (isAlertExisted && !alertNumber));
181+
}
182+
183+
async addAlertToIssue (alert) {
184+
const updates = {};
185+
const { issue } = this.alertDictionary.get(alert.security_advisory.summary);
186+
187+
updates.issue_number = issue.number;
188+
updates.body = issue.body.replace(/(?<=Repositories:)[\s\S]*?(?=####|$)/g, (match) => {
189+
return match + `- [ ] \`${this.context.repo}\` - ${alert.html_url}\n`;
190+
});
191+
192+
await this.updateIssue(updates);
189193
}
190194

191-
async createCodeqlIssues(codeqlAlerts) {
195+
async createCodeqlIssues (codeqlAlerts) {
192196
for (const alert of codeqlAlerts) {
193197
if (!this.needCreateIssue(alert, false))
194198
continue;
@@ -203,13 +207,13 @@ class SecurityChecker {
203207
}
204208
}
205209

206-
needCreateIssue(alert, isDependabotAlert = true) {
210+
needCreateIssue (alert, isDependabotAlert = true) {
207211
const dictionaryKey = isDependabotAlert ? alert.security_advisory.summary : `[${this.context.repo}] ${alert.rule.description}`;
208212

209213
return !this.alertDictionary.get(dictionaryKey) && Date.now() - new Date(alert.created_at) <= 1000 * 60 * 60 * 24;
210214
}
211215

212-
async createIssue({ labels, originRepo, summary, description, link, issuePackage = '', cveId, ghsaId }, isDependabotAlert = true) {
216+
async createIssue ({ labels, originRepo, summary, description, link, issuePackage = '', cveId, ghsaId }, isDependabotAlert = true) {
213217
const title = isDependabotAlert ? `${summary}` : `[${originRepo}] ${summary}`;
214218
let body = ''
215219
+ `#### Repositories:\n`

0 commit comments

Comments
 (0)