immers-space / activitypub-express Goto Github PK
View Code? Open in Web Editor NEWModular ActivityPub implementation as Express JS middleware to easily add decentralization and federation to Node apps
License: MIT License
Modular ActivityPub implementation as Express JS middleware to easily add decentralization and federation to Node apps
License: MIT License
| Unsupported BSON version, bson types must be from bson 5.0 or later {} BSONVersionError: Unsupported BSON version, bson types must be from bson 5.0 or later
| at serializeInto (/var/www/test/node_modules/bson/lib/bson.cjs:3637:23)
| at serializeObject (/var/www/test/node_modules/bson/lib/bson.cjs:3199:22)
| at serializeInto (/var/www/test/node_modules/bson/lib/bson.cjs:3633:25)
| at serializeObject (/var/www/test/node_modules/bson/lib/bson.cjs:3199:22)
| at serializeInto (/var/www/test/node_modules/bson/lib/bson.cjs:3633:25)
| at serializeObject (/var/www/test/node_modules/bson/lib/bson.cjs:3199:22)
| at serializeInto (/var/www/test/node_modules/bson/lib/bson.cjs:3432:25)
| at serializeObject (/var/www/test/node_modules/bson/lib/bson.cjs:3199:22)
| at serializeInto (/var/www/test/node_modules/bson/lib/bson.cjs:3633:25)
| at Object.serialize (/var/www/test/node_modules/bson/lib/bson.cjs:4015:32)
It may make sense for gup.pe to skip fetching unknown actors on certain events, such as:
Delete
where the actor
and the object
are one and the same: this is how Mastodon signals account deletions, so fetching the actor would not work (since it is deleted already), and since you don't know the actor, you have nothing to deleteUpdate
where the actor
and the object
are one and the same: if you don't know the actor already, you probably don't need to process their profile updatesactivitypub-express/pub/federation.js
Line 124 in 364d907
result.statusCode == 401
Unauthorized response status code indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.
When receiving an update for a collection on another server, maybe we should prefetch all the pages and populate the items for easy access when needed. Probably the only use case where this is vital would be shared inbox delivery (#24). Usage for display could be fetched on demand and shown page by page
Validation should add all the audiences from the original object to Delete and Update activities in order to improve federation
Fetching activity by IRI returns actor as an IRI string, this is inconsistent with the collection enpoints
Mastodon now requires presence of Digest header in signature. See implementation in immers-space/guppe@5208b67
Also, Mastodon requires signed GETs in some configurations, may use a single system-wide user for this purpose
Somehow, native fetch is being invoked in the jsonld document loader, bypassing mocks
(node:81130) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
jsonld context caching
✗ fetches and caches new contexts
- jsonld.InvalidUrl: Dereferencing a URL did not result in a valid JSON-LD object. Possible causes are an inaccessible URL perhaps due to a same-origin policy (ensure the server uses CORS if you are using client-side JavaScript), too many redirects, a non-JSON response, or more than one HTTP Link Header was provided for a remote context.
✗ caches redirected contexts by original url
- jsonld.InvalidUrl: Dereferencing a URL did not result in a valid JSON-LD object. Possible causes are an inaccessible URL perhaps due to a same-origin policy (ensure the server uses CORS if you are using client-side JavaScript), too many redirects, a non-JSON response, or more than one HTTP Link Header was provided for a remote context.
When I try using the example code from the readme, I get the following error:
/<redacted>/index.js:35
app.use(express.json({ type: apex.consts.jsonldTypes }), apex);
^
TypeError: Cannot read properties of undefined (reading 'jsonldTypes')
at Object.<anonymous> (/<redacted>/index.js:35:42)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
Masto Announces objects (e.g. Note) but we're looking for an activity
Collection fetch should return resolved objects for immediate rendering. When saving certain types of activities in streams, we should replace object references with their resolved objects so that they will appear in collections
Hi, going through your code as ActivityPub learning exercise as this is the nicest ActivityPub code I could find on the web!
Back to the point: I got 2 tests failing. Going through documentation you've warned about possible http-signature
issue, but
I didn't get the InvalidHeaderError, so I am raising this as an issue.
The tests were run on Windows 10
, Node: v14.5.0
, NPM: 6.14.5
.
1) federation background delivery process backs off repeated attempts
- Expected spy deliver to have been called 4 times. It was called 3 times.
2) federation background delivery process can restart delivery while retries are pending
- Expected spy deliver to have been called 4 times. It was called 2 times.
- Expected spy deliver to have been called 6 times. It was called 5 times.
- Expected $[2] = 'https://mocked.com/bob/inbox' to equal 'https://ignore.com/sally/inbox'.
if using the actorId-in-place-of-object shortcut, it errors out during validation trying to look up that actor id as if it was an activity
Provide a way for implementations to specify whether inbox/outbox GETs include only public posts or include all posts
Mastodon will start sending Add
/Remove
in their groups functionality to federate the contents of the group's timeline.
We don't currently process any side effects for inbox add/remove, but we would want a way to record their addition to the collection and fetch that collection later.
Perhaps not as simple as just adding the given remote collection id to activity._meta.collections, as there's no api to fetch a collection from another instance out of the local database
Since the only acceptable types:
jsonldTypes: [
'application/ld+json',
'application/activity+json'
],
are relatively uncommon and activitypub-express at the moment uses standard 404 Not Found
I think returning status code 406 Not Acceptable
for other types with suggestion on which types to use instead in the response body could be helpful.
It would be nice to have a sharedInbox
to cut on traffic when tagging multiple groups, or when federating non-group-related events (such as account deletions).
For context, Mastodon currently broadcasts account deletion events to all the actors it knows about, but if the actors have a sharedInbox
, it will send such events there instead of in each individual actor's inbox.
TimeoutOverflowWarning: 9986935433 does not fit into a 32-bit signed integer.
Timeout duration was set to 1.
Does the delivery backoff timeline cause this overflow before giving up?
KeyId's often have a hash suffix, e.g. https://example.com/users/bob#main-key
, but when apex fetches that IRI, it receives:
{
id: "https://example.com/users/bob",
...
}
so an object with id: https://example.com/users/bob#main-key
never gets cached and is fetched again on each signature validation attempt
Gathering all the todos I've left in different places:
activity.address
TODO: track errors during address resolution for redelivery attempts (not spec)federation.runDelivery
TODO: consider tracking unreachable servers, removing followers (not spec)store.deliveryEnqueue
TODO maybe catch errored docs and retry? (not spec)store.updateObjectCopies
TODO: if this is a profile update that includes a private key change, need to update copies in delivery queue (not spec)It would be great to have some code examples for creating an actor, creating an activity, following an actor, and other common actions. Based on the info in the readme, I'm not sure how to use this library after starting up the server.
After some additional debugging logging, we figured out why a.gup.pe was not accepting posts from our instance, it replies with "Error processing request JSON-LD", which is defined here:
activitypub-express/net/validators.js
Line 167 in 37b7119
We're using Akkoma 3.11
The JSON we were trying to send to the inbox was the following;
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://cooltrans.men/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"actor": "https://cooltrans.men/users/jo",
"cc": [
"https://www.w3.org/ns/activitystreams#Public"
],
"context": "https://cooltrans.men/contexts/0443005c-aaf5-4557-b156-39087a5035d2",
"directMessage": false,
"id": "https://cooltrans.men/activities/1399b1f9-b48d-4790-b9ed-db6114011bff",
"object": {
"actor": "https://cooltrans.men/users/jo",
"attachment": [],
"attributedTo": "https://cooltrans.men/users/jo",
"cc": [
"https://www.w3.org/ns/activitystreams#Public"
],
"content": "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"AfRIZEdbPmhJwgNVuC\" href=\"https://a.gup.pe/u/test\" rel=\"ugc\">@<span>test</span></a></span> A test post",
"contentMap": {
"en": "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"AfRIZEdbPmhJwgNVuC\" href=\"https://a.gup.pe/u/test\" rel=\"ugc\">@<span>test</span></a></span> A test post"
},
"context": "https://cooltrans.men/contexts/0443005c-aaf5-4557-b156-39087a5035d2",
"conversation": "https://cooltrans.men/contexts/0443005c-aaf5-4557-b156-39087a5035d2",
"id": "https://cooltrans.men/objects/2702435d-83fa-4b49-a18f-be4636ee3e8c",
"published": "2024-03-02T13:11:10.574761Z",
"sensitive": null,
"source": {
"content": "@[email protected] A test post",
"mediaType": "text/plain"
},
"summary": "",
"tag": [
{
"href": "https://a.gup.pe/u/test",
"name": "@[email protected]",
"type": "Mention"
}
],
"to": [
"https://cooltrans.men/users/jo/followers",
"https://a.gup.pe/u/test"
],
"type": "Note"
},
"published": "2024-03-02T13:11:10.574683Z",
"to": [
"https://cooltrans.men/users/jo/followers",
"https://a.gup.pe/u/test"
],
"type": "Create"
}
https://github.com/immers-space/activitypub-express/blob/master/net/validators.js#L362-L373
Our accept validation heuristic depends on the object activity's 'to' field, but Mastodon follows don't have one. Looks like we just need to put the special Follow rule first and only try the 'to' check for other types
Would resolve FAQ item on InvalidHeaderError
Blocklist & permission-based filtering in collections could be done in the database to prevent the chance empty collection pages
This issue is to keep track of progress in digitalbazaar/jsonld.js/issues/451
jsonld.js
with version 5.0.0
moved away from request
library. Unfortunately with this version the documentLoader: jsonld.documentLoaders.node()
fails to load remote context.
If this won't be fixed and the upgrade would be needed for other reasons then possibility is to create custom documentLoader.
Right now, one delivery may be permanently lost when the server shuts down
https://github.com/immers-space/activitypub-express/blob/master/net/validators.js#L315
{
2023-06-17T19:33:10.181735055Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | id: 'https://rumbly.net/activity/7f2ba55f-0854-4a5b-a5e1-b5121eef7624',
2023-06-17T19:33:10.181737876Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | type: 'Add',
2023-06-17T19:33:10.181739755Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/apschema#conversation': [
2023-06-17T19:33:10.181741745Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/conversation/7f2ba55f-0854-4a5b-a5e1-b5121eef7624'
2023-06-17T19:33:10.181743618Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | ],
2023-06-17T19:33:10.181745450Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/apschema#isContainedConversation': [ true ],
2023-06-17T19:33:10.181747391Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/apschema#replyTo': [ 'https://rumbly.net/channel/mario' ],
2023-06-17T19:33:10.181749159Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | signature: [
2023-06-17T19:33:10.181751240Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | {
2023-06-17T19:33:10.181753067Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | type: 'RsaSignature2017',
2023-06-17T19:33:10.181755197Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | created: [Array],
2023-06-17T19:33:10.181756927Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | creator: [Array],
2023-06-17T19:33:10.181758885Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | nonce: [Array],
2023-06-17T19:33:10.181760627Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | signatureValue: [Array]
2023-06-17T19:33:10.181762361Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | }
2023-06-17T19:33:10.181764321Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | ],
2023-06-17T19:33:10.181766115Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | actor: [ 'https://rumbly.net/channel/mario' ],
2023-06-17T19:33:10.181768225Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | attachment: [ { type: 'Link', href: [Array], mediaType: [Array] } ],
2023-06-17T19:33:10.181770141Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | cc: [ 'https://rumbly.net/followers/mario' ],
2023-06-17T19:33:10.181771883Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | context: [
2023-06-17T19:33:10.181773702Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/conversation/7f2ba55f-0854-4a5b-a5e1-b5121eef7624'
2023-06-17T19:33:10.181775446Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | ],
2023-06-17T19:33:10.181777219Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | object: [
2023-06-17T19:33:10.181778985Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | {
2023-06-17T19:33:10.181780729Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | id: 'https://rumbly.net/item/7f2ba55f-0854-4a5b-a5e1-b5121eef7624',
2023-06-17T19:33:10.181782493Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | type: 'Note',
2023-06-17T19:33:10.181784304Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'http://joinmastodon.org/ns#canReply': [Array],
2023-06-17T19:33:10.181786121Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/apschema#commentPolicy': [Array],
2023-06-17T19:33:10.181787866Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/apschema#conversation': [Array],
2023-06-17T19:33:10.181789624Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/apschema#isContainedConversation': [Array],
2023-06-17T19:33:10.181791343Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/apschema#replyTo': [Array],
2023-06-17T19:33:10.181793073Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | attachment: [Array],
2023-06-17T19:33:10.181794842Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | attributedTo: [Array],
2023-06-17T19:33:10.181796586Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | cc: [Array],
2023-06-17T19:33:10.181798334Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | content: [Array],
2023-06-17T19:33:10.181813220Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | context: [Array],
2023-06-17T19:33:10.181815049Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | published: [Array],
2023-06-17T19:33:10.181816631Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | source: [Array],
2023-06-17T19:33:10.181818203Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | tag: [Array],
2023-06-17T19:33:10.181819808Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | to: [Array],
2023-06-17T19:33:10.181821385Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | url: [Array]
2023-06-17T19:33:10.181822965Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | }
2023-06-17T19:33:10.181824554Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | ],
2023-06-17T19:33:10.181826167Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | published: [ '2023-06-17T19:31:32Z' ],
2023-06-17T19:33:10.181827804Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | tag: [
2023-06-17T19:33:10.181829464Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | { type: 'Mention', href: [Array], name: [Array] },
2023-06-17T19:33:10.181831104Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | { type: 'Mention', href: [Array], name: [Array] }
2023-06-17T19:33:10.181832760Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | ],
2023-06-17T19:33:10.181834336Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | to: [
2023-06-17T19:33:10.181836104Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'as:Public',
2023-06-17T19:33:10.181837702Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/channel/mario',
2023-06-17T19:33:10.181839302Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://hub.somaton.com/channel/testc10'
2023-06-17T19:33:10.181840884Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | ],
2023-06-17T19:33:10.181842476Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | url: [
2023-06-17T19:33:10.181861335Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | 'https://rumbly.net/activity/7f2ba55f-0854-4a5b-a5e1-b5121eef7624'
2023-06-17T19:33:10.181863424Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | ]
2023-06-17T19:33:10.181865251Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | }
id.startsWith is not a function
2023-06-17T19:33:10.181867138Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | at /usr/src/guppe/node_modules/activitypub-express/pub/utils.js:255:35
2023-06-17T19:33:10.181868871Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | at Array.some (<anonymous>)
2023-06-17T19:33:10.181871745Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | at Function.isLocalhostIRI (/usr/src/guppe/node_modules/activitypub-express/pub/utils.js:255:21)
2023-06-17T19:33:10.181873659Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | at Function.requestObject (/usr/src/guppe/node_modules/activitypub-express/pub/federation.js:20:38)
2023-06-17T19:33:10.181875514Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | at Function.resolveActivity (/usr/src/guppe/node_modules/activitypub-express/pub/activity.js:230:27)
2023-06-17T19:33:10.181877523Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | at runMicrotasks (<anonymous>)
2023-06-17T19:33:10.181879449Z guppe_guppe.2.t9occtkazzdj@docker-s-1vcpu-1gb-nyc1-01 | at processTicksAndRejections (node:internal/process/task_queues:96:5)
Find a new library for sending http requests
node-fetch
is out, with a proposed fix sitting idle for 3 years node-fetch/node-fetch#480Collections don't have a direct link to their owner, so it is difficult to validate Updates to collections directly.
getCollection
without deciphering id to figure out which collection it is (because the items are no longer included in the base collection object so the collection-specific remapping doesn't matter) 39ebf2dadded
collection, update Actor.streams
as needed to include all collectionsRelated code comment todos:
activity.inboxSideEffects
TODO: publish appropriate collection updates 39ebf2dactivity.outboxSideEffects
TODO: publish appropriate collection updates 39ebf2dRelated pending tests:
security.verifyActor
TODO: LD-signatures verification and/or check for valid inbox forwarding casesvalidators.actor
TODO: alternative authorization via JSON-LD signatures for forwardingRelated: #12
As it is just by importing request-promise-native
or ActivitypubExpress
that uses it, the async tests in Jest will fail in some instances. Here is an example (uncomment any requires: ActivitypubExpress
or request
to see the errors):
const jsonld = require('jsonld')
// const ActivitypubExpress = require('activitypub-express')
// const request = require('request-promise-native')
const context = [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1'
]
const obj = {
'@id': 'https://example.org/personID',
'@type': 'https://www.w3.org/ns/activitystreams#Person',
'https://w3id.org/security#publicKey': {
'@id': 'https://example.org/personID#main-key',
'https://w3id.org/security#owner': 'https://example.org/personID'
}
}
const opts = {
compactArrays: false,
documentLoader: jsonld.documentLoaders.node()
}
it('jsonld.compact activitystreams+security [promise]', function () {
expect.assertions(1);
return jsonld.compact(obj, context, opts).then((result) => {
// console.log('result:', JSON.stringify(result, null, ' '))
expect(result).toStrictEqual({
'@context': [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1'
],
'@graph': [
{
id: 'https://example.org/personID',
type: 'Person',
publicKey: [
{
id: "https://example.org/personID#main-key",
"sec:owner": [ "https://example.org/personID",],
},
],
}
]
})
}).catch((error) => {
console.error(error)
throw error
})
})
In this instance it will fail on fetching https://w3id.org/security/v1
since it will first return Status Code 302
(document moved). The proper promise with @context
will never resolve breaking this and messing up subsequent tests.
To install Jest: npm install jest
, to run single test file: npx jest -- testpath/compact.spec.js
Besides making it impossible to test projects using ActivitypubExpress
with Jest
I am concerned that this may also indicate other promise related issues in the future.
I was thinking node-fetch might be a good fit although not complete:
node-fetch/node-fetch#480
According to ActivityPub specification, servers should return ActivityStreams object representation in response to requests having application/ld+json; profile="https://www.w3.org/ns/activitystreams"
in Accept header, but Guppe only does that for application/activity+json
media type.
Servers ... MUST present the ActivityStreams object representation in response to application/ld+json; profile="https://www.w3.org/ns/activitystreams", and SHOULD also present the ActivityStreams representation in response to application/activity+json as well.
-- https://www.w3.org/TR/activitypub/#retrieving-objects
Example:
curl -H 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"' https://a.gup.pe/u/3goodthings
This command returns 404 error page instead of the actor object.
Test posting the same activity to multiple inboxes in close proximity. I think we'll need to refactor to add the meta properties on-disk rather than in-memory to avoid race conditions
Re-evaluate the side effects and new activity logic to ensure we're getting what we want from it, e.g. do some side effects need to be reprocessed for each recipient (e.g. a like needs to be processed by the activity owner to send the update, but what if it gets delivered to some cc recipient first?)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.