mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
fix(api): fix password validation for /reset_password
route (#3858)
Previously, the password validation logic for the `/reset_password` route was reversed: An error was returned when the password was valid and the operation would succeed when the password was invalid. This commit fixes the logic to return an error when the validation fails and proceed with resetting the password when the password is valid.
This commit is contained in:
parent
87acf824ed
commit
702d5c4971
4 changed files with 150 additions and 34 deletions
6
.changeset/eighty-snails-admire.md
Normal file
6
.changeset/eighty-snails-admire.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'@verdaccio/server-fastify': patch
|
||||
'@verdaccio/web': patch
|
||||
---
|
||||
|
||||
Fix the password validation logic for the `/reset_password` route to ensure that the password is only reset if it is valid.
|
|
@ -83,30 +83,31 @@ async function loginRoute(fastify: FastifyInstance) {
|
|||
fastify.configInstance?.server?.passwordValidationRegex
|
||||
) === false
|
||||
) {
|
||||
fastify.auth.changePassword(
|
||||
name as string,
|
||||
password.old,
|
||||
password.new,
|
||||
(err, isUpdated): void => {
|
||||
if (_.isNil(err) && isUpdated) {
|
||||
reply.code(fastify.statusCode.OK);
|
||||
} else {
|
||||
reply.send(
|
||||
fastify.errorUtils.getInternalError(
|
||||
fastify.errorUtils.API_ERROR.INTERNAL_SERVER_ERROR
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
reply.send(
|
||||
fastify.errorUtils.getCode(
|
||||
fastify.statusCode.BAD_REQUEST,
|
||||
fastify.errorUtils.APP_ERROR.PASSWORD_VALIDATION
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
fastify.auth.changePassword(
|
||||
name as string,
|
||||
password.old,
|
||||
password.new,
|
||||
(err, isUpdated): void => {
|
||||
if (_.isNil(err) && isUpdated) {
|
||||
reply.code(fastify.statusCode.OK);
|
||||
} else {
|
||||
reply.send(
|
||||
fastify.errorUtils.getInternalError(
|
||||
fastify.errorUtils.API_ERROR.INTERNAL_SERVER_ERROR
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
// });
|
||||
|
|
|
@ -71,23 +71,18 @@ function addUserAuthApi(auth: Auth, config: Config): Router {
|
|||
config?.serverSettings?.passwordValidationRegex
|
||||
) === false
|
||||
) {
|
||||
auth.changePassword(
|
||||
name as string,
|
||||
password.old,
|
||||
password.new,
|
||||
(err, isUpdated): void => {
|
||||
if (_.isNil(err) && isUpdated) {
|
||||
next({
|
||||
ok: true,
|
||||
});
|
||||
} else {
|
||||
return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));
|
||||
}
|
||||
|
||||
auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {
|
||||
if (_.isNil(err) && isUpdated) {
|
||||
next({
|
||||
ok: true,
|
||||
});
|
||||
} else {
|
||||
return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -79,6 +79,122 @@ describe('test web server', () => {
|
|||
.expect(HTTP_STATUS.CANNOT_HANDLE, JSON.stringify({ error: 'cannot handle this' }));
|
||||
});
|
||||
|
||||
test('should change password', async () => {
|
||||
const oldPass = 'test';
|
||||
const newPass = 'new-pass';
|
||||
|
||||
const api = supertest(await initializeServer('default-test.yaml'));
|
||||
|
||||
// Login with the old password.
|
||||
const loginRes = await api
|
||||
.post('/-/verdaccio/sec/login')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
username: 'test',
|
||||
password: oldPass,
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
|
||||
// Change the password.
|
||||
await api
|
||||
.put('/-/verdaccio/sec/reset_password')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.set(HEADER_TYPE.AUTHORIZATION, `Bearer ${loginRes.body.token}`)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
password: {
|
||||
old: oldPass,
|
||||
new: newPass,
|
||||
},
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
|
||||
// Verify that you cannot login with the old password.
|
||||
await api
|
||||
.post('/-/verdaccio/sec/login')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
username: 'test',
|
||||
password: oldPass,
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.UNAUTHORIZED);
|
||||
|
||||
// Verify that you can login with the new password.
|
||||
await api
|
||||
.post('/-/verdaccio/sec/login')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
username: 'test',
|
||||
password: newPass,
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
});
|
||||
|
||||
test('should not change to invalid password', async () => {
|
||||
const oldPass = 'test';
|
||||
const newPass = '12'; // Invalid password: Too short.
|
||||
|
||||
const api = supertest(await initializeServer('default-test.yaml'));
|
||||
|
||||
// Login with the old password.
|
||||
const loginRes = await api
|
||||
.post('/-/verdaccio/sec/login')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
username: 'test',
|
||||
password: oldPass,
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
|
||||
// Try changing to an invalid password.
|
||||
await api
|
||||
.put('/-/verdaccio/sec/reset_password')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.set(HEADER_TYPE.AUTHORIZATION, `Bearer ${loginRes.body.token}`)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
password: {
|
||||
old: oldPass,
|
||||
new: newPass,
|
||||
},
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.BAD_REQUEST);
|
||||
|
||||
// Verify that you cannot login with the new (invalid) password.
|
||||
await api
|
||||
.post('/-/verdaccio/sec/login')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
username: 'test',
|
||||
password: newPass,
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.UNAUTHORIZED);
|
||||
|
||||
// Verify that you can still login with the old password.
|
||||
await api
|
||||
.post('/-/verdaccio/sec/login')
|
||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||
.send(
|
||||
JSON.stringify({
|
||||
username: 'test',
|
||||
password: oldPass,
|
||||
})
|
||||
)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
});
|
||||
|
||||
test('should not change password if flag is disabled', async () => {
|
||||
const oldPass = 'test';
|
||||
const newPass = 'new-pass';
|
||||
|
@ -136,6 +252,4 @@ describe('test web server', () => {
|
|||
)
|
||||
.expect(HTTP_STATUS.OK);
|
||||
});
|
||||
|
||||
test.todo('should change password');
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue