diff --git a/package-lock.json b/package-lock.json index 3aa50ebe6b..ae5ac43110 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7025,18 +7025,16 @@ "integrity": "sha512-DwSbLtdC8zC5B5gTJkFzJj5s9vr9SGzOgQvV9nH7tUVuMSScg0EswAczhjIapOmH3Y8AyP7C4Jv7b8+QJObWZA==" }, "node_modules/@node-oauth/oauth2-server": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@node-oauth/oauth2-server/-/oauth2-server-4.3.0.tgz", - "integrity": "sha512-QxSWMPwiEFwZczFbZRJjmzsRT9rgb3FhBw/rZlFe9+ZrOWEc6r7mFCcvX14ekxLHSxAxZEYIgzUtE4yHfKiTxg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@node-oauth/oauth2-server/-/oauth2-server-5.1.0.tgz", + "integrity": "sha512-sYvqL1GeZLRSwgl++/oOzxJj/ZBe2yXnp6E5LGNQ5qjpn0+t/dwquXILUe3Sk2Y8/wU7XeRxToOtBVeSVkuJag==", "dependencies": { - "@node-oauth/formats": "^1.0.0", + "@node-oauth/formats": "1.0.0", "basic-auth": "2.0.1", - "bluebird": "3.7.2", - "promisify-any": "2.0.1", "type-is": "1.6.18" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@node-rs/crc32": { @@ -19756,31 +19754,6 @@ "node": ">=0.10.0" } }, - "node_modules/co-bluebird": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/co-bluebird/-/co-bluebird-1.1.0.tgz", - "integrity": "sha1-yLnzqTIKftMJh9zKGlw8/1llXHw=", - "dependencies": { - "bluebird": "^2.10.0", - "co-use": "^1.1.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/co-bluebird/node_modules/bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" - }, - "node_modules/co-use": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/co-use/-/co-use-1.1.0.tgz", - "integrity": "sha1-xrs83xDLc17Kqdru2kbXJclKTmI=", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -28085,11 +28058,6 @@ "node": ">=8" } }, - "node_modules/is-generator": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz", - "integrity": "sha1-wUwhBX7TbjKNuANHlmxpP4hjifM=" - }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -35458,24 +35426,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/promisify-any": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promisify-any/-/promisify-any-2.0.1.tgz", - "integrity": "sha1-QD4AqIE/F1JCq1D+M6afjuzkcwU=", - "dependencies": { - "bluebird": "^2.10.0", - "co-bluebird": "^1.1.0", - "is-generator": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/promisify-any/node_modules/bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" - }, "node_modules/promptly": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/promptly/-/promptly-3.2.0.tgz", @@ -46077,7 +46027,7 @@ "@contentful/rich-text-html-renderer": "^16.0.2", "@contentful/rich-text-types": "^16.0.2", "@google-cloud/bigquery": "^6.0.1", - "@node-oauth/oauth2-server": "^4.3.0", + "@node-oauth/oauth2-server": "^5.1.0", "@node-saml/passport-saml": "^4.0.4", "@overleaf/access-token-encryptor": "*", "@overleaf/fetch-utils": "*", @@ -52367,14 +52317,12 @@ "integrity": "sha512-DwSbLtdC8zC5B5gTJkFzJj5s9vr9SGzOgQvV9nH7tUVuMSScg0EswAczhjIapOmH3Y8AyP7C4Jv7b8+QJObWZA==" }, "@node-oauth/oauth2-server": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@node-oauth/oauth2-server/-/oauth2-server-4.3.0.tgz", - "integrity": "sha512-QxSWMPwiEFwZczFbZRJjmzsRT9rgb3FhBw/rZlFe9+ZrOWEc6r7mFCcvX14ekxLHSxAxZEYIgzUtE4yHfKiTxg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@node-oauth/oauth2-server/-/oauth2-server-5.1.0.tgz", + "integrity": "sha512-sYvqL1GeZLRSwgl++/oOzxJj/ZBe2yXnp6E5LGNQ5qjpn0+t/dwquXILUe3Sk2Y8/wU7XeRxToOtBVeSVkuJag==", "requires": { - "@node-oauth/formats": "^1.0.0", + "@node-oauth/formats": "1.0.0", "basic-auth": "2.0.1", - "bluebird": "3.7.2", - "promisify-any": "2.0.1", "type-is": "1.6.18" } }, @@ -55025,7 +54973,7 @@ "@lezer/highlight": "^1.1.6", "@lezer/lr": "^1.3.13", "@lezer/markdown": "^1.1.0", - "@node-oauth/oauth2-server": "^4.3.0", + "@node-oauth/oauth2-server": "^5.1.0", "@node-saml/passport-saml": "^4.0.4", "@opentelemetry/api": "^1.4.1", "@opentelemetry/auto-instrumentations-web": "^0.33.1", @@ -64665,27 +64613,6 @@ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==" }, - "co-bluebird": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/co-bluebird/-/co-bluebird-1.1.0.tgz", - "integrity": "sha1-yLnzqTIKftMJh9zKGlw8/1llXHw=", - "requires": { - "bluebird": "^2.10.0", - "co-use": "^1.1.0" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" - } - } - }, - "co-use": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/co-use/-/co-use-1.1.0.tgz", - "integrity": "sha1-xrs83xDLc17Kqdru2kbXJclKTmI=" - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -71007,11 +70934,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "is-generator": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz", - "integrity": "sha1-wUwhBX7TbjKNuANHlmxpP4hjifM=" - }, "is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -77508,23 +77430,6 @@ "es-abstract": "^1.19.1" } }, - "promisify-any": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promisify-any/-/promisify-any-2.0.1.tgz", - "integrity": "sha1-QD4AqIE/F1JCq1D+M6afjuzkcwU=", - "requires": { - "bluebird": "^2.10.0", - "co-bluebird": "^1.1.0", - "is-generator": "^1.0.2" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" - } - } - }, "promptly": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/promptly/-/promptly-3.2.0.tgz", diff --git a/services/web/app/src/Features/Authentication/AuthenticationController.js b/services/web/app/src/Features/Authentication/AuthenticationController.js index de5bd149bf..fb359c8bb1 100644 --- a/services/web/app/src/Features/Authentication/AuthenticationController.js +++ b/services/web/app/src/Features/Authentication/AuthenticationController.js @@ -26,6 +26,7 @@ const { const { ParallelLoginError } = require('./AuthenticationErrors') const { hasAdminAccess } = require('../Helpers/AdminAuthorizationHelper') const Modules = require('../../infrastructure/Modules') +const { expressify } = require('@overleaf/promise-utils') function send401WithChallenge(res) { res.setHeader('WWW-Authenticate', 'OverleafLogin') @@ -320,35 +321,33 @@ const AuthenticationController = { // require this here because module may not be included in some versions const Oauth2Server = require('../../../../modules/oauth2-server/app/src/Oauth2Server') - return function (req, res, next) { + const middleware = async (req, res, next) => { const request = new Oauth2Server.Request(req) const response = new Oauth2Server.Response(res) - Oauth2Server.server.authenticate( - request, - response, - { scope }, - function (err, token) { - if (err) { - // use a 401 status code for malformed header for git-bridge - if ( - err.code === 400 && - err.message === 'Invalid request: malformed authorization header' - ) { - err.code = 401 - } - // send all other errors - res - .status(err.code) - .json({ error: err.name, error_description: err.message }) - } else { - req.oauth = { access_token: token.accessToken } - req.oauth_token = token - req.oauth_user = token.user - next() - } + try { + const token = await Oauth2Server.server.authenticate( + request, + response, + { scope } + ) + req.oauth = { access_token: token.accessToken } + req.oauth_token = token + req.oauth_user = token.user + next() + } catch (err) { + if ( + err.code === 400 && + err.message === 'Invalid request: malformed authorization header' + ) { + err.code = 401 } - ) + // send all other errors + res + .status(err.code) + .json({ error: err.name, error_description: err.message }) + } } + return expressify(middleware) }, validateUserSession: function () { diff --git a/services/web/package.json b/services/web/package.json index b363ce9551..d0a929fff3 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -69,7 +69,7 @@ "@contentful/rich-text-html-renderer": "^16.0.2", "@contentful/rich-text-types": "^16.0.2", "@google-cloud/bigquery": "^6.0.1", - "@node-oauth/oauth2-server": "^4.3.0", + "@node-oauth/oauth2-server": "^5.1.0", "@node-saml/passport-saml": "^4.0.4", "@overleaf/access-token-encryptor": "*", "@overleaf/fetch-utils": "*", diff --git a/services/web/test/unit/src/Authentication/AuthenticationControllerTests.js b/services/web/test/unit/src/Authentication/AuthenticationControllerTests.js index b7765063a6..b477a531c9 100644 --- a/services/web/test/unit/src/Authentication/AuthenticationControllerTests.js +++ b/services/web/test/unit/src/Authentication/AuthenticationControllerTests.js @@ -578,13 +578,15 @@ describe('AuthenticationController', function () { }) describe('when Oauth2Server authenticates', function () { - beforeEach(function () { + beforeEach(function (done) { this.token = { accessToken: 'token', user: 'user', } - this.Oauth2Server.server.authenticate.yields(null, this.token) - this.middleware(this.req, this.res, this.next) + this.Oauth2Server.server.authenticate = sinon + .stub() + .resolves(this.token) + this.middleware(this.req, this.res, () => done()) }) it('should set oauth_token on request', function () { @@ -598,15 +600,12 @@ describe('AuthenticationController', function () { it('should set oauth_user on request', function () { this.req.oauth_user.should.equal('user') }) - - it('should call next', function () { - this.next.should.have.been.calledOnce - }) }) describe('when Oauth2Server returns 401 error', function () { - beforeEach(function () { - this.Oauth2Server.server.authenticate.yields({ code: 401 }) + beforeEach(function (done) { + this.res.json.callsFake(() => done()) + this.Oauth2Server.server.authenticate.rejects({ code: 401 }) this.middleware(this.req, this.res, this.next) })