mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-24 06:35:49 +03:00
Switch to Eslint (#9197)
refs #9178 * Add eslint deps, remove old lint deps * Add eslint config, remove old lint configs * Config for server and tests are different * Tweaked rules to suit us * Fix linting in codebase - lots of indent changes. * Fix a real broken test
This commit is contained in:
parent
a7fe464d64
commit
bcf5a1bc34
300
.eslintrc.json
Normal file
300
.eslintrc.json
Normal file
@ -0,0 +1,300 @@
|
||||
{
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"accessor-pairs": "error",
|
||||
"array-bracket-newline": "off",
|
||||
"array-bracket-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"array-callback-return": "off",
|
||||
"array-element-newline": "off",
|
||||
"arrow-body-style": "error",
|
||||
"arrow-parens": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"arrow-spacing": [
|
||||
"error",
|
||||
{
|
||||
"after": true,
|
||||
"before": true
|
||||
}
|
||||
],
|
||||
"block-scoped-var": "error",
|
||||
"brace-style": [
|
||||
"error",
|
||||
"1tbs",
|
||||
{
|
||||
"allowSingleLine": true
|
||||
}
|
||||
],
|
||||
"callback-return": "error",
|
||||
"camelcase": [
|
||||
"error",
|
||||
{
|
||||
"properties": "never"
|
||||
}
|
||||
],
|
||||
"capitalized-comments": "off",
|
||||
"class-methods-use-this": "off",
|
||||
"comma-dangle": "error",
|
||||
"comma-spacing": "error",
|
||||
"comma-style": [
|
||||
"error",
|
||||
"last"
|
||||
],
|
||||
"complexity": "off",
|
||||
"computed-property-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"consistent-return": "off",
|
||||
"consistent-this": "off",
|
||||
"curly": "error",
|
||||
"default-case": "error",
|
||||
"dot-location": [
|
||||
"error",
|
||||
"property"
|
||||
],
|
||||
"dot-notation": "error",
|
||||
"eol-last": "error",
|
||||
"eqeqeq": "error",
|
||||
"for-direction": "error",
|
||||
"func-call-spacing": "error",
|
||||
"func-name-matching": "off",
|
||||
"func-names": "off",
|
||||
"func-style": "off",
|
||||
"function-paren-newline": "off",
|
||||
"generator-star-spacing": "error",
|
||||
"getter-return": "error",
|
||||
"global-require": "off",
|
||||
"guard-for-in": "error",
|
||||
"handle-callback-err": "error",
|
||||
"id-blacklist": "error",
|
||||
"id-length": "off",
|
||||
"id-match": "error",
|
||||
"indent": [
|
||||
"error",
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"indent-legacy": "off",
|
||||
"init-declarations": "off",
|
||||
"jsx-quotes": "error",
|
||||
"key-spacing": "error",
|
||||
"keyword-spacing": "error",
|
||||
"line-comment-position": "off",
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"lines-around-comment": "off",
|
||||
"lines-around-directive": "off",
|
||||
"lines-between-class-members": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"max-depth": "error",
|
||||
"max-len": "off",
|
||||
"max-lines": "off",
|
||||
"max-nested-callbacks": "error",
|
||||
"max-params": "off",
|
||||
"max-statements": "off",
|
||||
"max-statements-per-line": "off",
|
||||
"multiline-comment-style": "off",
|
||||
"multiline-ternary": "off",
|
||||
"new-parens": "error",
|
||||
"newline-after-var": "off",
|
||||
"newline-before-return": "off",
|
||||
"newline-per-chained-call": "off",
|
||||
"no-alert": "error",
|
||||
"no-array-constructor": "error",
|
||||
"no-await-in-loop": "error",
|
||||
"no-bitwise": "off",
|
||||
"no-buffer-constructor": "off",
|
||||
"no-caller": "error",
|
||||
"no-catch-shadow": "error",
|
||||
"no-confusing-arrow": "error",
|
||||
"no-continue": "error",
|
||||
"no-div-regex": "off",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-else-return": "off",
|
||||
"no-empty-function": "off",
|
||||
"no-eq-null": "error",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-label": "error",
|
||||
"no-extra-parens": "off",
|
||||
"no-floating-decimal": "error",
|
||||
"no-implicit-globals": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-inline-comments": "off",
|
||||
"no-inner-declarations": [
|
||||
"error",
|
||||
"functions"
|
||||
],
|
||||
"no-invalid-this": "error",
|
||||
"no-iterator": "error",
|
||||
"no-label-var": "error",
|
||||
"no-labels": "error",
|
||||
"no-lone-blocks": "error",
|
||||
"no-lonely-if": "off",
|
||||
"no-loop-func": "error",
|
||||
"no-magic-numbers": "off",
|
||||
"no-mixed-operators": "off",
|
||||
"no-mixed-requires": "off",
|
||||
"no-multi-assign": "off",
|
||||
"no-multi-spaces": "off",
|
||||
"no-multi-str": "error",
|
||||
"no-multiple-empty-lines": "error",
|
||||
"no-native-reassign": "error",
|
||||
"no-negated-condition": "off",
|
||||
"no-negated-in-lhs": "error",
|
||||
"no-nested-ternary": "off",
|
||||
"no-new": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-object": "error",
|
||||
"no-new-require": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-param-reassign": "off",
|
||||
"no-path-concat": "off",
|
||||
"no-plusplus": "error",
|
||||
"no-process-env": "off",
|
||||
"no-process-exit": "off",
|
||||
"no-proto": "error",
|
||||
"no-prototype-builtins": "off",
|
||||
"no-restricted-globals": "error",
|
||||
"no-restricted-imports": "error",
|
||||
"no-restricted-modules": "error",
|
||||
"no-restricted-properties": "error",
|
||||
"no-restricted-syntax": "error",
|
||||
"no-return-assign": "error",
|
||||
"no-return-await": "error",
|
||||
"no-script-url": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "off",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-spaced-func": "error",
|
||||
"no-sync": "off",
|
||||
"no-tabs": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-ternary": "off",
|
||||
"no-throw-literal": "error",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-undefined": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-unneeded-ternary": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-useless-call": "error",
|
||||
"no-useless-computed-key": "error",
|
||||
"no-useless-concat": "off",
|
||||
"no-useless-constructor": "error",
|
||||
"no-useless-escape": "off",
|
||||
"no-useless-rename": "error",
|
||||
"no-useless-return": "error",
|
||||
"no-var": "off",
|
||||
"no-void": "error",
|
||||
"no-warning-comments": "off",
|
||||
"no-whitespace-before-property": "error",
|
||||
"no-with": "error",
|
||||
"nonblock-statement-body-position": "error",
|
||||
"object-curly-newline": [
|
||||
"error",
|
||||
{
|
||||
"consistent": true
|
||||
}
|
||||
],
|
||||
"object-curly-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"object-property-newline": [
|
||||
"error",
|
||||
{
|
||||
"allowMultiplePropertiesPerLine": true
|
||||
}
|
||||
],
|
||||
"object-shorthand": "off",
|
||||
"one-var": "off",
|
||||
"one-var-declaration-per-line": "off",
|
||||
"operator-assignment": "off",
|
||||
"operator-linebreak": "off",
|
||||
"padded-blocks": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"padding-line-between-statements": "error",
|
||||
"prefer-arrow-callback": "off",
|
||||
"prefer-const": "off",
|
||||
"prefer-destructuring": "off",
|
||||
"prefer-numeric-literals": "error",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"prefer-reflect": "off",
|
||||
"prefer-rest-params": "off",
|
||||
"prefer-spread": "off",
|
||||
"prefer-template": "off",
|
||||
"quote-props": [
|
||||
"error",
|
||||
"as-needed"
|
||||
],
|
||||
"quotes": ["error", "single"],
|
||||
"radix": "off",
|
||||
"require-await": "error",
|
||||
"require-jsdoc": "off",
|
||||
"rest-spread-spacing": "error",
|
||||
"semi": ["error", "always"],
|
||||
"semi-spacing": "error",
|
||||
"semi-style": [
|
||||
"error",
|
||||
"last"
|
||||
],
|
||||
"sort-imports": "error",
|
||||
"sort-keys": "off",
|
||||
"sort-vars": "off",
|
||||
"space-before-blocks": "error",
|
||||
"space-before-function-paren": [
|
||||
"error",
|
||||
{
|
||||
"anonymous": "always",
|
||||
"named": "never"
|
||||
}
|
||||
],
|
||||
"space-in-parens": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"space-infix-ops": "error",
|
||||
"space-unary-ops": "error",
|
||||
"spaced-comment": "error",
|
||||
"strict": "off",
|
||||
"switch-colon-spacing": "error",
|
||||
"symbol-description": "error",
|
||||
"template-curly-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"template-tag-spacing": "error",
|
||||
"unicode-bom": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"valid-jsdoc": "off",
|
||||
"vars-on-top": "off",
|
||||
"wrap-iife": "off",
|
||||
"wrap-regex": "off",
|
||||
"yield-star-spacing": "error",
|
||||
"yoda": "error"
|
||||
}
|
||||
}
|
75
.jscsrc
75
.jscsrc
@ -1,75 +0,0 @@
|
||||
{
|
||||
"requireCurlyBraces": [
|
||||
"if",
|
||||
"else",
|
||||
"for",
|
||||
"while",
|
||||
"do",
|
||||
"try",
|
||||
"catch"
|
||||
],
|
||||
"requireSpaceAfterKeywords": [
|
||||
"if",
|
||||
"else",
|
||||
"for",
|
||||
"while",
|
||||
"do",
|
||||
"switch",
|
||||
"case",
|
||||
"return",
|
||||
"try",
|
||||
"catch",
|
||||
"function",
|
||||
"typeof"
|
||||
],
|
||||
"requireSpaceBeforeBlockStatements": true,
|
||||
"requireParenthesesAroundIIFE": true,
|
||||
"requireSpacesInConditionalExpression": true,
|
||||
"disallowSpacesInNamedFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInFunctionDeclaration": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"requireSpacesInAnonymousFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"requireMultipleVarDecl": "onevar",
|
||||
"requireBlocksOnNewline": 1,
|
||||
"disallowPaddingNewlinesInBlocks": true,
|
||||
"disallowEmptyBlocks": true,
|
||||
"disallowSpacesInsideObjectBrackets": "all",
|
||||
"disallowSpacesInsideArrayBrackets": true,
|
||||
"disallowSpacesInsideParentheses": true,
|
||||
"disallowQuotedKeysInObjects": true,
|
||||
"disallowSpaceAfterObjectKeys": true,
|
||||
"requireCommaBeforeLineBreak": true,
|
||||
"disallowSpaceAfterPrefixUnaryOperators": true,
|
||||
"disallowSpaceBeforePostfixUnaryOperators": true,
|
||||
"disallowSpaceBeforeBinaryOperators": [
|
||||
","
|
||||
],
|
||||
"requireSpaceBeforeBinaryOperators": true,
|
||||
"requireSpaceAfterBinaryOperators": true,
|
||||
"requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
|
||||
"disallowKeywords": [ "with" ],
|
||||
"disallowMultipleLineBreaks": true,
|
||||
"validateQuoteMarks": "'",
|
||||
"validateIndentation": 4,
|
||||
"disallowMixedSpacesAndTabs": true,
|
||||
"disallowTrailingWhitespace": true,
|
||||
"disallowTrailingComma": true,
|
||||
"disallowKeywordsOnNewLine": [ "else" ],
|
||||
"requireLineFeedAtFileEnd": true,
|
||||
"requireCapitalizedConstructors": true,
|
||||
"safeContextKeyword": ["self"],
|
||||
"requireDotNotation": true,
|
||||
"disallowYodaConditions": true,
|
||||
"jsDoc": {
|
||||
"checkParamNames": true,
|
||||
"checkRedundantParams": true,
|
||||
"requireParamTypes": true
|
||||
},
|
||||
"requireSpaceAfterLineComment": true,
|
||||
"disallowNewlineBeforeBlockStatements": true
|
||||
}
|
27
.jshintrc
27
.jshintrc
@ -1,27 +0,0 @@
|
||||
{
|
||||
"node": true,
|
||||
"browser": false,
|
||||
"strict": false,
|
||||
"sub": true,
|
||||
"eqeqeq": true,
|
||||
"laxbreak": true,
|
||||
"bitwise": true,
|
||||
"curly": true,
|
||||
"forin": true,
|
||||
"immed": true,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"plusplus": true,
|
||||
"regexp": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"mocha": true,
|
||||
"indent": 4,
|
||||
"predef": [
|
||||
"-Promise"
|
||||
],
|
||||
"esversion": 6
|
||||
}
|
77
Gruntfile.js
77
Gruntfile.js
@ -6,9 +6,9 @@
|
||||
//
|
||||
// **Debug tip:** If you have any problems with any Grunt tasks, try running them with the `--verbose` command
|
||||
|
||||
// jshint unused: false
|
||||
var overrides = require('./core/server/overrides'),
|
||||
config = require('./core/server/config'),
|
||||
require('./core/server/overrides');
|
||||
|
||||
var config = require('./core/server/config'),
|
||||
utils = require('./core/server/utils'),
|
||||
_ = require('lodash'),
|
||||
chalk = require('chalk'),
|
||||
@ -68,8 +68,8 @@ var overrides = require('./core/server/overrides'),
|
||||
}
|
||||
},
|
||||
express: {
|
||||
files: ['core/ghost-server.js', 'core/server/**/*.js', 'config.*.json', '!config.testing.json'],
|
||||
tasks: ['express:dev'],
|
||||
files: ['core/ghost-server.js', 'core/server/**/*.js', 'config.*.json', '!config.testing.json'],
|
||||
tasks: ['express:dev'],
|
||||
options: {
|
||||
nospawn: true,
|
||||
livereload: true
|
||||
@ -95,42 +95,31 @@ var overrides = require('./core/server/overrides'),
|
||||
}
|
||||
},
|
||||
|
||||
// ### grunt-contrib-jshint
|
||||
// ### grunt-eslint
|
||||
// Linting rules, run as part of `grunt validate`. See [grunt validate](#validate) and its subtasks for
|
||||
// more information.
|
||||
jshint: {
|
||||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
},
|
||||
|
||||
server: [
|
||||
'*.js',
|
||||
'!config.*.json', // note: i added this, do we want this linted?
|
||||
'core/*.js',
|
||||
'core/server/**/*.js',
|
||||
'core/test/**/*.js',
|
||||
'!core/test/coverage/**',
|
||||
'!core/server/public/**/*.js'
|
||||
]
|
||||
},
|
||||
|
||||
jscs: {
|
||||
options: {
|
||||
config: true
|
||||
},
|
||||
|
||||
eslint: {
|
||||
server: {
|
||||
files: {
|
||||
src: [
|
||||
'*.js',
|
||||
'!config.*.json', // note: i added this, do we want this linted?
|
||||
'core/*.js',
|
||||
'core/server/**/*.js',
|
||||
'core/test/**/*.js',
|
||||
'!core/test/coverage/**',
|
||||
'!core/server/public/**/*.js'
|
||||
]
|
||||
}
|
||||
options: {
|
||||
config: '.eslintrc.json'
|
||||
},
|
||||
src: [
|
||||
'*.js',
|
||||
'core/*.js',
|
||||
'core/server/*.js',
|
||||
'core/server/**/*.js',
|
||||
'!core/server/public/**/*.js'
|
||||
]
|
||||
},
|
||||
test: {
|
||||
options: {
|
||||
config: './core/test/.eslintrc.json'
|
||||
},
|
||||
src: [
|
||||
'core/test/*.js',
|
||||
'core/test/**/*.js',
|
||||
'!core/test/coverage/**'
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@ -403,7 +392,7 @@ var overrides = require('./core/server/overrides'),
|
||||
grunt.registerTask('help',
|
||||
'Outputs help information if you type `grunt help` instead of `grunt --help`',
|
||||
function () {
|
||||
console.log('Type `grunt --help` to get the details of available grunt tasks.');
|
||||
grunt.log.writeln('Type `grunt --help` to get the details of available grunt tasks.');
|
||||
});
|
||||
|
||||
// ### Documentation
|
||||
@ -516,9 +505,9 @@ var overrides = require('./core/server/overrides'),
|
||||
|
||||
// ### Lint
|
||||
//
|
||||
// `grunt lint` will run the linter and the code style checker so you can make sure your code is pretty
|
||||
grunt.registerTask('lint', 'Run the code style checks and linter for server',
|
||||
['jshint', 'jscs']
|
||||
// `grunt lint` will run the linter
|
||||
grunt.registerTask('lint', 'Run the code style checks for server & tests',
|
||||
['eslint']
|
||||
);
|
||||
|
||||
// ### test-setup *(utility)(
|
||||
@ -630,11 +619,11 @@ var overrides = require('./core/server/overrides'),
|
||||
grunt.registerTask('master-warn',
|
||||
'Outputs a warning to runners of grunt prod, that master shouldn\'t be used for live blogs',
|
||||
function () {
|
||||
console.log(chalk.red(
|
||||
grunt.log.writeln(chalk.red(
|
||||
'Use the ' + chalk.bold('stable') + ' branch for live blogs. '
|
||||
+ chalk.bold.underline('Never') + ' master!'
|
||||
));
|
||||
console.log('>', 'Always two there are, no more, no less. A master and a ' + chalk.bold('stable') + '.');
|
||||
grunt.log.writeln('>', 'Always two there are, no more, no less. A master and a ' + chalk.bold('stable') + '.');
|
||||
});
|
||||
|
||||
// ## Building assets
|
||||
|
@ -40,9 +40,8 @@ exports.createAdapter = function (options) {
|
||||
// CASE: only throw error if module does exist
|
||||
if (err.code !== 'MODULE_NOT_FOUND') {
|
||||
return Promise.reject(new errors.IncorrectUsageError({err: err}));
|
||||
}
|
||||
// CASE: if module not found it can be an error within the adapter (cannot find bluebird for example)
|
||||
else if (err.code === 'MODULE_NOT_FOUND' && err.message.indexOf(contentPath + activeAdapter) === -1) {
|
||||
} else if (err.code === 'MODULE_NOT_FOUND' && err.message.indexOf(contentPath + activeAdapter) === -1) {
|
||||
return Promise.reject(new errors.IncorrectUsageError({err: err, help: 'Please check the imports are valid in ' + contentPath + activeAdapter}));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
// jscs:disable requireMultipleVarDecl
|
||||
|
||||
'use strict';
|
||||
|
||||
// # Local File System Image Storage module
|
||||
@ -18,7 +16,6 @@ var serveStatic = require('express').static,
|
||||
StorageBase = require('ghost-storage-base');
|
||||
|
||||
class LocalFileStore extends StorageBase {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
@ -37,16 +37,14 @@ function getStorage() {
|
||||
help: 'Add \'use strict\'; on top of your adapter.',
|
||||
err: err
|
||||
});
|
||||
}
|
||||
// CASE: if module not found it can be an error within the adapter (cannot find bluebird for example)
|
||||
else if (err.code === 'MODULE_NOT_FOUND' && err.message.indexOf(config.getContentPath('storage') + storageChoice) === -1) {
|
||||
} else if (err.code === 'MODULE_NOT_FOUND' && err.message.indexOf(config.getContentPath('storage') + storageChoice) === -1) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: 'We have detected an error in your custom storage adapter.',
|
||||
err: err
|
||||
});
|
||||
}
|
||||
// CASE: only throw error if module does exist
|
||||
else if (err.code !== 'MODULE_NOT_FOUND') {
|
||||
} else if (err.code !== 'MODULE_NOT_FOUND') {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: 'We have detected an unknown error in your custom storage adapter.',
|
||||
err: err
|
||||
|
@ -11,7 +11,6 @@ var debug = require('ghost-ignition').debug('admin:controller'),
|
||||
// Path: /ghost/
|
||||
// Method: GET
|
||||
module.exports = function adminController(req, res) {
|
||||
/*jslint unparam:true*/
|
||||
debug('index called');
|
||||
|
||||
updateCheck().then(function then() {
|
||||
@ -27,7 +26,11 @@ module.exports = function adminController(req, res) {
|
||||
location: 'upgrade.new-version-available',
|
||||
dismissible: false,
|
||||
message: i18n.t('notices.controllers.newVersionAvailable',
|
||||
{version: updateVersion, link: '<a href="https://docs.ghost.org/docs/upgrade" target="_blank">Click here</a>'})};
|
||||
{
|
||||
version: updateVersion,
|
||||
link: '<a href="https://docs.ghost.org/docs/upgrade" target="_blank">Click here</a>'
|
||||
})
|
||||
};
|
||||
|
||||
return api.notifications.browse({context: {internal: true}}).then(function then(results) {
|
||||
if (!_.some(results.notifications, {message: notification.message})) {
|
||||
|
@ -5,7 +5,6 @@ var debug = require('ghost-ignition').debug('admin:serviceworker'),
|
||||
// Path: /ghost/sw.js|sw-registration.js
|
||||
// Method: GET
|
||||
module.exports = function adminController(req, res) {
|
||||
/*jslint unparam:true*/
|
||||
debug('serviceworker called');
|
||||
|
||||
var sw = path.join(__dirname, '..', '..', 'built', 'assets', 'sw.js'),
|
||||
|
@ -25,11 +25,11 @@ function getAboutConfig() {
|
||||
|
||||
function getBaseConfig() {
|
||||
return {
|
||||
useGravatar: !config.isPrivacyDisabled('useGravatar'),
|
||||
publicAPI: config.get('publicAPI') === true,
|
||||
blogUrl: apiUtils.url.urlFor('home', true),
|
||||
blogTitle: settingsCache.get('title'),
|
||||
routeKeywords: config.get('routeKeywords'),
|
||||
useGravatar: !config.isPrivacyDisabled('useGravatar'),
|
||||
publicAPI: config.get('publicAPI') === true,
|
||||
blogUrl: apiUtils.url.urlFor('home', true),
|
||||
blogTitle: settingsCache.get('title'),
|
||||
routeKeywords: config.get('routeKeywords'),
|
||||
clientExtensions: config.get('clientExtensions')
|
||||
};
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ db = {
|
||||
return Promise.each(collections, function then(Collection) {
|
||||
return Collection.invokeThen('destroy', queryOpts);
|
||||
}).return({db: []})
|
||||
.catch(function (err) {
|
||||
throw new errors.GhostError({err: err});
|
||||
});
|
||||
.catch(function (err) {
|
||||
throw new errors.GhostError({err: err});
|
||||
});
|
||||
}
|
||||
|
||||
tasks = [
|
||||
|
@ -93,7 +93,7 @@ notifications = {
|
||||
id: ObjectId.generate()
|
||||
});
|
||||
|
||||
existingNotification = _.find(notificationsStore, {message:notification.message});
|
||||
existingNotification = _.find(notificationsStore, {message: notification.message});
|
||||
|
||||
if (!existingNotification) {
|
||||
notificationsStore.push(notification);
|
||||
|
@ -59,8 +59,10 @@ exports.publishPost = function publishPost(object, options) {
|
||||
return Promise.reject(new errors.NotFoundError({message: i18n.t('errors.api.job.publishInThePast')}));
|
||||
}
|
||||
|
||||
return postsAPI.edit({
|
||||
posts: [{status: 'published'}]},
|
||||
return postsAPI.edit(
|
||||
{
|
||||
posts: [{status: 'published'}]
|
||||
},
|
||||
_.pick(cleanOptions, ['context', 'id', 'transacting', 'forUpdate', 'opts'])
|
||||
);
|
||||
});
|
||||
|
@ -10,8 +10,9 @@ var Promise = require('bluebird'),
|
||||
settingsCache = require('../settings/cache'),
|
||||
docName = 'settings',
|
||||
settings,
|
||||
settingsFilter,
|
||||
settingsResult,
|
||||
canEditAllSettings,
|
||||
canEditAllSettings;
|
||||
|
||||
// ## Helpers
|
||||
|
||||
|
@ -25,26 +25,26 @@ var Promise = require('bluebird'),
|
||||
ampHTML;
|
||||
|
||||
allowedAMPTags = ['html', 'body', 'article', 'section', 'nav', 'aside', 'h1', 'h2',
|
||||
'h3', 'h4', 'h5', 'h6', 'header', 'footer', 'address', 'p', 'hr',
|
||||
'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure',
|
||||
'figcaption', 'div', 'main', 'a', 'em', 'strong', 'small', 's', 'cite',
|
||||
'q', 'dfn', 'abbr', 'data', 'time', 'code', 'var', 'samp', 'kbd', 'sub',
|
||||
'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'bdi',
|
||||
'bdo', 'span', 'br', 'wbr', 'ins', 'del', 'source', 'track', 'svg', 'g',
|
||||
'path', 'glyph', 'glyphref', 'marker', 'view', 'circle', 'line', 'polygon',
|
||||
'polyline', 'rect', 'text', 'textpath', 'tref', 'tspan', 'clippath',
|
||||
'filter', 'lineargradient', 'radialgradient', 'mask', 'pattern', 'vkern',
|
||||
'hkern', 'defs', 'stop', 'use', 'foreignobject', 'symbol', 'desc', 'title',
|
||||
'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td',
|
||||
'th', 'button', 'noscript', 'acronym', 'center', 'dir', 'hgroup', 'listing',
|
||||
'multicol', 'nextid', 'nobr', 'spacer', 'strike', 'tt', 'xmp', 'amp-img',
|
||||
'amp-video', 'amp-ad', 'amp-embed', 'amp-anim', 'amp-iframe', 'amp-pixel',
|
||||
'amp-audio', 'O:P'];
|
||||
'h3', 'h4', 'h5', 'h6', 'header', 'footer', 'address', 'p', 'hr',
|
||||
'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure',
|
||||
'figcaption', 'div', 'main', 'a', 'em', 'strong', 'small', 's', 'cite',
|
||||
'q', 'dfn', 'abbr', 'data', 'time', 'code', 'var', 'samp', 'kbd', 'sub',
|
||||
'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'bdi',
|
||||
'bdo', 'span', 'br', 'wbr', 'ins', 'del', 'source', 'track', 'svg', 'g',
|
||||
'path', 'glyph', 'glyphref', 'marker', 'view', 'circle', 'line', 'polygon',
|
||||
'polyline', 'rect', 'text', 'textpath', 'tref', 'tspan', 'clippath',
|
||||
'filter', 'lineargradient', 'radialgradient', 'mask', 'pattern', 'vkern',
|
||||
'hkern', 'defs', 'stop', 'use', 'foreignobject', 'symbol', 'desc', 'title',
|
||||
'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td',
|
||||
'th', 'button', 'noscript', 'acronym', 'center', 'dir', 'hgroup', 'listing',
|
||||
'multicol', 'nextid', 'nobr', 'spacer', 'strike', 'tt', 'xmp', 'amp-img',
|
||||
'amp-video', 'amp-ad', 'amp-embed', 'amp-anim', 'amp-iframe', 'amp-pixel',
|
||||
'amp-audio', 'O:P'];
|
||||
|
||||
allowedAMPAttributes = {
|
||||
'*': ['itemid', 'itemprop', 'itemref', 'itemscope', 'itemtype', 'accesskey', 'class', 'dir', 'draggable',
|
||||
'id', 'lang', 'tabindex', 'title', 'translate', 'aria-*', 'role', 'placeholder', 'fallback', 'lightbox',
|
||||
'overflow', 'amp-access', 'amp-access-*', 'i-amp-access-id'],
|
||||
'id', 'lang', 'tabindex', 'title', 'translate', 'aria-*', 'role', 'placeholder', 'fallback', 'lightbox',
|
||||
'overflow', 'amp-access', 'amp-access-*', 'i-amp-access-id'],
|
||||
h1: ['align'],
|
||||
h2: ['align'],
|
||||
h3: ['align'],
|
||||
@ -105,14 +105,14 @@ allowedAMPAttributes = {
|
||||
'amp-img': ['media', 'noloading', 'alt', 'attribution', 'placeholder', 'src', 'srcset', 'width', 'height', 'layout'],
|
||||
'amp-pixel': ['src'],
|
||||
'amp-video': ['src', 'srcset', 'media', 'noloading', 'width', 'height', 'layout', 'alt', 'attribution',
|
||||
'autoplay', 'controls', 'loop', 'muted', 'poster', 'preload'],
|
||||
'autoplay', 'controls', 'loop', 'muted', 'poster', 'preload'],
|
||||
'amp-embed': ['media', 'noloading', 'width', 'height', 'layout', 'type', 'data-*', 'json'],
|
||||
'amp-ad': ['media', 'noloading', 'width', 'height', 'layout', 'type', 'data-*', 'json'],
|
||||
// extended components we support
|
||||
'amp-anim': ['media', 'noloading', 'alt', 'attribution', 'placeholder', 'src', 'srcset', 'width', 'height', 'layout'],
|
||||
'amp-audio': ['src', 'width', 'height', 'autoplay', 'loop', 'muted', 'controls'],
|
||||
'amp-iframe': ['src', 'srcdoc', 'width', 'height', 'layout', 'frameborder', 'allowfullscreen', 'allowtransparency',
|
||||
'sandbox', 'referrerpolicy']
|
||||
'sandbox', 'referrerpolicy']
|
||||
};
|
||||
|
||||
function getAmperizeHTML(html, post) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
var SimpleDom = require('simple-dom'),
|
||||
tokenizer = require('simple-html-tokenizer').tokenize,
|
||||
var SimpleDom = require('simple-dom'),
|
||||
tokenizer = require('simple-html-tokenizer').tokenize,
|
||||
parser;
|
||||
|
||||
module.exports = {
|
||||
name: 'card-html',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
parser = new SimpleDom.HTMLParser(tokenizer, opts.env.dom, SimpleDom.voidMap);
|
||||
return parser.parse('<div class="kg-card-html">' + opts.payload.html + '</div>');
|
||||
}
|
||||
};
|
||||
name: 'card-html',
|
||||
type: 'dom',
|
||||
render(opts) {
|
||||
parser = new SimpleDom.HTMLParser(tokenizer, opts.env.dom, SimpleDom.voidMap);
|
||||
return parser.parse('<div class="kg-card-html">' + opts.payload.html + '</div>');
|
||||
}
|
||||
};
|
||||
|
@ -1,19 +1,19 @@
|
||||
module.exports = {
|
||||
name: 'card-markdown',
|
||||
type: 'dom',
|
||||
render: function (opts) {
|
||||
var markdownConverter = require('../../../utils/markdown-converter'),
|
||||
html, element;
|
||||
name: 'card-markdown',
|
||||
type: 'dom',
|
||||
render: function (opts) {
|
||||
var markdownConverter = require('../../../utils/markdown-converter'),
|
||||
html, element;
|
||||
|
||||
// convert markdown to HTML ready for insertion into dom
|
||||
html = '<div class="kg-card-markdown">'
|
||||
+ markdownConverter.render(opts.payload.markdown || '')
|
||||
+ '</div>';
|
||||
// convert markdown to HTML ready for insertion into dom
|
||||
html = '<div class="kg-card-markdown">'
|
||||
+ markdownConverter.render(opts.payload.markdown || '')
|
||||
+ '</div>';
|
||||
|
||||
// use the SimpleDOM document to create a raw HTML section.
|
||||
// avoids parsing/rendering of potentially broken or unsupported HTML
|
||||
element = opts.env.dom.createRawHTMLSection(html);
|
||||
// use the SimpleDOM document to create a raw HTML section.
|
||||
// avoids parsing/rendering of potentially broken or unsupported HTML
|
||||
element = opts.env.dom.createRawHTMLSection(html);
|
||||
|
||||
return element;
|
||||
}
|
||||
};
|
||||
return element;
|
||||
}
|
||||
};
|
||||
|
@ -2,16 +2,14 @@
|
||||
// Usage: `{{input_password}}`
|
||||
//
|
||||
// Password input used on private.hbs for password-protected blogs
|
||||
//
|
||||
// We use the name input_password to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
// (less) dirty requires
|
||||
var proxy = require('../../../../helpers/proxy'),
|
||||
SafeString = proxy.SafeString,
|
||||
templates = proxy.templates;
|
||||
|
||||
module.exports = function input_password(options) {
|
||||
// We use the name input_password to match the helper for consistency:
|
||||
module.exports = function input_password(options) { // eslint-disable-line camelcase
|
||||
options = options || {};
|
||||
options.hash = options.hash || {};
|
||||
|
||||
|
@ -2,16 +2,14 @@
|
||||
// Usage: `{{input_email}}`
|
||||
//
|
||||
// Used by `{{subscribe_form}}`
|
||||
//
|
||||
// We use the name input_email to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
// (less) dirty requires
|
||||
var proxy = require('../../../../helpers/proxy'),
|
||||
SafeString = proxy.SafeString,
|
||||
templates = proxy.templates;
|
||||
|
||||
module.exports = function input_email(options) {
|
||||
// We use the name input_email to match the helper for consistency:
|
||||
module.exports = function input_email(options) { // eslint-disable-line camelcase
|
||||
options = options || {};
|
||||
options.hash = options.hash || {};
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
// # Subscribe Form Helper
|
||||
// Usage: `{{subscribe_form}}`
|
||||
//
|
||||
// We use the name subscribe_form to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
var _ = require('lodash'),
|
||||
|
||||
// (Less) dirty requires
|
||||
@ -38,7 +35,8 @@ subscribeScript =
|
||||
'})(window,document,\'querySelector\',\'value\');' +
|
||||
'</script>';
|
||||
|
||||
module.exports = function subscribe_form(options) {
|
||||
// We use the name subscribe_form to match the helper for consistency:
|
||||
module.exports = function subscribe_form(options) { // eslint-disable-line camelcase
|
||||
var root = options.data.root,
|
||||
data = _.merge({}, options.hash, _.pick(root, params), {
|
||||
action: url.urlJoin('/', url.getSubdir(), config.get('routeKeywords').subscribe, '/'),
|
||||
|
@ -29,8 +29,6 @@ function controller(req, res) {
|
||||
* For success cases, we don't have to worry, because then the input contained a valid email address.
|
||||
*/
|
||||
function errorHandler(error, req, res, next) {
|
||||
/*jshint unused:false */
|
||||
|
||||
req.body.email = '';
|
||||
|
||||
if (error.statusCode !== 404) {
|
||||
|
@ -86,7 +86,7 @@ function processQuery(query, slugParam) {
|
||||
function fetchData(channelOptions) {
|
||||
// @TODO improve this further
|
||||
var pageOptions = channelOptions.isRSS ?
|
||||
{options: channelOptions.postOptions} : fetchPostsPerPage(channelOptions.postOptions),
|
||||
{options: channelOptions.postOptions} : fetchPostsPerPage(channelOptions.postOptions),
|
||||
postQuery,
|
||||
props = {};
|
||||
|
||||
|
@ -11,8 +11,7 @@ JSONHandler = {
|
||||
contentTypes: ['application/octet-stream', 'application/json'],
|
||||
directories: [],
|
||||
|
||||
loadFile: function (files, startDir) {
|
||||
/*jshint unused:false */
|
||||
loadFile: function (files, startDir) { // eslint-disable-line no-unused-vars
|
||||
// @TODO: Handle multiple JSON files
|
||||
var filePath = files[0].path;
|
||||
|
||||
|
@ -87,7 +87,6 @@ MarkdownHandler = {
|
||||
directories: [],
|
||||
|
||||
loadFile: function (files, startDir) {
|
||||
/*jshint unused:false */
|
||||
var startDirRegex = startDir ? new RegExp('^' + startDir + '/') : new RegExp(''),
|
||||
posts = [],
|
||||
ops = [];
|
||||
|
@ -132,8 +132,8 @@ class PostsImporter extends BaseImporter {
|
||||
version: '0.3.1',
|
||||
markups: [],
|
||||
atoms: [],
|
||||
cards: [['card-markdown',{cardName: 'card-markdown',markdown: mobileDocContent}]],
|
||||
sections:[[10,0]]
|
||||
cards: [['card-markdown', {cardName: 'card-markdown', markdown: mobileDocContent}]],
|
||||
sections: [[10, 0]]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ function getExcerpt(html, truncateOptions) {
|
||||
// Strip other html
|
||||
excerpt = excerpt.replace(/<\/?[^>]+>/gi, '');
|
||||
excerpt = excerpt.replace(/(\r\n|\n|\r)+/gm, ' ');
|
||||
/*jslint regexp:false */
|
||||
|
||||
if (!truncateOptions.words && !truncateOptions.characters) {
|
||||
truncateOptions.words = 50;
|
||||
|
@ -28,50 +28,50 @@ var Promise = require('bluebird'),
|
||||
|
||||
function getMetaData(data, root) {
|
||||
var metaData = {
|
||||
url: getUrl(data, true),
|
||||
canonicalUrl: getCanonicalUrl(data),
|
||||
ampUrl: getAmpUrl(data),
|
||||
previousUrl: getPaginatedUrl('prev', data, true),
|
||||
nextUrl: getPaginatedUrl('next', data, true),
|
||||
authorUrl: getAuthorUrl(data, true),
|
||||
rssUrl: getRssUrl(data, true),
|
||||
metaTitle: getTitle(data, root),
|
||||
metaDescription: getDescription(data, root) || null,
|
||||
coverImage: {
|
||||
url: getCoverImage(data, true)
|
||||
url: getUrl(data, true),
|
||||
canonicalUrl: getCanonicalUrl(data),
|
||||
ampUrl: getAmpUrl(data),
|
||||
previousUrl: getPaginatedUrl('prev', data, true),
|
||||
nextUrl: getPaginatedUrl('next', data, true),
|
||||
authorUrl: getAuthorUrl(data, true),
|
||||
rssUrl: getRssUrl(data, true),
|
||||
metaTitle: getTitle(data, root),
|
||||
metaDescription: getDescription(data, root) || null,
|
||||
coverImage: {
|
||||
url: getCoverImage(data, true)
|
||||
},
|
||||
authorImage: {
|
||||
url: getAuthorImage(data, true)
|
||||
},
|
||||
ogImage: {
|
||||
url: getOgImage(data, true)
|
||||
},
|
||||
ogTitle: getTitle(data, root, {property: 'og'}),
|
||||
ogDescription: getDescription(data, root, {property: 'og'}),
|
||||
twitterImage: getTwitterImage(data, true),
|
||||
twitterTitle: getTitle(data, root, {property: 'twitter'}),
|
||||
twitterDescription: getDescription(data, root, {property: 'twitter'}),
|
||||
authorFacebook: getAuthorFacebook(data),
|
||||
creatorTwitter: getCreatorTwitter(data),
|
||||
keywords: getKeywords(data),
|
||||
publishedDate: getPublishedDate(data),
|
||||
modifiedDate: getModifiedDate(data),
|
||||
ogType: getOgType(data),
|
||||
// @TODO: pass into each meta helper - wrap each helper
|
||||
blog: {
|
||||
title: settingsCache.get('title'),
|
||||
description: settingsCache.get('description'),
|
||||
url: utils.url.urlFor('home', true),
|
||||
facebook: settingsCache.get('facebook'),
|
||||
twitter: settingsCache.get('twitter'),
|
||||
timezone: settingsCache.get('active_timezone'),
|
||||
navigation: settingsCache.get('navigation'),
|
||||
icon: settingsCache.get('icon'),
|
||||
cover_image: settingsCache.get('cover_image'),
|
||||
logo: getBlogLogo(),
|
||||
amp: settingsCache.get('amp')
|
||||
}
|
||||
},
|
||||
authorImage: {
|
||||
url: getAuthorImage(data, true)
|
||||
},
|
||||
ogImage: {
|
||||
url: getOgImage(data, true)
|
||||
},
|
||||
ogTitle: getTitle(data, root, {property: 'og'}),
|
||||
ogDescription: getDescription(data, root, {property: 'og'}),
|
||||
twitterImage: getTwitterImage(data, true),
|
||||
twitterTitle: getTitle(data, root, {property: 'twitter'}),
|
||||
twitterDescription: getDescription(data, root, {property: 'twitter'}),
|
||||
authorFacebook: getAuthorFacebook(data),
|
||||
creatorTwitter: getCreatorTwitter(data),
|
||||
keywords: getKeywords(data),
|
||||
publishedDate: getPublishedDate(data),
|
||||
modifiedDate: getModifiedDate(data),
|
||||
ogType: getOgType(data),
|
||||
// @TODO: pass into each meta helper - wrap each helper
|
||||
blog: {
|
||||
title: settingsCache.get('title'),
|
||||
description: settingsCache.get('description'),
|
||||
url: utils.url.urlFor('home', true),
|
||||
facebook: settingsCache.get('facebook'),
|
||||
twitter: settingsCache.get('twitter'),
|
||||
timezone: settingsCache.get('active_timezone'),
|
||||
navigation: settingsCache.get('navigation'),
|
||||
icon: settingsCache.get('icon'),
|
||||
cover_image: settingsCache.get('cover_image'),
|
||||
logo: getBlogLogo(),
|
||||
amp: settingsCache.get('amp')
|
||||
}
|
||||
},
|
||||
customExcerpt,
|
||||
metaDescription,
|
||||
fallbackExcerpt;
|
||||
|
@ -1,4 +1,4 @@
|
||||
var _ = require('lodash'),
|
||||
var _ = require('lodash'),
|
||||
config = require('../../config'),
|
||||
utils = require('../../utils');
|
||||
|
||||
@ -30,7 +30,7 @@ function getPaginatedUrl(page, data, absolute) {
|
||||
// baseUrl can be undefined, if there was nothing preceding the pagePath (e.g. first page of the index channel)
|
||||
newRelativeUrl = baseUrl ? utils.url.urlJoin(baseUrl, newRelativeUrl) : newRelativeUrl;
|
||||
|
||||
return utils.url.urlFor({relativeUrl: newRelativeUrl, secure: data.secure}, absolute);
|
||||
return utils.url.urlFor({relativeUrl: newRelativeUrl, secure: data.secure}, absolute);
|
||||
}
|
||||
|
||||
module.exports = getPaginatedUrl;
|
||||
|
@ -84,8 +84,8 @@ function getPostSchema(metaData, data) {
|
||||
url: metaData.authorUrl,
|
||||
sameAs: trimSameAs(data, 'post'),
|
||||
description: data.post.author.metaDescription ?
|
||||
escapeExpression(data.post.author.metaDescription) :
|
||||
null
|
||||
escapeExpression(data.post.author.metaDescription) :
|
||||
null
|
||||
},
|
||||
headline: escapeExpression(metaData.metaTitle),
|
||||
url: metaData.url,
|
||||
@ -120,8 +120,8 @@ function getHomeSchema(metaData) {
|
||||
'@id': metaData.blog.url || null
|
||||
},
|
||||
description: metaData.metaDescription ?
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
};
|
||||
return trimSchema(schema);
|
||||
}
|
||||
@ -143,8 +143,8 @@ function getTagSchema(metaData, data) {
|
||||
'@id': metaData.blog.url || null
|
||||
},
|
||||
description: metaData.metaDescription ?
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
};
|
||||
|
||||
return trimSchema(schema);
|
||||
@ -163,8 +163,8 @@ function getAuthorSchema(metaData, data) {
|
||||
'@id': metaData.blog.url || null
|
||||
},
|
||||
description: metaData.metaDescription ?
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
escapeExpression(metaData.metaDescription) :
|
||||
null
|
||||
};
|
||||
|
||||
return trimSchema(schema);
|
||||
|
@ -1,5 +1,5 @@
|
||||
var sqlite3 = require('./sqlite3'),
|
||||
mysql = require('./mysql');
|
||||
mysql = require('./mysql');
|
||||
|
||||
module.exports = {
|
||||
sqlite3: sqlite3,
|
||||
|
@ -1,4 +1,4 @@
|
||||
var _ = require('lodash'),
|
||||
var _ = require('lodash'),
|
||||
db = require('../../../data/db'),
|
||||
|
||||
// private
|
||||
@ -18,7 +18,9 @@ doRawAndFlatten = function doRaw(query, transaction, flattenFn) {
|
||||
|
||||
getTables = function getTables(transaction) {
|
||||
return doRawAndFlatten('show tables', transaction, function (response) {
|
||||
return _.map(response[0], function (entry) { return _.values(entry); });
|
||||
return _.map(response[0], function (entry) {
|
||||
return _.values(entry);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -50,7 +52,7 @@ checkPostTable = function checkPostTable(transaction) {
|
||||
|
||||
module.exports = {
|
||||
checkPostTable: checkPostTable,
|
||||
getTables: getTables,
|
||||
getTables: getTables,
|
||||
getIndexes: getIndexes,
|
||||
getColumns: getColumns
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
var _ = require('lodash'),
|
||||
var _ = require('lodash'),
|
||||
db = require('../../../data/db'),
|
||||
|
||||
// private
|
||||
@ -39,7 +39,7 @@ getColumns = function getColumns(table, transaction) {
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getTables: getTables,
|
||||
getTables: getTables,
|
||||
getIndexes: getIndexes,
|
||||
getColumns: getColumns
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
var _ = require('lodash'),
|
||||
var _ = require('lodash'),
|
||||
db = require('../../../data/db'),
|
||||
|
||||
// private
|
||||
@ -41,7 +41,7 @@ getColumns = function getColumns(table, transaction) {
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getTables: getTables,
|
||||
getTables: getTables,
|
||||
getIndexes: getIndexes,
|
||||
getColumns: getColumns
|
||||
};
|
||||
|
@ -46,7 +46,6 @@ function characterOccurance(stringToTest) {
|
||||
_.forIn(chars, function (charCount) {
|
||||
if (charCount >= allowedOccurancy) {
|
||||
valid = false;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
@ -98,15 +97,15 @@ validatePassword = function validatePassword(password, email, blogTitle) {
|
||||
disallowedPasswords = ['password', 'ghost', 'passw0rd'],
|
||||
blogUrl = utils.urlFor('home', true),
|
||||
badPasswords = [
|
||||
'1234567890',
|
||||
'qwertyuiop',
|
||||
'qwertzuiop',
|
||||
'asdfghjkl;',
|
||||
'abcdefghij',
|
||||
'0987654321',
|
||||
'1q2w3e4r5t',
|
||||
'12345asdfg'
|
||||
];
|
||||
'1234567890',
|
||||
'qwertyuiop',
|
||||
'qwertzuiop',
|
||||
'asdfghjkl;',
|
||||
'abcdefghij',
|
||||
'0987654321',
|
||||
'1q2w3e4r5t',
|
||||
'12345asdfg'
|
||||
];
|
||||
|
||||
blogTitle = blogTitle ? blogTitle : settingsCache.get('title');
|
||||
blogUrl = blogUrl.replace(/^http(s?):\/\//, '');
|
||||
@ -195,21 +194,34 @@ validateSchema = function validateSchema(tableName, model) {
|
||||
if (schema[tableName][columnKey].hasOwnProperty('maxlength')) {
|
||||
if (!validator.isLength(strVal, 0, schema[tableName][columnKey].maxlength)) {
|
||||
message = i18n.t('notices.data.validation.index.valueExceedsMaxLength',
|
||||
{tableName: tableName, columnKey: columnKey, maxlength: schema[tableName][columnKey].maxlength});
|
||||
validationErrors.push(new errors.ValidationError({message: message, context: tableName + '.' + columnKey}));
|
||||
{
|
||||
tableName: tableName,
|
||||
columnKey: columnKey,
|
||||
maxlength: schema[tableName][columnKey].maxlength
|
||||
});
|
||||
validationErrors.push(new errors.ValidationError({
|
||||
message: message,
|
||||
context: tableName + '.' + columnKey
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// check validations objects
|
||||
if (schema[tableName][columnKey].hasOwnProperty('validations')) {
|
||||
if (schema[tableName][columnKey].hasOwnProperty('validations')) {
|
||||
validationErrors = validationErrors.concat(validate(strVal, columnKey, schema[tableName][columnKey].validations));
|
||||
}
|
||||
|
||||
// check type
|
||||
if (schema[tableName][columnKey].hasOwnProperty('type')) {
|
||||
if (schema[tableName][columnKey].hasOwnProperty('type')) {
|
||||
if (schema[tableName][columnKey].type === 'integer' && !validator.isInt(strVal)) {
|
||||
message = i18n.t('notices.data.validation.index.valueIsNotInteger', {tableName: tableName, columnKey: columnKey});
|
||||
validationErrors.push(new errors.ValidationError({message: message, context: tableName + '.' + columnKey}));
|
||||
message = i18n.t('notices.data.validation.index.valueIsNotInteger', {
|
||||
tableName: tableName,
|
||||
columnKey: columnKey
|
||||
});
|
||||
validationErrors.push(new errors.ValidationError({
|
||||
message: message,
|
||||
context: tableName + '.' + columnKey
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ function GhostError(options) {
|
||||
errors.IgnitionError.call(this, options);
|
||||
}
|
||||
|
||||
// jscs:disable
|
||||
var ghostErrors = {
|
||||
DataExportError: function DataExportError(options) {
|
||||
GhostError.call(this, _.merge({
|
||||
@ -58,13 +57,13 @@ var ghostErrors = {
|
||||
DisabledFeatureError: function DisabledFeatureError(options) {
|
||||
GhostError.call(this, _.merge({
|
||||
statusCode: 409,
|
||||
errorType: 'DisabledFeatureError',
|
||||
errorType: 'DisabledFeatureError'
|
||||
}, options));
|
||||
},
|
||||
UpdateCollisionError: function UpdateCollisionError(options) {
|
||||
GhostError.call(this, _.merge({
|
||||
statusCode: 409,
|
||||
errorType: 'UpdateCollisionError',
|
||||
errorType: 'UpdateCollisionError'
|
||||
}, options));
|
||||
}
|
||||
};
|
||||
|
@ -2,15 +2,12 @@
|
||||
// Usage: `{{body_class}}`
|
||||
//
|
||||
// Output classes for the body element
|
||||
//
|
||||
// We use the name body_class to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var proxy = require('./proxy'),
|
||||
_ = require('lodash'),
|
||||
SafeString = proxy.SafeString;
|
||||
|
||||
module.exports = function body_class(options) {
|
||||
// We use the name body_class to match the helper for consistency:
|
||||
module.exports = function body_class(options) { // eslint-disable-line camelcase
|
||||
var classes = [],
|
||||
context = options.data.root.context,
|
||||
post = this.post,
|
||||
|
@ -2,15 +2,12 @@
|
||||
// Usage: `{{facebook_url}}` or `{{facebook_url author.facebook}}`
|
||||
//
|
||||
// Output a url for a twitter username
|
||||
//
|
||||
// We use the name facebook_url to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var proxy = require('./proxy'),
|
||||
socialUrls = proxy.socialUrls,
|
||||
findKey = proxy.utils.findKey;
|
||||
|
||||
module.exports = function facebook_url(username, options) {
|
||||
// We use the name facebook_url to match the helper for consistency:
|
||||
module.exports = function facebook_url(username, options) { // eslint-disable-line camelcase
|
||||
if (!options) {
|
||||
options = username;
|
||||
username = findKey('facebook', this, options.data.blog);
|
||||
|
@ -71,15 +71,14 @@ module.exports = function foreach(items, options) {
|
||||
}
|
||||
|
||||
output = output + fn(items[field], {
|
||||
data: data,
|
||||
blockParams: hbsUtils.blockParams([items[field], field], [contextPath + field, null])
|
||||
});
|
||||
data: data,
|
||||
blockParams: hbsUtils.blockParams([items[field], field], [contextPath + field, null])
|
||||
});
|
||||
}
|
||||
|
||||
function iterateCollection(context) {
|
||||
// Context is all posts on the blog
|
||||
var count = 1,
|
||||
current = 1;
|
||||
var current = 1;
|
||||
|
||||
// For each post, if it is a post number that fits within the from and to
|
||||
// send the key to execIteration to set to be added to the page
|
||||
@ -92,7 +91,6 @@ module.exports = function foreach(items, options) {
|
||||
if (current <= to) {
|
||||
execIteration(key, current - 1, current === to);
|
||||
}
|
||||
count += 1;
|
||||
current += 1;
|
||||
});
|
||||
}
|
||||
|
@ -2,16 +2,14 @@
|
||||
// Usage: `{{ghost_foot}}`
|
||||
//
|
||||
// Outputs scripts and other assets at the bottom of a Ghost theme
|
||||
//
|
||||
// We use the name ghost_foot to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
var proxy = require('./proxy'),
|
||||
_ = require('lodash'),
|
||||
SafeString = proxy.SafeString,
|
||||
filters = proxy.filters,
|
||||
settingsCache = proxy.settingsCache;
|
||||
|
||||
module.exports = function ghost_foot(options) {
|
||||
// We use the name ghost_foot to match the helper for consistency:
|
||||
module.exports = function ghost_foot(options) { // eslint-disable-line camelcase
|
||||
var foot = [],
|
||||
globalCodeinjection = settingsCache.get('ghost_foot'),
|
||||
postCodeinjection = options.data.root && options.data.root.post ? options.data.root.post.codeinjection_foot : null;
|
||||
|
@ -2,10 +2,6 @@
|
||||
// Usage: `{{ghost_head}}`
|
||||
//
|
||||
// Outputs scripts and other assets at the top of a Ghost theme
|
||||
//
|
||||
// We use the name ghost_head to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var proxy = require('./proxy'),
|
||||
_ = require('lodash'),
|
||||
debug = require('ghost-ignition').debug('ghost_head'),
|
||||
@ -93,7 +89,8 @@ function getAjaxHelper(clientId, clientSecret) {
|
||||
* `blog`, `labs` and `config` are the templateOptions, search for `hbs.updateTemplateOptions` in the code base.
|
||||
* Also see how the root object get's created, https://github.com/wycats/handlebars.js/blob/v4.0.6/lib/handlebars/runtime.js#L259
|
||||
*/
|
||||
module.exports = function ghost_head(options) {
|
||||
// We use the name ghost_head to match the helper for consistency:
|
||||
module.exports = function ghost_head(options) { // eslint-disable-line camelcase
|
||||
debug('begin');
|
||||
|
||||
// if server error page do nothing
|
||||
|
@ -14,11 +14,11 @@ function evaluateTagList(expr, tags) {
|
||||
return v.trim();
|
||||
}).reduce(function (p, c) {
|
||||
return p || (_.findIndex(tags, function (item) {
|
||||
// Escape regex special characters
|
||||
item = item.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g, '\\$&');
|
||||
item = new RegExp('^' + item + '$', 'i');
|
||||
return item.test(c);
|
||||
}) !== -1);
|
||||
// Escape regex special characters
|
||||
item = item.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g, '\\$&');
|
||||
item = new RegExp('^' + item + '$', 'i');
|
||||
return item.test(c);
|
||||
}) !== -1);
|
||||
}, false);
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,8 @@ module.exports = function imgUrl(attr, options) {
|
||||
|
||||
if (attr) {
|
||||
return url.urlFor('image', {image: attr}, absolute);
|
||||
} else {
|
||||
// CASE: if you pass e.g. cover_image, but it is not set, then attr is null!
|
||||
// in this case we don't show a warning
|
||||
return;
|
||||
}
|
||||
|
||||
// CASE: if you pass e.g. cover_image, but it is not set, then attr is null!
|
||||
// in this case we don't show a warning
|
||||
};
|
||||
|
@ -2,17 +2,12 @@
|
||||
// Usage: `{{meta_description}}`
|
||||
//
|
||||
// Page description used for sharing and SEO
|
||||
//
|
||||
// We use the name meta_description to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var proxy = require('./proxy'),
|
||||
getMetaDataDescription = proxy.metaData.getMetaDataDescription;
|
||||
|
||||
function meta_description(options) {
|
||||
// We use the name meta_description to match the helper for consistency:
|
||||
module.exports = function meta_description(options) { // eslint-disable-line camelcase
|
||||
options = options || {};
|
||||
|
||||
return getMetaDataDescription(this, options.data.root) || '';
|
||||
}
|
||||
|
||||
module.exports = meta_description;
|
||||
};
|
||||
|
@ -2,15 +2,10 @@
|
||||
// Usage: `{{meta_title}}`
|
||||
//
|
||||
// Page title used for sharing and SEO
|
||||
//
|
||||
// We use the name meta_title to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var proxy = require('./proxy'),
|
||||
getMetaDataTitle = proxy.metaData.getMetaDataTitle;
|
||||
|
||||
function meta_title(options) {
|
||||
// We use the name meta_title to match the helper for consistency:
|
||||
module.exports = function meta_title(options) { // eslint-disable-line camelcase
|
||||
return getMetaDataTitle(this, options.data.root);
|
||||
}
|
||||
|
||||
module.exports = meta_title;
|
||||
};
|
||||
|
@ -3,15 +3,12 @@
|
||||
// *Usage example:*
|
||||
// `{{page_url 2}}`
|
||||
//
|
||||
// Returns the URL for the page specified in the current object
|
||||
// context.
|
||||
//
|
||||
// We use the name page_url to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
// Returns the URL for the page specified in the current object context.
|
||||
var proxy = require('./proxy'),
|
||||
getPaginatedUrl = proxy.metaData.getPaginatedUrl;
|
||||
|
||||
module.exports = function page_url(page, options) {
|
||||
// We use the name page_url to match the helper for consistency:
|
||||
module.exports = function page_url(page, options) { // eslint-disable-line camelcase
|
||||
if (!options) {
|
||||
options = page;
|
||||
page = 1;
|
||||
|
@ -10,7 +10,6 @@ var proxy = require('./proxy'),
|
||||
pagination;
|
||||
|
||||
pagination = function (options) {
|
||||
/*jshint unused:false*/
|
||||
if (!_.isObject(this.pagination) || _.isFunction(this.pagination)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: i18n.t('warnings.helpers.pagination.invalidData')
|
||||
|
@ -2,15 +2,12 @@
|
||||
// Usage: `{{post_class}}`
|
||||
//
|
||||
// Output classes for the body element
|
||||
//
|
||||
// We use the name body_class to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var proxy = require('./proxy'),
|
||||
_ = require('lodash'),
|
||||
SafeString = proxy.SafeString;
|
||||
|
||||
module.exports = function post_class() {
|
||||
// We use the name post_class to match the helper for consistency:
|
||||
module.exports = function post_class() { // eslint-disable-line camelcase
|
||||
var classes = ['post'],
|
||||
tags = this.post && this.post.tags ? this.post.tags : this.tags || [],
|
||||
featured = this.post && this.post.featured ? this.post.featured : this.featured || false,
|
||||
|
@ -29,7 +29,7 @@ buildApiOptions = function buildApiOptions(options, post) {
|
||||
limit: 1,
|
||||
// This line deliberately uses double quotes because GQL cannot handle either double quotes
|
||||
// or escaped singles, see TryGhost/GQL#34
|
||||
filter: "slug:-" + slug + "+published_at:" + op + "'" + publishedAt + "'", // jscs:ignore
|
||||
filter: "slug:-" + slug + "+published_at:" + op + "'" + publishedAt + "'" // eslint-disable-line quotes
|
||||
};
|
||||
|
||||
if (_.get(options, 'hash.in')) {
|
||||
|
@ -2,15 +2,12 @@
|
||||
// Usage: `{{twitter_url}}` or `{{twitter_url author.twitter}}`
|
||||
//
|
||||
// Output a url for a twitter username
|
||||
//
|
||||
// We use the name twitter_url to match the helper for consistency:
|
||||
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
||||
|
||||
var proxy = require('./proxy'),
|
||||
socialUrls = proxy.socialUrls,
|
||||
findKey = proxy.utils.findKey;
|
||||
|
||||
module.exports = function twitter_url(username, options) {
|
||||
// We use the name twitter_url to match the helper for consistency:
|
||||
module.exports = function twitter_url(username, options) { // eslint-disable-line camelcase
|
||||
if (!options) {
|
||||
options = username;
|
||||
username = findKey('twitter', this, options.data.blog);
|
||||
|
@ -53,25 +53,25 @@ globalBlock = function globalBlock() {
|
||||
db = require('../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
|
||||
globalBlockInstance = globalBlockInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
context: i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.error',
|
||||
{rfa: spamGlobalBlock.freeRetries + 1 || 5, rfp: spamGlobalBlock.lifetime || 60 * 60}),
|
||||
help: i18n.t('errors.middleware.spamprevention.tooManyAttempts')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamGlobalBlock, spamConfigKeys))
|
||||
);
|
||||
_.extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
context: i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.error',
|
||||
{rfa: spamGlobalBlock.freeRetries + 1 || 5, rfp: spamGlobalBlock.lifetime || 60 * 60}),
|
||||
help: i18n.t('errors.middleware.spamprevention.tooManyAttempts')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamGlobalBlock, spamConfigKeys))
|
||||
);
|
||||
|
||||
return globalBlockInstance;
|
||||
};
|
||||
@ -82,26 +82,26 @@ globalReset = function globalReset() {
|
||||
db = require('../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
|
||||
globalResetInstance = globalResetInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
// TODO use i18n again
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
context: i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.error',
|
||||
{rfa: spamGlobalReset.freeRetries + 1 || 5, rfp: spamGlobalReset.lifetime || 60 * 60}),
|
||||
help: i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamGlobalReset, spamConfigKeys))
|
||||
);
|
||||
_.extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
// TODO use i18n again
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
context: i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.error',
|
||||
{rfa: spamGlobalReset.freeRetries + 1 || 5, rfp: spamGlobalReset.lifetime || 60 * 60}),
|
||||
help: i18n.t('errors.middleware.spamprevention.forgottenPasswordIp.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamGlobalReset, spamConfigKeys))
|
||||
);
|
||||
|
||||
return globalResetInstance;
|
||||
};
|
||||
@ -116,25 +116,25 @@ userLogin = function userLogin() {
|
||||
db = require('../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
|
||||
userLoginInstance = userLoginInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
attachResetToRequest: true,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many sign-in attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
// TODO add more options to i18n
|
||||
context: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context'),
|
||||
help: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamUserLogin, spamConfigKeys))
|
||||
);
|
||||
_.extend({
|
||||
attachResetToRequest: true,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many sign-in attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
// TODO add more options to i18n
|
||||
context: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context'),
|
||||
help: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamUserLogin, spamConfigKeys))
|
||||
);
|
||||
|
||||
return userLoginInstance;
|
||||
};
|
||||
@ -148,25 +148,25 @@ userReset = function userReset() {
|
||||
db = require('../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
|
||||
userResetInstance = userResetInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
attachResetToRequest: true,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many password reset attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
context: i18n.t('errors.middleware.spamprevention.forgottenPasswordEmail.error',
|
||||
{rfa: spamUserReset.freeRetries + 1 || 5, rfp: spamUserReset.lifetime || 60 * 60}),
|
||||
help: i18n.t('errors.middleware.spamprevention.forgottenPasswordEmail.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamUserReset, spamConfigKeys))
|
||||
);
|
||||
_.extend({
|
||||
attachResetToRequest: true,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
return next(new errors.TooManyRequestsError({
|
||||
message: 'Too many password reset attempts try again in ' + moment(nextValidRequestDate).fromNow(true),
|
||||
context: i18n.t('errors.middleware.spamprevention.forgottenPasswordEmail.error',
|
||||
{rfa: spamUserReset.freeRetries + 1 || 5, rfp: spamUserReset.lifetime || 60 * 60}),
|
||||
help: i18n.t('errors.middleware.spamprevention.forgottenPasswordEmail.context')
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamUserReset, spamConfigKeys))
|
||||
);
|
||||
|
||||
return userResetInstance;
|
||||
};
|
||||
@ -179,28 +179,28 @@ privateBlog = function privateBlog() {
|
||||
db = require('../../data/db');
|
||||
|
||||
store = store || new BruteKnex({
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
tablename: 'brute',
|
||||
createTable: false,
|
||||
knex: db.knex
|
||||
});
|
||||
|
||||
privateBlogInstance = privateBlogInstance || new ExpressBrute(store,
|
||||
_.extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
logging.error(new errors.GhostError({
|
||||
message: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.error',
|
||||
{rfa: spamPrivateBlog.freeRetries + 1 || 5, rfp: spamPrivateBlog.lifetime || 60 * 60}),
|
||||
context: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context')
|
||||
}));
|
||||
_.extend({
|
||||
attachResetToRequest: false,
|
||||
failCallback: function (req, res, next, nextValidRequestDate) {
|
||||
logging.error(new errors.GhostError({
|
||||
message: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.error',
|
||||
{rfa: spamPrivateBlog.freeRetries + 1 || 5, rfp: spamPrivateBlog.lifetime || 60 * 60}),
|
||||
context: i18n.t('errors.middleware.spamprevention.tooManySigninAttempts.context')
|
||||
}));
|
||||
|
||||
return next(new errors.GhostError({
|
||||
message: 'Too many private sign-in attempts try again in ' + moment(nextValidRequestDate).fromNow(true)
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamPrivateBlog, spamConfigKeys))
|
||||
);
|
||||
return next(new errors.GhostError({
|
||||
message: 'Too many private sign-in attempts try again in ' + moment(nextValidRequestDate).fromNow(true)
|
||||
}));
|
||||
},
|
||||
handleStoreError: handleStoreError
|
||||
}, _.pick(spamPrivateBlog, spamConfigKeys))
|
||||
);
|
||||
|
||||
return privateBlogInstance;
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ _private.prepareError = function prepareError(err, req, res, next) {
|
||||
next(err);
|
||||
};
|
||||
|
||||
_private.JSONErrorRenderer = function JSONErrorRenderer(err, req, res, /*jshint unused:false */ next) {
|
||||
_private.JSONErrorRenderer = function JSONErrorRenderer(err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
// @TODO: jsonapi errors format (http://jsonapi.org/format/#error-objects)
|
||||
res.json({
|
||||
errors: [{
|
||||
@ -115,7 +115,7 @@ _private.HTMLErrorRenderer = function HTMLErrorRender(err, req, res, next) {
|
||||
});
|
||||
};
|
||||
|
||||
_private.BasicErorRenderer = function BasicErrorRenderer(err, req, res, /*jshint unused:false */ next) {
|
||||
_private.BasicErorRenderer = function BasicErrorRenderer(err, req, res, next) { // eslint-disable-line no-unused-vars
|
||||
return res.send(res.statusCode + ' ' + err.message);
|
||||
};
|
||||
|
||||
|
@ -58,9 +58,7 @@ function serveFavicon() {
|
||||
res.writeHead(200, content.headers);
|
||||
res.end(content.body);
|
||||
})
|
||||
.catch(function (err) {
|
||||
next(err);
|
||||
});
|
||||
.catch(next);
|
||||
} else {
|
||||
originalExtension = path.extname(filePath).toLowerCase();
|
||||
|
||||
@ -81,7 +79,7 @@ function serveFavicon() {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
return next();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ function servePublicFile(file, type, maxAge) {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
return next();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -19,14 +19,14 @@ function isWhiteListedFile(file) {
|
||||
|
||||
function forwardToExpressStatic(req, res, next) {
|
||||
if (!themeUtils.getActive()) {
|
||||
next();
|
||||
} else {
|
||||
var configMaxAge = config.get('caching:theme:maxAge');
|
||||
|
||||
express.static(themeUtils.getActive().path,
|
||||
{maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : utils.ONE_YEAR_MS}
|
||||
)(req, res, next);
|
||||
return next();
|
||||
}
|
||||
|
||||
var configMaxAge = config.get('caching:theme:maxAge');
|
||||
|
||||
express.static(themeUtils.getActive().path,
|
||||
{maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : utils.ONE_YEAR_MS}
|
||||
)(req, res, next);
|
||||
}
|
||||
|
||||
function staticTheme() {
|
||||
|
@ -36,13 +36,13 @@ uncapitalise = function uncapitalise(req, res, next) {
|
||||
*/
|
||||
if (/[A-Z]/.test(decodeURIComponent(pathToTest))) {
|
||||
redirectPath = (
|
||||
utils.removeOpenRedirectFromUrl((req.originalUrl || req.url).replace(pathToTest, pathToTest.toLowerCase()))
|
||||
utils.removeOpenRedirectFromUrl((req.originalUrl || req.url).replace(pathToTest, pathToTest.toLowerCase()))
|
||||
);
|
||||
|
||||
return utils.url.redirect301(res, redirectPath);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = uncapitalise;
|
||||
|
@ -6,7 +6,6 @@ App = ghostBookshelf.Model.extend({
|
||||
tableName: 'apps',
|
||||
|
||||
onSaving: function onSaving(newPage, attr, options) {
|
||||
/*jshint unused:false*/
|
||||
var self = this;
|
||||
|
||||
ghostBookshelf.Model.prototype.onSaving.apply(this, arguments);
|
||||
|
@ -23,7 +23,7 @@ Basetoken = ghostBookshelf.Model.extend({
|
||||
}
|
||||
|
||||
}, {
|
||||
destroyAllExpired: function destroyAllExpired(options) {
|
||||
destroyAllExpired: function destroyAllExpired(options) {
|
||||
options = this.filterOptions(options, 'destroyAll');
|
||||
return ghostBookshelf.Collection.forge([], {model: this})
|
||||
.query('where', 'expires', '<', Date.now())
|
||||
|
@ -1,4 +1,5 @@
|
||||
var _ = require('lodash');
|
||||
var debug = require('ghost-ignition').debug('models:plugin:include-count'),
|
||||
_ = require('lodash');
|
||||
|
||||
module.exports = function (Bookshelf) {
|
||||
var modelProto = Bookshelf.Model.prototype,
|
||||
@ -60,9 +61,7 @@ module.exports = function (Bookshelf) {
|
||||
fetch: function () {
|
||||
this.addCounts.apply(this, arguments);
|
||||
|
||||
if (this.debug) {
|
||||
console.log('QUERY', this.query().toQuery());
|
||||
}
|
||||
debug('QUERY', this.query().toQuery());
|
||||
|
||||
// Call parent fetch
|
||||
return modelProto.fetch.apply(this, arguments);
|
||||
@ -70,9 +69,7 @@ module.exports = function (Bookshelf) {
|
||||
fetchAll: function () {
|
||||
this.addCounts.apply(this, arguments);
|
||||
|
||||
if (this.debug) {
|
||||
console.log('QUERY', this.query().toQuery());
|
||||
}
|
||||
debug('QUERY', this.query().toQuery());
|
||||
|
||||
// Call parent fetchAll
|
||||
return modelProto.fetchAll.apply(this, arguments);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// # Pagination
|
||||
//
|
||||
// Extends Bookshelf.Model with a `fetchPage` method. Handles everything to do with paginated requests.
|
||||
var _ = require('lodash'),
|
||||
var _ = require('lodash'),
|
||||
defaults,
|
||||
paginationUtils,
|
||||
pagination;
|
||||
@ -66,12 +66,12 @@ paginationUtils = {
|
||||
formatResponse: function formatResponse(totalItems, options) {
|
||||
var calcPages = Math.ceil(totalItems / options.limit) || 0,
|
||||
pagination = {
|
||||
page: options.page || defaults.page,
|
||||
page: options.page || defaults.page,
|
||||
limit: options.limit,
|
||||
pages: calcPages === 0 ? 1 : calcPages,
|
||||
total: totalItems,
|
||||
next: null,
|
||||
prev: null
|
||||
next: null,
|
||||
prev: null
|
||||
};
|
||||
|
||||
if (pagination.pages > 1) {
|
||||
@ -126,7 +126,7 @@ pagination = function pagination(bookshelf) {
|
||||
// Extend updates the first object passed to it, no need for an assignment
|
||||
_.extend(bookshelf.Model.prototype, {
|
||||
/**
|
||||
* ### Fetch page
|
||||
* ### Fetch page
|
||||
* A `fetch` extension to get a paginated set of items from a collection
|
||||
*
|
||||
* We trigger two queries:
|
||||
@ -148,11 +148,6 @@ pagination = function pagination(bookshelf) {
|
||||
bookshelf.knex.raw('count(distinct ' + tableName + '.' + idAttribute + ') as aggregate')
|
||||
);
|
||||
|
||||
// the debug flag doesn't work for the raw knex count query!
|
||||
if (this.debug) {
|
||||
console.log('COUNT', countPromise.toQuery());
|
||||
}
|
||||
|
||||
// #### Pre count clauses
|
||||
// Add any where or join clauses which need to be included with the aggregate query
|
||||
|
||||
|
@ -31,7 +31,6 @@ Tag = ghostBookshelf.Model.extend({
|
||||
},
|
||||
|
||||
onSaving: function onSaving(newTag, attr, options) {
|
||||
/*jshint unused:false*/
|
||||
var self = this;
|
||||
|
||||
ghostBookshelf.Model.prototype.onSaving.apply(this, arguments);
|
||||
|
@ -236,8 +236,9 @@ User = ghostBookshelf.Model.extend({
|
||||
format: function format(options) {
|
||||
if (!_.isEmpty(options.website) &&
|
||||
!validator.isURL(options.website, {
|
||||
require_protocol: true,
|
||||
protocols: ['http', 'https']})) {
|
||||
require_protocol: true,
|
||||
protocols: ['http', 'https']
|
||||
})) {
|
||||
options.website = 'http://' + options.website;
|
||||
}
|
||||
return ghostBookshelf.Model.prototype.format.call(this, options);
|
||||
@ -575,7 +576,7 @@ User = ghostBookshelf.Model.extend({
|
||||
options.withRelated = _.union(options.withRelated, options.include);
|
||||
|
||||
userData.slug = null;
|
||||
return self.edit.call(self, userData, options);
|
||||
return self.edit(userData, options);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -792,41 +793,46 @@ User = ghostBookshelf.Model.extend({
|
||||
var ownerRole,
|
||||
contextUser;
|
||||
|
||||
return Promise.join(ghostBookshelf.model('Role').findOne({name: 'Owner'}),
|
||||
User.findOne({id: options.context.user}, {include: ['roles']}))
|
||||
.then(function then(results) {
|
||||
ownerRole = results[0];
|
||||
contextUser = results[1];
|
||||
return Promise.join(
|
||||
ghostBookshelf.model('Role').findOne({name: 'Owner'}),
|
||||
User.findOne({id: options.context.user}, {include: ['roles']})
|
||||
)
|
||||
.then(function then(results) {
|
||||
ownerRole = results[0];
|
||||
contextUser = results[1];
|
||||
|
||||
// check if user has the owner role
|
||||
var currentRoles = contextUser.toJSON(options).roles;
|
||||
if (!_.some(currentRoles, {id: ownerRole.id})) {
|
||||
return Promise.reject(new errors.NoPermissionError({message: i18n.t('errors.models.user.onlyOwnerCanTransferOwnerRole')}));
|
||||
}
|
||||
// check if user has the owner role
|
||||
var currentRoles = contextUser.toJSON(options).roles;
|
||||
if (!_.some(currentRoles, {id: ownerRole.id})) {
|
||||
return Promise.reject(new errors.NoPermissionError({message: i18n.t('errors.models.user.onlyOwnerCanTransferOwnerRole')}));
|
||||
}
|
||||
|
||||
return Promise.join(ghostBookshelf.model('Role').findOne({name: 'Administrator'}),
|
||||
User.findOne({id: object.id}, {include: ['roles']}));
|
||||
}).then(function then(results) {
|
||||
var adminRole = results[0],
|
||||
user = results[1],
|
||||
currentRoles = user.toJSON(options).roles;
|
||||
return Promise.join(ghostBookshelf.model('Role').findOne({name: 'Administrator'}),
|
||||
User.findOne({id: object.id}, {include: ['roles']}));
|
||||
})
|
||||
.then(function then(results) {
|
||||
var adminRole = results[0],
|
||||
user = results[1],
|
||||
currentRoles = user.toJSON(options).roles;
|
||||
|
||||
if (!_.some(currentRoles, {id: adminRole.id})) {
|
||||
return Promise.reject(new errors.ValidationError({message: i18n.t('errors.models.user.onlyAdmCanBeAssignedOwnerRole')}));
|
||||
}
|
||||
if (!_.some(currentRoles, {id: adminRole.id})) {
|
||||
return Promise.reject(new errors.ValidationError({message: i18n.t('errors.models.user.onlyAdmCanBeAssignedOwnerRole')}));
|
||||
}
|
||||
|
||||
// convert owner to admin
|
||||
return Promise.join(contextUser.roles().updatePivot({role_id: adminRole.id}),
|
||||
user.roles().updatePivot({role_id: ownerRole.id}),
|
||||
user.id);
|
||||
}).then(function then(results) {
|
||||
return Users.forge()
|
||||
.query('whereIn', 'id', [contextUser.id, results[2]])
|
||||
.fetch({withRelated: ['roles']});
|
||||
}).then(function then(users) {
|
||||
options.include = ['roles'];
|
||||
return users.toJSON(options);
|
||||
});
|
||||
// convert owner to admin
|
||||
return Promise.join(contextUser.roles().updatePivot({role_id: adminRole.id}),
|
||||
user.roles().updatePivot({role_id: ownerRole.id}),
|
||||
user.id);
|
||||
})
|
||||
.then(function then(results) {
|
||||
return Users.forge()
|
||||
.query('whereIn', 'id', [contextUser.id, results[2]])
|
||||
.fetch({withRelated: ['roles']});
|
||||
})
|
||||
.then(function then(users) {
|
||||
options.include = ['roles'];
|
||||
return users.toJSON(options);
|
||||
});
|
||||
},
|
||||
|
||||
// Get the user by email address, enforces case insensitivity rejects if the user is not found
|
||||
|
@ -10,19 +10,17 @@ var _ = require('lodash'),
|
||||
CanThisResult;
|
||||
|
||||
// Base class for canThis call results
|
||||
CanThisResult = function () {
|
||||
return;
|
||||
};
|
||||
CanThisResult = function () {};
|
||||
|
||||
CanThisResult.prototype.buildObjectTypeHandlers = function (objTypes, actType, context, permissionLoad) {
|
||||
var objectTypeModelMap = {
|
||||
post: models.Post,
|
||||
role: models.Role,
|
||||
user: models.User,
|
||||
post: models.Post,
|
||||
role: models.Role,
|
||||
user: models.User,
|
||||
permission: models.Permission,
|
||||
setting: models.Settings,
|
||||
setting: models.Settings,
|
||||
subscriber: models.Subscriber,
|
||||
invite: models.Invite
|
||||
invite: models.Invite
|
||||
};
|
||||
|
||||
// Iterate through the object types, i.e. ['post', 'tag', 'user']
|
||||
|
@ -29,7 +29,7 @@ generateProxyFunctions = function (name, permissions, isInternal) {
|
||||
var permValue = getPermissionToMethod(perm, method);
|
||||
|
||||
if (!permValue) {
|
||||
throw new Error(i18n.t('errors.apps.accessResourceWithoutPermission.error', {name:name, perm: perm, method: method}));
|
||||
throw new Error(i18n.t('errors.apps.accessResourceWithoutPermission.error', {name: name, perm: perm, method: method}));
|
||||
}
|
||||
|
||||
return wrappedFunc.apply(context, args);
|
||||
@ -41,8 +41,8 @@ generateProxyFunctions = function (name, permissions, isInternal) {
|
||||
},
|
||||
passThruAppContextToApi = function (perm, apiMethods) {
|
||||
var appContext = {
|
||||
app: name
|
||||
};
|
||||
app: name
|
||||
};
|
||||
|
||||
return _.reduce(apiMethods, function (memo, apiMethod, methodName) {
|
||||
memo[methodName] = function () {
|
||||
|
@ -83,8 +83,6 @@ function ping(post) {
|
||||
|
||||
// with all the data we have, we're doing the request now
|
||||
makeRequest(reqOptions, slackData);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
// jscs:disable requireMultipleVarDecl
|
||||
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs-extra'),
|
||||
|
@ -63,18 +63,18 @@ function createCustomNotification(message) {
|
||||
}
|
||||
|
||||
var notification = {
|
||||
status: 'alert',
|
||||
type: 'info',
|
||||
custom: true,
|
||||
uuid: message.id,
|
||||
dismissible: true,
|
||||
message: message.content
|
||||
},
|
||||
getAllNotifications = api.notifications.browse({context: {internal: true}}),
|
||||
getSeenNotifications = api.settings.read(_.extend({key: 'seen_notifications'}, internal));
|
||||
status: 'alert',
|
||||
type: 'info',
|
||||
custom: true,
|
||||
uuid: message.id,
|
||||
dismissible: true,
|
||||
message: message.content
|
||||
},
|
||||
getAllNotifications = api.notifications.browse({context: {internal: true}}),
|
||||
getSeenNotifications = api.settings.read(_.extend({key: 'seen_notifications'}, internal));
|
||||
|
||||
return Promise.join(getAllNotifications, getSeenNotifications, function joined(all, seen) {
|
||||
var isSeen = _.includes(JSON.parse(seen.settings[0].value || []), notification.id),
|
||||
var isSeen = _.includes(JSON.parse(seen.settings[0].value || []), notification.id),
|
||||
isDuplicate = _.some(all.notifications, {message: notification.message});
|
||||
|
||||
if (!isSeen && !isDuplicate) {
|
||||
@ -233,7 +233,7 @@ function updateCheck() {
|
||||
|
||||
if (nextUpdateCheck && nextUpdateCheck.value && nextUpdateCheck.value > moment().unix()) {
|
||||
// It's not time to check yet
|
||||
return;
|
||||
return; // eslint-disable-line no-useless-return
|
||||
} else {
|
||||
// We need to do a check
|
||||
return updateCheckRequest()
|
||||
|
@ -21,6 +21,7 @@ utils = {
|
||||
/**
|
||||
* Timespans in seconds and milliseconds for better readability
|
||||
*/
|
||||
/* eslint-disable key-spacing */
|
||||
ONE_HOUR_S: 3600,
|
||||
ONE_DAY_S: 86400,
|
||||
ONE_MONTH_S: 2628000,
|
||||
@ -33,6 +34,7 @@ utils = {
|
||||
ONE_MONTH_MS: 2628000000,
|
||||
SIX_MONTH_MS: 15768000000,
|
||||
ONE_YEAR_MS: 31536000000,
|
||||
// eslint-enable key-spacing */
|
||||
|
||||
/**
|
||||
* Return a unique identifier with the given `len`.
|
||||
|
@ -4,45 +4,42 @@ var MarkdownIt = require('markdown-it'),
|
||||
breaks: true,
|
||||
linkify: true
|
||||
})
|
||||
.use(require('markdown-it-footnote'))
|
||||
.use(require('markdown-it-lazy-headers'))
|
||||
.use(require('markdown-it-mark'))
|
||||
.use(function namedHeaders(md) {
|
||||
// jscs:disable
|
||||
.use(require('markdown-it-footnote'))
|
||||
.use(require('markdown-it-lazy-headers'))
|
||||
.use(require('markdown-it-mark'))
|
||||
.use(function namedHeaders(md) {
|
||||
// match legacy Showdown IDs
|
||||
var slugify = function (inputString, usedHeaders) {
|
||||
var slug = inputString.replace(/[^\w]/g, '').toLowerCase();
|
||||
if (usedHeaders[slug]) {
|
||||
usedHeaders[slug] += 1;
|
||||
slug += usedHeaders[slug];
|
||||
}
|
||||
return slug;
|
||||
};
|
||||
var originalHeadingOpen = md.renderer.rules.heading_open;
|
||||
|
||||
// match legacy Showdown IDs
|
||||
var slugify = function (inputString, usedHeaders) {
|
||||
var slug = inputString.replace(/[^\w]/g, '').toLowerCase();
|
||||
if (usedHeaders[slug]) {
|
||||
usedHeaders[slug] += 1;
|
||||
slug += usedHeaders[slug];
|
||||
}
|
||||
return slug;
|
||||
};
|
||||
var originalHeadingOpen = md.renderer.rules.heading_open;
|
||||
// originally from https://github.com/leff/markdown-it-named-headers
|
||||
// moved here to avoid pulling in http://stringjs.com dependency
|
||||
md.renderer.rules.heading_open = function (tokens, idx, something, somethingelse, self) {
|
||||
var usedHeaders = {};
|
||||
|
||||
// originally from https://github.com/leff/markdown-it-named-headers
|
||||
// moved here to avoid pulling in http://stringjs.com dependency
|
||||
md.renderer.rules.heading_open = function (tokens, idx, something, somethingelse, self) {
|
||||
var used_headers = {};
|
||||
tokens[idx].attrs = tokens[idx].attrs || [];
|
||||
|
||||
tokens[idx].attrs = tokens[idx].attrs || [];
|
||||
var title = tokens[idx + 1].children.reduce(function (acc, t) {
|
||||
return acc + t.content;
|
||||
}, '');
|
||||
|
||||
var title = tokens[idx + 1].children.reduce(function (acc, t) {
|
||||
return acc + t.content;
|
||||
}, '');
|
||||
var slug = slugify(title, usedHeaders);
|
||||
tokens[idx].attrs.push(['id', slug]);
|
||||
|
||||
var slug = slugify(title, used_headers);
|
||||
tokens[idx].attrs.push(['id', slug]);
|
||||
|
||||
if (originalHeadingOpen) {
|
||||
return originalHeadingOpen.apply(this, arguments);
|
||||
} else {
|
||||
return self.renderToken.apply(self, arguments);
|
||||
}
|
||||
};
|
||||
// jscs:enable
|
||||
});
|
||||
if (originalHeadingOpen) {
|
||||
return originalHeadingOpen.apply(this, arguments);
|
||||
} else {
|
||||
return self.renderToken.apply(self, arguments);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// configure linkify-it
|
||||
converter.linkify.set({
|
||||
|
@ -1,9 +1,9 @@
|
||||
var SimpleDom = require('simple-dom'),
|
||||
Renderer = require('mobiledoc-dom-renderer').default,
|
||||
config = require('../config'),
|
||||
logging = require('../logging'),
|
||||
errors = require('../errors'),
|
||||
defaults = require(config.get('paths').internalAppPath + 'default-cards'),
|
||||
var SimpleDom = require('simple-dom'),
|
||||
Renderer = require('mobiledoc-dom-renderer').default,
|
||||
config = require('../config'),
|
||||
logging = require('../logging'),
|
||||
errors = require('../errors'),
|
||||
defaults = require(config.get('paths').internalAppPath + 'default-cards'),
|
||||
options = {
|
||||
dom: new SimpleDom.Document(),
|
||||
cards: defaults.cards,
|
||||
@ -38,9 +38,9 @@ var SimpleDom = require('simple-dom'),
|
||||
module.exports = {
|
||||
render: function (mobiledoc) {
|
||||
var renderer = new Renderer(options),
|
||||
rendered = renderer.render(mobiledoc),
|
||||
serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap),
|
||||
html = serializer.serializeChildren(rendered.result);
|
||||
rendered = renderer.render(mobiledoc),
|
||||
serializer = new SimpleDom.HTMLSerializer(SimpleDom.voidMap),
|
||||
html = serializer.serializeChildren(rendered.result);
|
||||
return html;
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var parsePackageJson = require('./parse-package-json'),
|
||||
errors = require('../../errors'),
|
||||
Promise = require('bluebird'),
|
||||
|
@ -13,46 +13,46 @@ function readCSV(options) {
|
||||
readFile.on('err', function (err) {
|
||||
reject(err);
|
||||
})
|
||||
.pipe(csvParser())
|
||||
.on('data', function (row) {
|
||||
rows.push(row);
|
||||
})
|
||||
.on('end', function () {
|
||||
// If CSV is single column - return all values including header
|
||||
var headers = _.keys(rows[0]), result = {}, columnMap = {};
|
||||
if (columnsToExtract.length === 1 && headers.length === 1) {
|
||||
results = _.map(rows, function (value) {
|
||||
.pipe(csvParser())
|
||||
.on('data', function (row) {
|
||||
rows.push(row);
|
||||
})
|
||||
.on('end', function () {
|
||||
// If CSV is single column - return all values including header
|
||||
var headers = _.keys(rows[0]), result = {}, columnMap = {};
|
||||
if (columnsToExtract.length === 1 && headers.length === 1) {
|
||||
results = _.map(rows, function (value) {
|
||||
result = {};
|
||||
result[columnsToExtract[0].name] = value[headers[0]];
|
||||
return result;
|
||||
});
|
||||
|
||||
// Add first row
|
||||
result = {};
|
||||
result[columnsToExtract[0].name] = value[headers[0]];
|
||||
return result;
|
||||
});
|
||||
result[columnsToExtract[0].name] = headers[0];
|
||||
results = [result].concat(results);
|
||||
} else {
|
||||
// If there are multiple columns in csv file
|
||||
// try to match headers using lookup value
|
||||
|
||||
// Add first row
|
||||
result = {};
|
||||
result[columnsToExtract[0].name] = headers[0];
|
||||
results = [result].concat(results);
|
||||
} else {
|
||||
// If there are multiple columns in csv file
|
||||
// try to match headers using lookup value
|
||||
|
||||
_.map(columnsToExtract, function findMatches(column) {
|
||||
_.each(headers, function checkheader(header) {
|
||||
if (column.lookup.test(header)) {
|
||||
columnMap[column.name] = header;
|
||||
}
|
||||
_.map(columnsToExtract, function findMatches(column) {
|
||||
_.each(headers, function checkheader(header) {
|
||||
if (column.lookup.test(header)) {
|
||||
columnMap[column.name] = header;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
results = _.map(rows, function evaluateRow(row) {
|
||||
var result = {};
|
||||
_.each(columnMap, function returnMatches(value, key) {
|
||||
result[key] = row[value];
|
||||
results = _.map(rows, function evaluateRow(row) {
|
||||
var result = {};
|
||||
_.each(columnMap, function returnMatches(value, key) {
|
||||
result[key] = row[value];
|
||||
});
|
||||
return result;
|
||||
});
|
||||
return result;
|
||||
});
|
||||
}
|
||||
resolve(results);
|
||||
});
|
||||
}
|
||||
resolve(results);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,8 @@ function removeOpenRedirectFromUrl(urlString) {
|
||||
var parsedUrl = url.parse(urlString);
|
||||
|
||||
return (
|
||||
(parsedUrl.protocol ? parsedUrl.protocol + '//' : '') + // http://
|
||||
// http://
|
||||
(parsedUrl.protocol ? parsedUrl.protocol + '//' : '') +
|
||||
(parsedUrl.auth || '') +
|
||||
(parsedUrl.host || '') +
|
||||
removeDoubleCharacters('/', parsedUrl.path) +
|
||||
|
@ -43,7 +43,6 @@ exports.resetToken = {
|
||||
email: email
|
||||
};
|
||||
},
|
||||
/*jslint bitwise:true*/
|
||||
compare: function compare(options) {
|
||||
options = options || {};
|
||||
|
||||
|
@ -227,13 +227,13 @@ function urlFor(context, data, absolute) {
|
||||
knownObjects = ['post', 'tag', 'author', 'image', 'nav'], baseUrl,
|
||||
hostname,
|
||||
|
||||
// this will become really big
|
||||
knownPaths = {
|
||||
home: '/',
|
||||
rss: '/rss/',
|
||||
api: API_PATH,
|
||||
sitemap_xsl: '/sitemap.xsl'
|
||||
};
|
||||
// this will become really big
|
||||
knownPaths = {
|
||||
home: '/',
|
||||
rss: '/rss/',
|
||||
api: API_PATH,
|
||||
sitemap_xsl: '/sitemap.xsl'
|
||||
};
|
||||
|
||||
// Make data properly optional
|
||||
if (_.isBoolean(data)) {
|
||||
@ -278,7 +278,7 @@ function urlFor(context, data, absolute) {
|
||||
|
||||
if (urlPath.indexOf(hostname) > -1
|
||||
&& !urlPath.split(hostname)[0].match(/\.|mailto:/)
|
||||
&& urlPath.split(hostname)[1].substring(0,1) !== ':') {
|
||||
&& urlPath.split(hostname)[1].substring(0, 1) !== ':') {
|
||||
// make link relative to account for possible
|
||||
// mismatch in http/https etc, force absolute
|
||||
// do not do so if link is a subdomain of blog url
|
||||
|
288
core/test/.eslintrc.json
Normal file
288
core/test/.eslintrc.json
Normal file
@ -0,0 +1,288 @@
|
||||
{
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"accessor-pairs": "error",
|
||||
"array-bracket-newline": "off",
|
||||
"array-bracket-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"array-callback-return": "off",
|
||||
"array-element-newline": "off",
|
||||
"arrow-body-style": "error",
|
||||
"arrow-parens": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"arrow-spacing": [
|
||||
"error",
|
||||
{
|
||||
"after": true,
|
||||
"before": true
|
||||
}
|
||||
],
|
||||
"block-scoped-var": "error",
|
||||
"brace-style": [
|
||||
"error",
|
||||
"1tbs",
|
||||
{
|
||||
"allowSingleLine": true
|
||||
}
|
||||
],
|
||||
"callback-return": "error",
|
||||
"camelcase": "off",
|
||||
"capitalized-comments": "off",
|
||||
"class-methods-use-this": "off",
|
||||
"comma-dangle": "error",
|
||||
"comma-spacing": "error",
|
||||
"comma-style": [
|
||||
"error",
|
||||
"last"
|
||||
],
|
||||
"complexity": "off",
|
||||
"computed-property-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"consistent-return": "off",
|
||||
"consistent-this": "off",
|
||||
"curly": "error",
|
||||
"default-case": "error",
|
||||
"dot-location": [
|
||||
"error",
|
||||
"property"
|
||||
],
|
||||
"dot-notation": "off",
|
||||
"eol-last": "error",
|
||||
"eqeqeq": "error",
|
||||
"for-direction": "error",
|
||||
"func-call-spacing": "error",
|
||||
"func-name-matching": "off",
|
||||
"func-names": "off",
|
||||
"func-style": "off",
|
||||
"function-paren-newline": "off",
|
||||
"generator-star-spacing": "error",
|
||||
"getter-return": "error",
|
||||
"global-require": "off",
|
||||
"guard-for-in": "error",
|
||||
"handle-callback-err": "error",
|
||||
"id-blacklist": "error",
|
||||
"id-length": "off",
|
||||
"id-match": "error",
|
||||
"indent": "off",
|
||||
"indent-legacy": "off",
|
||||
"init-declarations": "off",
|
||||
"jsx-quotes": "error",
|
||||
"key-spacing": "off",
|
||||
"keyword-spacing": "error",
|
||||
"line-comment-position": "off",
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"lines-around-comment": "off",
|
||||
"lines-around-directive": "off",
|
||||
"lines-between-class-members": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"max-depth": "error",
|
||||
"max-len": "off",
|
||||
"max-lines": "off",
|
||||
"max-nested-callbacks": "error",
|
||||
"max-params": "off",
|
||||
"max-statements": "off",
|
||||
"max-statements-per-line": "off",
|
||||
"multiline-comment-style": "off",
|
||||
"multiline-ternary": "off",
|
||||
"new-parens": "error",
|
||||
"newline-after-var": "off",
|
||||
"newline-before-return": "off",
|
||||
"newline-per-chained-call": "off",
|
||||
"no-alert": "error",
|
||||
"no-array-constructor": "error",
|
||||
"no-await-in-loop": "error",
|
||||
"no-bitwise": "off",
|
||||
"no-buffer-constructor": "off",
|
||||
"no-caller": "error",
|
||||
"no-catch-shadow": "error",
|
||||
"no-confusing-arrow": "error",
|
||||
"no-console": "off",
|
||||
"no-continue": "error",
|
||||
"no-div-regex": "off",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-else-return": "off",
|
||||
"no-empty-function": "off",
|
||||
"no-eq-null": "error",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-label": "error",
|
||||
"no-extra-parens": "off",
|
||||
"no-floating-decimal": "error",
|
||||
"no-implicit-globals": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-inline-comments": "off",
|
||||
"no-inner-declarations": [
|
||||
"error",
|
||||
"functions"
|
||||
],
|
||||
"no-invalid-this": "error",
|
||||
"no-iterator": "error",
|
||||
"no-label-var": "error",
|
||||
"no-labels": "error",
|
||||
"no-lone-blocks": "error",
|
||||
"no-lonely-if": "off",
|
||||
"no-loop-func": "error",
|
||||
"no-magic-numbers": "off",
|
||||
"no-mixed-operators": "off",
|
||||
"no-mixed-requires": "off",
|
||||
"no-multi-assign": "off",
|
||||
"no-multi-spaces": "off",
|
||||
"no-multi-str": "error",
|
||||
"no-multiple-empty-lines": "error",
|
||||
"no-native-reassign": "error",
|
||||
"no-negated-condition": "off",
|
||||
"no-negated-in-lhs": "error",
|
||||
"no-nested-ternary": "off",
|
||||
"no-new": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-object": "error",
|
||||
"no-new-require": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-param-reassign": "off",
|
||||
"no-path-concat": "off",
|
||||
"no-plusplus": "error",
|
||||
"no-process-env": "off",
|
||||
"no-process-exit": "error",
|
||||
"no-proto": "error",
|
||||
"no-prototype-builtins": "off",
|
||||
"no-regex-spaces": "off",
|
||||
"no-restricted-globals": "error",
|
||||
"no-restricted-imports": "error",
|
||||
"no-restricted-modules": "error",
|
||||
"no-restricted-properties": "error",
|
||||
"no-restricted-syntax": "error",
|
||||
"no-return-assign": "error",
|
||||
"no-return-await": "error",
|
||||
"no-script-url": "off",
|
||||
"no-self-compare": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "off",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-spaced-func": "error",
|
||||
"no-sync": "off",
|
||||
"no-tabs": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-ternary": "off",
|
||||
"no-throw-literal": "error",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-undefined": "off",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-unneeded-ternary": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-useless-call": "error",
|
||||
"no-useless-computed-key": "error",
|
||||
"no-useless-concat": "off",
|
||||
"no-useless-constructor": "error",
|
||||
"no-useless-escape": "off",
|
||||
"no-useless-rename": "error",
|
||||
"no-useless-return": "error",
|
||||
"no-var": "off",
|
||||
"no-void": "error",
|
||||
"no-warning-comments": "off",
|
||||
"no-whitespace-before-property": "error",
|
||||
"no-with": "error",
|
||||
"nonblock-statement-body-position": "error",
|
||||
"object-curly-newline": [
|
||||
"error",
|
||||
{
|
||||
"consistent": true
|
||||
}
|
||||
],
|
||||
"object-curly-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"object-property-newline": "off",
|
||||
"object-shorthand": "off",
|
||||
"one-var": "off",
|
||||
"one-var-declaration-per-line": "off",
|
||||
"operator-assignment": "off",
|
||||
"operator-linebreak": "off",
|
||||
"padded-blocks": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"padding-line-between-statements": "error",
|
||||
"prefer-arrow-callback": "off",
|
||||
"prefer-const": "off",
|
||||
"prefer-destructuring": "off",
|
||||
"prefer-numeric-literals": "error",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"prefer-reflect": "off",
|
||||
"prefer-rest-params": "off",
|
||||
"prefer-spread": "off",
|
||||
"prefer-template": "off",
|
||||
"quote-props": [
|
||||
"error",
|
||||
"as-needed"
|
||||
],
|
||||
"quotes": "off",
|
||||
"radix": "off",
|
||||
"require-await": "error",
|
||||
"require-jsdoc": "off",
|
||||
"rest-spread-spacing": "error",
|
||||
"semi": ["error", "always"],
|
||||
"semi-spacing": "error",
|
||||
"semi-style": [
|
||||
"error",
|
||||
"last"
|
||||
],
|
||||
"sort-imports": "error",
|
||||
"sort-keys": "off",
|
||||
"sort-vars": "off",
|
||||
"space-before-blocks": "error",
|
||||
"space-before-function-paren": [
|
||||
"error",
|
||||
{
|
||||
"anonymous": "always",
|
||||
"named": "never"
|
||||
}
|
||||
],
|
||||
"space-in-parens": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"space-infix-ops": "error",
|
||||
"space-unary-ops": "error",
|
||||
"spaced-comment": "off",
|
||||
"strict": "off",
|
||||
"switch-colon-spacing": "error",
|
||||
"symbol-description": "error",
|
||||
"template-curly-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"template-tag-spacing": "error",
|
||||
"unicode-bom": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"valid-jsdoc": "off",
|
||||
"vars-on-top": "off",
|
||||
"wrap-iife": "off",
|
||||
"wrap-regex": "off",
|
||||
"yield-star-spacing": "error",
|
||||
"yoda": "error"
|
||||
}
|
||||
}
|
@ -38,6 +38,10 @@ describe('Configuration API', function () {
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
|
||||
should.exist(res.body.configuration);
|
||||
done();
|
||||
});
|
||||
|
@ -100,9 +100,12 @@ describe('Frontend Routing', function () {
|
||||
var date = moment().format('YYYY/MM/DD');
|
||||
|
||||
request.get('/2016/04/01/welcome/')
|
||||
.expect('Content-Type', /html/)
|
||||
.end(function (err, res) {
|
||||
res.status.should.eql(301);
|
||||
.expect(301)
|
||||
.end(function (err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
request.get('/' + date + '/welcome/')
|
||||
.expect(200)
|
||||
.expect('Content-Type', /html/)
|
||||
|
@ -54,7 +54,7 @@ describe('Import', function () {
|
||||
it('removes duplicate posts', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003',{lts:true}).then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function (importResult) {
|
||||
@ -97,7 +97,7 @@ describe('Import', function () {
|
||||
it('cares about invalid dates', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003',{lts:true}).then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003', {lts:true}).then(function (exported) {
|
||||
exportData = exported;
|
||||
return dataImporter.doImport(exportData);
|
||||
}).then(function (importResult) {
|
||||
|
@ -137,8 +137,7 @@ function forkGhost(newConfig) {
|
||||
resolve(child);
|
||||
}
|
||||
});
|
||||
socket.on('error', function (err) {
|
||||
/*jshint unused:false*/
|
||||
socket.on('error', function () {
|
||||
pingTries = pingTries + 1;
|
||||
|
||||
// continue checking
|
||||
|
@ -95,28 +95,26 @@
|
||||
"sqlite3": "3.1.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "4.10.0",
|
||||
"grunt": "1.0.1",
|
||||
"grunt-bg-shell": "2.3.3",
|
||||
"grunt-cli": "1.2.0",
|
||||
"grunt-contrib-clean": "1.1.0",
|
||||
"grunt-contrib-compress": "1.4.3",
|
||||
"grunt-contrib-copy": "1.0.0",
|
||||
"grunt-contrib-jshint": "1.1.0",
|
||||
"grunt-contrib-symlink": "^1.0.0",
|
||||
"grunt-contrib-uglify": "2.0.0",
|
||||
"grunt-contrib-watch": "1.0.0",
|
||||
"grunt-cssnano": "2.1.0",
|
||||
"grunt-docker": "0.0.11",
|
||||
"grunt-eslint": "20.1.0",
|
||||
"grunt-express-server": "0.5.3",
|
||||
"grunt-jscs": "3.0.1",
|
||||
"grunt-mocha-cli": "2.1.0",
|
||||
"grunt-mocha-istanbul": "5.0.2",
|
||||
"grunt-shell": "1.3.1",
|
||||
"grunt-subgrunt": "1.2.0",
|
||||
"grunt-update-submodules": "0.4.1",
|
||||
"istanbul": "0.4.5",
|
||||
"jshint": "2.9.5",
|
||||
"jshint-stylish": "2.2.1",
|
||||
"matchdep": "1.0.1",
|
||||
"minimist": "1.2.0",
|
||||
"mocha": "3.5.3",
|
||||
|
Loading…
Reference in New Issue
Block a user