Actor.fromLocalUser()
This commit is contained in:
parent
2370185bcc
commit
e5b2beffcf
|
@ -4,9 +4,15 @@
|
|||
// ENiGMA½
|
||||
const actorDb = require('./database.js').dbs.actor;
|
||||
const { Errors } = require('./enig_error.js');
|
||||
const Events = require('./events.js');
|
||||
const { ActorProps } = require('./activitypub_actor_property');
|
||||
const { isValidLink } = require('./activitypub_util');
|
||||
const UserProps = require('./user_property');
|
||||
const {
|
||||
webFingerProfileUrl,
|
||||
makeUserUrl,
|
||||
selfUrl,
|
||||
isValidLink,
|
||||
} = require('./activitypub_util');
|
||||
const Log = require('./logger').log;
|
||||
|
||||
// deps
|
||||
const assert = require('assert');
|
||||
|
@ -54,8 +60,55 @@ module.exports = class Actor {
|
|||
return true;
|
||||
}
|
||||
|
||||
// :TODO: create an Actor object from a local user
|
||||
static fromLocalUser(userId, cb) {}
|
||||
// :TODO: from a User object
|
||||
static fromLocalUser(user, webServer, cb) {
|
||||
const userSelfUrl = selfUrl(webServer, user);
|
||||
|
||||
const obj = {
|
||||
'@context': [
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1', // :TODO: add support
|
||||
],
|
||||
id: userSelfUrl,
|
||||
type: 'Person',
|
||||
preferredUsername: user.username,
|
||||
name: user.getSanitizedName('real'),
|
||||
endpoints: {
|
||||
sharedInbox: 'TODO',
|
||||
},
|
||||
inbox: makeUserUrl(webServer, user, '/ap/users/') + '/inbox',
|
||||
outbox: makeUserUrl(webServer, user, '/ap/users/') + '/outbox',
|
||||
followers: makeUserUrl(webServer, user, '/ap/users/') + '/followers',
|
||||
following: makeUserUrl(webServer, user, '/ap/users/') + '/following',
|
||||
summary: user.getProperty(UserProps.AutoSignature) || '',
|
||||
url: webFingerProfileUrl(webServer, user),
|
||||
|
||||
// :TODO: we can start to define BBS related stuff with the community perhaps
|
||||
// attachment: [
|
||||
// {
|
||||
// name: 'SomeNetwork Address',
|
||||
// type: 'PropertyValue',
|
||||
// value: 'Mateo@21:1/121',
|
||||
// },
|
||||
// ],
|
||||
};
|
||||
|
||||
const publicKeyPem = user.getProperty(UserProps.PublicKeyMain);
|
||||
if (!_.isEmpty(publicKeyPem)) {
|
||||
obj.publicKey = {
|
||||
id: userSelfUrl + '#main-key',
|
||||
owner: userSelfUrl,
|
||||
publicKeyPem,
|
||||
};
|
||||
} else {
|
||||
Log.warn(
|
||||
{ username: user.username },
|
||||
`No public key (${UserProps.PublicKeyMain}) for user "${user.username}"`
|
||||
);
|
||||
}
|
||||
|
||||
return cb(null, new Actor(obj));
|
||||
}
|
||||
|
||||
static fromRemoteUrl(url, cb) {
|
||||
const headers = {
|
||||
|
|
|
@ -214,54 +214,6 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
});
|
||||
}
|
||||
|
||||
// :TODO: replace me with a fetch-and-cache in Actor, wrapped in e.g. Actor.fetch(url, options, cb)
|
||||
_fetchActor(actorUrl, cb) {
|
||||
const headers = {
|
||||
Accept: 'application/activity+json',
|
||||
};
|
||||
https
|
||||
.get(actorUrl, { headers }, res => {
|
||||
if (res.statusCode !== 200) {
|
||||
return cb(Errors.Invalid(`Bad HTTP status code: ${req.statusCode}`));
|
||||
}
|
||||
|
||||
const contentType = res.headers['content-type'];
|
||||
if (
|
||||
!_.isString(contentType) ||
|
||||
!contentType.startsWith('application/activity+json')
|
||||
) {
|
||||
return cb(Errors.Invalid(`Invalid Content-Type: ${contentType}`));
|
||||
}
|
||||
|
||||
res.setEncoding('utf8');
|
||||
let body = '';
|
||||
res.on('data', data => {
|
||||
body += data;
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
try {
|
||||
const actor = JSON.parse(body);
|
||||
if (
|
||||
!Array.isArray(actor['@context']) ||
|
||||
actor['@context'][0] !==
|
||||
'https://www.w3.org/ns/activitystreams'
|
||||
) {
|
||||
return cb(
|
||||
Errors.Invalid('Invalid or missing Actor "@context"')
|
||||
);
|
||||
}
|
||||
return cb(null, actor);
|
||||
} catch (e) {
|
||||
return cb(e);
|
||||
}
|
||||
});
|
||||
})
|
||||
.on('error', err => {
|
||||
return cb(err);
|
||||
});
|
||||
}
|
||||
|
||||
_validateKeyId(keyId) {
|
||||
if (!keyId) {
|
||||
return false;
|
||||
|
@ -275,74 +227,19 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
console.log(req);
|
||||
}
|
||||
|
||||
// _populateKeyIdInfo(keyId, info) {
|
||||
// if (!_.isString(keyId)) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// const m = /^https?:\/\/.+\/(.+)#(main-key)$/.exec(keyId);
|
||||
// if (!m || !m.length === 3) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// info.accountName = m[1];
|
||||
// info.keyType = m[2];
|
||||
// return true;
|
||||
// }
|
||||
|
||||
_selfAsActorHandler(user, req, resp) {
|
||||
this.log.trace(
|
||||
{ username: user.username },
|
||||
`Serving ActivityPub Actor for "${user.username}"`
|
||||
);
|
||||
|
||||
const userSelfUrl = selfUrl(this.webServer, user);
|
||||
|
||||
// :TODO: something like: Actor.makeActor(...)
|
||||
const bodyJson = {
|
||||
'@context': [
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
'https://w3id.org/security/v1',
|
||||
],
|
||||
id: userSelfUrl,
|
||||
type: 'Person',
|
||||
preferredUsername: user.username,
|
||||
name: user.getSanitizedName('real'),
|
||||
endpoints: {
|
||||
sharedInbox: 'TODO',
|
||||
},
|
||||
inbox: makeUserUrl(this.webServer, user, '/ap/users/') + '/inbox',
|
||||
outbox: makeUserUrl(this.webServer, user, '/ap/users/') + '/outbox',
|
||||
followers: makeUserUrl(this.webServer, user, '/ap/users/') + '/followers',
|
||||
following: makeUserUrl(this.webServer, user, '/ap/users/') + '/following',
|
||||
summary: user.getProperty(UserProps.AutoSignature) || '',
|
||||
url: webFingerProfileUrl(this.webServer, user),
|
||||
|
||||
// :TODO: we can start to define BBS related stuff with the community perhaps
|
||||
// attachment: [
|
||||
// {
|
||||
// name: 'SomeNetwork Address',
|
||||
// type: 'PropertyValue',
|
||||
// value: 'Mateo@21:1/121',
|
||||
// },
|
||||
// ],
|
||||
};
|
||||
|
||||
const publicKeyPem = user.getProperty(UserProps.PublicKeyMain);
|
||||
if (!_.isEmpty(publicKeyPem)) {
|
||||
bodyJson['publicKey'] = {
|
||||
id: userSelfUrl + '#main-key',
|
||||
owner: userSelfUrl,
|
||||
publicKeyPem,
|
||||
};
|
||||
} else {
|
||||
this.log.warn(
|
||||
{ username: user.username },
|
||||
`No public key (${UserProps.PublicKeyMain}) for user "${user.username}"`
|
||||
);
|
||||
Actor.fromLocalUser(user, this.webServer, (err, actor) => {
|
||||
if (err) {
|
||||
// :TODO: Log me
|
||||
return this.webServer.internalServerError(resp);
|
||||
}
|
||||
|
||||
const body = JSON.stringify(bodyJson);
|
||||
const body = JSON.stringify(actor);
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/activity+json',
|
||||
|
@ -351,6 +248,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
|
||||
resp.writeHead(200, headers);
|
||||
return resp.end(body);
|
||||
});
|
||||
}
|
||||
|
||||
_standardSelfHandler(user, req, resp) {
|
||||
|
|
Loading…
Reference in New Issue