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;
|
||||
|
|
|
@ -278,61 +278,6 @@ export const pack = (
|
|||
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) {
|
||||
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 Accesses from 'accesses';
|
||||
|
||||
import activityPub from './activitypub';
|
||||
import log from './log-request';
|
||||
import config from '../conf';
|
||||
|
||||
|
@ -53,6 +54,7 @@ app.use((req, res, next) => {
|
|||
*/
|
||||
app.use('/api', require('./api'));
|
||||
app.use('/files', require('./file'));
|
||||
app.use(activityPub);
|
||||
app.use(require('./web'));
|
||||
|
||||
function createServer() {
|
||||
|
|
Loading…
Reference in a new issue