Support updating profile via /account/data

This commit is contained in:
Calvin Montgomery 2017-09-06 22:53:34 -07:00
parent 9e3426633d
commit 4db78deda3
2 changed files with 187 additions and 0 deletions

View File

@ -44,6 +44,15 @@ class AccountController {
requirePassword = true; requirePassword = true;
} }
if (updates.profile) {
validateProfile(updates.profile);
fields.profile = {
image: updates.profile.image.trim(),
text: updates.profile.text
};
}
if (requirePassword) { if (requirePassword) {
if (!password) { if (!password) {
throw new InvalidRequestError('Password required'); throw new InvalidRequestError('Password required');
@ -67,4 +76,28 @@ class AccountController {
} }
} }
function validateProfile(profile) {
// TODO: replace all of these errors with a standard errorcode + field checker
if (profile.toString() !== '[object Object]')
throw new InvalidRequestError('Invalid profile');
if (typeof profile.text !== 'string')
throw new InvalidRequestError('Invalid profile');
if (typeof profile.image !== 'string')
throw new InvalidRequestError('Invalid profile');
if (profile.text.length > 255)
throw new InvalidRequestError('Profile text must not exceed 255 characters');
if (profile.image.length > 255)
throw new InvalidRequestError('Profile image URL must not exceed 255 characters');
if (profile.image.trim() === '') return true;
const url = parseURL(profile.image);
if (!url.host)
throw new InvalidRequestError('Invalid profile image URL');
if (url.protocol !== 'https:')
throw new InvalidRequestError('Profile image URL must start with "https:"');
return true;
}
export { AccountController }; export { AccountController };

View File

@ -278,6 +278,33 @@ describe('AccountDataRoute', () => {
}); });
}); });
it('updates profile', () => {
accountDB.expects('updateByName').withArgs(
'test',
{
profile: {
text: 'testing',
image: 'https://example.com/image.jpg'
}
}
);
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
profile: {
text: 'testing',
image: 'https://example.com/image.jpg'
}
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 204);
accountDB.verify();
});
});
it('rejects invalid email address', () => { it('rejects invalid email address', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, { return request('PATCH', `${URL_BASE}/account/data/test`, {
body: { body: {
@ -377,6 +404,133 @@ describe('AccountDataRoute', () => {
}); });
}); });
it('rejects invalid profile', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
profile: 'not valid'
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Invalid profile'
);
accountDB.verify();
});
});
it('rejects wrongly typed profile text', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
profile: {
text: ['wrong'],
image: 'https://example.com'
}
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Invalid profile'
);
accountDB.verify();
});
});
it('rejects too long profile text', () => {
let longText = ''; for (let i = 0; i < 256; i++) longText += 'a';
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
profile: {
text: longText,
image: 'https://example.com'
}
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Profile text must not exceed 255 characters'
);
accountDB.verify();
});
});
it('rejects wrongly typed profile image', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
profile: {
text: 'test',
image: 42
}
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Invalid profile'
);
accountDB.verify();
});
});
it('rejects too long profile image', () => {
let longText = 'https://'; for (let i = 0; i < 256; i++) longText += 'a';
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
profile: {
text: 'test',
image: longText
}
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Profile image URL must not exceed 255 characters'
);
accountDB.verify();
});
});
it('rejects non-https profile image', () => {
return request('PATCH', `${URL_BASE}/account/data/test`, {
body: {
updates: {
profile: {
text: 'test',
image: 'http://example.com/image.jpg'
}
}
}
}).then(res => {
assert.strictEqual(res.statusCode, 400);
assert.strictEqual(
JSON.parse(res.body).error,
'Profile image URL must start with "https:"'
);
accountDB.verify();
});
});
checkDefaults('/account/data/test', 'PATCH'); checkDefaults('/account/data/test', 'PATCH');
}); });