@graffiti-garden/implementation-decentralized 0.0.9 → 0.1.0
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 +4 -673
- package/dist/1-services/1-authorization.d.ts.map +1 -1
- package/dist/1-services/2-dids.d.ts +1 -3
- package/dist/1-services/2-dids.d.ts.map +1 -1
- package/dist/1-services/3-storage-buckets.d.ts.map +1 -1
- package/dist/1-services/4-inboxes.d.ts.map +1 -1
- package/dist/1-services/utilities.d.ts.map +1 -1
- package/dist/2-primitives/1-string-encoding.d.ts.map +1 -1
- package/dist/2-primitives/2-content-addresses.d.ts.map +1 -1
- package/dist/2-primitives/3-channel-attestations.d.ts.map +1 -1
- package/dist/2-primitives/4-allowed-attestations.d.ts.map +1 -1
- package/dist/3-protocol/1-sessions.d.ts.map +1 -1
- package/dist/3-protocol/2-handles.d.ts.map +1 -1
- package/dist/3-protocol/3-object-encoding.d.ts.map +1 -1
- package/dist/3-protocol/4-graffiti.d.ts.map +1 -1
- package/dist/3-protocol/browser-storage.d.ts +4 -0
- package/dist/3-protocol/browser-storage.d.ts.map +1 -0
- package/dist/browser/ajv-X6C4R6QN.js +9 -0
- package/dist/browser/ajv-X6C4R6QN.js.map +7 -0
- package/dist/browser/{build-BXWPS7VK.js → build-KAK33G4E.js} +2 -2
- package/dist/browser/{build-BXWPS7VK.js.map → build-KAK33G4E.js.map} +1 -1
- package/dist/browser/chunk-O4MIY67H.js +2 -0
- package/dist/browser/{graffiti-KV3G3O72-URO7SJIJ.js → graffiti-KV3G3O72-QD3APAKT.js} +2 -2
- package/dist/browser/{graffiti-KV3G3O72-URO7SJIJ.js.map → graffiti-KV3G3O72-QD3APAKT.js.map} +1 -1
- package/dist/browser/index.js +13 -10
- package/dist/browser/index.js.map +4 -4
- package/dist/browser/{login-dialog.html-VTDKJZBG.js → login-dialog.html-E6VRKMXH.js} +2 -2
- package/dist/browser/{rock-salt-LI7DAH66-KPFEBIBO.js → rock-salt-LI7DAH66-M6W5PPFD.js} +2 -2
- package/dist/browser/{rock-salt-LI7DAH66-KPFEBIBO.js.map → rock-salt-LI7DAH66-M6W5PPFD.js.map} +1 -1
- package/dist/browser/{style-BOBMBTYJ-ORUSIJTZ.js → style-BOBMBTYJ-2YZTO5FX.js} +2 -2
- package/dist/browser/{style-BOBMBTYJ-ORUSIJTZ.js.map → style-BOBMBTYJ-2YZTO5FX.js.map} +1 -1
- package/dist/cjs/1-services/2-dids.js +4 -1
- package/dist/cjs/1-services/2-dids.js.map +2 -2
- package/dist/cjs/3-protocol/1-sessions.js +6 -6
- package/dist/cjs/3-protocol/1-sessions.js.map +2 -2
- package/dist/cjs/3-protocol/2-handles.js +1 -0
- package/dist/cjs/3-protocol/2-handles.js.map +1 -1
- package/dist/cjs/3-protocol/3-object-encoding.js +1 -0
- package/dist/cjs/3-protocol/3-object-encoding.js.map +1 -1
- package/dist/cjs/3-protocol/4-graffiti.js +4 -1
- package/dist/cjs/3-protocol/4-graffiti.js.map +2 -2
- package/dist/cjs/3-protocol/browser-storage.js +59 -0
- package/dist/cjs/3-protocol/browser-storage.js.map +7 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/index.spec.js +54 -41
- package/dist/cjs/index.spec.js.map +2 -2
- package/dist/esm/1-services/2-dids.js +4 -1
- package/dist/esm/1-services/2-dids.js.map +2 -2
- package/dist/esm/3-protocol/1-sessions.js +10 -6
- package/dist/esm/3-protocol/1-sessions.js.map +2 -2
- package/dist/esm/3-protocol/2-handles.js +1 -0
- package/dist/esm/3-protocol/2-handles.js.map +1 -1
- package/dist/esm/3-protocol/3-object-encoding.js +1 -0
- package/dist/esm/3-protocol/3-object-encoding.js.map +1 -1
- package/dist/esm/3-protocol/4-graffiti.js +4 -1
- package/dist/esm/3-protocol/4-graffiti.js.map +2 -2
- package/dist/esm/3-protocol/browser-storage.js +29 -0
- package/dist/esm/3-protocol/browser-storage.js.map +7 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/index.spec.js +59 -42
- package/dist/esm/index.spec.js.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +25 -18
- package/src/1-services/2-dids.ts +6 -3
- package/src/3-protocol/1-sessions.ts +9 -6
- package/src/3-protocol/4-graffiti.ts +8 -1
- package/src/3-protocol/browser-storage.ts +37 -0
- package/src/index.spec.ts +66 -48
- package/src/index.ts +2 -1
- package/dist/1-services/2-dids-tests.d.ts +0 -2
- package/dist/1-services/2-dids-tests.d.ts.map +0 -1
- package/dist/1-services/3-storage-buckets-tests.d.ts +0 -2
- package/dist/1-services/3-storage-buckets-tests.d.ts.map +0 -1
- package/dist/1-services/4-inboxes-tests.d.ts +0 -2
- package/dist/1-services/4-inboxes-tests.d.ts.map +0 -1
- package/dist/2-primitives/1-string-encoding-tests.d.ts +0 -2
- package/dist/2-primitives/1-string-encoding-tests.d.ts.map +0 -1
- package/dist/2-primitives/2-content-addresses-tests.d.ts +0 -2
- package/dist/2-primitives/2-content-addresses-tests.d.ts.map +0 -1
- package/dist/2-primitives/3-channel-attestations-tests.d.ts +0 -2
- package/dist/2-primitives/3-channel-attestations-tests.d.ts.map +0 -1
- package/dist/2-primitives/4-allowed-attestations-tests.d.ts +0 -2
- package/dist/2-primitives/4-allowed-attestations-tests.d.ts.map +0 -1
- package/dist/3-protocol/2-handles-tests.d.ts +0 -2
- package/dist/3-protocol/2-handles-tests.d.ts.map +0 -1
- package/dist/3-protocol/3-object-encoding-tests.d.ts +0 -2
- package/dist/3-protocol/3-object-encoding-tests.d.ts.map +0 -1
- package/dist/browser/ajv-U35FOJ27.js +0 -9
- package/dist/browser/ajv-U35FOJ27.js.map +0 -7
- package/dist/browser/chunk-RFBBAUMM.js +0 -2
- package/dist/index.spec.d.ts +0 -2
- package/dist/index.spec.d.ts.map +0 -1
- /package/dist/browser/{chunk-RFBBAUMM.js.map → chunk-O4MIY67H.js.map} +0 -0
- /package/dist/browser/{login-dialog.html-VTDKJZBG.js.map → login-dialog.html-E6VRKMXH.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.spec.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n GraffitiLoginEvent,\n GraffitiLogoutEvent,\n GraffitiSession,\n} from \"@graffiti-garden/api\";\nimport {\n graffitiCRUDTests,\n graffitiDiscoverTests,\n graffitiMediaTests,\n} from \"@graffiti-garden/api/tests\";\nimport { DecentralizedIdentifiers } from \"./1-services/2-dids\";\nimport { Authorization } from \"./1-services/1-authorization\";\nimport { StorageBuckets } from \"./1-services/3-storage-buckets\";\nimport { Inboxes } from \"./1-services/4-inboxes\";\nimport { Sessions } from \"./3-protocol/1-sessions\";\nimport { afterAll, describe } from \"vitest\";\nimport { Handles } from \"./3-protocol/2-handles\";\nimport { didTests } from \"./1-services/2-dids-tests\";\nimport { storageBucketTests } from \"./1-services/3-storage-buckets-tests\";\nimport { inboxTests } from \"./1-services/4-inboxes-tests\";\nimport { stringEncodingTests } from \"./2-primitives/1-string-encoding-tests\";\nimport { contentAddressesTests } from \"./2-primitives/2-content-addresses-tests\";\nimport { channelAttestationTests } from \"./2-primitives/3-channel-attestations-tests\";\nimport { allowedAttestationTests } from \"./2-primitives/4-allowed-attestations-tests\";\nimport { handleTests } from \"./3-protocol/2-handles-tests\";\nimport { objectEncodingTests } from \"./3-protocol/3-object-encoding-tests\";\nimport { GraffitiDecentralized } from \"./3-protocol/4-graffiti\";\n\ndescribe(\"GraffitiDecentralized Tests\",
|
|
5
|
-
"mappings": "AAKA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gCAAgC;AACzC,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,UAAU,gBAAgB;
|
|
4
|
+
"sourcesContent": ["import type {\n GraffitiLoginEvent,\n GraffitiLogoutEvent,\n GraffitiSession,\n} from \"@graffiti-garden/api\";\nimport {\n graffitiCRUDTests,\n graffitiDiscoverTests,\n graffitiMediaTests,\n} from \"@graffiti-garden/api/tests\";\nimport { DecentralizedIdentifiers } from \"./1-services/2-dids\";\nimport { Authorization } from \"./1-services/1-authorization\";\nimport { StorageBuckets } from \"./1-services/3-storage-buckets\";\nimport { Inboxes } from \"./1-services/4-inboxes\";\nimport { Sessions } from \"./3-protocol/1-sessions\";\nimport { afterAll, beforeAll, describe } from \"vitest\";\nimport { Handles } from \"./3-protocol/2-handles\";\nimport { didTests } from \"./1-services/2-dids-tests\";\nimport { storageBucketTests } from \"./1-services/3-storage-buckets-tests\";\nimport { inboxTests } from \"./1-services/4-inboxes-tests\";\nimport { stringEncodingTests } from \"./2-primitives/1-string-encoding-tests\";\nimport { contentAddressesTests } from \"./2-primitives/2-content-addresses-tests\";\nimport { channelAttestationTests } from \"./2-primitives/3-channel-attestations-tests\";\nimport { allowedAttestationTests } from \"./2-primitives/4-allowed-attestations-tests\";\nimport { handleTests } from \"./3-protocol/2-handles-tests\";\nimport { objectEncodingTests } from \"./3-protocol/3-object-encoding-tests\";\nimport { GraffitiDecentralized } from \"./3-protocol/4-graffiti\";\nimport {\n DecentralizedTestEnvironment,\n decentralizedSharedInbox,\n decentralizedTestUsers,\n} from \"../test/environment\";\n\ndescribe(\"GraffitiDecentralized Tests\", () => {\n const environment = new DecentralizedTestEnvironment();\n const handles = decentralizedTestUsers.map((user) => user.handle);\n let sessions: GraffitiSession[] = [];\n let sessionMethods: Sessions;\n let handleMethods: Handles;\n\n beforeAll(async () => {\n await environment.start();\n\n const dids = new DecentralizedIdentifiers();\n sessionMethods = new Sessions({\n dids,\n authorization: new Authorization(),\n inboxes: new Inboxes(),\n storageBuckets: new StorageBuckets(),\n });\n handleMethods = new Handles({ dids });\n\n for (const handle of handles) {\n sessions.push(await login(handle));\n }\n });\n\n afterAll(async () => {\n try {\n for (const session of sessions) {\n await logout(session.actor);\n }\n } finally {\n await environment.stop();\n }\n });\n\n // Service tests\n didTests();\n storageBucketTests(\n decentralizedTestUsers[0].bucketEndpoint,\n decentralizedTestUsers[0].token,\n );\n inboxTests(\n decentralizedTestUsers[0].inboxEndpoint,\n decentralizedTestUsers[0].token,\n );\n\n // Primitive tests\n stringEncodingTests();\n contentAddressesTests();\n channelAttestationTests();\n allowedAttestationTests();\n\n // Protocol tests\n handleTests(handles[0]);\n objectEncodingTests();\n\n const useGraffiti = () =>\n new GraffitiDecentralized({\n defaultInboxEndpoints: [decentralizedSharedInbox],\n });\n graffitiCRUDTests(\n useGraffiti,\n () => sessions[0],\n () => sessions[1],\n );\n graffitiMediaTests(\n useGraffiti,\n () => sessions[0],\n () => sessions[1],\n );\n graffitiDiscoverTests(\n useGraffiti,\n () => sessions[0],\n () => sessions[1],\n );\n\n // How to log in/out vvv\n async function login(handle: string) {\n const actor = await handleMethods.handleToActor(handle);\n\n return await new Promise<GraffitiSession>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout>;\n const cleanup = () => {\n clearTimeout(timeout);\n sessionMethods.sessionEvents.removeEventListener(\"login\", listener);\n };\n const listener = (e: unknown) => {\n if (!(e instanceof CustomEvent)) return;\n const detail = e.detail as GraffitiLoginEvent[\"detail\"];\n if (detail.session?.actor !== actor) return;\n cleanup();\n if (detail.error) {\n reject(detail.error);\n } else {\n resolve(detail.session);\n }\n };\n sessionMethods.sessionEvents.addEventListener(\"login\", listener);\n\n timeout = setTimeout(\n () => {\n cleanup();\n reject(new Error(\"Authorization timed out\"));\n },\n 30 * 1000,\n );\n\n void sessionMethods.login(actor);\n });\n }\n\n async function logout(actor: string) {\n return await new Promise<void>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout>;\n const cleanup = () => {\n clearTimeout(timeout);\n sessionMethods.sessionEvents.removeEventListener(\"logout\", listener);\n };\n const listener = (e: unknown) => {\n if (!(e instanceof CustomEvent)) return;\n const detail = e.detail as GraffitiLogoutEvent[\"detail\"];\n if (detail.actor !== actor) return;\n cleanup();\n\n if (detail.error) {\n reject(detail.error);\n } else {\n resolve();\n }\n };\n sessionMethods.sessionEvents.addEventListener(\"logout\", listener);\n\n timeout = setTimeout(\n () => {\n cleanup();\n reject(new Error(\"Logout timed out\"));\n },\n 30 * 1000,\n );\n\n void sessionMethods.logout(actor);\n });\n }\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,yBAAyB,CAAC;AAEjC;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,oBAAoB;IAC7D,YAAY,OAAO,CAAC,EAAE,4BAA4B,EAGjD;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graffiti-garden/implementation-decentralized",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "A client for a decentralized implementation of the Graffiti API",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -27,39 +27,46 @@
|
|
|
27
27
|
"author": "Theia Henderson",
|
|
28
28
|
"license": "GPL-3.0-or-later",
|
|
29
29
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
-
"test
|
|
32
|
-
"test:
|
|
30
|
+
"check": "tsc --noEmit && tsc -p tsconfig.test.json",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest --watch",
|
|
33
|
+
"test:coverage": "vitest --coverage",
|
|
33
34
|
"build:types": "tsc --declaration --emitDeclarationOnly",
|
|
34
35
|
"build:js": "tsx esbuild.config.mts",
|
|
35
36
|
"build": "rm -rf dist && npm run build:types && npm run build:js",
|
|
36
|
-
"prepublishOnly": "npm
|
|
37
|
+
"prepublishOnly": "npm test && npm run build"
|
|
37
38
|
},
|
|
38
39
|
"repository": {
|
|
39
40
|
"type": "git",
|
|
40
|
-
"url": "git+https://github.com/graffiti-garden/
|
|
41
|
+
"url": "git+https://github.com/graffiti-garden/graffiti.git",
|
|
42
|
+
"directory": "implementations/decentralized/client"
|
|
41
43
|
},
|
|
42
44
|
"bugs": {
|
|
43
|
-
"url": "https://github.com/graffiti-garden/
|
|
45
|
+
"url": "https://github.com/graffiti-garden/graffiti/issues"
|
|
44
46
|
},
|
|
45
47
|
"devDependencies": {
|
|
46
|
-
"@types/
|
|
48
|
+
"@types/js-cookie": "^3.0.6",
|
|
49
|
+
"@types/node": "^26.1.1",
|
|
47
50
|
"@vitest/coverage-v8": "^4.0.18",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
51
|
+
"esbuild": "^0.28.1",
|
|
52
|
+
"miniflare": "4.20260730.0",
|
|
53
|
+
"tsx": "^4.23.1",
|
|
54
|
+
"typescript": "^7.0.2",
|
|
50
55
|
"vitest": "^4.0.18"
|
|
51
56
|
},
|
|
52
57
|
"dependencies": {
|
|
53
|
-
"@graffiti-garden/api": "^1.
|
|
54
|
-
"@graffiti-garden/modal": "^1.0
|
|
55
|
-
"@
|
|
56
|
-
"@
|
|
57
|
-
"@noble/
|
|
58
|
-
"
|
|
58
|
+
"@graffiti-garden/api": "^1.3.0",
|
|
59
|
+
"@graffiti-garden/modal": "^1.1.0",
|
|
60
|
+
"@graffiti-garden/wrapper-runtime-types": "^0.1.0",
|
|
61
|
+
"@ipld/dag-cbor": "^10.0.1",
|
|
62
|
+
"@noble/ed25519": "^3.1.0",
|
|
63
|
+
"@noble/hashes": "2.4",
|
|
64
|
+
"did-resolver": "^5.0.1",
|
|
59
65
|
"idb": "^8.0.3",
|
|
60
|
-
"
|
|
66
|
+
"js-cookie": "^3.0.8",
|
|
67
|
+
"openid-client": "^6.8.4",
|
|
61
68
|
"plc-did-resolver": "^1.0.0",
|
|
62
69
|
"web-did-resolver": "^2.0.32",
|
|
63
|
-
"zod": "^4.3
|
|
70
|
+
"zod": "^4.4.3"
|
|
64
71
|
}
|
|
65
72
|
}
|
package/src/1-services/2-dids.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { GraffitiErrorNotFound } from "@graffiti-garden/api";
|
|
2
|
-
import { Resolver, type DIDDocument } from "did-resolver";
|
|
2
|
+
import { Resolver, type DIDDocument, type ResolverRegistry } from "did-resolver";
|
|
3
3
|
import { getResolver as plcResolver } from "plc-did-resolver";
|
|
4
4
|
import { getResolver as webResolver } from "web-did-resolver";
|
|
5
5
|
|
|
6
6
|
export class DecentralizedIdentifiers {
|
|
7
|
-
protected readonly methods = {
|
|
7
|
+
protected readonly methods: Record<string, unknown> = {
|
|
8
8
|
...plcResolver(),
|
|
9
9
|
...webResolver(),
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
protected readonly resolver = new Resolver(
|
|
12
|
+
protected readonly resolver = new Resolver(
|
|
13
|
+
this.methods as unknown as ResolverRegistry,
|
|
14
|
+
{ cache: true },
|
|
15
|
+
);
|
|
13
16
|
|
|
14
17
|
async resolve(did: string): Promise<DIDDocument> {
|
|
15
18
|
if (
|
|
@@ -15,6 +15,11 @@ import {
|
|
|
15
15
|
import { StorageBuckets } from "../1-services/3-storage-buckets";
|
|
16
16
|
import type { Inboxes } from "../1-services/4-inboxes";
|
|
17
17
|
import type { Service } from "did-resolver";
|
|
18
|
+
import {
|
|
19
|
+
getBrowserStorageItem,
|
|
20
|
+
removeBrowserStorageItem,
|
|
21
|
+
setBrowserStorageItem,
|
|
22
|
+
} from "./browser-storage";
|
|
18
23
|
import {
|
|
19
24
|
type infer as infer_,
|
|
20
25
|
extend,
|
|
@@ -512,9 +517,7 @@ export class Sessions {
|
|
|
512
517
|
protected get loggedInSessions(): StoredSession[] {
|
|
513
518
|
if (typeof window === "undefined") return loggedInSessions_;
|
|
514
519
|
|
|
515
|
-
const data =
|
|
516
|
-
LOCAL_STORAGE_LOGGED_IN_SESSIONS_KEY,
|
|
517
|
-
);
|
|
520
|
+
const data = getBrowserStorageItem(LOCAL_STORAGE_LOGGED_IN_SESSIONS_KEY);
|
|
518
521
|
if (!data) return [];
|
|
519
522
|
|
|
520
523
|
let json: unknown;
|
|
@@ -522,14 +525,14 @@ export class Sessions {
|
|
|
522
525
|
json = JSON.parse(data);
|
|
523
526
|
} catch {
|
|
524
527
|
console.error("Error parsing stored session data");
|
|
525
|
-
|
|
528
|
+
removeBrowserStorageItem(LOCAL_STORAGE_LOGGED_IN_SESSIONS_KEY);
|
|
526
529
|
return [];
|
|
527
530
|
}
|
|
528
531
|
|
|
529
532
|
const parsed = array(StoredSessionSchema).safeParse(json);
|
|
530
533
|
if (!parsed.success) {
|
|
531
534
|
console.error("Stored session data is invalid");
|
|
532
|
-
|
|
535
|
+
removeBrowserStorageItem(LOCAL_STORAGE_LOGGED_IN_SESSIONS_KEY);
|
|
533
536
|
return [];
|
|
534
537
|
}
|
|
535
538
|
return parsed.data;
|
|
@@ -540,7 +543,7 @@ export class Sessions {
|
|
|
540
543
|
return;
|
|
541
544
|
}
|
|
542
545
|
|
|
543
|
-
|
|
546
|
+
setBrowserStorageItem(
|
|
544
547
|
LOCAL_STORAGE_LOGGED_IN_SESSIONS_KEY,
|
|
545
548
|
JSON.stringify(sessions),
|
|
546
549
|
);
|
|
@@ -710,6 +710,13 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
710
710
|
getMedia: Graffiti["getMedia"] = async (...args) => {
|
|
711
711
|
const [mediaUrl, accept, session] = args;
|
|
712
712
|
|
|
713
|
+
if (
|
|
714
|
+
accept?.maxBytes !== undefined &&
|
|
715
|
+
(!Number.isSafeInteger(accept.maxBytes) || accept.maxBytes < 0)
|
|
716
|
+
) {
|
|
717
|
+
throw new TypeError("maxBytes must be a nonnegative safe integer");
|
|
718
|
+
}
|
|
719
|
+
|
|
713
720
|
const object = await this.get<typeof MEDIA_OBJECT_SCHEMA>(
|
|
714
721
|
mediaUrl,
|
|
715
722
|
MEDIA_OBJECT_SCHEMA,
|
|
@@ -718,7 +725,7 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
718
725
|
|
|
719
726
|
const { key, type, size } = object.value;
|
|
720
727
|
|
|
721
|
-
if (accept?.maxBytes && size > accept.maxBytes) {
|
|
728
|
+
if (accept?.maxBytes !== undefined && size > accept.maxBytes) {
|
|
722
729
|
throw new GraffitiErrorTooLarge("File size exceeds limit");
|
|
723
730
|
}
|
|
724
731
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Cookies from "js-cookie";
|
|
2
|
+
|
|
3
|
+
// The Storage Access API only exposes cookies, but not
|
|
4
|
+
// localstorage or indexedDB. Therefore, we must use cookies
|
|
5
|
+
// for storage that persists across iframes. This just involves
|
|
6
|
+
// session tokens, the rest of the storage is for in-process
|
|
7
|
+
// authorization, which cannot be done in an iframe anyways,
|
|
8
|
+
// and caching, which just adds efficiency.
|
|
9
|
+
|
|
10
|
+
const BROWSER_STORAGE_EXPIRATION_DAYS = 365;
|
|
11
|
+
|
|
12
|
+
export function setBrowserStorageItem(key: string, value: string): void {
|
|
13
|
+
Cookies.set(key, value, getBrowserStorageOptions());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getBrowserStorageItem(key: string): string | undefined {
|
|
17
|
+
return Cookies.get(key);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function removeBrowserStorageItem(key: string): void {
|
|
21
|
+
Cookies.remove(key, getBrowserStorageOptions());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getBrowserStorageOptions(): Cookies.CookieAttributes {
|
|
25
|
+
const attributes: Cookies.CookieAttributes = {
|
|
26
|
+
expires: BROWSER_STORAGE_EXPIRATION_DAYS,
|
|
27
|
+
path: "/",
|
|
28
|
+
sameSite: "lax",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
if (typeof window !== "undefined" && window.location.protocol === "https:") {
|
|
32
|
+
attributes.sameSite = "none";
|
|
33
|
+
attributes.secure = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return attributes;
|
|
37
|
+
}
|
package/src/index.spec.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { Authorization } from "./1-services/1-authorization";
|
|
|
13
13
|
import { StorageBuckets } from "./1-services/3-storage-buckets";
|
|
14
14
|
import { Inboxes } from "./1-services/4-inboxes";
|
|
15
15
|
import { Sessions } from "./3-protocol/1-sessions";
|
|
16
|
-
import { afterAll, describe } from "vitest";
|
|
16
|
+
import { afterAll, beforeAll, describe } from "vitest";
|
|
17
17
|
import { Handles } from "./3-protocol/2-handles";
|
|
18
18
|
import { didTests } from "./1-services/2-dids-tests";
|
|
19
19
|
import { storageBucketTests } from "./1-services/3-storage-buckets-tests";
|
|
@@ -25,48 +25,55 @@ import { allowedAttestationTests } from "./2-primitives/4-allowed-attestations-t
|
|
|
25
25
|
import { handleTests } from "./3-protocol/2-handles-tests";
|
|
26
26
|
import { objectEncodingTests } from "./3-protocol/3-object-encoding-tests";
|
|
27
27
|
import { GraffitiDecentralized } from "./3-protocol/4-graffiti";
|
|
28
|
+
import {
|
|
29
|
+
DecentralizedTestEnvironment,
|
|
30
|
+
decentralizedSharedInbox,
|
|
31
|
+
decentralizedTestUsers,
|
|
32
|
+
} from "../test/environment";
|
|
28
33
|
|
|
29
|
-
describe("GraffitiDecentralized Tests",
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const sessionMethods = new Sessions({
|
|
33
|
-
dids,
|
|
34
|
-
authorization: new Authorization(),
|
|
35
|
-
inboxes: new Inboxes(),
|
|
36
|
-
storageBuckets: new StorageBuckets(),
|
|
37
|
-
});
|
|
38
|
-
const handleMethods = new Handles({ dids });
|
|
39
|
-
|
|
40
|
-
// Login
|
|
41
|
-
const handles = [
|
|
42
|
-
"localhost%3A5173:app:handles:handle:test1",
|
|
43
|
-
"localhost%3A5173:app:handles:handle:test2",
|
|
44
|
-
];
|
|
34
|
+
describe("GraffitiDecentralized Tests", () => {
|
|
35
|
+
const environment = new DecentralizedTestEnvironment();
|
|
36
|
+
const handles = decentralizedTestUsers.map((user) => user.handle);
|
|
45
37
|
let sessions: GraffitiSession[] = [];
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
let sessionMethods: Sessions;
|
|
39
|
+
let handleMethods: Handles;
|
|
40
|
+
|
|
41
|
+
beforeAll(async () => {
|
|
42
|
+
await environment.start();
|
|
43
|
+
|
|
44
|
+
const dids = new DecentralizedIdentifiers();
|
|
45
|
+
sessionMethods = new Sessions({
|
|
46
|
+
dids,
|
|
47
|
+
authorization: new Authorization(),
|
|
48
|
+
inboxes: new Inboxes(),
|
|
49
|
+
storageBuckets: new StorageBuckets(),
|
|
50
|
+
});
|
|
51
|
+
handleMethods = new Handles({ dids });
|
|
52
|
+
|
|
53
|
+
for (const handle of handles) {
|
|
54
|
+
sessions.push(await login(handle));
|
|
55
|
+
}
|
|
53
56
|
});
|
|
54
|
-
|
|
57
|
+
|
|
55
58
|
afterAll(async () => {
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
try {
|
|
60
|
+
for (const session of sessions) {
|
|
61
|
+
await logout(session.actor);
|
|
62
|
+
}
|
|
63
|
+
} finally {
|
|
64
|
+
await environment.stop();
|
|
58
65
|
}
|
|
59
66
|
});
|
|
60
67
|
|
|
61
68
|
// Service tests
|
|
62
69
|
didTests();
|
|
63
70
|
storageBucketTests(
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
decentralizedTestUsers[0].bucketEndpoint,
|
|
72
|
+
decentralizedTestUsers[0].token,
|
|
66
73
|
);
|
|
67
74
|
inboxTests(
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
decentralizedTestUsers[0].inboxEndpoint,
|
|
76
|
+
decentralizedTestUsers[0].token,
|
|
70
77
|
);
|
|
71
78
|
|
|
72
79
|
// Primitive tests
|
|
@@ -79,13 +86,10 @@ describe("GraffitiDecentralized Tests", async () => {
|
|
|
79
86
|
handleTests(handles[0]);
|
|
80
87
|
objectEncodingTests();
|
|
81
88
|
|
|
82
|
-
const useGraffiti = () =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
},
|
|
87
|
-
);
|
|
88
|
-
};
|
|
89
|
+
const useGraffiti = () =>
|
|
90
|
+
new GraffitiDecentralized({
|
|
91
|
+
defaultInboxEndpoints: [decentralizedSharedInbox],
|
|
92
|
+
});
|
|
89
93
|
graffitiCRUDTests(
|
|
90
94
|
useGraffiti,
|
|
91
95
|
() => sessions[0],
|
|
@@ -107,9 +111,16 @@ describe("GraffitiDecentralized Tests", async () => {
|
|
|
107
111
|
const actor = await handleMethods.handleToActor(handle);
|
|
108
112
|
|
|
109
113
|
return await new Promise<GraffitiSession>((resolve, reject) => {
|
|
114
|
+
let timeout: ReturnType<typeof setTimeout>;
|
|
115
|
+
const cleanup = () => {
|
|
116
|
+
clearTimeout(timeout);
|
|
117
|
+
sessionMethods.sessionEvents.removeEventListener("login", listener);
|
|
118
|
+
};
|
|
110
119
|
const listener = (e: unknown) => {
|
|
111
120
|
if (!(e instanceof CustomEvent)) return;
|
|
112
121
|
const detail = e.detail as GraffitiLoginEvent["detail"];
|
|
122
|
+
if (detail.session?.actor !== actor) return;
|
|
123
|
+
cleanup();
|
|
113
124
|
if (detail.error) {
|
|
114
125
|
reject(detail.error);
|
|
115
126
|
} else {
|
|
@@ -118,23 +129,30 @@ describe("GraffitiDecentralized Tests", async () => {
|
|
|
118
129
|
};
|
|
119
130
|
sessionMethods.sessionEvents.addEventListener("login", listener);
|
|
120
131
|
|
|
121
|
-
setTimeout(
|
|
132
|
+
timeout = setTimeout(
|
|
122
133
|
() => {
|
|
123
|
-
|
|
134
|
+
cleanup();
|
|
124
135
|
reject(new Error("Authorization timed out"));
|
|
125
136
|
},
|
|
126
|
-
|
|
127
|
-
);
|
|
137
|
+
30 * 1000,
|
|
138
|
+
);
|
|
128
139
|
|
|
129
|
-
sessionMethods.login(actor);
|
|
140
|
+
void sessionMethods.login(actor);
|
|
130
141
|
});
|
|
131
142
|
}
|
|
132
143
|
|
|
133
144
|
async function logout(actor: string) {
|
|
134
145
|
return await new Promise<void>((resolve, reject) => {
|
|
146
|
+
let timeout: ReturnType<typeof setTimeout>;
|
|
147
|
+
const cleanup = () => {
|
|
148
|
+
clearTimeout(timeout);
|
|
149
|
+
sessionMethods.sessionEvents.removeEventListener("logout", listener);
|
|
150
|
+
};
|
|
135
151
|
const listener = (e: unknown) => {
|
|
136
152
|
if (!(e instanceof CustomEvent)) return;
|
|
137
153
|
const detail = e.detail as GraffitiLogoutEvent["detail"];
|
|
154
|
+
if (detail.actor !== actor) return;
|
|
155
|
+
cleanup();
|
|
138
156
|
|
|
139
157
|
if (detail.error) {
|
|
140
158
|
reject(detail.error);
|
|
@@ -144,15 +162,15 @@ describe("GraffitiDecentralized Tests", async () => {
|
|
|
144
162
|
};
|
|
145
163
|
sessionMethods.sessionEvents.addEventListener("logout", listener);
|
|
146
164
|
|
|
147
|
-
setTimeout(
|
|
165
|
+
timeout = setTimeout(
|
|
148
166
|
() => {
|
|
149
|
-
|
|
167
|
+
cleanup();
|
|
150
168
|
reject(new Error("Logout timed out"));
|
|
151
169
|
},
|
|
152
|
-
|
|
153
|
-
);
|
|
170
|
+
30 * 1000,
|
|
171
|
+
);
|
|
154
172
|
|
|
155
|
-
sessionMethods.logout(actor);
|
|
173
|
+
void sessionMethods.logout(actor);
|
|
156
174
|
});
|
|
157
175
|
}
|
|
158
176
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Graffiti
|
|
1
|
+
import type { Graffiti } from "@graffiti-garden/api";
|
|
2
|
+
import { GraffitiRuntimeTypes } from "@graffiti-garden/wrapper-runtime-types";
|
|
2
3
|
import {
|
|
3
4
|
GraffitiDecentralized as GraffitiDecentralized_,
|
|
4
5
|
type GraffitiDecentralizedOptions,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"2-dids-tests.d.ts","sourceRoot":"","sources":["../../src/1-services/2-dids-tests.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,4CAoBvB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"3-storage-buckets-tests.d.ts","sourceRoot":"","sources":["../../src/1-services/3-storage-buckets-tests.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,CAChC,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,MAAM,QAiH3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"4-inboxes-tests.d.ts","sourceRoot":"","sources":["../../src/1-services/4-inboxes-tests.ts"],"names":[],"mappings":"AAMA,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAqJnE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"1-string-encoding-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/1-string-encoding-tests.ts"],"names":[],"mappings":"AAOA,wBAAgB,mBAAmB,SAyBlC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"2-content-addresses-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/2-content-addresses-tests.ts"],"names":[],"mappings":"AAOA,wBAAgB,qBAAqB,SAsCpC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"3-channel-attestations-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/3-channel-attestations-tests.ts"],"names":[],"mappings":"AAWA,wBAAgB,uBAAuB,SAiHtC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"4-allowed-attestations-tests.d.ts","sourceRoot":"","sources":["../../src/2-primitives/4-allowed-attestations-tests.ts"],"names":[],"mappings":"AAWA,wBAAgB,uBAAuB,SA0EtC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"2-handles-tests.d.ts","sourceRoot":"","sources":["../../src/3-protocol/2-handles-tests.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,QAYzC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"3-object-encoding-tests.d.ts","sourceRoot":"","sources":["../../src/3-protocol/3-object-encoding-tests.ts"],"names":[],"mappings":"AA2BA,wBAAgB,mBAAmB,SAiPlC"}
|