Просмотр исходного кода

Merge pull request #16202 from overleaf/msm-passport-upgrade-2

[web] passport + passport-saml updates (post revert)

GitOrigin-RevId: e1fa5757e15b3ac733511570637d39297247e050
Miguel Serrano 2 лет назад
Родитель
Сommit
771f07d7ad

+ 317 - 50
package-lock.json

@@ -6934,6 +6934,125 @@
         "tslib": "^2.0.0"
       }
     },
+    "node_modules/@node-saml/node-saml": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-4.0.5.tgz",
+      "integrity": "sha512-J5DglElbY1tjOuaR1NPtjOXkXY5bpUhDoKVoeucYN98A3w4fwgjIOPqIGcb6cQsqFq2zZ6vTCeKn5C/hvefSaw==",
+      "dependencies": {
+        "@types/debug": "^4.1.7",
+        "@types/passport": "^1.0.11",
+        "@types/xml-crypto": "^1.4.2",
+        "@types/xml-encryption": "^1.2.1",
+        "@types/xml2js": "^0.4.11",
+        "@xmldom/xmldom": "^0.8.6",
+        "debug": "^4.3.4",
+        "xml-crypto": "^3.0.1",
+        "xml-encryption": "^3.0.2",
+        "xml2js": "^0.5.0",
+        "xmlbuilder": "^15.1.1"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@node-saml/node-saml/node_modules/@xmldom/xmldom": {
+      "version": "0.8.10",
+      "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+      "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/@node-saml/node-saml/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@node-saml/node-saml/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "node_modules/@node-saml/node-saml/node_modules/xml-crypto": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz",
+      "integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==",
+      "dependencies": {
+        "@xmldom/xmldom": "^0.8.8",
+        "xpath": "0.0.32"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/@node-saml/node-saml/node_modules/xml-encryption": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-3.0.2.tgz",
+      "integrity": "sha512-VxYXPvsWB01/aqVLd6ZMPWZ+qaj0aIdF+cStrVJMcFj3iymwZeI0ABzB3VqMYv48DkSpRhnrXqTUkR34j+UDyg==",
+      "dependencies": {
+        "@xmldom/xmldom": "^0.8.5",
+        "escape-html": "^1.0.3",
+        "xpath": "0.0.32"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@node-saml/node-saml/node_modules/xml2js": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+      "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+      "dependencies": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/@node-saml/node-saml/node_modules/xml2js/node_modules/xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/@node-saml/node-saml/node_modules/xpath": {
+      "version": "0.0.32",
+      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz",
+      "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==",
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/@node-saml/passport-saml": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@node-saml/passport-saml/-/passport-saml-4.0.4.tgz",
+      "integrity": "sha512-xFw3gw0yo+K1mzlkW15NeBF7cVpRHN/4vpjmBKzov5YFImCWh/G0LcTZ8krH3yk2/eRPc3Or8LRPudVJBjmYaw==",
+      "dependencies": {
+        "@node-saml/node-saml": "^4.0.4",
+        "@types/express": "^4.17.14",
+        "@types/passport": "^1.0.11",
+        "@types/passport-strategy": "^0.2.35",
+        "passport": "^0.6.0",
+        "passport-strategy": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -13502,13 +13621,22 @@
       "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
     },
     "node_modules/@types/passport": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.7.tgz",
-      "integrity": "sha512-JtswU8N3kxBYgo+n9of7C97YQBT+AYPP2aBfNGTzABqPAZnK/WOAaKfh3XesUYMZRrXFuoPc2Hv0/G/nQFveHw==",
+      "version": "1.0.15",
+      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.15.tgz",
+      "integrity": "sha512-oHOgzPBp5eLI1U/7421qYV/ZySQXMYCBSfRkDe1tQ0YrIbLY/M/76qIXE7Bs7lFyvw1x5QqiNQ9imvh0fQHe9Q==",
       "dependencies": {
         "@types/express": "*"
       }
     },
+    "node_modules/@types/passport-strategy": {
+      "version": "0.2.38",
+      "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
+      "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==",
+      "dependencies": {
+        "@types/express": "*",
+        "@types/passport": "*"
+      }
+    },
     "node_modules/@types/pg": {
       "version": "8.6.1",
       "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz",
@@ -13772,6 +13900,39 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/xml-crypto": {
+      "version": "1.4.5",
+      "resolved": "https://registry.npmjs.org/@types/xml-crypto/-/xml-crypto-1.4.5.tgz",
+      "integrity": "sha512-rHc0tlw/ixu7PCqqlpmP9KDIA79IsoV+HFnhJDsdS4MkVAEhBNaazXjv92Xf9oYjWp9e4His4Qzo8fOzoTjT+Q==",
+      "dependencies": {
+        "@types/node": "*",
+        "xpath": "0.0.27"
+      }
+    },
+    "node_modules/@types/xml-crypto/node_modules/xpath": {
+      "version": "0.0.27",
+      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
+      "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==",
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/@types/xml-encryption": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@types/xml-encryption/-/xml-encryption-1.2.4.tgz",
+      "integrity": "sha512-I69K/WW1Dv7j6O3jh13z0X8sLWJRXbu5xnHDl9yHzUNDUBtUoBY058eb5s+x/WG6yZC1h8aKdI2EoyEPjyEh+Q==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/xml2js": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz",
+      "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/yargs": {
       "version": "17.0.24",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
@@ -30573,15 +30734,20 @@
       }
     },
     "node_modules/passport": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
-      "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
+      "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
       "dependencies": {
         "passport-strategy": "1.x.x",
-        "pause": "0.0.1"
+        "pause": "0.0.1",
+        "utils-merge": "^1.0.1"
       },
       "engines": {
         "node": ">= 0.4.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/jaredhanson"
       }
     },
     "node_modules/passport-google-oauth20": {
@@ -30664,24 +30830,6 @@
         "passport-oauth2": "^1.5.0"
       }
     },
