commit
						1fc185e569
					
				
					 6 changed files with 69 additions and 6 deletions
				
			
		| 
						 | 
					@ -134,6 +134,7 @@
 | 
				
			||||||
		"hard-source-webpack-plugin": "0.6.4",
 | 
							"hard-source-webpack-plugin": "0.6.4",
 | 
				
			||||||
		"highlight.js": "9.12.0",
 | 
							"highlight.js": "9.12.0",
 | 
				
			||||||
		"html-minifier": "3.5.12",
 | 
							"html-minifier": "3.5.12",
 | 
				
			||||||
 | 
							"http-signature": "^1.2.0",
 | 
				
			||||||
		"inquirer": "5.2.0",
 | 
							"inquirer": "5.2.0",
 | 
				
			||||||
		"is-root": "2.0.0",
 | 
							"is-root": "2.0.0",
 | 
				
			||||||
		"is-url": "1.2.4",
 | 
							"is-url": "1.2.4",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,10 @@ export default async (value, usernameLower, hostLower, acctLower) => {
 | 
				
			||||||
		host: toUnicode(finger.subject.replace(/^.*?@/, '')),
 | 
							host: toUnicode(finger.subject.replace(/^.*?@/, '')),
 | 
				
			||||||
		hostLower,
 | 
							hostLower,
 | 
				
			||||||
		account: {
 | 
							account: {
 | 
				
			||||||
 | 
								publicKey: {
 | 
				
			||||||
 | 
									id: object.publicKey.id,
 | 
				
			||||||
 | 
									publicKeyPem: object.publicKey.publicKeyPem
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
			uri: object.id,
 | 
								uri: object.id,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,10 @@ export type ILocalAccount = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IRemoteAccount = {
 | 
					export type IRemoteAccount = {
 | 
				
			||||||
	uri: string;
 | 
						uri: string;
 | 
				
			||||||
 | 
						publicKey: {
 | 
				
			||||||
 | 
							id: string;
 | 
				
			||||||
 | 
							publicKeyPem: string;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IUser = {
 | 
					export type IUser = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										42
									
								
								src/server/activitypub/inbox.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/server/activitypub/inbox.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					import * as bodyParser from 'body-parser';
 | 
				
			||||||
 | 
					import * as express from 'express';
 | 
				
			||||||
 | 
					import { parseRequest, verifySignature } from 'http-signature';
 | 
				
			||||||
 | 
					import User, { IRemoteAccount } from '../../models/user';
 | 
				
			||||||
 | 
					import queue from '../../queue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const app = express();
 | 
				
			||||||
 | 
					app.disable('x-powered-by');
 | 
				
			||||||
 | 
					app.use(bodyParser.json());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.get('/@:user/inbox', async (req, res) => {
 | 
				
			||||||
 | 
						let parsed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
							parsed = parseRequest(req);
 | 
				
			||||||
 | 
						} catch (exception) {
 | 
				
			||||||
 | 
							return res.sendStatus(401);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const user = await User.findOne({
 | 
				
			||||||
 | 
							host: { $ne: null },
 | 
				
			||||||
 | 
							account: { publicKey: { id: parsed.keyId } }
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (user === null) {
 | 
				
			||||||
 | 
							return res.sendStatus(401);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!verifySignature(parsed, (user.account as IRemoteAccount).publicKey.publicKeyPem)) {
 | 
				
			||||||
 | 
							return res.sendStatus(401);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						queue.create('http', {
 | 
				
			||||||
 | 
							type: 'performActivityPub',
 | 
				
			||||||
 | 
							actor: user._id,
 | 
				
			||||||
 | 
							outbox: req.body,
 | 
				
			||||||
 | 
						}).save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res.sendStatus(200);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default app;
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/server/activitypub/index.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/server/activitypub/index.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					import * as express from 'express';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import user from './user';
 | 
				
			||||||
 | 
					import inbox from './inbox';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const app = express();
 | 
				
			||||||
 | 
					app.disable('x-powered-by');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.use(user);
 | 
				
			||||||
 | 
					app.use(inbox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default app;
 | 
				
			||||||
| 
						 | 
					@ -1,16 +1,15 @@
 | 
				
			||||||
import * as express from 'express';
 | 
					import * as express from 'express';
 | 
				
			||||||
 | 
					import config from '../../conf';
 | 
				
			||||||
import config from '../conf';
 | 
					import { extractPublic } from '../../crypto_key';
 | 
				
			||||||
import { extractPublic } from '../crypto_key';
 | 
					import parseAcct from '../../common/user/parse-acct';
 | 
				
			||||||
import parseAcct from '../common/user/parse-acct';
 | 
					import User, { ILocalAccount } from '../../models/user';
 | 
				
			||||||
import User, { ILocalAccount } from '../models/user';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const app = express();
 | 
					const app = express();
 | 
				
			||||||
app.disable('x-powered-by');
 | 
					app.disable('x-powered-by');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.get('/@:user', async (req, res, next) => {
 | 
					app.get('/@:user', async (req, res, next) => {
 | 
				
			||||||
	const accepted = req.accepts(['html', 'application/activity+json', 'application/ld+json']);
 | 
						const accepted = req.accepts(['html', 'application/activity+json', 'application/ld+json']);
 | 
				
			||||||
	if (!['application/activity+json', 'application/ld+json'].includes(accepted)) {
 | 
						if (!(['application/activity+json', 'application/ld+json'] as Array<any>).includes(accepted)) {
 | 
				
			||||||
		return next();
 | 
							return next();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +39,7 @@ app.get('/@:user', async (req, res, next) => {
 | 
				
			||||||
		],
 | 
							],
 | 
				
			||||||
		type: 'Person',
 | 
							type: 'Person',
 | 
				
			||||||
		id,
 | 
							id,
 | 
				
			||||||
 | 
							inbox: `${id}/inbox`,
 | 
				
			||||||
		preferredUsername: user.username,
 | 
							preferredUsername: user.username,
 | 
				
			||||||
		name: user.name,
 | 
							name: user.name,
 | 
				
			||||||
		summary: user.description,
 | 
							summary: user.description,
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue