@graffiti-garden/implementation-decentralized 0.0.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.
- package/LICENSE +674 -0
- package/dist/1-services/1-authorization.d.ts +37 -0
- package/dist/1-services/1-authorization.d.ts.map +1 -0
- package/dist/1-services/2-dids-tests.d.ts +2 -0
- package/dist/1-services/2-dids-tests.d.ts.map +1 -0
- package/dist/1-services/2-dids.d.ts +9 -0
- package/dist/1-services/2-dids.d.ts.map +1 -0
- package/dist/1-services/3-storage-buckets-tests.d.ts +2 -0
- package/dist/1-services/3-storage-buckets-tests.d.ts.map +1 -0
- package/dist/1-services/3-storage-buckets.d.ts +11 -0
- package/dist/1-services/3-storage-buckets.d.ts.map +1 -0
- package/dist/1-services/4-inboxes-tests.d.ts +2 -0
- package/dist/1-services/4-inboxes-tests.d.ts.map +1 -0
- package/dist/1-services/4-inboxes.d.ts +87 -0
- package/dist/1-services/4-inboxes.d.ts.map +1 -0
- package/dist/1-services/utilities.d.ts +7 -0
- package/dist/1-services/utilities.d.ts.map +1 -0
- package/dist/2-primitives/1-string-encoding-tests.d.ts +2 -0
- package/dist/2-primitives/1-string-encoding-tests.d.ts.map +1 -0
- package/dist/2-primitives/1-string-encoding.d.ts +6 -0
- package/dist/2-primitives/1-string-encoding.d.ts.map +1 -0
- package/dist/2-primitives/2-content-addresses-tests.d.ts +2 -0
- package/dist/2-primitives/2-content-addresses-tests.d.ts.map +1 -0
- package/dist/2-primitives/2-content-addresses.d.ts +8 -0
- package/dist/2-primitives/2-content-addresses.d.ts.map +1 -0
- package/dist/2-primitives/3-channel-attestations-tests.d.ts +2 -0
- package/dist/2-primitives/3-channel-attestations-tests.d.ts.map +1 -0
- package/dist/2-primitives/3-channel-attestations.d.ts +13 -0
- package/dist/2-primitives/3-channel-attestations.d.ts.map +1 -0
- package/dist/2-primitives/4-allowed-attestations-tests.d.ts +2 -0
- package/dist/2-primitives/4-allowed-attestations-tests.d.ts.map +1 -0
- package/dist/2-primitives/4-allowed-attestations.d.ts +9 -0
- package/dist/2-primitives/4-allowed-attestations.d.ts.map +1 -0
- package/dist/3-protocol/1-sessions.d.ts +81 -0
- package/dist/3-protocol/1-sessions.d.ts.map +1 -0
- package/dist/3-protocol/2-handles-tests.d.ts +2 -0
- package/dist/3-protocol/2-handles-tests.d.ts.map +1 -0
- package/dist/3-protocol/2-handles.d.ts +13 -0
- package/dist/3-protocol/2-handles.d.ts.map +1 -0
- package/dist/3-protocol/3-object-encoding-tests.d.ts +2 -0
- package/dist/3-protocol/3-object-encoding-tests.d.ts.map +1 -0
- package/dist/3-protocol/3-object-encoding.d.ts +43 -0
- package/dist/3-protocol/3-object-encoding.d.ts.map +1 -0
- package/dist/3-protocol/4-graffiti.d.ts +79 -0
- package/dist/3-protocol/4-graffiti.d.ts.map +1 -0
- package/dist/3-protocol/login-dialog.html.d.ts +2 -0
- package/dist/3-protocol/login-dialog.html.d.ts.map +1 -0
- package/dist/browser/ajv-QBSREQSI.js +9 -0
- package/dist/browser/ajv-QBSREQSI.js.map +7 -0
- package/dist/browser/build-BXWPS7VK.js +2 -0
- package/dist/browser/build-BXWPS7VK.js.map +7 -0
- package/dist/browser/chunk-RFBBAUMM.js +2 -0
- package/dist/browser/chunk-RFBBAUMM.js.map +7 -0
- package/dist/browser/graffiti-KV3G3O72-URO7SJIJ.js +2 -0
- package/dist/browser/graffiti-KV3G3O72-URO7SJIJ.js.map +7 -0
- package/dist/browser/index.js +16 -0
- package/dist/browser/index.js.map +7 -0
- package/dist/browser/login-dialog.html-XUWYDNNI.js +44 -0
- package/dist/browser/login-dialog.html-XUWYDNNI.js.map +7 -0
- package/dist/browser/rock-salt-LI7DAH66-KPFEBIBO.js +2 -0
- package/dist/browser/rock-salt-LI7DAH66-KPFEBIBO.js.map +7 -0
- package/dist/browser/style-YUTCEBZV-RWYJV575.js +287 -0
- package/dist/browser/style-YUTCEBZV-RWYJV575.js.map +7 -0
- package/dist/cjs/1-services/1-authorization.js +317 -0
- package/dist/cjs/1-services/1-authorization.js.map +7 -0
- package/dist/cjs/1-services/2-dids-tests.js +44 -0
- package/dist/cjs/1-services/2-dids-tests.js.map +7 -0
- package/dist/cjs/1-services/2-dids.js +47 -0
- package/dist/cjs/1-services/2-dids.js.map +7 -0
- package/dist/cjs/1-services/3-storage-buckets-tests.js +123 -0
- package/dist/cjs/1-services/3-storage-buckets-tests.js.map +7 -0
- package/dist/cjs/1-services/3-storage-buckets.js +148 -0
- package/dist/cjs/1-services/3-storage-buckets.js.map +7 -0
- package/dist/cjs/1-services/4-inboxes-tests.js +145 -0
- package/dist/cjs/1-services/4-inboxes-tests.js.map +7 -0
- package/dist/cjs/1-services/4-inboxes.js +539 -0
- package/dist/cjs/1-services/4-inboxes.js.map +7 -0
- package/dist/cjs/1-services/utilities.js +75 -0
- package/dist/cjs/1-services/utilities.js.map +7 -0
- package/dist/cjs/2-primitives/1-string-encoding-tests.js +50 -0
- package/dist/cjs/2-primitives/1-string-encoding-tests.js.map +7 -0
- package/dist/cjs/2-primitives/1-string-encoding.js +46 -0
- package/dist/cjs/2-primitives/1-string-encoding.js.map +7 -0
- package/dist/cjs/2-primitives/2-content-addresses-tests.js +62 -0
- package/dist/cjs/2-primitives/2-content-addresses-tests.js.map +7 -0
- package/dist/cjs/2-primitives/2-content-addresses.js +53 -0
- package/dist/cjs/2-primitives/2-content-addresses.js.map +7 -0
- package/dist/cjs/2-primitives/3-channel-attestations-tests.js +130 -0
- package/dist/cjs/2-primitives/3-channel-attestations-tests.js.map +7 -0
- package/dist/cjs/2-primitives/3-channel-attestations.js +84 -0
- package/dist/cjs/2-primitives/3-channel-attestations.js.map +7 -0
- package/dist/cjs/2-primitives/4-allowed-attestations-tests.js +96 -0
- package/dist/cjs/2-primitives/4-allowed-attestations-tests.js.map +7 -0
- package/dist/cjs/2-primitives/4-allowed-attestations.js +68 -0
- package/dist/cjs/2-primitives/4-allowed-attestations.js.map +7 -0
- package/dist/cjs/3-protocol/1-sessions.js +473 -0
- package/dist/cjs/3-protocol/1-sessions.js.map +7 -0
- package/dist/cjs/3-protocol/2-handles-tests.js +39 -0
- package/dist/cjs/3-protocol/2-handles-tests.js.map +7 -0
- package/dist/cjs/3-protocol/2-handles.js +65 -0
- package/dist/cjs/3-protocol/2-handles.js.map +7 -0
- package/dist/cjs/3-protocol/3-object-encoding-tests.js +253 -0
- package/dist/cjs/3-protocol/3-object-encoding-tests.js.map +7 -0
- package/dist/cjs/3-protocol/3-object-encoding.js +287 -0
- package/dist/cjs/3-protocol/3-object-encoding.js.map +7 -0
- package/dist/cjs/3-protocol/4-graffiti.js +937 -0
- package/dist/cjs/3-protocol/4-graffiti.js.map +7 -0
- package/dist/cjs/3-protocol/login-dialog.html.js +67 -0
- package/dist/cjs/3-protocol/login-dialog.html.js.map +7 -0
- package/dist/cjs/index.js +32 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/index.spec.js +130 -0
- package/dist/cjs/index.spec.js.map +7 -0
- package/dist/esm/1-services/1-authorization.js +304 -0
- package/dist/esm/1-services/1-authorization.js.map +7 -0
- package/dist/esm/1-services/2-dids-tests.js +24 -0
- package/dist/esm/1-services/2-dids-tests.js.map +7 -0
- package/dist/esm/1-services/2-dids.js +27 -0
- package/dist/esm/1-services/2-dids.js.map +7 -0
- package/dist/esm/1-services/3-storage-buckets-tests.js +103 -0
- package/dist/esm/1-services/3-storage-buckets-tests.js.map +7 -0
- package/dist/esm/1-services/3-storage-buckets.js +132 -0
- package/dist/esm/1-services/3-storage-buckets.js.map +7 -0
- package/dist/esm/1-services/4-inboxes-tests.js +125 -0
- package/dist/esm/1-services/4-inboxes-tests.js.map +7 -0
- package/dist/esm/1-services/4-inboxes.js +533 -0
- package/dist/esm/1-services/4-inboxes.js.map +7 -0
- package/dist/esm/1-services/utilities.js +60 -0
- package/dist/esm/1-services/utilities.js.map +7 -0
- package/dist/esm/2-primitives/1-string-encoding-tests.js +33 -0
- package/dist/esm/2-primitives/1-string-encoding-tests.js.map +7 -0
- package/dist/esm/2-primitives/1-string-encoding.js +26 -0
- package/dist/esm/2-primitives/1-string-encoding.js.map +7 -0
- package/dist/esm/2-primitives/2-content-addresses-tests.js +45 -0
- package/dist/esm/2-primitives/2-content-addresses-tests.js.map +7 -0
- package/dist/esm/2-primitives/2-content-addresses.js +33 -0
- package/dist/esm/2-primitives/2-content-addresses.js.map +7 -0
- package/dist/esm/2-primitives/3-channel-attestations-tests.js +116 -0
- package/dist/esm/2-primitives/3-channel-attestations-tests.js.map +7 -0
- package/dist/esm/2-primitives/3-channel-attestations.js +69 -0
- package/dist/esm/2-primitives/3-channel-attestations.js.map +7 -0
- package/dist/esm/2-primitives/4-allowed-attestations-tests.js +82 -0
- package/dist/esm/2-primitives/4-allowed-attestations-tests.js.map +7 -0
- package/dist/esm/2-primitives/4-allowed-attestations.js +51 -0
- package/dist/esm/2-primitives/4-allowed-attestations.js.map +7 -0
- package/dist/esm/3-protocol/1-sessions.js +465 -0
- package/dist/esm/3-protocol/1-sessions.js.map +7 -0
- package/dist/esm/3-protocol/2-handles-tests.js +19 -0
- package/dist/esm/3-protocol/2-handles-tests.js.map +7 -0
- package/dist/esm/3-protocol/2-handles.js +45 -0
- package/dist/esm/3-protocol/2-handles.js.map +7 -0
- package/dist/esm/3-protocol/3-object-encoding-tests.js +248 -0
- package/dist/esm/3-protocol/3-object-encoding-tests.js.map +7 -0
- package/dist/esm/3-protocol/3-object-encoding.js +280 -0
- package/dist/esm/3-protocol/3-object-encoding.js.map +7 -0
- package/dist/esm/3-protocol/4-graffiti.js +957 -0
- package/dist/esm/3-protocol/4-graffiti.js.map +7 -0
- package/dist/esm/3-protocol/login-dialog.html.js +47 -0
- package/dist/esm/3-protocol/login-dialog.html.js.map +7 -0
- package/dist/esm/index.js +14 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/index.spec.js +133 -0
- package/dist/esm/index.spec.js.map +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.spec.d.ts +2 -0
- package/dist/index.spec.d.ts.map +1 -0
- package/package.json +62 -0
- package/src/1-services/1-authorization.ts +399 -0
- package/src/1-services/2-dids-tests.ts +24 -0
- package/src/1-services/2-dids.ts +30 -0
- package/src/1-services/3-storage-buckets-tests.ts +121 -0
- package/src/1-services/3-storage-buckets.ts +183 -0
- package/src/1-services/4-inboxes-tests.ts +154 -0
- package/src/1-services/4-inboxes.ts +722 -0
- package/src/1-services/utilities.ts +65 -0
- package/src/2-primitives/1-string-encoding-tests.ts +33 -0
- package/src/2-primitives/1-string-encoding.ts +33 -0
- package/src/2-primitives/2-content-addresses-tests.ts +46 -0
- package/src/2-primitives/2-content-addresses.ts +42 -0
- package/src/2-primitives/3-channel-attestations-tests.ts +125 -0
- package/src/2-primitives/3-channel-attestations.ts +95 -0
- package/src/2-primitives/4-allowed-attestations-tests.ts +86 -0
- package/src/2-primitives/4-allowed-attestations.ts +69 -0
- package/src/3-protocol/1-sessions.ts +601 -0
- package/src/3-protocol/2-handles-tests.ts +17 -0
- package/src/3-protocol/2-handles.ts +60 -0
- package/src/3-protocol/3-object-encoding-tests.ts +269 -0
- package/src/3-protocol/3-object-encoding.ts +396 -0
- package/src/3-protocol/4-graffiti.ts +1265 -0
- package/src/3-protocol/login-dialog.html.ts +43 -0
- package/src/index.spec.ts +158 -0
- package/src/index.ts +16 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var handles_exports = {};
|
|
20
|
+
__export(handles_exports, {
|
|
21
|
+
Handles: () => Handles
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(handles_exports);
|
|
24
|
+
var import_api = require("@graffiti-garden/api");
|
|
25
|
+
var import_dids = require("../1-services/2-dids");
|
|
26
|
+
const HANDLE_DID_PREFIX = "did:web:";
|
|
27
|
+
class Handles {
|
|
28
|
+
constructor(services) {
|
|
29
|
+
this.services = services;
|
|
30
|
+
}
|
|
31
|
+
actorToHandle = async (actor) => {
|
|
32
|
+
const actorDocument = await this.services.dids.resolve(actor);
|
|
33
|
+
const handleDid = actorDocument.alsoKnownAs?.at(0);
|
|
34
|
+
if (!handleDid) {
|
|
35
|
+
throw new import_api.GraffitiErrorNotFound(
|
|
36
|
+
`Handle for actor DID ${actor} not found`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (!handleDid.startsWith(HANDLE_DID_PREFIX)) {
|
|
40
|
+
throw new Error(`Handle DID ${handleDid} is not a valid handle`);
|
|
41
|
+
}
|
|
42
|
+
const handle = handleDid.slice(HANDLE_DID_PREFIX.length);
|
|
43
|
+
const handleDocument = await this.services.dids.resolve(handleDid);
|
|
44
|
+
if (!handleDocument.alsoKnownAs || !handleDocument.alsoKnownAs.includes(actor)) {
|
|
45
|
+
throw new Error(`Handle ${handle} does not match actor ${actor}`);
|
|
46
|
+
}
|
|
47
|
+
return handle;
|
|
48
|
+
};
|
|
49
|
+
handleToActor = async (handle) => {
|
|
50
|
+
const handleDid = `${HANDLE_DID_PREFIX}${handle}`;
|
|
51
|
+
const handleDocument = await this.services.dids.resolve(handleDid);
|
|
52
|
+
const actor = handleDocument.alsoKnownAs?.at(0);
|
|
53
|
+
if (!actor) {
|
|
54
|
+
throw new import_api.GraffitiErrorNotFound(
|
|
55
|
+
`Actor for handle DID ${handleDid} not found`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
const actorDocument = await this.services.dids.resolve(actor);
|
|
59
|
+
if (!actorDocument.alsoKnownAs || !actorDocument.alsoKnownAs.includes(handleDid)) {
|
|
60
|
+
throw new Error(`Actor ${actor} does not match handle ${handle}`);
|
|
61
|
+
}
|
|
62
|
+
return actor;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=2-handles.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/3-protocol/2-handles.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Graffiti } from \"@graffiti-garden/api\";\nimport { GraffitiErrorNotFound } from \"@graffiti-garden/api\";\nimport { DecentralizedIdentifiers } from \"../1-services/2-dids\";\n\n// Handles used a fixed method\nconst HANDLE_DID_PREFIX = \"did:web:\";\n\nexport class Handles {\n constructor(\n protected readonly services: { dids: DecentralizedIdentifiers },\n ) {}\n\n actorToHandle: Graffiti[\"actorToHandle\"] = async (actor) => {\n const actorDocument = await this.services.dids.resolve(actor);\n\n const handleDid = actorDocument.alsoKnownAs?.at(0);\n if (!handleDid) {\n throw new GraffitiErrorNotFound(\n `Handle for actor DID ${actor} not found`,\n );\n }\n if (!handleDid.startsWith(HANDLE_DID_PREFIX)) {\n throw new Error(`Handle DID ${handleDid} is not a valid handle`);\n }\n\n const handle = handleDid.slice(HANDLE_DID_PREFIX.length);\n\n const handleDocument = await this.services.dids.resolve(handleDid);\n if (\n !handleDocument.alsoKnownAs ||\n !handleDocument.alsoKnownAs.includes(actor)\n ) {\n throw new Error(`Handle ${handle} does not match actor ${actor}`);\n }\n\n return handle;\n };\n\n handleToActor: Graffiti[\"handleToActor\"] = async (handle) => {\n const handleDid = `${HANDLE_DID_PREFIX}${handle}`;\n const handleDocument = await this.services.dids.resolve(handleDid);\n\n const actor = handleDocument.alsoKnownAs?.at(0);\n if (!actor) {\n throw new GraffitiErrorNotFound(\n `Actor for handle DID ${handleDid} not found`,\n );\n }\n\n const actorDocument = await this.services.dids.resolve(actor);\n if (\n !actorDocument.alsoKnownAs ||\n !actorDocument.alsoKnownAs.includes(handleDid)\n ) {\n throw new Error(`Actor ${actor} does not match handle ${handle}`);\n }\n\n return actor;\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAAsC;AACtC,kBAAyC;AAGzC,MAAM,oBAAoB;AAEnB,MAAM,QAAQ;AAAA,EACnB,YACqB,UACnB;AADmB;AAAA,EAClB;AAAA,EAEH,gBAA2C,OAAO,UAAU;AAC1D,UAAM,gBAAgB,MAAM,KAAK,SAAS,KAAK,QAAQ,KAAK;AAE5D,UAAM,YAAY,cAAc,aAAa,GAAG,CAAC;AACjD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR,wBAAwB,KAAK;AAAA,MAC/B;AAAA,IACF;AACA,QAAI,CAAC,UAAU,WAAW,iBAAiB,GAAG;AAC5C,YAAM,IAAI,MAAM,cAAc,SAAS,wBAAwB;AAAA,IACjE;AAEA,UAAM,SAAS,UAAU,MAAM,kBAAkB,MAAM;AAEvD,UAAM,iBAAiB,MAAM,KAAK,SAAS,KAAK,QAAQ,SAAS;AACjE,QACE,CAAC,eAAe,eAChB,CAAC,eAAe,YAAY,SAAS,KAAK,GAC1C;AACA,YAAM,IAAI,MAAM,UAAU,MAAM,yBAAyB,KAAK,EAAE;AAAA,IAClE;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,gBAA2C,OAAO,WAAW;AAC3D,UAAM,YAAY,GAAG,iBAAiB,GAAG,MAAM;AAC/C,UAAM,iBAAiB,MAAM,KAAK,SAAS,KAAK,QAAQ,SAAS;AAEjE,UAAM,QAAQ,eAAe,aAAa,GAAG,CAAC;AAC9C,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,wBAAwB,SAAS;AAAA,MACnC;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,KAAK,SAAS,KAAK,QAAQ,KAAK;AAC5D,QACE,CAAC,cAAc,eACf,CAAC,cAAc,YAAY,SAAS,SAAS,GAC7C;AACA,YAAM,IAAI,MAAM,SAAS,KAAK,0BAA0B,MAAM,EAAE;AAAA,IAClE;AAEA,WAAO;AAAA,EACT;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var object_encoding_tests_exports = {};
|
|
20
|
+
__export(object_encoding_tests_exports, {
|
|
21
|
+
objectEncodingTests: () => objectEncodingTests
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(object_encoding_tests_exports);
|
|
24
|
+
var import_vitest = require("vitest");
|
|
25
|
+
var import_object_encoding = require("./3-object-encoding.js");
|
|
26
|
+
var import_utils = require("@noble/hashes/utils.js");
|
|
27
|
+
var import_string_encoding = require("../2-primitives/1-string-encoding.js");
|
|
28
|
+
var import_content_addresses = require("../2-primitives/2-content-addresses.js");
|
|
29
|
+
var import_channel_attestations = require("../2-primitives/3-channel-attestations.js");
|
|
30
|
+
var import_allowed_attestations = require("../2-primitives/4-allowed-attestations.js");
|
|
31
|
+
var import_dag_cbor = require("@ipld/dag-cbor");
|
|
32
|
+
var import_api = require("@graffiti-garden/api");
|
|
33
|
+
function objectEncodingTests() {
|
|
34
|
+
(0, import_vitest.describe)("object Urls", () => {
|
|
35
|
+
for (const actor of [
|
|
36
|
+
"did:plc:alsdkjfkdjf",
|
|
37
|
+
"did:web:example.com/someone",
|
|
38
|
+
"did:example:123456789abcdefghi\u{1F47B}"
|
|
39
|
+
]) {
|
|
40
|
+
(0, import_vitest.test)(`encodeObjectUrl encodes and decodes correctly with actor: ${actor}`, async () => {
|
|
41
|
+
const contentAddressBytes = (0, import_utils.randomBytes)();
|
|
42
|
+
const contentAddress = await new import_string_encoding.StringEncoder().encode(
|
|
43
|
+
import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
|
|
44
|
+
contentAddressBytes
|
|
45
|
+
);
|
|
46
|
+
const url = (0, import_object_encoding.encodeObjectUrl)(actor, contentAddress);
|
|
47
|
+
const decoded = (0, import_object_encoding.decodeObjectUrl)(url);
|
|
48
|
+
(0, import_vitest.expect)(decoded.actor).toBe(actor);
|
|
49
|
+
(0, import_vitest.expect)(decoded.contentAddress).toBe(contentAddress);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
for (const invalidUrl of [
|
|
53
|
+
"http://example.com/not-an-object-url",
|
|
54
|
+
"graffiti:",
|
|
55
|
+
"graffiti:",
|
|
56
|
+
"graffiti:no-content-address",
|
|
57
|
+
"graffiti:too:many:parts"
|
|
58
|
+
]) {
|
|
59
|
+
(0, import_vitest.test)(`Invalid Graffiti URL: ${invalidUrl}`, () => {
|
|
60
|
+
(0, import_vitest.expect)(() => (0, import_object_encoding.decodeObjectUrl)(invalidUrl)).toThrow();
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
(0, import_vitest.describe)("object encoding and validation", async () => {
|
|
65
|
+
const objectEncoding = new import_object_encoding.ObjectEncoding({
|
|
66
|
+
stringEncoder: new import_string_encoding.StringEncoder(),
|
|
67
|
+
allowedAttestations: new import_allowed_attestations.AllowedAttestations(),
|
|
68
|
+
channelAttestations: new import_channel_attestations.ChannelAttestations(),
|
|
69
|
+
contentAddresses: new import_content_addresses.ContentAddresses()
|
|
70
|
+
});
|
|
71
|
+
const value = {
|
|
72
|
+
message: "Hello world!",
|
|
73
|
+
nested: {
|
|
74
|
+
foo: {
|
|
75
|
+
bar: 42
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
array: [1, "something \u{1F47B}", { key: "value" }]
|
|
79
|
+
};
|
|
80
|
+
const channels = ["channel1\u{1F47B}", "channel2"];
|
|
81
|
+
const allowed = ["did:web:noone.example.com", "did:web:someone.else.com"];
|
|
82
|
+
const actor = "did:web:someone.example.com";
|
|
83
|
+
const { allowedTickets, tags, objectBytes, object } = await objectEncoding.encode(
|
|
84
|
+
{
|
|
85
|
+
value,
|
|
86
|
+
channels,
|
|
87
|
+
allowed
|
|
88
|
+
},
|
|
89
|
+
actor
|
|
90
|
+
);
|
|
91
|
+
(0, import_vitest.assert)(Array.isArray(allowedTickets));
|
|
92
|
+
(0, import_vitest.test)("validate private", async () => {
|
|
93
|
+
await objectEncoding.validate(object, tags, objectBytes, {
|
|
94
|
+
allowedTickets
|
|
95
|
+
});
|
|
96
|
+
for (const [index, recipient] of allowed.entries()) {
|
|
97
|
+
const copy = JSON.parse(JSON.stringify(object));
|
|
98
|
+
const masked = (0, import_api.maskGraffitiObject)(copy, [], recipient);
|
|
99
|
+
await objectEncoding.validate(masked, tags, objectBytes, {
|
|
100
|
+
recipient,
|
|
101
|
+
allowedTicket: allowedTickets[index],
|
|
102
|
+
allowedIndex: index
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
(0, import_vitest.test)("incorrect value", async () => {
|
|
107
|
+
await (0, import_vitest.expect)(
|
|
108
|
+
objectEncoding.validate(
|
|
109
|
+
{
|
|
110
|
+
...object,
|
|
111
|
+
value: {
|
|
112
|
+
...object.value,
|
|
113
|
+
extra: "field"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
tags,
|
|
117
|
+
objectBytes,
|
|
118
|
+
{
|
|
119
|
+
allowedTickets
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
).rejects.toThrow();
|
|
123
|
+
});
|
|
124
|
+
(0, import_vitest.test)("incorrect content address", async () => {
|
|
125
|
+
const url = (0, import_object_encoding.encodeObjectUrl)(
|
|
126
|
+
actor,
|
|
127
|
+
await new import_string_encoding.StringEncoder().encode(
|
|
128
|
+
import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
|
|
129
|
+
(0, import_utils.randomBytes)()
|
|
130
|
+
)
|
|
131
|
+
);
|
|
132
|
+
await (0, import_vitest.expect)(
|
|
133
|
+
objectEncoding.validate(
|
|
134
|
+
{
|
|
135
|
+
...object,
|
|
136
|
+
url
|
|
137
|
+
},
|
|
138
|
+
[new TextEncoder().encode(url), ...tags.slice(1)],
|
|
139
|
+
objectBytes,
|
|
140
|
+
{
|
|
141
|
+
allowedTickets
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
).rejects.toThrow();
|
|
145
|
+
});
|
|
146
|
+
(0, import_vitest.test)("incorrect bytes", async () => {
|
|
147
|
+
const wrongObjectBytes = (0, import_utils.randomBytes)();
|
|
148
|
+
const correctContentAddress = (0, import_object_encoding.decodeObjectUrl)(object.url).contentAddress;
|
|
149
|
+
const correctContentAddressBytes = await new import_string_encoding.StringEncoder().decode(
|
|
150
|
+
correctContentAddress
|
|
151
|
+
);
|
|
152
|
+
const contentAddresses = new import_content_addresses.ContentAddresses();
|
|
153
|
+
const contentAddressMethod = await contentAddresses.getMethod(
|
|
154
|
+
correctContentAddressBytes
|
|
155
|
+
);
|
|
156
|
+
const wrongContentAddressBytes = await contentAddresses.register(
|
|
157
|
+
contentAddressMethod,
|
|
158
|
+
wrongObjectBytes
|
|
159
|
+
);
|
|
160
|
+
const wrongContentAddress = await new import_string_encoding.StringEncoder().encode(
|
|
161
|
+
import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
|
|
162
|
+
wrongContentAddressBytes
|
|
163
|
+
);
|
|
164
|
+
const wrongObjectUrl = (0, import_object_encoding.encodeObjectUrl)(actor, wrongContentAddress);
|
|
165
|
+
await (0, import_vitest.expect)(
|
|
166
|
+
objectEncoding.validate(
|
|
167
|
+
{
|
|
168
|
+
...object,
|
|
169
|
+
url: wrongObjectUrl
|
|
170
|
+
},
|
|
171
|
+
[new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],
|
|
172
|
+
wrongObjectBytes,
|
|
173
|
+
{
|
|
174
|
+
allowedTickets
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
).rejects.toThrow();
|
|
178
|
+
});
|
|
179
|
+
(0, import_vitest.test)("incorrect format", async () => {
|
|
180
|
+
const wrongData = {
|
|
181
|
+
not: "the expected format"
|
|
182
|
+
};
|
|
183
|
+
const wrongObjectBytes = (0, import_dag_cbor.encode)(wrongData);
|
|
184
|
+
const correctContentAddress = (0, import_object_encoding.decodeObjectUrl)(object.url).contentAddress;
|
|
185
|
+
const correctContentAddressBytes = await new import_string_encoding.StringEncoder().decode(
|
|
186
|
+
correctContentAddress
|
|
187
|
+
);
|
|
188
|
+
const contentAddresses = new import_content_addresses.ContentAddresses();
|
|
189
|
+
const contentAddressMethod = await contentAddresses.getMethod(
|
|
190
|
+
correctContentAddressBytes
|
|
191
|
+
);
|
|
192
|
+
const wrongContentAddressBytes = await contentAddresses.register(
|
|
193
|
+
contentAddressMethod,
|
|
194
|
+
wrongObjectBytes
|
|
195
|
+
);
|
|
196
|
+
const wrongContentAddress = await new import_string_encoding.StringEncoder().encode(
|
|
197
|
+
import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
|
|
198
|
+
wrongContentAddressBytes
|
|
199
|
+
);
|
|
200
|
+
const wrongObjectUrl = (0, import_object_encoding.encodeObjectUrl)(actor, wrongContentAddress);
|
|
201
|
+
await (0, import_vitest.expect)(
|
|
202
|
+
objectEncoding.validate(
|
|
203
|
+
{
|
|
204
|
+
...object,
|
|
205
|
+
url: wrongObjectUrl
|
|
206
|
+
},
|
|
207
|
+
[new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],
|
|
208
|
+
wrongObjectBytes,
|
|
209
|
+
{
|
|
210
|
+
allowedTickets
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
).rejects.toThrow();
|
|
214
|
+
});
|
|
215
|
+
(0, import_vitest.test)("missing allowed tickets", async () => {
|
|
216
|
+
await (0, import_vitest.expect)(
|
|
217
|
+
objectEncoding.validate(object, tags, objectBytes)
|
|
218
|
+
).rejects.toThrow();
|
|
219
|
+
});
|
|
220
|
+
(0, import_vitest.test)("wrong allowed tickets", async () => {
|
|
221
|
+
const wrongAllowedTickets = await Promise.all(
|
|
222
|
+
allowedTickets.map(
|
|
223
|
+
async (ticket) => (await new import_allowed_attestations.AllowedAttestations().attest(
|
|
224
|
+
import_allowed_attestations.ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,
|
|
225
|
+
"did:web:not-the-right.actor"
|
|
226
|
+
)).ticket
|
|
227
|
+
)
|
|
228
|
+
);
|
|
229
|
+
await (0, import_vitest.expect)(
|
|
230
|
+
objectEncoding.validate(object, tags, objectBytes, {
|
|
231
|
+
allowedTickets: wrongAllowedTickets
|
|
232
|
+
})
|
|
233
|
+
).rejects.toThrow();
|
|
234
|
+
});
|
|
235
|
+
(0, import_vitest.test)("wrong recipients", async () => {
|
|
236
|
+
const wrongRecipients = allowed.map((recipient) => recipient + "-wrong");
|
|
237
|
+
await (0, import_vitest.expect)(
|
|
238
|
+
objectEncoding.validate(
|
|
239
|
+
{
|
|
240
|
+
...object,
|
|
241
|
+
allowed: wrongRecipients
|
|
242
|
+
},
|
|
243
|
+
tags,
|
|
244
|
+
objectBytes,
|
|
245
|
+
{
|
|
246
|
+
allowedTickets
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
).rejects.toThrow();
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=3-object-encoding-tests.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/3-protocol/3-object-encoding-tests.ts"],
|
|
4
|
+
"sourcesContent": ["import { assert, describe, expect, test } from \"vitest\";\n\nimport {\n encodeObjectUrl,\n decodeObjectUrl,\n ObjectEncoding,\n} from \"./3-object-encoding.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\nimport {\n STRING_ENCODER_METHOD_BASE64URL,\n StringEncoder,\n} from \"../2-primitives/1-string-encoding.js\";\nimport { ContentAddresses } from \"../2-primitives/2-content-addresses.js\";\nimport { ChannelAttestations } from \"../2-primitives/3-channel-attestations.js\";\nimport {\n ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,\n AllowedAttestations,\n} from \"../2-primitives/4-allowed-attestations.js\";\nimport {\n encode as dagCborEncode,\n decode as dagCborDecode,\n} from \"@ipld/dag-cbor\";\nimport {\n maskGraffitiObject,\n type GraffitiObjectBase,\n} from \"@graffiti-garden/api\";\n\nexport function objectEncodingTests() {\n describe(\"object Urls\", () => {\n for (const actor of [\n \"did:plc:alsdkjfkdjf\",\n \"did:web:example.com/someone\",\n \"did:example:123456789abcdefghi\uD83D\uDC7B\",\n ]) {\n test(`encodeObjectUrl encodes and decodes correctly with actor: ${actor}`, async () => {\n const contentAddressBytes = randomBytes();\n const contentAddress = await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n contentAddressBytes,\n );\n\n const url = encodeObjectUrl(actor, contentAddress);\n const decoded = decodeObjectUrl(url);\n expect(decoded.actor).toBe(actor);\n expect(decoded.contentAddress).toBe(contentAddress);\n });\n }\n\n for (const invalidUrl of [\n \"http://example.com/not-an-object-url\",\n \"graffiti:\",\n \"graffiti:\",\n \"graffiti:no-content-address\",\n \"graffiti:too:many:parts\",\n ]) {\n test(`Invalid Graffiti URL: ${invalidUrl}`, () => {\n expect(() => decodeObjectUrl(invalidUrl)).toThrow();\n });\n }\n });\n\n describe(\"object encoding and validation\", async () => {\n const objectEncoding = new ObjectEncoding({\n stringEncoder: new StringEncoder(),\n allowedAttestations: new AllowedAttestations(),\n channelAttestations: new ChannelAttestations(),\n contentAddresses: new ContentAddresses(),\n });\n\n const value = {\n message: \"Hello world!\",\n nested: {\n foo: {\n bar: 42,\n },\n },\n array: [1, \"something \uD83D\uDC7B\", { key: \"value\" }],\n };\n const channels = [\"channel1\uD83D\uDC7B\", \"channel2\"];\n const allowed = [\"did:web:noone.example.com\", \"did:web:someone.else.com\"];\n const actor = \"did:web:someone.example.com\";\n\n const { allowedTickets, tags, objectBytes, object } =\n await objectEncoding.encode<{}>(\n {\n value,\n channels,\n allowed,\n },\n actor,\n );\n assert(Array.isArray(allowedTickets));\n\n test(\"validate private\", async () => {\n await objectEncoding.validate(object, tags, objectBytes, {\n allowedTickets,\n });\n\n for (const [index, recipient] of allowed.entries()) {\n const copy = JSON.parse(JSON.stringify(object)) as GraffitiObjectBase;\n const masked = maskGraffitiObject(copy, [], recipient);\n await objectEncoding.validate(masked, tags, objectBytes, {\n recipient: recipient,\n allowedTicket: allowedTickets[index],\n allowedIndex: index,\n });\n }\n });\n\n test(\"incorrect value\", async () => {\n await expect(\n objectEncoding.validate(\n {\n ...object,\n value: {\n ...object.value,\n extra: \"field\",\n },\n },\n tags,\n objectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"incorrect content address\", async () => {\n const url = encodeObjectUrl(\n actor,\n await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n randomBytes(),\n ),\n );\n\n await expect(\n objectEncoding.validate(\n {\n ...object,\n url,\n },\n [new TextEncoder().encode(url), ...tags.slice(1)],\n objectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"incorrect bytes\", async () => {\n const wrongObjectBytes = randomBytes();\n const correctContentAddress = decodeObjectUrl(object.url).contentAddress;\n const correctContentAddressBytes = await new StringEncoder().decode(\n correctContentAddress,\n );\n const contentAddresses = new ContentAddresses();\n const contentAddressMethod = await contentAddresses.getMethod(\n correctContentAddressBytes,\n );\n const wrongContentAddressBytes = await contentAddresses.register(\n contentAddressMethod,\n wrongObjectBytes,\n );\n const wrongContentAddress = await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n wrongContentAddressBytes,\n );\n const wrongObjectUrl = encodeObjectUrl(actor, wrongContentAddress);\n\n await expect(\n objectEncoding.validate(\n {\n ...object,\n url: wrongObjectUrl,\n },\n [new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],\n wrongObjectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"incorrect format\", async () => {\n const wrongData = {\n not: \"the expected format\",\n };\n const wrongObjectBytes = dagCborEncode(wrongData);\n const correctContentAddress = decodeObjectUrl(object.url).contentAddress;\n const correctContentAddressBytes = await new StringEncoder().decode(\n correctContentAddress,\n );\n const contentAddresses = new ContentAddresses();\n const contentAddressMethod = await contentAddresses.getMethod(\n correctContentAddressBytes,\n );\n const wrongContentAddressBytes = await contentAddresses.register(\n contentAddressMethod,\n wrongObjectBytes,\n );\n const wrongContentAddress = await new StringEncoder().encode(\n STRING_ENCODER_METHOD_BASE64URL,\n wrongContentAddressBytes,\n );\n const wrongObjectUrl = encodeObjectUrl(actor, wrongContentAddress);\n await expect(\n objectEncoding.validate(\n {\n ...object,\n url: wrongObjectUrl,\n },\n [new TextEncoder().encode(wrongObjectUrl), ...tags.slice(1)],\n wrongObjectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n\n test(\"missing allowed tickets\", async () => {\n await expect(\n objectEncoding.validate(object, tags, objectBytes),\n ).rejects.toThrow();\n });\n\n test(\"wrong allowed tickets\", async () => {\n const wrongAllowedTickets = await Promise.all(\n allowedTickets.map(\n async (ticket) =>\n (\n await new AllowedAttestations().attest(\n ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,\n \"did:web:not-the-right.actor\",\n )\n ).ticket,\n ),\n );\n\n await expect(\n objectEncoding.validate(object, tags, objectBytes, {\n allowedTickets: wrongAllowedTickets,\n }),\n ).rejects.toThrow();\n });\n\n test(\"wrong recipients\", async () => {\n const wrongRecipients = allowed.map((recipient) => recipient + \"-wrong\");\n\n await expect(\n objectEncoding.validate(\n {\n ...object,\n allowed: wrongRecipients,\n },\n tags,\n objectBytes,\n {\n allowedTickets,\n },\n ),\n ).rejects.toThrow();\n });\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["dagCborEncode"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var object_encoding_exports = {};
|
|
20
|
+
__export(object_encoding_exports, {
|
|
21
|
+
GRAFFITI_OBJECT_URL_PREFIX: () => GRAFFITI_OBJECT_URL_PREFIX,
|
|
22
|
+
MAX_OBJECT_SIZE_BYTES: () => MAX_OBJECT_SIZE_BYTES,
|
|
23
|
+
ObjectEncoding: () => ObjectEncoding,
|
|
24
|
+
decodeObjectUrl: () => decodeObjectUrl,
|
|
25
|
+
decodeObjectUrlComponent: () => decodeObjectUrlComponent,
|
|
26
|
+
encodeObjectUrl: () => encodeObjectUrl,
|
|
27
|
+
encodeObjectUrlComponent: () => encodeObjectUrlComponent
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(object_encoding_exports);
|
|
30
|
+
var import_content_addresses = require("../2-primitives/2-content-addresses");
|
|
31
|
+
var import_utils = require("@noble/hashes/utils.js");
|
|
32
|
+
var import_dag_cbor = require("@ipld/dag-cbor");
|
|
33
|
+
var import_mini = require("zod/mini");
|
|
34
|
+
var import_channel_attestations = require("../2-primitives/3-channel-attestations");
|
|
35
|
+
var import_allowed_attestations = require("../2-primitives/4-allowed-attestations");
|
|
36
|
+
var import_string_encoding = require("../2-primitives/1-string-encoding");
|
|
37
|
+
const MAX_OBJECT_SIZE_BYTES = 32 * 1024;
|
|
38
|
+
class ObjectEncoding {
|
|
39
|
+
constructor(primitives) {
|
|
40
|
+
this.primitives = primitives;
|
|
41
|
+
}
|
|
42
|
+
async encode(partialObject, actor) {
|
|
43
|
+
partialObject = cleanUndefined(partialObject);
|
|
44
|
+
const channelAttestationAndPublicIds = await Promise.all(
|
|
45
|
+
partialObject.channels.map(
|
|
46
|
+
(channel) => this.primitives.channelAttestations.attest(
|
|
47
|
+
// TODO: get this from the DID document of the actor
|
|
48
|
+
import_channel_attestations.CHANNEL_ATTESTATION_METHOD_SHA256_ED25519,
|
|
49
|
+
actor,
|
|
50
|
+
channel
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
);
|
|
54
|
+
const channelAttestations = channelAttestationAndPublicIds.map(
|
|
55
|
+
(c) => c.attestation
|
|
56
|
+
);
|
|
57
|
+
const channelPublicIds = channelAttestationAndPublicIds.map(
|
|
58
|
+
(c) => c.channelPublicId
|
|
59
|
+
);
|
|
60
|
+
const objectData = {
|
|
61
|
+
[VALUE_PROPERTY]: partialObject.value,
|
|
62
|
+
[CHANNEL_ATTESTATIONS_PROPERTY]: channelAttestations,
|
|
63
|
+
[NONCE_PROPERTY]: (0, import_utils.randomBytes)(32)
|
|
64
|
+
};
|
|
65
|
+
let allowedTickets = void 0;
|
|
66
|
+
if (Array.isArray(partialObject.allowed)) {
|
|
67
|
+
const allowedAttestations = await Promise.all(
|
|
68
|
+
partialObject.allowed.map(
|
|
69
|
+
async (allowedActor) => this.primitives.allowedAttestations.attest(
|
|
70
|
+
// TODO: get this from the DID document of the actor
|
|
71
|
+
import_allowed_attestations.ALLOWED_ATTESTATION_METHOD_HMAC_SHA256,
|
|
72
|
+
allowedActor
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
objectData[ALLOWED_ATTESTATIONS_PROPERTY] = allowedAttestations.map(
|
|
77
|
+
(a) => a.attestation
|
|
78
|
+
);
|
|
79
|
+
allowedTickets = allowedAttestations.map((a) => a.ticket);
|
|
80
|
+
}
|
|
81
|
+
const objectBytes = (0, import_dag_cbor.encode)(objectData);
|
|
82
|
+
if (objectBytes.byteLength > MAX_OBJECT_SIZE_BYTES) {
|
|
83
|
+
throw new Error("The object is too large");
|
|
84
|
+
}
|
|
85
|
+
const objectContentAddressBytes = await this.primitives.contentAddresses.register(
|
|
86
|
+
// TODO: get this from the DID document of the actor
|
|
87
|
+
import_content_addresses.CONTENT_ADDRESS_METHOD_SHA256,
|
|
88
|
+
objectBytes
|
|
89
|
+
);
|
|
90
|
+
const objectContentAddress = await this.primitives.stringEncoder.encode(
|
|
91
|
+
import_string_encoding.STRING_ENCODER_METHOD_BASE64URL,
|
|
92
|
+
objectContentAddressBytes
|
|
93
|
+
);
|
|
94
|
+
const objectUrl = encodeObjectUrl(actor, objectContentAddress);
|
|
95
|
+
const tags = [new TextEncoder().encode(objectUrl), ...channelPublicIds];
|
|
96
|
+
const object = {
|
|
97
|
+
value: partialObject.value,
|
|
98
|
+
channels: partialObject.channels,
|
|
99
|
+
url: objectUrl,
|
|
100
|
+
actor,
|
|
101
|
+
...partialObject.allowed ? {
|
|
102
|
+
allowed: partialObject.allowed
|
|
103
|
+
} : {}
|
|
104
|
+
};
|
|
105
|
+
return {
|
|
106
|
+
object,
|
|
107
|
+
tags,
|
|
108
|
+
objectBytes,
|
|
109
|
+
allowedTickets
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
async validate(object, tags, objectBytes, privateObjectInfo) {
|
|
113
|
+
if (objectBytes.byteLength > MAX_OBJECT_SIZE_BYTES) {
|
|
114
|
+
throw new Error("Object is too big");
|
|
115
|
+
}
|
|
116
|
+
const { actor, contentAddress } = decodeObjectUrl(object.url);
|
|
117
|
+
if (actor !== object.actor) {
|
|
118
|
+
throw new Error("Object actor does not match URL actor");
|
|
119
|
+
}
|
|
120
|
+
const objectUrlTag = tags.at(0);
|
|
121
|
+
if (!objectUrlTag) {
|
|
122
|
+
throw new Error("No object URL tag");
|
|
123
|
+
}
|
|
124
|
+
if (new TextDecoder().decode(objectUrlTag) !== object.url) {
|
|
125
|
+
throw new Error("Object URL tag does not match object URL");
|
|
126
|
+
}
|
|
127
|
+
const channelPublicIds = tags.slice(1);
|
|
128
|
+
const contentAddressBytes = await this.primitives.stringEncoder.decode(contentAddress);
|
|
129
|
+
const contentAddressMethod = await this.primitives.contentAddresses.getMethod(contentAddressBytes);
|
|
130
|
+
const expectedContentAddress = await this.primitives.contentAddresses.register(
|
|
131
|
+
contentAddressMethod,
|
|
132
|
+
objectBytes
|
|
133
|
+
);
|
|
134
|
+
if (expectedContentAddress.length !== contentAddressBytes.length || !expectedContentAddress.every((b, i) => b === contentAddressBytes[i])) {
|
|
135
|
+
throw new Error("Content address is invalid");
|
|
136
|
+
}
|
|
137
|
+
const objectDataUnknown = (0, import_dag_cbor.decode)(objectBytes);
|
|
138
|
+
const objectData = ObjectDataSchema.parse(objectDataUnknown);
|
|
139
|
+
const value = objectData[VALUE_PROPERTY];
|
|
140
|
+
const channelAttestations = objectData[CHANNEL_ATTESTATIONS_PROPERTY];
|
|
141
|
+
const allowedAttestations = objectData[ALLOWED_ATTESTATIONS_PROPERTY];
|
|
142
|
+
const valueBytes = (0, import_dag_cbor.encode)(value);
|
|
143
|
+
const expectedValueBytes = (0, import_dag_cbor.encode)(object.value);
|
|
144
|
+
if (valueBytes.length !== expectedValueBytes.length || !valueBytes.every((b, i) => b === expectedValueBytes[i])) {
|
|
145
|
+
throw new Error("Object value does not match storage value");
|
|
146
|
+
}
|
|
147
|
+
if (channelAttestations.length !== channelPublicIds.length) {
|
|
148
|
+
throw new Error("Not as many channel attestations and public ids");
|
|
149
|
+
}
|
|
150
|
+
for (const [index, attestation] of channelAttestations.entries()) {
|
|
151
|
+
const channelPublicId = channelPublicIds[index];
|
|
152
|
+
const isValid = await this.primitives.channelAttestations.validate(
|
|
153
|
+
attestation,
|
|
154
|
+
actor,
|
|
155
|
+
channelPublicId
|
|
156
|
+
);
|
|
157
|
+
if (!isValid) {
|
|
158
|
+
throw new Error("Invalid channel attestation");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (object.channels.length) {
|
|
162
|
+
if (object.channels.length !== channelPublicIds.length) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
"Number of claimed channels does not match attestations/public IDs"
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
const channelAttestationMethod = await this.primitives.channelAttestations.getMethod(
|
|
168
|
+
channelPublicIds[0]
|
|
169
|
+
);
|
|
170
|
+
const expectedChannelPublicIds = await Promise.all(
|
|
171
|
+
object.channels.map(
|
|
172
|
+
(channel) => this.primitives.channelAttestations.register(
|
|
173
|
+
channelAttestationMethod,
|
|
174
|
+
channel
|
|
175
|
+
)
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
for (const [
|
|
179
|
+
index,
|
|
180
|
+
expectedPublicId
|
|
181
|
+
] of expectedChannelPublicIds.entries()) {
|
|
182
|
+
const actualPublicId = channelPublicIds[index];
|
|
183
|
+
if (expectedPublicId.length !== actualPublicId.length || !expectedPublicId.every((b, i) => b === actualPublicId[i])) {
|
|
184
|
+
throw new Error("Channel public id does not match expected");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (privateObjectInfo) {
|
|
189
|
+
if (!allowedAttestations) {
|
|
190
|
+
throw new Error("Object is public but thought to be private");
|
|
191
|
+
}
|
|
192
|
+
let recipients;
|
|
193
|
+
let allowedTickets;
|
|
194
|
+
let attestations;
|
|
195
|
+
if ("recipient" in privateObjectInfo) {
|
|
196
|
+
recipients = [privateObjectInfo.recipient];
|
|
197
|
+
allowedTickets = [privateObjectInfo.allowedTicket];
|
|
198
|
+
attestations = allowedAttestations.filter(
|
|
199
|
+
(_, i) => i === privateObjectInfo.allowedIndex
|
|
200
|
+
);
|
|
201
|
+
} else {
|
|
202
|
+
recipients = [...object.allowed ?? []];
|
|
203
|
+
allowedTickets = privateObjectInfo.allowedTickets;
|
|
204
|
+
attestations = allowedAttestations;
|
|
205
|
+
}
|
|
206
|
+
if (recipients.length !== object.allowed?.length) {
|
|
207
|
+
throw new Error("Recipient count does not match object allowed list");
|
|
208
|
+
}
|
|
209
|
+
if (!recipients.every((r) => object.allowed?.includes(r))) {
|
|
210
|
+
throw new Error("Recipient not in object allowed list");
|
|
211
|
+
}
|
|
212
|
+
for (const [index, recipient] of recipients.entries()) {
|
|
213
|
+
const allowedTicket = allowedTickets.at(index);
|
|
214
|
+
const allowedAttestation = attestations.at(index);
|
|
215
|
+
if (!allowedTicket) {
|
|
216
|
+
throw new Error("Missing allowed ticket for recipient");
|
|
217
|
+
}
|
|
218
|
+
if (!allowedAttestation) {
|
|
219
|
+
throw new Error("Missing allowed attestation for recipient");
|
|
220
|
+
}
|
|
221
|
+
const isValid = await this.primitives.allowedAttestations.validate(
|
|
222
|
+
allowedAttestation,
|
|
223
|
+
recipient,
|
|
224
|
+
allowedTicket
|
|
225
|
+
);
|
|
226
|
+
if (!isValid) {
|
|
227
|
+
throw new Error("Invalid allowed attestation for recipient");
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
} else if (allowedAttestations) {
|
|
231
|
+
throw new Error("Object is private but no recipient info provided");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const VALUE_PROPERTY = "v";
|
|
236
|
+
const CHANNEL_ATTESTATIONS_PROPERTY = "c";
|
|
237
|
+
const ALLOWED_ATTESTATIONS_PROPERTY = "a";
|
|
238
|
+
const NONCE_PROPERTY = "n";
|
|
239
|
+
const Uint8ArraySchema = (0, import_mini.custom)(
|
|
240
|
+
(v) => v instanceof Uint8Array
|
|
241
|
+
);
|
|
242
|
+
const ObjectDataSchema = (0, import_mini.strictObject)({
|
|
243
|
+
[VALUE_PROPERTY]: (0, import_mini.looseObject)({}),
|
|
244
|
+
[CHANNEL_ATTESTATIONS_PROPERTY]: (0, import_mini.array)(Uint8ArraySchema),
|
|
245
|
+
[ALLOWED_ATTESTATIONS_PROPERTY]: (0, import_mini.optional)((0, import_mini.array)(Uint8ArraySchema)),
|
|
246
|
+
[NONCE_PROPERTY]: Uint8ArraySchema
|
|
247
|
+
});
|
|
248
|
+
const GRAFFITI_OBJECT_URL_PREFIX = "graffiti:";
|
|
249
|
+
function encodeObjectUrlComponent(value) {
|
|
250
|
+
const replaced = value.replace(/:/g, "!").replace(/\//g, "~");
|
|
251
|
+
return encodeURIComponent(replaced);
|
|
252
|
+
}
|
|
253
|
+
function decodeObjectUrlComponent(value) {
|
|
254
|
+
const decoded = decodeURIComponent(value);
|
|
255
|
+
return decoded.replace(/!/g, ":").replace(/~/g, "/");
|
|
256
|
+
}
|
|
257
|
+
function encodeObjectUrl(actor, contentAddress) {
|
|
258
|
+
return `${GRAFFITI_OBJECT_URL_PREFIX}${encodeObjectUrlComponent(actor)}:${encodeObjectUrlComponent(contentAddress)}`;
|
|
259
|
+
}
|
|
260
|
+
function decodeObjectUrl(objectUrl) {
|
|
261
|
+
if (!objectUrl.startsWith(GRAFFITI_OBJECT_URL_PREFIX)) {
|
|
262
|
+
throw new Error("Invalid object URL");
|
|
263
|
+
}
|
|
264
|
+
const rest = objectUrl.slice(GRAFFITI_OBJECT_URL_PREFIX.length);
|
|
265
|
+
const parts = rest.split(":");
|
|
266
|
+
if (parts.length !== 2) {
|
|
267
|
+
throw new Error("Invalid object URL format");
|
|
268
|
+
}
|
|
269
|
+
const [actor, contentAddress] = parts;
|
|
270
|
+
return {
|
|
271
|
+
actor: decodeObjectUrlComponent(actor),
|
|
272
|
+
contentAddress: decodeObjectUrlComponent(contentAddress)
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function cleanUndefined(value) {
|
|
276
|
+
if (value === void 0) return null;
|
|
277
|
+
if (Array.isArray(value)) {
|
|
278
|
+
return value.map(cleanUndefined);
|
|
279
|
+
}
|
|
280
|
+
if (typeof value === "object") {
|
|
281
|
+
return Object.fromEntries(
|
|
282
|
+
Object.entries(value).filter(([, v]) => v !== void 0).map(([k, v]) => [k, cleanUndefined(v)])
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
return value;
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=3-object-encoding.js.map
|