瀏覽代碼

Merge pull request #3820 from overleaf/as-block-ie

Add middleware to block unsupported browsers

GitOrigin-RevId: b1f1e4ae1572c3c323dc72442c8d5169b4879d5d
Alasdair Smith 5 年之前
父節點
當前提交
f7cf7626ec

+ 23 - 0
services/web/app/src/infrastructure/UnsupportedBrowserMiddleware.js

@@ -0,0 +1,23 @@
+const Bowser = require('bowser')
+const Settings = require('settings-sharelatex')
+
+function unsupportedBrowserMiddleware(req, res, next) {
+  if (!Settings.unsupportedBrowsers) return next()
+
+  const userAgent = req.headers['user-agent']
+
+  const parser = Bowser.getParser(userAgent)
+
+  // Allow bots through by only ignoring bots or unrecognised UA strings
+  const isBot = parser.isPlatform('bot') || !parser.getBrowserName()
+  if (isBot) return next()
+
+  const isUnsupported = parser.satisfies(Settings.unsupportedBrowsers)
+  if (isUnsupported) {
+    return res.redirect('/unsupported-browser')
+  }
+
+  next()
+}
+
+module.exports = { unsupportedBrowserMiddleware }

+ 9 - 0
services/web/app/src/router.js

@@ -49,6 +49,9 @@ const InstitutionsController = require('./Features/Institutions/InstitutionsCont
 const UserMembershipRouter = require('./Features/UserMembership/UserMembershipRouter')
 const UserMembershipRouter = require('./Features/UserMembership/UserMembershipRouter')
 const SystemMessageController = require('./Features/SystemMessages/SystemMessageController')
 const SystemMessageController = require('./Features/SystemMessages/SystemMessageController')
 const { Joi, validate } = require('./infrastructure/Validation')
 const { Joi, validate } = require('./infrastructure/Validation')
+const {
+  unsupportedBrowserMiddleware
+} = require('./infrastructure/UnsupportedBrowserMiddleware')
 
 
 const logger = require('logger-sharelatex')
 const logger = require('logger-sharelatex')
 const _ = require('underscore')
 const _ = require('underscore')
@@ -263,6 +266,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
       maxRequests: 30,
       maxRequests: 30,
       timeInterval: 60
       timeInterval: 60
     }),
     }),
+    unsupportedBrowserMiddleware,
     ProjectController.projectListPage
     ProjectController.projectListPage
   )
   )
   webRouter.post(
   webRouter.post(
@@ -284,6 +288,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
       maxRequests: 15,
       maxRequests: 15,
       timeInterval: 60
       timeInterval: 60
     }),
     }),
+    unsupportedBrowserMiddleware,
     AuthenticationController.validateUserSession(),
     AuthenticationController.validateUserSession(),
     AuthorizationMiddleware.ensureUserCanReadProject,
     AuthorizationMiddleware.ensureUserCanReadProject,
     ProjectController.loadEditor
     ProjectController.loadEditor
@@ -1138,5 +1143,9 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
     TokenAccessController.grantTokenAccessReadOnly
     TokenAccessController.grantTokenAccessReadOnly
   )
   )
 
 
+  webRouter.get('/unsupported-browser', (req, res) => {
+    res.render('general/unsupported-browser')
+  })
+
   webRouter.get('*', ErrorController.notFound)
   webRouter.get('*', ErrorController.notFound)
 }
 }

+ 16 - 0
services/web/app/views/general/unsupported-browser.pug

@@ -0,0 +1,16 @@
+extends ../layout/layout-no-js
+
+block vars
+	- metadata = { title: 'Unsupported browser', viewport: true }
+
+block body
+	body.full-height
+		main.content.content-alt.full-height
+			.container.full-height
+				.error-container.full-height
+					.error-details
+						h1.error-status Unsupported Browser
+						p.error-description
+							| Sorry, we don't support your browser anymore. Find out more about #[a(href="https://www.overleaf.com/learn/how-to/What_browsers_do_you_support") what browsers we support].
+							br
+							| If you think you're seeing this message in error, please #[a(href="/contact") let us know].

+ 27 - 10
services/web/package-lock.json

@@ -2710,7 +2710,17 @@
         "string_decoder": {
         "string_decoder": {
           "version": "1.3.0",
           "version": "1.3.0",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-          "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="
+          "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+          "requires": {
+            "safe-buffer": "~5.2.0"
+          },
+          "dependencies": {
+            "safe-buffer": {
+              "version": "5.2.1",
+              "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+              "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+            }
+          }
         }
         }
       }
       }
     },
     },
@@ -5848,6 +5858,12 @@
       "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
       "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
       "dev": true
       "dev": true
     },
     },
+    "@ungap/promise-all-settled": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+      "dev": true
+    },
     "@uppy/companion-client": {
     "@uppy/companion-client": {
       "version": "1.8.2",
       "version": "1.8.2",
       "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-1.8.2.tgz",
       "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-1.8.2.tgz",
@@ -6000,12 +6016,6 @@
         "cuid": "^2.1.1"
         "cuid": "^2.1.1"
       }
       }
     },
     },
-    "@ungap/promise-all-settled": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-      "dev": true
-    },
     "@webassemblyjs/ast": {
     "@webassemblyjs/ast": {
       "version": "1.9.0",
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -8815,9 +8825,9 @@
       "dev": true
       "dev": true
     },
     },
     "bowser": {
     "bowser": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz",
-      "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA=="
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
+      "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="
     },
     },
     "boxen": {
     "boxen": {
       "version": "4.2.0",
       "version": "4.2.0",
@@ -16681,6 +16691,13 @@
         "camelize": "1.0.0",
         "camelize": "1.0.0",
         "content-security-policy-builder": "2.1.0",
         "content-security-policy-builder": "2.1.0",
         "dasherize": "2.0.0"
         "dasherize": "2.0.0"
+      },
+      "dependencies": {
+        "bowser": {
+          "version": "2.9.0",
+          "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz",
+          "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA=="
+        }
       }
       }
     },
     },
     "hex-color-regex": {
     "hex-color-regex": {

+ 1 - 0
services/web/package.json

@@ -69,6 +69,7 @@
     "basic-auth-connect": "^1.0.0",
     "basic-auth-connect": "^1.0.0",
     "bcrypt": "^5.0.0",
     "bcrypt": "^5.0.0",
     "body-parser": "^1.19.0",
     "body-parser": "^1.19.0",
+    "bowser": "^2.11.0",
     "bufferedstream": "1.6.0",
     "bufferedstream": "1.6.0",
     "bull": "^3.18.0",
     "bull": "^3.18.0",
     "celebrate": "^10.0.1",
     "celebrate": "^10.0.1",