Reject Follow request support

This commit is contained in:
Bryan Ashby 2023-08-26 22:29:19 -06:00
parent 460070e61d
commit 65ea0192fa
No known key found for this signature in database
GPG Key ID: C2C1B501E4EFD994
3 changed files with 110 additions and 21 deletions

View File

@ -27,12 +27,21 @@ module.exports = class Activity extends ActivityPubObject {
} }
// https://www.w3.org/TR/activitypub/#accept-activity-inbox // https://www.w3.org/TR/activitypub/#accept-activity-inbox
static makeAccept(localActor, followRequest) { static makeAccept(localActor, activity) {
return new Activity({ return new Activity({
id: Activity.activityObjectId(), id: Activity.activityObjectId(),
type: WellKnownActivity.Accept, type: WellKnownActivity.Accept,
actor: localActor, actor: localActor,
object: followRequest, // previous request Activity object: activity, // previous request Activity
});
}
static makeReject(localActor, activity) {
return new Activity({
id: Activity.activityObjectId(),
type: WellKnownActivity.Reject,
actor: localActor.id,
object: activity,
}); });
} }

View File

@ -11,6 +11,7 @@ const async = require('async');
exports.sendFollowRequest = sendFollowRequest; exports.sendFollowRequest = sendFollowRequest;
exports.sendUnfollowRequest = sendUnfollowRequest; exports.sendUnfollowRequest = sendUnfollowRequest;
exports.acceptFollowRequest = acceptFollowRequest; exports.acceptFollowRequest = acceptFollowRequest;
exports.rejectFollowRequest = rejectFollowRequest;
function sendFollowRequest(fromUser, toActor, cb) { function sendFollowRequest(fromUser, toActor, cb) {
const fromActorId = fromUser.getProperty(UserProps.ActivityPubActorId); const fromActorId = fromUser.getProperty(UserProps.ActivityPubActorId);
@ -138,3 +139,46 @@ function acceptFollowRequest(localUser, remoteActor, requestActivity, cb) {
} }
); );
} }
function rejectFollowRequest(localUser, requestActor, requestActivity, cb) {
async.series(
[
callback => {
Actor.fromLocalUser(localUser, (err, localActor) => {
if (err) {
return callback(err);
}
const reject = Activity.makeReject(localActor, localActor);
reject.sendTo(requestActor.inbox, localUser, (err, respBody, res) => {
if (err) {
return callback(Errors.HttpError(err.message, err.code));
}
if (res.statusCode !== 202 && res.statusCode !== 200) {
return callback(
Errors.HttpError(
`Unexpected HTTP status code ${res.statusCode}`
)
);
}
return callback(null);
});
});
},
callback => {
// remove from local requests Collection
return Collection.removeOwnedById(
Collections.FollowRequests,
localUser,
requestActivity.id,
callback
);
},
],
err => {
return cb(err);
}
);
}

View File

@ -11,6 +11,7 @@ const {
sendFollowRequest, sendFollowRequest,
sendUnfollowRequest, sendUnfollowRequest,
acceptFollowRequest, acceptFollowRequest,
rejectFollowRequest,
} = require('./follow_util'); } = require('./follow_util');
const { Collections } = require('./const'); const { Collections } = require('./const');
const EnigAssert = require('../enigma_assert'); const EnigAssert = require('../enigma_assert');
@ -53,14 +54,14 @@ exports.getModule = class activityPubSocialManager extends MenuModule {
this.menuMethods = { this.menuMethods = {
actorListKeyPressed: (formData, extraArgs, cb) => { actorListKeyPressed: (formData, extraArgs, cb) => {
const collection = this.currentCollection;
switch (formData.key.name) { switch (formData.key.name) {
case 'space': case 'space':
{ {
if (this.currentCollection === Collections.Following) { if (collection === Collections.Following) {
return this._toggleFollowing(cb); return this._toggleFollowing(cb);
} else if ( }
this.currentCollection === Collections.FollowRequests if (collection === Collections.FollowRequests) {
) {
return this._acceptFollowRequest(cb); return this._acceptFollowRequest(cb);
} }
} }
@ -68,16 +69,18 @@ exports.getModule = class activityPubSocialManager extends MenuModule {
case 'delete': case 'delete':
{ {
if (this.currentCollection === Collections.Followers) { if (collection === Collections.Followers) {
return this._removeFollower(cb); return this._removeFollower(cb);
} else if ( }
this.currentCollection === Collections.FollowRequests
) { if (collection === Collections.FollowRequests) {
return this._denyFollowRequest(cb); return this._rejectFollowRequest(cb);
} }
} }
break; break;
} }
return cb(null);
}, },
listKeyPressed: (formData, extraArgs, cb) => { listKeyPressed: (formData, extraArgs, cb) => {
const actorListView = this.getView('main', MciViewIds.main.actorList); const actorListView = this.getView('main', MciViewIds.main.actorList);
@ -308,6 +311,19 @@ exports.getModule = class activityPubSocialManager extends MenuModule {
} }
} }
_removeSelectedFollowRequest(actorListView, moveToFollowers) {
const followingActor = this.followRequests.splice(
actorListView.getFocusItemIndex(),
1
)[0];
if (moveToFollowers) {
this.followerActors.push(followingActor);
}
this._switchTo(this.currentCollection); // redraw
}
_acceptFollowRequest(cb) { _acceptFollowRequest(cb) {
EnigAssert(Collections.FollowRequests === this.currentCollection); EnigAssert(Collections.FollowRequests === this.currentCollection);
@ -327,30 +343,50 @@ exports.getModule = class activityPubSocialManager extends MenuModule {
if (err) { if (err) {
this.client.log.error( this.client.log.error(
{ error: err.message }, { error: err.message },
'Failed to fully accept Follow request' 'Error Accepting Follow request'
); );
} }
const followingActor = this.followRequests.splice( this._removeSelectedFollowRequest(actorListView, true); // true=move to followers
actorListView.getFocusItemIndex(),
1
)[0];
this.followerActors.push(followingActor); // move to followers
this._switchTo(this.currentCollection); // redraw
return cb(err); return cb(err);
}); });
} }
_removeFollower(cb) { _removeFollower(cb) {
// :TODO: Send a Undo
return cb(null); return cb(null);
} }
_denyFollowRequest(cb) { _rejectFollowRequest(cb) {
EnigAssert(Collections.FollowRequests === this.currentCollection);
const actorListView = this.getView('main', MciViewIds.main.actorList);
const selectedActor = this._getSelectedActorItem(
actorListView.getFocusItemIndex()
);
if (!selectedActor) {
return cb(null); return cb(null);
} }
const request = selectedActor.request;
EnigAssert(request);
rejectFollowRequest(this.client.user, selectedActor, request, err => {
if (err) {
this.client.log.error(
{ error: err.message },
'Error Rejecting Follow request'
);
}
this._removeSelectedFollowRequest(actorListView, false); // false=do not move to followers
return cb(err);
});
}
_followingActorToggled(actorInfo, cb) { _followingActorToggled(actorInfo, cb) {
// Local user/Actor wants to follow or un-follow // Local user/Actor wants to follow or un-follow
const wantsToFollow = actorInfo.status; const wantsToFollow = actorInfo.status;