Skip to content
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

feat: Add Parse Server option resetPasswordSuccessOnInvalidEmail to choose success or error response on password reset with invalid email #7551

Merged
merged 41 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
9ef1968
ci: fix node engine check (#7891)
mtrezza Mar 25, 2022
f63fb2b
fix: return correct response when revert is used in beforeSave (#7839)
dblythy Mar 26, 2022
b3199d7
chore(release): 5.2.1-alpha.1 [skip ci]
semantic-release-bot Mar 26, 2022
48bd512
perf: reduce database operations when using the constant parameter in…
dblythy Mar 26, 2022
e0cca58
chore(release): 5.2.1-alpha.2 [skip ci]
semantic-release-bot Mar 26, 2022
90155cf
feat: add MongoDB 5.1 compatibility (#7682)
github-actions[bot] Mar 27, 2022
499cead
chore(release): 5.3.0-alpha.1 [skip ci]
semantic-release-bot Mar 27, 2022
ef56e98
fix: security upgrade parse push adapter from 4.1.0 to 4.1.2 (#7893)
mtrezza Mar 27, 2022
119dbe0
chore(release): 5.3.0-alpha.2 [skip ci]
semantic-release-bot Mar 27, 2022
6b4b358
feat: add MongoDB 5.2 support (#7894)
mtrezza Mar 27, 2022
75eca2d
chore(release): 5.3.0-alpha.3 [skip ci]
semantic-release-bot Mar 27, 2022
61ef23f
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy May 3, 2022
606ed96
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy May 5, 2022
1e89817
Merge branch 'alpha' of https://github.com/dblythy/parse-server into …
dblythy Jun 7, 2022
9720e8e
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Jun 7, 2022
7bc5c36
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Jun 17, 2022
7b2ab38
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Jun 18, 2022
3c8f5cc
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Sep 18, 2022
5814437
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Sep 29, 2022
986c6c2
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Nov 3, 2022
6a40dc4
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Nov 10, 2022
a9fb355
Merge remote-tracking branch 'upstream/alpha' into alpha
dblythy Dec 20, 2022
11fae79
new: reset password improve transparency
dblythy Jun 18, 2021
a5adbf7
add resetPasswordSuccessOnInvalidEmail
dblythy Sep 6, 2021
08c417e
Update UsersRouter.js
dblythy Sep 6, 2021
532ecd1
Update ValidationAndPasswordsReset.spec.js
dblythy Sep 7, 2021
27e289a
add config check
dblythy May 19, 2022
fd335e3
Update ValidationAndPasswordsReset.spec.js
dblythy May 22, 2022
1815923
refactor
dblythy Dec 23, 2022
ed15b95
Merge branch 'alpha' into forgotPassword
dblythy Dec 23, 2022
4386152
Merge branch 'alpha' into forgotPassword
mtrezza Jan 6, 2023
101211f
Update ValidationAndPasswordsReset.spec.js
dblythy Jan 8, 2023
74db98e
Merge branch 'alpha' into forgotPassword
dblythy Jan 8, 2023
5874552
Merge branch 'alpha' into forgotPassword
dblythy Feb 5, 2023
1c00821
wip
dblythy Feb 5, 2023
682e4e5
Merge branch 'forgotPassword' of https://github.com/dblythy/parse-ser…
dblythy Feb 5, 2023
aa9abc9
Merge branch 'alpha' into forgotPassword
mtrezza Feb 9, 2023
93687bc
Merge branch 'alpha' into forgotPassword
mtrezza Feb 24, 2023
1c67f00
Update src/Options/index.js
mtrezza Feb 24, 2023
2115d36
Update src/Options/docs.js
mtrezza Feb 24, 2023
1d77a97
Update src/Options/Definitions.js
mtrezza Feb 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions spec/ValidationAndPasswordsReset.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1082,4 +1082,43 @@ describe('Custom Pages, Email Verification, Password Reset', () => {
done();
});
});

it('should throw on an invalid reset password', async () => {
dblythy marked this conversation as resolved.
Show resolved Hide resolved
await reconfigureServer({
appName: 'coolapp',
publicServerURL: 'http://localhost:1337/1',
emailAdapter: MockEmailAdapterWithOptions({
fromAddress: 'parse@example.com',
apiKey: 'k',
domain: 'd',
}),
passwordPolicy: {
resetPasswordSuccessOnInvalidEmail: false,
},
});

await expectAsync(Parse.User.requestPasswordReset('test@example.com')).toBeRejectedWith(
new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'A user with that email does not exist.')
);
});

it('validate resetPasswordSuccessonInvalidEmail', async () => {
const invalidValues = [[], {}, 1, 'string'];
for (const value of invalidValues) {
await expectAsync(
reconfigureServer({
appName: 'coolapp',
publicServerURL: 'http://localhost:1337/1',
emailAdapter: MockEmailAdapterWithOptions({
fromAddress: 'parse@example.com',
apiKey: 'k',
domain: 'd',
}),
passwordPolicy: {
resetPasswordSuccessOnInvalidEmail: value,
},
})
).toBeRejectedWith('resetPasswordSuccessOnInvalidEmail must be a boolean value');
}
});
});
7 changes: 7 additions & 0 deletions src/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,13 @@ export class Config {
if (passwordPolicy.resetTokenReuseIfValid && !passwordPolicy.resetTokenValidityDuration) {
throw 'You cannot use resetTokenReuseIfValid without resetTokenValidityDuration';
}

if (
passwordPolicy.resetPasswordSuccessOnInvalidEmail &&
typeof passwordPolicy.resetPasswordSuccessOnInvalidEmail !== 'boolean'
) {
throw 'resetPasswordSuccessOnInvalidEmail must be a boolean value';
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/Options/Definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,13 @@ module.exports.PasswordPolicyOptions = {
'Set the number of previous password that will not be allowed to be set as new password. If the option is not set or set to `0`, no previous passwords will be considered.<br><br>Valid values are >= `0` and <= `20`.<br>Default is `0`.',
action: parsers.numberParser('maxPasswordHistory'),
},
resetPasswordSuccessOnInvalidEmail: {
dblythy marked this conversation as resolved.
Show resolved Hide resolved
env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_PASSWORD_SUCCESS_ON_INVALID_EMAIL',
help:
'Set to true if password resets should return success if the email is invalid<br><br>Default is `true`.',
dblythy marked this conversation as resolved.
Show resolved Hide resolved
mtrezza marked this conversation as resolved.
Show resolved Hide resolved
action: parsers.booleanParser,
default: true,
},
resetTokenReuseIfValid: {
env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_REUSE_IF_VALID',
help:
Expand Down
1 change: 1 addition & 0 deletions src/Options/docs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,11 @@ export interface PasswordPolicyOptions {
Default is `false`.
:DEFAULT: false */
resetTokenReuseIfValid: ?boolean;
/* Set to `true` if a request to reset the password should return a success response even if the provided email address is invalid, or `false` if the request should return an error response if the email address is invalid.
<br><br>
Default is `true`.
:DEFAULT: true */
resetPasswordSuccessOnInvalidEmail: ?boolean;
}

export interface FileUploadOptions {
Expand Down
30 changes: 14 additions & 16 deletions src/Routers/UsersRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ export class UsersRouter extends ClassesRouter {
}
}

handleResetRequest(req) {
async handleResetRequest(req) {
dblythy marked this conversation as resolved.
Show resolved Hide resolved
this._throwOnBadEmailConfig(req);

const { email } = req.body;
Expand All @@ -428,24 +428,22 @@ export class UsersRouter extends ClassesRouter {
);
}
const userController = req.config.userController;
return userController.sendPasswordResetEmail(email).then(
() => {
return Promise.resolve({
response: {},
});
},
err => {
if (err.code === Parse.Error.OBJECT_NOT_FOUND) {
// Return success so that this endpoint can't
// be used to enumerate valid emails
return Promise.resolve({
try {
await userController.sendPasswordResetEmail(email);
return {
response: {},
};
} catch (err) {
if (err.code === Parse.Error.OBJECT_NOT_FOUND) {
if (req.config.passwordPolicy?.resetPasswordSuccessOnInvalidEmail ?? true) {
return {
response: {},
});
} else {
throw err;
};
}
err.message = `A user with that email does not exist.`;
}
);
throw err;
}
}

handleVerificationEmailRequest(req) {
Expand Down