mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
* [web] add infrastructure level zod change * [web] set req validation mode for tests to 'enforce' GitOrigin-RevId: 6dbc8bff7ed9f89045c398df93d84bca589de4e9
100 lines
6.5 KiB
Diff
100 lines
6.5 KiB
Diff
diff --git a/lib/strategy.js b/lib/strategy.js
|
|
index 4de162f7e92a20b1ccd4d34dd9bcc0916f4c8c43..c67bb4e0b0287d615eac4c01b84c83d2bac91446 100644
|
|
--- a/lib/strategy.js
|
|
+++ b/lib/strategy.js
|
|
@@ -5,6 +5,29 @@ const passport_strategy_1 = require("passport-strategy");
|
|
const assert_1 = require("assert");
|
|
const url = require("url");
|
|
const node_saml_1 = require("@node-saml/node-saml");
|
|
+// --- Overleaf patch: request-input lockdown compatibility ---
|
|
+// This library reads req.query/req.body directly to parse the SAML protocol
|
|
+// fields (SAMLResponse, SAMLRequest, RelayState) it's built around, which is
|
|
+// otherwise indistinguishable from unvalidated application code reading raw
|
|
+// request input under Overleaf's request-input lockdown (see
|
|
+// libraries/validation-tools and the patched express in
|
|
+// .yarn/patches/express-npm-*.patch). The lockdown captures the original
|
|
+// parsed values in symbol-keyed fields, registered in the global symbol
|
|
+// registry (the same ones @overleaf/validation-tools' lockdown.js reads), and
|
|
+// only turns the *public* req.query/req.body properties into throwing
|
|
+// accessors -- reading through these raw fields instead sidesteps that, and
|
|
+// is identical to plain req.query/req.body when the lockdown isn't installed
|
|
+// (i.e. for every consumer of this package outside this monorepo).
|
|
+const __overleafLockdownInstalled = Symbol.for("overleaf.lockdown.installed");
|
|
+const __overleafLockdownRawQuery = Symbol.for("overleaf.lockdown.rawQuery");
|
|
+const __overleafLockdownRawBody = Symbol.for("overleaf.lockdown.rawBody");
|
|
+function __overleafRawQuery(req) {
|
|
+ return req[__overleafLockdownInstalled] ? req[__overleafLockdownRawQuery] : req.query;
|
|
+}
|
|
+function __overleafRawBody(req) {
|
|
+ return req[__overleafLockdownInstalled] ? req[__overleafLockdownRawBody] : req.body;
|
|
+}
|
|
+// --- end Overleaf patch ---
|
|
class AbstractStrategy extends passport_strategy_1.Strategy {
|
|
constructor(options, signonVerify, logoutVerify) {
|
|
super();
|
|
@@ -52,7 +75,7 @@ class AbstractStrategy extends passport_strategy_1.Strategy {
|
|
catch (_c) {
|
|
userMatch = false;
|
|
}
|
|
- const RelayState = ((_a = req.query) === null || _a === void 0 ? void 0 : _a.RelayState) || ((_b = req.body) === null || _b === void 0 ? void 0 : _b.RelayState);
|
|
+ const RelayState = ((_a = __overleafRawQuery(req)) === null || _a === void 0 ? void 0 : _a.RelayState) || ((_b = __overleafRawBody(req)) === null || _b === void 0 ? void 0 : _b.RelayState);
|
|
if (this._saml == null) {
|
|
return this.error(new Error("Can't get logout response URL without a SAML provider defined."));
|
|
}
|
|
@@ -125,22 +148,22 @@ class AbstractStrategy extends passport_strategy_1.Strategy {
|
|
this.redirect(url);
|
|
}
|
|
};
|
|
- if (((_a = req.query) === null || _a === void 0 ? void 0 : _a.SAMLResponse) || ((_b = req.query) === null || _b === void 0 ? void 0 : _b.SAMLRequest)) {
|
|
+ if (((_a = __overleafRawQuery(req)) === null || _a === void 0 ? void 0 : _a.SAMLResponse) || ((_b = __overleafRawQuery(req)) === null || _b === void 0 ? void 0 : _b.SAMLRequest)) {
|
|
const originalQuery = (_c = url.parse(req.url).query) !== null && _c !== void 0 ? _c : "";
|
|
this._saml
|
|
- .validateRedirectAsync(req.query, originalQuery)
|
|
+ .validateRedirectAsync(__overleafRawQuery(req), originalQuery)
|
|
.then(validateCallback)
|
|
.catch((err) => this.error(err));
|
|
}
|
|
- else if ((_d = req.body) === null || _d === void 0 ? void 0 : _d.SAMLResponse) {
|
|
+ else if ((_d = __overleafRawBody(req)) === null || _d === void 0 ? void 0 : _d.SAMLResponse) {
|
|
this._saml
|
|
- .validatePostResponseAsync(req.body)
|
|
+ .validatePostResponseAsync(__overleafRawBody(req))
|
|
.then(validateCallback)
|
|
.catch((err) => this.error(err));
|
|
}
|
|
- else if ((_e = req.body) === null || _e === void 0 ? void 0 : _e.SAMLRequest) {
|
|
+ else if ((_e = __overleafRawBody(req)) === null || _e === void 0 ? void 0 : _e.SAMLRequest) {
|
|
this._saml
|
|
- .validatePostRequestAsync(req.body)
|
|
+ .validatePostRequestAsync(__overleafRawBody(req))
|
|
.then(validateCallback)
|
|
.catch((err) => this.error(err));
|
|
}
|
|
@@ -151,7 +174,7 @@ class AbstractStrategy extends passport_strategy_1.Strategy {
|
|
if (this._saml == null) {
|
|
throw new Error("Can't process login request without a SAML provider defined.");
|
|
}
|
|
- const RelayState = (req.query && req.query.RelayState) || (req.body && req.body.RelayState);
|
|
+ const RelayState = (__overleafRawQuery(req) && __overleafRawQuery(req).RelayState) || (__overleafRawBody(req) && __overleafRawBody(req).RelayState);
|
|
const host = req.headers && req.headers.host;
|
|
if (this._saml.options.authnRequestBinding === "HTTP-POST") {
|
|
const data = await this._saml.getAuthorizeFormAsync(RelayState, host);
|
|
@@ -172,7 +195,7 @@ class AbstractStrategy extends passport_strategy_1.Strategy {
|
|
throw new Error("Can't process logout request without a SAML provider defined.");
|
|
}
|
|
try {
|
|
- const RelayState = (req.query && req.query.RelayState) || (req.body && req.body.RelayState);
|
|
+ const RelayState = (__overleafRawQuery(req) && __overleafRawQuery(req).RelayState) || (__overleafRawBody(req) && __overleafRawBody(req).RelayState);
|
|
// Defaults to HTTP-Redirect
|
|
this.redirect(await this._saml.getLogoutUrlAsync(req.user, RelayState, options));
|
|
}
|
|
@@ -188,7 +211,7 @@ class AbstractStrategy extends passport_strategy_1.Strategy {
|
|
if (this._saml == null) {
|
|
throw new Error("Can't logout without a SAML provider defined.");
|
|
}
|
|
- const RelayState = (req.query && req.query.RelayState) || (req.body && req.body.RelayState);
|
|
+ const RelayState = (__overleafRawQuery(req) && __overleafRawQuery(req).RelayState) || (__overleafRawBody(req) && __overleafRawBody(req).RelayState);
|
|
this._saml
|
|
.getLogoutUrlAsync(req.user, RelayState, {})
|
|
.then((url) => callback(null, url))
|