1 |
|
2 |
|
3 |
|
4 |
|
5 | var express = require('express');
|
6 | var cookieParser = require('cookie-parser');
|
7 | var uuid = require('uuid');
|
8 | var cryptography = require('antisocial-encryption');
|
9 |
|
10 |
|
11 | var app = express();
|
12 |
|
13 | app.use(express.json());
|
14 | app.use(express.urlencoded({
|
15 | extended: false
|
16 | }));
|
17 | app.use(cookieParser());
|
18 |
|
19 |
|
20 |
|
21 | var antisocial = require('./index');
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | function dbHandler() {
|
29 | var self = this;
|
30 |
|
31 | self.collections = {
|
32 | 'users': {},
|
33 | 'friends': {},
|
34 | 'invitations': {},
|
35 | 'blocks': {}
|
36 | };
|
37 |
|
38 |
|
39 | this.newInstance = function (collectionName, data, cb) {
|
40 | data.id = uuid();
|
41 | self.collections[collectionName][data.id] = data;
|
42 | if (cb) {
|
43 | cb(null, data);
|
44 | }
|
45 | else {
|
46 | return data;
|
47 | }
|
48 | };
|
49 |
|
50 |
|
51 | this.getInstances = function (collectionName, pairs, cb) {
|
52 | var found = [];
|
53 | for (var item in self.collections[collectionName]) {
|
54 | if (self.collections[collectionName].hasOwnProperty(item)) {
|
55 | var instance = self.collections[collectionName][item];
|
56 |
|
57 | var match = 0;
|
58 | for (var i = 0; i < pairs.length; i++) {
|
59 | var prop = pairs[i].property;
|
60 | var value = pairs[i].value;
|
61 | if (instance[prop] === value) {
|
62 | ++match;
|
63 | }
|
64 | }
|
65 |
|
66 | if (match == pairs.length) {
|
67 | found.push(instance);
|
68 | }
|
69 | }
|
70 | }
|
71 | if (cb) {
|
72 | cb(null, found);
|
73 | }
|
74 | else {
|
75 | return found;
|
76 | }
|
77 | };
|
78 |
|
79 |
|
80 | this.updateInstance = function (collectionName, id, patch, cb) {
|
81 | var item = self.collections[collectionName][id];
|
82 | for (var prop in patch) {
|
83 | if (patch.hasOwnProperty(prop)) {
|
84 | item[prop] = patch[prop];
|
85 | }
|
86 | }
|
87 | if (cb) {
|
88 | cb(null, item);
|
89 | }
|
90 | else {
|
91 | return item;
|
92 | }
|
93 | };
|
94 |
|
95 | this.deleteInstance = function (collectionName, id, cb) {
|
96 | delete self.collections[collectionName][id];
|
97 | if (cb) {
|
98 | cb(null);
|
99 | }
|
100 | };
|
101 | }
|
102 |
|
103 | var db = new dbHandler();
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 | function getAuthenticatedUser(req, res, next) {
|
115 | var token;
|
116 |
|
117 | if (req.cookies && req.cookies.access_token) {
|
118 | token = req.cookies.access_token;
|
119 | }
|
120 |
|
121 | if (req.body && req.body.access_token) {
|
122 | token = req.body.access_token;
|
123 | }
|
124 |
|
125 | if (!token) {
|
126 | return next();
|
127 | }
|
128 |
|
129 | db.getInstances('users', [{
|
130 | 'property': 'token',
|
131 | 'value': token
|
132 | }], function (err, userInstances) {
|
133 | req.antisocialUser = userInstances[0];
|
134 | next();
|
135 | });
|
136 | }
|
137 |
|
138 | app.db = db;
|
139 |
|
140 | function setupAntisocialEvents(antisocialApp) {
|
141 | antisocialApp.on('new-friend-request', function (e) {
|
142 | console.log('antisocial new-friend-request %s %j', e.info.user.username, e.info.friend.remoteEndPoint);
|
143 | });
|
144 |
|
145 | antisocialApp.on('new-friend', function (e) {
|
146 | console.log('antisocial new-friend %s %j', e.info.user.username, e.info.friend.remoteEndPoint);
|
147 | });
|
148 |
|
149 | antisocialApp.on('friend-updated', function (e) {
|
150 | console.log('antisocial friend-updated %s %j', e.info.user.username, e.info.friend.remoteEndPoint);
|
151 | });
|
152 |
|
153 | antisocialApp.on('friend-deleted', function (e) {
|
154 | console.log('antisocial friend-deleted %s %j', e.info.user.username, e.info.friend.remoteEndPoint);
|
155 | });
|
156 |
|
157 | antisocialApp.on('open-activity-connection', function (e) {
|
158 | var friend = e.info.friend;
|
159 | var user = e.info.user;
|
160 | var socket = e.socket;
|
161 |
|
162 | console.log('antisocial new-activity-connection %j', e.info.key);
|
163 |
|
164 |
|
165 | socket.antisocial.setDataHandler(function (data) {
|
166 | console.log('antisocial activity-data from %s to %s %j', friend.remoteName, user.name, data);
|
167 | });
|
168 |
|
169 | var data = JSON.stringify({
|
170 | 'hello': friend.remoteName
|
171 | });
|
172 |
|
173 | var message = cryptography.encrypt(friend.remotePublicKey, friend.keys.private, data);
|
174 |
|
175 | e.socket.emit('data', message);
|
176 | });
|
177 |
|
178 | antisocialApp.on('activity-backfill', function (e) {
|
179 | var user = e.info.user;
|
180 | var friend = e.info.friend;
|
181 | var socket = e.socket;
|
182 | var highwater = e.highwater;
|
183 | console.log('antisocial activity-backfill user %s friend %s requesting backfill since %s', user.username, friend.remoteEndPoint, highwater);
|
184 | });
|
185 |
|
186 | antisocialApp.on('close-activity-connection', function (e) {
|
187 | console.log('antisocial new-activity-connection %j', e.info.key);
|
188 | });
|
189 |
|
190 | antisocialApp.on('open-notification-connection', function (e) {
|
191 | console.log('antisocial new-notification-connection %j', e.info.key);
|
192 |
|
193 | socket.antisocial.setDataHandler(function (data) {
|
194 | console.log('antisocial notification-data from %s to %s %j', e.info.user.name, data);
|
195 | });
|
196 |
|
197 | e.socket.emit('data', {
|
198 | 'hello': 'world'
|
199 | });
|
200 | });
|
201 |
|
202 | antisocialApp.on('close-notification-connection', function (e) {
|
203 | console.log('antisocial new-notification-connection %j', e.info.key);
|
204 | });
|
205 |
|
206 | antisocialApp.on('notification-backfill', function (e) {
|
207 | var user = e.info.user;
|
208 | var socket = e.socket;
|
209 | var highwater = e.highwater;
|
210 | console.log('antisocial notification-backfill user %s requesting backfill since %s', user.username, highwater);
|
211 | });
|
212 | }
|
213 |
|
214 |
|
215 | var router = express.Router();
|
216 | router.all('/register', function (req, res) {
|
217 | var params = req.method === 'GET' ? req.query : req.body;
|
218 | app.db.newInstance('users', {
|
219 | 'name': params.name,
|
220 | 'username': params.username,
|
221 | 'token': uuid(),
|
222 | 'id': uuid()
|
223 | }, function (err, user) {
|
224 | res.cookie('access_token', user.token).send({
|
225 | 'status': 'ok',
|
226 | 'result': user
|
227 | });
|
228 | });
|
229 | });
|
230 |
|
231 | app.use(router);
|
232 |
|
233 | var server = null;
|
234 |
|
235 | app.start = function (port) {
|
236 | var http = require('http');
|
237 | server = http.createServer(app);
|
238 | var listener = server.listen(port);
|
239 |
|
240 |
|
241 | var config = {
|
242 | 'APIPrefix': '/antisocial',
|
243 | 'publicHost': 'http://127.0.0.1:3000',
|
244 | 'port': 3000
|
245 | };
|
246 |
|
247 | var antisocialApp = antisocial(app, config, db, getAuthenticatedUser, listener);
|
248 |
|
249 | setupAntisocialEvents(antisocialApp);
|
250 | };
|
251 |
|
252 | app.stop = function () {
|
253 | server.close();
|
254 | };
|
255 |
|
256 | if (require.main === module) {
|
257 | app.start(3000);
|
258 | }
|
259 |
|
260 | module.exports = app;
|