Răsfoiți Sursa

Add option for parsing valid RFC5322 email addresses (#8065)

GitOrigin-RevId: 6af8ae850bd8075e6bf0ebcafd2731177cdf49ad
Alf Eaton 4 ani în urmă
părinte
comite
80f6662957

+ 12 - 0
package-lock.json

@@ -11998,6 +11998,11 @@
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.57.tgz",
       "integrity": "sha512-FNC+P5K1n6pF+M0zIK+gFCoXcJhhzDViL3DRIGy2Fv5PohuSES1JHR7T+GlwxSxlzx4yYbsuzCZvHxcBSRCIOw=="
     },
+    "node_modules/email-addresses": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz",
+      "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw=="
+    },
     "node_modules/emitter-listener": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz",
@@ -35051,6 +35056,7 @@
         "daterangepicker": "https://github.com/overleaf/daterangepicker/archive/e496d2d44ca53e208c930e4cb4bcf29bcefa4550.tar.gz",
         "downshift": "^6.1.0",
         "east": "^2.0.2",
+        "email-addresses": "^5.0.0",
         "events": "^3.3.0",
         "express": "4.17.1",
         "express-bearer-token": "^2.4.0",
@@ -42796,6 +42802,7 @@
         "daterangepicker": "https://github.com/overleaf/daterangepicker/archive/e496d2d44ca53e208c930e4cb4bcf29bcefa4550.tar.gz",
         "downshift": "^6.1.0",
         "east": "^2.0.2",
+        "email-addresses": "^5.0.0",
         "es6-promise": "^4.2.8",
         "escodegen": "^2.0.0",
         "eslint-config-standard-jsx": "^11.0.0-0",
@@ -50335,6 +50342,11 @@
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.57.tgz",
       "integrity": "sha512-FNC+P5K1n6pF+M0zIK+gFCoXcJhhzDViL3DRIGy2Fv5PohuSES1JHR7T+GlwxSxlzx4yYbsuzCZvHxcBSRCIOw=="
     },
+    "email-addresses": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz",
+      "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw=="
+    },
     "emitter-listener": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz",

+ 1 - 1
services/web/app/src/Features/Collaborators/CollaboratorsInviteController.js

@@ -125,7 +125,7 @@ module.exports = CollaboratorsInviteController = {
           return res.json({ invite: null })
         }
         ;({ email, privileges } = req.body)
-        email = EmailHelper.parseEmail(email)
+        email = EmailHelper.parseEmail(email, true)
         if (email == null || email === '') {
           logger.debug(
             { projectId, email, sendingUserId },

+ 12 - 1
services/web/app/src/Features/Helpers/EmailHelper.js

@@ -1,3 +1,5 @@
+const { parseOneAddress } = require('email-addresses')
+
 const EMAIL_REGEXP =
   // eslint-disable-next-line no-useless-escape
   /^([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
@@ -7,10 +9,19 @@ function getDomain(email) {
   return email ? email.split('@').pop() : null
 }
 
-function parseEmail(email) {
+function parseEmail(email, parseRfcAddress = false) {
   if (email == null) {
     return null
   }
+
+  if (parseRfcAddress) {
+    const result = parseOneAddress(email)
+    if (!result) {
+      return null
+    }
+    email = result.address
+  }
+
   if (email.length > 254) {
     return null
   }

+ 1 - 0
services/web/package.json

@@ -106,6 +106,7 @@
     "daterangepicker": "https://github.com/overleaf/daterangepicker/archive/e496d2d44ca53e208c930e4cb4bcf29bcefa4550.tar.gz",
     "downshift": "^6.1.0",
     "east": "^2.0.2",
+    "email-addresses": "^5.0.0",
     "events": "^3.3.0",
     "express": "4.17.1",
     "express-bearer-token": "^2.4.0",

+ 32 - 0
services/web/test/unit/src/HelperFiles/EmailHelperTests.js

@@ -0,0 +1,32 @@
+const { expect } = require('chai')
+const {
+  parseEmail,
+} = require('../../../../app/src/Features/Helpers/EmailHelper')
+
+describe('EmailHelper', function () {
+  it('should parse a single email', function () {
+    const address = 'test@example.com'
+    const expected = 'test@example.com'
+    expect(parseEmail(address)).to.equal(expected)
+    expect(parseEmail(address, true)).to.equal(expected)
+  })
+
+  it('should parse a valid email address', function () {
+    const address = '"Test Person" <test@example.com>'
+    const expected = 'test@example.com'
+    expect(parseEmail(address)).to.equal(null)
+    expect(parseEmail(address, true)).to.equal(expected)
+  })
+
+  it('should return null for an invalid single email', function () {
+    const address = 'testexample.com'
+    expect(parseEmail(address)).to.equal(null)
+    expect(parseEmail(address, true)).to.equal(null)
+  })
+
+  it('should return null for an invalid email address', function () {
+    const address = '"Test Person" test@example.com>'
+    expect(parseEmail(address)).to.equal(null)
+    expect(parseEmail(address, true)).to.equal(null)
+  })
+})