-    "node_modules/passport-saml": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-3.2.4.tgz",
-      "integrity": "sha512-JSgkFXeaexLNQh1RrOvJAgjLnZzH/S3HbX/mWAk+i7aulnjqUe7WKnPl1NPnJWqP7Dqsv0I2Xm6KIFHkftk0HA==",
-      "deprecated": "For versions >= 4, please use scopped package @node-saml/passport-saml",
-      "dependencies": {
-        "@xmldom/xmldom": "^0.7.6",
-        "debug": "^4.3.2",
-        "passport-strategy": "^1.0.0",
-        "xml-crypto": "^2.1.3",
-        "xml-encryption": "^2.0.0",
-        "xml2js": "^0.4.23",
-        "xmlbuilder": "^15.1.1"
-      },
-      "engines": {
-        "node": ">= 12"
-      }
-    },
     "node_modules/passport-strategy": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
@@ -43472,6 +43620,7 @@
         "@contentful/rich-text-types": "^16.0.2",
         "@google-cloud/bigquery": "^6.0.1",
         "@node-oauth/oauth2-server": "^4.3.0",
+        "@node-saml/passport-saml": "^4.0.4",
         "@overleaf/access-token-encryptor": "*",
         "@overleaf/fetch-utils": "*",
         "@overleaf/logger": "*",
@@ -43541,13 +43690,12 @@
         "otplib": "^12.0.1",
         "p-limit": "^2.3.0",
         "parse-data-url": "^2.0.0",
-        "passport": "^0.4.1",
+        "passport": "^0.6.0",
         "passport-google-oauth20": "^2.0.0",
         "passport-ldapauth": "^2.1.4",
         "passport-local": "^1.0.0",
         "passport-oauth2": "^1.5.0",
         "passport-orcid": "0.0.4",
-        "passport-saml": "^3.2.4",
         "passport-twitter": "^1.0.4",
         "pug": "^3.0.1",
         "pug-runtime": "^3.0.1",
@@ -49454,6 +49602,97 @@
         "tslib": "^2.0.0"
       }
     },
