Add server module

This commit is contained in:
Michael Puckett 2023-07-08 22:04:51 -04:00
parent 8caf34f7bc
commit 2119ea8e95
28 changed files with 577 additions and 66 deletions

View File

@ -31,7 +31,7 @@ import * as express from "express";
import { MongoClient } from "mongodb";
import { AP, Adapters } from "@activity-kit/types";
import { activityKitPlugin } from "@activity-kit/server-express";
import { activityKitPlugin } from "@activity-kit/express-middleware";
import { MongoDbAdapter } from "@activity-kit/db-mongo";
import { TokenAuthAdapter } from "@activity-kit/auth-token";
import { NodeCryptoAdapter } from "@activity-kit/crypto-node";
@ -202,10 +202,7 @@ The server must handle the core endpoint requests.
Currently this project comes with:
- `@activity-kit/server-express`
- TODO: `@activity-kit/server-fastify`
- TODO: `@activity-kit/server-serverless`
- TODO: `@activity-kit/server-koa`
- `@activity-kit/express-middleware`
#### Crypto Adapters

181
package-lock.json generated
View File

@ -41,12 +41,16 @@
"resolved": "packages/endpoints",
"link": true
},
"node_modules/@activity-kit/express-middleware": {
"resolved": "packages/express-middleware",
"link": true
},
"node_modules/@activity-kit/plugin-groups": {
"resolved": "packages/plugin-groups",
"link": true
},
"node_modules/@activity-kit/server-express": {
"resolved": "packages/server-express",
"node_modules/@activity-kit/server": {
"resolved": "packages/server",
"link": true
},
"node_modules/@activity-kit/storage-ftp": {
@ -3018,6 +3022,72 @@
"node": "^14.15.0 || >=16.0.0"
}
},
"node_modules/@lit-labs/ssr": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr/-/ssr-3.1.5.tgz",
"integrity": "sha512-OvjM3CZGPRjZTIAgWvLCXS3sFj574rXfAzhtzQjgHYNxTuRy+LMfKpgeu8xF7PywdcOniVaLZuGKF4WS7YI7hA==",
"dependencies": {
"@lit-labs/ssr-client": "^1.1.0",
"@lit-labs/ssr-dom-shim": "^1.1.0",
"@lit/reactive-element": "^1.6.0",
"@parse5/tools": "^0.1.0",
"@types/node": "^16.0.0",
"enhanced-resolve": "^5.10.0",
"lit": "^2.7.0",
"lit-element": "^3.3.0",
"lit-html": "^2.7.0",
"node-fetch": "^3.2.8",
"parse5": "^7.1.1"
},
"engines": {
"node": ">=13.9.0"
}
},
"node_modules/@lit-labs/ssr-client": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-client/-/ssr-client-1.1.2.tgz",
"integrity": "sha512-hb10IRTmxtnQ2fcYYJE7bC2f+6UmucBgFnkfxepoE1cZ5mO6ZiTZGoFzFrNd5EQXeQq+HpYmYOF4W/JBwBE+AA==",
"dependencies": {
"@lit/reactive-element": "^1.0.0",
"lit": "^2.0.0",
"lit-html": "^2.7.1"
}
},
"node_modules/@lit-labs/ssr-dom-shim": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz",
"integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
},
"node_modules/@lit-labs/ssr/node_modules/@types/node": {
"version": "16.18.38",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.38.tgz",
"integrity": "sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ=="
},
"node_modules/@lit-labs/ssr/node_modules/node-fetch": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz",
"integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/@lit/reactive-element": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz",
"integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==",
"dependencies": {
"@lit-labs/ssr-dom-shim": "^1.0.0"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"dev": true,
@ -3519,6 +3589,14 @@
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parse5/tools": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@parse5/tools/-/tools-0.1.0.tgz",
"integrity": "sha512-VB9+4BsFoS+4HdB/Ph9jD4FHQt7GyiWESVNfBSh8Eu54LujWyy+NySGLjg8GZFWSZcESG72F67LjgmKZDZCvPg==",
"dependencies": {
"parse5": "^7.0.0"
}
},
"node_modules/@protobufjs/aspromise": {
"version": "1.1.2",
"license": "BSD-3-Clause"
@ -3766,6 +3844,11 @@
"@types/node": "*"
}
},
"node_modules/@types/trusted-types": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
"integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g=="
},
"node_modules/@types/webidl-conversions": {
"version": "7.0.0",
"dev": true,
@ -5462,6 +5545,18 @@
"once": "^1.4.0"
}
},
"node_modules/enhanced-resolve": {
"version": "5.15.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
"integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/enquirer": {
"version": "2.3.6",
"dev": true,
@ -6969,7 +7064,6 @@
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"devOptional": true,
"license": "ISC"
},
"node_modules/grapheme-splitter": {
@ -8237,6 +8331,34 @@
"uc.micro": "^1.0.1"
}
},
"node_modules/lit": {
"version": "2.7.6",
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.6.tgz",
"integrity": "sha512-1amFHA7t4VaaDe+vdQejSVBklwtH9svGoG6/dZi9JhxtJBBlqY5D1RV7iLUYY0trCqQc4NfhYYZilZiVHt7Hxg==",
"dependencies": {
"@lit/reactive-element": "^1.6.0",
"lit-element": "^3.3.0",
"lit-html": "^2.7.0"
}
},
"node_modules/lit-element": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz",
"integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==",
"dependencies": {
"@lit-labs/ssr-dom-shim": "^1.1.0",
"@lit/reactive-element": "^1.3.0",
"lit-html": "^2.7.0"
}
},
"node_modules/lit-html": {
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.5.tgz",
"integrity": "sha512-YqUzpisJodwKIlbMFCtyrp58oLloKGnnPLMJ1t23cbfIJjg/H9pvLWK4XS69YeubK5HUs1UE4ys9w5dP1zg6IA==",
"dependencies": {
"@types/trusted-types": "^2.0.2"
}
},
"node_modules/load-json-file": {
"version": "6.2.0",
"dev": true,
@ -11130,6 +11252,14 @@
"version": "3.2.4",
"license": "MIT"
},
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/tar": {
"version": "6.1.13",
"dev": true,
@ -12120,6 +12250,25 @@
"typescript": "^5.0.4"
}
},
"packages/express-middleware": {
"name": "@activity-kit/express-middleware",
"version": "0.4.36",
"license": "MIT",
"dependencies": {
"@activity-kit/endpoints": "^0.4.36",
"@activity-kit/types": "^0.4.36",
"@activity-kit/utilities": "^0.4.36",
"express": "^4.18.2",
"path-to-regexp": "^6.2.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"eslint": "^8.25.0",
"prettier": "^2.7.1",
"typescript": "^5.0.4"
}
},
"packages/plugin-groups": {
"name": "@activity-kit/plugin-groups",
"version": "0.4.36",
@ -12141,9 +12290,35 @@
"typescript": "^5.0.4"
}
},
"packages/server": {
"name": "@activity-kit/server",
"version": "0.4.36",
"license": "MIT",
"dependencies": {
"@activity-kit/auth-token": "^0.4.36",
"@activity-kit/crypto-node": "^0.4.36",
"@activity-kit/db-mongo": "^0.4.36",
"@activity-kit/endpoints": "^0.4.36",
"@activity-kit/express-middleware": "^0.4.36",
"@activity-kit/storage-ftp": "^0.4.36",
"@activity-kit/types": "^0.4.36",
"@activity-kit/utilities": "^0.4.36",
"@lit-labs/ssr": "^3.1.5",
"express": "^4.18.2",
"lit": "^2.7.6"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"eslint": "^8.25.0",
"prettier": "^2.7.1",
"typescript": "^5.0.4"
}
},
"packages/server-express": {
"name": "@activity-kit/server-express",
"version": "0.4.36",
"extraneous": true,
"license": "MIT",
"dependencies": {
"@activity-kit/endpoints": "^0.4.36",

View File

@ -1,8 +1,2 @@
import { UserPostEndpoint } from '.';
export declare function createUserActor(this: UserPostEndpoint, user: {
uid: string;
type: string;
email: string;
name: string;
preferredUsername: string;
}): Promise<void>;
import { UserPostEndpoint, User } from '.';
export declare function createUserActor(this: UserPostEndpoint, user: User, uid: string): Promise<void>;

View File

@ -4,14 +4,15 @@ exports.createUserActor = void 0;
const utilities_1 = require("@activity-kit/utilities");
const types_1 = require("@activity-kit/types");
const path_to_regexp_1 = require("path-to-regexp");
async function createUserActor(user) {
async function createUserActor(user, uid) {
(0, types_1.assertIsApActor)(user);
const { publicKey, privateKey } = await this.core.generateKeyPair();
const publishedDate = new Date();
const getRouteUrl = (route, data) => new URL(`${utilities_1.LOCAL_DOMAIN}${(0, path_to_regexp_1.compile)(route, {
validate: false,
})(data)}`);
const userId = getRouteUrl(this.routes[user.type.toLowerCase()], {
const firstType = (Array.isArray(user.type) ? user.type[0] : user.type).toLowerCase();
const userId = getRouteUrl(this.routes[firstType], {
username: user.preferredUsername,
});
const entityRoute = userId.pathname;
@ -155,12 +156,9 @@ async function createUserActor(user) {
entityRoute,
slug: 'upload-media',
});
let userActor = (0, utilities_1.applyContext)({
const userActorProperties = {
id: userId,
url: userId,
type: user.type === types_1.AP.ActorTypes.GROUP
? types_1.AP.ActorTypes.GROUP
: types_1.AP.ActorTypes.PERSON,
name: user.name,
preferredUsername: user.preferredUsername,
inbox: userInbox.id,
@ -185,7 +183,16 @@ async function createUserActor(user) {
publicKeyPem: publicKey,
},
published: publishedDate,
});
};
let userActor = (0, utilities_1.applyContext)(user.type === types_1.AP.ActorTypes.GROUP
? {
...userActorProperties,
type: types_1.AP.ActorTypes.GROUP,
}
: {
...userActorProperties,
type: types_1.AP.ActorTypes.PERSON,
});
(0, types_1.assertIsApActor)(userActor);
const botActor = await this.core.findOne('entity', {
preferredUsername: utilities_1.SERVER_ACTOR_USERNAME,
@ -253,9 +260,9 @@ async function createUserActor(user) {
this.core.saveEntity(userBlocks),
this.core.saveEntity(userLists),
this.core.saveEntity(userBookmarks),
this.core.saveString('account', user.uid, user.email),
this.core.saveString('privateKey', user.uid, privateKey),
this.core.saveString('username', user.uid, user.preferredUsername),
this.core.saveString('account', uid, user.email),
this.core.saveString('privateKey', uid, privateKey),
this.core.saveString('username', uid, user.preferredUsername),
]);
await Promise.all(declaredStreams);
if (createActorActivity.id && userInbox.id) {

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,15 @@ import { createServerActor } from './createServerActor';
import { createUserActor } from './createUserActor';
import type { IncomingMessage, ServerResponse } from 'http';
import { CoreLibrary, Plugin, Routes } from '@activity-kit/types';
export declare class User {
readonly uid: string;
readonly type: string;
readonly email: string;
readonly name: string;
readonly preferredUsername: string;
readonly password: string;
constructor(rawBody: Record<string, unknown>);
}
export declare class UserPostEndpoint {
routes: Routes;
req: IncomingMessage;

View File

@ -1,9 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserPostEndpoint = void 0;
exports.UserPostEndpoint = exports.User = void 0;
const utilities_1 = require("@activity-kit/utilities");
const createServerActor_1 = require("./createServerActor");
const createUserActor_1 = require("./createUserActor");
class User {
uid;
type;
email;
name;
preferredUsername;
password;
constructor(rawBody) {
if (typeof rawBody.uid !== 'string') {
throw {
error: 'No uid provided',
field: 'uid',
};
}
if (typeof rawBody.type !== 'string') {
throw {
error: 'No type provided',
field: 'type',
};
}
if (typeof rawBody.email !== 'string') {
throw {
error: 'Email is required.',
field: 'email',
};
}
if (typeof rawBody.name !== 'string') {
throw {
error: 'Name is required.',
field: 'name',
};
}
if (typeof rawBody.preferredUsername !== 'string') {
throw {
error: 'Preferred Username is required.',
field: 'preferredUsername',
};
}
if (typeof rawBody.password !== 'string') {
throw {
error: 'Password is required.',
field: 'password',
};
}
this.uid = rawBody.uid;
this.type = rawBody.type;
this.email = rawBody.email;
this.name = rawBody.name;
this.preferredUsername = rawBody.preferredUsername;
this.password = rawBody.password;
}
}
exports.User = User;
class UserPostEndpoint {
routes;
req;
@ -21,38 +74,21 @@ class UserPostEndpoint {
createUserActor = createUserActor_1.createUserActor;
async respond() {
const body = JSON.parse(await (0, utilities_1.streamToString)(this.req));
const { email, type, password, name, preferredUsername } = body;
if (!email) {
const user = await new Promise((resolve) => {
resolve(new User(body));
}).catch((error) => {
this.res.statusCode = 300;
this.res.write(JSON.stringify({
error: 'Email is required.',
field: 'email',
}));
this.res.end();
return;
}
if (!password) {
this.res.statusCode = 300;
this.res.write(JSON.stringify({
error: 'Password is required.',
field: 'password',
}));
this.res.end();
return;
}
if (!preferredUsername) {
this.res.statusCode = 300;
this.res.write(JSON.stringify({
error: 'Username is required.',
field: 'username',
}));
this.res.write(JSON.stringify(error));
this.res.end();
});
if (!user) {
return;
}
const isUsernameTaken = !!(await this.core.findOne('entity', {
preferredUsername,
preferredUsername: user.preferredUsername,
}));
if (isUsernameTaken || utilities_1.RESERVED_USERNAMES.includes(preferredUsername)) {
if (isUsernameTaken ||
utilities_1.RESERVED_USERNAMES.includes(user.preferredUsername)) {
this.res.statusCode = 409;
this.res.write(JSON.stringify({
error: 'Username taken.',
@ -63,9 +99,9 @@ class UserPostEndpoint {
}
try {
const { uid, token } = await this.core.createUser({
email,
password,
preferredUsername,
email: user.email,
password: user.password,
preferredUsername: user.preferredUsername,
});
const isBotCreated = !!(await this.core.findOne('entity', {
preferredUsername: utilities_1.SERVER_ACTOR_USERNAME,
@ -73,13 +109,7 @@ class UserPostEndpoint {
if (!isBotCreated) {
await this.createServerActor();
}
await this.createUserActor({
uid,
type,
email,
preferredUsername,
name,
});
await this.createUserActor(user, uid);
this.res.statusCode = 200;
this.res.write(JSON.stringify({
token,

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/user/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/user/index.ts"],"names":[],"mappings":"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"}

View File

@ -1,5 +1,5 @@
{
"name": "@activity-kit/server-express",
"name": "@activity-kit/express-middleware",
"version": "0.4.36",
"description": "> TODO: description",
"author": "Michael Puckett <michaelcpuckett@gmail.com>",

27
packages/server/.build.js Normal file
View File

@ -0,0 +1,27 @@
const fs = require('fs');
try {
fs.rmSync('./lib', { recursive: true, });
} catch (error) {
// Already deleted.
}
const ts = require('typescript');
const path = require('path');
const configFileName = path.resolve(__dirname, 'tsconfig.json');
const { config } = ts.readConfigFile(configFileName, ts.sys.readFile);
const compilerOptions = ts.parseJsonConfigFileContent(config, ts.sys, path.dirname(configFileName)).options;
const program = ts.createProgram(['./src/index.ts'], compilerOptions);
const emitResult = program.emit();
if (emitResult.emitSkipped) {
const message = emitResult.diagnostics
.map(diagnostic => ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'))
.join('\n');
console.log(message);
process.exit(1);
}
console.log('Built TS.');

View File

@ -0,0 +1,10 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"extends": ["plugin:@typescript-eslint/recommended"],
"ignorePatterns": "*.js"
}

View File

@ -0,0 +1,6 @@
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 80
}

11
packages/server/README.md Normal file
View File

@ -0,0 +1,11 @@
# `server`
> TODO: description
## Usage
```
const server = require('server');
// TODO: DEMONSTRATE API
```

1
packages/server/lib/index.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,90 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const express = __importStar(require("express"));
const path = __importStar(require("path"));
const mongodb_1 = require("mongodb");
const db_mongo_1 = require("@activity-kit/db-mongo");
const auth_token_1 = require("@activity-kit/auth-token");
const crypto_node_1 = require("@activity-kit/crypto-node");
const utilities_1 = require("@activity-kit/utilities");
(async () => {
const app = express.default();
app.use(express.static(path.resolve(__dirname, '../static')));
const mongoClient = new mongodb_1.MongoClient(process.env.AP_MONGO_CLIENT_URL ?? 'mongodb://127.0.0.1:27017');
await mongoClient.connect();
const mongoDb = mongoClient.db(process.env.AP_MONGO_DB_NAME ?? 'activitypub');
const mongoDbAdapter = new db_mongo_1.MongoDbAdapter(mongoDb);
const nodeCryptoAdapter = new crypto_node_1.NodeCryptoAdapter();
const tokenAuthAdapter = new auth_token_1.TokenAuthAdapter({
db: mongoDbAdapter,
crypto: nodeCryptoAdapter,
});
app.post('/login', async (req, res, next) => {
const body = JSON.parse(await (0, utilities_1.streamToString)(req));
const email = body.email;
const password = body.password;
if (!email) {
res.send({
success: false,
error: 'Email must be provided.',
});
next();
return;
}
if (!password) {
res.send({
success: false,
error: 'Password must be provided.',
});
next();
return;
}
const result = await tokenAuthAdapter.authenticatePassword(email, password);
res.send(result
? {
success: true,
token: result.token,
}
: {
success: false,
error: 'Invalid email and password combo.',
});
next();
});
app.get('/', async (req, res, next) => {
const htmlResponse = `<!DOCTYPE html>
<html>
<h1>Hello world</h1>
</html>
`;
res.send(htmlResponse);
next();
});
app.listen(process.env.PORT ?? process.env.AP_PORT ?? 3000, () => {
console.log('Running...');
});
})();
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAmC;AACnC,2CAA6B;AAC7B,qCAAsC;AAGtC,qDAAwD;AACxD,yDAA4D;AAC5D,2DAA8D;AAE9D,uDAAyD;AAEzD,CAAC,KAAK,IAAI,EAAE;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAG9B,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAE9D,MAAM,WAAW,GAAG,IAAI,qBAAW,CACjC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,2BAA2B,CAC/D,CAAC;IACF,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,aAAa,CAAC,CAAC;IAC9E,MAAM,cAAc,GAAG,IAAI,yBAAc,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,iBAAiB,GAAG,IAAI,+BAAiB,EAAE,CAAC;IAClD,MAAM,gBAAgB,GAAG,IAAI,6BAAgB,CAAC;QAC5C,EAAE,EAAE,cAAc;QAClB,MAAM,EAAE,iBAAiB;KAC1B,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAA,0BAAc,EAAC,GAAG,CAAC,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE/B,IAAI,CAAC,KAAK,EAAE;YACV,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,yBAAyB;aACjC,CAAC,CAAC;YACH,IAAI,EAAE,CAAC;YACP,OAAO;SACR;QAED,IAAI,CAAC,QAAQ,EAAE;YACb,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,4BAA4B;aACpC,CAAC,CAAC;YACH,IAAI,EAAE,CAAC;YACP,OAAO;SACR;QAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,oBAAoB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAE5E,GAAG,CAAC,IAAI,CACN,MAAM;YACJ,CAAC,CAAC;gBACE,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB;YACH,CAAC,CAAC;gBACE,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,mCAAmC;aAC3C,CACN,CAAC;QACF,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACpC,MAAM,YAAY,GAAG;;;;KAIpB,CAAC;QACF,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvB,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,EAAE,GAAG,EAAE;QAC/D,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,EAAE,CAAC"}

View File

@ -0,0 +1,44 @@
{
"name": "@activity-kit/server",
"version": "0.4.36",
"description": "> TODO: description",
"author": "Michael Puckett <michaelcpuckett@gmail.com>",
"homepage": "",
"license": "MIT",
"main": "lib/index.js",
"directories": {
"lib": "lib"
},
"files": [
"lib"
],
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"eslint": "^8.25.0",
"prettier": "^2.7.1",
"typescript": "^5.0.4"
},
"scripts": {
"build": "node .build.js",
"format": "prettier --config .prettierrc \"**/*.ts\" --write",
"lint": "eslint src/**/*.ts",
"dev": "node lib/index.js"
},
"dependencies": {
"@activity-kit/auth-token": "^0.4.36",
"@activity-kit/crypto-node": "^0.4.36",
"@activity-kit/db-mongo": "^0.4.36",
"@activity-kit/endpoints": "^0.4.36",
"@activity-kit/express-middleware": "^0.4.36",
"@activity-kit/storage-ftp": "^0.4.36",
"@activity-kit/types": "^0.4.36",
"@activity-kit/utilities": "^0.4.36",
"@lit-labs/ssr": "^3.1.5",
"express": "^4.18.2",
"lit": "^2.7.6"
}
}

View File

@ -0,0 +1,83 @@
import * as express from 'express';
import * as path from 'path';
import { MongoClient } from 'mongodb';
import { AP } from '@activity-kit/types';
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';
import { streamToString } from '@activity-kit/utilities';
(async () => {
// Use Express for all routes.
const app = express.default();
// Static files.
app.use(express.static(path.resolve(__dirname, '../static')));
const mongoClient = new MongoClient(
process.env.AP_MONGO_CLIENT_URL ?? 'mongodb://127.0.0.1:27017',
);
await mongoClient.connect();
const mongoDb = mongoClient.db(process.env.AP_MONGO_DB_NAME ?? 'activitypub');
const mongoDbAdapter = new MongoDbAdapter(mongoDb);
const nodeCryptoAdapter = new NodeCryptoAdapter();
const tokenAuthAdapter = new TokenAuthAdapter({
db: mongoDbAdapter,
crypto: nodeCryptoAdapter,
});
app.post('/login', async (req, res, next) => {
const body = JSON.parse(await streamToString(req));
const email = body.email;
const password = body.password;
if (!email) {
res.send({
success: false,
error: 'Email must be provided.',
});
next();
return;
}
if (!password) {
res.send({
success: false,
error: 'Password must be provided.',
});
next();
return;
}
const result = await tokenAuthAdapter.authenticatePassword(email, password);
res.send(
result
? {
success: true,
token: result.token,
}
: {
success: false,
error: 'Invalid email and password combo.',
},
);
next();
});
app.get('/', async (req, res, next) => {
const htmlResponse = `<!DOCTYPE html>
<html>
<h1>Hello world</h1>
</html>
`;
res.send(htmlResponse);
next();
});
app.listen(process.env.PORT ?? process.env.AP_PORT ?? 3000, () => {
console.log('Running...');
});
})();

View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"esModuleInterop": true,
"target": "ESNext",
"jsx": "react",
"skipLibCheck": true,
"moduleResolution": "node",
"sourceMap": true,
"lib": [
"ESNext"
],
"outDir": "./lib"
},
"exclude": [
"./node_modules",
"../../node_modules"
],
"include": [
"src/index.ts"
]
}