Gitter migration: Setup redirects (rollout pt. 3)
[gitter.git] / server / web / middlewares / timezone.js
blob90c2e2b06a5cf092bc635b3ea6d17ef5f99418f2
1 'use strict';
3 var env = require('gitter-web-env');
4 var logger = env.logger;
5 var errorReporter = env.errorReporter;
6 var userService = require('gitter-web-users');
7 var debug = require('debug')('gitter:infra:timezone-middleware');
9 function parseOffset(value) {
10   if (value.length !== 5) return;
11   var sign = value[0];
12   var hours = parseInt(value.substr(1, 2), 10);
13   var mins = parseInt(value.substr(3, 2), 10);
15   if (sign !== '+' && sign !== '-') return;
16   if (isNaN(hours) || isNaN(mins)) return;
18   return (sign === '-' ? -1 : 1) * hours * 60 + mins;
21 function parseTimezoneCookie(value) {
22   if (!value) return;
23   var parts = value.split(':');
25   if (parts.length < 1) return;
27   var offsetString = parts[0];
28   var abbr = parts[1];
29   var iana = parts[2];
31   var offset = parseOffset(offsetString);
32   if (offset === undefined) return;
34   return { offset: offset, abbr: abbr, iana: iana };
37 /**
38  * Note, does not return a promise as it's indented to be
39  * called outside of the promise-chain.
40  */
41 function updateUserTzInfo(user, timezoneInfo) {
42   debug('Saving timezone information for user %s: %j', user.username, timezoneInfo);
43   userService
44     .updateTzInfo(user._id, timezoneInfo)
45     .catch(function(err) {
46       logger.error('Unable to save timezone info for user', { exception: err });
47       errorReporter(err, { user: user.username }, { module: 'timezone-middleware' });
48     })
49     .done();
52 // eslint-disable-next-line complexity
53 module.exports = function(req, res, next) {
54   /** Parse the cookie if one exists */
55   var parsed = parseTimezoneCookie(req.cookies.gitter_tz);
56   var userTz = req.user && req.user.tz;
58   debug('User presented timezone cookie %j', parsed);
60   if (parsed) {
61     if (userTz) {
62       /* Its possible that the users browser can't do IANA,
63        * so just used the saved value if possible */
64       if (userTz.offset === parsed.offset && userTz.abbr === parsed.abbr) {
65         if (userTz.iana && !parsed.iana) {
66           parsed.iana = userTz.iana;
67         }
68       }
70       /* Has the user presented us with new timezone information? If so, update */
71       if (
72         userTz.offset !== parsed.offset ||
73         userTz.abbr !== parsed.abbr ||
74         userTz.iana !== parsed.iana
75       ) {
76         updateUserTzInfo(req.user, parsed);
77       }
78     } else if (req.user) {
79       /* First time we've got timezone information from this user, so save it */
80       updateUserTzInfo(req.user, parsed);
81     }
83     res.locals.tz = parsed;
84     res.locals.tzOffset = parsed.offset;
85   } else {
86     /* The user did not present a cookie.
87      * Do we have some saved state for the user? If so, let's use that */
88     if (userTz) {
89       res.locals.tz = userTz;
90       res.locals.tzOffset = userTz.offset;
91     } else {
92       /* No cookie, no saved state, default to UTC */
93       res.locals.tzOffset = 0;
94     }
95   }
97   next();