diff --git a/src/common/cid.js b/src/common/cid.js index e07b5fe5..0ed28e41 100644 --- a/src/common/cid.js +++ b/src/common/cid.js @@ -1,3 +1,4 @@ +import { equals } from "iso-base/utils"; import { CID } from "multiformats/cid"; import { sha256 } from "multiformats/hashes/sha2"; @@ -11,3 +12,13 @@ export async function create(code, data) { return cid.toString(); } + +/** + * @param {Uint8Array} data + * @param {string} expected + */ +export async function verify(data, expected) { + const expectedCid = CID.parse(expected); + const hash = await sha256.digest(data); + return equals(expectedCid.multihash.bytes, hash.bytes); +} diff --git a/src/common/utils.js b/src/common/utils.js index cd923d81..8ca9cfb4 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1,5 +1,4 @@ import { Temporal } from "@js-temporal/polyfill"; -import { base64url } from "iso-base/rfc4648"; import { xxh32r } from "xxh32/dist/raw.js"; /** diff --git a/src/components/processor/search/constants.js b/src/components/processor/search/constants.js index 6b9b527b..94d82b3c 100644 --- a/src/components/processor/search/constants.js +++ b/src/components/processor/search/constants.js @@ -23,10 +23,5 @@ export const SCHEMA = { no: /** @type {const} */ ("number"), }, }, - - // TODO: - // isFavorite: "boolean" as const, - // inPlaylists: [ ... ], - embeddings: /** @type {const} */ ("vector[512]"), }; diff --git a/src/components/processor/search/worker.js b/src/components/processor/search/worker.js index 96db4faf..4b58c729 100644 --- a/src/components/processor/search/worker.js +++ b/src/components/processor/search/worker.js @@ -1,6 +1,5 @@ import * as Orama from "@orama/orama"; import { xxh32 } from "xxh32"; -// import { pluginQPS } from "@orama/plugin-qps"; import { SCHEMA } from "./constants.js"; import { announce, ostiary, rpc } from "~/common/worker.js"; @@ -30,10 +29,6 @@ export const $supplyFingerprint = signal( // DATABASE //////////////////////////////////////////// -// TODO: -// * pluginEmbeddings -// * pluginQPS - /** * @type {Orama.OramaPlugin[]} */ @@ -42,11 +37,6 @@ const PLUGINS = []; const db = Orama.create({ schema: SCHEMA, plugins: PLUGINS, - // components: { - // TODO: - // https://docs.orama.com/open-source/usage/insert#remote-document-storing - // documentStore: { ... } - // }, }); //////////////////////////////////////////// @@ -122,6 +112,7 @@ ostiary((context) => { }); // Effects + // ------- // Communicate state effect(() => @@ -142,7 +133,6 @@ async function _search(params, tracks) { // @ts-ignore: No clue what the correct type is for this one sortBy, ...params, - // mode: "hybrid", threshold: 0, // AND operator: all search terms must match in at least one property limit: 10000, offset: tracks.length, diff --git a/src/components/transformer/output/bytes/dasl-sync/element.js b/src/components/transformer/output/bytes/dasl-sync/element.js index 33d9e976..c12e9f13 100644 --- a/src/components/transformer/output/bytes/dasl-sync/element.js +++ b/src/components/transformer/output/bytes/dasl-sync/element.js @@ -286,7 +286,6 @@ class DaslBytesSyncOutputTransformer extends OutputTransformer { }; return { - // TODO: Do we need this? Too big of a perf penalty? cid: await CID.create(0x71, encode(newInventory)), data: collection, inventory: newInventory, diff --git a/src/facets/l/index.js b/src/facets/l/index.js index 0bb8fde6..3545e83f 100644 --- a/src/facets/l/index.js +++ b/src/facets/l/index.js @@ -1,5 +1,6 @@ import foundation from "~/common/facets/foundation.js"; -import { createLoader } from "~/common/loader.js"; +import * as CID from "~/common/cid.js"; +import { createLoader, renderError } from "~/common/loader.js"; createLoader({ $type: "sh.diffuse.output.facet", @@ -8,12 +9,26 @@ createLoader({ const output = foundation.orchestrator.output(); return output.facets; }, - render(facet) { - // TODO: Validate if CID matches HTML + async render(facet) { const container = /** @type {HTMLDivElement} */ ( document.querySelector("#container") ); + if (facet.cid) { + const valid = await CID.verify( + new TextEncoder().encode(facet.html ?? ""), + facet.cid, + ); + + if (!valid) { + renderError( + container, + "CID mismatch: HTML content does not match the CID", + ); + return; + } + } + const range = document.createRange(); range.selectNode(container); const documentFragment = range.createContextualFragment(facet.html ?? ""); diff --git a/src/themes/l/index.js b/src/themes/l/index.js index b7f99085..c442562b 100644 --- a/src/themes/l/index.js +++ b/src/themes/l/index.js @@ -1,5 +1,6 @@ import foundation from "~/common/facets/foundation.js"; -import { createLoader } from "~/common/loader.js"; +import * as CID from "~/common/cid.js"; +import { createLoader, renderError } from "~/common/loader.js"; createLoader({ $type: "sh.diffuse.output.theme", @@ -8,8 +9,22 @@ createLoader({ const output = foundation.orchestrator.output(); return output.themes; }, - render(theme) { - // TODO: Validate if CID matches HTML + async render(theme) { + if (theme.cid) { + const valid = await CID.verify( + new TextEncoder().encode(theme.html ?? ""), + theme.cid, + ); + + if (!valid) { + renderError( + document.body, + "CID mismatch: HTML content does not match the CID", + ); + return; + } + } + const iframe = document.createElement("iframe"); iframe.srcdoc = theme.html ?? "";