UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

104 lines (102 loc) 3.88 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_runtime = require('./_virtual/_rolldown/runtime.cjs'); const require_fastkv = require('./fastkv.cjs'); let node_crypto = require("node:crypto"); //#region src/integrity.ts function computeSriHash(content) { return `sha384-${(0, node_crypto.createHash)("sha384").update(content).digest("base64")}`; } async function computeSriHashForUrl(url) { try { const entryUrl = resolveEntryUrl(url); const response = await fetch(entryUrl); if (!response.ok) { console.warn(`[SRI] Failed to fetch ${entryUrl}: ${response.status} ${response.statusText}`); return null; } return computeSriHash(Buffer.from(await response.arrayBuffer())); } catch (error) { console.warn(`[SRI] Error computing integrity for ${url}:`, error instanceof Error ? error.message : error); return null; } } function resolveEntryUrl(url) { if (url.endsWith("/remoteEntry.js")) return url; if (url.endsWith("/mf-manifest.json")) return `${url.replace(/\/mf-manifest\.json$/, "")}/remoteEntry.js`; return `${url.replace(/\/$/, "")}/remoteEntry.js`; } async function verifySriForUrl(url, expectedIntegrity) { const entryUrl = resolveEntryUrl(url); const response = await fetch(entryUrl); if (!response.ok) { console.warn(`[SRI] Failed to fetch ${entryUrl} for verification: ${response.status}`); return; } const computed = computeSriHash(Buffer.from(await response.arrayBuffer())); if (computed !== expectedIntegrity) throw new Error(`[SRI] Integrity check failed for ${entryUrl}\n Expected: ${expectedIntegrity}\n Computed: ${computed}`); } var IntegrityRegistry = class { hashes = /* @__PURE__ */ new Map(); register(url, integrity) { this.hashes.set(url, integrity); } registerEntry(baseUrl, integrity) { this.hashes.set(resolveEntryUrl(baseUrl), integrity); } get(url) { return this.hashes.get(url); } has(url) { return this.hashes.has(url); } entries() { return this.hashes.entries(); } }; function extractIntegrityHashes(config) { const hashes = /* @__PURE__ */ new Map(); const app = config.app; const plugins = config.plugins; if (app) { for (const [, entry] of Object.entries(app)) if (entry?.integrity && entry?.production) hashes.set(resolveEntryUrl(entry.production), entry.integrity); } if (plugins) { for (const [, entry] of Object.entries(plugins)) if (entry?.integrity && entry?.production) hashes.set(resolveEntryUrl(entry.production), entry.integrity); } return hashes; } async function verifyConfigAgainstChain(localConfig, bosUrl) { const mismatches = []; let chainConfig; try { chainConfig = await require_fastkv.fetchBosConfigFromFastKv(bosUrl); } catch (error) { console.warn(`[Attestation] Failed to fetch on-chain config: ${error instanceof Error ? error.message : String(error)}`); return { verified: false, mismatches: ["chain-fetch-failed"] }; } const localHashes = extractIntegrityHashes(localConfig); const chainHashes = extractIntegrityHashes(chainConfig); for (const [url, chainHash] of chainHashes) { const localHash = localHashes.get(url); if (localHash && localHash !== chainHash) { mismatches.push(url); console.error(`[Attestation] Integrity mismatch for ${url}\n Local: ${localHash}\n Chain: ${chainHash}`); } } if (mismatches.length === 0 && localHashes.size > 0) console.log(`[Attestation] Local config verified against on-chain anchor (${localHashes.size} entries checked)`); return { verified: mismatches.length === 0, mismatches }; } //#endregion exports.IntegrityRegistry = IntegrityRegistry; exports.computeSriHash = computeSriHash; exports.computeSriHashForUrl = computeSriHashForUrl; exports.resolveEntryUrl = resolveEntryUrl; exports.verifyConfigAgainstChain = verifyConfigAgainstChain; exports.verifySriForUrl = verifySriForUrl; //# sourceMappingURL=integrity.cjs.map