Merge pull request #10394 from overleaf/ii-password-reset-and-strength-checking

[web] Password reset strength checking and UI updates

GitOrigin-RevId: 442a5c9e7e9d0a61d3ae649f3526bc3c02fd5704
This commit is contained in:
ilkin-overleaf
2022-12-07 09:03:36 +00:00
committed by Copybot
parent 887ac13f06
commit 2675cab92e
21 changed files with 309 additions and 159 deletions
@@ -34,6 +34,7 @@ async function getMetricFailure() {
}
let user, previous
async function resetPassword(password) {
await user.getCsrfToken()
await user.doRequest('POST', {
@@ -51,13 +52,15 @@ async function resetPassword(password) {
await user.doRequest('GET', {
url: `/user/password/set?passwordResetToken=${token}&email=${user.email}`,
})
await user.doRequest('POST', {
const { response } = await user.doRequest('POST', {
url: '/user/password/set',
form: {
passwordResetToken: token,
password,
},
})
return response
}
describe('HaveIBeenPwnedApi', function () {
@@ -187,7 +190,15 @@ describe('HaveIBeenPwnedApi', function () {
previous = await getMetricReUsed()
})
beforeEach('set password', async function () {
await resetPassword('aLeakedPassword42')
const response = await resetPassword('aLeakedPassword42')
expect(response.statusCode).to.equal(400)
expect(response.body).to.equal(
JSON.stringify({
message: {
key: 'password-must-be-strong',
},
})
)
await letPasswordCheckRunInBackground()
})
it('should track the weak password', async function () {
@@ -208,7 +219,8 @@ describe('HaveIBeenPwnedApi', function () {
previous = await getMetricUnique()
})
beforeEach('set password', async function () {
await resetPassword('a-strong-new-password')
const response = await resetPassword('a-strong-new-password')
expect(response.statusCode).to.equal(200)
await letPasswordCheckRunInBackground()
})
it('should track the strong password', async function () {
@@ -157,25 +157,29 @@ class User {
ensureUserExists(callback) {
const filter = { email: this.email }
const options = { upsert: true, new: true, setDefaultsOnInsert: true }
UserModel.findOneAndUpdate(filter, {}, options, (error, user) => {
if (error != null) {
return callback(error)
}
this.setExtraAttributes(user)
AuthenticationManager.setUserPasswordInV2(user, this.password, error => {
AuthenticationManager.hashPassword(
this.password,
(error, hashedPassword) => {
if (error != null) {
if (error.name !== 'PasswordMustBeDifferentError') {
return callback(error)
}
return callback(error)
}
this.mongoUpdate({ $set: { emails: this.emails } }, error => {
if (error != null) {
return callback(error)
UserModel.findOneAndUpdate(
filter,
{ $set: { hashedPassword, emails: this.emails } },
options,
(error, user) => {
if (error != null) {
return callback(error)
}
this.setExtraAttributes(user)
callback(null, this.password)
}
callback(null, this.password)
})
})
})
)
}
)
}
setFeatures(features, callback) {
@@ -28,6 +28,7 @@ describe('AuthenticationManager', function () {
'../User/UserGetter': (this.UserGetter = {}),
'./AuthenticationErrors': AuthenticationErrors,
'./HaveIBeenPwned': {
checkPasswordForReuse: sinon.stub().yields(null, false),
checkPasswordForReuseInBackground: sinon.stub(),
},
'../User/UserAuditLogHandler': (this.UserAuditLogHandler = {