git-userhub 3.0.8 → 3.0.9
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/bin/git-user.js +13 -140
- package/package.json +3 -2
package/bin/git-user.js
CHANGED
|
@@ -4,154 +4,27 @@ const { spawn } = require('child_process');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const os = require('os');
|
|
7
|
-
const https = require('https');
|
|
8
|
-
const crypto = require('crypto');
|
|
9
|
-
const tar = require('tar');
|
|
10
|
-
const PKG_JSON = require('../package.json');
|
|
11
|
-
|
|
12
|
-
const REPO = 'divyo-argha/git-user';
|
|
13
|
-
const VERSION = `v${PKG_JSON.version}`;
|
|
14
|
-
|
|
15
|
-
// --- START PINNED HASHES ---
|
|
16
|
-
const PINNED_HASHES = {
|
|
17
|
-
"git-user_darwin_arm64.tar.gz": {
|
|
18
|
-
"archive": "759e6a4137bc9caed58b393f751fa4c670a3dea98ef072a6551f38d41a9fc9ce",
|
|
19
|
-
"binary": "9b39841ca909f8dfcffff9a856771a65a8615ffb5e872e4c1108f0fa2e0d1752"
|
|
20
|
-
},
|
|
21
|
-
"git-user_darwin_x86_64.tar.gz": {
|
|
22
|
-
"archive": "eda5a46ea9f440174408d33659de38b7623da28b94ee447a3dc7fa509ffced83",
|
|
23
|
-
"binary": "efd1e62a40659f5e9132448ae5d1c5a5f23069a5277db73641de726cd28c55f1"
|
|
24
|
-
},
|
|
25
|
-
"git-user_linux_arm64.tar.gz": {
|
|
26
|
-
"archive": "3e311264bedf0672eee3625396d2e42d1c72d2a263a56fe2a7de9e5c54a2e2d3",
|
|
27
|
-
"binary": "f177a44c4c7d0a79840a404b669ce924c0117d58db6d407880007684efea64a2"
|
|
28
|
-
},
|
|
29
|
-
"git-user_linux_x86_64.tar.gz": {
|
|
30
|
-
"archive": "aab7e800a2b49a265409e0fbc3c64d4282b334bca222ea975532bd92dc7869dc",
|
|
31
|
-
"binary": "31172516986f3020bda2d5186ef7034919c09690399f849dcc980b542ed060f8"
|
|
32
|
-
},
|
|
33
|
-
"git-user_windows_x86_64.tar.gz": {
|
|
34
|
-
"archive": "eee27a75cfa131053b0901d8432216881aae25fda4586258b9b357ffa3558455",
|
|
35
|
-
"binary": "36e2ebc6272fe828b9b6a49d2623a049d001e826cca2c6ad428f178e9ca09403"
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
// --- END PINNED HASHES ---
|
|
39
7
|
|
|
40
8
|
const platform = os.platform();
|
|
41
9
|
const arch = os.arch();
|
|
42
|
-
|
|
43
|
-
const platformMap = { 'darwin': 'darwin', 'linux': 'linux', 'win32': 'windows' };
|
|
44
|
-
const archMap = { 'x64': 'x86_64', 'arm64': 'arm64' };
|
|
45
|
-
|
|
46
|
-
const osName = platformMap[platform];
|
|
47
|
-
const archName = archMap[arch];
|
|
48
10
|
const ext = platform === 'win32' ? '.exe' : '';
|
|
49
11
|
|
|
50
|
-
if (!osName || !archName) {
|
|
51
|
-
console.error(`❌ Unsupported platform: ${platform} ${arch}`);
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
12
|
const finalBinaryName = `git-user-${platform}-${arch}${ext}`;
|
|
56
13
|
const finalBinaryPath = path.join(__dirname, finalBinaryName);
|
|
57
|
-
const assetName = `git-user_${osName}_${archName}.tar.gz`;
|
|
58
|
-
const pinnedData = PINNED_HASHES[assetName];
|
|
59
14
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return hash.digest('hex');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function computeHash(file) {
|
|
68
|
-
return new Promise((resolve, reject) => {
|
|
69
|
-
const hash = crypto.createHash('sha256');
|
|
70
|
-
const stream = fs.createReadStream(file);
|
|
71
|
-
stream.on('data', d => hash.update(d));
|
|
72
|
-
stream.on('end', () => resolve(hash.digest('hex')));
|
|
73
|
-
stream.on('error', reject);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function runBinary() {
|
|
78
|
-
if (pinnedData) {
|
|
79
|
-
const currentHash = computeHashSync(finalBinaryPath);
|
|
80
|
-
if (currentHash !== pinnedData.binary) {
|
|
81
|
-
console.error(`❌ Security Error: Cached binary hash mismatch! Deleting compromised binary.`);
|
|
82
|
-
fs.unlinkSync(finalBinaryPath);
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const child = spawn(finalBinaryPath, process.argv.slice(2), {
|
|
88
|
-
stdio: 'inherit',
|
|
89
|
-
shell: false
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
child.on('exit', (code) => process.exit(code || 0));
|
|
93
|
-
child.on('error', (err) => {
|
|
94
|
-
console.error('❌ Failed to start git-user:', err.message);
|
|
95
|
-
process.exit(1);
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (fs.existsSync(finalBinaryPath)) {
|
|
100
|
-
runBinary();
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// FIRST RUN: Download binary
|
|
105
|
-
console.log(`[git-user] Downloading cryptographically signed binary for ${platform}-${arch}...`);
|
|
106
|
-
|
|
107
|
-
function fetchFile(url, dest) {
|
|
108
|
-
return new Promise((resolve, reject) => {
|
|
109
|
-
https.get(url, { headers: { 'User-Agent': 'node' } }, (res) => {
|
|
110
|
-
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
111
|
-
return fetchFile(res.headers.location, dest).then(resolve).catch(reject);
|
|
112
|
-
}
|
|
113
|
-
if (res.statusCode !== 200) return reject(new Error(`Download Error ${res.statusCode}`));
|
|
114
|
-
const file = fs.createWriteStream(dest);
|
|
115
|
-
res.pipe(file);
|
|
116
|
-
file.on('finish', () => { file.close(); resolve(); });
|
|
117
|
-
}).on('error', reject);
|
|
118
|
-
});
|
|
15
|
+
if (!fs.existsSync(finalBinaryPath)) {
|
|
16
|
+
console.error(`❌ git-user binary not found at ${finalBinaryPath}`);
|
|
17
|
+
console.error('Please reinstall the package: npm install -g git-userhub');
|
|
18
|
+
process.exit(1);
|
|
119
19
|
}
|
|
120
20
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
await fetchFile(downloadUrl, archivePath);
|
|
127
|
-
|
|
128
|
-
if (pinnedData) {
|
|
129
|
-
const archiveHash = await computeHash(archivePath);
|
|
130
|
-
if (archiveHash !== pinnedData.archive) {
|
|
131
|
-
throw new Error("Archive checksum mismatch! Connection may be compromised.");
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const binaryNameInArchive = platform === 'win32' ? 'git-user.exe' : 'git-user';
|
|
136
|
-
await tar.extract({
|
|
137
|
-
file: archivePath,
|
|
138
|
-
cwd: __dirname,
|
|
139
|
-
filter: (p) => p.replace(/^\.\//, '') === binaryNameInArchive
|
|
140
|
-
});
|
|
21
|
+
const child = spawn(finalBinaryPath, process.argv.slice(2), {
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
shell: false
|
|
24
|
+
});
|
|
141
25
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
fs.unlinkSync(archivePath);
|
|
148
|
-
|
|
149
|
-
console.log(`[git-user] Installation and verification complete.\n`);
|
|
150
|
-
runBinary();
|
|
151
|
-
} catch (err) {
|
|
152
|
-
console.error(`\n❌ git-user installation failed: ${err.message}`);
|
|
153
|
-
process.exit(1);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
install();
|
|
26
|
+
child.on('exit', (code) => process.exit(code || 0));
|
|
27
|
+
child.on('error', (err) => {
|
|
28
|
+
console.error('❌ Failed to start git-user:', err.message);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-userhub",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.9",
|
|
4
4
|
"description": "Switch Git accounts in one command. No config editing. No SSH key chaos.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"git-user": "bin/git-user.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
9
|
"test": "echo \"No tests yet\" && exit 0",
|
|
10
|
-
"prepublishOnly": "node scripts/inject-hashes.js"
|
|
10
|
+
"prepublishOnly": "node scripts/inject-hashes.js",
|
|
11
|
+
"postinstall": "node scripts/install.js"
|
|
11
12
|
},
|
|
12
13
|
"keywords": [
|
|
13
14
|
"git",
|