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