mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-01 02:41:39 -05:00
parent
7e17c56feb
commit
006c83fbe4
36 changed files with 424 additions and 420 deletions
|
@ -1,22 +1,22 @@
|
|||
const debug = require('ghost-ignition').debug('admin'),
|
||||
express = require('express'),
|
||||
const debug = require('ghost-ignition').debug('admin');
|
||||
const express = require('express');
|
||||
|
||||
// App requires
|
||||
config = require('../../config'),
|
||||
constants = require('../../lib/constants'),
|
||||
urlService = require('../../services/url'),
|
||||
// App requires
|
||||
const config = require('../../config');
|
||||
const constants = require('../../lib/constants');
|
||||
const urlService = require('../../services/url');
|
||||
|
||||
// Middleware
|
||||
// Admin only middleware
|
||||
adminMiddleware = require('./middleware'),
|
||||
serveStatic = require('express').static,
|
||||
// Middleware
|
||||
// Admin only middleware
|
||||
const adminMiddleware = require('./middleware');
|
||||
const serveStatic = require('express').static;
|
||||
|
||||
// Global/shared middleware
|
||||
cacheControl = require('../middleware/cache-control'),
|
||||
urlRedirects = require('../middleware/url-redirects'),
|
||||
errorHandler = require('../middleware/error-handler'),
|
||||
maintenance = require('../middleware/maintenance'),
|
||||
prettyURLs = require('../middleware/pretty-urls');
|
||||
// Global/shared middleware
|
||||
const cacheControl = require('../middleware/cache-control');
|
||||
const urlRedirects = require('../middleware/url-redirects');
|
||||
const errorHandler = require('../middleware/error-handler');
|
||||
const maintenance = require('../middleware/maintenance');
|
||||
const prettyURLs = require('../middleware/pretty-urls');
|
||||
|
||||
module.exports = function setupAdminApp() {
|
||||
debug('Admin setup start');
|
||||
|
@ -42,7 +42,7 @@ module.exports = function setupAdminApp() {
|
|||
|
||||
// Ember CLI's live-reload script
|
||||
if (config.get('env') === 'development') {
|
||||
adminApp.get('/ember-cli-live-reload.js', function (req, res) {
|
||||
adminApp.get('/ember-cli-live-reload.js', function emberLiveReload(req, res) {
|
||||
res.redirect(`http://localhost:4200${urlService.utils.getSubdir()}/ghost/ember-cli-live-reload.js`);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const debug = require('ghost-ignition').debug('admin:controller'),
|
||||
path = require('path'),
|
||||
config = require('../../config'),
|
||||
updateCheck = require('../../update-check'),
|
||||
common = require('../../lib/common');
|
||||
const debug = require('ghost-ignition').debug('admin:controller');
|
||||
const path = require('path');
|
||||
const config = require('../../config');
|
||||
const updateCheck = require('../../update-check');
|
||||
const common = require('../../lib/common');
|
||||
|
||||
// Route: index
|
||||
// Path: /ghost/
|
||||
|
@ -12,12 +12,12 @@ module.exports = function adminController(req, res) {
|
|||
|
||||
// run in background, don't block the admin rendering
|
||||
updateCheck()
|
||||
.catch(function onError(err) {
|
||||
.catch((err) => {
|
||||
common.logging.error(err);
|
||||
});
|
||||
|
||||
let defaultTemplate = config.get('env') === 'production' ? 'default-prod.html' : 'default.html',
|
||||
templatePath = path.resolve(config.get('paths').adminViews, defaultTemplate);
|
||||
const defaultTemplate = config.get('env') === 'production' ? 'default-prod.html' : 'default.html';
|
||||
const templatePath = path.resolve(config.get('paths').adminViews, defaultTemplate);
|
||||
|
||||
res.sendFile(templatePath);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const debug = require('ghost-ignition').debug('admin:serviceworker'),
|
||||
path = require('path');
|
||||
const debug = require('ghost-ignition').debug('admin:serviceworker');
|
||||
const path = require('path');
|
||||
|
||||
// Route: index
|
||||
// Path: /ghost/sw.js|sw-registration.js
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
// # API routes
|
||||
const debug = require('ghost-ignition').debug('api'),
|
||||
boolParser = require('express-query-boolean'),
|
||||
express = require('express'),
|
||||
const debug = require('ghost-ignition').debug('api');
|
||||
const boolParser = require('express-query-boolean');
|
||||
const express = require('express');
|
||||
|
||||
// routes
|
||||
routes = require('./routes'),
|
||||
// routes
|
||||
const routes = require('./routes');
|
||||
|
||||
// Include the middleware
|
||||
// Include the middleware
|
||||
|
||||
// API specific
|
||||
versionMatch = require('../../middleware/api/version-match'), // global
|
||||
// API specific
|
||||
const versionMatch = require('../../middleware/api/version-match'); // global
|
||||
|
||||
// Shared
|
||||
bodyParser = require('body-parser'), // global, shared
|
||||
cacheControl = require('../../middleware/cache-control'), // global, shared
|
||||
maintenance = require('../../middleware/maintenance'), // global, shared
|
||||
errorHandler = require('../../middleware/error-handler'); // global, shared
|
||||
// Shared
|
||||
const bodyParser = require('body-parser'); // global, shared
|
||||
const cacheControl = require('../../middleware/cache-control'); // global, shared
|
||||
const maintenance = require('../../middleware/maintenance'); // global, shared
|
||||
const errorHandler = require('../../middleware/error-handler'); // global, shared
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('API v0.1 setup start');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const prettyURLs = require('../../middleware/pretty-urls'),
|
||||
cors = require('../../middleware/api/cors'),
|
||||
urlRedirects = require('../../middleware/url-redirects'),
|
||||
auth = require('../../../services/auth');
|
||||
const prettyURLs = require('../../middleware/pretty-urls');
|
||||
const cors = require('../../middleware/api/cors');
|
||||
const urlRedirects = require('../../middleware/url-redirects');
|
||||
const auth = require('../../../services/auth');
|
||||
|
||||
/**
|
||||
* Auth Middleware Packages
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
const express = require('express'),
|
||||
// This essentially provides the controllers for the routes
|
||||
api = require('../../../api'),
|
||||
const express = require('express');
|
||||
// This essentially provides the controllers for the routes
|
||||
const api = require('../../../api');
|
||||
|
||||
// Middleware
|
||||
mw = require('./middleware'),
|
||||
// Middleware
|
||||
const mw = require('./middleware');
|
||||
|
||||
// API specific
|
||||
auth = require('../../../services/auth'),
|
||||
cors = require('../../middleware/api/cors'),
|
||||
brute = require('../../middleware/brute'),
|
||||
// API specific
|
||||
const auth = require('../../../services/auth');
|
||||
const cors = require('../../middleware/api/cors');
|
||||
const brute = require('../../middleware/brute');
|
||||
|
||||
// Handling uploads & imports
|
||||
tmpdir = require('os').tmpdir,
|
||||
upload = require('multer')({dest: tmpdir()}),
|
||||
validation = require('../../middleware/validation'),
|
||||
image = require('../../middleware/image'),
|
||||
// Handling uploads & imports
|
||||
const tmpdir = require('os').tmpdir;
|
||||
const upload = require('multer')({dest: tmpdir()});
|
||||
const validation = require('../../middleware/validation');
|
||||
const image = require('../../middleware/image');
|
||||
|
||||
// Temporary
|
||||
// @TODO find a more appy way to do this!
|
||||
labs = require('../../middleware/labs');
|
||||
// Temporary
|
||||
// @TODO find a more appy way to do this!
|
||||
const labs = require('../../middleware/labs');
|
||||
|
||||
module.exports = function apiRoutes() {
|
||||
const apiRouter = express.Router();
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
// # API routes
|
||||
const debug = require('ghost-ignition').debug('api'),
|
||||
boolParser = require('express-query-boolean'),
|
||||
express = require('express'),
|
||||
const debug = require('ghost-ignition').debug('api');
|
||||
const boolParser = require('express-query-boolean');
|
||||
const express = require('express');
|
||||
|
||||
// routes
|
||||
routes = require('./routes'),
|
||||
// routes
|
||||
const routes = require('./routes');
|
||||
|
||||
// Include the middleware
|
||||
// Include the middleware
|
||||
|
||||
// API specific
|
||||
versionMatch = require('../../../middleware/api/version-match'), // global
|
||||
// API specific
|
||||
const versionMatch = require('../../../middleware/api/version-match'); // global
|
||||
|
||||
// Shared
|
||||
bodyParser = require('body-parser'), // global, shared
|
||||
cacheControl = require('../../../middleware/cache-control'), // global, shared
|
||||
maintenance = require('../../../middleware/maintenance'), // global, shared
|
||||
errorHandler = require('../../../middleware/error-handler'); // global, shared
|
||||
// Shared
|
||||
const bodyParser = require('body-parser'); // global, shared
|
||||
const cacheControl = require('../../../middleware/cache-control'); // global, shared
|
||||
const maintenance = require('../../../middleware/maintenance'); // global, shared
|
||||
const errorHandler = require('../../../middleware/error-handler'); // global, shared
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Admin API v2 setup start');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const prettyURLs = require('../../../middleware/pretty-urls'),
|
||||
cors = require('../../../middleware/api/cors'),
|
||||
{adminRedirect} = require('../../../middleware/url-redirects'),
|
||||
auth = require('../../../../services/auth');
|
||||
const prettyURLs = require('../../../middleware/pretty-urls');
|
||||
const cors = require('../../../middleware/api/cors');
|
||||
const {adminRedirect} = require('../../../middleware/url-redirects');
|
||||
const auth = require('../../../../services/auth');
|
||||
|
||||
/**
|
||||
* Authentication for private endpoints
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
const express = require('express'),
|
||||
// This essentially provides the controllers for the routes
|
||||
api = require('../../../../api'),
|
||||
const express = require('express');
|
||||
// This essentially provides the controllers for the routes
|
||||
const api = require('../../../../api');
|
||||
|
||||
// Middleware
|
||||
mw = require('./middleware'),
|
||||
// Middleware
|
||||
const mw = require('./middleware');
|
||||
|
||||
// API specific
|
||||
auth = require('../../../../services/auth'),
|
||||
cors = require('../../../middleware/api/cors'),
|
||||
brute = require('../../../middleware/brute'),
|
||||
// API specific
|
||||
const auth = require('../../../../services/auth');
|
||||
const cors = require('../../../middleware/api/cors');
|
||||
const brute = require('../../../middleware/brute');
|
||||
|
||||
// Handling uploads & imports
|
||||
tmpdir = require('os').tmpdir,
|
||||
upload = require('multer')({dest: tmpdir()}),
|
||||
validation = require('../../../middleware/validation'),
|
||||
image = require('../../../middleware/image'),
|
||||
// Handling uploads & imports
|
||||
const tmpdir = require('os').tmpdir;
|
||||
const upload = require('multer')({dest: tmpdir()});
|
||||
const validation = require('../../../middleware/validation');
|
||||
const image = require('../../../middleware/image');
|
||||
|
||||
// Temporary
|
||||
// @TODO find a more appy way to do this!
|
||||
labs = require('../../../middleware/labs');
|
||||
// Temporary
|
||||
// @TODO find a more appy way to do this!
|
||||
const labs = require('../../../middleware/labs');
|
||||
|
||||
module.exports = function apiRoutes() {
|
||||
const router = express.Router();
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
// # API routes
|
||||
const debug = require('ghost-ignition').debug('api'),
|
||||
boolParser = require('express-query-boolean'),
|
||||
express = require('express'),
|
||||
const debug = require('ghost-ignition').debug('api');
|
||||
const boolParser = require('express-query-boolean');
|
||||
const express = require('express');
|
||||
|
||||
// routes
|
||||
routes = require('./routes'),
|
||||
// routes
|
||||
const routes = require('./routes');
|
||||
|
||||
// Include the middleware
|
||||
// Include the middleware
|
||||
|
||||
// Shared
|
||||
cacheControl = require('../../../middleware/cache-control'), // global, shared
|
||||
maintenance = require('../../../middleware/maintenance'), // global, shared
|
||||
errorHandler = require('../../../middleware/error-handler'); // global, shared
|
||||
// Shared
|
||||
const cacheControl = require('../../../middleware/cache-control'); // global, shared
|
||||
const maintenance = require('../../../middleware/maintenance'); // global, shared
|
||||
const errorHandler = require('../../../middleware/error-handler'); // global, shared
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Content API v2 setup start');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const prettyURLs = require('../../../middleware/pretty-urls'),
|
||||
cors = require('../../../middleware/api/cors'),
|
||||
{adminRedirect} = require('../../../middleware/url-redirects'),
|
||||
auth = require('../../../../services/auth');
|
||||
const prettyURLs = require('../../../middleware/pretty-urls');
|
||||
const cors = require('../../../middleware/api/cors');
|
||||
const {adminRedirect} = require('../../../middleware/url-redirects');
|
||||
const auth = require('../../../../services/auth');
|
||||
|
||||
/**
|
||||
* Auth Middleware Packages
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
const express = require('express'),
|
||||
// This essentially provides the controllers for the routes
|
||||
api = require('../../../../api'),
|
||||
const express = require('express');
|
||||
// This essentially provides the controllers for the routes
|
||||
const api = require('../../../../api');
|
||||
|
||||
// Middleware
|
||||
mw = require('./middleware'),
|
||||
// Middleware
|
||||
const mw = require('./middleware');
|
||||
|
||||
// API specific
|
||||
cors = require('../../../middleware/api/cors'),
|
||||
// API specific
|
||||
const cors = require('../../../middleware/api/cors');
|
||||
|
||||
// Temporary
|
||||
// @TODO find a more appy way to do this!
|
||||
labs = require('../../../middleware/labs');
|
||||
// Temporary
|
||||
// @TODO find a more appy way to do this!
|
||||
const labs = require('../../../middleware/labs');
|
||||
|
||||
module.exports = function apiRoutes() {
|
||||
const router = express.Router();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const express = require('express'),
|
||||
urlService = require('../../services/url');
|
||||
const express = require('express');
|
||||
const urlService = require('../../services/url');
|
||||
|
||||
const adminRedirect = function adminRedirect(path) {
|
||||
const adminRedirect = (path) => {
|
||||
return function doRedirect(req, res) {
|
||||
return urlService.utils.redirectToAdmin(301, res, path);
|
||||
};
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
var cors = require('cors'),
|
||||
_ = require('lodash'),
|
||||
url = require('url'),
|
||||
os = require('os'),
|
||||
urlService = require('../../../services/url'),
|
||||
whitelist = [],
|
||||
ENABLE_CORS = {origin: true, maxAge: 86400},
|
||||
DISABLE_CORS = {origin: false};
|
||||
const cors = require('cors');
|
||||
const url = require('url');
|
||||
const os = require('os');
|
||||
const some = require('lodash/some');
|
||||
const urlService = require('../../../services/url');
|
||||
|
||||
let whitelist = [];
|
||||
const ENABLE_CORS = {origin: true, maxAge: 86400};
|
||||
const DISABLE_CORS = {origin: false};
|
||||
|
||||
/**
|
||||
* Gather a list of local ipv4 addresses
|
||||
* @return {Array<String>}
|
||||
*/
|
||||
function getIPs() {
|
||||
var ifaces = os.networkInterfaces(),
|
||||
const ifaces = os.networkInterfaces(),
|
||||
ips = [
|
||||
'localhost'
|
||||
];
|
||||
|
||||
Object.keys(ifaces).forEach(function (ifname) {
|
||||
ifaces[ifname].forEach(function (iface) {
|
||||
Object.keys(ifaces).forEach((ifname) => {
|
||||
ifaces[ifname].forEach((iface) => {
|
||||
// only support IPv4
|
||||
if (iface.family !== 'IPv4') {
|
||||
return;
|
||||
|
@ -32,9 +33,9 @@ function getIPs() {
|
|||
}
|
||||
|
||||
function getUrls() {
|
||||
var blogHost = url.parse(urlService.utils.urlFor('home', true)).hostname,
|
||||
adminHost = url.parse(urlService.utils.urlFor('admin', true)).hostname,
|
||||
urls = [];
|
||||
const blogHost = url.parse(urlService.utils.urlFor('home', true)).hostname;
|
||||
const adminHost = url.parse(urlService.utils.urlFor('admin', true)).hostname;
|
||||
const urls = [];
|
||||
|
||||
urls.push(blogHost);
|
||||
|
||||
|
@ -47,7 +48,7 @@ function getUrls() {
|
|||
|
||||
function getWhitelist() {
|
||||
// This needs doing just one time after init
|
||||
if (_.isEmpty(whitelist)) {
|
||||
if (whitelist.length === 0) {
|
||||
// origins that always match: localhost, local IPs, etc.
|
||||
whitelist = whitelist.concat(getIPs());
|
||||
// Trusted urls from config.js
|
||||
|
@ -64,8 +65,8 @@ function getWhitelist() {
|
|||
* @return {null}
|
||||
*/
|
||||
function handleCORS(req, cb) {
|
||||
var origin = req.get('origin'),
|
||||
trustedDomains = req.client && req.client.trustedDomains;
|
||||
const origin = req.get('origin');
|
||||
const trustedDomains = req.client && req.client.trustedDomains;
|
||||
|
||||
// Request must have an Origin header
|
||||
if (!origin) {
|
||||
|
@ -73,7 +74,7 @@ function handleCORS(req, cb) {
|
|||
}
|
||||
|
||||
// Origin matches a client_trusted_domain
|
||||
if (_.some(trustedDomains, {trusted_domain: origin})) {
|
||||
if (some(trustedDomains, {trusted_domain: origin})) {
|
||||
return cb(null, ENABLE_CORS);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
var moment = require('moment'),
|
||||
_ = require('lodash'),
|
||||
config = require('../../../config'),
|
||||
common = require('../../../lib/common'),
|
||||
spam = config.get('spam') || {},
|
||||
spamPrivateBlog = spam.private_blog || {},
|
||||
spamGlobalBlock = spam.global_block || {},
|
||||
spamGlobalReset = spam.global_reset || {},
|
||||
spamUserReset = spam.user_reset || {},
|
||||
spamUserLogin = spam.user_login || {},
|
||||
const moment = require('moment');
|
||||
const extend = require('lodash/extend');
|
||||
const pick = require('lodash/pick');
|
||||
const config = require('../../../config');
|
||||
const common = require('../../../lib/common');
|
||||
const spam = config.get('spam') || {};
|
||||
|
||||
store,
|
||||
handleStoreError,
|
||||
globalBlock,
|
||||
globalReset,
|
||||
privateBlogInstance,
|
||||
globalResetInstance,
|
||||
globalBlockInstance,
|
||||
userLoginInstance,
|
||||
userResetInstance,
|
||||
privateBlog,
|
||||
userLogin,
|
||||
userReset,
|
||||
spamConfigKeys = ['freeRetries', 'minWait', 'maxWait', 'lifetime'];
|
||||
const spamPrivateBlog = spam.private_blog || {};
|
||||
const spamGlobalBlock = spam.global_block || {};
|
||||
const spamGlobalReset = spam.global_reset || {};
|
||||
const spamUserReset = spam.user_reset || {};
|
||||
const spamUserLogin = spam.user_login || {};
|
||||
|
||||
handleStoreError = function handleStoreError(err) {
|
||||
var customError = new common.errors.InternalServerError({
|
||||
let store;
|
||||
let privateBlogInstance;
|
||||
let globalResetInstance;
|
||||
let globalBlockInstance;
|
||||
let userLoginInstance;
|
||||
let userResetInstance;
|
||||
|
||||
const spamConfigKeys = ['freeRetries', 'minWait', 'maxWait', 'lifetime'];
|
||||
|
||||
const handleStoreError = (err) => {
|
||||
const customError = new common.errors.InternalServerError({
|
||||
message: 'Unknown error',
|
||||
err: err.parent ? err.parent : err
|
||||
});
|
||||
|
@ -45,10 +42,10 @@ handleStoreError = function handleStoreError(err) {
|
|||
// requests from a single IP
|
||||
// We allow for a generous number of requests here to prevent communites on the same IP bing barred on account of a single suer
|
||||
// Defaults to 50 attempts per hour and locks the endpoint for an hour
|
||||
globalBlock = function globalBlock() {
|
||||
var ExpressBrute = require('express-brute'),
|
||||
BruteKnex = require('brute-knex'),
|
||||
db = require('../../../data/db');
|
||||
const globalBlock = () => {
|
||||
const ExpressBrute = require('express-brute');
|
||||
const BruteKnex = require('brute-knex');
|
||||
const db = require('../../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
|
@ -57,27 +54,27 @@ globalBlock = function globalBlock() {
|
|||
});
|
||||
|
||||
globalBlockInstance = globalBlockInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
failCallback(req, res, next, nextValidRequestDate) {
|
||||
return next(new common.errors.TooManyRequestsError({
|
||||
message: 'Too many attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
message: `Too many attempts try again in ${moment(nextValidRequestDate).fromNow(true)}`,
|
||||
context: common.i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.error',
|
||||
{rfa: spamGlobalBlock.freeRetries + 1 || 5, rfp: spamGlobalBlock.lifetime || 60 * 60}),
|
||||
help: common.i18n.t('errors.middleware.spamprevention.tooManyAttempts')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamGlobalBlock, spamConfigKeys))
|
||||
}, pick(spamGlobalBlock, spamConfigKeys))
|
||||
);
|
||||
|
||||
return globalBlockInstance;
|
||||
};
|
||||
|
||||
globalReset = function globalReset() {
|
||||
var ExpressBrute = require('express-brute'),
|
||||
BruteKnex = require('brute-knex'),
|
||||
db = require('../../../data/db');
|
||||
const globalReset = () => {
|
||||
const ExpressBrute = require('express-brute');
|
||||
const BruteKnex = require('brute-knex');
|
||||
const db = require('../../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
|
@ -86,19 +83,19 @@ globalReset = function globalReset() {
|
|||
});
|
||||
|
||||
globalResetInstance = globalResetInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
failCallback(req, res, next, nextValidRequestDate) {
|
||||
// TODO use i18n again
|
||||
return next(new common.errors.TooManyRequestsError({
|
||||
message: 'Too many attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
message: `Too many attempts try again in ${moment(nextValidRequestDate).fromNow(true)}`,
|
||||
context: common.i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.error',
|
||||
{rfa: spamGlobalReset.freeRetries + 1 || 5, rfp: spamGlobalReset.lifetime || 60 * 60}),
|
||||
help: common.i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamGlobalReset, spamConfigKeys))
|
||||
}, pick(spamGlobalReset, spamConfigKeys))
|
||||
);
|
||||
|
||||
return globalResetInstance;
|
||||
|
@ -108,10 +105,10 @@ globalReset = function globalReset() {
|
|||
// and rising to a week in a fibonnaci sequence
|
||||
// The user+IP count is reset when on successful login
|
||||
// Default value of 5 attempts per user+IP pair
|
||||
userLogin = function userLogin() {
|
||||
var ExpressBrute = require('express-brute'),
|
||||
BruteKnex = require('brute-knex'),
|
||||
db = require('../../../data/db');
|
||||
const userLogin = () => {
|
||||
const ExpressBrute = require('express-brute');
|
||||
const BruteKnex = require('brute-knex');
|
||||
const db = require('../../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
|
@ -120,18 +117,18 @@ userLogin = function userLogin() {
|
|||
});
|
||||
|
||||
userLoginInstance = userLoginInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
extend({
|
||||
attachResetToRequest: true,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
failCallback(req, res, next, nextValidRequestDate) {
|
||||
return next(new common.errors.TooManyRequestsError({
|
||||
message: 'Too many sign-in attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
message: `Too many sign-in attempts try again in ${moment(nextValidRequestDate).fromNow(true)}`,
|
||||
// TODO add more options to i18n
|
||||
context: common.i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context'),
|
||||
help: common.i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamUserLogin, spamConfigKeys))
|
||||
}, pick(spamUserLogin, spamConfigKeys))
|
||||
);
|
||||
|
||||
return userLoginInstance;
|
||||
|
@ -140,10 +137,10 @@ userLogin = function userLogin() {
|
|||
// Stop password reset requests when there are (freeRetries + 1) requests per lifetime per email
|
||||
// Defaults here are 5 attempts per hour for a user+IP pair
|
||||
// The endpoint is then locked for an hour
|
||||
userReset = function userReset() {
|
||||
var ExpressBrute = require('express-brute'),
|
||||
BruteKnex = require('brute-knex'),
|
||||
db = require('../../../data/db');
|
||||
const userReset = function userReset() {
|
||||
const ExpressBrute = require('express-brute');
|
||||
const BruteKnex = require('brute-knex');
|
||||
const db = require('../../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
|
@ -152,18 +149,18 @@ userReset = function userReset() {
|
|||
});
|
||||
|
||||
userResetInstance = userResetInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
extend({
|
||||
attachResetToRequest: true,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
failCallback(req, res, next, nextValidRequestDate) {
|
||||
return next(new common.errors.TooManyRequestsError({
|
||||
message: 'Too many password reset attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
message: `Too many password reset attempts try again in ${moment(nextValidRequestDate).fromNow(true)}`,
|
||||
context: common.i18n.t('errors.middleware.spamprevention.forgottenPasswordEmail.error',
|
||||
{rfa: spamUserReset.freeRetries + 1 || 5, rfp: spamUserReset.lifetime || 60 * 60}),
|
||||
help: common.i18n.t('errors.middleware.spamprevention.forgottenPasswordEmail.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamUserReset, spamConfigKeys))
|
||||
}, pick(spamUserReset, spamConfigKeys))
|
||||
);
|
||||
|
||||
return userResetInstance;
|
||||
|
@ -171,10 +168,10 @@ userReset = function userReset() {
|
|||
|
||||
// This protects a private blog from spam attacks. The defaults here allow 10 attempts per IP per hour
|
||||
// The endpoint is then locked for an hour
|
||||
privateBlog = function privateBlog() {
|
||||
var ExpressBrute = require('express-brute'),
|
||||
BruteKnex = require('brute-knex'),
|
||||
db = require('../../../data/db');
|
||||
const privateBlog = () => {
|
||||
const ExpressBrute = require('express-brute');
|
||||
const BruteKnex = require('brute-knex');
|
||||
const db = require('../../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
|
@ -183,9 +180,9 @@ privateBlog = function privateBlog() {
|
|||
});
|
||||
|
||||
privateBlogInstance = privateBlogInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
failCallback(req, res, next, nextValidRequestDate) {
|
||||
common.logging.error(new common.errors.GhostError({
|
||||
message: common.i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.error',
|
||||
{
|
||||
|
@ -196,11 +193,11 @@ privateBlog = function privateBlog() {
|
|||
}));
|
||||
|
||||
return next(new common.errors.GhostError({
|
||||
message: 'Too many private sign-in attempts try again in ' + moment(nextValidRequestDate).fromNow(true)
|
||||
message: `Too many private sign-in attempts try again in ${moment(nextValidRequestDate).fromNow(true)}`
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamPrivateBlog, spamConfigKeys))
|
||||
}, pick(spamPrivateBlog, spamConfigKeys))
|
||||
);
|
||||
|
||||
return privateBlogInstance;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
var semver = require('semver'),
|
||||
common = require('../../../lib/common');
|
||||
const semver = require('semver');
|
||||
const common = require('../../../lib/common');
|
||||
|
||||
function checkVersionMatch(req, res, next) {
|
||||
var clientVersion = req.get('X-Ghost-Version'),
|
||||
// can contain pre-release suffix, you should be able to use e.g. 1.19.0-pre [server] with 1.18.0 [client]
|
||||
serverVersion = res.locals.version.match(/^(\d+\.)?(\d+\.)?(\d+)/)[0],
|
||||
constraint = '^' + clientVersion + '.0';
|
||||
const clientVersion = req.get('X-Ghost-Version');
|
||||
// can contain pre-release suffix, you should be able to use e.g. 1.19.0-pre [server] with 1.18.0 [client]
|
||||
const serverVersion = res.locals.version.match(/^(\d+\.)?(\d+\.)?(\d+)/)[0];
|
||||
const constraint = '^' + clientVersion + '.0';
|
||||
|
||||
// no error when client is on an earlier minor version than server
|
||||
// error when client is on a later minor version than server
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const url = require('url'),
|
||||
spamPrevention = require('./api/spam-prevention');
|
||||
const url = require('url');
|
||||
const spamPrevention = require('./api/spam-prevention');
|
||||
|
||||
/**
|
||||
* We set ignoreIP to false, because we tell brute-knex to use `req.ip`.
|
||||
|
@ -9,7 +9,7 @@ module.exports = {
|
|||
/**
|
||||
* block per route per ip
|
||||
*/
|
||||
globalBlock: function (req, res, next) {
|
||||
globalBlock(req, res, next) {
|
||||
return spamPrevention.globalBlock().getMiddleware({
|
||||
ignoreIP: false,
|
||||
key: function (req, res, next) {
|
||||
|
@ -20,10 +20,10 @@ module.exports = {
|
|||
/**
|
||||
* block per route per ip
|
||||
*/
|
||||
globalReset: function (req, res, next) {
|
||||
globalReset(req, res, next) {
|
||||
return spamPrevention.globalReset().getMiddleware({
|
||||
ignoreIP: false,
|
||||
key: function (req, res, next) {
|
||||
key(req, res, next) {
|
||||
next(url.parse(req.url).pathname);
|
||||
}
|
||||
})(req, res, next);
|
||||
|
@ -32,20 +32,20 @@ module.exports = {
|
|||
* block per user
|
||||
* username === email!
|
||||
*/
|
||||
userLogin: function (req, res, next) {
|
||||
userLogin(req, res, next) {
|
||||
return spamPrevention.userLogin().getMiddleware({
|
||||
ignoreIP: false,
|
||||
key: function (req, res, next) {
|
||||
key(req, res, next) {
|
||||
if (req.body.username) {
|
||||
return next(req.body.username + 'login');
|
||||
return next(`${req.body.username}login`);
|
||||
}
|
||||
|
||||
if (req.body.authorizationCode) {
|
||||
return next(req.body.authorizationCode + 'login');
|
||||
return next(`${req.body.authorizationCode}login`);
|
||||
}
|
||||
|
||||
if (req.body.refresh_token) {
|
||||
return next(req.body.refresh_token + 'login');
|
||||
return next(`${req.body.refresh_token}login`);
|
||||
}
|
||||
|
||||
return next();
|
||||
|
@ -55,21 +55,21 @@ module.exports = {
|
|||
/**
|
||||
* block per user
|
||||
*/
|
||||
userReset: function (req, res, next) {
|
||||
userReset(req, res, next) {
|
||||
return spamPrevention.userReset().getMiddleware({
|
||||
ignoreIP: false,
|
||||
key: function (req, res, next) {
|
||||
next(req.body.username + 'reset');
|
||||
key(req, res, next) {
|
||||
next(`${req.body.username}reset`);
|
||||
}
|
||||
})(req, res, next);
|
||||
},
|
||||
/**
|
||||
* block per ip
|
||||
*/
|
||||
privateBlog: function (req, res, next) {
|
||||
privateBlog(req, res, next) {
|
||||
return spamPrevention.privateBlog().getMiddleware({
|
||||
ignoreIP: false,
|
||||
key: function (req, res, next) {
|
||||
key(req, res, next) {
|
||||
next('privateblog');
|
||||
}
|
||||
})(req, res, next);
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
//
|
||||
// Allows each app to declare its own default caching rules
|
||||
|
||||
const _ = require('lodash'),
|
||||
config = require('../../config');
|
||||
const isString = require('lodash/isString');
|
||||
const config = require('../../config');
|
||||
|
||||
const cacheControl = function cacheControl(options) {
|
||||
const cacheControl = (options) => {
|
||||
const profiles = {
|
||||
public: 'public, max-age=' + config.get('caching:frontend:maxAge'),
|
||||
private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
||||
|
@ -17,7 +17,7 @@ const cacheControl = function cacheControl(options) {
|
|||
|
||||
let output;
|
||||
|
||||
if (_.isString(options) && profiles.hasOwnProperty(options)) {
|
||||
if (isString(options) && profiles.hasOwnProperty(options)) {
|
||||
output = profiles[options];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
const fs = require('fs-extra'),
|
||||
express = require('express'),
|
||||
url = require('url'),
|
||||
path = require('path'),
|
||||
debug = require('ghost-ignition').debug('custom-redirects'),
|
||||
config = require('../../config'),
|
||||
common = require('../../lib/common'),
|
||||
validation = require('../../data/validation'),
|
||||
_private = {};
|
||||
const fs = require('fs-extra');
|
||||
const express = require('express');
|
||||
const url = require('url');
|
||||
const path = require('path');
|
||||
const debug = require('ghost-ignition').debug('custom-redirects');
|
||||
const config = require('../../config');
|
||||
const common = require('../../lib/common');
|
||||
const validation = require('../../data/validation');
|
||||
|
||||
const _private = {};
|
||||
|
||||
let customRedirectsRouter;
|
||||
|
||||
_private.registerRoutes = function registerRoutes() {
|
||||
_private.registerRoutes = () => {
|
||||
debug('redirects loading');
|
||||
|
||||
customRedirectsRouter = express.Router();
|
||||
|
@ -20,7 +21,7 @@ _private.registerRoutes = function registerRoutes() {
|
|||
redirects = JSON.parse(redirects);
|
||||
validation.validateRedirects(redirects);
|
||||
|
||||
redirects.forEach(function (redirect) {
|
||||
redirects.forEach((redirect) => {
|
||||
/**
|
||||
* always delete trailing slashes, doesn't matter if regex or not
|
||||
* Example:
|
||||
|
@ -36,12 +37,12 @@ _private.registerRoutes = function registerRoutes() {
|
|||
}
|
||||
|
||||
debug('register', redirect.from);
|
||||
customRedirectsRouter.get(new RegExp(redirect.from), function (req, res) {
|
||||
customRedirectsRouter.get(new RegExp(redirect.from), function customRedirect(req, res) {
|
||||
const maxAge = redirect.permanent ? config.get('caching:customRedirects:maxAge') : 0,
|
||||
parsedUrl = url.parse(req.originalUrl);
|
||||
|
||||
res.set({
|
||||
'Cache-Control': 'public, max-age=' + maxAge
|
||||
'Cache-Control': `public, max-age=${maxAge}`
|
||||
});
|
||||
|
||||
res.redirect(redirect.permanent ? 301 : 302, url.format({
|
||||
|
@ -75,7 +76,7 @@ exports.use = function use(siteApp) {
|
|||
|
||||
// Recommended approach by express, see https://github.com/expressjs/express/issues/2596#issuecomment-81353034.
|
||||
// As soon as the express router get's re-instantiated, the old router instance is not used anymore.
|
||||
siteApp.use(function (req, res, next) {
|
||||
siteApp.use(function customRedirect(req, res, next) {
|
||||
customRedirectsRouter(req, res, next);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
const hbs = require('express-hbs'),
|
||||
debug = require('ghost-ignition').debug('error-handler'),
|
||||
config = require('../../config'),
|
||||
common = require('../../lib/common'),
|
||||
helpers = require('../../services/routing/helpers'),
|
||||
escapeExpression = hbs.Utils.escapeExpression,
|
||||
_private = {},
|
||||
errorHandler = {};
|
||||
const hbs = require('express-hbs');
|
||||
const debug = require('ghost-ignition').debug('error-handler');
|
||||
const config = require('../../config');
|
||||
const common = require('../../lib/common');
|
||||
const helpers = require('../../services/routing/helpers');
|
||||
|
||||
const escapeExpression = hbs.Utils.escapeExpression;
|
||||
const _private = {};
|
||||
const errorHandler = {};
|
||||
|
||||
/**
|
||||
* This is a bare minimum setup, which allows us to render the error page
|
||||
* It uses the {{asset}} helper, and nothing more
|
||||
*/
|
||||
_private.createHbsEngine = function createHbsEngine() {
|
||||
_private.createHbsEngine = () => {
|
||||
const engine = hbs.create();
|
||||
engine.registerHelper('asset', require('../../helpers/asset'));
|
||||
|
||||
|
@ -23,7 +24,7 @@ _private.createHbsEngine = function createHbsEngine() {
|
|||
*
|
||||
* @TODO: support multiple errors within one single error, see https://github.com/TryGhost/Ghost/issues/7116#issuecomment-252231809
|
||||
*/
|
||||
_private.prepareError = function prepareError(err, req, res, next) {
|
||||
_private.prepareError = (err, req, res, next) => {
|
||||
debug(err);
|
||||
|
||||
if (Array.isArray(err)) {
|
||||
|
@ -60,7 +61,7 @@ _private.prepareError = function prepareError(err, req, res, next) {
|
|||
next(err);
|
||||
};
|
||||
|
||||
_private.JSONErrorRenderer = function JSONErrorRenderer(err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
_private.JSONErrorRenderer = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
||||
// @TODO: jsonapi errors format (http://jsonapi.org/format/#error-objects)
|
||||
res.json({
|
||||
errors: [{
|
||||
|
@ -72,15 +73,13 @@ _private.JSONErrorRenderer = function JSONErrorRenderer(err, req, res, next) { /
|
|||
});
|
||||
};
|
||||
|
||||
_private.ErrorFallbackMessage = function ErrorFallbackMessage(err) {
|
||||
return `<h1>${common.i18n.t('errors.errors.oopsErrorTemplateHasError')}</h1>
|
||||
_private.ErrorFallbackMessage = err => `<h1>${common.i18n.t('errors.errors.oopsErrorTemplateHasError')}</h1>
|
||||
<p>${common.i18n.t('errors.errors.encounteredError')}</p>
|
||||
<pre>${escapeExpression(err.message || err)}</pre>
|
||||
<br ><p>${common.i18n.t('errors.errors.whilstTryingToRender')}</p>
|
||||
${err.statusCode} <pre>${escapeExpression(err.message || err)}</pre>`;
|
||||
};
|
||||
|
||||
_private.ThemeErrorRenderer = function ThemeErrorRenderer(err, req, res, next) {
|
||||
_private.ThemeErrorRenderer = (err, req, res, next) => {
|
||||
// If the error code is explicitly set to STATIC_FILE_NOT_FOUND,
|
||||
// Skip trying to render an HTML error, and move on to the basic error renderer
|
||||
// We do this because customised 404 templates could reference the image that's missing
|
||||
|
@ -115,7 +114,7 @@ _private.ThemeErrorRenderer = function ThemeErrorRenderer(err, req, res, next) {
|
|||
|
||||
// @TODO use renderer here?!
|
||||
// Render Call - featuring an error handler for what happens if rendering fails
|
||||
res.render(res._template, data, function renderResponse(err, html) {
|
||||
res.render(res._template, data, (err, html) => {
|
||||
if (!err) {
|
||||
return res.send(html);
|
||||
}
|
||||
|
@ -129,7 +128,7 @@ _private.ThemeErrorRenderer = function ThemeErrorRenderer(err, req, res, next) {
|
|||
});
|
||||
};
|
||||
|
||||
_private.HTMLErrorRenderer = function HTMLErrorRender(err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
_private.HTMLErrorRenderer = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
||||
const data = {
|
||||
message: err.message,
|
||||
statusCode: err.statusCode,
|
||||
|
@ -146,7 +145,7 @@ _private.HTMLErrorRenderer = function HTMLErrorRender(err, req, res, next) { //
|
|||
req.app.set('views', config.get('paths').defaultViews);
|
||||
}
|
||||
|
||||
res.render('error', data, function renderResponse(err, html) {
|
||||
res.render('error', data, (err, html) => {
|
||||
if (!err) {
|
||||
return res.send(html);
|
||||
}
|
||||
|
@ -160,17 +159,17 @@ _private.HTMLErrorRenderer = function HTMLErrorRender(err, req, res, next) { //
|
|||
});
|
||||
};
|
||||
|
||||
_private.BasicErrorRenderer = function BasicErrorRenderer(err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
_private.BasicErrorRenderer = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
||||
return res.send(res.statusCode + ' ' + err.message);
|
||||
};
|
||||
|
||||
errorHandler.resourceNotFound = function resourceNotFound(req, res, next) {
|
||||
errorHandler.resourceNotFound = (req, res, next) => {
|
||||
// TODO, handle unknown resources & methods differently, so that we can also produce
|
||||
// 405 Method Not Allowed
|
||||
next(new common.errors.NotFoundError({message: common.i18n.t('errors.errors.resourceNotFound')}));
|
||||
};
|
||||
|
||||
errorHandler.pageNotFound = function pageNotFound(req, res, next) {
|
||||
errorHandler.pageNotFound = (req, res, next) => {
|
||||
next(new common.errors.NotFoundError({message: common.i18n.t('errors.errors.pageNotFound')}));
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const api = require('../../api'),
|
||||
labs = require('../../services/labs'),
|
||||
common = require('../../lib/common');
|
||||
const api = require('../../api');
|
||||
const labs = require('../../services/labs');
|
||||
const common = require('../../lib/common');
|
||||
|
||||
module.exports = function getFrontendClient(req, res, next) {
|
||||
if (labs.isSet('publicAPI') !== true) {
|
||||
|
@ -9,7 +9,7 @@ module.exports = function getFrontendClient(req, res, next) {
|
|||
|
||||
return api.clients
|
||||
.read({slug: 'ghost-frontend'})
|
||||
.then(function handleClient(client) {
|
||||
.then((client) => {
|
||||
client = client.clients[0];
|
||||
|
||||
if (client.status === 'enabled') {
|
||||
|
@ -21,7 +21,7 @@ module.exports = function getFrontendClient(req, res, next) {
|
|||
|
||||
next();
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch((err) => {
|
||||
// Log the error, but carry on as this is non-critical
|
||||
common.logging.error(err);
|
||||
next();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const _ = require('lodash');
|
||||
const cloneDeep = require('lodash/cloneDeep');
|
||||
const path = require('path');
|
||||
const config = require('../../../config');
|
||||
const common = require('../../../lib/common');
|
||||
|
@ -35,7 +35,7 @@ module.exports = function normalize(req, res, next) {
|
|||
// CASE: push original image, we keep a copy of it
|
||||
const parsedFileName = path.parse(req.file.name);
|
||||
const newName = `${parsedFileName.name}_o${parsedFileName.ext}`;
|
||||
req.files.push(Object.assign(_.cloneDeep(req.file), {path: originalPath, name: newName}));
|
||||
req.files.push(Object.assign(cloneDeep(req.file), {path: originalPath, name: newName}));
|
||||
|
||||
next();
|
||||
})
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const labsUtil = require('../../services/labs'),
|
||||
common = require('../../lib/common');
|
||||
const labsUtil = require('../../services/labs');
|
||||
const common = require('../../lib/common');
|
||||
|
||||
const labs = {
|
||||
subscribers: function subscribers(req, res, next) {
|
||||
subscribers(req, res, next) {
|
||||
if (labsUtil.isSet('subscribers') === true) {
|
||||
return next();
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const uuid = require('uuid'),
|
||||
common = require('../../lib/common');
|
||||
const uuid = require('uuid');
|
||||
const common = require('../../lib/common');
|
||||
|
||||
/**
|
||||
* @TODO:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const config = require('../../config'),
|
||||
common = require('../../lib/common'),
|
||||
urlService = require('../../services/url');
|
||||
const config = require('../../config');
|
||||
const common = require('../../lib/common');
|
||||
const urlService = require('../../services/url');
|
||||
|
||||
module.exports = function maintenance(req, res, next) {
|
||||
if (config.get('maintenance').enabled) {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
// Uncapitalise changes case to lowercase
|
||||
// @TODO optimise this to reduce the number of redirects required to get to a pretty URL
|
||||
// @TODO move this to being used by routers?
|
||||
const slashes = require('connect-slashes'),
|
||||
config = require('../../config');
|
||||
const slashes = require('connect-slashes');
|
||||
const config = require('../../config');
|
||||
|
||||
module.exports = [
|
||||
slashes(true, {
|
||||
headers: {
|
||||
'Cache-Control': 'public, max-age=' + config.get('caching:301:maxAge')
|
||||
'Cache-Control': `public, max-age=${config.get('caching:301:maxAge')}`
|
||||
}
|
||||
}),
|
||||
require('./uncapitalise')
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
const fs = require('fs-extra'),
|
||||
path = require('path'),
|
||||
crypto = require('crypto'),
|
||||
config = require('../../config'),
|
||||
imageLib = require('../../lib/image'),
|
||||
storage = require('../../adapters/storage'),
|
||||
urlService = require('../../services/url'),
|
||||
settingsCache = require('../../services/settings/cache');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const config = require('../../config');
|
||||
const imageLib = require('../../lib/image');
|
||||
const storage = require('../../adapters/storage');
|
||||
const urlService = require('../../services/url');
|
||||
const settingsCache = require('../../services/settings/cache');
|
||||
|
||||
let content;
|
||||
|
||||
const buildContentResponse = function buildContentResponse(ext, buf) {
|
||||
const buildContentResponse = (ext, buf) => {
|
||||
content = {
|
||||
headers: {
|
||||
'Content-Type': 'image/' + ext,
|
||||
'Content-Type': `image/${ext}`,
|
||||
'Content-Length': buf.length,
|
||||
ETag: '"' + crypto.createHash('md5').update(buf, 'utf8').digest('hex') + '"',
|
||||
'Cache-Control': 'public, max-age=' + config.get('caching:favicon:maxAge')
|
||||
ETag: `"${crypto.createHash('md5').update(buf, 'utf8').digest('hex')}"`,
|
||||
'Cache-Control': `public, max-age=${config.get('caching:favicon:maxAge')}`
|
||||
},
|
||||
body: buf
|
||||
};
|
||||
|
@ -26,8 +26,8 @@ const buildContentResponse = function buildContentResponse(ext, buf) {
|
|||
// ### serveFavicon Middleware
|
||||
// Handles requests to favicon.png and favicon.ico
|
||||
function serveFavicon() {
|
||||
let iconType,
|
||||
filePath;
|
||||
let iconType;
|
||||
let filePath;
|
||||
|
||||
return function serveFavicon(req, res, next) {
|
||||
if (req.path.match(/^\/favicon\.(ico|png)/i)) {
|
||||
|
@ -46,12 +46,12 @@ function serveFavicon() {
|
|||
if (settingsCache.get('icon')) {
|
||||
// depends on the uploaded icon extension
|
||||
if (originalExtension !== requestedExtension) {
|
||||
return res.redirect(302, urlService.utils.urlFor({relativeUrl: '/favicon' + originalExtension}));
|
||||
return res.redirect(302, urlService.utils.urlFor({relativeUrl: `/favicon${originalExtension}`}));
|
||||
}
|
||||
|
||||
storage.getStorage()
|
||||
.read({path: filePath})
|
||||
.then(function readFile(buf) {
|
||||
.then((buf) => {
|
||||
iconType = imageLib.blogIcon.getIconType();
|
||||
content = buildContentResponse(iconType, buf);
|
||||
|
||||
|
@ -67,7 +67,7 @@ function serveFavicon() {
|
|||
return res.redirect(302, urlService.utils.urlFor({relativeUrl: '/favicon.ico'}));
|
||||
}
|
||||
|
||||
fs.readFile(filePath, function readFile(err, buf) {
|
||||
fs.readFile(filePath, (err, buf) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
const crypto = require('crypto'),
|
||||
fs = require('fs-extra'),
|
||||
path = require('path'),
|
||||
config = require('../../config'),
|
||||
urlService = require('../../services/url');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const config = require('../../config');
|
||||
const urlService = require('../../services/url');
|
||||
|
||||
// ### servePublicFile Middleware
|
||||
// Handles requests to robots.txt and favicon.ico (and caches them)
|
||||
function servePublicFile(file, type, maxAge) {
|
||||
let content;
|
||||
const publicFilePath = config.get('paths').publicFilePath,
|
||||
filePath = file.match(/^public/) ? path.join(publicFilePath, file.replace(/^public/, '')) : path.join(publicFilePath, file),
|
||||
blogRegex = /(\{\{blog-url\}\})/g,
|
||||
apiRegex = /(\{\{api-url\}\})/g;
|
||||
const publicFilePath = config.get('paths').publicFilePath;
|
||||
const filePath = file.match(/^public/) ? path.join(publicFilePath, file.replace(/^public/, '')) : path.join(publicFilePath, file);
|
||||
const blogRegex = /(\{\{blog-url\}\})/g;
|
||||
const apiRegex = /(\{\{api-url\}\})/g;
|
||||
|
||||
return function servePublicFile(req, res, next) {
|
||||
if (req.path === '/' + file) {
|
||||
|
@ -19,7 +19,7 @@ function servePublicFile(file, type, maxAge) {
|
|||
res.writeHead(200, content.headers);
|
||||
res.end(content.body);
|
||||
} else {
|
||||
fs.readFile(filePath, function readFile(err, buf) {
|
||||
fs.readFile(filePath, (err, buf) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ function servePublicFile(file, type, maxAge) {
|
|||
headers: {
|
||||
'Content-Type': type,
|
||||
'Content-Length': buf.length,
|
||||
ETag: '"' + crypto.createHash('md5').update(buf, 'utf8').digest('hex') + '"',
|
||||
'Cache-Control': 'public, max-age=' + maxAge
|
||||
ETag: `"${crypto.createHash('md5').update(buf, 'utf8').digest('hex')}"`,
|
||||
'Cache-Control': `public, max-age=${maxAge}`
|
||||
},
|
||||
body: buf
|
||||
};
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
const express = require('express'),
|
||||
path = require('path'),
|
||||
config = require('../../config'),
|
||||
constants = require('../../lib/constants'),
|
||||
themeUtils = require('../../services/themes');
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const config = require('../../config');
|
||||
const constants = require('../../lib/constants');
|
||||
const themeUtils = require('../../services/themes');
|
||||
|
||||
function isBlackListedFileType(file) {
|
||||
const blackListedFileTypes = ['.hbs', '.md', '.json'],
|
||||
ext = path.extname(file);
|
||||
const blackListedFileTypes = ['.hbs', '.md', '.json'];
|
||||
const ext = path.extname(file);
|
||||
|
||||
return blackListedFileTypes.includes(ext);
|
||||
}
|
||||
|
||||
function isWhiteListedFile(file) {
|
||||
const whiteListedFiles = ['manifest.json'],
|
||||
base = path.basename(file);
|
||||
const whiteListedFiles = ['manifest.json'];
|
||||
const base = path.basename(file);
|
||||
|
||||
return whiteListedFiles.includes(base);
|
||||
}
|
||||
|
||||
|
@ -33,6 +35,7 @@ function staticTheme() {
|
|||
if (!isWhiteListedFile(req.path) && isBlackListedFileType(req.path)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return forwardToExpressStatic(req, res, next);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
// req.baseUrl = /blog
|
||||
// req.path = /ghost/signin/
|
||||
|
||||
const urlService = require('../../services/url'),
|
||||
common = require('../../lib/common'),
|
||||
localUtils = require('../utils');
|
||||
const urlService = require('../../services/url');
|
||||
const common = require('../../lib/common');
|
||||
const localUtils = require('../utils');
|
||||
|
||||
const uncapitalise = function uncapitalise(req, res, next) {
|
||||
let pathToTest = (req.baseUrl ? req.baseUrl : '') + req.path,
|
||||
redirectPath,
|
||||
decodedURI;
|
||||
const uncapitalise = (req, res, next) => {
|
||||
let pathToTest = (req.baseUrl ? req.baseUrl : '') + req.path;
|
||||
let redirectPath;
|
||||
let decodedURI;
|
||||
|
||||
const isSignupOrReset = pathToTest.match(/^(.*\/ghost\/(signup|reset)\/)/i),
|
||||
isAPI = pathToTest.match(/^(.*\/ghost\/api\/v[\d.]+\/.*?\/)/i);
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
const url = require('url'),
|
||||
path = require('path'),
|
||||
debug = require('ghost-ignition').debug('url-redirects'),
|
||||
urlService = require('../../services/url'),
|
||||
_private = {};
|
||||
const url = require('url');
|
||||
const path = require('path');
|
||||
const debug = require('ghost-ignition').debug('url-redirects');
|
||||
const urlService = require('../../services/url');
|
||||
|
||||
_private.redirectUrl = function redirectUrl(options) {
|
||||
const redirectTo = options.redirectTo,
|
||||
query = options.query,
|
||||
parts = url.parse(redirectTo);
|
||||
const _private = {};
|
||||
|
||||
_private.redirectUrl = (options) => {
|
||||
const redirectTo = options.redirectTo;
|
||||
const query = options.query;
|
||||
const parts = url.parse(redirectTo);
|
||||
let pathname = options.path;
|
||||
|
||||
// CASE: ensure we always add a trailing slash to reduce the number of redirects
|
||||
|
@ -26,15 +27,15 @@ _private.redirectUrl = function redirectUrl(options) {
|
|||
});
|
||||
};
|
||||
|
||||
_private.getAdminRedirectUrl = function getAdminRedirectUrl(options) {
|
||||
const blogHostWithProtocol = urlService.utils.urlFor('home', true),
|
||||
adminHostWithProtocol = urlService.utils.urlFor('admin', true),
|
||||
adminHostWithoutProtocol = adminHostWithProtocol.replace(/(^\w+:|^)\/\//, ''),
|
||||
blogHostWithoutProtocol = blogHostWithProtocol.replace(/(^\w+:|^)\/\//, ''),
|
||||
requestedHost = options.requestedHost,
|
||||
requestedUrl = options.requestedUrl,
|
||||
queryParameters = options.queryParameters,
|
||||
secure = options.secure;
|
||||
_private.getAdminRedirectUrl = (options) => {
|
||||
const blogHostWithProtocol = urlService.utils.urlFor('home', true);
|
||||
const adminHostWithProtocol = urlService.utils.urlFor('admin', true);
|
||||
const adminHostWithoutProtocol = adminHostWithProtocol.replace(/(^\w+:|^)\/\//, '');
|
||||
const blogHostWithoutProtocol = blogHostWithProtocol.replace(/(^\w+:|^)\/\//, '');
|
||||
const requestedHost = options.requestedHost;
|
||||
const requestedUrl = options.requestedUrl;
|
||||
const queryParameters = options.queryParameters;
|
||||
const secure = options.secure;
|
||||
|
||||
debug('getAdminRedirectUrl', requestedHost, requestedUrl, adminHostWithoutProtocol, blogHostWithoutProtocol, urlService.utils.urlJoin(blogHostWithoutProtocol, 'ghost/'));
|
||||
|
||||
|
@ -65,12 +66,12 @@ _private.getAdminRedirectUrl = function getAdminRedirectUrl(options) {
|
|||
}
|
||||
};
|
||||
|
||||
_private.getBlogRedirectUrl = function getBlogRedirectUrl(options) {
|
||||
const blogHostWithProtocol = urlService.utils.urlFor('home', true),
|
||||
requestedHost = options.requestedHost,
|
||||
requestedUrl = options.requestedUrl,
|
||||
queryParameters = options.queryParameters,
|
||||
secure = options.secure;
|
||||
_private.getBlogRedirectUrl = (options) => {
|
||||
const blogHostWithProtocol = urlService.utils.urlFor('home', true);
|
||||
const requestedHost = options.requestedHost;
|
||||
const requestedUrl = options.requestedUrl;
|
||||
const queryParameters = options.queryParameters;
|
||||
const secure = options.secure;
|
||||
|
||||
debug('getBlogRedirectUrl', requestedHost, requestedUrl, blogHostWithProtocol);
|
||||
|
||||
|
@ -79,7 +80,7 @@ _private.getBlogRedirectUrl = function getBlogRedirectUrl(options) {
|
|||
debug('redirect because protocol does not match');
|
||||
|
||||
return _private.redirectUrl({
|
||||
redirectTo: 'https://' + requestedHost,
|
||||
redirectTo: `https://${requestedHost}`,
|
||||
path: requestedUrl,
|
||||
query: queryParameters
|
||||
});
|
||||
|
@ -102,7 +103,7 @@ _private.redirect = (req, res, next, redirectFn) => {
|
|||
});
|
||||
|
||||
if (redirectUrl) {
|
||||
debug('url redirect to: ' + redirectUrl);
|
||||
debug(`url redirect to: ${redirectUrl}`);
|
||||
return urlService.utils.redirect301(res, redirectUrl);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
var config = require('../../../config'),
|
||||
common = require('../../../lib/common'),
|
||||
imageLib = require('../../../lib/image'),
|
||||
validIconFileSize;
|
||||
const config = require('../../../config');
|
||||
const common = require('../../../lib/common');
|
||||
const imageLib = require('../../../lib/image');
|
||||
|
||||
validIconFileSize = function validIconFileSize(size) {
|
||||
return size / 1024 <= 100 ? true : false;
|
||||
const validIconFileSize = (size) => {
|
||||
return (size / 1024) <= 100;
|
||||
};
|
||||
|
||||
module.exports = function blogIcon() {
|
||||
// we checked for a valid image file, now we need to do validations for blog icons
|
||||
return function blogIconValidation(req, res, next) {
|
||||
var iconExtensions = (config.get('uploads').icons && config.get('uploads').icons.extensions) || [];
|
||||
const iconExtensions = (config.get('uploads').icons && config.get('uploads').icons.extensions) || [];
|
||||
|
||||
// CASE: file should not be larger than 100kb
|
||||
if (!validIconFileSize(req.file.size)) {
|
||||
|
@ -19,7 +18,7 @@ module.exports = function blogIcon() {
|
|||
}));
|
||||
}
|
||||
|
||||
return imageLib.blogIcon.getIconDimensions(req.file.path).then(function (response) {
|
||||
return imageLib.blogIcon.getIconDimensions(req.file.path).then((response) => {
|
||||
// save the image dimensions in new property for file
|
||||
req.file.dimensions = response;
|
||||
|
||||
|
@ -46,7 +45,7 @@ module.exports = function blogIcon() {
|
|||
}
|
||||
|
||||
next();
|
||||
}).catch(function (err) {
|
||||
}).catch((err) => {
|
||||
next(err);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -4,12 +4,12 @@ const config = require('../../../config');
|
|||
const localUtils = require('../../utils');
|
||||
|
||||
module.exports = function upload(options) {
|
||||
var type = options.type;
|
||||
const type = options.type;
|
||||
|
||||
// if we finish the data/importer logic, we forward the request to the specified importer
|
||||
return function uploadValidation(req, res, next) {
|
||||
var extensions = (config.get('uploads')[type] && config.get('uploads')[type].extensions) || [],
|
||||
contentTypes = (config.get('uploads')[type] && config.get('uploads')[type].contentTypes) || [];
|
||||
const extensions = (config.get('uploads')[type] && config.get('uploads')[type].extensions) || [];
|
||||
const contentTypes = (config.get('uploads')[type] && config.get('uploads')[type].contentTypes) || [];
|
||||
|
||||
req.file = req.file || {};
|
||||
req.file.name = req.file.originalname;
|
||||
|
@ -18,7 +18,7 @@ module.exports = function upload(options) {
|
|||
// Check if a file was provided
|
||||
if (!localUtils.checkFileExists(req.file)) {
|
||||
return next(new common.errors.NoPermissionError({
|
||||
message: common.i18n.t('errors.api.' + type + '.missingFile')
|
||||
message: common.i18n.t(`errors.api.${type}.missingFile`)
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ module.exports = function upload(options) {
|
|||
// Check if the file is valid
|
||||
if (!localUtils.checkFileIsValid(req.file, contentTypes, extensions)) {
|
||||
return next(new common.errors.UnsupportedMediaTypeError({
|
||||
message: common.i18n.t('errors.api.' + type + '.invalidFile', {extensions: extensions})
|
||||
message: common.i18n.t(`errors.api.${type}.invalidFile`, {extensions: extensions})
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
var debug = require('ghost-ignition').debug('app'),
|
||||
express = require('express'),
|
||||
const debug = require('ghost-ignition').debug('app');
|
||||
const express = require('express');
|
||||
|
||||
// App requires
|
||||
config = require('../config'),
|
||||
// App requires
|
||||
const config = require('../config');
|
||||
|
||||
// middleware
|
||||
compress = require('compression'),
|
||||
netjet = require('netjet'),
|
||||
// middleware
|
||||
const compress = require('compression');
|
||||
const netjet = require('netjet');
|
||||
|
||||
// local middleware
|
||||
ghostLocals = require('./middleware/ghost-locals'),
|
||||
logRequest = require('./middleware/log-request');
|
||||
// local middleware
|
||||
const ghostLocals = require('./middleware/ghost-locals');
|
||||
const logRequest = require('./middleware/log-request');
|
||||
|
||||
module.exports = function setupParentApp(options = {}) {
|
||||
debug('ParentApp setup start');
|
||||
var parentApp = express();
|
||||
const parentApp = express();
|
||||
|
||||
// ## Global settings
|
||||
|
||||
|
|
|
@ -1,38 +1,40 @@
|
|||
var debug = require('ghost-ignition').debug('blog'),
|
||||
path = require('path'),
|
||||
express = require('express'),
|
||||
setPrototypeOf = require('setprototypeof'),
|
||||
const debug = require('ghost-ignition').debug('blog');
|
||||
const path = require('path');
|
||||
const express = require('express');
|
||||
|
||||
// App requires
|
||||
config = require('../../config'),
|
||||
apps = require('../../services/apps'),
|
||||
constants = require('../../lib/constants'),
|
||||
storage = require('../../adapters/storage'),
|
||||
urlService = require('../../services/url'),
|
||||
// this module is missing in package.json
|
||||
const setPrototypeOf = require('setprototypeof');
|
||||
|
||||
// This should probably be an internal app
|
||||
sitemapHandler = require('../../data/xml/sitemap/handler'),
|
||||
// App requires
|
||||
const config = require('../../config');
|
||||
const apps = require('../../services/apps');
|
||||
const constants = require('../../lib/constants');
|
||||
const storage = require('../../adapters/storage');
|
||||
const urlService = require('../../services/url');
|
||||
|
||||
// Route Service
|
||||
siteRoutes = require('./routes'),
|
||||
// This should probably be an internal app
|
||||
const sitemapHandler = require('../../data/xml/sitemap/handler');
|
||||
|
||||
// Global/shared middleware
|
||||
cacheControl = require('../middleware/cache-control'),
|
||||
errorHandler = require('../middleware/error-handler'),
|
||||
frontendClient = require('../middleware/frontend-client'),
|
||||
maintenance = require('../middleware/maintenance'),
|
||||
prettyURLs = require('../middleware/pretty-urls'),
|
||||
urlRedirects = require('../middleware/url-redirects'),
|
||||
// Route Service
|
||||
const siteRoutes = require('./routes');
|
||||
|
||||
// local middleware
|
||||
servePublicFile = require('../middleware/serve-public-file'),
|
||||
staticTheme = require('../middleware/static-theme'),
|
||||
customRedirects = require('../middleware/custom-redirects'),
|
||||
serveFavicon = require('../middleware/serve-favicon'),
|
||||
adminRedirects = require('../middleware/admin-redirects'),
|
||||
// Global/shared middleware
|
||||
const cacheControl = require('../middleware/cache-control');
|
||||
const errorHandler = require('../middleware/error-handler');
|
||||
const frontendClient = require('../middleware/frontend-client');
|
||||
const maintenance = require('../middleware/maintenance');
|
||||
const prettyURLs = require('../middleware/pretty-urls');
|
||||
const urlRedirects = require('../middleware/url-redirects');
|
||||
|
||||
// middleware for themes
|
||||
themeMiddleware = require('../../services/themes').middleware;
|
||||
// local middleware
|
||||
const servePublicFile = require('../middleware/serve-public-file');
|
||||
const staticTheme = require('../middleware/static-theme');
|
||||
const customRedirects = require('../middleware/custom-redirects');
|
||||
const serveFavicon = require('../middleware/serve-favicon');
|
||||
const adminRedirects = require('../middleware/admin-redirects');
|
||||
|
||||
// middleware for themes
|
||||
const themeMiddleware = require('../../services/themes').middleware;
|
||||
|
||||
let router;
|
||||
|
||||
|
@ -43,7 +45,7 @@ function SiteRouter(req, res, next) {
|
|||
module.exports = function setupSiteApp(options = {}) {
|
||||
debug('Site setup start');
|
||||
|
||||
var siteApp = express();
|
||||
const siteApp = express();
|
||||
|
||||
// ## App - specific code
|
||||
// set the view engine
|
||||
|
@ -104,8 +106,9 @@ module.exports = function setupSiteApp(options = {}) {
|
|||
|
||||
// setup middleware for internal apps
|
||||
// @TODO: refactor this to be a proper app middleware hook for internal & external apps
|
||||
config.get('apps:internal').forEach(function (appName) {
|
||||
var app = require(path.join(config.get('paths').internalAppPath, appName));
|
||||
config.get('apps:internal').forEach((appName) => {
|
||||
const app = require(path.join(config.get('paths').internalAppPath, appName));
|
||||
|
||||
if (app.hasOwnProperty('setupMiddleware')) {
|
||||
app.setupMiddleware(siteApp);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
const url = require('url'),
|
||||
_ = require('lodash');
|
||||
const url = require('url');
|
||||
|
||||
let _private = {};
|
||||
const _private = {};
|
||||
|
||||
_private.removeDoubleCharacters = function removeDoubleCharacters(character, string) {
|
||||
let stringArray = string.split('');
|
||||
_private.removeDoubleCharacters = (character, string) => {
|
||||
const stringArray = string.split('');
|
||||
|
||||
return stringArray.reduce(function (newString, currentCharacter, index) {
|
||||
return stringArray.reduce((newString, currentCharacter, index) => {
|
||||
if (
|
||||
currentCharacter === character &&
|
||||
stringArray[index + 1] === character
|
||||
|
@ -14,12 +13,12 @@ _private.removeDoubleCharacters = function removeDoubleCharacters(character, str
|
|||
return newString;
|
||||
}
|
||||
|
||||
return newString + currentCharacter;
|
||||
return `${newString}${currentCharacter}`;
|
||||
}, '');
|
||||
};
|
||||
|
||||
module.exports.removeOpenRedirectFromUrl = function removeOpenRedirectFromUrl(urlString) {
|
||||
let parsedUrl = url.parse(urlString);
|
||||
const parsedUrl = url.parse(urlString);
|
||||
|
||||
return (
|
||||
// http://
|
||||
|
@ -38,8 +37,9 @@ module.exports.checkFileExists = function checkFileExists(fileData) {
|
|||
module.exports.checkFileIsValid = function checkFileIsValid(fileData, types, extensions) {
|
||||
const type = fileData.mimetype;
|
||||
|
||||
if (_.includes(types, type) && _.includes(extensions, fileData.ext)) {
|
||||
if (types.includes(type) && extensions.includes(fileData.ext)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue