@symbiosis-lab/moss 0.12.0 → 0.14.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.
Files changed (2) hide show
  1. package/lib/fetch.js +41 -8
  2. package/package.json +1 -1
package/lib/fetch.js CHANGED
@@ -92,26 +92,57 @@ async function download(url) {
92
92
  return Buffer.from(await res.arrayBuffer());
93
93
  }
94
94
 
95
- // Verifies bytes against the release's SHA256SUMS. Releases before v0.11.2
96
- // published no checksums; a missing SHA256SUMS is a warning, not a failure.
95
+ // The first release that published a SHA256SUMS file. Before it there is
96
+ // nothing to verify against; from it on, every release has one.
97
+ const CHECKSUMS_SINCE = [0, 11, 2];
98
+
99
+ // Must a missing checksum be fatal for this version? Anything unparseable
100
+ // answers yes: an unrecognised version string is not a licence to skip the
101
+ // only check on bytes we are about to mark executable.
102
+ function checksumsRequired(version) {
103
+ const parts = String(version).split('-')[0].split('.').map(Number);
104
+ if (parts.length !== 3 || parts.some((n) => !Number.isInteger(n))) return true;
105
+ for (let i = 0; i < 3; i += 1) {
106
+ if (parts[i] !== CHECKSUMS_SINCE[i]) return parts[i] > CHECKSUMS_SINCE[i];
107
+ }
108
+ return true;
109
+ }
110
+
111
+ // Verifies bytes against the release's SHA256SUMS.
112
+ //
113
+ // Every reason we might not reach a checksum — a non-200, a network error, a
114
+ // SHA256SUMS with no line for this asset — is reached over the same connection
115
+ // that just served the binary. So on a version that publishes checksums, taking
116
+ // any of them as permission to skip verification hands the skip to whoever
117
+ // controls that connection: suppress one small request and the binary installs
118
+ // unverified. Fail closed there, and keep the warning only for the pre-v0.11.2
119
+ // releases where the file genuinely does not exist.
97
120
  async function verifyChecksum(bytes, asset, version) {
121
+ const unverified = (reason) => {
122
+ if (checksumsRequired(version)) {
123
+ throw new Error(
124
+ `moss-npm: cannot verify moss v${version} (${asset}): ${reason}.\n` +
125
+ ' Every release from v0.11.2 on publishes SHA256SUMS, so this is either a\n' +
126
+ ' transient network fault or a tampered download. Not installing.'
127
+ );
128
+ }
129
+ console.warn(`moss-npm: ${reason}; skipping checksum verification (v${version} predates SHA256SUMS)`);
130
+ };
131
+
98
132
  let sums;
99
133
  try {
100
134
  const res = await fetch(`${RELEASES}/v${version}/SHA256SUMS`, { redirect: 'follow' });
101
135
  if (!res.ok) {
102
- console.warn(`moss-npm: no SHA256SUMS published for v${version}; skipping checksum verification`);
103
- return;
136
+ return unverified(`no SHA256SUMS published for v${version} (${res.status})`);
104
137
  }
105
138
  sums = await res.text();
106
139
  } catch (err) {
107
- console.warn(`moss-npm: could not fetch SHA256SUMS (${err.message}); skipping checksum verification`);
108
- return;
140
+ return unverified(`could not fetch SHA256SUMS (${err.message})`);
109
141
  }
110
142
 
111
143
  const line = sums.split('\n').find((l) => l.trim().endsWith(asset));
112
144
  if (!line) {
113
- console.warn(`moss-npm: SHA256SUMS has no entry for ${asset}; skipping checksum verification`);
114
- return;
145
+ return unverified(`SHA256SUMS has no entry for ${asset}`);
115
146
  }
116
147
 
117
148
  const expected = line.trim().split(/\s+/)[0];
@@ -141,10 +172,12 @@ async function fetchBinary() {
141
172
  }
142
173
 
143
174
  module.exports = {
175
+ checksumsRequired,
144
176
  fetchBinary,
145
177
  vendorBinary,
146
178
  resolveAsset,
147
179
  resolveBinary,
148
180
  resolveVersion,
149
181
  skipDownloadReason,
182
+ verifyChecksum,
150
183
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiosis-lab/moss",
3
- "version": "0.12.0",
3
+ "version": "0.14.1",
4
4
  "description": "moss on your PATH — npm wrapper that installs the moss CLI binary from moss-releases",
5
5
  "bin": {
6
6
  "moss": "bin/moss.js"