Abilitiy to respond with 'Accept' Activity and ActivityPubSettings user props
This commit is contained in:
parent
e5b2beffcf
commit
3a70cc6939
|
@ -1,7 +1,10 @@
|
|||
const { isString, isObject } = require('lodash');
|
||||
const { v4: UUIDv4 } = require('uuid');
|
||||
const { ActivityStreamsContext } = require('./activitypub_util');
|
||||
|
||||
module.exports = class Activity {
|
||||
constructor(obj) {
|
||||
this['@context'] = ActivityStreamsContext;
|
||||
Object.assign(this, obj);
|
||||
}
|
||||
|
||||
|
@ -28,7 +31,7 @@ module.exports = class Activity {
|
|||
|
||||
isValid() {
|
||||
if (
|
||||
this['@context'] !== 'https://www.w3.org/ns/activitystreams' ||
|
||||
this['@context'] !== ActivityStreamsContext ||
|
||||
!isString(this.id) ||
|
||||
!isString(this.actor) ||
|
||||
(!isString(this.object) && !isObject(this.object)) ||
|
||||
|
@ -41,4 +44,19 @@ module.exports = class Activity {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/activitypub/#accept-activity-inbox
|
||||
static makeAccept(webServer, localActor, followRequest, id = null) {
|
||||
id = id || webServer.buildUrl(`/${UUIDv4()}`);
|
||||
|
||||
return new Activity({
|
||||
type: 'Accept',
|
||||
actor: localActor,
|
||||
object: followRequest, // previous request Activity
|
||||
});
|
||||
}
|
||||
|
||||
sendTo(actorUrl, cb) {
|
||||
// :TODO: https send |this| to actorUrl
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ const {
|
|||
makeUserUrl,
|
||||
selfUrl,
|
||||
isValidLink,
|
||||
ActivityStreamsContext,
|
||||
} = require('./activitypub_util');
|
||||
const Log = require('./logger').log;
|
||||
|
||||
|
@ -25,10 +26,11 @@ const isString = require('lodash/isString');
|
|||
// https://www.w3.org/TR/activitypub/#actor-objects
|
||||
module.exports = class Actor {
|
||||
constructor(obj) {
|
||||
this['@context'] = [ActivityStreamsContext];
|
||||
|
||||
if (obj) {
|
||||
Object.assign(this, obj);
|
||||
} else {
|
||||
this['@context'] = ['https://www.w3.org/ns/activitystreams'];
|
||||
this.id = '';
|
||||
this.type = '';
|
||||
this.inbox = '';
|
||||
|
@ -41,7 +43,7 @@ module.exports = class Actor {
|
|||
isValid() {
|
||||
if (
|
||||
!Array.isArray(this['@context']) ||
|
||||
this['@context'][0] !== 'https://www.w3.org/ns/activitystreams'
|
||||
this['@context'][0] !== ActivityStreamsContext
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -66,7 +68,7 @@ module.exports = class Actor {
|
|||
|
||||
const obj = {
|
||||
'@context': [
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
ActivityStreamsContext,
|
||||
'https://w3id.org/security/v1', // :TODO: add support
|
||||
],
|
||||
id: userSelfUrl,
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
const { selfUrl } = require('./activitypub_util');
|
||||
const UserProps = require('./user_property');
|
||||
|
||||
module.exports = class ActivityPubSettings {
|
||||
constructor(obj) {
|
||||
this.enabled = true; // :TODO: fetch from +op config default
|
||||
this.manuallyApproveFollowers = false;
|
||||
this.hideSocialGraph = false; // followers, following
|
||||
this.showRealName = false;
|
||||
this.imageUrl = '';
|
||||
this.iconUrl = '';
|
||||
|
||||
if (obj) {
|
||||
Object.assign(this, obj);
|
||||
}
|
||||
}
|
||||
|
||||
static fromUser(user) {
|
||||
if (!user.activityPubSettings) {
|
||||
const settingsProp = user.getProperty(UserProps.ActivityPubSettings);
|
||||
let settings;
|
||||
try {
|
||||
const parsed = JSON.parse(settingsProp);
|
||||
settings = new ActivityPubSettings(parsed);
|
||||
} catch (e) {
|
||||
settings = new ActivityPubSettings();
|
||||
}
|
||||
|
||||
user.activityPubSettings = settings;
|
||||
}
|
||||
|
||||
return user.activityPubSettings;
|
||||
}
|
||||
|
||||
persistToUserProperties(user, cb = null) {
|
||||
return user.persistProperty(
|
||||
UserProps.ActivityPubSettings,
|
||||
JSON.stringify(this),
|
||||
cb
|
||||
);
|
||||
}
|
||||
};
|
|
@ -2,6 +2,7 @@ const { WellKnownLocations } = require('./servers/content/web');
|
|||
const User = require('./user');
|
||||
const { Errors, ErrorReasons } = require('./enig_error');
|
||||
const UserProps = require('./user_property');
|
||||
const ActivityPubSettings = require('./activitypub_settings');
|
||||
|
||||
// deps
|
||||
const _ = require('lodash');
|
||||
|
@ -11,6 +12,7 @@ const fs = require('graceful-fs');
|
|||
const paths = require('path');
|
||||
const moment = require('moment');
|
||||
|
||||
exports.ActivityStreamsContext = 'https://www.w3.org/ns/activitystreams';
|
||||
exports.isValidLink = isValidLink;
|
||||
exports.makeUserUrl = makeUserUrl;
|
||||
exports.webFingerProfileUrl = webFingerProfileUrl;
|
||||
|
@ -52,6 +54,7 @@ function selfUrl(webServer, user) {
|
|||
|
||||
function accountFromSelfUrl(url) {
|
||||
// https://some.l33t.enigma.board/_enig/ap/users/Masto -> Masto
|
||||
// :TODO: take webServer, and just take path-to-users.length +1
|
||||
return url.substring(url.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
|
@ -78,6 +81,11 @@ function userFromAccount(accountName, cb) {
|
|||
return cb(Errors.AccessDenied('Account disabled', ErrorReasons.Disabled));
|
||||
}
|
||||
|
||||
const activityPubSettings = ActivityPubSettings.fromUser(user);
|
||||
if (!activityPubSettings.enabled) {
|
||||
return cb(Errors.AccessDenied('ActivityPub is not enabled for user'));
|
||||
}
|
||||
|
||||
return cb(null, user);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
const WebHandlerModule = require('../../../web_handler_module');
|
||||
const {
|
||||
makeUserUrl,
|
||||
webFingerProfileUrl,
|
||||
selfUrl,
|
||||
userFromAccount,
|
||||
getUserProfileTemplatedBody,
|
||||
DefaultProfileTemplate,
|
||||
accountFromSelfUrl,
|
||||
} = require('../../../activitypub_util');
|
||||
const UserProps = require('../../../user_property');
|
||||
const Config = require('../../../config').get;
|
||||
const Activity = require('../../../activitypub_activity');
|
||||
const ActivityPubSettings = require('../../../activitypub_settings');
|
||||
|
||||
// deps
|
||||
const _ = require('lodash');
|
||||
|
@ -46,7 +43,6 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
|
||||
this.webServer.addRoute({
|
||||
method: 'POST',
|
||||
//inbox: makeUserUrl(this.webServer, user, '/ap/users/') + '/inbox',
|
||||
path: /^\/_enig\/ap\/users\/.+\/inbox$/,
|
||||
handler: this._inboxPostHandler.bind(this),
|
||||
});
|
||||
|
@ -208,6 +204,31 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
|
|||
|
||||
// :TODO: return OK and kick off a async job of persisting and sending and 'Accepted'
|
||||
|
||||
//
|
||||
// If the user blindly accepts Followers, we can persist
|
||||
// and send an 'Accept' now. Otherwise, we need to queue this
|
||||
// request for the user to review and decide what to do with
|
||||
// at a later time.
|
||||
//
|
||||
const activityPubSettings = ActivityPubSettings.fromUser(user);
|
||||
if (!activityPubSettings.manuallyApproveFollowers) {
|
||||
//
|
||||
// :TODO: Implement the queue
|
||||
Actor.fromLocalUser(user, this.webServer, (err, localActor) => {
|
||||
if (err) {
|
||||
// :TODO:
|
||||
return;
|
||||
}
|
||||
|
||||
const accept = Activity.makeAccept(
|
||||
this.webServer,
|
||||
localActor,
|
||||
activity
|
||||
);
|
||||
console.log(accept);
|
||||
});
|
||||
}
|
||||
|
||||
resp.writeHead(200, { 'Content-Type': 'text/html' });
|
||||
return resp.end('');
|
||||
});
|
||||
|
|
|
@ -69,4 +69,6 @@ module.exports = {
|
|||
|
||||
PublicKeyMain: 'public_key_main_rsa_pem', // RSA public key for user
|
||||
PrivateKeyMain: 'private_key_main_rsa_pem', // RSA private key (corresponding to PublicKeyMain)
|
||||
|
||||
ActivityPubSettings: 'activity_pub_settings', // JSON object (above); see ActivityPubSettings in activitypub_settings.js
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue