@genesis-agent/channel-slack 0.5.9 → 0.5.10

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.
Files changed (2) hide show
  1. package/install.js +56 -0
  2. package/package.json +1 -1
package/install.js CHANGED
@@ -5,6 +5,7 @@
5
5
  const fs = require("fs");
6
6
  const path = require("path");
7
7
  const https = require("https");
8
+ const crypto = require("crypto");
8
9
  const { execSync } = require("child_process");
9
10
 
10
11
  const VERSION = require("./package.json").version;
@@ -42,6 +43,60 @@ function getDownloadUrl(binaryName) {
42
43
  return `https://github.com/${REPO}/releases/download/v${VERSION}/${binaryName}`;
43
44
  }
44
45
 
46
+ function getChecksumUrl() {
47
+ return `https://github.com/${REPO}/releases/download/v${VERSION}/sha256sums.txt`;
48
+ }
49
+
50
+ function fetchText(url) {
51
+ return new Promise((resolve, reject) => {
52
+ const follow = (url, redirects) => {
53
+ if (redirects > 5) return reject(new Error("Too many redirects"));
54
+
55
+ https
56
+ .get(url, (res) => {
57
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
58
+ return follow(res.headers.location, redirects + 1);
59
+ }
60
+ if (res.statusCode !== 200) {
61
+ return reject(new Error(`Download failed: HTTP ${res.statusCode}`));
62
+ }
63
+
64
+ res.setEncoding("utf8");
65
+ let body = "";
66
+ res.on("data", (chunk) => {
67
+ body += chunk;
68
+ });
69
+ res.on("end", () => resolve(body));
70
+ })
71
+ .on("error", reject);
72
+ };
73
+
74
+ follow(url, 0);
75
+ });
76
+ }
77
+
78
+ function checksumFor(text, binaryName) {
79
+ for (const line of text.split(/\r?\n/)) {
80
+ const fields = line.trim().split(/\s+/);
81
+ if (fields.length >= 2 && fields[1] === binaryName) return fields[0].toLowerCase();
82
+ }
83
+ return null;
84
+ }
85
+
86
+ function sha256File(filePath) {
87
+ const hash = crypto.createHash("sha256");
88
+ hash.update(fs.readFileSync(filePath));
89
+ return hash.digest("hex");
90
+ }
91
+
92
+ async function verifyChecksum(binaryName, dest) {
93
+ const sums = await fetchText(getChecksumUrl());
94
+ const expected = checksumFor(sums, binaryName);
95
+ if (!expected) throw new Error(`Missing checksum for ${binaryName}`);
96
+ const actual = sha256File(dest);
97
+ if (actual !== expected) throw new Error(`Checksum mismatch for ${binaryName}`);
98
+ }
99
+
45
100
  function download(url, dest) {
46
101
  return new Promise((resolve, reject) => {
47
102
  const follow = (url, redirects) => {
@@ -100,6 +155,7 @@ async function main() {
100
155
 
101
156
  try {
102
157
  await download(url, dest);
158
+ await verifyChecksum(binaryName, dest);
103
159
  if (process.platform !== "win32") {
104
160
  fs.chmodSync(dest, 0o755);
105
161
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genesis-agent/channel-slack",
3
- "version": "0.5.9",
3
+ "version": "0.5.10",
4
4
  "description": "Slack channel adapter for Genesis — DMs, file uploads, threads",
5
5
  "license": "MIT",
6
6
  "repository": {