mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-24 19:33:02 +03:00
Added gravatar URL to config to make it configurable (#14490)
refs https://github.com/TryGhost/Toolbox/issues/288 - Allows switching out the Gravatar URL to use placeholder images when working with mocked demo data
This commit is contained in:
parent
cb80be3d0c
commit
62164ecdf2
@ -1,5 +1,6 @@
|
||||
const Promise = require('bluebird');
|
||||
const crypto = require('crypto');
|
||||
const tpl = require('@tryghost/tpl');
|
||||
|
||||
class Gravatar {
|
||||
constructor({config, request}) {
|
||||
@ -7,21 +8,36 @@ class Gravatar {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
url(email, options) {
|
||||
if (options.default) {
|
||||
// tpl errors on token `{default}` so we use `{_default}` instead
|
||||
// but still allow the option to be passed as `default`
|
||||
options._default = options.default;
|
||||
}
|
||||
const defaultOptions = {
|
||||
size: 250,
|
||||
_default: 'blank',
|
||||
rating: 'g'
|
||||
};
|
||||
const emailHash = crypto.createHash('md5').update(email.toLowerCase().trim()).digest('hex');
|
||||
const gravatarUrl = this.config.get('gravatar').url;
|
||||
return tpl(gravatarUrl, Object.assign(defaultOptions, options, {hash: emailHash}));
|
||||
}
|
||||
|
||||
lookup(userData, timeout) {
|
||||
let gravatarUrl = '//www.gravatar.com/avatar/' +
|
||||
crypto.createHash('md5').update(userData.email.toLowerCase().trim()).digest('hex') +
|
||||
'?s=250';
|
||||
|
||||
if (this.config.isPrivacyDisabled('useGravatar')) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return Promise.resolve(this.request('https:' + gravatarUrl + '&d=404&r=x', {timeout: timeout || 2 * 1000}))
|
||||
|
||||
// test existence using a default 404, but return a different default
|
||||
// so we still have a fallback if the image gets removed from Gravatar
|
||||
const testUrl = this.url(userData.email, {default: 404, rating: 'x'});
|
||||
const imageUrl = this.url(userData.email, {default: 'mp', rating: 'x'});
|
||||
|
||||
return Promise.resolve(this.request(testUrl, {timeout: timeout || 2 * 1000}))
|
||||
.then(function () {
|
||||
gravatarUrl += '&d=mm&r=x';
|
||||
|
||||
return {
|
||||
image: gravatarUrl
|
||||
image: imageUrl
|
||||
};
|
||||
})
|
||||
.catch({statusCode: 404}, function () {
|
||||
|
@ -2,7 +2,7 @@ const ghostBookshelf = require('./base');
|
||||
const uuid = require('uuid');
|
||||
const _ = require('lodash');
|
||||
const config = require('../../shared/config');
|
||||
const crypto = require('crypto');
|
||||
const {gravatar} = require('../lib/image');
|
||||
|
||||
const Member = ghostBookshelf.Model.extend({
|
||||
tableName: 'members',
|
||||
@ -311,8 +311,7 @@ const Member = ghostBookshelf.Model.extend({
|
||||
// Will not use gravatar if privacy.useGravatar is false in config
|
||||
attrs.avatar_image = null;
|
||||
if (attrs.email && !config.isPrivacyDisabled('useGravatar')) {
|
||||
const emailHash = crypto.createHash('md5').update(attrs.email.toLowerCase().trim()).digest('hex');
|
||||
attrs.avatar_image = `https://gravatar.com/avatar/${emailHash}?s=250&d=blank`;
|
||||
attrs.avatar_image = gravatar.url(attrs.email, {size: 250, default: 'blank'});
|
||||
}
|
||||
|
||||
return attrs;
|
||||
|
@ -140,5 +140,8 @@
|
||||
},
|
||||
"twitter": {
|
||||
"privateReadOnlyToken": null
|
||||
},
|
||||
"gravatar": {
|
||||
"url": "https://www.gravatar.com/avatar/{hash}?s={size}&r={rating}&d={_default}"
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,38 @@ const should = require('should');
|
||||
const Gravatar = require('../../../../../core/server/lib/image/gravatar');
|
||||
|
||||
describe('lib/image: gravatar', function () {
|
||||
const gravatarUrl = 'https://www.gravatar.com/avatar/{hash}?s={size}&r={rating}&d={_default}';
|
||||
|
||||
it('can build a gravatar url', function () {
|
||||
const gravatar = new Gravatar({config: {
|
||||
isPrivacyDisabled: () => false,
|
||||
get: (config) => {
|
||||
return config === 'gravatar' ? {
|
||||
url: gravatarUrl
|
||||
} : null;
|
||||
}
|
||||
}, request: () => {}});
|
||||
|
||||
gravatar.url('exists@example.com', {
|
||||
size: 180,
|
||||
rating: 'r'
|
||||
}).should.eql('https://www.gravatar.com/avatar/ef6dcde5c99bb8f685dd451ccc3e050a?s=180&r=r&d=blank');
|
||||
});
|
||||
|
||||
it('can successfully lookup a gravatar url', function (done) {
|
||||
const gravatar = new Gravatar({config: {
|
||||
isPrivacyDisabled: () => false
|
||||
isPrivacyDisabled: () => false,
|
||||
get: (config) => {
|
||||
return config === 'gravatar' ? {
|
||||
url: gravatarUrl
|
||||
} : null;
|
||||
}
|
||||
}, request: () => {}});
|
||||
|
||||
gravatar.lookup({email: 'exists@example.com'}).then(function (result) {
|
||||
should.exist(result);
|
||||
should.exist(result.image);
|
||||
result.image.should.eql('//www.gravatar.com/avatar/ef6dcde5c99bb8f685dd451ccc3e050a?s=250&d=mm&r=x');
|
||||
result.image.should.eql('https://www.gravatar.com/avatar/ef6dcde5c99bb8f685dd451ccc3e050a?s=250&r=x&d=mp');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
@ -18,7 +41,12 @@ describe('lib/image: gravatar', function () {
|
||||
|
||||
it('can handle a non existant gravatar', function (done) {
|
||||
const gravatar = new Gravatar({config: {
|
||||
isPrivacyDisabled: () => false
|
||||
isPrivacyDisabled: () => false,
|
||||
get: (config) => {
|
||||
return config === 'gravatar' ? {
|
||||
url: gravatarUrl
|
||||
} : null;
|
||||
}
|
||||
}, request: () => {
|
||||
return Promise.reject({statusCode: 404});
|
||||
}});
|
||||
@ -34,7 +62,12 @@ describe('lib/image: gravatar', function () {
|
||||
it('will timeout', function () {
|
||||
const delay = 42;
|
||||
const gravatar = new Gravatar({config: {
|
||||
isPrivacyDisabled: () => false
|
||||
isPrivacyDisabled: () => false,
|
||||
get: (config) => {
|
||||
return config === 'gravatar' ? {
|
||||
url: gravatarUrl
|
||||
} : null;
|
||||
}
|
||||
}, request: (url, options) => {
|
||||
options.timeout.should.eql(delay);
|
||||
}});
|
||||
|
@ -35,7 +35,7 @@ describe('Unit: models/member', function () {
|
||||
config.set('privacy:useGravatar', true);
|
||||
const json = toJSON(member);
|
||||
|
||||
json.avatar_image.should.eql(`https://gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s=250&d=blank`);
|
||||
json.avatar_image.should.eql(`https://www.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s=250&r=g&d=blank`);
|
||||
});
|
||||
|
||||
it('avatar_image: skips gravatar when privacy.useGravatar=false', function () {
|
||||
|
Loading…
Reference in New Issue
Block a user