@orbit-tools/cli 0.27.0 → 0.28.1
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/package.json +1 -1
- package/scripts/install-binary.js +24 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orbit-tools/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"mcpName": "io.github.constellation-works/orbit",
|
|
5
5
|
"description": "npm proxy for the Orbit CLI. Downloads the matching native binary from GitHub Releases on install and forwards all invocations.",
|
|
6
6
|
"bin": {
|
|
@@ -190,13 +190,14 @@ function normalizeTrustedReleaseKeys(trustedKeys) {
|
|
|
190
190
|
}
|
|
191
191
|
const notAfter = key.notAfter || null;
|
|
192
192
|
const revokedAt = key.revokedAt || null;
|
|
193
|
-
// Mirror the shell-side
|
|
193
|
+
// Mirror the shell-side date format check (release_date_number) so a malformed
|
|
194
194
|
// override like notAfter: "next month" fails closed instead of silently
|
|
195
195
|
// becoming "never expires" under lexicographic comparison.
|
|
196
|
-
|
|
196
|
+
// The length check also rejects trailing newlines, which JS's $ permits.
|
|
197
|
+
if (notAfter !== null && (notAfter.length !== 10 || !/^\d{4}-\d{2}-\d{2}$/.test(notAfter))) {
|
|
197
198
|
throw new Error(`trusted release signing key ${key.id} has invalid notAfter: ${notAfter} (expected YYYY-MM-DD)`);
|
|
198
199
|
}
|
|
199
|
-
if (revokedAt !== null && !/^\d{4}-\d{2}-\d{2}$/.test(revokedAt)) {
|
|
200
|
+
if (revokedAt !== null && (revokedAt.length !== 10 || !/^\d{4}-\d{2}-\d{2}$/.test(revokedAt))) {
|
|
200
201
|
throw new Error(`trusted release signing key ${key.id} has invalid revokedAt: ${revokedAt} (expected YYYY-MM-DD)`);
|
|
201
202
|
}
|
|
202
203
|
return {
|
|
@@ -320,6 +321,24 @@ function extractTarGz(archivePath, destDir) {
|
|
|
320
321
|
validateExtractedBinary(path.join(destDir, 'orbit'));
|
|
321
322
|
}
|
|
322
323
|
|
|
324
|
+
// Stage the binary beside `destPath` and rename it into place so `destPath`
|
|
325
|
+
// only ever holds a complete, executable file. The bin shim treats an existing
|
|
326
|
+
// file as installed, so a partial copy (ENOSPC, kill) must never land there.
|
|
327
|
+
function installBinary(sourcePath, destPath, fsImpl = fs) {
|
|
328
|
+
const tempPath = path.join(
|
|
329
|
+
path.dirname(destPath),
|
|
330
|
+
`.${path.basename(destPath)}.${process.pid}.${crypto.randomBytes(4).toString('hex')}.tmp`
|
|
331
|
+
);
|
|
332
|
+
try {
|
|
333
|
+
fsImpl.copyFileSync(sourcePath, tempPath, fs.constants.COPYFILE_EXCL);
|
|
334
|
+
fsImpl.chmodSync(tempPath, 0o755);
|
|
335
|
+
fsImpl.renameSync(tempPath, destPath);
|
|
336
|
+
} catch (err) {
|
|
337
|
+
fsImpl.rmSync(tempPath, { force: true });
|
|
338
|
+
throw err;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
323
342
|
async function main() {
|
|
324
343
|
if (process.env.ORBIT_SKIP_DOWNLOAD === '1') {
|
|
325
344
|
log('ORBIT_SKIP_DOWNLOAD=1 set; skipping binary download.');
|
|
@@ -374,8 +393,7 @@ async function main() {
|
|
|
374
393
|
if (!fs.existsSync(extractedBinary)) {
|
|
375
394
|
fail(`extracted archive did not contain 'orbit' binary at ${extractedBinary}`);
|
|
376
395
|
}
|
|
377
|
-
|
|
378
|
-
fs.chmodSync(BIN_PATH, 0o755);
|
|
396
|
+
installBinary(extractedBinary, BIN_PATH);
|
|
379
397
|
} finally {
|
|
380
398
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
381
399
|
}
|
|
@@ -394,6 +412,7 @@ module.exports = {
|
|
|
394
412
|
acknowledgeTrustedPublicKeyOverride,
|
|
395
413
|
acknowledgeTrustedKeysOverride,
|
|
396
414
|
extractTarGz,
|
|
415
|
+
installBinary,
|
|
397
416
|
normalizeTrustedReleaseKeys,
|
|
398
417
|
readTrustedReleaseKeys,
|
|
399
418
|
validateArchiveMembers,
|