+    "@node-saml/node-saml": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-4.0.5.tgz",
+      "integrity": "sha512-J5DglElbY1tjOuaR1NPtjOXkXY5bpUhDoKVoeucYN98A3w4fwgjIOPqIGcb6cQsqFq2zZ6vTCeKn5C/hvefSaw==",
+      "requires": {
+        "@types/debug": "^4.1.7",
+        "@types/passport": "^1.0.11",
+        "@types/xml-crypto": "^1.4.2",
+        "@types/xml-encryption": "^1.2.1",
+        "@types/xml2js": "^0.4.11",
+        "@xmldom/xmldom": "^0.8.6",
+        "debug": "^4.3.4",
+        "xml-crypto": "^3.0.1",
+        "xml-encryption": "^3.0.2",
+        "xml2js": "^0.5.0",
+        "xmlbuilder": "^15.1.1"
+      },
+      "dependencies": {
+        "@xmldom/xmldom": {
+          "version": "0.8.10",
+          "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+          "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="
+        },
+        "debug": {
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+          "requires": {
+            "ms": "2.1.2"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+        },
+        "xml-crypto": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz",
+          "integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==",
+          "requires": {
+            "@xmldom/xmldom": "^0.8.8",
+            "xpath": "0.0.32"
+          }
+        },
+        "xml-encryption": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-3.0.2.tgz",
+          "integrity": "sha512-VxYXPvsWB01/aqVLd6ZMPWZ+qaj0aIdF+cStrVJMcFj3iymwZeI0ABzB3VqMYv48DkSpRhnrXqTUkR34j+UDyg==",
+          "requires": {
+            "@xmldom/xmldom": "^0.8.5",
+            "escape-html": "^1.0.3",
+            "xpath": "0.0.32"
+          }
+        },
+        "xml2js": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
+          "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
+          "requires": {
+            "sax": ">=0.6.0",
+            "xmlbuilder": "~11.0.0"
+          },
+          "dependencies": {
+            "xmlbuilder": {
+              "version": "11.0.1",
+              "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+              "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+            }
+          }
+        },
+        "xpath": {
+          "version": "0.0.32",
+          "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz",
+          "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw=="
+        }
+      }
+    },
+    "@node-saml/passport-saml": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@node-saml/passport-saml/-/passport-saml-4.0.4.tgz",
+      "integrity": "sha512-xFw3gw0yo+K1mzlkW15NeBF7cVpRHN/4vpjmBKzov5YFImCWh/G0LcTZ8krH3yk2/eRPc3Or8LRPudVJBjmYaw==",
+      "requires": {
+        "@node-saml/node-saml": "^4.0.4",
+        "@types/express": "^4.17.14",
+        "@types/passport": "^1.0.11",
+        "@types/passport-strategy": "^0.2.35",
+        "passport": "^0.6.0",
+        "passport-strategy": "^1.0.0"
+      }
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -52099,6 +52338,7 @@
         "@lezer/lr": "^1.3.13",
         "@lezer/markdown": "^1.1.0",
         "@node-oauth/oauth2-server": "^4.3.0",
+        "@node-saml/passport-saml": "^4.0.4",
         "@opentelemetry/api": "^1.4.1",
         "@opentelemetry/auto-instrumentations-web": "^0.33.1",
         "@opentelemetry/context-zone": "^1.15.2",
@@ -52280,13 +52520,12 @@
         "otplib": "^12.0.1",
         "p-limit": "^2.3.0",
         "parse-data-url": "^2.0.0",
-        "passport": "^0.4.1",
+        "passport": "^0.6.0",
         "passport-google-oauth20": "^2.0.0",
         "passport-ldapauth": "^2.1.4",
         "passport-local": "^1.0.0",
         "passport-oauth2": "^1.5.0",
         "passport-orcid": "0.0.4",
-        "passport-saml": "^3.2.4",
         "passport-twitter": "^1.0.4",
         "pdfjs-dist213": "npm:pdfjs-dist@2.13.216",
         "pdfjs-dist401": "npm:pdfjs-dist@4.0.189",
@@ -56786,13 +57025,22 @@
       "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
     },
     "@types/passport": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.7.tgz",
