UNPKG

3.59 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 fixIfBehindProxy = require('../lib/utilities').fixIfBehindProxy;
6var debug = require('debug')('antisocial-friends');
7var VError = require('verror').VError;
8var WError = require('verror').WError;
9var async = require('async');
10var request = require('request');
11var _ = require('lodash');
12
13module.exports = function mountRequestFriendCancel(antisocialApp) {
14
15 var router = antisocialApp.router;
16 var config = antisocialApp.config;
17 var db = antisocialApp.db;
18 var authUserMiddleware = antisocialApp.authUserMiddleware;
19
20 var cancelRegex = /^\/([a-zA-Z0-9\-.]+)\/request-friend-cancel$/;
21
22 debug('mounting GET /username/request-friend-cancel', cancelRegex);
23
24 router.post(cancelRegex, authUserMiddleware, function handleRequestFriendCancel(req, res) {
25 var matches = req.path.match(cancelRegex);
26 var username = matches[1];
27
28 var endpoint = req.body.endpoint;
29
30 if (!endpoint) {
31 debug('endpoint not supplied');
32 return res.status(400).send('endpoint not supplied');
33 }
34
35 if (!endpoint.match(/(^|\s)((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi)) {
36 debug('endpoint not a valid url');
37 return res.status(400).send('endpoint not a valid url');
38 }
39
40 // must be a logged in user
41 var currentUser = req.antisocialUser;
42 if (!currentUser) {
43 debug('not logged in');
44 return res.sendStatus(401);
45 }
46
47 // by convention expects user to match username
48 if (currentUser.username !== username) {
49 debug('username mismatch');
50 return res.status(400).send('username mismatch');
51 }
52
53 async.waterfall([
54 function findFriend(cb) {
55 debug('/request-friend-cancel findFriend');
56 db.getInstances('friends', [{
57 'property': 'userId',
58 'value': currentUser.id
59 }, {
60 'property': 'remoteEndPoint',
61 'value': req.body.endpoint
62 }], function (err, friendInstances) {
63 if (err) {
64 return cb(new VError(err, 'error reading friends'));
65 }
66
67 if (friendInstances.length !== 1) {
68 return cb(new VError(err, 'friend request not found'));
69 }
70
71 cb(null, friendInstances[0]);
72 });
73 },
74 function callWebHook(friend, cb) {
75 debug('/request-friend-cancel callWebhook');
76
77 var payload = {
78 'accessToken': friend.remoteAccessToken,
79 'action': 'request-friend-cancel'
80 };
81
82 var options = {
83 'url': fixIfBehindProxy(friend.remoteEndPoint + '/friend-webhook'),
84 'form': payload,
85 'json': true
86 };
87
88 request.post(options, function (err, response, body) {
89 if (err) {
90 return cb(new VError(err, '/request-friend-cancel callWebhook failed'));
91 }
92 if (response.statusCode !== 200) {
93 return cb(new VError('/request-friend-cancel callWebhook http error ' + response.statusCode));
94 }
95 if (_.get(body, 'status') !== 'ok') {
96 return cb(new VError('/request-friend-cancel callWebhook unexpected result %j' + body));
97 }
98
99 cb(null, friend);
100 });
101 },
102 function updateFriend(friend, cb) {
103 db.deleteInstance('friends', friend.id, function (err, friend) {
104 if (err) {
105 var e = new VError(err, '/request-friend-cancel updateFriend error');
106 return cb(e);
107 }
108
109 cb(null);
110 });
111 }
112 ], function (err) {
113 if (err) {
114 var e = new WError(err, '/request-friend-cancel failed');
115 return res.send({
116 'status': 'error',
117 'reason': e.message,
118 'details': e.cause().message
119 });
120 }
121
122 res.send({
123 'status': 'ok'
124 });
125 });
126 });
127};