add Undo support to unfollow

This commit is contained in:
Will Murphy 2019-09-25 17:15:39 -05:00
parent dbf8e5a413
commit e47dd9286f
4 changed files with 51 additions and 15 deletions

View file

@ -7,7 +7,8 @@ const pubFederation = require('./federation')
module.exports = {
address,
addToOutbox,
build
build,
undo
}
function build (type, actorId, object, to, cc, etc) {
@ -61,11 +62,26 @@ async function address (activity) {
}
function addToOutbox (actor, activity) {
return Promise.all([
// ensure object is cached, but don't alter representation in activity
// so activities can be sent with objects as links
//pubObject.resolve(activity.object),
const tasks = [
store.stream.save(activity),
address(activity).then(addresses => pubFederation.deliver(actor, activity, addresses))
])
]
// ensure activity object is cached if local, but do not try to resolve links
// because Mastodon won't resolve activity IRIs
if (pubUtils.validateObject(activity.object)) {
tasks.push(pubObject.resolve(activity.object))
}
return Promise.all(tasks)
}
function undo (activity, undoActor) {
if (!pubUtils.validateActivity(activity)) {
if (!activity || Object.prototype.toString.call(activity) !== '[object String]') {
throw new Error('Invalid undo target')
}
activity = { id: activity }
}
// matches the target activity with the actor from the undo
// so actors can only undo their own activities
return store.stream.remove(activity, undoActor)
}

View file

@ -6,13 +6,18 @@ const store = require('../store')
router.post('/', net.validators.activity, net.security.verifySignature, function (req, res) {
req.body._meta = { _target: pub.utils.usernameToIRI(req.user) }
console.log(req.body);
console.log(req.body)
const toDo = {
saveActivity: true,
saveObject: false
}
// side effects
switch (req.body.type) {
case 'Accept':
// TODO - side effect necessary for following collection?
break
case 'Follow':
// TODO resolve object and ensure specified target matches inbox user
// req.body._meta._target = req.body.object.id
// send acceptance reply
pub.actor.getOrCreateActor(req.user, true)
@ -24,6 +29,7 @@ router.post('/', net.validators.activity, net.security.verifySignature, function
.catch(e => console.log(e))
break
case 'Create':
toDo.saveObject = true
pub.actor.getOrCreateActor(req.user, true)
.then(user => {
const to = [user.followers]
@ -31,15 +37,23 @@ router.post('/', net.validators.activity, net.security.verifySignature, function
pub.utils.actorFromActivity(req.body),
'https://www.w3.org/ns/activitystreams#Public'
]
const accept = pub.activity.build('Announce', user.id, req.body.object.id, to, cc)
return pub.activity.addToOutbox(user, accept)
const announce = pub.activity.build('Announce', user.id, req.body.object.id, to, cc)
return pub.activity.addToOutbox(user, announce)
}).catch(e => console.log(e))
break
case 'Undo':
pub.activity.undo(req.body.object, req.body.actor)
.catch(err => console.log(err))
break
}
Promise.all([
pub.object.resolve(req.body.object),
store.stream.save(req.body)
]).then(() => res.status(200).send())
const tasks = []
if (toDo.saveObject) {
tasks.push(pub.object.resolve(req.body.object))
}
if (toDo.saveActivity) {
tasks.push(store.stream.save(req.body))
}
Promise.all(tasks).then(() => res.status(200).send())
.catch(err => {
console.log(err)
res.status(500).send()

View file

@ -2,6 +2,7 @@
const connection = require('./connection')
module.exports = {
get,
remove,
save
}
@ -34,3 +35,8 @@ async function save (activity) {
// server object ID avoids mutating local copy of document
.insertOne(activity, { forceServerObjectId: true })
}
function remove (activity, actor) {
return connection.getDb().collection('streams')
.deleteMany({ id: activity.id, actor: actor })
}