Adds password history support to passwordPolicy (#3102)
* password history support in passwordPolicy * Refactor RestWrite.transformUser * fix eslint issues
This commit is contained in:
committed by
Diwakar Cherukumilli
parent
08bac9f790
commit
bd1689190f
@@ -1010,4 +1010,242 @@ describe("Password Policy: ", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if passwordPolicy.maxPasswordHistory is not a number', done => {
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
maxPasswordHistory: "not a number"
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
fail('passwordPolicy.maxPasswordHistory "not a number" test failed');
|
||||
done();
|
||||
}).catch(err => {
|
||||
expect(err).toEqual('passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if passwordPolicy.maxPasswordHistory is a negative number', done => {
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
maxPasswordHistory: -10
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
fail('passwordPolicy.maxPasswordHistory negative number test failed');
|
||||
done();
|
||||
}).catch(err => {
|
||||
expect(err).toEqual('passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if passwordPolicy.maxPasswordHistory is greater than 20', done => {
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
passwordPolicy: {
|
||||
maxPasswordHistory: 21
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
fail('passwordPolicy.maxPasswordHistory negative number test failed');
|
||||
done();
|
||||
}).catch(err => {
|
||||
expect(err).toEqual('passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail to reset if the new password is same as the last password', done => {
|
||||
const user = new Parse.User();
|
||||
const emailAdapter = {
|
||||
sendVerificationEmail: () => Promise.resolve(),
|
||||
sendPasswordResetEmail: options => {
|
||||
requestp.get({
|
||||
uri: options.link,
|
||||
followRedirect: false,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true
|
||||
}).then(response => {
|
||||
expect(response.statusCode).toEqual(302);
|
||||
const re = /http:\/\/localhost:8378\/1\/apps\/choose_password\?token=([a-zA-Z0-9]+)\&id=test\&username=user1/;
|
||||
const match = response.body.match(re);
|
||||
if (!match) {
|
||||
fail("should have a token");
|
||||
return Promise.reject("Invalid password link");
|
||||
}
|
||||
return Promise.resolve(match[1]); // token
|
||||
}).then(token => {
|
||||
return new Promise((resolve, reject) => {
|
||||
requestp.post({
|
||||
uri: "http://localhost:8378/1/apps/test/request_password_reset",
|
||||
body: `new_password=user1&token=${token}&username=user1`,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
followRedirect: false,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true
|
||||
}).then(response => {
|
||||
resolve([response, token]);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}).then(data => {
|
||||
const response = data[0];
|
||||
const token = data[1];
|
||||
expect(response.statusCode).toEqual(302);
|
||||
expect(response.body).toEqual(`Found. Redirecting to http://localhost:8378/1/apps/choose_password?username=user1&token=${token}&id=test&error=New%20password%20should%20not%20be%20the%20same%20as%20last%201%20passwords.&app=passwordPolicy`);
|
||||
done();
|
||||
return Promise.resolve();
|
||||
}).catch(error => {
|
||||
jfail(error);
|
||||
fail("Repeat password test failed");
|
||||
done();
|
||||
});
|
||||
},
|
||||
sendMail: () => {
|
||||
}
|
||||
};
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
verifyUserEmails: false,
|
||||
emailAdapter: emailAdapter,
|
||||
passwordPolicy: {
|
||||
maxPasswordHistory: 1
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
user.setUsername("user1");
|
||||
user.setPassword("user1");
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
return Parse.User.logOut();
|
||||
}).then(() => {
|
||||
return Parse.User.requestPasswordReset('user1@parse.com');
|
||||
}).catch(error => {
|
||||
jfail(error);
|
||||
fail("SignUp or reset request failed");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should fail if the new password is same as the previous one', done => {
|
||||
const user = new Parse.User();
|
||||
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
verifyUserEmails: false,
|
||||
passwordPolicy: {
|
||||
maxPasswordHistory: 5
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
user.setUsername("user1");
|
||||
user.setPassword("user1");
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
// try to set the same password as the previous one
|
||||
user.setPassword('user1');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
fail("should have failed because the new password is same as the old");
|
||||
done();
|
||||
}).catch(error => {
|
||||
expect(error.message).toEqual('New password should not be the same as last 5 passwords.');
|
||||
expect(error.code).toEqual(Parse.Error.VALIDATION_ERROR);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if the new password is same as the 5th oldest one and policy does not allow the previous 5', done => {
|
||||
const user = new Parse.User();
|
||||
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
verifyUserEmails: false,
|
||||
passwordPolicy: {
|
||||
maxPasswordHistory: 5
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
user.setUsername("user1");
|
||||
user.setPassword("user1");
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
// build history
|
||||
user.setPassword('user2');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
user.setPassword('user3');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
user.setPassword('user4');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
user.setPassword('user5');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
// set the same password as the initial one
|
||||
user.setPassword('user1');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
fail("should have failed because the new password is same as the old");
|
||||
done();
|
||||
}).catch(error => {
|
||||
expect(error.message).toEqual('New password should not be the same as last 5 passwords.');
|
||||
expect(error.code).toEqual(Parse.Error.VALIDATION_ERROR);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should succeed if the new password is same as the 6th oldest one and policy does not allow only previous 5', done => {
|
||||
const user = new Parse.User();
|
||||
|
||||
reconfigureServer({
|
||||
appName: 'passwordPolicy',
|
||||
verifyUserEmails: false,
|
||||
passwordPolicy: {
|
||||
maxPasswordHistory: 5
|
||||
},
|
||||
publicServerURL: "http://localhost:8378/1"
|
||||
}).then(() => {
|
||||
user.setUsername("user1");
|
||||
user.setPassword("user1");
|
||||
user.set('email', 'user1@parse.com');
|
||||
user.signUp().then(() => {
|
||||
// build history
|
||||
user.setPassword('user2');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
user.setPassword('user3');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
user.setPassword('user4');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
user.setPassword('user5');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
user.setPassword('user6'); // this pushes initial password out of history
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
// set the same password as the initial one
|
||||
user.setPassword('user1');
|
||||
return user.save();
|
||||
}).then(() => {
|
||||
done();
|
||||
}).catch(() => {
|
||||
fail("should have succeeded because the new password is not in history");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user