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

Merge pull request #17793 from overleaf/jel-password-token-when-managed-linked

[web] Check permissions when using password reset token

GitOrigin-RevId: b5339d5ad5322fcae7beaa99fb40a87ffb938b52
Jessica Lawshe 2 лет назад
Родитель
Сommit
94e9456a4b

+ 3 - 0
services/web/app/src/Features/PasswordReset/PasswordResetController.js

@@ -168,6 +168,9 @@ async function renderSetPasswordForm(req, res, next) {
 
       return res.redirect('/user/password/set' + emailQuery)
     } catch (err) {
+      if (err.name === 'ForbiddenError') {
+        return next(err)
+      }
       return res.redirect('/user/password/reset?error=token_expired')
     }
   }

+ 3 - 0
services/web/app/src/Features/PasswordReset/PasswordResetHandler.js

@@ -71,6 +71,9 @@ async function getUserForPasswordResetToken(token) {
     'overleaf.id': 1,
     email: 1,
   })
+
+  await checkUserPermissions(user, ['change-password'])
+
   if (user == null) {
     return { user: null, remainingPeeks: 0 }
   } else if (data.user_id != null && data.user_id === user._id.toString()) {

+ 47 - 0
services/web/test/unit/src/PasswordReset/PasswordResetHandlerTests.js

@@ -45,6 +45,11 @@ describe('PasswordResetHandler', function () {
         '../Email/EmailHandler': this.EmailHandler,
         '../Authentication/AuthenticationManager': this.AuthenticationManager,
         '@overleaf/settings': this.settings,
+        '../Authorization/PermissionsManager': (this.PermissionsManager = {
+          promises: {
+            checkUserPermissions: sinon.stub(),
+          },
+        }),
       },
     })
     this.token = '12312321i'
@@ -512,4 +517,46 @@ describe('PasswordResetHandler', function () {
       })
     })
   })
+
+  describe('getUserForPasswordResetToken', function () {
+    beforeEach(function () {
+      this.OneTimeTokenHandler.promises.peekValueFromToken.resolves({
+        data: {
+          user_id: this.user._id,
+          email: this.email,
+        },
+        remainingPeeks: 1,
+      })
+
+      this.UserGetter.promises.getUserByMainEmail.resolves({
+        _id: this.user._id,
+        email: this.email,
+      })
+    })
+
+    it('should returns errors from user permissions', async function () {
+      let error
+      const err = new Error('nope')
+      this.PermissionsManager.promises.checkUserPermissions.rejects(err)
+      try {
+        await this.PasswordResetHandler.promises.getUserForPasswordResetToken(
+          'abc123'
+        )
+      } catch (e) {
+        error = e
+      }
+      expect(error).to.deep.equal(error)
+    })
+
+    it('returns user when user has permissions and remaining peaks', async function () {
+      const result =
+        await this.PasswordResetHandler.promises.getUserForPasswordResetToken(
+          'abc123'
+        )
+      expect(result).to.deep.equal({
+        user: { _id: this.user._id, email: this.email },
+        remainingPeeks: 1,
+      })
+    })
+  })
 })