activity-kit-core/README.md

267 lines
8.5 KiB
Markdown
Raw Permalink Normal View History

2023-04-16 18:11:14 +00:00
# ActivityKit
2022-10-14 20:32:27 +00:00
2023-04-16 18:11:14 +00:00
This is a [Lerna](https://lerna.js.org/) monorepo that holds packages related to a TypeScript implementation of the ActivityPub protocol.
2022-10-14 20:32:27 +00:00
2022-10-24 15:27:44 +00:00
[ActivityPub](https://activitypub.rocks) is a standardized method of exchanging social data.
2022-10-14 20:32:27 +00:00
## Current Status
2022-11-12 21:18:08 +00:00
This project is still incomplete at the moment. Much of the core functionality is complete, but refer to:
2022-10-14 20:32:27 +00:00
2023-04-05 00:26:22 +00:00
- [TODO.md](TODO.md)
- [CHECKLIST.md](CHECKLIST.md)
- [CONTRIBUTING.md](CONTRIBUTING.md)
2022-10-24 15:27:44 +00:00
2022-10-15 19:31:01 +00:00
## Running in a Project
2023-04-14 22:53:42 +00:00
### Prerequesities
2023-04-16 15:38:01 +00:00
In addition to hosting a (Node) server, you will also need:
2023-04-14 22:53:42 +00:00
2023-04-15 15:07:34 +00:00
- **Database**: A compatable database that the server can access.
- **Storage**: A way to store files such as profile pics.
- **HTML Templating**: A way to render pages with provided JSON data.
2023-04-14 22:53:42 +00:00
### Example
Canonical example using Express + MongoDB + FTP:
2022-10-15 19:31:01 +00:00
```ts
2023-04-06 14:36:23 +00:00
import * as express from "express";
import { MongoClient } from "mongodb";
2023-04-16 18:11:14 +00:00
import { AP, Adapters } from "@activity-kit/types";
2023-07-09 02:04:51 +00:00
import { activityKitPlugin } from "@activity-kit/express-middleware";
2023-04-16 18:11:14 +00:00
import { MongoDbAdapter } from "@activity-kit/db-mongo";
import { TokenAuthAdapter } from "@activity-kit/auth-token";
import { NodeCryptoAdapter } from "@activity-kit/crypto-node";
import { FtpStorageAdapter } from "@activity-kit/storage-ftp";
2023-04-06 14:36:23 +00:00
// Use Express for all routes.
const app = express.default();
(async () => {
const ftpStorageAdapterOptions = {
user: process.env.AP_FTP_USER,
password: process.env.AP_FTP_PASSWORD,
host: process.env.AP_FTP_HOST,
path: process.env.AP_FTP_PATH,
};
// Use the FTP adapter for handling uploaded media.
2023-04-15 15:07:34 +00:00
const ftpStorageAdapter = new FtpStorageAdapter(ftpStorageAdapterOptions);
2023-04-06 14:36:23 +00:00
2023-04-16 15:38:01 +00:00
// Use MongoDB to store data.
2023-04-06 14:36:23 +00:00
const mongoClient = new MongoClient(process.env.AP_MONGO_CLIENT_URL);
await mongoClient.connect();
const mongoDb = mongoClient.db("activitypub");
2023-04-16 15:38:01 +00:00
const mongoDbAdapter = new MongoDbAdapter(mongoDb);
2023-04-06 14:36:23 +00:00
2023-04-16 18:58:48 +00:00
// Use Node's Crypto library + Mongo for authentication.
const nodeCryptoAdapter = new NodeCryptoAdapter();
2023-04-15 15:07:34 +00:00
const cryptoAuthAdapter = new CryptoAuthAdapter({
2023-04-06 14:36:23 +00:00
db: mongoDbAdapter,
2023-04-16 18:58:48 +00:00
crypto: nodeCryptoAdapter,
2023-04-06 14:36:23 +00:00
});
2023-04-16 18:11:14 +00:00
// Use the ActivityKit Express plugin.
2023-04-06 14:36:23 +00:00
app.use(
2023-04-16 18:11:14 +00:00
activityKitPlugin({
2023-04-06 14:36:23 +00:00
adapters: {
auth: cryptoAuthAdapter,
2023-04-15 15:07:34 +00:00
crypto: nodeCryptoAdapter,
2023-04-06 14:36:23 +00:00
db: mongoDbAdapter,
storage: ftpStorageAdapter,
},
plugins: [],
routes: {},
2023-04-06 14:36:23 +00:00
pages: {
// Login/Signup via Auth adapter.
login: async (): Promise<string> => {
// Use a rendering engine to generate and return a string here.
return `
<html>
<!-- Signup form POSTs to /user endpoint to create new user. -->
<form>...</form>
<!-- Login form POSTs to /login endpoint to get cookie token. -->
<form>...</form>
</html>
`;
},
// Logged-in users can edit their profile, create new posts, etc.
home: async (homePageProps: {
actor: AP.Actor;
shared: AP.Announce[];
requests: AP.Follow[];
members: AP.Actor[];
blocks: AP.Block[];
}): Promise<string> => {
// Use a rendering engine to generate and return a string here.
return `
<html>
<title>@${actor.preferredUsername}</title>
<!-- Forms POST to user's outbox URL using AP protocol. -->
<form>...</form>
</html>
`;
},
2023-04-15 15:07:34 +00:00
// All ActivityPub entities have an HTML view.
2023-04-06 14:36:23 +00:00
entity: async (entityPageProps: {
entity: AP.Entity;
actor?: AP.Actor;
}): Promise<string> => {
// Use a rendering engine to generate and return a string here.
return `
<html>
<h1>${entity.type}</h1>
<p>${entity.summary}</p>
</html>
`;
},
},
})
);
app.listen(process.env.PORT ?? 3000, () => {
console.log("Running...");
});
})();
2022-10-15 19:31:01 +00:00
```
2022-10-14 20:32:27 +00:00
## General Philosophy
This project aims to be spec-compliant.
2023-04-16 15:38:01 +00:00
This project aims to be as versatile and non-opinionated as possible. The hope is to be able to integrate with any project.
2022-10-14 20:32:27 +00:00
This project is MIT-licensed, with the hope it will be forked, reused, or
2023-07-04 20:50:02 +00:00
wholly included in other projects due to this permissive license. There may be similiar software that exists, but inclusion would be inviable due to licensing restrictions.
2022-10-14 20:32:27 +00:00
## Architecture
2023-07-04 20:50:02 +00:00
This project aims to be agnostic as to how the data is stored, which server is used, etc. Adapters that conform to a specific interface can be mixed and matched.
2022-10-27 15:52:47 +00:00
2023-04-16 18:11:14 +00:00
Additionally, Plugins can modify the endpoints.
2022-10-14 20:32:27 +00:00
2023-04-16 18:11:14 +00:00
### Core Layer
2022-10-14 20:32:27 +00:00
2023-04-16 18:11:14 +00:00
The core layer that gets included in all projects include these packages:
2022-10-14 20:32:27 +00:00
2023-04-16 18:11:14 +00:00
- `@activity-kit/types`
2022-10-26 21:11:43 +00:00
- The Activity vocabularies converted to TypeScript types.
2023-04-16 18:11:14 +00:00
- `@activity-kit/endpoints`
2022-10-22 07:10:51 +00:00
- The logic for carrying out the bulk of the ActivityPub protocol.
2023-04-16 18:11:14 +00:00
- `@activity-kit/core`
- Common functions that depend on the Adapter APIs.
2023-04-16 18:11:14 +00:00
- `@activity-kit/utilities`
- Common functions with no dependencies on packages from upper layers.
2022-10-14 20:32:27 +00:00
2022-10-27 15:52:47 +00:00
### Adapaters
#### Database Adapaters
2022-10-14 20:32:27 +00:00
2022-11-29 20:18:25 +00:00
There is a large amount of data related to profiles and interactions that must be persisted over time.
2022-10-14 20:32:27 +00:00
Currently this project comes with:
2023-04-16 18:11:14 +00:00
- `@activity-kit/db-mongo`
- `@activity-kit/db-sqlite`
- TODO: `@activity-kit/db-postgresql`
- TODO: `@activity-kit/db-d1`
2022-10-26 21:11:43 +00:00
2022-10-27 15:52:47 +00:00
#### Authentication Adapters
2022-10-15 17:55:54 +00:00
2023-04-15 15:07:34 +00:00
Users need to be able to sign up and log in to their account.
2022-11-29 20:18:25 +00:00
2022-10-15 17:55:54 +00:00
Current this project comes with:
2023-04-16 18:11:14 +00:00
- `@activity-kit/auth-token`
- Generates tokens via Crypto APIs and stores them in the provided database.
- `@activity-kit/auth-firebase`
- Wrapper around `@firebase/auth`
2022-10-15 17:55:54 +00:00
2022-10-27 15:52:47 +00:00
#### Storage Adapters
2022-10-15 17:55:54 +00:00
2023-04-15 15:07:34 +00:00
Users must be able to upload media, such as profile pictures or attachments.
2022-11-29 20:18:25 +00:00
2022-10-26 21:11:43 +00:00
Currently this project comes with:
2023-04-16 18:11:14 +00:00
- `@activity-kit/storage-ftp`
- Uploads media via FTP with the provided credentials.
- TODO: `@activity-kit/storage-s3`
- Upload media via S3-compatible storage APIs.
2022-10-15 17:55:54 +00:00
2022-10-27 15:52:47 +00:00
#### Server Adapters
2022-10-14 20:32:27 +00:00
2022-11-29 20:18:25 +00:00
The server must handle the core endpoint requests.
2022-10-14 20:32:27 +00:00
Currently this project comes with:
2023-07-09 02:04:51 +00:00
- `@activity-kit/express-middleware`
2023-04-16 18:11:14 +00:00
#### Crypto Adapters
2022-10-14 20:32:27 +00:00
2023-04-16 18:11:14 +00:00
There are a few instances that require using native cryptography APIs, such as generating Actors' public/private key pairs.
Typically this will be handled by Node's `crypto` library, but the crypto functions are abstracted to also enable support running within a web worker context.
- `@activity-kit/crypto-node`
- TODO: `@activity-kit/crypto-browser`
2022-10-26 21:11:43 +00:00
#### Email Adapters
In the future, email will be an optional adapter that can be used to reset passwords and send notifications to users.
- TODO: `@activity-kit/email-nodemailer`
2022-10-27 15:52:47 +00:00
### Plugins
2023-04-16 18:11:14 +00:00
Plugins provide lifecycle hooks that can modify core functionality.
2022-11-29 19:59:14 +00:00
2023-04-16 18:11:14 +00:00
You can write your own.
2022-10-27 15:52:47 +00:00
2023-04-16 18:11:14 +00:00
Currently this project comes with:
2022-10-27 15:52:47 +00:00
2023-04-16 18:11:14 +00:00
- `@activity-kit/plugin-groups`
- TODO: `@activity-kit/single-user`
2023-04-16 15:38:01 +00:00
2022-10-26 21:11:43 +00:00
### Client/Rendering Layer
2022-10-14 20:32:27 +00:00
2023-04-15 15:07:34 +00:00
This project does not aim to provide any HTML code for client rendering.
The `pages` configuration properties expect a callback function that renders an HTML string, leaving the front-end mostly to the host app.
The front-end should utilize ActivityPub's Client-to-Server protocol to post Activities on behalf of users.
2023-04-16 18:11:14 +00:00
## Use Cases
There are a few use cases this project attempts to fulfill. Ideally this project papers over some of the complexity of JSON-LD, Activity Streams collections, etc. to make getting started easy.
2023-04-16 18:11:14 +00:00
### Connecting a Blog to the Fediverse
Someone already has an HTML blog and a domain name and wants their posts to be read by others and get replies. Instead of setting up a CMS, they decide to set up an ActivityPub server.
2023-04-16 18:11:14 +00:00
### Single-Server Social Feeds
An exercise app wants to build in social features to make their users feel
proud of their achievements. This would probably include something like a
notification bell and a feed where updates about their friends appear. Users might have with the option to react with an emoji or sticker.
2023-04-16 18:11:14 +00:00
All these exchanges would stay local to the server.
### Private Group Chat
A small group of people who communicate online become dissatisfied with their existing app's policies and decide to communicate privately. They would like to develop their own system for communication.
2023-04-16 18:11:14 +00:00
Although ActivityPub does not define an encryption layer, messages could stay local to a single server or could be exchanged between all parties in an ephermeral way. Encryption could be a good addition, however.
2023-04-16 18:11:14 +00:00
### Federated Social Network
Ideally this project could be used to build an entire social network that
interfaces with the rest of the Fediverse.