· 6 years ago · Apr 26, 2019, 11:38 AM
1(
2 function() {
3
4 var layer = 'framework';
5 var component = 'routes';
6 var console = {
7 log: function() {
8 require('./framework/fwk').fwk.log(layer, component, arguments);
9 },
10 warn: function() {
11 require('./framework/fwk').fwk.warn(layer, component, arguments);
12 },
13 error: function() {
14 require('./framework/fwk').fwk.error(layer, component, arguments);
15 }
16 }
17
18 var clientDirectory = '/client';
19
20 function establishRoutes(io, app) {
21 var isProdMode = process.env.NODE_ENV === 'production';
22 var staticFileOptions = {};
23 var fwk = require('./framework/fwk').fwk;
24 var cfg = fwk.config;
25 if (isProdMode) {
26 clientDirectory = '/client-release';
27 console.log('Is in Prod Mode');
28 // set a 5 hour expiration
29 staticFileOptions.maxAge = 5 * 60 * 60 * 1000;
30 }
31
32 app.use('/login/kmb', function(req, res, next) {
33
34 require('./framework/security/validate_ip_address').validateIPAddress(req, res, next, { apiName: "kmb", apiMethod: "post", moduleName: "login" }, (data) => {
35 if (data && data.is_valid) {
36 next();
37 } else {
38 res.status(data.status_code);
39 delete data['is_valid'];
40 delete data['status_code'];
41 var data_to_response = {
42 code: 0,
43 data: data
44 };
45 res.json(data_to_response);
46 res.end();
47 }
48 });
49 });
50
51 //Created by Raj for ADFS integration.
52 //ADFS block start
53 //This block picks up all the auth configs from auth config directory
54 //It initializes passport instance for each config found with the config name
55 if (cfg && cfg.saml_auth_configs && cfg.saml_auth_configs.config_path) {
56 try {
57 var configPath = cfg.saml_auth_configs.config_path;
58 var files = require('fs').readdirSync(configPath);
59 files.forEach((file) => {
60 var fileNameWithoutExtn = file.substring(0, (file.length - ".js".length));
61 var config = require(configPath + fileNameWithoutExtn);
62 config.config_name = fileNameWithoutExtn;
63 require('./auth_saml').configureSaml(app, config);
64 });
65 } catch (err) {
66 console.error('Error initializing ad. Error - ' + err.toString());
67 }
68 }
69
70 //This block handles the callback from the the saml passport instance
71 app.use('/login/:accountName', function(req, res, next) {
72 handleSamlAuthentication(req.params.accountName, req, res, next)
73 });
74 //This block handles the adfs calls
75 function handleSamlAuthentication(accountName, req, res, next) {
76
77 try {
78 var path = '/login/' + accountName;
79 console.warn('Attempting to authenticate account name - ' + accountName);
80
81 app.get(path, (r, s, n) => {
82 console.log("req called", r.path);
83 n();
84 }, require('passport').authenticate(accountName));
85
86 app.post(path, require('passport').authenticate(accountName), function(req, res, next) {
87 res.redirect(cfg.dashboard_base_url);
88 });
89
90 } catch (err) {
91 console.error(err);
92 }
93
94
95 }
96 //ADFS block end
97
98 //for deeplink added by sohel 3 april 2019 -reference id -5254190402LP
99 //fallback: optional-If available, will prefer this fallback address over the one from the options.
100 //android_package_name:optional-Incase you want to support Android deep links, pass your app 's package name.
101 //ios_store_link: optional-Incase you want to support ios deep links, pass your app 's itunes url
102 var deeplink = require('node-deeplink');
103 var fallback_url = fwk.config.dashboard_base_url;
104 var android_link = fwk.config.lw_pulse_app.android_link;
105 var ios_link = fwk.config.lw_pulse_app.ios_link;
106
107 app.get(
108 '/lw_issue_link',
109 function(req, res, next) {
110 // you can do stuff here like add analytics to the request
111 // when you're done, simply pass on to deeplink:
112 var options = {
113 fallback: '{{fallback}}',
114 url: '{{url}}',
115 ios_store_link: '{{ios_store_link}}',
116 android_package_name: '{{android_package_name}}'
117 }
118 deepLink(options);
119 next();;
120 },
121
122 deeplink({
123 fallback: fallback_url,
124 android_package_name: android_link,
125 ios_store_link: ios_link
126 })
127 );
128
129 function deepLink(options) {
130 console.log("deeplink", options)
131 var fallback = options.fallback || '';
132 var url = options.url || '';
133 var iosStoreLink = options.ios_store_link;
134 var androidPackageName = options.android_package_name;
135 var playStoreLink =
136 'https://market.android.com/details?id=' + androidPackageName;
137 var ua = window.navigator.userAgent;
138
139 // split the first :// from the url string
140 var split = url.split(/:\/\/(.+)/);
141 var scheme = split[0];
142 var path = split[1] || '';
143
144 var urls = {
145 deepLink: url,
146 iosStoreLink: iosStoreLink,
147 android_intent: 'intent://' +
148 path +
149 '#Intent;scheme=' +
150 scheme +
151 ';package=' +
152 androidPackageName +
153 ';end;',
154 playStoreLink: playStoreLink,
155 fallback: fallback
156 };
157
158 var isMobile = {
159 android: function() {
160 return /Android/i.test(ua);
161 },
162 ios: function() {
163 return /iPhone|iPad|iPod/i.test(ua);
164 }
165 };
166
167 // fallback to the application store on mobile devices
168 if (isMobile.ios() && urls.deepLink && urls.iosStoreLink) {
169 iosLaunch();
170 } else if (isMobile.android() && androidPackageName) {
171 androidLaunch();
172 } else {
173 window.location = urls.fallback;
174 }
175
176 function launchWekitApproach(url, fallback) {
177 document.location = url;
178 setTimeout(function() {
179 document.location = fallback;
180 }, 250);
181 }
182
183 function launchIframeApproach(url, fallback) {
184 var iframe = document.createElement('iframe');
185 iframe.style.border = 'none';
186 iframe.style.width = '1px';
187 iframe.style.height = '1px';
188 iframe.onload = function() {
189 document.location = url;
190 };
191 iframe.src = url;
192
193 window.onload = function() {
194 document.body.appendChild(iframe);
195
196 setTimeout(function() {
197 window.location = fallback;
198 }, 25);
199 };
200 }
201
202 function iosLaunch() {
203 // chrome and safari on ios >= 9 don't allow the iframe approach
204 if (
205 ua.match(/CriOS/) ||
206 (ua.match(/Safari/) && ua.match(/Version\/(9|10|11|12)/))
207 ) {
208 launchWekitApproach(urls.deepLink, urls.iosStoreLink || urls.fallback);
209 } else {
210 launchIframeApproach(urls.deepLink, urls.iosStoreLink || urls.fallback);
211 }
212 }
213
214 function androidLaunch() {
215 if (ua.match(/Chrome/)) {
216 document.location = urls.android_intent;
217 } else if (ua.match(/Firefox/)) {
218 launchWekitApproach(urls.deepLink, urls.playStoreLink || urls.fallback);
219 } else {
220 launchIframeApproach(url, urls.playStoreLink || urls.fallback);
221 }
222 }
223 }
224
225 ///end
226
227
228 app.get('/version', function(req, res) {
229 console.log("Getting Version ");
230 var packageJson = require('./package.json');
231 // we need to see how to allow PUT and DELETE only on certain entities.
232 if (req.headers['origin']) {
233 res.append('Access-Control-Allow-Methods', 'GET');
234 res.append('Access-Control-Allow-Headers', 'Content-Type');
235 }
236 res.status(200).send(packageJson.version);
237 });
238
239 app.get('/es_configs', function(req, res) {
240 var fwk = require('./framework/fwk').fwk;
241 if (fwk.hasProperty(fwk.config, 'elasticsearch.apis')) {
242 res.send({ code: 0, config: fwk.config.elasticsearch.apis, use_es: fwk.config.elasticsearch.use_es });
243 } else {
244 res.send({ code: 1, error_message: "elasticsearch config not found" });
245 }
246 });
247
248 // Based on the user agent set if it is a mobile device or not.
249 app.use(function(req, res, next) {
250 if (req.headers['user-agent']) {
251 var matches = req.headers['user-agent'].match(/Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/);
252 req.is_mobile_device = !!(matches);
253 req.is_uc_browser = !!req.headers['user-agent'].match(/UCBrowser/);
254 next();
255 } else {
256 next();
257 }
258 });
259
260 // for the new rating
261 // app.locals.pretty = true;
262 app.set('view engine', 'pug');
263 if (isProdMode) {
264 app.set('views', __dirname + '/views-release');
265 } else {
266 app.set('views', __dirname + '/views');
267 }
268
269
270 // Rendering Engine - Files - Start
271 // Placed this on the top so that these are responded to as quickly as possible
272 var PathModule = require('path');
273 var tmp;
274
275 require('./rendering_engine').establishRoutes(app, fwk);
276 require('./rendering_engine_360').establishRoutes(app, fwk);
277
278 // Use the Components JS from the app-rendering-engine directory of web-private
279 tmp = PathModule.join(__dirname, clientDirectory, 'app-rendering-engine', 'js');
280 app.use('/v2-client/js', require('express').static(tmp, staticFileOptions));
281
282 // Use the Components JS from the app-rendering-engine directory of web-private
283 tmp = PathModule.join(__dirname, clientDirectory, 'app-rendering-engine', 'css');
284 app.use('/v2-client/css', require('express').static(tmp, staticFileOptions));
285
286
287
288 // Rendering Engine - Files - End
289
290
291
292 app.get('/r/:feedbackTokenId', require('./view-controllers/rating_handler').execute);
293 // added for axis
294 // Axis TCC - Leg 1 - Mobile version
295 app.get('/a/:feedbackTokenId', require('./view-controllers/rating_handler_axis').execute);
296 app.get('/b/:feedbackTokenId', require('./view-controllers/rating_handler_axis_burgundy').execute);
297 app.get('/t/:feedbackTokenId', require('./view-controllers/test_rating_handler').execute);
298 app.get('/web/:feedbackTokenId', require('./view-controllers/view_in_web_handler').execute);
299 app.get('/c/:feedbackTokenId', require('./view-controllers/shukran/rating_handler_shukran').execute);
300 app.get('/d/:feedbackTokenId', require('./view-controllers/eureka-sales/rating_handler_eureka_sales').execute);
301 app.get('/e/:feedbackTokenId', require('./view-controllers/sanofi/sanofi_rating_handler').execute);
302 app.get('/g/:feedbackTokenId', require('./view-controllers/sanofi-conference/sanofi_conference_rating_handler').execute);
303 app.get('/i/:feedbackTokenId', require('./view-controllers/sanofi-conference-survey/sanofi_conference_survey_rating_handler').execute);
304 app.get('/j/:feedbackTokenId', require('./view-controllers/sanofi-pre-conference/sanofi_pre_conference_rating_handler').execute);
305 app.get('/k/:feedbackTokenId', require('./view-controllers/sanofi-post-conference/sanofi_post_conference_rating_handler').execute);
306 app.get('/l/:feedbackTokenId', require('./view-controllers/eureka-conference/eureka_conference_rating_handler').execute);
307 app.get('/m/:feedbackTokenId', require('./view-controllers/icici/icici_imboile_rating_handler_single_page').execute);
308 app.get('/n/:feedbackTokenId', require('./view-controllers/shukran/rating_handler_shukran_new').execute);
309 app.get('/p/:feedbackTokenId', require('./view-controllers/eureka/rating_handler_eureka_uc').execute);
310 app.get('/q/:feedbackTokenId', require('./view-controllers/icici/icici_atm_rating_handler_single_page').execute);
311 app.get('/axis-tcc2/:feedbackTokenId', function(req, res, next) {
312 if (req.is_mobile_device) {
313 require('./view-controllers/axis_tcc/rating_handler_axis_tcc').execute(req, res, next);
314 } else {
315 require('./view-controllers/axis-tcc2-desktop/rating_handler_axis_tcc2_desktop').execute(req, res, next);
316 }
317 });
318
319
320 app.get('/axis-tcc1/:feedbackTokenId', function(req, res, next) {
321 if (req.is_mobile_device) {
322 require('./view-controllers/rating_handler_axis').execute(req, res, next);
323 } else {
324 require('./view-controllers/axis-tcc1-desktop/rating_handler_axis_tcc1_desktop').execute(req, res, next);
325 }
326 });
327
328 app.get('/f/:feedbackTokenId', function(req, res, next) {
329 if (req.is_mobile_device) {
330 if (req.is_uc_browser) {
331 var tmp = req.headers['x-absolute-url'];
332 tmp = tmp.substring(0, tmp.indexOf("/f/")) + "/m/" + tmp.substring(tmp.indexOf("/f/") + "/f/".length)
333 res.redirect(tmp);
334 } else {
335 require('./view-controllers/icici/icici_rating_handler_mobile').execute(req, res, next);
336 }
337
338
339 } else {
340 require('./view-controllers/icici/rating_handler_icici_desktop').execute(req, res, next);
341 }
342 });
343
344 app.get('/h/:feedbackTokenId', function(req, res, next) {
345 if (req.is_mobile_device) {
346 var UAParser = require('ua-parser-js');
347 var parser = new UAParser();
348 var ua = req.headers['user-agent']; // user-agent header from an HTTP request
349 var result = parser.setUA(ua).getResult();
350 var browserName = result.browser.name;
351
352 var plainBrowser = true;
353
354 if (browserName.indexOf("Chrome") > -1 || browserName.indexOf("Safari") > -1) {
355 plainBrowser = false;
356 }
357 if (plainBrowser) {
358 var tmp = req.headers['x-absolute-url'];
359 tmp = tmp.substring(0, tmp.indexOf("/h/")) + "/q/" + tmp.substring(tmp.indexOf("/h/") + "/h/".length)
360 res.redirect(tmp);
361 } else {
362 require('./view-controllers/icici/icici_atm_rating_handler_mobile').execute(req, res, next);
363 }
364
365 } else {
366 require('./view-controllers/icici/rating_handler_icici_atm_survey_desktop').execute(req, res, next);
367 }
368 });
369
370 app.get('/axis-tcc3/:feedbackTokenId', function(req, res, next) {
371 if (req.is_mobile_device) {
372 require('./view-controllers/axis-reload/rating_handler_axis_reload_mobile').execute(req, res, next);
373 } else {
374 require('./view-controllers/axis-reload-desktop/rating_handler_axis_reload_desktop').execute(req, res, next);
375 }
376 });
377 app.get('/o/:feedbackTokenId', function(req, res, next) {
378 if (req.is_mobile_device) {
379 if (req.is_uc_browser) {
380 var tmp = req.headers['x-absolute-url'];
381 tmp = tmp.substring(0, tmp.indexOf("/o/")) + "/p/" + tmp.substring(tmp.indexOf("/o/") + "/o/".length)
382 res.redirect(tmp);
383 } else {
384 require('./view-controllers/eureka/rating_handler_eureka').execute(req, res, next);
385 }
386 } else {
387 require('./view-controllers/eureka/rating_handler_eureka').execute(req, res, next);
388 }
389 });
390
391 app.get('/litmus/:feedbackTokenId', require('./view-controllers/litmus/rating_handler_litmus').execute);
392 app.get('/dominos/:feedbackTokenId', require('./view-controllers/dominos/rating_handler_dominos').execute);
393 //socket io listen on /publish/:shopId
394 //require('./socket_io').handleSocketIo(io, app);
395
396 // commented because moved code into litmus.js
397 /*app.get('/publish/:shopId', function(req, res, next) {
398 require('./socket_io').handleSocketIo(req.params.shopId, io, app);
399 });*/
400 app.get('/url-config.js', function(req, res) {
401 var contents = 'var baseUrl="' + require('./framework/fwk').fwk.config.base_url + '";';
402 contents += 'var gaOfferCode="' + require('./framework/fwk').fwk.config.offers.ga_code + '";';
403 // contents += 'var requestPublicKey = "' + require('./helpers').helpers.Encryptor.RequestPublicKey + '";';
404 res.set('Content-Type', 'text/javascript; charset=UTF-8');
405 disableCacheOnResponse(req, res);
406 res.status(200).send(new Buffer(contents));
407 });
408
409 app.get('/pb-key', function(req, res) {
410 var key = require('./helpers').helpers.Encryptor.RequestPublicKey;
411 disableCacheOnResponse(req, res);
412 res.set('Content-Type', 'text/plain');
413 res.status(200).send(new Buffer(key));
414 });
415
416 app.get('/pv-key', function(req, res) {
417 var key = require('./helpers').helpers.Encryptor.ResponsePrivateKey;
418 disableCacheOnResponse(req, res);
419 res.set('Content-Type', 'text/plain');
420 res.status(200).send(new Buffer(key));
421 });
422 app.get('/pv-phrase', function(req, res) {
423 var key = require('./helpers').helpers.Encryptor.ResponsePrivateKeyPhrase;
424 disableCacheOnResponse(req, res);
425 res.set('Content-Type', 'text/plain');
426 res.status(200).send(new Buffer(key));
427 });
428
429 // mapping for litmus rating app
430 mapStaticFile('index.html', app);
431 mapStaticFile('feedback-detail.html', app);
432 mapStaticFile('publish-feed-details.html', app);
433 mapStaticFile('invites-offers.html', app);
434 mapStaticFile('offers.html', app);
435 mapStaticFile('ifb-offers.html', app);
436 mapStaticFile('axis-dd.html', app);
437 mapStaticFile('axis-speed-banking.html', app);
438 mapStaticFile('axis-branch-banking.html', app);
439 mapStaticFile('demo-shop.html', app);
440 mapStaticFile('unauthorized.html', app);
441 mapStaticFile('unsubscribe.html', app);
442 mapStaticFile('detailed-offer.html', app);
443 mapStaticFile('axis-kiosk.html', app);
444 mapStaticFile('axis-internet-banking.html', app);
445 mapStaticFile('axis-internet-banking-component.html', app);
446 mapStaticFile('offer.html', app);
447 mapStaticFile('tms-offer.html', app);
448 mapStaticFile('offer-details.html', app);
449 mapStaticFile('tms-tnc.html', app);
450 mapStaticFile('tms-prebook-offer.html', app);
451 mapStaticFile('tms-single-offer.html', app);
452 mapStaticFile('tms-prebook-iphone.html', app);
453 mapStaticFile('error_pmo.html', app);
454 // added error page for advanced downloader link expiry
455 mapStaticFile('advanced-downloader-link-expiry.html', app);
456 // added error page
457 mapStaticFile('error.html', app);
458 mapStaticFile('success.html', app);
459 app.use('/nmo/', require('express').static(__dirname + clientDirectory + '/app/nmo', staticFileOptions));
460 app.use('/css/', require('express').static(__dirname + clientDirectory + '/app/css', staticFileOptions));
461 app.use('/feedback-img/', require('express').static(__dirname + clientDirectory + '/app/feedback-img', staticFileOptions));
462 app.use('/img/', require('express').static(__dirname + clientDirectory + '/app/img', staticFileOptions));
463 app.use('/js/', require('express').static(__dirname + clientDirectory + '/app/js', staticFileOptions));
464 app.use('/partials/', require('express').static(__dirname + clientDirectory + '/app/partials', staticFileOptions));
465 app.use('/sounds/', require('express').static(__dirname + clientDirectory + '/app/sounds', staticFileOptions));
466 app.use('/uploads/', require('express').static(__dirname + '/uploads', staticFileOptions));
467 app.use('/fonts/', require('express').static(__dirname + clientDirectory + '/app/fonts', staticFileOptions));
468 app.use('/pwa/', require('express').static(__dirname + clientDirectory + '/app/pwa', staticFileOptions));
469 // end mapping for litmus rating app
470 // mapping for API Documentation - Start
471 app.use('/api-docs/', require('express').static(__dirname + clientDirectory + '/api-docs', staticFileOptions));
472
473 const csurf = require('csurf');
474 // app.use('/api', csurf());
475
476
477
478 /*
479 Check for allowed IP address for the Brand.
480 Check will be at API level (Array of API).
481 */
482 // COmmented by Sachin - Unused
483 // app.use('/api/:apiName/:id', function(req, res, next) {
484 // handleApiCall(req.method, req.params.apiName, req, res, next);
485 // });
486 var multer = require('multer');
487 var multer_s3 = require("multer-s3");
488
489 var upload = null;
490 var upload_files = null;
491 var upload_in_server = null;
492 var upload_file_via_tmp_folder = null;
493 var upload_email_template_via_tmp_folder = null;
494 var upload_template = null;
495
496
497 var template_storage = multer.diskStorage({
498 destination: function(req, file, cb) {
499 cb(null, require('./framework/fwk').fwk.getTemporaryFolder());
500 }
501 });
502
503 upload_template = multer({ 'storage': template_storage });
504
505 app.post('/api/notification_configuration/template', upload_template.single('file'), function(req, res, next) {
506 handleApiCallWithModule(req.method, 'notification_configuration', 'template', req, res, next);
507 });
508
509
510 //store uploaded files on server
511 var local_file_storage = multer.diskStorage({
512 destination: function(req, file, cb) {
513 cb(null, './uploads/temp')
514 },
515 filename: function(req, file, cb) {
516 var newFileName = require('./framework/fwk').fwk.uuid.v4();
517 switch (file.mimetype.toString().toLowerCase()) {
518 case 'text/javascript':
519 newFileName += ".js"
520 break;
521 case 'text/css':
522 newFileName += ".css"
523 break;
524 }
525 cb(null, newFileName);
526 }
527 });
528 upload_in_server = multer({
529 storage: local_file_storage
530 });
531
532 //store files in temp folder
533 var tmp_folder_storage = multer.diskStorage({
534 destination: function(req, file, cb) {
535 cb(null, require('./framework/fwk').fwk.getTemporaryFolder());
536 },
537 filename: function(req, file, cb) {
538 var splitted_file = file.originalname.split(".");
539 var new_file_name = splitted_file[0] + "_" + new Date().getTime();
540 if (splitted_file.length > 1 && splitted_file[1]) {
541 new_file_name += "." + splitted_file[1];
542 }
543 cb(null, new_file_name);
544 }
545 });
546 upload_file_via_tmp_folder = multer({
547 storage: tmp_folder_storage
548 });
549
550 switch (cfg.file_storage_type.toLowerCase()) {
551 case 'localstorage':
552 //store uploaded files on server if localstorage was configured on config file
553 var local_storage = multer.diskStorage({
554 destination: function(req, file, cb) {
555 cb(null, './uploads')
556 },
557 filename: function(req, file, cb) {
558 var newFileName = require('./framework/fwk').fwk.uuid.v4();
559 switch (file.mimetype.toString().toLowerCase()) {
560 case 'image/jpeg':
561 newFileName += ".jpeg"
562 break;
563 case 'image/jpg':
564 newFileName += ".jpg"
565 break;
566 case 'image/png':
567 newFileName += ".png"
568 break;
569 case 'image/gif':
570 newFileName += ".gif"
571 break;
572 case 'text/csv':
573 newFileName += ".csv"
574 break;
575 case 'text/html':
576 newFileName += ".html"
577 break;
578 }
579 cb(null, newFileName);
580 }
581 });
582 upload = multer({
583 storage: local_storage
584 })
585 upload_files = multer({
586 storage: local_storage
587 });
588 console.log("====== Server storage is selected. ========");
589 break;
590
591 case 'awss3':
592
593 default:
594 //here we are directly upload the images on AWS S3 server
595 upload = multer({
596 storage: multer_s3({
597 dirname: 'offer-photos',
598 bucket: cfg.awsS3.bucketName,
599 secretAccessKey: cfg.awsS3.secretAccessKey,
600 accessKeyId: cfg.awsS3.accessKeyId,
601 region: 'us-east-1',
602 filename: function(rqst, file, cb) {
603 var newFileName = require('./framework/fwk').fwk.uuid.v4();
604 switch (file.mimetype.toString().toLowerCase()) {
605 case 'image/jpeg':
606 newFileName += ".jpeg"
607 break;
608 case 'image/jpg':
609 newFileName += ".jpg"
610 break;
611 case 'image/png':
612 newFileName += ".png"
613 break;
614 case 'image/gif':
615 newFileName += ".gif"
616 break;
617 case 'text/csv':
618 newFileName += ".csv"
619 break;
620 case 'text/html':
621 newFileName += ".html"
622 break;
623 }
624 cb(null, newFileName);
625 }
626 })
627 })
628 upload_files = multer({
629 storage: multer_s3({
630 dirname: cfg.awsS3.groups.directoryName,
631 bucket: cfg.awsS3.groups.bucketName,
632 secretAccessKey: cfg.awsS3.groups.secretAccessKey,
633 accessKeyId: cfg.awsS3.groups.accessKeyId,
634 region: cfg.awsS3.groups.region,
635 filename: function(rqst, file, cb) {
636 var newFileName = require('./framework/fwk').fwk.uuid.v4();
637 var group_hierarchy_type = (rqst.body.hierarchy_type) ? rqst.body.hierarchy_type.toString().trim().toLowerCase() : "default";
638 if (rqst.body.file_type == "groups" && rqst.body.brand_id && rqst.body.brand_name) {
639 newFileName = rqst.body.brand_name.toString().toLowerCase() + "++" + rqst.body.brand_id.toString() + "++" + group_hierarchy_type + "++" + new Date().getTime();
640 }
641 switch (file.mimetype.toString().toLowerCase()) {
642 case 'image/jpeg':
643 newFileName += ".jpeg"
644 break;
645 case 'image/jpg':
646 newFileName += ".jpg"
647 break;
648 case 'image/png':
649 newFileName += ".png"
650 break;
651 case 'image/gif':
652 newFileName += ".gif"
653 break;
654 case 'text/csv':
655 newFileName += ".csv"
656 break;
657 case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
658 newFileName += ".xlsx"
659 break;
660 case 'application/vnd.ms-excel':
661 newFileName += ".xls"
662 break;
663 case 'text/html':
664 newFileName += ".html"
665 break;
666 }
667
668 cb(null, newFileName);
669 }
670 })
671 })
672 console.log("====== Aws s3 storage is selected. ========");
673 }
674
675
676
677
678
679 //upload feedback csv file
680 app.post('/api/upload_csv_file', upload.single('feedback_csv_file'), function(req, res, next) {
681 // this will provide the APIs to call services.
682 handleApiCall(req.method, 'upload_csv_file', req, res, next);
683 });
684 //upload offer photos
685 app.post('/api/upload_offer_photo', upload.single('offer_photo'), function(req, res, next) {
686 // this will provide the APIs to call services.
687 handleApiCall(req.method, 'upload_offer_photo', req, res, next);
688 });
689 //upload feedback photos
690 app.post('/api/upload_feedback_photo', upload.single('feedback_photo'), function(req, res, next) {
691 // this will provide the APIs to call services.
692 handleApiCall(req.method, 'upload_feedback_photo', req, res, next);
693 });
694 app.post('/api/upload_brand_images', upload_file_via_tmp_folder.single('brand_images'), function(req, res, next) {
695 handleApiCall(req.method, 'upload_brand_images', req, res, next);
696 });
697 app.post('/api/uploaders/upload_files', upload_files.single('file_name'), function(req, res, next) {
698 handleApiCallWithModule(req.method, 'uploaders', 'upload_files', req, res, next);
699 });
700
701 /*
702 check for incoming request file if malicious or not.
703 */
704 app.post('/api/infra/upload', upload_file_via_tmp_folder.single('file_name'), function(req, res, next) {
705 var fwk = require('./framework/fwk').fwk;
706 /*
707 calling helpers.ClamavScanner.scan_single_file to check if incoming file is malicious.
708 */
709 var job_name = 'file_parser';
710 fwk.helpers.ClamavScanner.scanSingleFile(req, fwk, job_name, function(allowed, response) {
711 if (allowed) {
712 /*
713 The incoming file is not infected calling handleApiCallWithModule() function.
714 */
715 handleApiCallWithModule(req.method, 'infra', 'upload', req, res, next);
716 } else {
717 res.status(200);
718 res.json(response);
719 res.end();
720 }
721 });
722 });
723
724 // upload the file on local server then upload the files on AWS S3 based on parameters
725 app.post('/api/uploaders/upload', upload_in_server.single('file_name'), function(req, res, next) {
726 handleApiCallWithModule(req.method, 'uploaders', 'upload', req, res, next);
727 });
728
729 app.post('/api/uploaders/multimedia_file_upload', upload_file_via_tmp_folder.single('file'), function(req, res, next) {
730 handleApiCallWithModule(req.method, 'uploaders', 'multimedia_file_upload', req, res, next);
731 });
732
733 app.post('/api/coupons/upload_coupon_code', upload_file_via_tmp_folder.single('file_name'), function(req, res, next) {
734 // this will provide the APIs to call services.
735 handleApiCallWithModule(req.method, 'coupons', 'upload_coupon_code', req, res, next);
736 });
737
738 app.post('/api/managers/managers_list_upload', upload_file_via_tmp_folder.single('file_name'), function(req, res, next) {
739 // this will provide the APIs to call services.
740 handleApiCallWithModule(req.method, 'managers', 'managers_list_upload', req, res, next);
741 });
742
743 // upload the file on local server
744 app.post('/api/configs/upload_interactions', upload_file_via_tmp_folder.single('file_name'), function(req, res, next) {
745 handleApiCallWithModule(req.method, 'configs', 'upload_interactions', req, res, next);
746 });
747
748 app.post('/api/uploaders/hierarchy_file_upload', upload_file_via_tmp_folder.single('file_name'), function(req, res, next) {
749 handleApiCallWithModule(req.method, 'uploaders', 'hierarchy_file_upload', req, res, next);
750 });
751
752
753 app.use(upload.any());
754
755 app.post('/api/external/mailgun_hook', function(req, res, next) {
756 // this will provide the APIs to call services.
757 handleApiCallWithModule(req.method, 'external', 'mailgun_hook', req, res, next);
758 });
759
760 app.use(function(req, res, next) {
761 if (req.cookies[cfg.login_cookie_name]) {
762 req.customer_id = req.cookies[cfg.login_cookie_name];
763 }
764 getBrandIdAndUserId(req, res, fwk, next);
765 });
766
767 app.use(function(req, res, next) {
768 getShopId(req, res, fwk, next);
769 });
770
771 // app.get('/api/me',
772 // function(req, res, next) {
773 // if (req.user == null || typeof req.user == 'undefined') {
774
775 // // try to do a basic authentication
776 // require('passport').authenticate('basic', function(err, user) {
777 // req.user = user;
778 // handleApiCall(req.method, 'me', req, res, next);
779 // })(req, res, next);
780 // } else {
781 // handleApiCall(req.method, 'me', req, res, next);
782 // }
783 // });
784 var csurfed = csurf({
785 ignoreMethods: ["GET", "HEAD", "OPTIONS", "POST", "PUT", "DELETE"]
786 });
787
788 app.get('/api/me', csurfed, function(req, res, next) {
789 /*
790 Commented by Raj
791 */
792 // if (req.user == null || typeof req.user == 'undefined') {
793 // require('passport').authenticate('basic', function(err, user) {
794 // req.user = user;
795 // handleApiCall(req.method, 'me', req, res, next);
796 // })(req, res, next);
797 // } else {
798 // handleApiCall(req.method, 'me', req, res, next);
799 // }
800 if (req && req.user && req.user.user_name) {
801 var api_details = {
802 apiName: "me",
803 apiMethod: "get",
804 moduleName: ""
805 };
806 require('./framework/security/validate_ip_address').validateIPAddress(req, res, next, api_details, (data) => {
807 if (data && data.is_valid) {
808 res.cookie('XSRF-TOKEN', req.csrfToken(), { secure: true });
809 handleApiCall(req.method, 'me', req, res, next);
810 } else {
811 req.logout();
812 res.status(data.status_code);
813 delete data['is_valid'];
814 delete data['status_code'];
815 var data_to_response = {
816 code: 0,
817 data: data
818 };
819 res.json(data_to_response);
820 res.end();
821 }
822 });
823 } else {
824 res.cookie('XSRF-TOKEN', req.csrfToken(), { secure: true });
825 handleApiCall(req.method, 'me', req, res, next);
826 }
827 });
828
829
830 app.use('/api/:moduleName/:apiName', csurfed, (req, res, next) => {
831 res.cookie('XSRF-TOKEN', req.csrfToken(), { secure: true });
832 next();
833 }, function(req, res, next) {
834 console.log('APi Called with Module: ' + req.params.moduleName + '/' + req.params.apiName);
835 var apiModuleObject = {
836 moduleName: req.params.moduleName,
837 apiName: req.params.apiName
838 };
839 //If query has secret key then validate user as admin manager.
840 if (req.query.manager_secret_key) {
841 var fwk = require('./framework/fwk').fwk;
842 fwk.db.Managers.getBySecretKey(req.query.manager_secret_key, fwk, function(user) {
843 req.login(user, function() {
844 checkIPAndProceedWithHandleApiRequestWithModule(apiModuleObject, req, res, next);
845 });
846 });
847
848 } else {
849 console.log("Calling without secret key");
850 checkIPAndProceedWithHandleApiRequestWithModule(apiModuleObject, req, res, next);
851 }
852 });
853
854 //Check IP Address validation.
855 app.use('/api/:apiName', csurfed, (req, res, next) => {
856 res.cookie('XSRF-TOKEN', req.csrfToken(), { secure: true });
857 next();
858 }, function(req, res, next) {
859 //var apiModuleObject = getModuleNameAndApiName(req.params.apiName);
860 var apiModuleObject = require('./handle_api_module').getModuleNameAndApiName(req.params.apiName);
861
862 if (apiModuleObject.moduleName && apiModuleObject.apiName) {
863 //handleApiCallWithModule(req.method, apiModuleObject.moduleName, apiModuleObject.apiName, req, res, next);
864 //If query has secret key then validate user as admin manager.
865 if (req.query.manager_secret_key) {
866 var fwk = require('./framework/fwk').fwk;
867 fwk.db.Managers.getBySecretKey(req.query.manager_secret_key, fwk, function(user) {
868 req.login(user, function() {
869 checkIPAndProceedWithHandleApiRequestWithModule(apiModuleObject, req, res, next);
870 });
871 });
872
873 } else {
874 console.log("Calling without secret key");
875 checkIPAndProceedWithHandleApiRequestWithModule(apiModuleObject, req, res, next);
876 }
877 } else {
878 //If query has secret key then validate user as admin manager.
879 if (req.query.manager_secret_key) {
880 var fwk = require('./framework/fwk').fwk;
881 fwk.db.Managers.getBySecretKey(req.query.manager_secret_key, fwk, function(user) {
882 req.login(user, function() {
883 checkIPAndProceedWithHandleApiRequest(req, res, next);
884 });
885 });
886
887 } else {
888 checkIPAndProceedWithHandleApiRequest(req, res, next);
889 }
890 }
891 });
892
893 function checkIPAndProceedWithHandleApiRequest(req, res, next) {
894 console.log("Calling HANDLE API");
895
896 //Get IP Address of the client requesting.
897 var ipAddress = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress;
898 switch (req.params.apiName) {
899 default:
900 //Removed case for request_feeback_for_shop_id
901 try {
902 require('./framework/security/validate_ip_address').validateIPAddress(req, res, next, { apiName: req.params.apiName, apiMethod: req.method, moduleName: null }, (data) => {
903 if (data && data.is_valid) {
904 // this will provide the APIs to call services.
905 handleApiCall(req.method, req.params.apiName, req, res, next);
906 } else {
907 res.status(data.status_code);
908 delete data['is_valid'];
909 delete data['status_code'];
910 var data_to_response = {
911 code: 0,
912 data: data
913 };
914 res.json(data_to_response);
915 res.end();
916 }
917 });
918 } catch (err) {
919 console.error('IP address validator: An unhandled error occured while calling the api. Error was ', err);
920 res.status(500).end('An unexpected error occurred and was reported to the admin. Please contact support at support@litmusworld.com, if you were not expecting this error.');
921 }
922 }
923 }
924
925 //Tekram Patel: method for checking the IP and proceed with handle ip request with module(duplicate code some minor changes)
926 function checkIPAndProceedWithHandleApiRequestWithModule(apiModuleObject, req, res, next) {
927 console.log("Calling HANDLE API WITH MODULE");
928
929 //Get IP Address of the client requesting.
930 var ipAddress = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress;
931 switch (req.params.apiName) {
932 //Removed case for request_feeback_for_shop_id
933 default:
934 // this will provide the APIs to call services.
935 //handleApiCallWithModule(req.method, apiModuleObject.moduleName, apiModuleObject.apiName, req, res, next);
936 //break;
937 try {
938 require('./framework/security/validate_ip_address').validateIPAddress(req, res, next, { apiName: apiModuleObject.apiName, apiMethod: req.method, moduleName: apiModuleObject.moduleName }, (data) => {
939 if (data && data.is_valid) {
940 // this will provide the APIs to call services.
941 handleApiCallWithModule(req.method, apiModuleObject.moduleName, apiModuleObject.apiName, req, res, next);
942 } else {
943 res.status(data.status_code);
944 delete data['is_valid'];
945 delete data['status_code'];
946 var data_to_response = {
947 code: 0,
948 data: data
949 };
950 res.json(data_to_response);
951 res.end();
952 }
953 });
954 } catch (err) {
955 console.error('IP address validator: An unhandled error occured while calling the api. Error was ', err);
956 res.status(500).end('An unexpected error occurred and was reported to the admin. Please contact support at support@litmusworld.com, if you were not expecting this error.');
957 }
958 break;
959 }
960 }
961
962 function mapStaticFile(filePath) {
963 app.use('/' + filePath, function(req, res) {
964 var options = {
965 root: __dirname + clientDirectory + '/app/',
966 dotfiles: 'deny',
967 headers: {
968 'x-timestamp': Date.now(),
969 'x-sent': true
970 }
971 };
972 console.log('trying to send ' + filePath);
973 res.sendFile(filePath, options, function() {
974 res.end();
975 });
976
977 });
978 }
979
980 mapStaticFile('robots.txt');
981 mapStaticFile('promoters.html');
982 /*app.use('/', function(req, res) {
983 var options = {
984 root: __dirname + clientDirectory+'/app/',
985 dotfiles: 'deny',
986 headers: {
987 'x-timestamp': Date.now(),
988 'x-sent': true
989 }
990 };
991 res.sendFile('index.html', options, function() {
992 res.end();
993 });
994 })*/
995 }
996
997 function handleApiCall(apiMethod, apiName, req, res, next) {
998 //call method to log the called api details with incoming parameters
999 logAPIRequestDetails(apiMethod, null, apiName, req);
1000 var startTime = new Date();
1001 var queryString = req.query;
1002 var params = req.params;
1003 var q = require('q').defer();
1004 q.promise.then(function(result) {
1005 console.warn("[" + getFormatedDate() + "] [INFO] [API] [" + apiName + '_' + apiMethod.toLowerCase() + "] [execute] Litmus API Process Ended.");
1006 res.status = result.status;
1007 if (res.status === 302) {
1008 res.redirect(result.data.redirect_url);
1009 } else if (res.status == 205) {
1010 res.status = 200;
1011 console.log('status for download')
1012 res.append('Content-disposition', 'attachment;filename=' + require('uuid').v4() + '.csv');
1013 var readStream = require('fs').createReadStream(result.data.file_name);
1014 // We replaced all the event handlers with a simple call to readStream.pipe()
1015 disableCacheOnResponse(req, res);
1016 //Deleted the file after download.
1017 readStream.on('end', function() {
1018 require('fs').unlink(result.data.file_name, function() {
1019 // File deleted
1020 });
1021 });
1022 readStream.pipe(res);
1023 } else if (res.status == 206) {
1024 console.log('status for image')
1025 res.status = 200;
1026 try {
1027 res.append('Content-disposition', 'attachment;filename=spacer.gif');
1028 res.set('Content-Type', 'image/gif');
1029 disableCacheOnResponse(req, res);
1030 console.log("Sending image " + result.data.image_url.toString());
1031 var img = require('fs').readFileSync(result.data.image_url.toString());
1032 res.end(img, 'binary');
1033 } catch (err) {
1034 console.log("Error while sending response: " + err.toString());
1035 }
1036 } else if (res.status == 207) {
1037 // Same as 206, but we dont want attachement
1038 res.status = 200;
1039 try {
1040 disableCacheOnResponse(req, res);
1041 res.set('Content-Type', result.data.content_type);;
1042 var img = require('fs').readFileSync(result.data.image_url.toString());
1043 res.end(img, 'binary');
1044 } catch (err) {
1045 console.log("Error while sending response: " + err.toString());
1046 }
1047
1048 } else if (res.status == 404) {
1049 res.status(404).end('Oops! \nThe requested URL /404 was not found on this server.');
1050 } else if (res.status === 200 && result.data.code === 0 && result.data.send_code) {
1051 console.log("about to write")
1052 // this is to handle a subscribe call from Facebook
1053 disableCacheOnResponse(req, res);
1054 res.write(result.data.send_code);
1055 res.end();
1056 } else {
1057 var response = {
1058 code: 0,
1059 data: result.data,
1060 message: result.error_message
1061 };
1062 disableCacheOnResponse(req, res);
1063 res.json(response);
1064 res.end();
1065 var endTime = new Date();
1066 var elapsedTime = (endTime - startTime) / 1000;
1067 //console.log("Time elapsed "+elapsedTime);
1068 console.warn("API Response", apiName, elapsedTime);
1069 var _os = require("os");
1070 var hostname = _os.hostname();
1071
1072 if (!hostname) {
1073 hostname = "no_hostname";
1074 }
1075
1076 var metricData = [{
1077 "module": "api.generic",
1078 "key": apiName + '.' + hostname + ".time_taken",
1079 "metric_type": "count",
1080 "value": elapsedTime
1081 }];
1082 require('./framework/fwk').fwk.feedMetricData(metricData, function() {});
1083
1084 }
1085 }, function(err) {
1086 // error handler if q.promise failed.
1087 console.error('An unhandled error occured while calling the api. Error was ', err);
1088 res.status(500).end('An unexpected error occurred and was reported to the admin. Please contact support at support@litmusworld.com, if you were not expecting this error.');
1089 }.bind(startTime));
1090
1091 console.log('about to call ' + apiName + '_' + apiMethod.toLowerCase());
1092 console.warn("[" + getFormatedDate() + "] [INFO] [API] [" + apiName + '_' + apiMethod.toLowerCase() + "] [execute] Litmus API Process Started.");
1093 switch (apiMethod.toLowerCase()) {
1094 case 'get':
1095 var rqst = {
1096 query: queryString,
1097 params: params,
1098 cookies: req.cookies,
1099 req: req,
1100 res: res
1101 };
1102 try {
1103 console.log("API Calling")
1104 require('./api/' + apiName + '_' + apiMethod.toLowerCase()).execute(rqst, q, require('./framework/fwk').fwk);
1105 } catch (err) {
1106 if (err.code === 'MODULE_NOT_FOUND') {
1107 console.warn(' Api Name: ' + apiName + ', Method Name: ' + apiMethod.toLowerCase() + ', Unhandled Error', err.code);
1108 next();
1109 } else {
1110 q.reject(err);
1111 }
1112 }
1113 break;
1114 case 'options':
1115 // we will have only a single handler for OPTIONS HTTP METHOD
1116 apiName = 'handle';
1117 apiMethod = 'options';
1118 case 'post':
1119 case 'put':
1120 var rqst = {
1121 query: queryString,
1122 params: params,
1123 cookies: req.cookies,
1124 body: req.body,
1125 files: req.files,
1126 req: req,
1127 res: res
1128 };
1129 try {
1130 require('./api/' + apiName + '_' + apiMethod.toLowerCase()).execute(rqst, q, require('./framework/fwk').fwk);
1131 } catch (err) {
1132 if (err.code === 'MODULE_NOT_FOUND') {
1133 console.warn(' Api Name: ' + apiName + ', Method Name: ' + apiMethod.toLowerCase() + ', Unhandled Error', err.code);
1134 next();
1135 }
1136 /*console.error(err.toString());
1137 console.error(err.stack);*/
1138 }
1139 break;
1140 case 'delete':
1141 var rqst = {
1142 query: queryString,
1143 params: params,
1144 cookies: req.cookies,
1145 req: req,
1146 res: res
1147 };
1148 try {
1149 require('./api/' + apiName + '_' + apiMethod.toLowerCase()).execute(rqst, q, require('./framework/fwk').fwk);
1150 } catch (err) {
1151 if (err.code === 'MODULE_NOT_FOUND') {
1152 console.warn(' Api Name: ' + apiName + ', Method Name: ' + apiMethod.toLowerCase() + ', Unhandled Error', err.code);
1153 next();
1154 }
1155 }
1156 break;
1157 default:
1158 apiMethod = '';
1159 break;
1160 }
1161 }
1162
1163 //Tekram Patel: method for handle the api call with module names(duplicate code with some minor changes)
1164 function handleApiCallWithModule(apiMethod, moduleName, apiName, req, res, next) {
1165 //call method to log the called api details with incoming parameters
1166 logAPIRequestDetails(apiMethod, moduleName, apiName, req);
1167 var queryString = req.query;
1168 var params = req.params;
1169 var q = require('q').defer();
1170 var startTime = new Date();
1171 q.promise.then(function(result) {
1172
1173 console.warn("[" + getFormatedDate() + "] [INFO] [API] [" + moduleName + "/" + apiName + '_' + apiMethod.toLowerCase() + "] [execute] Litmus API Process Ended.");
1174 res.status = result.status;
1175
1176 if (res.status === 302) {
1177 res.redirect(result.data.redirect_url);
1178 } else if (res.status == 205) {
1179 console.log('status for download')
1180 res.status = 200;
1181
1182 if ('content_type' in result.data && result.data.content_type == 'text/html') {
1183 //If content_type is available and is type text/html
1184 res.append('Content-disposition', 'attachment;filename=' + require('uuid').v4() + '.html');
1185 } else if ('file_name' in result.data && result.data.file_name) {
1186 //If file name is available on result
1187 res.append('Content-disposition', 'attachment;filename=' + result.data.file_name);
1188 } else {
1189 //This is the default logic when no content_type is present
1190 res.append('Content-disposition', 'attachment;filename=' + require('uuid').v4() + '.csv');
1191 }
1192
1193 var readStream = require('fs').createReadStream(result.data.file_name);
1194 disableCacheOnResponse(req, res);
1195 readStream.on('end', function() {
1196 require('fs').unlink(result.data.file_name, function() {
1197 // File deleted
1198 });
1199 });
1200 readStream.pipe(res);
1201
1202 } else if (res.status == 206) {
1203 console.log('status for image')
1204 try {
1205 disableCacheOnResponse(req, res);
1206 res.writeHead(404, {
1207 "Content-Type": "text/html; charset=UTF-8"
1208 });
1209 res.write("404 \nNot Found\n");
1210 res.end();
1211 } catch (err) {
1212 console.log("Error while sending response: " + err.toString());
1213 }
1214 } else if (res.status == 207) {
1215 // Same as 206, but we dont want attachement
1216 res.status = 200;
1217 try {
1218 disableCacheOnResponse(req, res);
1219 res.set('Content-Type', result.data.content_type);;
1220 var img = require('fs').readFileSync(result.data.image_url.toString());
1221 res.end(img, 'binary');
1222 } catch (err) {
1223 console.log("Error while sending response: " + err.toString());
1224 }
1225
1226 } else if (res.status === 404) {
1227 res.writeHead(404, {
1228 "Content-Type": "text/plain"
1229 });
1230 res.end('Oops! \nThe requested URL /404 was not found on this server.');
1231 } else if (res.status === 200 && result.data.code === 0 && result.data.send_code) {
1232 // this is to handle a subscribe call from Facebook
1233 res.write(result.data.send_code);
1234 res.end();
1235 } else {
1236 var response = {
1237 code: 0,
1238 data: result.data,
1239 message: result.error_message
1240 };
1241 disableCacheOnResponse(req, res);
1242 res.json(response);
1243 res.end();
1244 var endTime = new Date();
1245 var elapsedTime = (endTime - startTime) / 1000;
1246
1247 //console.log("Time elapsed "+elapsedTime);
1248 console.warn("API Response", moduleName + "@" + apiName, elapsedTime);
1249 var _os = require("os");
1250 var hostname = _os.hostname();
1251
1252 if (!hostname) {
1253 hostname = "no_hostname";
1254 }
1255 var metric = [{
1256 "module": "api." + moduleName,
1257 "key": apiName + '.' + hostname + ".time_taken",
1258 "metric_type": "count",
1259 "value": elapsedTime
1260 }];
1261 require('./framework/fwk').fwk.feedMetricData(metric, function() {});
1262 }
1263 }, function(err) {
1264 // error handler if q.promise failed.
1265 console.error('An unhandled error occured while calling the api. Error was ' + err.toString());
1266 console.error('A db connection may have leaked.');
1267 }.bind(startTime));
1268
1269 console.log('about to call ' + moduleName + '/' + apiName + '_' + apiMethod.toLowerCase());
1270 console.warn("[" + getFormatedDate() + "] [INFO] [API] [" + moduleName + "/" + apiName + '_' + apiMethod.toLowerCase() + "] [execute] Litmus API Process Started.");
1271 switch (apiMethod.toLowerCase()) {
1272 case 'get':
1273 var rqst = {
1274 query: queryString,
1275 params: params,
1276 cookies: req.cookies,
1277 req: req,
1278 res: res
1279 };
1280 try {
1281 console.log("API Calling")
1282 require('./api/' + moduleName + '/' + apiName + '_' + apiMethod.toLowerCase()).execute(rqst, q, require('./framework/fwk').fwk);
1283 } catch (err) {
1284 if (err.code === 'MODULE_NOT_FOUND') {
1285 console.warn('Module name: ' + moduleName + ', Api Name: ' + apiName + ', Method Name: ' + apiMethod.toLowerCase() + ', Unhandled Error', err.code);
1286 q.resolve({
1287 status: 404
1288 });
1289 }
1290 }
1291 break;
1292 case 'options':
1293 // we will have only a single handler for OPTIONS HTTP METHOD
1294 apiName = 'handle';
1295 moduleName = 'configs';
1296 apiMethod = 'options';
1297 case 'post':
1298 case 'put':
1299 var rqst = {
1300 query: queryString,
1301 params: params,
1302 cookies: req.cookies,
1303 body: req.body,
1304 files: req.files,
1305 req: req,
1306 res: res
1307 };
1308 try {
1309 require('./api/' + moduleName + '/' + apiName + '_' + apiMethod.toLowerCase()).execute(rqst, q, require('./framework/fwk').fwk);
1310 } catch (err) {
1311 if (err.code === 'MODULE_NOT_FOUND') {
1312 console.warn('Module name: ' + moduleName + ', Api Name: ' + apiName + ', Method Name: ' + apiMethod.toLowerCase() + ', Unhandled Error', err.code);
1313 q.resolve({
1314 status: 404
1315 });
1316 } else {
1317 console.error('Error executing the API ' + moduleName + '_' + apiName, err);
1318 }
1319 /*console.error(err.toString());
1320 console.error(err.stack);*/
1321 }
1322 break;
1323 case 'delete':
1324 var rqst = {
1325 query: queryString,
1326 params: params,
1327 cookies: req.cookies,
1328 req: req,
1329 res: res
1330 };
1331 try {
1332 require('./api/' + moduleName + '/' + apiName + '_' + apiMethod.toLowerCase()).execute(rqst, q, require('./framework/fwk').fwk);
1333 } catch (err) {
1334 if (err.code === 'MODULE_NOT_FOUND') {
1335 console.warn('Module name: ' + moduleName + ', Api Name: ' + apiName + ', Method Name: ' + apiMethod.toLowerCase() + ', Unhandled Error', err.code);
1336 q.resolve({
1337 status: 404
1338 });
1339 }
1340 }
1341 break;
1342 default:
1343 apiMethod = '';
1344 break;
1345 }
1346 }
1347
1348 /*
1349 Check if Ip address is avaiable in IP address Array or not.
1350 */
1351 function checkAllowedIPAddress(ipAddresses, ipAddress, cb) {
1352 cb(ipAddresses.indexOf(ipAddress) > -1);
1353 }
1354
1355 /*
1356 Get allowed IP address based on based on type.
1357 type can be app_id or shop_id or brand_id.
1358 value will be id for corresponding type.
1359 */
1360 function getAllowedIPAddress(type, value, cb) {
1361 var brandDetails = {};
1362 var resq = require('q').defer();
1363 if (type == "app_id") {
1364 //Create request for the parameter
1365 var request = {
1366 "query": {
1367 "app_id": value
1368 }
1369 }
1370 //Resolve Promise
1371 resq.promise.then(function(result) {
1372 cb(result);
1373 });
1374 //Execute Request.
1375 require('./api/brands/by_shop_get').execute(request, resq, require('./framework/fwk').fwk);
1376 } else if (type == "shop_id") {
1377 var request = {
1378 "query": {
1379 "shop_id": value
1380 }
1381 }
1382 //Resolve Promise
1383 resq.promise.then(function(result) {
1384 cb(result);
1385 });
1386 //Execute Request.
1387 require('./api/brands/by_shop_get').execute(request, resq, require('./framework/fwk').fwk);
1388 } else if (type == "brand_id") {
1389 var fwk = require('./framework/fwk').fwk
1390 //Get Brand Details by Brand ID.
1391 fwk.db.Brands.getById(value, fwk, function(brand) {
1392 if (brand) {
1393 cb({
1394 status: 200,
1395 data: {
1396 code: 0,
1397 //add the brand details on response
1398 brand: brand
1399 }
1400 });
1401 } else {
1402 cb({
1403 status: 200,
1404 data: {
1405 code: 0
1406 }
1407 })
1408 }
1409
1410 });
1411 }
1412 }
1413
1414 //get the user_id if user_key populated on req body or query and get the brand_id if secret_key populated on req body or query.
1415 function getBrandIdAndUserId(req, res, fwk, next) {
1416 if (req.query.secret_key) {
1417 //get the brand id by secret key
1418 fwk.db.Brands.getCustomizedFieldBySecretKey({
1419 _id: 1
1420 }, req.query.secret_key, fwk, function(response) {
1421 if (response && response._id) {
1422 //assign the brand id on requested query
1423 req.query.brand_id = response._id.toString();
1424 //check if request query have user key
1425 if (req.query.user_key) {
1426 //get the user_id by user_key and brand_id
1427 fwk.db.Users.getCustomizedUserByKeyAndBrandId({
1428 _id: 1
1429 }, req.query.user_key, req.query.brand_id, fwk, function(user) {
1430 if (user) {
1431 //set user id on req customer_id
1432 req.customer_id = user._id.toString();
1433 //set the user id on req.query.user_id
1434 req.query.user_id = user._id.toString();
1435 next();
1436 } else {
1437 var req_parameters = req.query;
1438 //create the new user with user key and brand id
1439 createNewUser(req_parameters, fwk, function(user_id) {
1440 if (user_id) {
1441 //set user id on req customer_id
1442 req.customer_id = user_id.toString();
1443 //set the user id on req.query.user_id
1444 req.query.user_id = user_id.toString();
1445 next();
1446 } else {
1447 next();
1448 }
1449 });
1450 }
1451 });
1452 } else {
1453 next();
1454 }
1455 } else {
1456 // var data = {
1457 // code: 2,
1458 // error_message: "Invalid secret key."
1459 // };
1460 // responseForInvalidValues(data, req, res);
1461 next();
1462 }
1463 });
1464
1465 } else if (req.body.secret_key) {
1466 //get the brand id by secret key
1467 fwk.db.Brands.getCustomizedFieldBySecretKey({
1468 _id: 1
1469 }, req.body.secret_key, fwk, function(response) {
1470 if (response && response._id) {
1471 //assign the brand id on requested body
1472 req.body.brand_id = response._id.toString();
1473 //check request body have user_key
1474 if (req.body.user_key || req.query.user_key) {
1475 var user_key = (req.body.user_key) ? req.body.user_key : ((req.query.user_key) ? req.query.user_key : null)
1476 //get the user_id by user_key and brand_id
1477 fwk.db.Users.getCustomizedUserByKeyAndBrandId({
1478 _id: 1
1479 }, user_key, req.body.brand_id, fwk, function(user) {
1480 if (user && user._id) {
1481
1482 //set user id on req customer_id
1483 req.customer_id = user._id.toString();
1484 if (req.body.user_key) {
1485 req.body.user_id = user._id.toString();
1486 } else {
1487 req.query.user_id = user._id.toString();
1488 }
1489 //set user id on req.body.user_id
1490 req.body.user_id = user._id.toString();
1491 next();
1492 } else {
1493 var req_parameters = req.body;
1494 //create the new user with user key and brand id
1495 createNewUser(req_parameters, fwk, function(user_id) {
1496 if (user_id) {
1497 //set user id on req customer_id
1498 req.customer_id = user_id.toString();
1499 //set the user id on req.query.user_id
1500 req.body.user_id = user_id.toString();
1501 next();
1502 } else {
1503 next();
1504 }
1505 });
1506 }
1507 });
1508 } else {
1509 next();
1510 }
1511 } else {
1512 // var data = {
1513 // code: 2,
1514 // error_message: "Invalid secret key."
1515 // };
1516 // responseForInvalidValues(data, req, res);
1517 next();
1518 }
1519 })
1520 } else {
1521 //check request body have user_key
1522 if (req.body.user_key) {
1523 //get the user_id by user_key and brand_id
1524 fwk.db.Users.getCustomizedUserByKeyAndBrandId({
1525 _id: 1
1526 }, req.body.user_key, req.body.brand_id, fwk, function(user) {
1527 if (user) {
1528 //set user id on req customer_id
1529 req.customer_id = user._id.toString();
1530 //set user id on req.body.user_id
1531 req.body.user_id = user._id.toString();
1532 next();
1533 } else {
1534 var req_parameters = req.body;
1535 //create the new user with user key and brand id
1536 createNewUser(req_parameters, fwk, function(user_id) {
1537 if (user_id) {
1538 //set user id on req customer_id
1539 req.customer_id = user_id.toString();
1540 //set the user id on req.query.user_id
1541 req.body.user_id = user_id.toString();
1542 next();
1543 } else {
1544 next();
1545 }
1546 });
1547 }
1548 });
1549 //check if request query have user key
1550 } else if (req.query.user_key) {
1551 //get the user_id by user_key and brand_id
1552 fwk.db.Users.getCustomizedUserByKeyAndBrandId({
1553 _id: 1
1554 }, req.query.user_key, req.query.brand_id, fwk, function(user) {
1555 if (user) {
1556 //set user id on req customer_id
1557 req.customer_id = user._id.toString();
1558 //set the user id on req.query.user_id
1559 req.query.user_id = user._id.toString();
1560 next();
1561 } else {
1562 var req_parameters = req.query;
1563 //create the new user with user key and brand id
1564 createNewUser(req_parameters, fwk, function(user_id) {
1565 if (user_id) {
1566 //set user id on req customer_id
1567 req.customer_id = user_id.toString();
1568 //set the user id on req.query.user_id
1569 req.query.user_id = user_id.toString();
1570 next();
1571 } else {
1572 next();
1573 }
1574 });
1575 }
1576 });
1577 } else {
1578 next();
1579 }
1580 }
1581
1582 }
1583
1584 //get the shop id by app id and populate it on reqest body or query
1585 function getShopId(req, res, fwk, next) {
1586 //check request body have app_id
1587 if (req.body.app_id || req.body.appId) {
1588 var app_id = (req.body.app_id) ? req.body.app_id : req.body.appId;
1589 app_id = (app_id) ? app_id.toLowerCase() : app_id;
1590 req.body.appId = app_id;
1591 req.body.app_id = app_id;
1592 //get the shop id by app_id
1593 fwk.db.Shops.getShopByAppId(app_id, fwk, function(shop) {
1594 if (shop && shop._id) {
1595 //set shop id on req.body.shop_id
1596 req.body.shop_id = shop._id.toString();
1597 req.body.shopId = shop._id.toString();
1598 if (shop.brand_id) {
1599 //Tekram Patel: Added to log the brand id in logs
1600 //after logging this brand_id will removed from logging parameters
1601 req.logging = {};
1602 req.logging.brand_id = shop.brand_id.toString();
1603 }
1604 next();
1605 } else {
1606 // var data = {
1607 // code: 2,
1608 // error_message: "Invalid app id."
1609 // };
1610 // responseForInvalidValues(data, req, res);
1611 next();
1612 }
1613 });
1614 //check if request query have app id
1615 } else if (req.query.app_id || req.query.appId) {
1616 var app_id = (req.query.app_id) ? req.query.app_id : req.query.appId;
1617 app_id = (app_id) ? app_id.toLowerCase() : app_id;
1618 req.query.app_id = app_id;
1619 req.query.appId = app_id;
1620 //get the shop id by app_id
1621 fwk.db.Shops.getShopByAppId(app_id, fwk, function(shop) {
1622 if (shop && shop._id) {
1623 //set the shop id on req.query.shop_id
1624 req.query.shop_id = shop._id.toString();
1625 req.query.shopId = shop._id.toString();
1626 if (shop.brand_id) {
1627 //Tekram Patel: Added to log the brand id in logs,
1628 //after logging this brand_id will removed from logging parameters
1629 req.logging = {};
1630 req.logging.brand_id = shop.brand_id.toString();
1631 }
1632 next();
1633 } else {
1634 // var data = {
1635 // code: 2,
1636 // error_message: "Invalid app id."
1637 // };
1638 // responseForInvalidValues(data, req, res);
1639 next();
1640 }
1641 });
1642 } else {
1643 next();
1644 }
1645 }
1646
1647 //create the new user with customer id(user key) and brand id
1648 function createNewUser(req_parameters, fwk, cb) {
1649 var brand_id = null;
1650 if (!fwk.isIdEmpty(req_parameters.brand_id)) {
1651 brand_id = new fwk.ObjectID.createFromHexString(req_parameters.brand_id);
1652 } else {
1653 brand_id = req_parameters.brand_id;
1654 }
1655 //user parameters for create the new user
1656 var user_parameters_for_insert = {
1657 name: req_parameters.name,
1658 email_address: req_parameters.userEmail,
1659 phone_number: req_parameters.userPhone,
1660 brand_customer_id: {},
1661 brand_id: brand_id
1662 };
1663 //append brand id with user details
1664 user_parameters_for_insert.brand_customer_id[req_parameters.brand_id] = {
1665 brand_id: brand_id,
1666 created_date: new Date(),
1667 customer_id: req_parameters.user_key
1668 };
1669 //insert new user on users collection
1670 fwk.db.Users.insertNewUsersWithGivenParameters(user_parameters_for_insert, fwk, function(user_id) {
1671 cb(user_id);
1672 });
1673 }
1674
1675 //method for get the formated date for loging
1676 function getFormatedDate() {
1677 var current_date = new Date();
1678 current_date = current_date.toJSON();
1679 //Commented by Tek: 09/05/2018: because winston timestamp have T in timestamp we need to add timestamp same as winston timestamp
1680 //current_date = current_date.replace("T", " ");
1681 //current_date = current_date.replace(".", ",");
1682 //Commented by Tek: 09/05/2018: because winston timestamp have Z in timestamp we need to add timestamp same as winston timestamp
1683 // current_date = current_date.replace("Z", "");
1684 return current_date;
1685 }
1686
1687 function disableCacheOnResponse(req, res) {
1688 res.set('Cache-Control', 'no-store,no-cache');
1689 res.set('Pragma', 'no-cache');
1690 changeExpiryOfSession(req);
1691 }
1692
1693
1694
1695 function changeExpiryOfSession(req) {
1696 // rolling the session to increase expiry time.
1697 if (req && req.session) {
1698 let sessionTime = req.session.sessionTimeInSeconds;
1699 let fwk = require('./framework/fwk').fwk;
1700 if (sessionTime && sessionTime > 0) {
1701 let client = fwk.getSessionRedisClient();
1702 if (client) {
1703 let result = client.expire('sess:' + req.sessionID, sessionTime, () => {
1704 client.quit();
1705 });
1706 console.warn("set expiry from litmus: ", 'sess:' + req.sessionID, sessionTime, result);
1707 }
1708 }
1709 }
1710 }
1711
1712 //method to log the api request details
1713 function logAPIRequestDetails(api_method, module_name, api_name, req) {
1714
1715 var component_name = (module_name) ? (module_name + "@" + api_name) : api_name;
1716 //list of api/component name those needs to ignore for logging
1717 var excluded_api_list = ['me'];
1718 //ignore the logging message for http method options
1719 if (api_method && api_method.toLowerCase() != "options" && excluded_api_list.indexOf(component_name) == -1) {
1720 var logging_message = "";
1721 //explicitly adding the timestamp to logs, because winston http transport does not provide the timestamp with logs
1722 //TODO: Needs to add timestamp by winston itself instead of adding explicitly
1723 logging_message += getFormatedDate() + " - warn: [framework.routes]";
1724 //Adding api details to logs
1725 logging_message += " [" + component_name + "]";
1726 //Adding performance parameters to logs
1727 logging_message += " [api_hit]";
1728 //check if req have logging details and brand_id or not, if Yes then add brand_id to logs
1729 if (req.logging && req.logging.brand_id) {
1730 //adding brand_id to logs
1731 logging_message += " [" + req.logging.brand_id + "]";
1732 //adding group_id as a NA, because group_id is not exists in this condition
1733 logging_message += " [NA]";
1734 //check if req body or query have shop_id or not if yes then add shop_id or add NA as shop_id
1735 if (req.body.shop_id) {
1736 logging_message += " [" + req.body.shop_id + "]";
1737 } else if (req.query.shop_id) {
1738 logging_message += " [" + req.query.shop_id + "]";
1739 } else {
1740 logging_message += " [NA]";
1741 }
1742 //check if req body or query have app_id or not if yes then add app_id or add NA as app_id
1743 if (req.body.app_id) {
1744 logging_message += " [" + req.body.app_id + "]";
1745 } else if (req.query.app_id) {
1746 logging_message += " [" + req.query.app_id + "]";
1747 } else {
1748 logging_message += " [NA]";
1749 }
1750 //delete the logging object from req, I am using this for only the project details
1751 delete req['logging'];
1752 } else {
1753 //check http method and append the ids based on http method
1754 switch (api_method.toLowerCase()) {
1755 case "get":
1756 case "delete":
1757 req_key = "query";
1758 //appending the ids by query parameters
1759 logging_message = appendLoggingMessage(req_key, req, logging_message);
1760 break;
1761 case "post":
1762 case "put":
1763 req_key = "body";
1764 //appending the ids by body parameters
1765 logging_message = appendLoggingMessage(req_key, req, logging_message);
1766 break;
1767 default:
1768 //appending all ids as a NA if matches found for http method
1769 logging_message += " [NA] [NA] [NA] [NA]";
1770 break;
1771 }
1772 }
1773 //append 1 as a value to sum the number of request calls
1774 logging_message += " [1] api called";
1775 console.warn("API Count", logging_message);
1776 }
1777 }
1778
1779 //method to get and append the ids by given req_key
1780 function appendLoggingMessage(req_key, req, logging_message) {
1781 if (req[req_key]) {
1782 //appending brand_id in logs
1783 logging_message += (req[req_key].brand_id) ? " [" + req[req_key].brand_id + "]" : " [NA]";
1784 //appending group_id in logs
1785 logging_message += (req[req_key].group_id) ? " [" + req[req_key].group_id + "]" : " [NA]";
1786 //appending shop_id in logs
1787 logging_message += (req[req_key].shop_id) ? " [" + req[req_key].shop_id + "]" : ((req[req_key].shopId) ? " [" + req[req_key].shopId + "]" : " [NA]");
1788 //appending app_id in logs
1789 logging_message += (req[req_key].app_id) ? " [" + req[req_key].app_id + "]" : ((req[req_key].appId) ? " [" + req[req_key].appId + "]" : " [NA]");
1790 } else {
1791 logging_message += " [NA] [NA] [NA] [NA]";
1792 }
1793 return logging_message;
1794 }
1795
1796 exports.establishRoutes = establishRoutes;
1797 } // end closure
1798)();