aboutsummaryrefslogtreecommitdiff
path: root/modules/ext
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-06-19 18:01:04 +0200
committerAgando <roduccomm@gmail.com>2026-06-19 18:01:04 +0200
commit82270d6f2685d84d5c9b4a454ae7260de75d34cf (patch)
tree1827e5854589bff4f0bb4baa915f010dccc026ad /modules/ext
parent0eca39021874a673933ebb82b973002b682e7a4b (diff)
auto: 2026-06-19_18:01 changes
Diffstat (limited to 'modules/ext')
-rw-r--r--modules/ext/wpm.js43
1 files changed, 37 insertions, 6 deletions
diff --git a/modules/ext/wpm.js b/modules/ext/wpm.js
index 314e124..68ac9cb 100644
--- a/modules/ext/wpm.js
+++ b/modules/ext/wpm.js
@@ -57,11 +57,39 @@ class WpmModule {
if (this.installed[name]) return this.terminal.print(`Package "${name}" already installed. Use wpm update to reinstall.`, 'warning');
this.terminal.print(`Installing ${pkg.name} v${pkg.version}...`, 'info');
this.terminal.print(` ${pkg.desc}`, 'info');
- const success = await this.terminal.moduleManager.loadModuleFromURL(pkg.url);
- if (success) {
- this.installed[name] = { version: pkg.version, installed: new Date().toISOString() };
- this.saveInstalled();
- this.terminal.print(`"${name}" installed successfully!`, 'success');
+ // P0: SRI — fetch source, compute SHA-256, verify integrity before loading
+ try {
+ const res = await fetch(pkg.url);
+ if (!res.ok) throw new Error('HTTP ' + res.status);
+ const source = await res.text();
+ // Compute SHA-256 via Web Crypto API
+ const encoder = new TextEncoder();
+ const data = encoder.encode(source);
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
+ const hashHex = Array.from(new Uint8Array(hashBuffer))
+ .map(b => b.toString(16).padStart(2, '0')).join('');
+ // Verify if package declares a hash
+ if (pkg.hash) {
+ if (hashHex !== pkg.hash) {
+ this.terminal.print(`❌ INTEGRITY CHECK FAILED: hash mismatch!`, 'error');
+ this.terminal.print(` Expected: ${pkg.hash}`, 'error');
+ this.terminal.print(` Got: ${hashHex}`, 'error');
+ this.terminal.print(` Package may have been tampered with. Aborting.`, 'error');
+ return;
+ }
+ this.terminal.print(`✅ Integrity verified (SHA-256: ${hashHex.substring(0, 16)}...)`, 'success');
+ } else {
+ this.terminal.print(`⚠ No hash declared. Computed SHA-256: ${hashHex.substring(0, 24)}...`, 'warning');
+ }
+ // Load the verified source
+ const success = await this.terminal.moduleManager.loadModuleFromURL(pkg.url);
+ if (success) {
+ this.installed[name] = { version: pkg.version, installed: new Date().toISOString(), hash: hashHex };
+ this.saveInstalled();
+ this.terminal.print(`"${name}" installed successfully!`, 'success');
+ }
+ } catch (e) {
+ this.terminal.print(`Install failed: ${e.message}`, 'error');
}
}
async list() {
@@ -143,7 +171,10 @@ class WpmModule {
this.terminal.print(`Commands: ${pkg.commands.join(', ')}`);
this.terminal.print(`URL: ${pkg.url}`);
const installed = this.installed[name];
- if (installed) this.terminal.print(`Installed: ${installed.installed}`, 'success');
+ if (installed) {
+ this.terminal.print(`Installed: ${installed.installed}`, 'success');
+ if (installed.hash) this.terminal.print(`Hash: ${installed.hash.substring(0, 24)}...`, 'info');
+ }
else this.terminal.print('Not installed. Use: wpm install ' + name, 'info');
}