-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
162 lines (139 loc) · 4.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
const axios = require("axios");
const core = require("@actions/core");
const exec = require("@actions/exec");
const fs = require("fs");
const tar = require("tar");
const { Octokit } = require("@octokit/rest");
const token = process.env["GITHUB_TOKEN"];
const octokit = new Octokit({ auth: `token ${token}` });
const commit = core.getInput("commit");
const secretsFilePath = core.getInput("secrets-file");
async function downloadFile(url, outputPath) {
const writer = require("fs").createWriteStream(outputPath);
const response = await axios.get(url, { responseType: "stream" });
response.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on("finish", resolve);
writer.on("error", reject);
});
}
async function checkForSecrets() {
let secretsDetected = false;
let data;
try {
data = fs.readFileSync(secretsFilePath, "utf8");
} catch (err) {
console.error(`Error reading file: ${err}`);
throw err;
}
// If the file is empty or only contains an empty array, assume no secrets found
if (!data || data.trim() === "[]") {
console.log("No secrets found, skipping processing...");
return secretsDetected;
}
const jsonData = JSON.parse(data);
if (
jsonData &&
jsonData.SourceMetadata &&
jsonData.SourceMetadata.Data &&
jsonData.SourceMetadata.Data.Git &&
jsonData.SourceMetadata.Data.Git.file
) {
secretsDetected = true;
const repoData = getRepoData(jsonData.SourceMetadata.Data.Git.repository);
if (!repoData) {
console.log("No repo data found, skipping processing...");
return secretsDetected;
}
const commentBody = `🚨 Secret Detected 🚨\nSecret detected at line ${jsonData.SourceMetadata.Data.Git.line} in file ${jsonData.SourceMetadata.Data.Git.file}. Please review.`;
const prs = await octokit.pulls.list({
owner: repoData.owner,
repo: repoData.repo,
});
for (const pr of prs.data) {
if (pr.state === "open") {
const commitId = await octokit.repos.getCommit({
owner: repoData.owner,
repo: repoData.repo,
ref: pr.head.sha,
});
await octokit.pulls.createReviewComment({
owner: repoData.owner,
repo: repoData.repo,
pull_number: pr.number,
body: commentBody,
commit_id: commitId.data.sha,
path: jsonData.SourceMetadata.Data.Git.file,
line: jsonData.SourceMetadata.Data.Git.line,
side: "RIGHT", // assuming the secret was added, not removed
});
}
}
}
return secretsDetected;
}
function getRepoData(repoUrl) {
const regex =
/(?:git@github\.com:|https:\/\/github.com\/)(.+)\/(.+)(?:\.git)?/i;
const match = regex.exec(repoUrl);
if (!match) {
console.log(`No match found for repoUrl: ${repoUrl}`);
return null;
}
return {
owner: match[1],
repo: match[2],
};
}
async function run() {
// Ensure secrets.json exists at the start
if (!fs.existsSync(secretsFilePath)) {
fs.writeFileSync(secretsFilePath, "[]"); // Create an empty JSON array
}
try {
const tarballPath = "./trufflehog.tar.gz";
await downloadFile(
"https://github.com/trufflesecurity/trufflehog/releases/download/v3.40.0/trufflehog_3.40.0_linux_amd64.tar.gz",
tarballPath
);
await tar.x({ file: tarballPath });
const options = {
listeners: {
stdout: (data) => {
fs.appendFileSync(secretsFilePath, data.toString());
},
stderr: (data) => {
console.error(data.toString());
},
},
};
try {
await exec.exec(
`./trufflehog`,
[
"git",
"file://./",
"--since-commit",
`${commit}`,
"--branch",
"HEAD",
"--fail",
"--no-update",
"--json",
"--no-verification",
],
options
);
} catch (error) {
console.error(`Error executing trufflehog: ${error}`);
throw error;
}
const secretsFound = await checkForSecrets();
if (secretsFound) {
core.setFailed("Secrets detected in the repository.");
}
} catch (error) {
core.setFailed(`Action failed with error: ${error}`);
}
}
run();