-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Add account unlock on password reset #7146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mtrezza
merged 17 commits into
parse-community:master
from
mtrezza:add-account-unlock-on-password-reset
Feb 1, 2021
Merged
Changes from 15 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
dc9f90d
Merge commit 'ccb045b68c5b4d983a90fa125513fc476e4e2387'
mtrezza 4d72525
Merge remote-tracking branch 'upstream/master'
mtrezza 65a6bdb
Merge remote-tracking branch 'upstream/master'
mtrezza 50274b8
Merge remote-tracking branch 'upstream/master'
mtrezza 3b337cd
Merge remote-tracking branch 'upstream/master'
mtrezza 073f0fc
Merge remote-tracking branch 'upstream/master'
mtrezza 2ee5907
Merge remote-tracking branch 'upstream/master'
mtrezza 241a1d8
Merge remote-tracking branch 'upstream/master'
mtrezza 4f097ce
Merge remote-tracking branch 'upstream/master'
mtrezza 8f3ea1c
Merge remote-tracking branch 'upstream/master'
mtrezza f2509e0
added account unlock on password reset
mtrezza 3514422
added account policy option
mtrezza 080fd0c
added changelog entry
mtrezza 0bb6743
Added docs entry
mtrezza fbc8748
moved changelog entry to correct position
mtrezza 7714357
improved tests to ensure requesting password reset email does not unl…
mtrezza 8539315
run prettier
mtrezza File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
'use strict'; | ||
|
||
const Config = require('../lib/Config'); | ||
const Definitions = require('../lib/Options/Definitions'); | ||
const request = require('../lib/request'); | ||
|
||
const loginWithWrongCredentialsShouldFail = function (username, password) { | ||
return new Promise((resolve, reject) => { | ||
|
@@ -340,3 +342,118 @@ describe('Account Lockout Policy: ', () => { | |
}); | ||
}); | ||
}); | ||
|
||
describe('lockout with password reset option', () => { | ||
let sendPasswordResetEmail; | ||
|
||
async function setup(options = {}) { | ||
const accountLockout = Object.assign( | ||
{ | ||
duration: 10000, | ||
threshold: 1, | ||
}, options | ||
); | ||
const config = { | ||
appName: 'exampleApp', | ||
accountLockout: accountLockout, | ||
publicServerURL: 'http://localhost:8378/1', | ||
emailAdapter: { | ||
sendVerificationEmail: () => Promise.resolve(), | ||
sendPasswordResetEmail: () => Promise.resolve(), | ||
sendMail: () => {}, | ||
}, | ||
}; | ||
await reconfigureServer(config); | ||
|
||
sendPasswordResetEmail = spyOn(config.emailAdapter, 'sendPasswordResetEmail').and.callThrough(); | ||
} | ||
|
||
it('accepts valid unlockOnPasswordReset option', async () => { | ||
const values = [true, false]; | ||
|
||
for (const value of values) { | ||
await expectAsync(setup({ unlockOnPasswordReset: value })).toBeResolved(); | ||
} | ||
}); | ||
|
||
it('rejects invalid unlockOnPasswordReset option', async () => { | ||
const values = ["a", 0, {}, [], null]; | ||
|
||
for (const value of values) { | ||
await expectAsync(setup({ unlockOnPasswordReset: value })).toBeRejected(); | ||
} | ||
}); | ||
|
||
it('uses default value if unlockOnPasswordReset is not set', async () => { | ||
await expectAsync(setup({ unlockOnPasswordReset: undefined })).toBeResolved(); | ||
|
||
const parseConfig = Config.get(Parse.applicationId); | ||
expect(parseConfig.accountLockout.unlockOnPasswordReset).toBe(Definitions.AccountLockoutOptions.unlockOnPasswordReset.default); | ||
}); | ||
|
||
it('allow login for locked account after password reset', async () => { | ||
await setup({ unlockOnPasswordReset: true }); | ||
const config = Config.get(Parse.applicationId); | ||
|
||
const user = new Parse.User(); | ||
const username = 'exampleUsername'; | ||
const password = 'examplePassword'; | ||
user.setUsername(username); | ||
user.setPassword(password); | ||
user.setEmail('[email protected]'); | ||
await user.signUp(); | ||
|
||
await expectAsync(Parse.User.logIn(username, 'incorrectPassword')).toBeRejected(); | ||
await expectAsync(Parse.User.logIn(username, password)).toBeRejected(); | ||
|
||
await Parse.User.requestPasswordReset(user.getEmail()); | ||
const link = sendPasswordResetEmail.calls.all()[0].args[0].link; | ||
const linkUrl = new URL(link); | ||
const token = linkUrl.searchParams.get('token'); | ||
const newPassword = 'newPassword'; | ||
await request({ | ||
method: 'POST', | ||
url: `${config.publicServerURL}/apps/test/request_password_reset`, | ||
body: `new_password=${newPassword}&token=${token}&username=${username}`, | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
followRedirects: false, | ||
}); | ||
|
||
await expectAsync(Parse.User.logIn(username, newPassword)).toBeResolved(); | ||
}); | ||
|
||
it('reject login for locked account after password reset (default)', async () => { | ||
await setup(); | ||
const config = Config.get(Parse.applicationId); | ||
|
||
const user = new Parse.User(); | ||
const username = 'exampleUsername'; | ||
const password = 'examplePassword'; | ||
user.setUsername(username); | ||
user.setPassword(password); | ||
user.setEmail('[email protected]'); | ||
await user.signUp(); | ||
|
||
await expectAsync(Parse.User.logIn(username, 'incorrectPassword')).toBeRejected(); | ||
await expectAsync(Parse.User.logIn(username, password)).toBeRejected(); | ||
|
||
await Parse.User.requestPasswordReset(user.getEmail()); | ||
const link = sendPasswordResetEmail.calls.all()[0].args[0].link; | ||
const linkUrl = new URL(link); | ||
const token = linkUrl.searchParams.get('token'); | ||
const newPassword = 'newPassword'; | ||
await request({ | ||
method: 'POST', | ||
url: `${config.publicServerURL}/apps/test/request_password_reset`, | ||
body: `new_password=${newPassword}&token=${token}&username=${username}`, | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
followRedirects: false, | ||
}); | ||
|
||
await expectAsync(Parse.User.logIn(username, newPassword)).toBeRejected(); | ||
}); | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.