1 | var url = require('url');
|
2 | var clc = require('cli-color');
|
3 |
|
4 | var clcError = clc.red;
|
5 | var clcWarn = clc.yellow;
|
6 | var apiDirectory = undefined;
|
7 | var os = require('os');
|
8 |
|
9 | exports.sockets = function SocketController(app, io, sessionStore, mongoose, apiLocation) {
|
10 | apiDirectory = apiLocation;
|
11 |
|
12 | io.sockets.on('connection', function(socket) {
|
13 | apiSocket(socket, sessionStore);
|
14 | });
|
15 |
|
16 | app.all(/^\/api/, function(req, res) {
|
17 | httpCall(req, res);
|
18 | });
|
19 | };
|
20 |
|
21 | function addSocketsToRoom(session, socket) {
|
22 | socket.join('onlineUsers');
|
23 | if (!session || !socket || !serverConfig.api.addSocketsToRoom) {
|
24 | return;
|
25 | }
|
26 | serverConfig.api.addSocketsToRoom(session, socket);
|
27 | }
|
28 |
|
29 | function apiSocket(socket, sessionStore) {
|
30 |
|
31 | socket.on('disconnect', function() {
|
32 | if (io.clients) {
|
33 | io.clients.removeSocket(socket.id);
|
34 | }
|
35 | });
|
36 |
|
37 | socket.on('api', function(fileName, method, data, fn) {
|
38 | var extras = {
|
39 | mongoose: mongoose,
|
40 | io: io,
|
41 | socket: socket,
|
42 | connectionType: 'socket',
|
43 | hostname: os.hostname()
|
44 | };
|
45 | extras = getIPAddress(extras);
|
46 | extras.fileName = fileName;
|
47 |
|
48 | if (fileName && fileName.path) {
|
49 | fileName = fileName.path;
|
50 | }
|
51 | if (method && method.method) {
|
52 | method = method.method;
|
53 | }
|
54 | var sessionID = socket.request.sessionID;
|
55 | if (!sessionID) {
|
56 | return;
|
57 | }
|
58 | var fn = arguments[arguments.length - 1];
|
59 | if (typeof fn != 'function') {
|
60 | fn = function() {};
|
61 | }
|
62 | sessionStore.load(sessionID, function(storeErr, session) {
|
63 | if (storeErr) {
|
64 | return fn('error getting a session');
|
65 | }
|
66 | addSocketsToRoom(session, socket);
|
67 | socket.join(sessionID);
|
68 |
|
69 |
|
70 | if (session) {
|
71 | session.sessionID = sessionID;
|
72 | session.save();
|
73 | }
|
74 |
|
75 | if (typeof fileName == 'object') {
|
76 |
|
77 | var apiVersion = '';
|
78 | if (!serverConfig.preventApiVersioning) {
|
79 | var apiVersion = typeof method == 'string' ? method : 'v1/';
|
80 | }
|
81 | var array = fileName;
|
82 | var count = 0;
|
83 | var last = array.length;
|
84 | var sendArray = [];
|
85 | for (var i in array) {
|
86 | getApi(array, i);
|
87 | }
|
88 |
|
89 | function getApi(array, i) {
|
90 | try {
|
91 | var file = array[i].location;
|
92 | var method = array[i].method;
|
93 | var data = array[i].data;
|
94 | API[apiVersion + file][method](data, function(err, data) {
|
95 | var dataToSend = data;
|
96 | if (err) {
|
97 | dataToSend = {
|
98 | err: err
|
99 | };
|
100 | }
|
101 | sendToClient(dataToSend, i);
|
102 | }, session, extras);
|
103 | } catch (err) {
|
104 | if (err && err.stack && err.stack.indexOf && err.stack.indexOf('Error: Cannot find module') != -1) {
|
105 | console.log(clcWarn('cannot find API::', array[i].location, array[i].method, array[i].data));
|
106 | console.log(clcError(err));
|
107 | return sendToClient({
|
108 | err: "Cannot find API '" + array[i].method + "' in '" + array[i].location + ".js.'"
|
109 | }, i);
|
110 | }
|
111 | console.log('Error with API call::');
|
112 | console.log(err.stack);
|
113 | sendToClient({
|
114 | err: fileName
|
115 | }, i);
|
116 | }
|
117 | }
|
118 |
|
119 | function sendToClient(data, i) {
|
120 | count++;
|
121 | sendArray[i] = data;
|
122 | if (count === last) {
|
123 | fn(sendArray, null);
|
124 | }
|
125 | }
|
126 | } else {
|
127 | try {
|
128 | API[fileName][method](data, function(err, data) {
|
129 |
|
130 | if (err) {
|
131 | if (!data) {
|
132 | data = {}
|
133 | }
|
134 | data.err = err;
|
135 | }
|
136 | if (typeof data == 'object') {
|
137 | data = JSON.parse(JSON.stringify(data));
|
138 | }
|
139 | fn(data, err);
|
140 | }, session, extras);
|
141 | } catch (err) {
|
142 | if (err && err.stack && err.stack.indexOf && err.stack.indexOf('Error: Cannot find module' != -1)) {
|
143 | console.log(clcWarn('cannot find API::', fileName, method, data));
|
144 | console.log(clcError(err));
|
145 | return fn(null, {
|
146 | err: "Cannot find API '" + method + "' in '" + fileName + ".js.'"
|
147 | });
|
148 | }
|
149 | console.log('Error with API call::');
|
150 | console.log(err.stack)
|
151 | fn(null, {
|
152 | err: [fileName, method, data]
|
153 | });
|
154 | }
|
155 | }
|
156 | });
|
157 | });
|
158 | }
|
159 |
|
160 | function httpCall(req, res, extras) {
|
161 | req.session.sessionID = req.sessionID;
|
162 | var method = req.method;
|
163 | var extras = {
|
164 | mongoose: mongoose,
|
165 | io: io,
|
166 | req: req,
|
167 | res: res,
|
168 | connectionType: 'http',
|
169 | method: method,
|
170 | hostname: os.hostname()
|
171 | };
|
172 | extras = getIPAddress(extras);
|
173 | var fileName;
|
174 | var requestData = data = (method == 'GET' || method == 'DELETE') ? req.query : req.body;
|
175 | try {
|
176 | var urlDic = url.parse(req.url).pathname.replace(/^\//, '');
|
177 | urlDic = urlDic.split('/');
|
178 | var fileName = '';
|
179 | for (var i = 1; i < urlDic.length - 1; i++) {
|
180 | fileName += '/' + urlDic[i];
|
181 | }
|
182 | fileName = fileName.slice(1, fileName.length);
|
183 | var api = projRequire(apiDirectory + fileName + '.js');
|
184 | var apiMethod = urlDic[urlDic.length - 1];
|
185 | API[fileName][apiMethod](requestData, function(err, doc) {
|
186 | if (err) {
|
187 | res.send({
|
188 | 'err': err
|
189 | });
|
190 | } else {
|
191 | res.send(doc);
|
192 | }
|
193 | }, req.session, extras);
|
194 | } catch (err) {
|
195 | if (err && err.stack && err.stack.indexOf && err.stack.indexOf('Error: Cannot find module' != -1)) {
|
196 | console.log(clcWarn('cannot find API::', fileName, method, data));
|
197 | console.log(clcError(err));
|
198 | return res.status(404).send("Cannot find API '" + method + "' in '" + fileName + ".js.'");
|
199 | }
|
200 | console.log('Error with API call::');
|
201 | console.log(err.stack)
|
202 | res.status(404).send('Not a proper api call');
|
203 | }
|
204 | }
|
205 |
|
206 | function getIPAddress(extras) {
|
207 | var ipAddress = 'unknown';
|
208 | if (extras.socket) {
|
209 | ipAddress = extras.socket.request.connection.remoteAddress;
|
210 | if (extras.socket.handshake.headers['x-forwarded-for']) {
|
211 | ipAddress = extras.socket.handshake.headers['x-forwarded-for'];
|
212 | }
|
213 | } else if (extras.req) {
|
214 | ipAddress = extras.req.connection.remoteAddress;
|
215 | if (extras.req.headers['x-forwarded-for']) {
|
216 | ipAddress = extras.req.headers['x-forwarded-for'];
|
217 | }
|
218 | }
|
219 | extras.ipAddress = ipAddress;
|
220 | return extras;
|
221 | }
|