Merge pull request #1346 from akihikodaki/user
Implement Activity Streams representation of user
This commit is contained in:
		
						commit
						55f716fc62
					
				
					 4 changed files with 63 additions and 55 deletions
				
			
		
							
								
								
									
										1
									
								
								src/crypto_key.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/crypto_key.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1 +1,2 @@
 | 
				
			||||||
 | 
					export function extractPublic(keypair: String): String;
 | 
				
			||||||
export function generate(): String;
 | 
					export function generate(): String;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -278,61 +278,6 @@ export const pack = (
 | 
				
			||||||
	resolve(_user);
 | 
						resolve(_user);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Pack a user for ActivityPub
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @param user target
 | 
					 | 
				
			||||||
 * @return Packed user
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export const packForAp = (
 | 
					 | 
				
			||||||
	user: string | mongo.ObjectID | IUser
 | 
					 | 
				
			||||||
) => new Promise<any>(async (resolve, reject) => {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let _user: any;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const fields = {
 | 
					 | 
				
			||||||
		// something
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate the user if 'user' is ID
 | 
					 | 
				
			||||||
	if (mongo.ObjectID.prototype.isPrototypeOf(user)) {
 | 
					 | 
				
			||||||
		_user = await User.findOne({
 | 
					 | 
				
			||||||
			_id: user
 | 
					 | 
				
			||||||
		}, { fields });
 | 
					 | 
				
			||||||
	} else if (typeof user === 'string') {
 | 
					 | 
				
			||||||
		_user = await User.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(user)
 | 
					 | 
				
			||||||
		}, { fields });
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		_user = deepcopy(user);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!_user) return reject('invalid user arg.');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const userUrl = `${config.url}/@@${_user._id}`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	resolve({
 | 
					 | 
				
			||||||
		"@context": ["https://www.w3.org/ns/activitystreams", {
 | 
					 | 
				
			||||||
			"@language": "ja"
 | 
					 | 
				
			||||||
		}],
 | 
					 | 
				
			||||||
		"type": "Person",
 | 
					 | 
				
			||||||
		"id": userUrl,
 | 
					 | 
				
			||||||
		"following": `${userUrl}/following.json`,
 | 
					 | 
				
			||||||
		"followers": `${userUrl}/followers.json`,
 | 
					 | 
				
			||||||
		"liked": `${userUrl}/liked.json`,
 | 
					 | 
				
			||||||
		"inbox": `${userUrl}/inbox.json`,
 | 
					 | 
				
			||||||
		"outbox": `${userUrl}/outbox.json`,
 | 
					 | 
				
			||||||
		"sharedInbox": `${config.url}/inbox`,
 | 
					 | 
				
			||||||
		"url": `${config.url}/@${_user.username}`,
 | 
					 | 
				
			||||||
		"preferredUsername": _user.username,
 | 
					 | 
				
			||||||
		"name": _user.name,
 | 
					 | 
				
			||||||
		"summary": _user.description,
 | 
					 | 
				
			||||||
		"icon": [
 | 
					 | 
				
			||||||
			`${config.drive_url}/${_user.avatarId}`
 | 
					 | 
				
			||||||
		]
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
function img(url) {
 | 
					function img(url) {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										60
									
								
								src/server/activitypub.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/server/activitypub.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					import config from '../conf';
 | 
				
			||||||
 | 
					import { extractPublic } from '../crypto_key';
 | 
				
			||||||
 | 
					import parseAcct from '../common/user/parse-acct';
 | 
				
			||||||
 | 
					import User, { ILocalAccount } from '../models/user';
 | 
				
			||||||
 | 
					const express = require('express');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const app = express();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.get('/@:user', async (req, res, next) => {
 | 
				
			||||||
 | 
						const accepted = req.accepts(['html', 'application/activity+json', 'application/ld+json']);
 | 
				
			||||||
 | 
						if (!['application/activity+json', 'application/ld+json'].includes(accepted)) {
 | 
				
			||||||
 | 
							return next();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const { username, host } = parseAcct(req.params.user);
 | 
				
			||||||
 | 
						if (host !== null) {
 | 
				
			||||||
 | 
							return res.send(422);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const user = await User.findOne({
 | 
				
			||||||
 | 
							usernameLower: username.toLowerCase(),
 | 
				
			||||||
 | 
							host: null
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						if (user === null) {
 | 
				
			||||||
 | 
							return res.send(404);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const id = `${config.url}/@${user.username}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (username !== user.username) {
 | 
				
			||||||
 | 
							return res.redirect(id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.json({
 | 
				
			||||||
 | 
							'@context': [
 | 
				
			||||||
 | 
								'https://www.w3.org/ns/activitystreams',
 | 
				
			||||||
 | 
								'https://w3id.org/security/v1'
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							type: 'Person',
 | 
				
			||||||
 | 
							id,
 | 
				
			||||||
 | 
							preferredUsername: user.username,
 | 
				
			||||||
 | 
							name: user.name,
 | 
				
			||||||
 | 
							summary: user.description,
 | 
				
			||||||
 | 
							icon: user.avatarId && {
 | 
				
			||||||
 | 
								type: 'Image',
 | 
				
			||||||
 | 
								url: `${config.drive_url}/${user.avatarId}`
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							image: user.bannerId && {
 | 
				
			||||||
 | 
								type: 'Image',
 | 
				
			||||||
 | 
								url: `${config.drive_url}/${user.bannerId}`
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							publicKey: {
 | 
				
			||||||
 | 
								type: 'Key',
 | 
				
			||||||
 | 
								owner: id,
 | 
				
			||||||
 | 
								publicKeyPem: extractPublic((user.account as ILocalAccount).keypair)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default app;
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ import * as express from 'express';
 | 
				
			||||||
import * as morgan from 'morgan';
 | 
					import * as morgan from 'morgan';
 | 
				
			||||||
import Accesses from 'accesses';
 | 
					import Accesses from 'accesses';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import activityPub from './activitypub';
 | 
				
			||||||
import log from './log-request';
 | 
					import log from './log-request';
 | 
				
			||||||
import config from '../conf';
 | 
					import config from '../conf';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +54,7 @@ app.use((req, res, next) => {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
app.use('/api', require('./api'));
 | 
					app.use('/api', require('./api'));
 | 
				
			||||||
app.use('/files', require('./file'));
 | 
					app.use('/files', require('./file'));
 | 
				
			||||||
 | 
					app.use(activityPub);
 | 
				
			||||||
app.use(require('./web'));
 | 
					app.use(require('./web'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createServer() {
 | 
					function createServer() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue