UNPKG

3.96 kBJavaScriptView Raw
1// Copyright Michael Rhodes. 2017,2018. All Rights Reserved.
2// This file is licensed under the MIT License.
3// License text available at https://opensource.org/licenses/MIT
4
5var debug = require('debug')('antisocial-friends');
6var VError = require('verror').VError;
7var WError = require('verror').WError;
8var async = require('async');
9
10module.exports = function mountFriendWebhook(antisocialApp) {
11
12 var router = antisocialApp.router;
13 var config = antisocialApp.config;
14 var db = antisocialApp.db;
15 var authUserMiddleware = antisocialApp.authUserMiddleware;
16
17 var webhookRegex = /^\/([a-zA-Z0-9\-.]+)\/friend-webhook$/;
18
19 debug('mounting GET /username/friend-webhook', webhookRegex);
20
21 router.post(webhookRegex, function handleFriendRequest(req, res) {
22 var matches = req.path.match(webhookRegex);
23 var username = matches[1];
24
25 async.waterfall([
26 function getUser(cb) {
27 debug('/friend-webhook getUser');
28 db.getInstances('users', [{
29 'property': 'username',
30 'value': username
31 }], function (err, userInstances) {
32 if (err) {
33 return cb(new VError(err, 'user not found'));
34 }
35
36 if (userInstances.length > 1) {
37 return cb(new VError('more than one user matching username'));
38 }
39
40 if (!userInstances.length) {
41 return cb(new VError('user not found'));
42 }
43
44 var user = userInstances[0];
45
46 cb(err, user);
47 });
48 },
49 function getFriendByAccessToken(user, cb) {
50 debug('/friend-webhook getFriendByAccessToken');
51 db.getInstances('friends', [{
52 'property': 'userId',
53 'value': user.id
54 }, {
55 'property': 'localAccessToken',
56 'value': req.body.accessToken
57 }], function (err, friendInstances) {
58 if (err) {
59 return cb(new VError(err, 'error reading friends'));
60 }
61
62 if (!friendInstances.length) {
63 return cb(new VError(err, 'friend not found'));
64 }
65
66 cb(err, user, friendInstances[0]);
67 });
68 },
69 function updateFriend(user, friend, cb) {
70 debug('/friend-webhook updateFriend action ' + req.body.action);
71
72 if (req.body.action === 'friend-request-accepted') {
73 // mark friend as accepted
74 friend.audiences.push('friends');
75 var update = {
76 'status': 'accepted',
77 'audiences': friend.audiences
78 };
79
80 db.updateInstance('friends', friend.id, update, function (err, friend) {
81 if (err) {
82 var e = new VError(err, '/friend-webhook friend-request-accepted error');
83 return cb(e, friend);
84 }
85
86 antisocialApp.emit('new-friend', user, friend);
87
88 antisocialApp.activityFeed.connect(user, friend);
89
90 cb(null, friend);
91 });
92 }
93 else if (req.body.action === 'friend-update') {
94
95 antisocialApp.emit('friend-updated', user, friend);
96
97 cb(null, friend);
98 }
99 else if (req.body.action === 'friend-request-declined' || req.body.action === 'request-friend-cancel' || req.body.action === 'friend-delete') {
100
101 antisocialApp.emit('friend-deleted', user, JSON.parse(JSON.stringify(friend)));
102
103 if (req.body.action === 'friend-delete') {
104 antisocialApp.activityFeed.disconnect(user, friend, function (err) {
105 db.deleteInstance('friends', friend.id, function (err) {
106 if (err) {
107 var e = new VError(err, '/friend-webhook ' + req.body.action + ' error');
108 return cb(e);
109 }
110 cb(null);
111 });
112 });
113 }
114 else {
115 db.deleteInstance('friends', friend.id, function (err) {
116 if (err) {
117 var e = new VError(err, '/friend-webhook ' + req.body.action + ' error');
118 return cb(e);
119 }
120 cb(null);
121 });
122 }
123 }
124 else {
125 return cb(new VError('unknown webhook action'));
126 }
127 }
128 ], function (err) {
129 if (err) {
130 var e = new WError(err, '/friend-webook failed');
131 return res.send({
132 'status': 'error',
133 'reason': e.message,
134 'details': e.cause().message
135 });
136 }
137 res.send({
138 'status': 'ok'
139 });
140 });
141 });
142};