refactor: Properly unescape tags, update deps, simplify code with lodash, use Remy's eslint rules (Closes #1375)

Signed-off-by: Richie Bendall <richiebendall@gmail.com>
This commit is contained in:
Richie Bendall 2019-11-06 20:08:34 +13:00
parent 2cd12f2695
commit 054b6b76c7
No known key found for this signature in database
GPG key ID: 1C6A99DFA9D306FC
8 changed files with 35 additions and 52 deletions

1
.eslintrc.js Normal file
View file

@ -0,0 +1 @@
module.exports = require('@remy/eslint')('node');

View file

@ -1,25 +0,0 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"plugins": [
"node"
],
"extends": [
"plugin:prettier/recommended",
"eslint:recommended",
"plugin:node/recommended"
],
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"warnOnUnsupportedTypeScriptVersion": false
},
"rules": {
"prettier/prettier": "error",
"node/no-deprecated-api": 0,
"no-console": 0
}
}

View file

@ -1,3 +0,0 @@
# use the prettier defaults except for:
trailingComma: "es5"
singleQuote: true

View file

@ -30,33 +30,34 @@
},
"license": "MIT",
"dependencies": {
"@octokit/rest": "^16.33.1",
"@octokit/rest": "^16.34.1",
"btoa": "^1.2.1",
"ejs": "^2.7.1",
"express": "^4.17.1",
"express-minify": "^1.0.0",
"lodash": "^4.17.15",
"md5": "^2.2.1",
"postcss-middleware": "^1.1.4",
"postcss-preset-env": "^6.7.0",
"serve-favicon": "^2.5.0"
},
"devDependencies": {
"@remy/eslint": "^3.2.2",
"@types/btoa": "^1.2.3",
"@types/css": "^0.0.31",
"@types/ejs": "^2.6.3",
"@types/express": "^4.17.1",
"@types/express": "^4.17.2",
"@types/express-minify": "^0.1.34",
"@types/lodash": "^4.14.144",
"@types/md5": "^2.1.33",
"@types/node": "^12.11.1",
"@types/node": "^12.12.6",
"babel-eslint": "^10.0.3",
"css": "^2.2.4",
"eslint": "^6.5.1",
"eslint-config-prettier": "^6.4.0",
"eslint": "^6.6.0",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-prettier": "^3.1.1",
"has-flag": "^4.0.0",
"husky": "^3.0.9",
"nodemon": "^1.19.4",
"prettier": "^1.18.2"
"nodemon": "^1.19.4"
},
"resolutions": {
"postcss-middleware/vinyl-fs/glob-stream/micromatch/braces": "^3.0.2"

View file

@ -1,14 +1,14 @@
const md5 = require('md5');
const path = require('path');
const { stripTags, escapeTags } = require('./utils');
const { stripTags, escapeTags, unescapeTags } = require('./utils');
const _ = require('lodash');
function getCopyrightHTML(user, plain) {
let html = '';
const name =
typeof user === 'string'
? user
: plain
const name = _.isString(user)
? user
: plain
? user.name || user.copyright
: escapeTags(user.name || user.copyright);
@ -34,9 +34,9 @@ module.exports = (req, res) => {
// No error and valid
if (user.copyright) {
if (typeof user.copyright === 'string') {
if (_.isString(user.copyright)) {
name = getCopyrightHTML(user, options.format !== 'html');
} else if (user.copyright.every(val => typeof val === 'string')) {
} else if (user.copyright.every(val => _.isString(val))) {
// Supports: ['Remy Sharp', 'Richie Bendall']
name = user
.map(_ => (options.format !== 'html' ? _ : escapeTags(_)))
@ -51,7 +51,7 @@ module.exports = (req, res) => {
gravatar = `<img id="gravatar" alt="Profile image" src="https://www.gravatar.com/avatar/${md5(
user.email.trim().toLowerCase()
)}" />`;
} else if (typeof user.copyright[0] === 'object' && user.gravatar) {
} else if (_.isObject(user.copyright[0]) && user.gravatar) {
// Supports multi-user format
gravatar = `<img id="gravatar" alt="Profile image" src="https://www.gravatar.com/avatar/${md5(
user.copyright[0].email.trim().toLowerCase()
@ -82,7 +82,7 @@ module.exports = (req, res) => {
res
.set('Content-Type', 'text/plain; charset=UTF-8')
.send(stripTags(plain).trim());
.send(unescapeTags(stripTags(plain)).trim());
return;
}

View file

@ -5,6 +5,7 @@ const access = promisify(fs.access);
const writeFile = promisify(fs.writeFile);
const btoa = require('btoa');
const { version } = require(path.join(__dirname, '..', 'package.json'));
const _ = require('lodash');
const github = require('@octokit/rest')({
// GitHub personal access token
auth: process.env.github_token,
@ -15,10 +16,10 @@ const { validDomainId } = require('./utils');
function getUserData({ query, body }) {
// If query parameters provided
if (Object.keys(query).length > 0) return query;
if (_.size(query) > 0) return query;
// If the data parsed as {'{data: "value"}': ''}
const keys = Object.keys(body);
if (keys.length === 1 && !Object.values(body)[0]) return JSON.parse(keys[0]);
if (_.size(body) === 1 && !_.first(_.values(body)))
return JSON.parse(_.first(_.keys(body)));
// Fallback
return body;
}
@ -39,7 +40,7 @@ module.exports = async (req, res) => {
}
// Extract the name from the URL
const id = params[0];
const id = _.first(params);
if (!validDomainId(id)) {
// Return a vague error intentionally

View file

@ -1,8 +1,16 @@
const _ = require('lodash');
const tags = {
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
};
exports.escapeTags = str => (str || '').replace(/[<>&]/g, m => tags[m]);
exports.stripTags = str => (str || '').replace(/<(?:.|\n)*?>/gm, '');
exports.validDomainId = str => /^[\w-_]+$/.test(str);
const untags = _.invert(tags);
module.exports = {
escapeTags: str => (str || '').replace(/[<>&]/g, m => tags[m]),
unescapeTags: str =>
(str || '').replace(/(&lt;|&gt;|&amp;)/g, m => untags[m]),
stripTags: str => (str || '').replace(/<(?:.|\n)*?>/gm, ''),
validDomainId: str => /^[\w-_]+$/.test(str),
};

BIN
yarn.lock

Binary file not shown.