Support updating email via /account/data

This commit is contained in:
Calvin Montgomery 2017-09-05 23:11:28 -07:00
parent 5b6f86668a
commit 9e3426633d
3 changed files with 152 additions and 9 deletions

View File

@ -49,7 +49,7 @@ class AccountController {
throw new InvalidRequestError('Password required'); throw new InvalidRequestError('Password required');
} }
const user = await this.accountDB.getUserByName(name); const user = await this.accountDB.getByName(name);
if (!user) { if (!user) {
throw new InvalidRequestError('User does not exist'); throw new InvalidRequestError('User does not exist');

View File

@ -104,7 +104,11 @@ class AccountDataRoute {
const { password, updates } = req.body; const { password, updates } = req.body;
try { try {
this.accountController.updateAccount(req.user, updates, password); await this.accountController.updateAccount(
req.params.user,
updates,
password
);
res.status(204).send(); res.status(204).send();
} catch (error) { } catch (error) {
reportError(req, res, error); reportError(req, res, error);

View File

@ -19,6 +19,19 @@ const URL_BASE = `http://localhost:${TEST_PORT}`;
function request(method, url, additionalOptions) { function request(method, url, additionalOptions) {
if (!additionalOptions) additionalOptions = {}; if (!additionalOptions) additionalOptions = {};
const { body } = additionalOptions;
if (body) {
delete additionalOptions.body;
if (!additionalOptions.headers) {
additionalOptions.headers = {
'Accept': 'application/json'
};
}
additionalOptions.headers['Content-Type'] = 'application/json';
}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const options = { const options = {
headers: { headers: {
@ -41,11 +54,6 @@ function request(method, url, additionalOptions) {
res.on('data', data => { res.on('data', data => {
buffer += data; buffer += data;
if (buffer.length > 100 * 1024) {
req.abort();
reject(new Error('Response size exceeds 100KB'));
}
}); });
res.on('end', () => { res.on('end', () => {
@ -54,6 +62,10 @@ function request(method, url, additionalOptions) {
}); });
}); });
if (body) {
req.write(JSON.stringify(body));
}
req.end(); req.end();
}); });
} }
@ -85,8 +97,7 @@ describe('AccountDataRoute', () => {
req.signedCookies = signedCookies; req.signedCookies = signedCookies;
next(); next();
}); });
app.use(bodyParser.urlencoded({ app.use(bodyParser.json({
extended: false,
limit: '1kb' limit: '1kb'
})); }));
@ -232,6 +243,7 @@ describe('AccountDataRoute', () => {
); );
assert(verifySessionAsync.calledWith(signedCookies.auth)); assert(verifySessionAsync.calledWith(signedCookies.auth));
assert(csrfVerify.called); assert(csrfVerify.called);
accountDB.verify();
}); });
}); });
@ -239,6 +251,132 @@ describe('AccountDataRoute', () => {
}); });
describe('#updateAccount', () => { describe('#updateAccount', () => {
it('updates email', () => {
accountDB.expects('getByName').withArgs('test').returns({
name: 'test',
password: '$2a$10$c26sbtkVlYlFUBdSxzQGhenZvdPBI2fvTPOmVRyrBuaD.8j7iyoNm',
email: 'test@example.com',
profile: { text: 'blah', image: 'image.jpeg' },
time: new Date('2017-09-01T00:00:00.000Z')
});
accountDB.expects('updateByName').withArgs(
'test',
{ email: 'test_new@example.com' }
);
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
password: 'test',
updates: {
email: 'test_new@example.com'
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 204);
accountDB.verify();
});
});
it('rejects invalid email address', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
password: 'test',
updates: {
email: 'not!!valid'
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Invalid email address'
);
accountDB.verify();
});
});
it('rejects request to change email with no password', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
email: 'test_new@example.com'
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Password required'
);
accountDB.verify();
});
});
it('rejects invalid password', () => {
accountDB.expects('getByName').withArgs('test').returns({
name: 'test',
password: '$2a$10$c26sbtkVlYlFUBdSxzQGhenZvdPBI2fvTPOmVRyrBuaD.8j7iyoNm',
email: 'test@example.com',
profile: { text: 'blah', image: 'image.jpeg' },
time: new Date('2017-09-01T00:00:00.000Z')
});
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
password: 'wrong',
updates: {
email: 'test_new@example.com'
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Invalid password'
);
accountDB.verify();
});
});
it('rejects non-existing user', () => {
accountDB.expects('getByName').withArgs('test').returns(null);
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
password: 'test',
updates: {
email: 'test_new@example.com'
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'User does not exist'
);
accountDB.verify();
});
});
it('rejects invalid input', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: ['not correct']
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Malformed input'
);
accountDB.verify();
});
});
checkDefaults('/account/data/test', 'PATCH'); checkDefaults('/account/data/test', 'PATCH');
}); });
@ -281,6 +419,7 @@ describe('AccountDataRoute', () => {
); );
assert(verifySessionAsync.calledWith(signedCookies.auth)); assert(verifySessionAsync.calledWith(signedCookies.auth));
assert(csrfVerify.called); assert(csrfVerify.called);
channelDB.verify();
}); });
}); });