diff --git a/.eslintrc.json b/.eslintrc.json index d238f72b1b..7752baad06 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,6 +18,7 @@ "Dropbox": false, "SockJS": false, "marked": false, + "md5": false, "moment": false, "i18n": false, "DynamicText": false, diff --git a/frontend_tests/node_tests/people.js b/frontend_tests/node_tests/people.js index 8802f34fd8..d754b7928f 100644 --- a/frontend_tests/node_tests/people.js +++ b/frontend_tests/node_tests/people.js @@ -1,12 +1,13 @@ -add_dependencies({ - util: 'js/util.js', -}); +zrequire('util'); +zrequire('people'); -var people = require("js/people.js"); set_global('blueslip', { error: function () { return undefined; }, }); set_global('page_params', {}); +set_global('md5', function (s) { + return 'md5-' + s; +}); var _ = global._; @@ -393,6 +394,23 @@ initialize(); assert.equal(people.small_avatar_url(message), 'legacy.png&s=50'); + message = { + avatar_url: undefined, + sender_id: maria.user_id, + }; + assert.equal(people.small_avatar_url(message), + 'https://secure.gravatar.com/avatar/md5-athens@example.com?d=identicon&s=50' + ); + + message = { + avatar_url: undefined, + sender_email: 'foo@example.com', + sender_id: 9999999, + }; + assert.equal(people.small_avatar_url(message), + 'https://secure.gravatar.com/avatar/md5-foo@example.com?d=identicon&s=50' + ); + message = { type: 'private', display_recipient: [ diff --git a/package.json b/package.json index 7f9a5c4ac9..cbb2c2e3a1 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dependencies": { "@types/node": "8.0.34", "@types/webpack": "3.0.13", + "blueimp-md5": "2.10.0", "clipboard": "1.5.16", "emoji-datasource": "3.0.0", "emoji-datasource-apple": "3.0.0", diff --git a/static/js/people.js b/static/js/people.js index 2dfbd65ae6..9db02b7606 100644 --- a/static/js/people.js +++ b/static/js/people.js @@ -508,16 +508,31 @@ exports.small_avatar_url = function (message) { person = exports.get_person_from_user_id(message.sender_id); } + var email; + // The first time we encounter a sender in a message, we may // not have person.avatar_url set, but if we do, then use that. - if (person && person.avatar_url) { + if (person) { url = person.avatar_url; - } else if (message.avatar_url) { - // Here we fall back to using the avatar_url from the message - // itself. + email = person.email; + } + + // Try to get info from the message if we didn't have a `person` object + // or if the avatar was missing. We do this verbosely to avoid false + // positives on line coverage (we don't do branch checking). + if (!url) { url = message.avatar_url; } + if (!email) { + email = message.sender_email; + } + + if (!url) { + var hash = md5(email); + url = 'https://secure.gravatar.com/avatar/' + hash + '?d=identicon'; + } + if (url) { url = exports.format_small_avatar_url(url); } diff --git a/yarn.lock b/yarn.lock index d0194f1e7a..897cfef17f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -412,6 +412,10 @@ block-stream@*: dependencies: inherits "~2.0.0" +blueimp-md5@2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.10.0.tgz#02f0843921f90dca14f5b8920a38593201d6964d" + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.6, bn.js@^4.4.0: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" diff --git a/zproject/settings.py b/zproject/settings.py index 17f4796ca6..11ab7b886d 100644 --- a/zproject/settings.py +++ b/zproject/settings.py @@ -894,6 +894,7 @@ JS_SPECS = { 'third/bootstrap-notify/js/bootstrap-notify.js', 'third/html5-formdata/formdata.js', 'node_modules/jquery-validation/dist/jquery.validate.js', + 'node_modules/blueimp-md5/js/md5.js', 'node_modules/clipboard/dist/clipboard.js', 'third/jquery-form/jquery.form.js', 'third/jquery-filedrop/jquery.filedrop.js',