mirror of
https://github.com/samsonjs/mit-license.git
synced 2026-04-11 12:15:47 +00:00
fix: Properly parse gravatar boolean and switch to standard linter.
Signed-off-by: Richie Bendall <richiebendall@gmail.com>
This commit is contained in:
parent
dfcaa303de
commit
f189d33f29
11 changed files with 201 additions and 188 deletions
|
|
@ -1,8 +1,8 @@
|
|||
module.exports = (_req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Origin', '*')
|
||||
res.header(
|
||||
'Access-Control-Allow-Headers',
|
||||
'Origin, X-Requested-With, Content-Type, Accept'
|
||||
);
|
||||
next();
|
||||
};
|
||||
)
|
||||
next()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,63 +1,63 @@
|
|||
const currentYear = new Date().getFullYear();
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
module.exports = (req, res, next) => {
|
||||
const parts = req.url.split('/');
|
||||
const parts = req.url.split('/')
|
||||
|
||||
res.locals.options = parts.reduce(
|
||||
(acc, curr) => {
|
||||
if (!curr) return acc;
|
||||
if (!curr) return acc
|
||||
|
||||
let match = curr.match(/^@?(\d{4})$/) || [];
|
||||
let match = curr.match(/^@?(\d{4})$/) || []
|
||||
|
||||
if (match.length) {
|
||||
// Pinned year
|
||||
if (curr.startsWith('@')) {
|
||||
acc.pinnedYear = parseInt(curr.substr(1), 10);
|
||||
acc.pinnedYear = parseInt(curr.substr(1), 10)
|
||||
} else {
|
||||
acc.startYear = parseInt(curr, 10);
|
||||
acc.startYear = parseInt(curr, 10)
|
||||
}
|
||||
return acc;
|
||||
return acc
|
||||
}
|
||||
|
||||
match = curr.match(/^(\d{4})-(\d{4})$/) || [];
|
||||
match = curr.match(/^(\d{4})-(\d{4})$/) || []
|
||||
|
||||
if (match.length) {
|
||||
acc.startYear = parseInt(match[1], 10);
|
||||
acc.endYear = parseInt(match[2], 10);
|
||||
acc.startYear = parseInt(match[1], 10)
|
||||
acc.endYear = parseInt(match[2], 10)
|
||||
|
||||
return acc;
|
||||
return acc
|
||||
}
|
||||
|
||||
if (curr.startsWith('license')) {
|
||||
acc.format = curr
|
||||
.split('.')
|
||||
.pop()
|
||||
.trim();
|
||||
return acc;
|
||||
.trim()
|
||||
return acc
|
||||
}
|
||||
|
||||
if (curr.startsWith('+')) {
|
||||
acc.license = curr.substr(1).toUpperCase();
|
||||
return acc;
|
||||
acc.license = curr.substr(1).toUpperCase()
|
||||
return acc
|
||||
}
|
||||
|
||||
acc.sha = curr; // not actually supported now - 2019-06-19
|
||||
return acc;
|
||||
acc.sha = curr // not actually supported now - 2019-06-19
|
||||
return acc
|
||||
},
|
||||
{
|
||||
format: 'html',
|
||||
startYear: null,
|
||||
endYear: currentYear,
|
||||
sha: null,
|
||||
sha: null
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
if (res.locals.options.sha) {
|
||||
res.setHeader(
|
||||
'X-note',
|
||||
'SHA and commit pinning is no longer supported, showing you latest release'
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
next()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = async (req, res, next) => {
|
||||
const id = req.hostname.split('.')[0];
|
||||
res.locals.id = id;
|
||||
const id = req.hostname.split('.')[0]
|
||||
res.locals.id = id
|
||||
|
||||
if (req.method.toUpperCase() !== 'GET') {
|
||||
return next();
|
||||
return next()
|
||||
}
|
||||
|
||||
// Otherwise load up the user json file
|
||||
res.locals.user = {
|
||||
copyright: '<copyright holders>',
|
||||
};
|
||||
copyright: '<copyright holders>'
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await fs.readFile(
|
||||
path.join(__dirname, '..', 'users', `${id}.json`),
|
||||
'utf8'
|
||||
);
|
||||
res.locals.user = { ...res.locals.user, ...JSON.parse(data) };
|
||||
)
|
||||
res.locals.user = { ...res.locals.user, ...JSON.parse(data) }
|
||||
} catch ({ code, message }) {
|
||||
if (code !== 'ENOENT') {
|
||||
res
|
||||
.code(500)
|
||||
.send(
|
||||
`An internal error occurred - open an issue on https://github.com/remy/mit-license with the following information: ${message}`
|
||||
);
|
||||
return;
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
next()
|
||||
}
|
||||
|
|
|
|||
14
package.json
14
package.json
|
|
@ -23,7 +23,7 @@
|
|||
"dev": "nodemon .",
|
||||
"serve": "node server.js",
|
||||
"test": "node test.js",
|
||||
"lint": "eslint server.js middleware/*.js routes/*.js --color"
|
||||
"lint": "standard"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/remy/mit-license/issues"
|
||||
|
|
@ -41,17 +41,15 @@
|
|||
"postcss-middleware": "^1.1.4",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"serve-favicon": "^2.5.0",
|
||||
"temp-dir": "^2.0.0"
|
||||
"temp-dir": "^2.0.0",
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@remy/eslint": "^3.2.2",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"css": "^2.2.4",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-node": "^11.0.0",
|
||||
"has-flag": "^4.0.0",
|
||||
"husky": "^3.1.0",
|
||||
"nodemon": "^2.0.2"
|
||||
"husky": "^4.0.7",
|
||||
"nodemon": "^2.0.2",
|
||||
"standard": "^14.3.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"postcss-middleware/vinyl-fs/glob-stream/micromatch/braces": "^3.0.2"
|
||||
|
|
|
|||
|
|
@ -1,48 +1,48 @@
|
|||
const md5 = require('md5');
|
||||
const path = require('path');
|
||||
const { stripTags, escapeTags, unescapeTags } = require('./utils');
|
||||
const _ = require('lodash');
|
||||
const md5 = require('md5')
|
||||
const path = require('path')
|
||||
const { stripTags, escapeTags, unescapeTags } = require('./utils')
|
||||
const _ = require('lodash')
|
||||
|
||||
function getCopyrightHTML(user, plain) {
|
||||
let html = '';
|
||||
function getCopyrightHTML (user, plain) {
|
||||
let html = ''
|
||||
|
||||
const name = _.isString(user)
|
||||
? user
|
||||
: plain
|
||||
? user.name || user.copyright
|
||||
: escapeTags(user.name || user.copyright);
|
||||
: escapeTags(user.name || user.copyright)
|
||||
|
||||
if (user.url) {
|
||||
html = `<a href="${stripTags(user.url)}">${name}</a>`;
|
||||
html = `<a href="${stripTags(user.url)}">${name}</a>`
|
||||
} else {
|
||||
html = name;
|
||||
html = name
|
||||
}
|
||||
|
||||
if (user.email) {
|
||||
html += ` <<a href="mailto:${stripTags(user.email)}">${
|
||||
plain ? user.email : escapeTags(user.email)
|
||||
}</a>>`;
|
||||
}</a>>`
|
||||
}
|
||||
|
||||
return html;
|
||||
return html
|
||||
}
|
||||
|
||||
module.exports = (req, res) => {
|
||||
const { user, options } = res.locals;
|
||||
let name;
|
||||
let gravatar;
|
||||
const { user, options } = res.locals
|
||||
let name
|
||||
let gravatar
|
||||
|
||||
// No error and valid
|
||||
if (user.copyright) {
|
||||
if (_.isString(user.copyright)) {
|
||||
name = getCopyrightHTML(user, options.format !== 'html');
|
||||
name = getCopyrightHTML(user, options.format !== 'html')
|
||||
} else if (_.isArray(user.copyright) && user.copyright.every(val => _.isString(val))) {
|
||||
// Supports: ['Remy Sharp', 'Richie Bendall']
|
||||
name = user.copyright
|
||||
.map(v => (options.format !== 'html' ? v : escapeTags(v)))
|
||||
.join(', ');
|
||||
.join(', ')
|
||||
} else {
|
||||
name = user.copyright.map(getCopyrightHTML).join(', ');
|
||||
name = user.copyright.map(getCopyrightHTML).join(', ')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,47 +50,47 @@ module.exports = (req, res) => {
|
|||
// Supports regular format
|
||||
gravatar = `<img id="gravatar" alt="Profile image" src="https://www.gravatar.com/avatar/${md5(
|
||||
user.email.trim().toLowerCase()
|
||||
)}" />`;
|
||||
)}" />`
|
||||
} 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()
|
||||
)}" />`;
|
||||
)}" />`
|
||||
}
|
||||
|
||||
const year = options.pinnedYear
|
||||
? options.pinnedYear
|
||||
: [options.startYear, options.endYear].filter(Boolean).join('-');
|
||||
const license = (options.license || user.license || 'MIT').toUpperCase();
|
||||
const format = options.format || user.format || 'html';
|
||||
: [options.startYear, options.endYear].filter(Boolean).join('-')
|
||||
const license = (options.license || user.license || 'MIT').toUpperCase()
|
||||
const format = options.format || user.format || 'html'
|
||||
|
||||
const args = {
|
||||
info: `${year} ${name}`,
|
||||
theme: user.theme || 'default',
|
||||
gravatar,
|
||||
};
|
||||
gravatar
|
||||
}
|
||||
|
||||
const filename = path.join(__dirname, '..', 'licenses', license);
|
||||
const filename = path.join(__dirname, '..', 'licenses', license)
|
||||
req.app.render(filename, args, (error, content) => {
|
||||
if (error) {
|
||||
res.status(500).send(error);
|
||||
return;
|
||||
res.status(500).send(error)
|
||||
return
|
||||
}
|
||||
|
||||
if (format === 'txt') {
|
||||
const plain = content.match(/<article>(.*)<\/article>/ms)[1];
|
||||
const plain = content.match(/<article>(.*)<\/article>/ms)[1]
|
||||
|
||||
res
|
||||
.set('Content-Type', 'text/plain; charset=UTF-8')
|
||||
.send(unescapeTags(stripTags(plain)).trim());
|
||||
return;
|
||||
.send(unescapeTags(stripTags(plain)).trim())
|
||||
return
|
||||
}
|
||||
|
||||
if (format === 'html') {
|
||||
res.send(content);
|
||||
return;
|
||||
res.send(content)
|
||||
return
|
||||
}
|
||||
|
||||
res.json({ ...user, ...options });
|
||||
});
|
||||
};
|
||||
res.json({ ...user, ...options })
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,44 @@
|
|||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const btoa = require('btoa');
|
||||
const { version } = require(path.join(__dirname, '..', 'package.json'));
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
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,
|
||||
// User agent with version from package.json
|
||||
userAgent: `mit-license v${version}`,
|
||||
});
|
||||
const { validDomainId } = require('./utils');
|
||||
userAgent: `mit-license v${version}`
|
||||
})
|
||||
const yn = require('yn')
|
||||
|
||||
function getUserData({ query, body }) {
|
||||
const { validDomainId } = require('./utils')
|
||||
|
||||
function getUserData ({ query, body }) {
|
||||
// If query parameters provided
|
||||
if (_.size(query) > 0) return query;
|
||||
if (_.size(query) > 0) return query
|
||||
// If the data parsed as {'{data: "value"}': ''}
|
||||
if (_.size(body) === 1 && !_.first(_.values(body))) return JSON.parse(_.first(_.keys(body)));
|
||||
if (_.size(body) === 1 && !_.first(_.values(body))) return JSON.parse(_.first(_.keys(body)))
|
||||
// Fallback
|
||||
return body;
|
||||
return body
|
||||
}
|
||||
|
||||
// HTTP POST API
|
||||
module.exports = async (req, res) => {
|
||||
const { hostname } = req;
|
||||
const { hostname } = req
|
||||
// Get different parts of hostname (example: remy.mit-license.org -> ['remy', 'mit-license', 'org'])
|
||||
const params = hostname.split('.');
|
||||
const params = hostname.split('.')
|
||||
|
||||
// This includes the copyright, year, etc.
|
||||
const userData = getUserData(req);
|
||||
const userData = getUserData(req)
|
||||
|
||||
// If there isn't enough part of the hostname
|
||||
if (params.length < 2) {
|
||||
res.status(400).send('Please specify a subdomain in the URL.');
|
||||
return;
|
||||
res.status(400).send('Please specify a subdomain in the URL.')
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the name from the URL
|
||||
const id = _.first(params);
|
||||
const id = _.first(params)
|
||||
|
||||
if (!validDomainId(id)) {
|
||||
// Return a vague error intentionally
|
||||
|
|
@ -44,31 +46,44 @@ module.exports = async (req, res) => {
|
|||
.status(400)
|
||||
.send(
|
||||
'User already exists - to update values, please send a pull request on https://github.com/remy/mit-license'
|
||||
);
|
||||
)
|
||||
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the user file exists in the users directory
|
||||
const exists = await fs.pathExists(path.join(__dirname, '..', 'users', `${id}.json`));
|
||||
const exists = await fs.pathExists(path.join(__dirname, '..', 'users', `${id}.json`))
|
||||
if (exists) {
|
||||
res
|
||||
.status(409)
|
||||
.send(
|
||||
'User already exists - to update values, please send a pull request on https://github.com/remy/mit-license'
|
||||
);
|
||||
return;
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (userData.gravatar) {
|
||||
// Parse the string version of a boolean or similar
|
||||
userData.gravatar = yn(userData.gravatar, { lenient: true })
|
||||
if (_.isUndefined(userData.gravatar)) {
|
||||
res
|
||||
.status(400)
|
||||
.send(
|
||||
'The "gravatar" JSON property must be a boolean.'
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// File doesn't exist
|
||||
// If copyright property and key doesn't exist
|
||||
if (!userData.copyright) {
|
||||
res.status(400).send('JSON requires "copyright" property and value');
|
||||
return;
|
||||
res.status(400).send('JSON requires "copyright" property and value')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const fileContent = JSON.stringify(userData, 0, 2);
|
||||
const fileContent = JSON.stringify(userData, 0, 2)
|
||||
|
||||
await github.repos.createOrUpdateFile({
|
||||
owner: 'remy',
|
||||
|
|
@ -78,18 +93,18 @@ module.exports = async (req, res) => {
|
|||
content: btoa(fileContent),
|
||||
committer: {
|
||||
name: 'MIT License Bot',
|
||||
email: 'remy@leftlogic.com',
|
||||
},
|
||||
});
|
||||
email: 'remy@leftlogic.com'
|
||||
}
|
||||
})
|
||||
|
||||
await fs.writeFile(path.join(__dirname, '..', 'users', `${id}.json`), fileContent);
|
||||
await fs.writeFile(path.join(__dirname, '..', 'users', `${id}.json`), fileContent)
|
||||
|
||||
res.status(201).send(`MIT license page created: https://${hostname}`);
|
||||
res.status(201).send(`MIT license page created: https://${hostname}`)
|
||||
} catch (err) {
|
||||
res
|
||||
.status(500)
|
||||
.send(
|
||||
`Unable to create new user - please send a pull request on https://github.com/remy/mit-license`
|
||||
);
|
||||
'Unable to create new user - please send a pull request on https://github.com/remy/mit-license'
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
const _ = require('lodash');
|
||||
const _ = require('lodash')
|
||||
|
||||
const tags = {
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'&': '&',
|
||||
};
|
||||
const untags = _.invert(tags);
|
||||
'&': '&'
|
||||
}
|
||||
const untags = _.invert(tags)
|
||||
|
||||
module.exports = {
|
||||
escapeTags: str => (str || '').replace(/[<>&]/g, m => tags[m]),
|
||||
unescapeTags: str =>
|
||||
(str || '').replace(/(<|>|&)/g, m => untags[m]),
|
||||
stripTags: str => (str || '').replace(/<(?:.|\n)*?>/gm, ''),
|
||||
validDomainId: str => /^[\w-_]+$/.test(str),
|
||||
};
|
||||
validDomainId: str => /^[\w-_]+$/.test(str)
|
||||
}
|
||||
|
|
|
|||
62
server.js
62
server.js
|
|
@ -5,68 +5,68 @@ IMPORTANT: Set the `github_token` environment variable to a personal access to
|
|||
Server port: The `PORT` environment variable can also be set to control the port the server
|
||||
should be hosted on.
|
||||
*/
|
||||
const express = require('express');
|
||||
const minify = require('express-minify');
|
||||
const favicon = require('serve-favicon');
|
||||
const postcssMiddleware = require('postcss-middleware');
|
||||
const tmpdir = require('temp-dir');
|
||||
const path = require('path');
|
||||
const express = require('express')
|
||||
const minify = require('express-minify')
|
||||
const favicon = require('serve-favicon')
|
||||
const postcssMiddleware = require('postcss-middleware')
|
||||
const tmpdir = require('temp-dir')
|
||||
const path = require('path')
|
||||
|
||||
// Server
|
||||
var PORT = process.env.PORT || 8080;
|
||||
var PORT = process.env.PORT || 8080
|
||||
|
||||
// Prepare application
|
||||
const app = express();
|
||||
const app = express()
|
||||
app.use(
|
||||
minify({
|
||||
cache: tmpdir,
|
||||
cache: tmpdir
|
||||
})
|
||||
);
|
||||
app.use(favicon(path.join(__dirname, 'favicon.ico')));
|
||||
app.set('views', path.join(__dirname, '/licenses'));
|
||||
app.set('view engine', 'ejs');
|
||||
)
|
||||
app.use(favicon(path.join(__dirname, 'favicon.ico')))
|
||||
app.set('views', path.join(__dirname, '/licenses'))
|
||||
app.set('view engine', 'ejs')
|
||||
|
||||
// Setup static files
|
||||
app.use('/robots.txt', express.static('robots.txt'));
|
||||
app.use('/favicon.ico', express.static(`${__dirname}/favicon.ico`));
|
||||
app.use('/robots.txt', express.static('robots.txt'))
|
||||
app.use('/favicon.ico', express.static(`${__dirname}/favicon.ico`))
|
||||
app.use(
|
||||
'/themes',
|
||||
postcssMiddleware({
|
||||
plugins: [
|
||||
require('postcss-preset-env')({
|
||||
overrideBrowserslist: '>= 0%',
|
||||
stage: 0,
|
||||
}),
|
||||
stage: 0
|
||||
})
|
||||
],
|
||||
src(req) {
|
||||
return path.join(__dirname, 'themes', req.path);
|
||||
},
|
||||
src (req) {
|
||||
return path.join(__dirname, 'themes', req.path)
|
||||
}
|
||||
}),
|
||||
express.static('themes')
|
||||
);
|
||||
)
|
||||
|
||||
// Middleware
|
||||
|
||||
// CORS
|
||||
app.use(require('./middleware/cors'));
|
||||
app.use(require('./middleware/cors'))
|
||||
// Parse URL-encoded bodies (as sent by HTML forms)
|
||||
app.use(
|
||||
express.urlencoded({
|
||||
extended: true,
|
||||
extended: true
|
||||
})
|
||||
);
|
||||
)
|
||||
// Parse JSON bodies (as sent by API clients)
|
||||
app.use(express.json());
|
||||
app.use(express.json())
|
||||
|
||||
// Capture the id from the subdomain
|
||||
app.use(require('./middleware/load-user'));
|
||||
app.use(require('./middleware/load-options'));
|
||||
app.use(require('./middleware/load-user'))
|
||||
app.use(require('./middleware/load-options'))
|
||||
|
||||
// HTTP POST API
|
||||
app.post('/', require('./routes/post'));
|
||||
app.get('/*', require('./routes/get'));
|
||||
app.post('/', require('./routes/post'))
|
||||
app.get('/*', require('./routes/get'))
|
||||
|
||||
// Start listening for HTTP requests
|
||||
app.listen(PORT, () => {
|
||||
console.log(`🚀 on http://localhost:${PORT}`);
|
||||
});
|
||||
console.log(`🚀 on http://localhost:${PORT}`)
|
||||
})
|
||||
|
|
|
|||
66
test.js
66
test.js
|
|
@ -1,68 +1,68 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const CSS = require('css');
|
||||
const { validDomainId } = require('./routes/utils');
|
||||
const hasFlag = require('has-flag');
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const CSS = require('css')
|
||||
const { validDomainId } = require('./routes/utils')
|
||||
const hasFlag = require('has-flag')
|
||||
|
||||
function report(content, fix) {
|
||||
console.error(content);
|
||||
if (fix && hasFlag('--fix')) fix();
|
||||
process.exitCode = 1;
|
||||
function report (content, fix) {
|
||||
console.error(content)
|
||||
if (fix && hasFlag('--fix')) fix()
|
||||
process.exitCode = 1
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const users = await fs.readdir('users');
|
||||
const users = await fs.readdir('users')
|
||||
users.forEach(async user => {
|
||||
if (!user.endsWith('json')) {
|
||||
report(`${user} is not a json file`, () =>
|
||||
fs.unlink(path.join('users', user), () => { })
|
||||
);
|
||||
)
|
||||
}
|
||||
if (!validDomainId(user.replace('.json', ''))) {
|
||||
report(`${user} is not a valid domain id.`);
|
||||
report(`${user} is not a valid domain id.`)
|
||||
}
|
||||
try {
|
||||
const data = await fs.readFile(path.join('users', user), 'utf8');
|
||||
const data = await fs.readFile(path.join('users', user), 'utf8')
|
||||
try {
|
||||
const u = JSON.parse(data);
|
||||
const u = JSON.parse(data)
|
||||
if (!u.locked && !u.copyright) {
|
||||
report(`Copyright not specified in ${user}`);
|
||||
report(`Copyright not specified in ${user}`)
|
||||
}
|
||||
if (u.version) {
|
||||
report(`Version tag found in ${user}`, () => {
|
||||
delete u.version;
|
||||
const stringified = `${JSON.stringify(u, 0, 2)}\n`;
|
||||
fs.writeFile(path.join('users', user), stringified, () => { });
|
||||
});
|
||||
delete u.version
|
||||
const stringified = `${JSON.stringify(u, 0, 2)}\n`
|
||||
fs.writeFile(path.join('users', user), stringified, () => { })
|
||||
})
|
||||
}
|
||||
if (typeof u.gravatar === 'string') {
|
||||
report(`Gravatar boolean encoded as string found in ${user}`, () => {
|
||||
u.gravatar = u.gravatar === 'true';
|
||||
const stringified = `${JSON.stringify(u, 0, 2)}\n`;
|
||||
fs.writeFile(path.join('users', user), stringified, () => { });
|
||||
});
|
||||
u.gravatar = u.gravatar === 'true'
|
||||
const stringified = `${JSON.stringify(u, 0, 2)}\n`
|
||||
fs.writeFile(path.join('users', user), stringified, () => { })
|
||||
})
|
||||
}
|
||||
} catch ({ message }) {
|
||||
report(`Invalid JSON in ${user} (${message})`);
|
||||
report(`Invalid JSON in ${user} (${message})`)
|
||||
}
|
||||
} catch ({ message }) {
|
||||
report(`Unable to read ${user} (${message})`);
|
||||
report(`Unable to read ${user} (${message})`)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
const themes = await fs.readdir('themes');
|
||||
const themes = await fs.readdir('themes')
|
||||
await themes.forEach(async theme => {
|
||||
if (theme.endsWith('css')) {
|
||||
try {
|
||||
const data = await fs.readFile(path.join('themes', theme), 'utf8');
|
||||
const data = await fs.readFile(path.join('themes', theme), 'utf8')
|
||||
try {
|
||||
CSS.parse(data);
|
||||
CSS.parse(data)
|
||||
} catch ({ message }) {
|
||||
report(`Invalid CSS in ${theme} (${message})`);
|
||||
report(`Invalid CSS in ${theme} (${message})`)
|
||||
}
|
||||
} catch ({ message }) {
|
||||
report(`Unable to read ${theme} (${message})`);
|
||||
report(`Unable to read ${theme} (${message})`)
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
})
|
||||
})()
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@
|
|||
"format": "text",
|
||||
"license": "mit",
|
||||
"theme": "default",
|
||||
"gravatar": "false"
|
||||
}
|
||||
"gravatar": false
|
||||
}
|
||||
|
|
|
|||
BIN
yarn.lock
BIN
yarn.lock
Binary file not shown.
Loading…
Reference in a new issue