diff --git a/core/client/app/templates/settings/general.hbs b/core/client/app/templates/settings/general.hbs
index 305ab158b2..a5e2f76655 100644
--- a/core/client/app/templates/settings/general.hbs
+++ b/core/client/app/templates/settings/general.hbs
@@ -98,7 +98,7 @@
{{#if model.isPrivate}}
{{/if}}
diff --git a/core/server/config/index.js b/core/server/config/index.js
index 757efcea8a..bb99294350 100644
--- a/core/server/config/index.js
+++ b/core/server/config/index.js
@@ -206,7 +206,8 @@ ConfigManager.prototype.set = function (config) {
tag: 'tag',
author: 'author',
page: 'page',
- preview: 'p'
+ preview: 'p',
+ private: 'private'
},
slugs: {
// Used by generateSlug to generate slugs for posts, tags, users, ..
diff --git a/core/server/controllers/frontend.js b/core/server/controllers/frontend.js
index d29237f8b2..7af96a89a8 100644
--- a/core/server/controllers/frontend.js
+++ b/core/server/controllers/frontend.js
@@ -71,7 +71,8 @@ function setResponseContext(req, res, data) {
var contexts = [],
pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1,
tagPattern = new RegExp('^\\/' + config.routeKeywords.tag + '\\/'),
- authorPattern = new RegExp('^\\/' + config.routeKeywords.author + '\\/');
+ authorPattern = new RegExp('^\\/' + config.routeKeywords.author + '\\/'),
+ privatePattern = new RegExp('^\\/' + config.routeKeywords.private + '\\/');
// paged context
if (!isNaN(pageParam) && pageParam > 1) {
@@ -85,6 +86,8 @@ function setResponseContext(req, res, data) {
contexts.push('index');
} else if (/\/rss\/(:page\/)?$/.test(req.route.path)) {
contexts.push('rss');
+ } else if (privatePattern.test(req.route.path)) {
+ contexts.push('private');
} else if (tagPattern.test(req.route.path)) {
contexts.push('tag');
} else if (authorPattern.test(req.route.path)) {
@@ -137,7 +140,6 @@ function renderPost(req, res) {
response = formatResponse(post);
setResponseContext(req, res, response);
-
res.render(view, response);
});
};
@@ -406,16 +408,16 @@ frontendControllers = {
},
rss: rss,
private: function (req, res) {
- var defaultPage = path.resolve(config.paths.adminViews, 'password.hbs');
+ var defaultPage = path.resolve(config.paths.adminViews, 'private.hbs');
return getActiveThemePaths().then(function (paths) {
- var data = {
- forward: req.query.r
- };
+ var data = {};
if (res.error) {
data.error = res.error;
}
- if (paths.hasOwnProperty('password.hbs')) {
- return res.render('password', data);
+
+ setResponseContext(req, res);
+ if (paths.hasOwnProperty('private.hbs')) {
+ return res.render('private', data);
} else {
return res.render(defaultPage, data);
}
diff --git a/core/server/helpers/index.js b/core/server/helpers/index.js
index f522b2d8c4..5f75a3c97d 100644
--- a/core/server/helpers/index.js
+++ b/core/server/helpers/index.js
@@ -23,22 +23,25 @@ coreHelpers.excerpt = require('./excerpt');
coreHelpers.foreach = require('./foreach');
coreHelpers.ghost_foot = require('./ghost_foot');
coreHelpers.ghost_head = require('./ghost_head');
+coreHelpers.image = require('./image');
coreHelpers.is = require('./is');
coreHelpers.has = require('./has');
coreHelpers.meta_description = require('./meta_description');
coreHelpers.meta_title = require('./meta_title');
coreHelpers.navigation = require('./navigation');
-coreHelpers.page_url = require('./page_url');
-coreHelpers.pageUrl = require('./page_url').deprecated;
coreHelpers.pagination = require('./pagination');
coreHelpers.plural = require('./plural');
coreHelpers.post_class = require('./post_class');
+coreHelpers.prev_post = require('./prev_next');
+coreHelpers.next_post = require('./prev_next');
coreHelpers.tags = require('./tags');
coreHelpers.title = require('./title');
coreHelpers.url = require('./url');
-coreHelpers.image = require('./image');
-coreHelpers.prev_post = require('./prev_next');
-coreHelpers.next_post = require('./prev_next');
+
+// Specialist helpers for certain templates
+coreHelpers.input_password = require('./input_password');
+coreHelpers.page_url = require('./page_url');
+coreHelpers.pageUrl = require('./page_url').deprecated;
coreHelpers.helperMissing = function (arg) {
if (arguments.length === 2) {
@@ -94,6 +97,7 @@ registerHelpers = function (adminHbs) {
registerThemeHelper('excerpt', coreHelpers.excerpt);
registerThemeHelper('foreach', coreHelpers.foreach);
registerThemeHelper('is', coreHelpers.is);
+ registerThemeHelper('input_password', coreHelpers.input_password);
registerThemeHelper('has', coreHelpers.has);
registerThemeHelper('navigation', coreHelpers.navigation);
registerThemeHelper('page_url', coreHelpers.page_url);
@@ -116,6 +120,7 @@ registerHelpers = function (adminHbs) {
// Register admin helpers
registerAdminHelper('asset', coreHelpers.asset);
+ registerAdminHelper('input_password', coreHelpers.input_password);
};
module.exports = coreHelpers;
diff --git a/core/server/helpers/input_password.js b/core/server/helpers/input_password.js
new file mode 100644
index 0000000000..445e24c1db
--- /dev/null
+++ b/core/server/helpers/input_password.js
@@ -0,0 +1,24 @@
+// # Input Password Helper
+// Usage: `{{input_password}}`
+//
+// Password input used on private.hbs for password-protected blogs
+//
+// We use the name meta_title to match the helper for consistency:
+// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
+
+var hbs = require('express-hbs'),
+ utils = require('./utils'),
+ input_password;
+
+input_password = function () {
+ var output = utils.inputTemplate({
+ type: 'password',
+ name: 'password',
+ className: 'private-login-password',
+ extras: 'autofocus="autofocus"'
+ });
+
+ return new hbs.handlebars.SafeString(output);
+};
+
+module.exports = input_password;
diff --git a/core/server/helpers/utils.js b/core/server/helpers/utils.js
index 457ed0e6aa..2d828a2073 100644
--- a/core/server/helpers/utils.js
+++ b/core/server/helpers/utils.js
@@ -5,6 +5,7 @@ utils = {
assetTemplate: _.template('<%= source %>?v=<%= version %>'),
linkTemplate: _.template('<%= text %> '),
scriptTemplate: _.template(''),
+ inputTemplate: _.template(' />'),
isProduction: process.env.NODE_ENV === 'production'
};
diff --git a/core/server/middleware/middleware.js b/core/server/middleware/middleware.js
index c3101f1517..09e14d5897 100644
--- a/core/server/middleware/middleware.js
+++ b/core/server/middleware/middleware.js
@@ -395,7 +395,7 @@ middleware = {
if (isVerified) {
return next();
} else {
- return res.redirect(config.urlFor({relativeUrl: '/private/'}) + '?r=' + encodeURI(req.url));
+ return res.redirect(config.urlFor({relativeUrl: '/private/'}) + '?r=' + encodeURIComponent(req.url));
}
});
},
@@ -470,14 +470,15 @@ middleware = {
return api.settings.read({context: {internal: true}, key: 'password'}).then(function (response) {
var pass = response.settings[0],
hasher = crypto.createHash('sha256'),
- salt = Date.now().toString();
+ salt = Date.now().toString(),
+ forward = req.query && req.query.r ? req.query.r : '/';
if (pass.value === bodyPass) {
hasher.update(bodyPass + salt, 'utf8');
req.session.token = hasher.digest('hex');
req.session.salt = salt;
- return res.redirect(config.urlFor({relativeUrl: decodeURI(req.body.forward)}));
+ return res.redirect(config.urlFor({relativeUrl: decodeURIComponent(forward)}));
} else {
res.error = {
message: 'Wrong password'
diff --git a/core/server/routes/frontend.js b/core/server/routes/frontend.js
index 597ad6a584..b92b9067cc 100644
--- a/core/server/routes/frontend.js
+++ b/core/server/routes/frontend.js
@@ -29,11 +29,11 @@ frontendRoutes = function (middleware) {
});
// password-protected frontend route
- router.get('/private/',
+ router.get('/' + routeKeywords.private + '/',
middleware.isPrivateSessionAuth,
frontend.private
);
- router.post('/private/',
+ router.post('/' + routeKeywords.private + '/',
middleware.isPrivateSessionAuth,
middleware.spamProtectedPrevention,
middleware.authenticateProtection,
diff --git a/core/server/views/password.hbs b/core/server/views/private.hbs
similarity index 84%
rename from core/server/views/password.hbs
rename to core/server/views/private.hbs
index 7ca982515b..9de3177fc8 100644
--- a/core/server/views/password.hbs
+++ b/core/server/views/private.hbs
@@ -7,8 +7,6 @@
Ghost - Private Blog Access
-
-
@@ -26,10 +24,9 @@