UNPKG

@fedify/fedify

Version:

An ActivityPub server framework

232 lines (228 loc) • 8.68 kB
import { Temporal } from "@js-temporal/polyfill"; import { URLPattern } from "urlpattern-polyfill"; globalThis.addEventListener = () => {}; import { assertEquals } from "../assert_equals-CTYbeopb.js"; import { assert } from "../assert-DmFG7ppO.js"; import "../docloader-C8mmLN-Y.js"; import "../url-kTAI6_KP.js"; import "../multibase-DeCHcK8L.js"; import { CryptographicKey } from "../vocab-dDpPQ0fF.js"; import "../langstr-DbWheeIS.js"; import "../lookup-Ozuw-rxN.js"; import "../type-D2s5lmbZ.js"; import "../actor-BP-NTJ2m.js"; import { generateCryptoKeyPair } from "../key-CPSlDkCj.js"; import { attachSignature, createSignature, detachSignature, signJsonLd, verifyJsonLd, verifySignature } from "../ld-D9kk1Uy2.js"; import { test } from "../testing-BZ0dJ4qn.js"; import { assertFalse, assertRejects } from "../assert_rejects-C-sxEMM5.js"; import "../assert_is_error-nrwA1GeT.js"; import { assertThrows } from "../assert_throws-Cn9C6Jur.js"; import { mockDocumentLoader } from "../docloader-09nVWLAZ.js"; import { ed25519Multikey, ed25519PrivateKey, rsaPrivateKey2, rsaPrivateKey3, rsaPublicKey2, rsaPublicKey3 } from "../keys-CtFc865v.js"; import { encodeBase64 } from "byte-encodings/base64"; //#region sig/ld.test.ts test("attachSignature()", () => { const sig = { "@context": "https://w3id.org/identity/v1", type: "RsaSignature2017", creator: "https://activitypub.academy/users/brauca_darradiul#main-key", created: "2024-09-12T16:50:46Z", signatureValue: "asdf" }; const doc = { "@context": "https://www.w3.org/ns/activitystreams", id: "https://example.com/1" }; assertEquals(attachSignature(doc, sig), { ...doc, signature: sig }); assertThrows(() => attachSignature(null, sig), TypeError); assertThrows(() => attachSignature(1234, sig), TypeError); }); test("createSignature()", async () => { const doc = { "@context": "https://www.w3.org/ns/activitystreams", id: "https://example.com/1", type: "Create" }; const sig = await createSignature(doc, rsaPrivateKey2, rsaPublicKey2.id, { contextLoader: mockDocumentLoader }); const key = await verifySignature(attachSignature(doc, sig), { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader }); assertEquals(key, rsaPublicKey2); assertRejects(() => createSignature(doc, rsaPublicKey2.publicKey, rsaPublicKey2.id, { contextLoader: mockDocumentLoader }), TypeError); assertRejects(() => createSignature(doc, ed25519PrivateKey, ed25519Multikey.id, { contextLoader: mockDocumentLoader }), TypeError); }); test("signJsonLd()", async () => { const doc = { "@context": "https://www.w3.org/ns/activitystreams", id: "https://example.com/1", type: "Create", actor: "https://example.com/person2" }; const signed = await signJsonLd(doc, rsaPrivateKey3, rsaPublicKey3.id, { contextLoader: mockDocumentLoader }); const verified = await verifyJsonLd(signed, { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader }); assert(verified); }); const document = { "@context": ["https://www.w3.org/ns/activitystreams", { "ostatus": "http://ostatus.org#", "atomUri": "ostatus:atomUri", "inReplyToAtomUri": "ostatus:inReplyToAtomUri", "conversation": "ostatus:conversation", "sensitive": "as:sensitive", "toot": "http://joinmastodon.org/ns#", "votersCount": "toot:votersCount" }], "id": "https://activitypub.academy/users/brauca_darradiul/statuses/113125611605598678/activity", "type": "Create", "actor": "https://activitypub.academy/users/brauca_darradiul", "published": "2024-09-12T16:50:45Z", "to": ["https://www.w3.org/ns/activitystreams#Public"], "cc": ["https://activitypub.academy/users/brauca_darradiul/followers"], "object": { "id": "https://activitypub.academy/users/brauca_darradiul/statuses/113125611605598678", "type": "Note", "summary": null, "inReplyTo": null, "published": "2024-09-12T16:50:45Z", "url": "https://activitypub.academy/@brauca_darradiul/113125611605598678", "attributedTo": "https://activitypub.academy/users/brauca_darradiul", "to": ["https://www.w3.org/ns/activitystreams#Public"], "cc": ["https://activitypub.academy/users/brauca_darradiul/followers"], "sensitive": false, "atomUri": "https://activitypub.academy/users/brauca_darradiul/statuses/113125611605598678", "inReplyToAtomUri": null, "conversation": "tag:activitypub.academy,2024-09-12:objectId=187606:objectType=Conversation", "content": "<p>Test</p>", "contentMap": { "en": "<p>Test</p>" }, "attachment": [], "tag": [], "replies": { "id": "https://activitypub.academy/users/brauca_darradiul/statuses/113125611605598678/replies", "type": "Collection", "first": { "type": "CollectionPage", "next": "https://activitypub.academy/users/brauca_darradiul/statuses/113125611605598678/replies?only_other_accounts=true&page=true", "partOf": "https://activitypub.academy/users/brauca_darradiul/statuses/113125611605598678/replies", "items": [] } } } }; const signature = { "type": "RsaSignature2017", "creator": "https://activitypub.academy/users/brauca_darradiul#main-key", "created": "2024-09-12T16:50:46Z", "signatureValue": "osp9n4Pubp8XFvBi0iwrpCjDkIpuuUr2klp+r8Jp289ISqRNlUPeHVvNrQSE2vqNm4j/cJGuQruIqZPTAmTjjB3HtqgawoAG11DA7OPpY6mJLruKnbqadV1cy5V0DJI9CRJXEBuEmMTJRO9gi1cyzlM4QxK30YrjmtQNLoU9th97da4lumsl+a5cAue38MDuJZvLWDOTZ1EGixwhLP8FevdnZ+jqwctGu9KrgDImBIpBkQaqHFTTGrbE7FlXsj1pneOUQTuRDa9zlk2DmgXeEBWN2OJZDjgJ4iBsF2JHtCn6PccKbuI9s2VLhnobPtLB8YdHYKqIPLmv0UOjAM8XrQ==" }; const testVector = { ...document, signature }; test("detachSignature()", () => { assertEquals(detachSignature(testVector), document); assertEquals(detachSignature(document), document); }); test("verifySignature()", async () => { const doc = { ...testVector }; const key = await verifySignature(doc, { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader }); assertEquals(doc, testVector); assertEquals(key, await CryptographicKey.fromJsonLd({ "@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"], id: "https://activitypub.academy/users/brauca_darradiul#main-key", owner: "https://activitypub.academy/users/brauca_darradiul", publicKeyPem: "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5W/9rYXddIjKo9Ury/LK XqQYbj0cOx/c+T1uRHJzced8JbvXdiBCNZXVVrIaygy3G/MOvxMW4kbA1bqeiSYY V9TXBMI6gVVDnl5VG64uGxswcvUWqQU5Q1mwuwyGCPhexAq3BKe/7uH64AZgx11e KLl3W3WcIMKmunYn8+z6hm0003hMensXMNpMVfqLoXaeuro7pYnwOSWoHFS3AxWK llMwAoa5waulgai8gD7/uA5Y9Hvguk/OBYBh9YnIX5N5jScsmY/EYuesNIH2Ct9s E3aVkTjZUt55JtXnk8Q9eTnrcB/98RtLWH4pJTKJhzxv19i3aZT3yDApPk0Q/biI JQIDAQAB -----END PUBLIC KEY----- " })); const doc2 = { ...testVector, signature: { ...testVector.signature, signatureValue: "!" } }; const key2 = await verifySignature(doc2, { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader }); assertEquals(doc2, { ...testVector, signature: { ...testVector.signature, signatureValue: "!" } }); assertEquals(key2, null); const incorrectSig = encodeBase64(new Uint8Array([ 1, 2, 3, 4 ])); const doc3 = { ...testVector, signature: { ...testVector.signature, signatureValue: incorrectSig } }; const key3 = await verifySignature(doc3, { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader }); assertEquals(doc3, { ...testVector, signature: { ...testVector.signature, signatureValue: incorrectSig } }); assertEquals(key3, null); const doc4 = { ...testVector }; const key4 = await verifySignature(doc4, { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader, keyCache: { async get(keyId) { return new CryptographicKey({ id: keyId, owner: new URL("https://activitypub.academy/users/brauca_darradiul"), publicKey: (await generateCryptoKeyPair("RSASSA-PKCS1-v1_5")).publicKey }); }, set(_keyId, _key) { return Promise.resolve(); } } }); assertEquals(doc4, testVector); assertEquals(key4, key); }); test("verifyJsonLd()", async () => { const verified = await verifyJsonLd(testVector, { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader }); assert(verified); const doc = { "@context": "https://www.w3.org/ns/activitystreams", id: "https://example.com/1", type: "Create", actor: "https://example.com/person2" }; const signed = await signJsonLd(doc, rsaPrivateKey2, rsaPublicKey2.id, { contextLoader: mockDocumentLoader }); const verified2 = await verifyJsonLd(signed, { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader }); assertFalse(verified2); }); //#endregion