mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-08-09 07:25:21 +02:00
added middlewares, user model and controller
This commit is contained in:
parent
56e60df763
commit
618123100e
12 changed files with 192 additions and 83 deletions
30
dbinsert.js
30
dbinsert.js
|
@ -1,16 +1,38 @@
|
||||||
let { password: db } = require('./src/utils/database');
|
let { password: db } = require('./src/utils/database');
|
||||||
const md5 = require('md5');
|
|
||||||
const program = require('commander');
|
const program = require('commander');
|
||||||
|
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
const saltRounds = 10;
|
||||||
|
|
||||||
program
|
program
|
||||||
.description('Application for inserting new passwords to database.')
|
.description('Application for inserting new passwords to database.')
|
||||||
.usage('insert [password]')
|
.usage('insert [password]')
|
||||||
.command('insert <password>')
|
.command('insert <password>')
|
||||||
.action(async function (password) {
|
.action(async function (password) {
|
||||||
let doc = { password: md5(password) };
|
let userDoc = null;
|
||||||
let newDoc = await db.insert(doc);
|
let saltDoc = null;
|
||||||
|
|
||||||
console.log('Password was inserted as', newDoc);
|
bcrypt.genSalt(saltRounds, function (err1, salt) {
|
||||||
|
if (err1) {
|
||||||
|
return ('Salt generation error');
|
||||||
|
}
|
||||||
|
|
||||||
|
saltDoc = { type: 'salt', saltValue: salt };
|
||||||
|
|
||||||
|
bcrypt.hash(password, salt, async (err2, hash) => {
|
||||||
|
if (err2) {
|
||||||
|
return ('Hash generation error');
|
||||||
|
}
|
||||||
|
|
||||||
|
userDoc = { passHash: hash };
|
||||||
|
|
||||||
|
await db.insert(saltDoc);
|
||||||
|
await db.insert(userDoc);
|
||||||
|
|
||||||
|
console.log('Generated salt:', saltDoc.saltValue);
|
||||||
|
console.log('Password hash was inserted as:', userDoc.passHash);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
program.on('--help', () => {
|
program.on('--help', () => {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "^7.0.0",
|
"@babel/polyfill": "^7.0.0",
|
||||||
|
"bcrypt": "^3.0.3",
|
||||||
"body-parser": "latest",
|
"body-parser": "latest",
|
||||||
"codex.editor": "^2.1.3",
|
"codex.editor": "^2.1.3",
|
||||||
"codex.editor.header": "^2.0.5",
|
"codex.editor.header": "^2.0.5",
|
||||||
|
@ -23,7 +24,6 @@
|
||||||
"express": "~4.16.0",
|
"express": "~4.16.0",
|
||||||
"http-errors": "~1.7.1",
|
"http-errors": "~1.7.1",
|
||||||
"jsonwebtoken": "^8.4.0",
|
"jsonwebtoken": "^8.4.0",
|
||||||
"md5": "^2.2.1",
|
|
||||||
"module-dispatcher": "^1.0.2",
|
"module-dispatcher": "^1.0.2",
|
||||||
"morgan": "~1.9.0",
|
"morgan": "~1.9.0",
|
||||||
"multer": "^1.3.1",
|
"multer": "^1.3.1",
|
||||||
|
|
|
@ -48,7 +48,7 @@ class Pages {
|
||||||
* @param {string} parent - id of current page
|
* @param {string} parent - id of current page
|
||||||
* @returns {Promise<Page[]>}
|
* @returns {Promise<Page[]>}
|
||||||
*/
|
*/
|
||||||
static async getAllExceptChildrens(parent) {
|
static async getAllExceptChildren(parent) {
|
||||||
let pagesAvailable = this.removeChildren(await Pages.getAll(), parent);
|
let pagesAvailable = this.removeChildren(await Pages.getAll(), parent);
|
||||||
|
|
||||||
return pagesAvailable.filter((item) => item !== null);
|
return pagesAvailable.filter((item) => item !== null);
|
||||||
|
|
33
src/controllers/users.js
Normal file
33
src/controllers/users.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
const Model = require('../models/user');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Users
|
||||||
|
* @classdesc Users controller
|
||||||
|
*/
|
||||||
|
class Users {
|
||||||
|
/**
|
||||||
|
* @static
|
||||||
|
* Find and return user model with given password hash
|
||||||
|
*
|
||||||
|
* @param {string} passHash - hashed password
|
||||||
|
* @returns {Promise<User>}
|
||||||
|
*/
|
||||||
|
static async get(passHash) {
|
||||||
|
const userDoc = await Model.get(passHash);
|
||||||
|
|
||||||
|
return userDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find and return salt
|
||||||
|
*
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
static async getSalt() {
|
||||||
|
const salt = await Model.getSalt();
|
||||||
|
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Users;
|
|
@ -75,7 +75,7 @@ class Page {
|
||||||
/**
|
/**
|
||||||
* Return PageData object
|
* Return PageData object
|
||||||
*
|
*
|
||||||
* @returns {PageData}
|
* @ {PageData}
|
||||||
*/
|
*/
|
||||||
get data() {
|
get data() {
|
||||||
return {
|
return {
|
||||||
|
|
41
src/models/user.js
Normal file
41
src/models/user.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
const {password: db} = require('../utils/database/index');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class User
|
||||||
|
* @class User model
|
||||||
|
*
|
||||||
|
* @property {string} passHash - hashed password
|
||||||
|
*/
|
||||||
|
class User {
|
||||||
|
/**
|
||||||
|
* Find and return model of user with given password hash
|
||||||
|
*
|
||||||
|
* @param {string} passHash - hashed password
|
||||||
|
* @returns {Promise<User>}
|
||||||
|
*/
|
||||||
|
static async get(passHash) {
|
||||||
|
const data = await db.findOne({ passHash: passHash });
|
||||||
|
|
||||||
|
return new User(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static async getSalt() {
|
||||||
|
const saltDoc = await db.findOne({type: 'salt'});
|
||||||
|
|
||||||
|
return saltDoc.saltValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*
|
||||||
|
* @param {Object} userData
|
||||||
|
*/
|
||||||
|
constructor(userData) {
|
||||||
|
this.passHash = userData.passHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = User;
|
|
@ -1,36 +1,47 @@
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const csrf = require('csurf');
|
|
||||||
const bodyParser = require('body-parser');
|
const bodyParser = require('body-parser');
|
||||||
const { password: db } = require('../utils/database/index');
|
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const config = require('../../config/index');
|
|
||||||
const md5 = require('md5');
|
|
||||||
|
|
||||||
|
const Users = require('../controllers/users');
|
||||||
|
const config = require('../../config/index');
|
||||||
|
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
// const saltRounds = 10;
|
||||||
|
|
||||||
|
const csrf = require('csurf');
|
||||||
const csrfProtection = csrf({ cookie: true });
|
const csrfProtection = csrf({ cookie: true });
|
||||||
const parseForm = bodyParser.urlencoded({ extended: false });
|
const parseForm = bodyParser.urlencoded({ extended: false });
|
||||||
|
|
||||||
/* GET authorization page. */
|
/* GET authorization page. */
|
||||||
router.get('/auth', csrfProtection, function (req, res, next) {
|
router.get('/auth', csrfProtection, function (req, res) {
|
||||||
res.render('auth', { title: 'Login page ', header: 'Enter password', csrfToken: req.csrfToken() });
|
res.render('auth', { title: 'Login page ', header: 'Enter password', csrfToken: req.csrfToken() });
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/auth', parseForm, csrfProtection, async (req, res) => {
|
router.post('/auth', parseForm, csrfProtection, async (req, res) => {
|
||||||
const passwordDoc = await db.findOne({ 'password': md5(req.body.password) });
|
let salt = await Users.getSalt();
|
||||||
|
|
||||||
if (passwordDoc !== null) {
|
bcrypt.hash(req.body.password, salt, async function (err, hash) {
|
||||||
const token = jwt.sign({
|
if (err) {
|
||||||
'iss': 'Codex Team',
|
res.status(500);
|
||||||
'sub': 'auth',
|
}
|
||||||
'iat': Date.now()
|
|
||||||
}, passwordDoc.password + config.secret);
|
|
||||||
|
|
||||||
res.cookie('authToken', token);
|
const userDoc = await Users.get(hash);
|
||||||
|
|
||||||
res.redirect('/');
|
if (userDoc) {
|
||||||
} else {
|
const token = jwt.sign({
|
||||||
res.render('auth', { title: 'Login page', header: 'Wrong password' });
|
'iss': 'Codex Team',
|
||||||
}
|
'sub': 'auth',
|
||||||
|
'iat': Date.now()
|
||||||
|
}, userDoc.passHash + config.secret);
|
||||||
|
|
||||||
|
res.cookie('authToken', token);
|
||||||
|
|
||||||
|
res.redirect('/');
|
||||||
|
} else {
|
||||||
|
res.render('auth', { title: 'Login page', header: 'Wrong password', csrfToken: req.csrfToken() });
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
@ -4,8 +4,7 @@ const router = express.Router();
|
||||||
|
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
router.get('/', verifyToken, async (req, res) => {
|
router.get('/', verifyToken, async (req, res) => {
|
||||||
|
res.render('index', { title: 'Express', isAuthorized: res.locals.isAuthorized });
|
||||||
res.render('index', { title: 'Express', isAuthorized: req.isAuthorized });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
7
src/routes/middlewares/locals.js
Normal file
7
src/routes/middlewares/locals.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
module.exports = function allowEdit(req, res, next) {
|
||||||
|
if (res.locals.isAuthorized) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
res.redirect('/auth');
|
||||||
|
}
|
||||||
|
};
|
|
@ -4,16 +4,9 @@ const jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
module.exports = async function verifyToken(req, res, next) {
|
module.exports = async function verifyToken(req, res, next) {
|
||||||
let token = req.cookies.authToken;
|
let token = req.cookies.authToken;
|
||||||
let isAuthorized = false;
|
|
||||||
|
|
||||||
jwt.verify(token, process.env.PASSWORD + config.secret, (err, decodedToken) => {
|
jwt.verify(token, process.env.PASSHASH + config.secret, (err, decodedToken) => {
|
||||||
if (err || !decodedToken) {
|
res.locals.isAuthorized = !(err || !decodedToken);
|
||||||
return (err);
|
next();
|
||||||
} else {
|
|
||||||
isAuthorized = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
req.isAuthorized = isAuthorized;
|
|
||||||
next();
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,44 +2,37 @@ const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const Pages = require('../controllers/pages');
|
const Pages = require('../controllers/pages');
|
||||||
const verifyToken = require('./middlewares/token');
|
const verifyToken = require('./middlewares/token');
|
||||||
|
const allowEdit = require('./middlewares/locals');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new page form
|
* Create new page form
|
||||||
*/
|
*/
|
||||||
router.get('/page/new', verifyToken, async (req, res, next) => {
|
router.get('/page/new', verifyToken, allowEdit, async (req, res, next) => {
|
||||||
if (!req.isAuthorized) {
|
let pagesAvailable = await Pages.getAll();
|
||||||
res.render('auth', { title: 'Login page', header: 'Enter password to do this!' });
|
|
||||||
} else {
|
|
||||||
let pagesAvailable = await Pages.getAll();
|
|
||||||
|
|
||||||
res.render('pages/form', {
|
res.render('pages/form', {
|
||||||
pagesAvailable,
|
pagesAvailable,
|
||||||
page: null
|
page: null
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit page form
|
* Edit page form
|
||||||
*/
|
*/
|
||||||
router.get('/page/edit/:id', verifyToken, async (req, res, next) => {
|
router.get('/page/edit/:id', verifyToken, allowEdit, async (req, res, next) => {
|
||||||
if (!req.isAuthorized) {
|
const pageId = req.params.id;
|
||||||
res.render('auth', { title: 'Login page', header: 'Enter password to do this!' });
|
|
||||||
} else {
|
|
||||||
const pageId = req.params.id;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let page = await Pages.get(pageId);
|
let page = await Pages.get(pageId);
|
||||||
let pagesAvailable = await Pages.getAllExceptChildrens(pageId);
|
let pagesAvailable = await Pages.getAllExceptChildren(pageId);
|
||||||
|
|
||||||
res.render('pages/form', {
|
res.render('pages/form', {
|
||||||
pagesAvailable,
|
pagesAvailable,
|
||||||
page
|
page
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(404);
|
res.status(404);
|
||||||
next(error);
|
next(error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -55,7 +48,7 @@ router.get('/page/:id', verifyToken, async (req, res, next) => {
|
||||||
let pageParent = await page.parent;
|
let pageParent = await page.parent;
|
||||||
|
|
||||||
res.render('pages/page', {
|
res.render('pages/page', {
|
||||||
page, pageParent, isAuthorized: req.isAuthorized
|
page, pageParent, isAuthorized: res.locals.isAuthorized
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(404);
|
res.status(404);
|
||||||
|
|
50
yarn.lock
50
yarn.lock
|
@ -1140,6 +1140,14 @@ basic-auth@~2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "5.1.2"
|
safe-buffer "5.1.2"
|
||||||
|
|
||||||
|
bcrypt@^3.0.3:
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-3.0.3.tgz#7d1e9e5d533c5ea060e6ac8834942c004dbffe9c"
|
||||||
|
integrity sha512-4EuzUo6K790QC3uq/ogzy9w2Hc7XDIBoEndU5y7l7YaEAwQF8vyFqv6tC30+gOBZvyxk3F632xzKBQoLNz2pjg==
|
||||||
|
dependencies:
|
||||||
|
nan "2.12.1"
|
||||||
|
node-pre-gyp "0.12.0"
|
||||||
|
|
||||||
big.js@^3.1.3:
|
big.js@^3.1.3:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
|
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
|
||||||
|
@ -1506,11 +1514,6 @@ chardet@^0.7.0:
|
||||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||||
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
||||||
|
|
||||||
charenc@~0.0.1:
|
|
||||||
version "0.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
|
||||||
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
|
|
||||||
|
|
||||||
check-error@^1.0.2:
|
check-error@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
||||||
|
@ -1932,11 +1935,6 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
|
||||||
shebang-command "^1.2.0"
|
shebang-command "^1.2.0"
|
||||||
which "^1.2.9"
|
which "^1.2.9"
|
||||||
|
|
||||||
crypt@~0.0.1:
|
|
||||||
version "0.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
|
||||||
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
|
|
||||||
|
|
||||||
crypto-browserify@^3.11.0:
|
crypto-browserify@^3.11.0:
|
||||||
version "3.12.0"
|
version "3.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
|
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
|
||||||
|
@ -3583,7 +3581,7 @@ is-binary-path@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions "^1.0.0"
|
binary-extensions "^1.0.0"
|
||||||
|
|
||||||
is-buffer@^1.1.5, is-buffer@~1.1.1:
|
is-buffer@^1.1.5:
|
||||||
version "1.1.6"
|
version "1.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||||
|
@ -4241,15 +4239,6 @@ md5.js@^1.3.4:
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
safe-buffer "^5.1.2"
|
safe-buffer "^5.1.2"
|
||||||
|
|
||||||
md5@^2.2.1:
|
|
||||||
version "2.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
|
|
||||||
integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=
|
|
||||||
dependencies:
|
|
||||||
charenc "~0.0.1"
|
|
||||||
crypt "~0.0.1"
|
|
||||||
is-buffer "~1.1.1"
|
|
||||||
|
|
||||||
mdn-data@~1.1.0:
|
mdn-data@~1.1.0:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
|
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
|
||||||
|
@ -4526,6 +4515,11 @@ mute-stream@0.0.7:
|
||||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||||
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
|
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
|
||||||
|
|
||||||
|
nan@2.12.1:
|
||||||
|
version "2.12.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
|
||||||
|
integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
|
||||||
|
|
||||||
nan@^2.9.2:
|
nan@^2.9.2:
|
||||||
version "2.11.1"
|
version "2.11.1"
|
||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
|
||||||
|
@ -4628,6 +4622,22 @@ node-libs-browser@^2.0.0:
|
||||||
util "^0.10.3"
|
util "^0.10.3"
|
||||||
vm-browserify "0.0.4"
|
vm-browserify "0.0.4"
|
||||||
|
|
||||||
|
node-pre-gyp@0.12.0:
|
||||||
|
version "0.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149"
|
||||||
|
integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==
|
||||||
|
dependencies:
|
||||||
|
detect-libc "^1.0.2"
|
||||||
|
mkdirp "^0.5.1"
|
||||||
|
needle "^2.2.1"
|
||||||
|
nopt "^4.0.1"
|
||||||
|
npm-packlist "^1.1.6"
|
||||||
|
npmlog "^4.0.2"
|
||||||
|
rc "^1.2.7"
|
||||||
|
rimraf "^2.6.1"
|
||||||
|
semver "^5.3.0"
|
||||||
|
tar "^4"
|
||||||
|
|
||||||
node-pre-gyp@^0.10.0:
|
node-pre-gyp@^0.10.0:
|
||||||
version "0.10.3"
|
version "0.10.3"
|
||||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc"
|
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue