Fix local Actor URLs, add addFollowing() API
This commit is contained in:
parent
bd2dc27477
commit
41cd0f7f33
|
@ -19,7 +19,6 @@ const ActivityPubSettings = require('./settings');
|
||||||
const ActivityPubObject = require('./object');
|
const ActivityPubObject = require('./object');
|
||||||
const { ActivityStreamMediaType } = require('./const');
|
const { ActivityStreamMediaType } = require('./const');
|
||||||
const apDb = require('../database').dbs.activitypub;
|
const apDb = require('../database').dbs.activitypub;
|
||||||
const Config = require('../config').get;
|
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
@ -132,11 +131,13 @@ module.exports = class Actor extends ActivityPubObject {
|
||||||
// value: 'Mateo@21:1/121',
|
// value: 'Mateo@21:1/121',
|
||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
bbsInfo: {
|
|
||||||
boardName: Config().general.boardName,
|
// :TODO: re-enable once a spec is defined; board should prob be a object with connection info, etc.
|
||||||
memberSince: user.getProperty(UserProps.AccountCreated),
|
// bbsInfo: {
|
||||||
affiliations: user.getProperty(UserProps.Affiliations) || '',
|
// boardName: Config().general.boardName,
|
||||||
},
|
// memberSince: user.getProperty(UserProps.AccountCreated),
|
||||||
|
// affiliations: user.getProperty(UserProps.Affiliations) || '',
|
||||||
|
// },
|
||||||
};
|
};
|
||||||
|
|
||||||
addImage(obj, 'icon');
|
addImage(obj, 'icon');
|
||||||
|
|
|
@ -26,27 +26,29 @@ module.exports = class Collection extends ActivityPubObject {
|
||||||
const headers = {
|
const headers = {
|
||||||
Accept: ActivityStreamMediaType,
|
Accept: ActivityStreamMediaType,
|
||||||
};
|
};
|
||||||
getJson(collectionUrl, { headers }, (err, collection) => {
|
getJson(
|
||||||
if (err) {
|
collectionUrl,
|
||||||
return cb(err);
|
{ headers, validContentTypes: [ActivityStreamMediaType] },
|
||||||
|
(err, collection) => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
collection = new Collection(collection);
|
||||||
|
if (!collection.isValid()) {
|
||||||
|
return cb(Errors.Invalid('Invalid Collection'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const { totalItems, type, id, summary } = collection;
|
||||||
|
|
||||||
|
return cb(null, {
|
||||||
|
totalItems,
|
||||||
|
type,
|
||||||
|
id,
|
||||||
|
summary,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
);
|
||||||
// :TODO: validate headers?
|
|
||||||
|
|
||||||
collection = new Collection(collection);
|
|
||||||
if (!collection.isValid()) {
|
|
||||||
return cb(Errors.Invalid('Invalid Collection'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { totalItems, type, id, summary } = collection;
|
|
||||||
|
|
||||||
return cb(null, {
|
|
||||||
totalItems,
|
|
||||||
type,
|
|
||||||
id,
|
|
||||||
summary,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static followers(collectionId, page, cb) {
|
static followers(collectionId, page, cb) {
|
||||||
|
@ -71,14 +73,14 @@ module.exports = class Collection extends ActivityPubObject {
|
||||||
|
|
||||||
static addFollower(owningUser, followingActor, webServer, ignoreDupes, cb) {
|
static addFollower(owningUser, followingActor, webServer, ignoreDupes, cb) {
|
||||||
const collectionId =
|
const collectionId =
|
||||||
makeUserUrl(webServer, owningUser, '/ap/collections/') + '/followers';
|
makeUserUrl(webServer, owningUser, '/ap/users/') + '/followers';
|
||||||
return Collection.addToCollection(
|
return Collection.addToCollection(
|
||||||
'followers',
|
'followers',
|
||||||
owningUser,
|
owningUser,
|
||||||
collectionId,
|
collectionId,
|
||||||
followingActor.id,
|
followingActor.id, // Actor following owningUser
|
||||||
followingActor,
|
followingActor,
|
||||||
false,
|
false, // we'll check dynamically when queried
|
||||||
ignoreDupes,
|
ignoreDupes,
|
||||||
cb
|
cb
|
||||||
);
|
);
|
||||||
|
@ -86,12 +88,12 @@ module.exports = class Collection extends ActivityPubObject {
|
||||||
|
|
||||||
static addFollowRequest(owningUser, requestingActor, webServer, ignoreDupes, cb) {
|
static addFollowRequest(owningUser, requestingActor, webServer, ignoreDupes, cb) {
|
||||||
const collectionId =
|
const collectionId =
|
||||||
makeUserUrl(webServer, owningUser, '/ap/collections/') + '/follow-requests';
|
makeUserUrl(webServer, owningUser, '/ap/users/') + '/follow-requests';
|
||||||
return Collection.addToCollection(
|
return Collection.addToCollection(
|
||||||
'follow-requests',
|
'follow-requests',
|
||||||
owningUser,
|
owningUser,
|
||||||
collectionId,
|
collectionId,
|
||||||
requestingActor.id,
|
requestingActor.id, // Actor requesting to follow owningUser
|
||||||
requestingActor,
|
requestingActor,
|
||||||
true,
|
true,
|
||||||
ignoreDupes,
|
ignoreDupes,
|
||||||
|
@ -99,13 +101,27 @@ module.exports = class Collection extends ActivityPubObject {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static addFollowing(owningUser, followingActor, webServer, ignoreDupes, cb) {
|
||||||
|
const collectionId =
|
||||||
|
makeUserUrl(webServer, owningUser, '/ap/users/') + '/following';
|
||||||
|
return Collection.addToCollection(
|
||||||
|
'following',
|
||||||
|
owningUser,
|
||||||
|
collectionId,
|
||||||
|
followingActor.id, // Actor owningUser is following
|
||||||
|
followingActor,
|
||||||
|
false, // we'll check dynamically when queried
|
||||||
|
ignoreDupes,
|
||||||
|
cb
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static outbox(collectionId, page, cb) {
|
static outbox(collectionId, page, cb) {
|
||||||
return Collection.publicOrderedById('outbox', collectionId, page, null, cb);
|
return Collection.publicOrderedById('outbox', collectionId, page, null, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static addOutboxItem(owningUser, outboxItem, isPrivate, webServer, ignoreDupes, cb) {
|
static addOutboxItem(owningUser, outboxItem, isPrivate, webServer, ignoreDupes, cb) {
|
||||||
const collectionId =
|
const collectionId = makeUserUrl(webServer, owningUser, '/ap/users/') + '/outbox';
|
||||||
makeUserUrl(webServer, owningUser, '/ap/collections/') + '/outbox';
|
|
||||||
return Collection.addToCollection(
|
return Collection.addToCollection(
|
||||||
'outbox',
|
'outbox',
|
||||||
owningUser,
|
owningUser,
|
||||||
|
@ -119,8 +135,7 @@ module.exports = class Collection extends ActivityPubObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
static addInboxItem(inboxItem, owningUser, webServer, ignoreDupes, cb) {
|
static addInboxItem(inboxItem, owningUser, webServer, ignoreDupes, cb) {
|
||||||
const collectionId =
|
const collectionId = makeUserUrl(webServer, owningUser, '/ap/users/') + '/inbox';
|
||||||
makeUserUrl(webServer, owningUser, '/ap/collections/') + '/inbox';
|
|
||||||
return Collection.addToCollection(
|
return Collection.addToCollection(
|
||||||
'inbox',
|
'inbox',
|
||||||
owningUser,
|
owningUser,
|
||||||
|
@ -282,9 +297,9 @@ module.exports = class Collection extends ActivityPubObject {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// e.g. http://somewhere.com/_enig/ap/collections/NuSkooler/followers
|
// e.g. http://somewhere.com/_enig/ap/users/NuSkooler/followers
|
||||||
const collectionId =
|
const collectionId =
|
||||||
makeUserUrl(webServer, owningUser, '/ap/collections/') + `/${collectionName}`;
|
makeUserUrl(webServer, owningUser, '/ap/users/') + `/${collectionName}`;
|
||||||
|
|
||||||
if (!page) {
|
if (!page) {
|
||||||
return apDb.get(
|
return apDb.get(
|
||||||
|
|
|
@ -493,7 +493,7 @@ dbs.message.run(
|
||||||
// ActivityPub Collections of various types such as followers, following, likes, ...
|
// ActivityPub Collections of various types such as followers, following, likes, ...
|
||||||
dbs.activitypub.run(
|
dbs.activitypub.run(
|
||||||
`CREATE TABLE IF NOT EXISTS collection (
|
`CREATE TABLE IF NOT EXISTS collection (
|
||||||
collection_id VARCHAR NOT NULL, -- ie: http://somewhere.com/_enig/ap/collections/NuSkooler/followers
|
collection_id VARCHAR NOT NULL, -- ie: http://somewhere.com/_enig/ap/users/NuSkooler/followers
|
||||||
name VARCHAR NOT NULL, -- examples: followers, follows, ...
|
name VARCHAR NOT NULL, -- examples: followers, follows, ...
|
||||||
timestamp DATETIME NOT NULL, -- Timestamp in which this entry was created
|
timestamp DATETIME NOT NULL, -- Timestamp in which this entry was created
|
||||||
owner_actor_id VARCHAR NOT NULL, -- Local, owning Actor ID, or the #Public magic collection ID
|
owner_actor_id VARCHAR NOT NULL, -- Local, owning Actor ID, or the #Public magic collection ID
|
||||||
|
|
|
@ -18,6 +18,17 @@ function getJson(url, options, cb) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(options.validContentTypes)) {
|
||||||
|
const contentType = res.headers['content-type'] || '';
|
||||||
|
if (
|
||||||
|
!options.validContentTypes.some(ct => {
|
||||||
|
return contentType.startsWith(ct);
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
return cb(Errors.HttpError(`Invalid Content-Type: ${contentType}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.debug({ url: url, body: body }, 'Response from getJson');
|
Log.debug({ url: url, body: body }, 'Response from getJson');
|
||||||
let parsed;
|
let parsed;
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue