@dk/hipp 0.1.19 → 0.1.20

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 (3) hide show
  1. package/README.md +23 -16
  2. package/hipp.js +21 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -109,32 +109,36 @@ The manifest contains:
109
109
  {
110
110
  "origin": "git@github.com:dk/your-package.git",
111
111
  "tag": "v1.0.0",
112
+ "revision": "<git-commit-hash>",
112
113
  "hash": "<sha256-of-tarball>",
113
114
  "signature": "<base64-ed25519-signature>",
114
115
  "name": "Jane Developer",
115
- "email": "jane@example.com"
116
+ "email": "jane@example.com",
117
+ "npm": "10.2.4",
118
+ "node": "v20.11.0"
116
119
  }
117
120
  ```
118
121
 
119
122
  **Step 2: Clone git and verify**
120
123
 
121
124
  3. Clone the repository at the tagged commit (using origin/tag from manifest)
122
- 4. Stage all tracked files
123
- 5. Run `npm pack` to create a tarball
124
- 6. Compute SHA256 hash of the clean tarball
125
- 7. Compare with the `hash` field from the npm manifest
125
+ 4. Verify the cloned commit hash matches the `revision` field in manifest
126
+ 5. Stage all tracked files
127
+ 6. Run `npm pack` to create a tarball
128
+ 7. Compute SHA256 hash of the clean tarball
129
+ 8. Compare with the `hash` field from the npm manifest
126
130
 
127
131
  **Step 3: Verify signature**
128
132
 
129
- 8. Read `hipp.pub` from the cloned repository
130
- 9. Verify the signature was created by signing:
131
- `hash + "\n" + origin + "\n" + tag + "\n" + name + "\n" + email`
133
+ 9. Read `hipp.pub` from the cloned repository
134
+ 10. Verify the signature was created by signing:
135
+ `hash + "\n" + origin + "\n" + tag + "\n" + revision + "\n" + name + "\n" + email`
132
136
 
133
137
  **Step 4: Rebuild verification**
134
138
 
135
- 10. Append the manifest to the staged README
136
- 11. Update the staged `package.json` version to match the tag
137
- 12. Run `npm pack` again and verify the hash matches the npm tarball
139
+ 11. Append the manifest to the staged README
140
+ 12. Update the staged `package.json` version to match the tag
141
+ 13. Run `npm pack` again and verify the hash matches the npm tarball
138
142
 
139
143
  ### Three Verification Checks
140
144
 
@@ -216,16 +220,19 @@ PERFORMANCE OF THIS SOFTWARE.
216
220
  Verify this package with [@dk/hipp](https://www.npmjs.com/package/@dk/hipp):
217
221
 
218
222
  ```bash
219
- npx @dk/hipp verify @dk/hipp@0.1.19
223
+ npx @dk/hipp verify @dk/hipp@0.1.20
220
224
  ```
221
225
 
222
226
  ```json
223
227
  {
224
228
  "origin": "git@github.com:dmytri/hipp.git",
225
- "tag": "v0.1.19",
226
- "hash": "adcdd07b563c5667d405b36ee1e391710e1baf4ee9434b1fd2f5a11c2acdecf0",
227
- "signature": "MdkA4AbDX4ofShqXKJxwWX+x+RWQJU16WpSkFvHU8LihgdIBJbsyNvzIfrjm+3cll2FdR5u3+/dwv+a0rHbUDw==",
229
+ "tag": "v0.1.20",
230
+ "revision": "1d5a16d3e837ffd79d4c6704cf1945f6d0b84a60",
231
+ "hash": "71fe169e31a68c92c249ae2a443a4062dc379b36bf854a290576e7b595ca4e58",
232
+ "signature": "UpVrjogkhwUyPvGj6bK4vOUj3p9R/JDvuDaupOibXFyK5FibLWzpMwjQWHJa78wYx4D4f/BmAn99J3Xt4icaDg==",
228
233
  "name": "Dmytri Kleiner",
229
- "email": "dev@dmytri.to"
234
+ "email": "dev@dmytri.to",
235
+ "npm": "11.12.1",
236
+ "node": "v25.8.2"
230
237
  }
231
238
  ```
package/hipp.js CHANGED
@@ -121,8 +121,8 @@ function verifySignature(data, signature, publicKey) {
121
121
  }, Buffer.from(signature, 'base64'));
122
122
  }
123
123
 
124
- function buildSignData(hash, origin, tag, name, email) {
125
- return `${hash}\n${origin}\n${tag}\n${name}\n${email}\n`;
124
+ function buildSignData(hash, origin, tag, revision, name, email) {
125
+ return `${hash}\n${origin}\n${tag}\n${revision}\n${name}\n${email}\n`;
126
126
  }
127
127
 
128
128
  function findLastJsonBlock(readmeContent) {
@@ -463,11 +463,11 @@ async function runVerify(packageSpec) {
463
463
 
464
464
  const npmReadme = fs.readFileSync(npmReadmePath, 'utf8');
465
465
  manifest = findLastJsonBlock(npmReadme);
466
- if (!manifest || !manifest.origin || !manifest.tag || !manifest.hash || !manifest.signature || !manifest.name || !manifest.email) {
466
+ if (!manifest || !manifest.origin || !manifest.tag || !manifest.revision || !manifest.hash || !manifest.signature || !manifest.name || !manifest.email) {
467
467
  fail(`❌ Manifest not found or invalid in README`);
468
468
  }
469
469
 
470
- const { origin: originUrl, tag, signature, name, email } = manifest;
470
+ const { origin: originUrl, tag, revision, signature, name, email, npm: npmVer, node: nodeVer } = manifest;
471
471
 
472
472
  log.info(`đŸŒŋ Cloning git origin at tag ${tag}...`);
473
473
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), `hipp-verify-git-`));
@@ -476,6 +476,12 @@ async function runVerify(packageSpec) {
476
476
  try {
477
477
  git(['clone', '--branch', tag, '--depth', '1', originUrl, tmpDir], { stdio: 'pipe' });
478
478
 
479
+ const clonedRevision = git(['rev-parse', 'HEAD'], { cwd: tmpDir });
480
+ if (clonedRevision !== revision) {
481
+ fail(`❌ Revision mismatch: manifest claims ${revision.slice(0, 12)} but tag points to ${clonedRevision.slice(0, 12)}`);
482
+ }
483
+ log.success(`đŸˇī¸ Revision verified: ${revision.slice(0, 12)}...`);
484
+
479
485
  const publicKeyPath = path.join(tmpDir, 'hipp.pub');
480
486
  if (!fs.existsSync(publicKeyPath)) {
481
487
  fail(`❌ hipp.pub not found in git at tag ${tag}`);
@@ -498,7 +504,7 @@ async function runVerify(packageSpec) {
498
504
  log.success(`🔒 Manifest hash verified`);
499
505
 
500
506
  log.info(`🔍 Check 1: Verifying signature...`);
501
- const signData = buildSignData(manifest.hash, originUrl, tag, name, email);
507
+ const signData = buildSignData(manifest.hash, originUrl, tag, revision, name, email);
502
508
  const signatureValid = verifySignature(signData, signature, publicKey);
503
509
  if (!signatureValid) {
504
510
  fail(`❌ Signature verification failed`);
@@ -540,6 +546,9 @@ async function runVerify(packageSpec) {
540
546
  log.info(`📍 Publisher: ${name} <${email}>`);
541
547
  log.info(`📍 Origin: ${originUrl}`);
542
548
  log.info(`📍 Tag: ${tag}`);
549
+ if (npmVer && nodeVer) {
550
+ log.info(`â„šī¸ npm: ${npmVer} | node: ${nodeVer}`);
551
+ }
543
552
  } finally {
544
553
  fs.rmSync(tmpDir, { recursive: true, force: true });
545
554
  fs.rmSync(stageDir, { recursive: true, force: true });
@@ -638,16 +647,22 @@ async function run() {
638
647
  }
639
648
 
640
649
  const { name, email } = getGitUserInfo();
641
- const dataToSign = buildSignData(tarballHash, provenance.remoteUrl, rawTag, name, email);
650
+ const revision = refInfo.head;
651
+ const npmVersion = runCmd('npm', ['--version']).stdout.trim();
652
+ const nodeVersion = process.version;
653
+ const dataToSign = buildSignData(tarballHash, provenance.remoteUrl, rawTag, revision, name, email);
642
654
  const signature = signContent(dataToSign, privateKey);
643
655
 
644
656
  const manifestJson = {
645
657
  origin: provenance.remoteUrl,
646
658
  tag: rawTag,
659
+ revision: revision,
647
660
  hash: tarballHash,
648
661
  signature: signature,
649
662
  name: name,
650
663
  email: email,
664
+ npm: npmVersion,
665
+ node: nodeVersion,
651
666
  };
652
667
 
653
668
  stagedReadme = stagedReadme.trimEnd() + '\n\n## Verify\n\n' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dk/hipp",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "High Integrity Package Publisher",
5
5
  "main": "hipp.js",
6
6
  "bin": {