donsetch 1.1.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/install.js +20 -6
- package/package.json +1 -1
package/install.js
CHANGED
|
@@ -18,7 +18,7 @@ const https = require('https');
|
|
|
18
18
|
const crypto = require('crypto');
|
|
19
19
|
const fs = require('fs');
|
|
20
20
|
const path = require('path');
|
|
21
|
-
const {
|
|
21
|
+
const { execFileSync } = require('child_process');
|
|
22
22
|
|
|
23
23
|
const REPO = 'dondai44423/donsetch';
|
|
24
24
|
const VERSION = require('./package.json').version;
|
|
@@ -61,15 +61,27 @@ const baseUrl = `https://github.com/${REPO}/releases/download/${TAG}`;
|
|
|
61
61
|
const assetUrl = `${baseUrl}/${plat.asset}`;
|
|
62
62
|
const checksumUrl = `${baseUrl}/${plat.asset}.sha256`;
|
|
63
63
|
|
|
64
|
-
// ── download with redirect following
|
|
64
|
+
// ── download with redirect following (max 5 hops) ───────────────
|
|
65
65
|
function download(url, dest) {
|
|
66
66
|
return new Promise((resolve, reject) => {
|
|
67
|
-
|
|
67
|
+
const MAX_REDIRECTS = 5;
|
|
68
|
+
function get(u, hops) {
|
|
69
|
+
if (hops > MAX_REDIRECTS) {
|
|
70
|
+
reject(new Error(`too many redirects for ${url}`));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
68
73
|
const opts = { headers: { 'Accept': 'application/octet-stream', 'User-Agent': 'donsetch-npm-installer' } };
|
|
69
74
|
https.get(u, opts, (res) => {
|
|
70
75
|
if ([301, 302, 303, 307, 308].includes(res.statusCode)) {
|
|
71
76
|
res.resume();
|
|
72
|
-
|
|
77
|
+
const loc = res.headers.location;
|
|
78
|
+
if (!loc) { reject(new Error(`redirect without Location from ${u}`)); return; }
|
|
79
|
+
// Stay on https: never follow a downgrade to cleartext.
|
|
80
|
+
if (loc.startsWith('http://')) {
|
|
81
|
+
reject(new Error(`refusing http:// downgrade redirect to ${loc}`));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
get(loc, hops + 1);
|
|
73
85
|
return;
|
|
74
86
|
}
|
|
75
87
|
if (res.statusCode !== 200) {
|
|
@@ -86,7 +98,7 @@ function download(url, dest) {
|
|
|
86
98
|
});
|
|
87
99
|
}).on('error', reject);
|
|
88
100
|
}
|
|
89
|
-
get(url);
|
|
101
|
+
get(url, 0);
|
|
90
102
|
});
|
|
91
103
|
}
|
|
92
104
|
|
|
@@ -119,7 +131,9 @@ async function main() {
|
|
|
119
131
|
|
|
120
132
|
// 4. Extract (tar is built into Linux, macOS, and Windows 10+)
|
|
121
133
|
console.log('donsetch: extracting...');
|
|
122
|
-
|
|
134
|
+
// execFileSync: no shell, no string interpolation — the install
|
|
135
|
+
// path (which can contain quotes/spaces) is passed as argv.
|
|
136
|
+
execFileSync('tar', ['xzf', tarball, '-C', binDir], { stdio: 'inherit' });
|
|
123
137
|
|
|
124
138
|
// 5. Cleanup
|
|
125
139
|
try { fs.unlinkSync(tarball); } catch (_) {}
|