diff --git a/api/src/api.js b/api/src/api.js index 24036e5..f4d251c 100644 --- a/api/src/api.js +++ b/api/src/api.js @@ -2,4 +2,5 @@ module.exports = { url: require('./api-utils.js').url, auth: require('./api/auth.js'), feed: require('./api/feed.js'), + accounts: require('./api/accounts.js'), } diff --git a/api/src/api/accounts.js b/api/src/api/accounts.js new file mode 100644 index 0000000..0cdd353 --- /dev/null +++ b/api/src/api/accounts.js @@ -0,0 +1,65 @@ +const crypto = require('crypto') +const auth = require('../auth.js') +const utils = require('../api-utils.js') + +async function getFollow(req, res) { + return await db.table.objects().findOne({ + actor: apID(res.locals.user.username), + to: req.query.url, + type: 'Follow', + }) +} + +module.exports = { + follow: { + post: [auth.enforceSession, async (req, res) => { + if (!utils.isURLValid(req.query.url)) + return res.json({ error: 'invalid_url' }) + + const follow = await getFollow(req, res) + if (follow !== null) + return res.json({ error: 'already_following' }) + + const actor = await apex.store.getObject( + apID(res.locals.user.username), true) + const payload = { + id: utils.apRandomURL(), + type: 'Follow', + actor: apID(res.locals.user.username), + object: req.query.url, + to: req.query.url, + } + await apex.addToOutbox(actor, payload) + await apex.store.saveObject(payload) + res.json({ result: 1 }) + }], + }, + unfollow: { + post: [auth.enforceSession, async (req, res) => { + if (!utils.isURLValid(req.query.url)) + return res.json({ error: 'invalid_url' }) + + const follow = await getFollow(req, res) + if (follow === null) + return res.json({ error: 'no_following' }) + + const actor = await apex.store.getObject( + apID(res.locals.user.username), true) + const payload = { + id: utils.apRandomURL(), + type: 'Undo', + actor: apID(res.locals.user.username), + to: req.query.url, + object: { + id: follow.id, + type: 'Follow', + actor: apID(res.locals.user.username), + object: req.query.url, + }, + } + await apex.addToOutbox(actor, payload) + await db.table.objects().deleteOne({ _id: follow._id }) + res.json({ result: 1 }) + }], + }, +} diff --git a/api/src/server.js b/api/src/server.js index 71331c0..6505eb6 100644 --- a/api/src/server.js +++ b/api/src/server.js @@ -67,6 +67,8 @@ app.on('apex-inbox', activity.federation.inbox) app.route(api.url('/auth/register')).post(api.auth.register.post) app.route(api.url('/auth/login')).post(api.auth.login.post) app.route(api.url('/feed/meet')).get(api.feed.meet.get) +app.route(api.url('/accounts/follow')).post(api.accounts.follow.post) +app.route(api.url('/accounts/unfollow')).post(api.accounts.unfollow.post) // initialize client.connect({ useNewUrlParser: true })