Added extra validation for reset_password endpoint

fix https://linear.app/tryghost/issue/SLO-104/cannot-read-properties-of-undefined-reading-0-an-unexpected-error

- if the request body didn't contain the correct keys, it'd just HTTP
  500 out of there
- this adds some optional chaining so we end up with undefined if
  anything isn't as expected, and the following if-statement does the
  rest of the check for us
- this also adds a breaking test (the first E2E test for authentication, yay!)
This commit is contained in:
Daniel Lockyer 2024-05-08 17:54:39 +02:00 committed by Daniel Lockyer
parent b5af65a130
commit 7e9d82655e
3 changed files with 45 additions and 1 deletions

View File

@ -25,7 +25,7 @@ module.exports = {
generateResetToken(apiConfig, frame) { generateResetToken(apiConfig, frame) {
debug('generateResetToken'); debug('generateResetToken');
const email = frame.data.password_reset[0].email; const email = frame.data.password_reset?.[0]?.email;
if (typeof email !== 'string' || !validator.isEmail(email)) { if (typeof email !== 'string' || !validator.isEmail(email)) {
throw new errors.BadRequestError({ throw new errors.BadRequestError({

View File

@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Authentication API generateResetToken Cannot generate reset token without required info 1: [body] 1`] = `
Object {
"errors": Array [
Object {
"code": null,
"context": null,
"details": null,
"ghostErrorCode": null,
"help": null,
"id": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/,
"message": "The server did not receive a valid email",
"property": null,
"type": "BadRequestError",
},
],
}
`;

View File

@ -0,0 +1,25 @@
const {agentProvider, fixtureManager, matchers} = require('../../utils/e2e-framework');
const {anyErrorId} = matchers;
describe('Authentication API', function () {
let agent;
before(async function () {
agent = await agentProvider.getAdminAPIAgent();
await fixtureManager.init('users');
await agent.loginAsOwner();
});
describe('generateResetToken', function () {
it('Cannot generate reset token without required info', async function () {
await agent
.post('authentication/password_reset')
.expectStatus(400)
.matchBodySnapshot({
errors: [{
id: anyErrorId
}]
});
});
});
});