-      "integrity": "sha512-JtswU8N3kxBYgo+n9of7C97YQBT+AYPP2aBfNGTzABqPAZnK/WOAaKfh3XesUYMZRrXFuoPc2Hv0/G/nQFveHw==",
+      "version": "1.0.15",
+      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.15.tgz",
+      "integrity": "sha512-oHOgzPBp5eLI1U/7421qYV/ZySQXMYCBSfRkDe1tQ0YrIbLY/M/76qIXE7Bs7lFyvw1x5QqiNQ9imvh0fQHe9Q==",
       "requires": {
         "@types/express": "*"
       }
     },
+    "@types/passport-strategy": {
+      "version": "0.2.38",
+      "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
+      "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==",
+      "requires": {
+        "@types/express": "*",
+        "@types/passport": "*"
+      }
+    },
     "@types/pg": {
       "version": "8.6.1",
       "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz",
@@ -57056,6 +57304,38 @@
         "@types/node": "*"
       }
     },
+    "@types/xml-crypto": {
+      "version": "1.4.5",
+      "resolved": "https://registry.npmjs.org/@types/xml-crypto/-/xml-crypto-1.4.5.tgz",
+      "integrity": "sha512-rHc0tlw/ixu7PCqqlpmP9KDIA79IsoV+HFnhJDsdS4MkVAEhBNaazXjv92Xf9oYjWp9e4His4Qzo8fOzoTjT+Q==",
+      "requires": {
+        "@types/node": "*",
+        "xpath": "0.0.27"
+      },
+      "dependencies": {
+        "xpath": {
+          "version": "0.0.27",
+          "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
+          "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ=="
+        }
+      }
+    },
+    "@types/xml-encryption": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@types/xml-encryption/-/xml-encryption-1.2.4.tgz",
+      "integrity": "sha512-I69K/WW1Dv7j6O3jh13z0X8sLWJRXbu5xnHDl9yHzUNDUBtUoBY058eb5s+x/WG6yZC1h8aKdI2EoyEPjyEh+Q==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/xml2js": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz",
+      "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/yargs": {
       "version": "17.0.24",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
@@ -71010,12 +71290,13 @@
       }
     },
     "passport": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
-      "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
+      "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
       "requires": {
         "passport-strategy": "1.x.x",
-        "pause": "0.0.1"
+        "pause": "0.0.1",
+        "utils-merge": "^1.0.1"
       }
     },
     "passport-google-oauth20": {
@@ -71075,20 +71356,6 @@
         "passport-oauth2": "^1.5.0"
       }
     },
-    "passport-saml": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-3.2.4.tgz",
-      "integrity": "sha512-JSgkFXeaexLNQh1RrOvJAgjLnZzH/S3HbX/mWAk+i7aulnjqUe7WKnPl1NPnJWqP7Dqsv0I2Xm6KIFHkftk0HA==",
-      "requires": {
-        "@xmldom/xmldom": "^0.7.6",
-        "debug": "^4.3.2",
-        "passport-strategy": "^1.0.0",
-        "xml-crypto": "^2.1.3",
-        "xml-encryption": "^2.0.0",
-        "xml2js": "^0.4.23",
-        "xmlbuilder": "^15.1.1"
-      }
-    },
     "passport-strategy": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",

+ 42 - 57
services/web/app/src/Features/Authentication/AuthenticationController.js

