add Undo support to unfollow
This commit is contained in:
parent
dbf8e5a413
commit
e47dd9286f
4 changed files with 51 additions and 15 deletions
|
@ -7,7 +7,8 @@ const pubFederation = require('./federation')
|
||||||
module.exports = {
|
module.exports = {
|
||||||
address,
|
address,
|
||||||
addToOutbox,
|
addToOutbox,
|
||||||
build
|
build,
|
||||||
|
undo
|
||||||
}
|
}
|
||||||
|
|
||||||
function build (type, actorId, object, to, cc, etc) {
|
function build (type, actorId, object, to, cc, etc) {
|
||||||
|
@ -61,11 +62,26 @@ async function address (activity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToOutbox (actor, activity) {
|
function addToOutbox (actor, activity) {
|
||||||
return Promise.all([
|
const tasks = [
|
||||||
// ensure object is cached, but don't alter representation in activity
|
|
||||||
// so activities can be sent with objects as links
|
|
||||||
//pubObject.resolve(activity.object),
|
|
||||||
store.stream.save(activity),
|
store.stream.save(activity),
|
||||||
address(activity).then(addresses => pubFederation.deliver(actor, activity, addresses))
|
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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,18 @@ const store = require('../store')
|
||||||
|
|
||||||
router.post('/', net.validators.activity, net.security.verifySignature, function (req, res) {
|
router.post('/', net.validators.activity, net.security.verifySignature, function (req, res) {
|
||||||
req.body._meta = { _target: pub.utils.usernameToIRI(req.user) }
|
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
|
// side effects
|
||||||
switch (req.body.type) {
|
switch (req.body.type) {
|
||||||
case 'Accept':
|
case 'Accept':
|
||||||
// TODO - side effect necessary for following collection?
|
// TODO - side effect necessary for following collection?
|
||||||
break
|
break
|
||||||
case 'Follow':
|
case 'Follow':
|
||||||
|
// TODO resolve object and ensure specified target matches inbox user
|
||||||
// req.body._meta._target = req.body.object.id
|
// req.body._meta._target = req.body.object.id
|
||||||
// send acceptance reply
|
// send acceptance reply
|
||||||
pub.actor.getOrCreateActor(req.user, true)
|
pub.actor.getOrCreateActor(req.user, true)
|
||||||
|
@ -24,6 +29,7 @@ router.post('/', net.validators.activity, net.security.verifySignature, function
|
||||||
.catch(e => console.log(e))
|
.catch(e => console.log(e))
|
||||||
break
|
break
|
||||||
case 'Create':
|
case 'Create':
|
||||||
|
toDo.saveObject = true
|
||||||
pub.actor.getOrCreateActor(req.user, true)
|
pub.actor.getOrCreateActor(req.user, true)
|
||||||
.then(user => {
|
.then(user => {
|
||||||
const to = [user.followers]
|
const to = [user.followers]
|
||||||
|
@ -31,15 +37,23 @@ router.post('/', net.validators.activity, net.security.verifySignature, function
|
||||||
pub.utils.actorFromActivity(req.body),
|
pub.utils.actorFromActivity(req.body),
|
||||||
'https://www.w3.org/ns/activitystreams#Public'
|
'https://www.w3.org/ns/activitystreams#Public'
|
||||||
]
|
]
|
||||||
const accept = pub.activity.build('Announce', user.id, req.body.object.id, to, cc)
|
const announce = pub.activity.build('Announce', user.id, req.body.object.id, to, cc)
|
||||||
return pub.activity.addToOutbox(user, accept)
|
return pub.activity.addToOutbox(user, announce)
|
||||||
}).catch(e => console.log(e))
|
}).catch(e => console.log(e))
|
||||||
break
|
break
|
||||||
|
case 'Undo':
|
||||||
|
pub.activity.undo(req.body.object, req.body.actor)
|
||||||
|
.catch(err => console.log(err))
|
||||||
|
break
|
||||||
}
|
}
|
||||||
Promise.all([
|
const tasks = []
|
||||||
pub.object.resolve(req.body.object),
|
if (toDo.saveObject) {
|
||||||
store.stream.save(req.body)
|
tasks.push(pub.object.resolve(req.body.object))
|
||||||
]).then(() => res.status(200).send())
|
}
|
||||||
|
if (toDo.saveActivity) {
|
||||||
|
tasks.push(store.stream.save(req.body))
|
||||||
|
}
|
||||||
|
Promise.all(tasks).then(() => res.status(200).send())
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
res.status(500).send()
|
res.status(500).send()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
const connection = require('./connection')
|
const connection = require('./connection')
|
||||||
module.exports = {
|
module.exports = {
|
||||||
get,
|
get,
|
||||||
|
remove,
|
||||||
save
|
save
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,3 +35,8 @@ async function save (activity) {
|
||||||
// server object ID avoids mutating local copy of document
|
// server object ID avoids mutating local copy of document
|
||||||
.insertOne(activity, { forceServerObjectId: true })
|
.insertOne(activity, { forceServerObjectId: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function remove (activity, actor) {
|
||||||
|
return connection.getDb().collection('streams')
|
||||||
|
.deleteMany({ id: activity.id, actor: actor })
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue