UNPKG

3.68 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
20 if (!antisocialApp.openNotificationsListeners) {
21 antisocialApp.openNotificationsListeners = {};
22 }
23
24 antisocialApp.ioNotifications = IO(expressListener, {
25 'path': '/antisocial-notifications'
26 });
27
28 antisocialApp.ioNotifications.on('connect', function (soc) {
29 debug('/antisocial-notifications connect %s', soc.id);
30 soc.on('disconnect', function (e) {
31 debug('/antisocial-notifications disconnect %s %s', soc.id, e);
32 });
33 soc.on('error', function (e) {
34 debug('/antisocial-notifications error %s %s', soc.id, e);
35 });
36 });
37
38
39
40 // user notification feed
41 // authenticate with access_token cookie
42 IOAuth(antisocialApp.ioNotifications, {
43 'timeout': 60000,
44 'authenticate': function (socket, data, callback) {
45 debug('notificationsFeedMount authenticate');
46
47 var cookie = require('cookie');
48 var cookieParser = require('cookie-parser');
49
50 if (!socket.handshake.headers.cookie) {
51 return callback(null, false);
52 }
53
54 var cookies = cookie.parse(socket.handshake.headers.cookie);
55 var signedCookies = cookieParser.signedCookies(cookies, config.secureCookiePassword);
56 if (!signedCookies.access_token) {
57 return callback(null, false);
58 }
59
60 var fakeReq = {
61 'cookies': signedCookies
62 };
63
64 authUserMiddleware(fakeReq, null, function () {
65 if (!fakeReq.antisocialUser) {
66 return callback(new VError('not logged in'));
67 }
68
69 data.currentUser = fakeReq.antisocialUser;
70 callback(null, true);
71 });
72 },
73 'postAuthenticate': function (socket, data) {
74 socket.antisocial = {
75 'user': data.currentUser,
76 'key': data.currentUser.username,
77 'setDataHandler': function setDataHandler(handler) {
78 socket.antisocial.dataHandler = handler;
79 }
80 };
81
82 debug('notificationsFeedMount connection established %s', socket.antisocial.key);
83
84 antisocialApp.openNotificationsListeners[socket.antisocial.key] = socket;
85
86 antisocialApp.emit('open-notification-connection', {
87 'info': socket.antisocial,
88 'socket': socket
89 });
90
91 socket.on('highwater', function (highwater) {
92 debug('got highwater from %s %s', socket.antisocial.key, highwater);
93 antisocialApp.emit('notification-backfill', {
94 'info': socket.antisocial,
95 'socket': socket,
96 'highwater': highwater
97 });
98 });
99
100 socket.on('data', function (data) {
101 debug('got data from %s', socket.antisocial.key);
102 if (socket.antisocial.dataHandler) {
103 socket.antisocial.dataHandler(data);
104 }
105 else {
106 debug('no data handler for %s', socket.antisocial.key);
107 }
108 });
109
110 socket.on('disconnect', function (reason) {
111 debug('got disconnect %s %s', socket.antisocial.key, reason);
112 antisocialApp.emit('close-notification-connection', {
113 'info': socket.antisocial,
114 'reason': reason
115 });
116 db.updateInstance('users', socket.antisocial.user.id, {
117 'online': false
118 });
119 delete antisocialApp.openNotificationsListeners[socket.antisocial.key];
120 });
121
122 db.updateInstance('users', socket.antisocial.user.id, {
123 'online': true
124 });
125 }
126 });
127};