@@ -80,30 +80,36 @@ const AuthenticationController = {
     // This function is middleware which wraps the passport.authenticate middleware,
     // so we can send back our custom `{message: {text: "", type: ""}}` responses on failure,
     // and send a `{redir: ""}` response on success
-    passport.authenticate('local', function (err, user, info) {
-      if (err) {
-        return next(err)
-      }
-      if (user) {
-        // `user` is either a user object or false
-        AuthenticationController.setAuditInfo(req, { method: 'Password login' })
-        return AuthenticationController.finishLogin(user, req, res, next)
-      } else {
-        if (info.redir != null) {
-          return res.json({ redir: info.redir })
+    passport.authenticate(
+      'local',
+      { keepSessionInfo: true },
+      function (err, user, info) {
+        if (err) {
+          return next(err)
+        }
+        if (user) {
+          // `user` is either a user object or false
+          AuthenticationController.setAuditInfo(req, {
+            method: 'Password login',
+          })
+          return AuthenticationController.finishLogin(user, req, res, next)
         } else {
-          res.status(info.status || 200)
-          delete info.status
-          const body = { message: info }
-          const { errorReason } = info
-          if (errorReason) {
-            body.errorReason = errorReason
-            delete info.errorReason
+          if (info.redir != null) {
+            return res.json({ redir: info.redir })
+          } else {
+            res.status(info.status || 200)
+            delete info.status
+            const body = { message: info }
+            const { errorReason } = info
+            if (errorReason) {
+              body.errorReason = errorReason
+              delete info.errorReason
+            }
+            return res.json(body)
           }
-          return res.json(body)
         }
       }
-    })(req, res, next)
+    )(req, res, next)
   },
 
   finishLogin(user, req, res, next) {
@@ -557,55 +563,34 @@ const AuthenticationController = {
 }
 
 function _afterLoginSessionSetup(req, user, callback) {
-  if (callback == null) {
-    callback = function () {}
-  }
-  req.login(user, function (err) {
+  req.login(user, { keepSessionInfo: true }, function (err) {
     if (err) {
       OError.tag(err, 'error from req.login', {
         user_id: user._id,
       })
       return callback(err)
     }
-    // Regenerate the session to get a new sessionID (cookie value) to
-    // protect against session fixation attacks
-    const oldSession = req.session
-    req.session.destroy(function (err) {
+    delete req.session.__tmp
+    delete req.session.csrfSecret
+    req.session.save(function (err) {
       if (err) {
-        OError.tag(err, 'error when trying to destroy old session', {
+        OError.tag(err, 'error saving regenerated session after login', {
           user_id: user._id,
         })
         return callback(err)
       }
-      req.sessionStore.generate(req)
-      // Note: the validation token is not writable, so it does not get
-      // transferred to the new session below.
-      for (const key in oldSession) {
-        const value = oldSession[key]
-        if (key !== '__tmp' && key !== 'csrfSecret') {
-          req.session[key] = value
-        }
+      UserSessionsManager.trackSession(user, req.sessionID, function () {})
+      if (!req.deviceHistory) {
+        // Captcha disabled or SSO-based login.
+        return callback()
       }
-      req.session.save(function (err) {
-        if (err) {
-          OError.tag(err, 'error saving regenerated session after login', {
-            user_id: user._id,
-          })
-          return callback(err)
-        }
-        UserSessionsManager.trackSession(user, req.sessionID, function () {})
-        if (!req.deviceHistory) {
-          // Captcha disabled or SSO-based login.
-          return callback()
-        }
-        req.deviceHistory.add(user.email)
-        req.deviceHistory
-          .serialize(req.res)
-          .catch(err => {
-            logger.err({ err }, 'cannot serialize deviceHistory')
-          })
-          .finally(() => callback())
-      })
+      req.deviceHistory.add(user.email)
+      req.deviceHistory
+        .serialize(req.res)
+        .catch(err => {
+          logger.err({ err }, 'cannot serialize deviceHistory')
+        })
+        .finally(() => callback())
     })
   })
 }

+ 5 - 3
services/web/app/src/Features/User/UserController.js

@@ -266,7 +266,8 @@ async function tryDeleteUser(req, res, next) {
   const sessionId = req.sessionID
 
   if (typeof req.logout === 'function') {
-    req.logout()
+    const logout = promisify(req.logout)
+    await logout()
   }
 
   const destroySession = promisify(req.session.destroy.bind(req.session))
@@ -431,9 +432,10 @@ async function doLogout(req) {
   logger.debug({ user }, 'logging out')
   const sessionId = req.sessionID
 
-  // passport logout
   if (typeof req.logout === 'function') {
-    req.logout()
+    // passport logout
+    const logout = promisify(req.logout.bind(req))
+    await logout()
   }
 
   const destroySession = promisify(req.session.destroy.bind(req.session))

+ 2 - 2
services/web/package.json

@@ -68,6 +68,7 @@
     "@contentful/rich-text-types": "^16.0.2",
     "@google-cloud/bigquery": "^6.0.1",
     "@node-oauth/oauth2-server": "^4.3.0",
+    "@node-saml/passport-saml": "^4.0.4",
     "@overleaf/access-token-encryptor": "*",
     "@overleaf/fetch-utils": "*",
     "@overleaf/logger": "*",
@@ -137,13 +138,12 @@
     "otplib": "^12.0.1",
     "p-limit": "^2.3.0",
     "parse-data-url": "^2.0.0",
-    "passport": "^0.4.1",
+    "passport": "^0.6.0",
     "passport-google-oauth20": "^2.0.0",
     "passport-ldapauth": "^2.1.4",
     "passport-local": "^1.0.0",
     "passport-oauth2": "^1.5.0",
     "passport-orcid": "0.0.4",
-    "passport-saml": "^3.2.4",
     "passport-twitter": "^1.0.4",
     "pug": "^3.0.1",
     "pug-runtime": "^3.0.1",

+ 20 - 23
services/web/test/unit/src/Authentication/AuthenticationControllerTests.js

@@ -77,7 +77,7 @@ describe('AuthenticationController', function () {
         '../User/UserSessionsManager': (this.UserSessionsManager = {
           trackSession: sinon.stub(),
           untrackSession: sinon.stub(),
-          revokeAllUserSessions: sinon.stub().callsArgWith(1, null),
+          revokeAllUserSessions: sinon.stub().yields(null),
         }),
         '../../infrastructure/Modules': (this.Modules = {
           hooks: { fire: sinon.stub().yields(null, []) },
@@ -184,17 +184,17 @@ describe('AuthenticationController', function () {
   describe('passportLogin', function () {
     beforeEach(function () {
       this.info = null
-      this.req.login = sinon.stub().callsArgWith(1, null)
+      this.req.login = sinon.stub().yields(null)
       this.res.json = sinon.stub()
       this.req.session = {
         passport: { user: this.user },
         postLoginRedirect: '/path/to/redir/to',
       }
-      this.req.session.destroy = sinon.stub().callsArgWith(0, null)
-      this.req.session.save = sinon.stub().callsArgWith(0, null)
+      this.req.session.destroy = sinon.stub().yields(null)
+      this.req.session.save = sinon.stub().yields(null)
       this.req.sessionStore = { generate: sinon.stub() }
       this.AuthenticationController.finishLogin = sinon.stub()
-      this.passport.authenticate.callsArgWith(1, null, this.user, this.info)
+      this.passport.authenticate.yields(null, this.user, this.info)
       this.err = new Error('woops')
     })
 
@@ -205,7 +205,7 @@ describe('AuthenticationController', function () {
 
     describe('when authenticate produces an error', function () {
       beforeEach(function () {
-        this.passport.authenticate.callsArgWith(1, this.err)
+        this.passport.authenticate.yields(this.err)
       })
 
       it('should return next with an error', function () {
@@ -221,7 +221,7 @@ describe('AuthenticationController', function () {
     describe('when authenticate produces a user', function () {
       beforeEach(function () {
         this.req.session.postLoginRedirect = 'some_redirect'
-        this.passport.authenticate.callsArgWith(1, null, this.user, this.info)
+        this.passport.authenticate.yields(null, this.user, this.info)
       })
 
       afterEach(function () {
@@ -244,7 +244,7 @@ describe('AuthenticationController', function () {
     describe('when authenticate does not produce a user', function () {
       beforeEach(function () {
         this.info = { text: 'a', type: 'b' }
-        this.passport.authenticate.callsArgWith(1, null, false, this.info)
+        this.passport.authenticate.yields(null, false, this.info)
       })
 
       it('should not call finishLogin', function () {
@@ -273,8 +273,7 @@ describe('AuthenticationController', function () {
     beforeEach(function () {
       this.AuthenticationController._recordFailedLogin = sinon.stub()
       this.AuthenticationController._recordSuccessfulLogin = sinon.stub()
-      this.Modules.hooks.fire = sinon.stub().callsArgWith(3, null, [])
-      // @AuthenticationController.establishUserSession = sinon.stub().callsArg(2)
+      this.Modules.hooks.fire = sinon.stub().yields(null, [])
       this.req.body = {
         email: this.email,
         password: this.password,
@@ -290,7 +289,7 @@ describe('AuthenticationController', function () {
       beforeEach(function () {
         this.Modules.hooks.fire = sinon
           .stub()
-          .callsArgWith(3, null, [null, { redir: '/somewhere' }, null])
+          .yields(null, [null, { redir: '/somewhere' }, null])
       })
 
       it('should stop early and call done with this info object', function (done) {
@@ -311,7 +310,7 @@ describe('AuthenticationController', function () {
 
     describe('when the users rate limit', function () {
       beforeEach(function () {
-        this.LoginRateLimiter.processLoginRequest.callsArgWith(1, null, false)
+        this.LoginRateLimiter.processLoginRequest.yields(null, false)
       })
 
       it('should block the request if the limit has been exceeded', function (done) {
@@ -330,10 +329,10 @@ describe('AuthenticationController', function () {
     describe('when the user is authenticated', function () {
       beforeEach(function () {
         this.cb = sinon.stub()
-        this.LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true)
+        this.LoginRateLimiter.processLoginRequest.yields(null, true)
         this.AuthenticationManager.authenticate = sinon
           .stub()
-          .callsArgWith(3, null, this.user)
+          .yields(null, this.user)
         this.req.sessionID = Math.random()
       })
 
@@ -361,7 +360,7 @@ describe('AuthenticationController', function () {
         beforeEach(function () {
           this.AuthenticationManager.authenticate = sinon
             .stub()
-            .callsArgWith(3, new AuthenticationErrors.ParallelLoginError())
+            .yields(new AuthenticationErrors.ParallelLoginError())
           this.AuthenticationController.doPassportLogin(
             this.req,
             this.req.body.email,
@@ -437,10 +436,10 @@ describe('AuthenticationController', function () {
 
     describe('when the user is not authenticated', function () {
       beforeEach(function () {
-        this.LoginRateLimiter.processLoginRequest.callsArgWith(1, null, true)
+        this.LoginRateLimiter.processLoginRequest.yields(null, true)
         this.AuthenticationManager.authenticate = sinon
           .stub()
-          .callsArgWith(3, null, null)
+          .yields(null, null)
         this.cb = sinon.stub()
         this.AuthenticationController.doPassportLogin(
           this.req,
@@ -937,7 +936,7 @@ describe('AuthenticationController', function () {
 
   describe('_recordSuccessfulLogin', function () {
     beforeEach(function () {
-      this.UserUpdater.updateUser = sinon.stub().callsArg(2)
+      this.UserUpdater.updateUser = sinon.stub().yields()
       this.AuthenticationController._recordSuccessfulLogin(
         this.user._id,
         this.callback
@@ -1078,8 +1077,8 @@ describe('AuthenticationController', function () {
       this.req.session = {
         passport: { user: { _id: 'one' } },
       }
-      this.req.session.destroy = sinon.stub().callsArgWith(0, null)
-      this.req.session.save = sinon.stub().callsArgWith(0, null)
+      this.req.session.destroy = sinon.stub().yields(null)
+      this.req.session.save = sinon.stub().yields(null)
       this.req.sessionStore = { generate: sinon.stub() }
       this.req.login = sinon.stub().yields(null)
 
@@ -1345,9 +1344,7 @@ describe('AuthenticationController', function () {
 
       describe('when req.session.save produces an error', function () {
         beforeEach(function () {
-          this.req.session.save = sinon
-            .stub()
-            .callsArgWith(0, new Error('woops'))
+          this.req.session.save = sinon.stub().yields(new Error('woops'))
         })
 
         it('should produce an error', function (done) {

+ 1 - 1
services/web/test/unit/src/User/UserControllerTests.js

@@ -173,7 +173,7 @@ describe('UserController', function () {
   describe('tryDeleteUser', function () {
     beforeEach(function () {
       this.req.body.password = 'wat'
-      this.req.logout = sinon.stub()
+      this.req.logout = sinon.stub().yields()
       this.req.session.destroy = sinon.stub().yields()
       this.SessionManager.getLoggedInUserId = sinon
         .stub()