Gitter migration: Setup redirects (rollout pt. 3)
[gitter.git] / server / handlers / root.js
blobcc67788c726e9b71b908ac9f6af908f80faf3d55
1 'use strict';
3 const Promise = require('bluebird');
4 const env = require('gitter-web-env');
5 const nconf = env.config;
6 const stats = env.stats;
7 const express = require('express');
8 const StatusError = require('statuserror');
9 const identifyRoute = env.middlewares.identifyRoute;
10 const featureToggles = require('../web/middlewares/feature-toggles');
11 const ensureLoggedIn = require('../web/middlewares/ensure-logged-in');
12 const preventClickjackingMiddleware = require('../web/middlewares/prevent-clickjacking');
13 const langs = require('langs');
14 const urlJoin = require('url-join');
15 //const loginUtils = require('../web/login-utils');
16 const socialMetadataGenerator = require('./social-metadata-generator');
17 const fonts = require('../web/fonts');
18 const contextGenerator = require('../web/context-generator');
19 const generateAdminChatMessageReportSnapshot = require('./snapshots/admin-chat-message-report-snapshot');
21 const survivalMode = !!process.env.SURVIVAL_MODE || false;
23 /**
24  * When Gitter hits a big news site, this setting disables
25  * the embedded chats on the home page, which helps with
26  * load
27  */
28 var slashdotEffectSurvivalMode = survivalMode || !!process.env.SLASHDOT_EFFECT_SURVIVAL_MODE;
30 var router = express.Router({ caseSensitive: true, mergeParams: true });
32 router.get(
33   nconf.get('web:homeurl'),
34   identifyRoute('homepage'),
35   preventClickjackingMiddleware,
36   featureToggles,
37   require('../web/middlewares/unawesome-browser'),
38   function(req, res /*, next*/) {
39     // if (req.user && req.query.redirect !== 'no') {
40     //   loginUtils.redirectUserToDefaultTroupe(req, res, next);
41     //   return;
42     // }
44     // This is code of the translation we are able to provide (e.g. en, zh-TW)
45     var locale = req.i18n.getLocale();
46     var requested = req.headers['accept-language'] || '';
47     requested = requested.split(';')[0] || '';
48     requested = requested.split(/,\s*/)[0];
49     requested = requested.toLowerCase();
51     var requestLangCode, requestLangLocalName;
52     // We compare the translation we provide with what user wants
53     // if we can't provide translation, we get localized name of the language so we can show  "Want this in 中文 ?" message
54     // "en" for "en-gb" is fine, so is "zh-tw" for "zh-tw"
55     const translationRequired = locale !== requested && locale !== requested.split('-')[0];
56     if (translationRequired) {
57       var requestLang = langs.where('1', requested);
58       if (requestLang) {
59         requestLangCode = requestLang['1'];
60         requestLangLocalName = requestLang.local;
61       }
62     }
64     var translatedBy = req.i18n.__('Translated By');
65     /* i18n doesn't like empty strings. Use a dash as a proxy */
66     if (translatedBy === '-') translatedBy = '';
68     // when the viewer is not logged in:
69     res.render('homepage', {
70       slashdotEffectSurvivalMode: slashdotEffectSurvivalMode,
71       bootScriptName: 'homepage',
72       cssFileName: 'styles/homepage.css',
73       elementUrl: nconf.get('element:appUrl'),
74       wordy: locale === 'ru',
75       translationRequired: translationRequired,
76       requestLangCode: requestLangCode,
77       requestLangLocalName: requestLangLocalName,
78       translated: translatedBy,
79       fonts: fonts.getFonts(),
80       hasCachedFonts: fonts.hasCachedFonts(req.cookies),
81       socialMetadata: socialMetadataGenerator.getMetadata()
82     });
83   }
86 if (nconf.get('web:homeurl') !== '/') {
87   router.get('/', identifyRoute('homepage-landing'), preventClickjackingMiddleware, function(
88     req,
89     res
90   ) {
91     if (req.user) {
92       if (req.query.redirect === 'no') {
93         res.relativeRedirect(nconf.get('web:homeurl') + '?redirect=no');
94       } else {
95         res.relativeRedirect(nconf.get('web:homeurl'));
96       }
97       return;
98     }
100     res.render('landing');
101   });
104 router.get('/apps', identifyRoute('homepage-apps'), preventClickjackingMiddleware, function(
105   req,
106   res
107 ) {
108   res.redirect(urlJoin(nconf.get('web:basepath'), '#apps-panel'));
111 router.get(
112   '/manifest.webmanifest',
113   identifyRoute('web-app-manifest'),
114   preventClickjackingMiddleware,
115   function(req, res) {
116     res.set('Content-Type', 'application/manifest+json');
117     res.render('manifest-webmanifest');
118   }
121 if (nconf.get('matrix:wellKnownServer')) {
122   router.get(
123     '/.well-known/matrix/server',
124     identifyRoute('well-known-matrix-server'),
125     preventClickjackingMiddleware,
126     function(req, res) {
127       res.set('Content-Type', 'application/manifest+json');
128       res.render('wellknown-matrix-server', {
129         matrixWellKnownServer: nconf.get('matrix:wellKnownServer')
130       });
131     }
132   );
135 if (nconf.get('matrix:wellKnownClient')) {
136   router.get(
137     '/.well-known/matrix/client',
138     identifyRoute('well-known-matrix-client'),
139     preventClickjackingMiddleware,
140     function(req, res) {
141       res.set('Content-Type', 'application/manifest+json');
142       // Allow any other client app to request this resource across origins (CORS)
143       res.set('access-control-allow-origin', '*');
145       res.render('wellknown-matrix-client', {
146         matrixWellKnownClient: nconf.get('matrix:wellKnownClient')
147       });
148     }
149   );
152 router.get('/robots.txt', identifyRoute('homepage-robots'), preventClickjackingMiddleware, function(
153   req,
154   res
155 ) {
156   res.set('Content-Type', 'text/text');
157   res.render('robotstxt', {
158     allowCrawling: nconf.get('sitemap:allowCrawling'),
159     sitemap: nconf.get('sitemap:location')
160   });
163 router.get('/humans.txt', identifyRoute('homepage-humans'), preventClickjackingMiddleware, function(
164   req,
165   res
166 ) {
167   res.set('Content-Type', 'text/text');
168   res.render('humanstxt');
171 router.get(
172   '/-/unawesome-browser',
173   identifyRoute('homepage-unawesome-browser'),
174   preventClickjackingMiddleware,
175   function(req, res) {
176     res.status(406 /* Not Acceptable */).render('unawesome-browser', {});
177   }
180 router.get('/about/early-bird', identifyRoute('earlybird'), preventClickjackingMiddleware, function(
181   req,
182   res
183 ) {
184   res.relativeRedirect('/');
187 router.get(
188   '/about/gitlab/mailing-list',
189   ensureLoggedIn,
190   identifyRoute('gitlab-mailing-list'),
191   preventClickjackingMiddleware,
192   function(req, res) {
193     var user = req.user;
195     stats.event('gitlab_ml_opt_in', {
196       userId: user.id,
197       username: user.username
198     });
200     res.render('gitlab-mailing-list');
201   }
204 // old campaign that still gets some hits
205 router.get('/about/*', identifyRoute('homepage-about'), preventClickjackingMiddleware, function(
206   req,
207   res
208 ) {
209   res.redirect(nconf.get('web:homeurl'));
212 // This really doesn't seem like the right place for this?
213 // Does anyone know what this is for?
214 router.get('/_s/cdn/*', identifyRoute('homepage-cdn'), preventClickjackingMiddleware, function(
215   req,
216   res
217 ) {
218   res.redirect(req.path.replace('/_s/cdn', ''));
221 router.get(
222   '/-/admin/chat-message-reports',
223   identifyRoute('admin-chat-message-reports'),
224   preventClickjackingMiddleware,
225   function(req, res) {
226     if (!req.user || !req.user.staff) {
227       throw new StatusError(403, 'Only staff can view this area');
228     }
230     Promise.props({
231       troupeContext: contextGenerator.generateBasicContext(req),
232       snapshots: generateAdminChatMessageReportSnapshot(req)
233     }).then(function({ troupeContext, snapshots }) {
234       troupeContext.snapshots = snapshots;
236       res.render('admin/chat-message-reports', {
237         bootScriptName: 'chat-message-reports',
238         cssFileName: 'styles/router-admin-dashboard.css',
239         troupeContext: troupeContext
240       });
241     });
242   }
245 module.exports = router;