UNPKG

4.04 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
5/*
6 mount socket.io listener for incoming notifications connections (client)
7*/
8
9var debug = require('debug')('antisocial-friends:notifications');
10var VError = require('verror').VError;
11var IO = require('socket.io');
12var IOAuth = require('socketio-auth');
13
14module.exports = function notificationsFeedMount(antisocialApp, expressListener) {
15 var config = antisocialApp.config;
16 var db = antisocialApp.db;
17 var authUserMiddleware = antisocialApp.authUserMiddleware;
18
19 if (!antisocialApp.openNotificationsListeners) {
20 antisocialApp.openNotificationsListeners = {};
21 }
22
23 antisocialApp.ioNotifications = IO(expressListener, {
24 'path': '/antisocial-notifications'
25 });
26
27 antisocialApp.ioNotifications.on('connect', function (soc) {
28 debug('/antisocial-notifications connect', soc.id);
29 soc.on('disconnect', function (e) {
30 debug('/antisocial-notifications disconnect %s %s', soc.id, e);
31 });
32 soc.on('error', function (e) {
33 debug('/antisocial-notifications error %s %s', soc.id, e);
34 });
35 });
36
37
38
39 // user notification feed
40 // authenticate with access_token cookie
41 IOAuth(antisocialApp.ioNotifications, {
42 'timeout': 60000,
43 'authenticate': function (socket, data, callback) {
44 debug('notificationsFeedMount authenticate');
45
46 var cookie = require('cookie');
47 var cookieParser = require('cookie-parser');
48
49 if (!socket.handshake.headers.cookie) {
50 return callback(null, false);
51 }
52
53 var cookies = cookie.parse(socket.handshake.headers.cookie);
54 var signedCookies = cookieParser.signedCookies(cookies, config.secureCookiePassword);
55 if (!signedCookies.access_token) {
56 return callback(null, false);
57 }
58
59 var fakeReq = {
60 'cookies': signedCookies
61 };
62
63 authUserMiddleware(fakeReq, null, function () {
64 if (!fakeReq.antisocialUser) {
65 return callback(new VError('not logged in'));
66 }
67
68 data.currentUser = fakeReq.antisocialUser;
69 callback(null, true);
70 });
71 },
72 'postAuthenticate': function (socket, data) {
73 socket.antisocial = {
74 'user': data.currentUser,
75 'key': data.currentUser.username
76 };
77
78 debug('notificationsFeedMount connection established %s', socket.antisocial.key);
79
80 antisocialApp.openNotificationsListeners[socket.antisocial.key] = socket;
81
82 socket.antisocial.emitter = function (appId, eventType, data) {
83 socket.emit(eventType, {
84 'appId': appId,
85 'data': data
86 });
87 };
88
89 antisocialApp.emit('open-notification-connection', socket.antisocial.user, socket.antisocial.emitter, socket.antisocial);
90
91 socket.on('highwater', function (data) {
92 debug('got highwater from %s %s', socket.antisocial.key, data);
93 var appid = data.appId;
94 antisocialApp.emit('notification-backfill-' + appid, socket.antisocial.user, data.highwater, socket.antisocial.emitter);
95 });
96
97 socket.on('data', function (message) {
98 debug('got data from %s', socket.antisocial.key, message);
99
100 try {
101 message = JSON.parse(message);
102 }
103 catch (e) {
104 debug('unable to parse JSON message %j', message);
105 }
106
107 var data = message.data;
108
109 if (!message.contentType || message.contentType === 'application/json') {
110 try {
111 data = JSON.parse(message.data);
112 }
113 catch (e) {
114 debug('unable to parse JSON data');
115 }
116 }
117
118 var appid = data.appId;
119 antisocialApp.emit('notification-data-' + appid, socket.antisocial.user, data.data);
120 });
121
122 socket.on('disconnect', function (reason) {
123 debug('got disconnect %s %s', socket.antisocial.key, reason);
124 antisocialApp.emit('close-notification-connection', socket.antisocial.user, reason, socket.antisocial);
125 db.updateInstance('users', socket.antisocial.user.id, {
126 'online': false
127 });
128 delete antisocialApp.openNotificationsListeners[socket.antisocial.key];
129 });
130
131 db.updateInstance('users', socket.antisocial.user.id, {
132 'online': true
133 });
134 }
135 });
136};