A Social Inbox for Decentralized Publishing and ActivityPub
This server runs a minimal implementation of an ActivityPub Inbox and Outbox.
Here's how to use it:
- Publish a static site that contains your ActivityPub Actor, Outbox, and Posts. You can fork our staticpub example or use this Jekyll Plugin. Make sure you set up the webfinger endpoint!
- Generate a keypair using either OpenSSL or
npm run generate-keypairin this repo - Add the public key to your ActivityPub Actor
- Set up the social inbox server somewhere like
httpa://social.example.com - Note the WebMention compatible format of your account like
@username@social.example.comwhich will be used as theusernamein parameters - Register your ActorInfo by doing a Signed HTTP POST to
/v1/:username/with JSON that looks like{actorURL, publicKeyId, keypair: {publicKeyPEM,privateKeyPem}}to initialize your inbox. The server will use your keypair to sign HTTP requests for activities you send to your outbox. You can also use theclient.setInfo()API. - Set your Actor's
inboxproperty to point athttps://yourserver/v1/:username/inbox - Send any Activities you want to notify your followers with by doing a Signed HTTP POST to
/v1/:username/outbox
Check out the available API endpoints either in the swagger docs at the https://yourserver/v1/docs/ or in the JS client API in /src/client/index.js.
This project requires Node.js Version 19.x and NPM.
The code is written using TypeScript in the src folder which gets compiled into the dist folder.
- Run server right from the source:
npm run dev - Lint the code to catch common mistakes and maintain code style:
npm run lint - Build JS files to
dist:npm run build - Build and run server:
npm run start
You can use the Swagger UI (http://localhost:8080/v1/docs/static/index.html) to test out API endpoints.
To test out internal authenticated endpoints, you can just comment out the authentication check on the endpoint's code (usually around a call to apsystem.hasPermissionActorRequest().)
Keep in mind that the actor you want to impersonate must actually exist; that is, it has to be able to respond to webfinger. Also, you should register it first locally to be able to use other endpoints by calling POST /v1/{actor} (you will need to bypass authentication in src/server/api/creation.ts like mentioned previously.) You need to pass vaild keys when creating the actor, which you can generate by running npm run generate-identity.
To test out external (ActivityPub server-to-server) endpoints, you can short-circuit APSystem.verifySignedRequest and return the actor you want to impersonate.
Keep in mind that the actor you want to impersonate must actually exist; that is, it has to be able to respond to webfinger.
For example, to impersonate @sutty@sutty.nl, you can add return '@sutty@sutty.nl' at the beginning of verifySignedRequest and send activites with the actor:
Example POST to /v1/{actor}/inbox
POST /v1/{actor}/inbox
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"@language": "es",
"sensitive": "as:sensitive"
}
],
"actor": "https://sutty.nl/about.jsonld",
"type": "Note",
"id": "https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty.jsonld",
"url": [
{
"type": "Link",
"mediaType": "text/html",
"href": "https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty/",
"rel": "canonical"
},
{
"type": "Link",
"mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href": "https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty.jsonld",
"rel": "alternate"
},
{
"type": "Link",
"mediaType": "application/activity+json",
"href": "https://sutty.nl/lanzamiento-de-publicaciones-distribuidas-en-el-fediverso-a-trav%C3%A9s-de-sutty.jsonld",
"rel": "alternate"
}
],
"summary": "Lanzamiento de publicaciones distribuidas en el Fediverso a través de Sutty",
"published": "2023-12-04T21:53:05+00:00",
"updated": "2023-12-05T20:41:34+00:00",
"attributedTo": "https://sutty.nl/about.jsonld",
"to": ["https://www.w3.org/ns/activitystreams#Public"],
"cc": ["https://social.distributed.press/v1/@sutty@sutty.nl/followers"],
"inReplyTo": "https://hypha.coop/dripline/announcing-dp-social-inbox/",
"sensitive": false,
"content": "content"
}(activity derived from the real one)
/scripts: Scripts for doing tasks like importing blocklists/admins or generating keypairs/src/Main folder for source code/src/server/Source code for the inbox server/src/server/api/HTTP routes/src/client/Implementation of a JS client to talk to the inbox viafetch