More consistant usage of urlFor('home') (#7689)

refs #7666 

Using `urlFor('home')` instead `config.get('url')` in Ghost.
When `urlFor('home', true)` returns the absolute adress of the blog as defined in the config.
Will always return a trailing `/`.
This commit is contained in:
Aileen Nowak 2017-01-23 15:22:37 +07:00 committed by Katharina Irrgang
parent 857ad4f1a7
commit 503148058c
17 changed files with 67 additions and 37 deletions

View File

@ -216,8 +216,8 @@ authentication = {
}
function sendResetNotification(data) {
var baseUrl = config.get('forceAdminSSL') ? (config.get('urlSSL') || config.get('url')) : config.get('url'),
resetUrl = globalUtils.url.urlJoin(baseUrl, 'ghost/reset', globalUtils.encodeBase64URLsafe(data.resetToken), '/');
var baseUrl = config.get('forceAdminSSL') ? globalUtils.url.urlFor('home', {secure: true}, true) : globalUtils.url.urlFor('home', true),
resetUrl = globalUtils.url.urlJoin(baseUrl, '/ghost/reset/', globalUtils.encodeBase64URLsafe(data.resetToken), '/');
return mail.utils.generateContent({
data: {

View File

@ -5,6 +5,7 @@ var _ = require('lodash'),
ghostVersion = require('../utils/ghost-version'),
models = require('../models'),
Promise = require('bluebird'),
utils = require('../utils'),
configuration;
@ -27,7 +28,7 @@ function getBaseConfig() {
fileStorage: config.get('fileStorage') !== false,
useGravatar: !config.isPrivacyDisabled('useGravatar'),
publicAPI: config.get('publicAPI') === true,
blogUrl: config.get('url').replace(/\/$/, ''),
blogUrl: utils.url.urlFor('home', true),
blogTitle: config.get('theme').title,
routeKeywords: config.get('routeKeywords')
};

View File

@ -106,7 +106,7 @@ invites = {
return settings.read({key: 'title'});
})
.then(function (response) {
var baseUrl = config.get('forceAdminSSL') ? (config.get('urlSSL') || config.get('url')) : config.get('url');
var baseUrl = config.get('forceAdminSSL') ? globalUtils.url.urlFor('home', {secure: true}, true) : globalUtils.url.urlFor('home', true);
emailData = {
blogName: response.settings[0].value,

View File

@ -9,7 +9,7 @@ var _ = require('lodash'),
logging = require('../logging'),
utils = require('./utils'),
i18n = require('../i18n'),
generalUtils = require('../utils'),
globalUtils = require('../utils'),
docName = 'settings',
settings,
@ -65,7 +65,7 @@ updateConfigCache = function () {
config.set('theme:twitter', (settingsCache.twitter && settingsCache.twitter.value) || '');
config.set('theme:facebook', (settingsCache.facebook && settingsCache.facebook.value) || '');
config.set('theme:timezone', (settingsCache.activeTimezone && settingsCache.activeTimezone.value) || config.get('theme').timezone);
config.set('theme:url', config.get('url') ? generalUtils.url.urlJoin(config.get('url'), '/') : '');
config.set('theme:url', globalUtils.url.urlFor('home', true));
config.set('theme:amp', (settingsCache.amp && settingsCache.amp.value === 'true'));
_.each(labsValue, function (value, key) {

View File

@ -11,11 +11,11 @@ var hbs = require('express-hbs'),
Amperize = require('amperize'),
moment = require('moment'),
sanitizeHtml = require('sanitize-html'),
config = require('../../../../config'),
logging = require('../../../../logging'),
i18n = require('../../../../i18n'),
errors = require('../../../../errors'),
makeAbsoluteUrl = require('../../../../utils/make-absolute-urls'),
utils = require('../../../../utils'),
cheerio = require('cheerio'),
amperize = new Amperize(),
amperizeCache = {},
@ -121,7 +121,7 @@ function getAmperizeHTML(html, post) {
}
// make relative URLs abolute
html = makeAbsoluteUrl(html, config.get('url'), post.url).html();
html = makeAbsoluteUrl(html, utils.url.urlFor('home', true), post.url).html();
if (!amperizeCache[post.id] || moment(new Date(amperizeCache[post.id].updated_at)).diff(new Date(post.updated_at)) < 0) {
return new Promise(function (resolve) {

View File

@ -4,7 +4,6 @@
// We use the name subscribe_form to match the helper for consistency:
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
var _ = require('lodash'),
path = require('path'),
// Dirty requires
hbs = require('express-hbs'),
@ -43,7 +42,7 @@ subscribeScript =
subscribe_form = function (options) {
var root = options.data.root,
data = _.merge({}, options.hash, _.pick(root, params), {
action: path.join('/', globalUtils.url.getSubdir(), config.get('routeKeywords').subscribe, '/'),
action: globalUtils.url.urlJoin('/', globalUtils.url.getSubdir(), config.get('routeKeywords').subscribe, '/'),
script: new hbs.handlebars.SafeString(subscribeScript),
hidden: new hbs.handlebars.SafeString(
makeHidden('confirm') +

View File

@ -8,6 +8,7 @@ var debug = require('debug')('ghost:server'),
_ = require('lodash'),
errors = require('./errors'),
config = require('./config'),
utils = require('./utils'),
i18n = require('./i18n'),
moment = require('moment');
@ -202,7 +203,7 @@ GhostServer.prototype.logStartMessages = function () {
chalk.green(i18n.t('notices.httpServer.ghostIsRunningIn', {env: process.env.NODE_ENV})),
i18n.t('notices.httpServer.listeningOn'),
config.get('server').socket || config.get('server').host + ':' + config.get('server').port,
i18n.t('notices.httpServer.urlConfiguredAs', {url: config.get('url')}),
i18n.t('notices.httpServer.urlConfiguredAs', {url: utils.url.urlFor('home', true)}),
chalk.gray(i18n.t('notices.httpServer.ctrlCToShutDown'))
);
}

View File

@ -1,7 +1,8 @@
var config = require('../config'),
GhostLogger = require('./GhostLogger'),
utils = require('../utils'),
adapter = new GhostLogger({
domain: config.get('url').replace(/[^\w]/gi, '_'),
domain: utils.url.urlFor('home', true).replace(/[^\w]/gi, '_'),
env: config.get('env'),
mode: process.env.NODE_MODE || process.env.MODE || config.get('logging:mode'),
level: process.env.NODE_LEVEL || process.env.LEVEL || config.get('logging:level'),

View File

@ -5,7 +5,8 @@ var _ = require('lodash'),
nodemailer = require('nodemailer'),
validator = require('validator'),
config = require('../config'),
i18n = require('../i18n');
i18n = require('../i18n'),
utils = require('../utils');
function GhostMailer() {
var transport = config.get('mail') && config.get('mail').transport || 'direct',
@ -40,7 +41,7 @@ GhostMailer.prototype.from = function () {
// Moved it to its own module
GhostMailer.prototype.getDomain = function () {
var domain = config.get('url').match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
var domain = utils.url.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
return domain && domain[1];
};

View File

@ -4,6 +4,7 @@ var _ = require('lodash').runInContext(),
path = require('path'),
htmlToText = require('html-to-text'),
config = require('../config'),
utils = require('../utils'),
templatesDir = path.resolve(__dirname, '..', 'mail', 'templates');
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
@ -13,7 +14,7 @@ exports.generateContent = function generateContent(options) {
data;
defaults = {
siteUrl: config.get('forceAdminSSL') ? (config.get('urlSSL') || config.get('url')) : config.get('url')
siteUrl: config.get('forceAdminSSL') ? utils.url.urlFor('home', {secure: true}, true) : utils.url.urlFor('home', true)
};
data = _.defaults(defaults, options.data);

View File

@ -2,6 +2,7 @@ var cors = require('cors'),
_ = require('lodash'),
url = require('url'),
os = require('os'),
utils = require('../../utils'),
config = require('../../config'),
whitelist = [],
ENABLE_CORS = {origin: true, maxAge: 86400},
@ -32,7 +33,7 @@ function getIPs() {
}
function getUrls() {
var urls = [url.parse(config.get('url')).hostname];
var urls = [url.parse(utils.url.urlFor('home', true)).hostname];
if (config.get('urlSSL')) {
urls.push(url.parse(config.get('urlSSL')).hostname);

View File

@ -1,5 +1,6 @@
var config = require('../config'),
url = require('url'),
utils = require('../utils'),
checkSSL;
function isSSLrequired(isAdmin, configUrl, forceAdminSSL) {
@ -38,12 +39,12 @@ function sslForbiddenOrRedirect(opt) {
// Check to see if we should use SSL
// and redirect if needed
checkSSL = function checkSSL(req, res, next) {
if (isSSLrequired(res.isAdmin, config.get('url'), config.get('forceAdminSSL'))) {
if (isSSLrequired(res.isAdmin, utils.url.urlFor('home', true), config.get('forceAdminSSL'))) {
if (!req.secure) {
var response = sslForbiddenOrRedirect({
forceAdminSSL: config.get('forceAdminSSL'),
configUrlSSL: config.get('urlSSL'),
configUrl: config.get('url'),
configUrl: utils.url.urlFor('home', true),
reqUrl: req.originalUrl || req.url
});

View File

@ -27,7 +27,7 @@ function serveSharedFile(file, type, maxAge) {
}
if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') {
buf = buf.toString().replace(blogRegex, config.get('url').replace(/\/$/, ''));
buf = buf.toString().replace(blogRegex, utils.url.urlFor('home', true).replace(/\/$/, ''));
buf = buf.toString().replace(apiRegex, utils.url.apiUrl({cors: true}));
}
content = {

View File

@ -30,6 +30,7 @@ var crypto = require('crypto'),
url = require('url'),
api = require('./api'),
config = require('./config'),
utils = require('./utils'),
logging = require('./logging'),
errors = require('./errors'),
i18n = require('./i18n'),
@ -116,7 +117,7 @@ function updateCheckData() {
posts = descriptors.posts.value(),
users = descriptors.users.value(),
npm = descriptors.npm.value(),
blogUrl = url.parse(config.get('url')),
blogUrl = url.parse(utils.url.urlFor('home', true)),
blogId = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value;
data.blog_id = crypto.createHash('md5').update(blogId).digest('hex');

View File

@ -8,18 +8,38 @@ var moment = require('moment-timezone'),
// @TODO: unify this with routes.apiBaseUrl
apiPath = '/ghost/api/v0.1';
/** getBaseUrl
* Returns the base URL of the blog as set in the config. If called with secure options, returns the ssl URL.
* @param {boolean} secure
* @return {string} URL returns the url as defined in config, but always with a trailing `/`
*/
function getBaseUrl(secure) {
var base;
// CASE: a specified SSL URL is configured (e. g. https://secure.blog.org/)
// see: https://github.com/TryGhost/Ghost/issues/6270#issuecomment-168939865
if (secure && config.get('urlSSL')) {
return config.get('urlSSL');
base = config.get('urlSSL');
} else {
// CASE: no specified SSL URL configured, but user request is secure. In this case we force SSL
// and therefore replace the protocol.
if (secure) {
return config.get('url').replace('http://', 'https://');
base = config.get('url').replace('http://', 'https://');
} else {
return config.get('url');
base = config.get('url');
}
}
if (!base.match(/\/$/)) {
base += '/';
}
return base;
}
/** getSubdir
* Returns a subdirectory URL, if defined so in the config.
* @return {string} URL a subdirectory if configured.
*/
function getSubdir() {
var localPath, subdir;
@ -47,14 +67,11 @@ function getProtectedSlugs() {
}
}
// ## urlJoin
// concats arguments to a path/URL
// Usage:
// urlJoin(getBaseUrl(), 'content', '/') -> http://my-ghost-blog.com/content/
// Returns a URL or relative path
// Only to use for Ghost URLs and paths
// TODO: urlJoin needs to be optimised and to validate the URL/path properly.
// e. g. URLs should end with a trailing `/` at the end of the pathname.
/** urlJoin
* Returns a URL/path for internal use in Ghost.
* @param {string} arguments takes arguments and concats those to a valid path/URL.
* @return {string} URL concatinated URL/path of arguments.
*/
function urlJoin() {
var args = Array.prototype.slice.call(arguments),
prefixDoubleSlash = false,
@ -245,6 +262,8 @@ function urlFor(context, data, absolute) {
absolute = true;
}
}
} else if (context === 'home' && absolute) {
urlPath = getBaseUrl(secure);
// other objects are recognised but not yet supported
} else if (_.isString(context) && _.indexOf(_.keys(knownPaths), context) !== -1) {
// trying to create a url for a named path
@ -273,7 +292,7 @@ function apiUrl(options) {
var url;
if (config.get('forceAdminSSL')) {
url = (config.get('urlSSL') || config.get('url')).replace(/^.*?:\/\//g, 'https://');
url = (config.get('urlSSL') || getBaseUrl(true)).replace(/^.*?:\/\//g, 'https://');
} else if (config.get('urlSSL')) {
url = config.get('urlSSL').replace(/^.*?:\/\//g, 'https://');
} else if (config.get('url').match(/^https:/)) {

View File

@ -28,7 +28,7 @@ describe('Configuration API', function () {
response.configuration.should.be.an.Array().with.lengthOf(1);
props = response.configuration[0];
props.blogUrl.should.eql('http://127.0.0.1:2369');
props.blogUrl.should.eql('http://127.0.0.1:2369/');
props.routeKeywords.should.eql({
tag: 'tag',
author: 'author',

View File

@ -100,21 +100,25 @@ describe('Url', function () {
it('should return home url when asked for', function () {
var testContext = 'home';
configUtils.set({url: 'http://my-ghost-blog.com'});
configUtils.set({url: 'http://my-ghost-blog.com', urlSSL: 'https://my-ghost-blog.com'});
utils.url.urlFor(testContext).should.equal('/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/');
configUtils.set({url: 'http://my-ghost-blog.com/'});
configUtils.set({url: 'http://my-ghost-blog.com/', urlSSL: 'https://my-ghost-blog.com/'});
utils.url.urlFor(testContext).should.equal('/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/');
configUtils.set({url: 'http://my-ghost-blog.com/blog'});
configUtils.set({url: 'http://my-ghost-blog.com/blog', urlSSL: 'https://my-ghost-blog.com/blog'});
utils.url.urlFor(testContext).should.equal('/blog/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/blog/');
configUtils.set({url: 'http://my-ghost-blog.com/blog/'});
configUtils.set({url: 'http://my-ghost-blog.com/blog/', urlSSL: 'https://my-ghost-blog.com/blog/'});
utils.url.urlFor(testContext).should.equal('/blog/');
utils.url.urlFor(testContext, true).should.equal('http://my-ghost-blog.com/blog/');
utils.url.urlFor(testContext, {secure: true}, true).should.equal('https://my-ghost-blog.com/blog/');
});
it('should return rss url when asked for', function () {