diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..3c3629e6 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..01955442 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,28 @@ +module.exports = { + "env": { + "es6": true + }, + "settings": { + "polyfills": [ + ] + }, + "extends": ["ash-nazg/sauron", "plugin:node/recommended-script"], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "import/no-commonjs": 0, + "import/unambiguous": 0, + "object-curly-spacing": ["error", "always"], + "no-console": 0, + "compat/compat": 0, + + // Reenable later as possible + "promise/prefer-await-to-callbacks": 0 + } +}; diff --git a/app.js b/app.js index de3da1e8..8f909475 100644 --- a/app.js +++ b/app.js @@ -1,54 +1,95 @@ /** - * Node.js Login Boilerplate - * More Info : https://github.com/braitsch/node-login - * Copyright (c) 2013-2018 Stephen Braitsch + * Node.js Login Boilerplate + * More Info : https://github.com/braitsch/node-login + * Copyright (c) 2013-2018 Stephen Braitsch **/ -var http = require('http'); -var express = require('express'); -var session = require('express-session'); -var bodyParser = require('body-parser'); -var cookieParser = require('cookie-parser'); -var MongoStore = require('connect-mongo')(session); +const http = require('http'); +const { join } = require('path'); +const express = require('express'); +const session = require('express-session'); +const bodyParser = require('body-parser'); +const cookieParser = require('cookie-parser'); +const MongoStore = require('connect-mongo')(session); +const stylus = require('stylus'); +const commandLineArgs = require('command-line-args'); -var app = express(); +const app = express(); + +const optionDefinitions = [ + { name: 'NL_EMAIL_HOST', type: String }, + { name: 'NL_EMAIL_USER', type: String }, + { name: 'NL_EMAIL_PASS', type: String }, + { name: 'NL_EMAIL_FROM', alias: 'f', type: String }, + { name: 'NL_SITE_URL', type: String }, + { name: 'countries', alias: 'c', type: String }, + { name: 'PORT', type: Number }, + { name: 'DB_NAME', alias: 'n', type: String }, + { name: 'DB_HOST', alias: 'h', type: String }, + { name: 'DB_PORT', alias: 'p', type: Number }, + { name: 'DB_USER', alias: 'u', type: String }, + { name: 'DB_PASS', alias: 'x', type: String } +]; +const options = commandLineArgs(optionDefinitions); + +const { + NL_EMAIL_HOST, + NL_EMAIL_USER, + NL_EMAIL_PASS, + NL_EMAIL_FROM, + NL_SITE_URL, + DB_NAME = 'node-login', + // eslint-disable-next-line global-require + countries = require('./app/server/modules/country-list'), + PORT = 3000, + DB_HOST = 'localhost', + DB_PORT = 27017, + DB_USER, + DB_PASS +} = options; app.locals.pretty = true; -app.set('port', process.env.PORT || 3000); -app.set('views', __dirname + '/app/server/views'); +app.set('port', PORT); +app.set('views', join(__dirname, '/app/server/views')); app.set('view engine', 'pug'); app.use(cookieParser()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); -app.use(require('stylus').middleware({ src: __dirname + '/app/public' })); -app.use(express.static(__dirname + '/app/public')); - -// build mongo database connection url // +app.use(stylus.middleware({ src: join(__dirname, '/app/public') })); +app.use(express.static(join(__dirname, '/app/public'))); -process.env.DB_HOST = process.env.DB_HOST || 'localhost' -process.env.DB_PORT = process.env.DB_PORT || 27017; -process.env.DB_NAME = process.env.DB_NAME || 'node-login'; - -if (app.get('env') != 'live'){ - process.env.DB_URL = 'mongodb://'+process.env.DB_HOST+':'+process.env.DB_PORT; -} else { -// prepend url with authentication credentials // - process.env.DB_URL = 'mongodb://'+process.env.DB_USER+':'+process.env.DB_PASS+'@'+process.env.DB_HOST+':'+process.env.DB_PORT; +let DB_URL; +// build mongo database connection url +if (app.get('env') !== 'live') { + DB_URL = `mongodb://${DB_HOST}:${DB_PORT}/${DB_NAME}`; +// prepend url with authentication credentials +} else { + DB_URL = `mongodb://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}`; } app.use(session({ - secret: 'faeb4453e5d14fe6f6d04637f78077c76c73d1b4', - proxy: true, - resave: true, - saveUninitialized: true, - store: new MongoStore({ url: process.env.DB_URL }) - }) -); - -require('./app/server/routes')(app); - -http.createServer(app).listen(app.get('port'), function(){ - console.log('Express server listening on port ' + app.get('port')); + secret: 'faeb4453e5d14fe6f6d04637f78077c76c73d1b4', + proxy: true, + resave: true, + saveUninitialized: true, + store: new MongoStore({ + url: DB_URL, + mongoOptions: { useUnifiedTopology: true, useNewUrlParser: true } + }) +})); + +require('./app/server/routes')(app, { + countries, + NL_EMAIL_HOST, + NL_EMAIL_USER, + NL_EMAIL_PASS, + NL_EMAIL_FROM, + NL_SITE_URL, + DB_URL, + DB_NAME }); +http.createServer(app).listen(app.get('port'), () => { + console.log('Express server listening on port ' + app.get('port')); +}); diff --git a/app/public/css/style.css b/app/public/css/style.css index 8a9112ed..d58600e2 100644 --- a/app/public/css/style.css +++ b/app/public/css/style.css @@ -26,9 +26,6 @@ h6 { font-weight: normal; text-shadow: -1px 1px 0 #fff; } -/* - login window -*/ #login { width: 380px; } @@ -103,9 +100,6 @@ h6 { #account-form-container .form-buttons>:not(:last-child) { margin-right: 0.5rem; } -/* - modal windows -*/ .modal .modal-dialog { width: 480px; } diff --git a/app/public/css/style.styl b/app/public/css/style.styl index 7fee1c9d..8d9502a0 100644 --- a/app/public/css/style.styl +++ b/app/public/css/style.styl @@ -1,158 +1,136 @@ raiseText() color grey - text-shadow -1px 1px 0 white - -moz-text-shadow -1px 1px 0 white - -webkit-text-shadow -1px 1px 0 white + text-shadow -1px 1px 0 white + -moz-text-shadow -1px 1px 0 white + -webkit-text-shadow -1px 1px 0 white -html{ +html height 100% -} -body{ +body margin 0 padding 0 height 100% - background-image: radial-gradient(circle, #f2f9fe, #ebf7fe, #e5f4fe, #ddf2fe, #d6f0fd); -} + background-image radial-gradient(circle, #f2f9fe, #ebf7fe, #e5f4fe, #ddf2fe, #d6f0fd) -h2{ - margin: 0 0 6px 0; - font-weight: bold; -} +h2 + margin 0 0 6px 0 + font-weight bold -hr{ +hr margin 14px 0 - border-top: 1px solid rgb(238, 238, 238); - border-bottom: 1px solid rgb(255, 255, 255); -} - -ul{ - margin: 4px 0 0 0; -} - -label, h6 { - color: #808080; - font-size: 13px; - font-weight: normal; - text-shadow: -1px 1px 0 #fff; -} - -/* - login window -*/ - -#login{ - width: 380px; - .btn{ - float: left; - width: 48%; - font-size: .8rem; - } - .btn-btm{ - padding: 0; - } - .btn-left{ - margin-right: 4%; - } - #btn_sign_in{ - color: white; - } - #btn_remember{ - background: white; - border: 1px solid #ced4da; - } - #btn_remember:hover{ - background: #F8F9FA; - } - h6, label{ - font-size: .8rem; - } - h6, label, #btn_remember{ - color: #808080; - text-shadow: -1px 1px 0 #fff; - } - .fa{ - padding-right: 10px; - } - hr{ - clear: left; - } - .btm-links{ - font-size: .8rem; + border-top 1px solid rgb(238, 238, 238) + border-bottom 1px solid rgb(255, 255, 255) + +ul + margin 4px 0 0 0 + +label, h6 + color #808080 + font-size 13px + font-weight normal + text-shadow -1px 1px 0 #fff + +// login window + +#login + width 380px + .btn + float left + width 48% + font-size .8rem + + .btn-btm + padding 0 + + .btn-left + margin-right 4% + + #btn_sign_in + color white + + #btn_remember + background white + border 1px solid #ced4da + + #btn_remember:hover + background #F8F9FA + + h6, label + font-size .8rem + + h6, label, #btn_remember + color #808080 + text-shadow -1px 1px 0 #fff + + .fa + padding-right 10px + + hr + clear left + + .btm-links + font-size .8rem margin 2px 0 0 0 - #forgot-password{ + #forgot-password float left - margin-left 16px; - } - #create-account{ + margin-left 16px + + #create-account float right - margin-right 20px; - } - } -} - -#account-form-container{ - label{ - text-align right; - margin-top 2px; - } - input, select{ - font-size: .875rem; - } - .col-sm-9{ - padding-left 0; - } - .margin-zero{ - margin-bottom 0; - } - .form-buttons{ - display flex; - align-items center; - justify-content flex-end; - } + margin-right 20px + +#account-form-container + label + text-align right + margin-top 2px + + input, select + font-size .875rem + + .col-sm-9 + padding-left 0 + + .margin-zero + margin-bottom 0 + + .form-buttons + display flex + align-items center + justify-content flex-end + .form-buttons>:not(:last-child) - { - margin-right: .5rem; - } -} - -/* - modal windows -*/ - -.modal{ - .modal-dialog{ - width:480px; - } - .form-group{ - margin-bottom: 0px; - } - .alert{ - margin-top 10px; - margin-bottom: 0 + margin-right .5rem; + +// modal windows + +.modal + .modal-dialog + width 480px + + .form-group + margin-bottom 0px + + .alert + margin-top 10px + margin-bottom 0 padding 8px 15px 8px 15px - } - .alert-dismissable, .close{ - right -4px; - } - p{ - margin:0; - padding:0; - } - .modal-footer{ - button{ - width:80px; - } - } -} - -.center-vertical{ - top 50%; left 50% - position: absolute; - -webkit-transform: translate(-50%, -50%); - -ms-transform: translate(-50%, -50%); - transform: translate(-50%, -50%); -} + .alert-dismissable, .close + right -4px + p + margin 0 + padding 0 + + .modal-footer + button + width 80px + +.center-vertical + top 50%; left 50% + position absolute + -webkit-transform translate(-50%, -50%) + -ms-transform translate(-50%, -50%) + transform translate(-50%, -50%) diff --git a/app/public/js/controllers/homeController.js b/app/public/js/controllers/homeController.js index 90255a8d..2628fbe1 100644 --- a/app/public/js/controllers/homeController.js +++ b/app/public/js/controllers/homeController.js @@ -1,65 +1,72 @@ +/* global $ */ +window.HomeController = class HomeController { + constructor () { + // handle user logout + $('#btn-logout').click(() => { this.attemptLogout(); }); -function HomeController() -{ -// bind event listeners to button clicks // - var that = this; + // confirm account deletion + $('#account-form-btn1').click(() => { + $('.modal-confirm').modal('show'); + }); -// handle user logout // - $('#btn-logout').click(function(){ that.attemptLogout(); }); + // handle account deletion + $('.modal-confirm .submit').click(() => { + this.deleteAccount(); + }); -// confirm account deletion // - $('#account-form-btn1').click(function(){$('.modal-confirm').modal('show')}); + this.deleteAccount = () => { + $('.modal-confirm').modal('hide'); + $.ajax({ + url: '/delete', + type: 'POST', + success (data) { + this.showLockedAlert( + 'Your account has been deleted.
' + + 'Redirecting you back to the homepage.' + ); + }, + error (jqXHR) { + console.log(jqXHR.responseText + ' :: ' + jqXHR.statusText); + } + }); + }; -// handle account deletion // - $('.modal-confirm .submit').click(function(){ that.deleteAccount(); }); + this.attemptLogout = function () { + $.ajax({ + url: '/logout', + type: 'POST', + data: { logout: true }, + success: (data) => { + this.showLockedAlert( + 'You are now logged out.
Redirecting you back to the homepage.' + ); + }, + error (jqXHR) { + console.log(jqXHR.responseText + ' :: ' + jqXHR.statusText); + } + }); + }; - this.deleteAccount = function() - { - $('.modal-confirm').modal('hide'); - var that = this; - $.ajax({ - url: '/delete', - type: 'POST', - success: function(data){ - that.showLockedAlert('Your account has been deleted.
Redirecting you back to the homepage.'); - }, - error: function(jqXHR){ - console.log(jqXHR.responseText+' :: '+jqXHR.statusText); - } - }); - } + this.showLockedAlert = function (msg) { + $('.modal-alert').modal({ + show: false, keyboard: false, backdrop: 'static' + }); + $('.modal-alert .modal-header h4').text('Success!'); + $('.modal-alert .modal-body p').html(msg); + $('.modal-alert').modal('show'); + $('.modal-alert button').click(() => { + window.location.href = '/'; + }); + setTimeout(() => { window.location.href = '/'; }, 3000); + }; + } - this.attemptLogout = function() - { - var that = this; - $.ajax({ - url: '/logout', - type: 'POST', - data: {logout : true}, - success: function(data){ - that.showLockedAlert('You are now logged out.
Redirecting you back to the homepage.'); - }, - error: function(jqXHR){ - console.log(jqXHR.responseText+' :: '+jqXHR.statusText); - } - }); - } - - this.showLockedAlert = function(msg){ - $('.modal-alert').modal({ show : false, keyboard : false, backdrop : 'static' }); - $('.modal-alert .modal-header h4').text('Success!'); - $('.modal-alert .modal-body p').html(msg); - $('.modal-alert').modal('show'); - $('.modal-alert button').click(function(){window.location.href = '/';}) - setTimeout(function(){window.location.href = '/';}, 3000); - } -} - -HomeController.prototype.onUpdateSuccess = function() -{ - $('.modal-alert').modal({ show : false, keyboard : true, backdrop : true }); - $('.modal-alert .modal-header h4').text('Success!'); - $('.modal-alert .modal-body p').html('Your account has been updated.'); - $('.modal-alert').modal('show'); - $('.modal-alert button').off('click'); -} + // eslint-disable-next-line class-methods-use-this + onUpdateSuccess () { + $('.modal-alert').modal({ show: false, keyboard: true, backdrop: true }); + $('.modal-alert .modal-header h4').text('Success!'); + $('.modal-alert .modal-body p').html('Your account has been updated.'); + $('.modal-alert').modal('show'); + $('.modal-alert button').off('click'); + } +}; diff --git a/app/public/js/controllers/loginController.js b/app/public/js/controllers/loginController.js index dc3b2f24..6327c013 100644 --- a/app/public/js/controllers/loginController.js +++ b/app/public/js/controllers/loginController.js @@ -1,25 +1,31 @@ +/* global $ */ +window.LoginController = function LoginController () { + // bind event listeners to button clicks + $('#retrieve-password-submit').click(() => { + $('#get-credentials-form').submit(); + }); + $('#login #forgot-password').click(() => { + $('#cancel').html('Cancel'); + $('#retrieve-password-submit').show(); + $('#get-credentials').modal('show'); + }); + $('#login .button-rememember-me').click(function (e) { + const span = $(this).find('span'); + if (span.hasClass('glyphicon-unchecked')) { + span.addClass('glyphicon-ok'); + span.removeClass('glyphicon-unchecked'); + } else { + span.removeClass('glyphicon-ok'); + span.addClass('glyphicon-unchecked'); + } + }); -function LoginController() -{ -// bind event listeners to button clicks // - $('#retrieve-password-submit').click(function(){ $('#get-credentials-form').submit();}); - $('#login #forgot-password').click(function(){ - $('#cancel').html('Cancel'); - $('#retrieve-password-submit').show(); - $('#get-credentials').modal('show'); - }); - $('#login .button-rememember-me').click(function(e) { - var span = $(this).find('span'); - if (span.hasClass('glyphicon-unchecked')){ - span.addClass('glyphicon-ok'); - span.removeClass('glyphicon-unchecked'); - } else{ - span.removeClass('glyphicon-ok'); - span.addClass('glyphicon-unchecked'); - } - }); - -// automatically toggle focus between the email modal window and the login form // - $('#get-credentials').on('shown.bs.modal', function(){ $('#email-tf').focus(); }); - $('#get-credentials').on('hidden.bs.modal', function(){ $('#user-tf').focus(); }); -} \ No newline at end of file + // automatically toggle focus between the email modal window and + // the login form + $('#get-credentials').on('shown.bs.modal', () => { + $('#email-tf').focus(); + }); + $('#get-credentials').on('hidden.bs.modal', () => { + $('#user-tf').focus(); + }); +}; diff --git a/app/public/js/controllers/signupController.js b/app/public/js/controllers/signupController.js index 97d20e6c..0a744b90 100644 --- a/app/public/js/controllers/signupController.js +++ b/app/public/js/controllers/signupController.js @@ -1,9 +1,15 @@ +/* global $ */ +window.SignupController = function SignupController () { + // redirect to homepage when cancel button is clicked + $('#account-form-btn1').click(() => { + window.location.href = '/'; + }); -function SignupController() -{ -// redirect to homepage when cancel button is clicked // - $('#account-form-btn1').click(function(){ window.location.href = '/';}); - -// redirect to homepage on new account creation, add short delay so user can read alert window // - $('.modal-alert #ok').click(function(){ setTimeout(function(){window.location.href = '/';}, 300)}); -} \ No newline at end of file + // redirect to homepage on new account creation, add short + // delay so user can read alert window + $('.modal-alert #ok').click(() => { + setTimeout(() => { + window.location.href = '/'; + }, 300); + }); +}; diff --git a/app/public/js/form-validators/accountValidator.js b/app/public/js/form-validators/accountValidator.js index 889afb05..df206e72 100644 --- a/app/public/js/form-validators/accountValidator.js +++ b/app/public/js/form-validators/accountValidator.js @@ -1,79 +1,84 @@ +/* global $ */ +window.AccountValidator = class AccountValidator { + constructor () { + // build array maps of the form inputs & control groups -function AccountValidator() -{ -// build array maps of the form inputs & control groups // + this.formFields = [ + $('#name-tf'), $('#email-tf'), $('#user-tf'), $('#pass-tf') + ]; + this.controlGroups = [ + $('#name-cg'), $('#email-cg'), $('#user-cg'), $('#pass-cg') + ]; - this.formFields = [$('#name-tf'), $('#email-tf'), $('#user-tf'), $('#pass-tf')]; - this.controlGroups = [$('#name-cg'), $('#email-cg'), $('#user-cg'), $('#pass-cg')]; - -// bind the form-error modal window to this controller to display any errors // - - this.alert = $('.modal-form-errors'); - this.alert.modal({ show : false, keyboard : true, backdrop : true}); - - this.validateName = function(s) - { - return s.length >= 3; - } - - this.validatePassword = function(s) - { - // if user is logged in and hasn't changed their password, return ok - if ($('#userId').val() && s===''){ - return true; - } else{ - return s.length >= 6; - } - } - - this.validateEmail = function(e) - { - var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - return re.test(e); - } - - this.showErrors = function(a) - { - $('.modal-form-errors .modal-body p').text('Please correct the following problems :'); - var ul = $('.modal-form-errors .modal-body ul'); - ul.empty(); - for (var i=0; i < a.length; i++) ul.append('
  • '+a[i]+'
  • '); - this.alert.modal('show'); - } + // bind the form-error modal window to this controller to display any errors -} + this.alert = $('.modal-form-errors'); + this.alert.modal({ show: false, keyboard: true, backdrop: true }); -AccountValidator.prototype.showInvalidEmail = function() -{ - this.controlGroups[1].addClass('error'); - this.showErrors(['That email address is already in use.']); -} + this.validateName = function (s) { + return s.length >= 3; + }; -AccountValidator.prototype.showInvalidUserName = function() -{ - this.controlGroups[2].addClass('error'); - this.showErrors(['That username is already in use.']); -} + this.validatePassword = function (s) { + // if user is logged in and hasn't changed their password, return ok + if ($('#userId').val() && s === '') { + return true; + } + return s.length >= 6; + }; -AccountValidator.prototype.validateForm = function() -{ - var e = []; - for (var i=0; i < this.controlGroups.length; i++) this.controlGroups[i].removeClass('error'); - if (this.validateName(this.formFields[0].val()) == false) { - this.controlGroups[0].addClass('error'); e.push('Please Enter Your Name'); - } - if (this.validateEmail(this.formFields[1].val()) == false) { - this.controlGroups[1].addClass('error'); e.push('Please Enter A Valid Email'); - } - if (this.validateName(this.formFields[2].val()) == false) { - this.controlGroups[2].addClass('error'); - e.push('Please Choose A Username'); - } - if (this.validatePassword(this.formFields[3].val()) == false) { - this.controlGroups[3].addClass('error'); - e.push('Password Should Be At Least 6 Characters'); - } - if (e.length) this.showErrors(e); - return e.length === 0; -} + this.validateEmail = function (e) { + // eslint-disable-next-line max-len + // eslint-disable-next-line unicorn/no-unsafe-regex, prefer-named-capture-group + const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/u; + return re.test(e); + }; + this.showErrors = function (a) { + $('.modal-form-errors .modal-body p').text( + 'Please correct the following problems :' + ); + const ul = $('.modal-form-errors .modal-body ul'); + ul.empty(); + a.forEach((li) => { + ul.append('
  • ' + li + '
  • '); + }); + this.alert.modal('show'); + }; + } + + showInvalidEmail () { + this.controlGroups[1].addClass('error'); + this.showErrors(['That email address is already in use.']); + } + + showInvalidUserName () { + this.controlGroups[2].addClass('error'); + this.showErrors(['That username is already in use.']); + } + + validateForm () { + const e = []; + this.controlGroups.forEach((controlGroup) => { + controlGroup.removeClass('error'); + }); + if (!this.validateName(this.formFields[0].val())) { + this.controlGroups[0].addClass('error'); + e.push('Please Enter Your Name'); + } + if (!this.validateEmail(this.formFields[1].val())) { + this.controlGroups[1].addClass('error'); + e.push('Please Enter A Valid Email'); + } + if (!this.validateName(this.formFields[2].val())) { + this.controlGroups[2].addClass('error'); + e.push('Please Choose A Username'); + } + if (!this.validatePassword(this.formFields[3].val())) { + this.controlGroups[3].addClass('error'); + e.push('Password Should Be At Least 6 Characters'); + } + if (e.length) this.showErrors(e); + return e.length === 0; + } +}; diff --git a/app/public/js/form-validators/emailValidator.js b/app/public/js/form-validators/emailValidator.js index 92a4af3c..01b30db9 100644 --- a/app/public/js/form-validators/emailValidator.js +++ b/app/public/js/form-validators/emailValidator.js @@ -1,35 +1,38 @@ +/* global $ */ +window.EmailValidator = class EmailValidator { + constructor () { + const modal = $('#get-credentials'); + const alrt = $('#get-credentials .alert'); -function EmailValidator() -{ - let modal = $('#get-credentials'); - let alert = $('#get-credentials .alert'); + this.modal = modal; + this.alert = alrt; + this.modal.on('show.bs.modal', () => { + $('#get-credentials-form').resetForm(); + alrt.hide(); + }); + } - this.modal = modal; - this.alert = alert; - this.modal.on('show.bs.modal', function(){ $('#get-credentials-form').resetForm(); alert.hide();}); -} + // eslint-disable-next-line class-methods-use-this + validateEmail (e) { + // eslint-disable-next-line max-len + // eslint-disable-next-line unicorn/no-unsafe-regex, prefer-named-capture-group + const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/u; + return re.test(e); + } -EmailValidator.prototype.validateEmail = function(e) -{ - var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - return re.test(e); -} + showEmailAlert (m) { + this.alert.attr('class', 'alert alert-danger'); + this.alert.html(m); + this.alert.show(); + } -EmailValidator.prototype.showEmailAlert = function(m) -{ - this.alert.attr('class', 'alert alert-danger'); - this.alert.html(m); - this.alert.show(); -} + hideEmailAlert () { + this.alert.hide(); + } -EmailValidator.prototype.hideEmailAlert = function() -{ - this.alert.hide(); -} - -EmailValidator.prototype.showEmailSuccess = function(m) -{ - this.alert.attr('class', 'alert alert-success'); - this.alert.html(m); - this.alert.fadeIn(500); -} \ No newline at end of file + showEmailSuccess (m) { + this.alert.attr('class', 'alert alert-success'); + this.alert.html(m); + this.alert.fadeIn(500); + } +}; diff --git a/app/public/js/form-validators/loginValidator.js b/app/public/js/form-validators/loginValidator.js index 03b347da..c8e27497 100644 --- a/app/public/js/form-validators/loginValidator.js +++ b/app/public/js/form-validators/loginValidator.js @@ -1,26 +1,25 @@ +/* global $ */ +window.LoginValidator = class LoginValidator { + constructor () { + // bind a simple alert window to this controller to display any errors + this.loginErrors = $('.modal-alert'); -function LoginValidator() -{ -// bind a simple alert window to this controller to display any errors // - this.loginErrors = $('.modal-alert'); - - this.showLoginError = function(t, m) - { - $('.modal-alert .modal-header h4').text(t); - $('.modal-alert .modal-body').html(m); - this.loginErrors.modal('show'); - } -} + this.showLoginError = function (t, m) { + $('.modal-alert .modal-header h4').text(t); + $('.modal-alert .modal-body').html(m); + this.loginErrors.modal('show'); + }; + } -LoginValidator.prototype.validateForm = function() -{ - if ($('#user-tf').val() == ''){ - this.showLoginError('Whoops!', 'Please enter a valid username'); - return false; - } else if ($('#pass-tf').val() == ''){ - this.showLoginError('Whoops!', 'Please enter a valid password'); - return false; - } else{ - return true; - } -} \ No newline at end of file + validateForm () { + if ($('#user-tf').val() === '') { + this.showLoginError('Whoops!', 'Please enter a valid username'); + return false; + } + if ($('#pass-tf').val() === '') { + this.showLoginError('Whoops!', 'Please enter a valid password'); + return false; + } + return true; + } +}; diff --git a/app/public/js/form-validators/resetValidator.js b/app/public/js/form-validators/resetValidator.js index 7cb19dfb..d7caedec 100644 --- a/app/public/js/form-validators/resetValidator.js +++ b/app/public/js/form-validators/resetValidator.js @@ -1,37 +1,34 @@ +/* global $ */ -function ResetValidator() -{ - this.modal = $('#set-password'); - this.modal.modal({ show : false, keyboard : false, backdrop : 'static' }); - this.alert = $('#set-password .alert'); - this.alert.hide(); -} +window.ResetValidator = class ResetValidator { + constructor () { + this.modal = $('#set-password'); + this.modal.modal({ show: false, keyboard: false, backdrop: 'static' }); + this.alert = $('#set-password .alert'); + this.alert.hide(); + } -ResetValidator.prototype.validatePassword = function(s) -{ - if (s.length >= 6){ - return true; - } else{ - this.showAlert('Password Should Be At Least 6 Characters'); - return false; - } -} + validatePassword (s) { + if (s.length >= 6) { + return true; + } + this.showAlert('Password Should Be At Least 6 Characters'); + return false; + } -ResetValidator.prototype.showAlert = function(m) -{ - this.alert.attr('class', 'alert alert-danger'); - this.alert.html(m); - this.alert.show(); -} + showAlert (m) { + this.alert.attr('class', 'alert alert-danger'); + this.alert.html(m); + this.alert.show(); + } -ResetValidator.prototype.hideAlert = function() -{ - this.alert.hide(); -} + hideAlert () { + this.alert.hide(); + } -ResetValidator.prototype.showSuccess = function(m) -{ - this.alert.attr('class', 'alert alert-success'); - this.alert.html(m); - this.alert.fadeIn(500); -} \ No newline at end of file + showSuccess (m) { + this.alert.attr('class', 'alert alert-success'); + this.alert.html(m); + this.alert.fadeIn(500); + } +}; diff --git a/app/public/js/views/home.js b/app/public/js/views/home.js index 04f25221..0e4e7b06 100644 --- a/app/public/js/views/home.js +++ b/app/public/js/views/home.js @@ -1,49 +1,49 @@ +/* global $, HomeController, AccountValidator */ +$(document).ready(function () { + const hc = new HomeController(); + const av = new AccountValidator(); -$(document).ready(function(){ + $('#account-form').ajaxForm({ + beforeSubmit (formData, jqForm, options) { + if (!av.validateForm()) { + return false; + } + // push the disabled username field onto the form data array + formData.push({ name: 'user', value: $('#user-tf').val() }); + return true; + }, + success (responseText, status, xhr, $form) { + if (status === 'success') hc.onUpdateSuccess(); + }, + error (e) { + if (e.responseText === 'email-taken') { + av.showInvalidEmail(); + } else if (e.responseText === 'username-taken') { + av.showInvalidUserName(); + } + } + }); + $('#name-tf').focus(); - var hc = new HomeController(); - var av = new AccountValidator(); - - $('#account-form').ajaxForm({ - beforeSubmit : function(formData, jqForm, options){ - if (av.validateForm() == false){ - return false; - } else{ - // push the disabled username field onto the form data array // - formData.push({name:'user', value:$('#user-tf').val()}) - return true; - } - }, - success : function(responseText, status, xhr, $form){ - if (status == 'success') hc.onUpdateSuccess(); - }, - error : function(e){ - if (e.responseText == 'email-taken'){ - av.showInvalidEmail(); - } else if (e.responseText == 'username-taken'){ - av.showInvalidUserName(); - } - } - }); - $('#name-tf').focus(); + // customize the account settings form + $('#account-form h2').text('Account Settings'); + $('#account-form #sub').text( + 'Here are the current settings for your account.' + ); + $('#user-tf').attr('disabled', 'disabled'); + $('#account-form-btn1').html('Delete'); + $('#account-form-btn1').removeClass('btn-outline-dark'); + $('#account-form-btn1').addClass('btn-danger'); + $('#account-form-btn2').html('Update'); -// customize the account settings form // - - $('#account-form h2').text('Account Settings'); - $('#account-form #sub').text('Here are the current settings for your account.'); - $('#user-tf').attr('disabled', 'disabled'); - $('#account-form-btn1').html('Delete'); - $('#account-form-btn1').removeClass('btn-outline-dark'); - $('#account-form-btn1').addClass('btn-danger'); - $('#account-form-btn2').html('Update'); - -// setup the confirm window that displays when the user chooses to delete their account // - - $('.modal-confirm').modal({ show : false, keyboard : true, backdrop : true }); - $('.modal-confirm .modal-header h4').text('Delete Account'); - $('.modal-confirm .modal-body p').html('Are you sure you want to delete your account?'); - $('.modal-confirm .cancel').html('Cancel'); - $('.modal-confirm .submit').html('Delete'); - $('.modal-confirm .submit').addClass('btn-danger'); - -}); \ No newline at end of file + // setup the confirm window that displays when the user chooses to + // delete their account + $('.modal-confirm').modal({ show: false, keyboard: true, backdrop: true }); + $('.modal-confirm .modal-header h4').text('Delete Account'); + $('.modal-confirm .modal-body p').html( + 'Are you sure you want to delete your account?' + ); + $('.modal-confirm .cancel').html('Cancel'); + $('.modal-confirm .submit').html('Delete'); + $('.modal-confirm .submit').addClass('btn-danger'); +}); diff --git a/app/public/js/views/login.js b/app/public/js/views/login.js index f67dccc6..5d4b363c 100644 --- a/app/public/js/views/login.js +++ b/app/public/js/views/login.js @@ -1,70 +1,74 @@ +/* global $, LoginValidator, LoginController, EmailValidator */ -$(document).ready(function(){ +$(document).ready(function () { + const lv = new LoginValidator(); + /* const lc = */ new LoginController(); // eslint-disable-line no-new - var lv = new LoginValidator(); - var lc = new LoginController(); + // main login form + $('#login').ajaxForm({ + beforeSubmit (formData, jqForm, options) { + if (!lv.validateForm()) { + return false; + } + // append 'remember-me' option to formData to write local cookie + formData.push({ + name: 'remember-me', + value: $('#btn_remember').find('span').hasClass('fa-check-square') + }); + return true; + }, + success (responseText, status, xhr, $form) { + if (status === 'success') window.location.href = '/home'; + }, + error (e) { + lv.showLoginError( + 'Login Failure', 'Please check your username and/or password' + ); + } + }); -// main login form // + $('input:text:visible:first').focus(); + $('#btn_remember').click(function () { + const span = $(this).find('span'); + if (span.hasClass('fa-minus-square')) { + span.removeClass('fa-minus-square'); + span.addClass('fa-check-square'); + } else { + span.addClass('fa-minus-square'); + span.removeClass('fa-check-square'); + } + }); - $('#login').ajaxForm({ - beforeSubmit : function(formData, jqForm, options){ - if (lv.validateForm() == false){ - return false; - } else{ - // append 'remember-me' option to formData to write local cookie // - formData.push({name:'remember-me', value:$('#btn_remember').find('span').hasClass('fa-check-square')}); - return true; - } - }, - success : function(responseText, status, xhr, $form){ - if (status == 'success') window.location.href = '/home'; - }, - error : function(e){ - lv.showLoginError('Login Failure', 'Please check your username and/or password'); - } - }); + // login retrieval form via email + const ev = new EmailValidator(); - $("input:text:visible:first").focus(); - $('#btn_remember').click(function(){ - var span = $(this).find('span'); - if (span.hasClass('fa-minus-square')){ - span.removeClass('fa-minus-square'); - span.addClass('fa-check-square'); - } else{ - span.addClass('fa-minus-square'); - span.removeClass('fa-check-square'); - } - }); - -// login retrieval form via email // - - var ev = new EmailValidator(); - - $('#get-credentials-form').ajaxForm({ - url: '/lost-password', - beforeSubmit : function(formData, jqForm, options){ - if (ev.validateEmail($('#email-tf').val())){ - ev.hideEmailAlert(); - return true; - } else{ - ev.showEmailAlert("Please enter a valid email address"); - return false; - } - }, - success : function(responseText, status, xhr, $form){ - $('#cancel').html('OK'); - $('#retrieve-password-submit').hide(); - ev.showEmailSuccess("A link to reset your password was emailed to you."); - }, - error : function(e){ - if (e.responseText == 'email-not-found'){ - ev.showEmailAlert("Email not found. Are you sure you entered it correctly?"); - } else{ - $('#cancel').html('OK'); - $('#retrieve-password-submit').hide(); - ev.showEmailAlert("Sorry. There was a problem, please try again later."); - } - } - }); - + $('#get-credentials-form').ajaxForm({ + url: '/lost-password', + beforeSubmit (formData, jqForm, options) { + if (ev.validateEmail($('#email-tf').val())) { + ev.hideEmailAlert(); + return true; + } + ev.showEmailAlert('Please enter a valid email address'); + return false; + }, + success (responseText, status, xhr, $form) { + $('#cancel').html('OK'); + $('#retrieve-password-submit').hide(); + ev.showEmailSuccess('A link to reset your password was emailed to you.'); + }, + error (e) { + if (e.responseText === 'email-not-found') { + ev.showEmailAlert( + 'Email not found. Are you sure you entered it correctly?' + ); + } else { + $('#cancel').html('OK'); + $('#retrieve-password-submit').hide(); + ev.showEmailAlert( + 'Sorry. There was a problem, please try again later.' + ); + } + } + }); }); diff --git a/app/public/js/views/reset.js b/app/public/js/views/reset.js index 1673ed33..3a738f97 100644 --- a/app/public/js/views/reset.js +++ b/app/public/js/views/reset.js @@ -1,29 +1,23 @@ +/* global $, ResetValidator */ +$(document).ready(function () { + const rv = new ResetValidator(); -$(document).ready(function(){ - - var rv = new ResetValidator(); - - $('#set-password-form').ajaxForm({ - beforeSubmit : function(formData, jqForm, options){; - rv.hideAlert(); - if (rv.validatePassword($('#pass-tf').val()) == false){ - return false; - } else{ - return true; - } - }, - success : function(responseText, status, xhr, $form){ - $('#set-password-submit').addClass('disabled'); - $('#set-password-submit').prop('disabled', true); - rv.showSuccess("Your password has been reset."); - setTimeout(function(){ window.location.href = '/'; }, 3000); - }, - error : function(){ - rv.showAlert("I'm sorry something went wrong, please try again."); - } - }); + $('#set-password-form').ajaxForm({ + beforeSubmit (formData, jqForm, options) { + rv.hideAlert(); + return rv.validatePassword($('#pass-tf').val()) !== false; + }, + success (responseText, status, xhr, $form) { + $('#set-password-submit').addClass('disabled'); + $('#set-password-submit').prop('disabled', true); + rv.showSuccess('Your password has been reset.'); + setTimeout(() => { window.location.href = '/'; }, 3000); + }, + error () { + rv.showAlert("I'm sorry something went wrong, please try again."); + } + }); - $('#set-password').modal('show'); - $('#set-password').on('shown', function(){ $('#pass-tf').focus(); }) - -}); \ No newline at end of file + $('#set-password').modal('show'); + $('#set-password').on('shown', () => { $('#pass-tf').focus(); }); +}); diff --git a/app/public/js/views/signup.js b/app/public/js/views/signup.js index 65a2b03b..de58e270 100644 --- a/app/public/js/views/signup.js +++ b/app/public/js/views/signup.js @@ -1,38 +1,36 @@ +/* global $, AccountValidator, SignupController */ +$(document).ready(function () { + const av = new AccountValidator(); + /* const sc = */ new SignupController(); // eslint-disable-line no-new -$(document).ready(function(){ - - var av = new AccountValidator(); - var sc = new SignupController(); - - $('#account-form').ajaxForm({ - beforeSubmit : function(formData, jqForm, options){ - return av.validateForm(); - }, - success : function(responseText, status, xhr, $form){ - if (status == 'success') $('.modal-alert').modal('show'); - }, - error : function(e){ - if (e.responseText == 'email-taken'){ - av.showInvalidEmail(); - } else if (e.responseText == 'username-taken'){ - av.showInvalidUserName(); - } - } - }); - $('#name-tf').focus(); - -// customize the account signup form // - - $('#account-form h2').text('Signup'); - $('#account-form #sub').text('Please tell us a little about yourself'); - $('#account-form-btn1').html('Cancel'); - $('#account-form-btn2').html('Submit'); - $('#account-form-btn2').addClass('btn-primary'); - -// setup the alert that displays when an account is successfully created // + $('#account-form').ajaxForm({ + beforeSubmit (formData, jqForm, options) { + return av.validateForm(); + }, + success (responseText, status, xhr, $form) { + if (status === 'success') $('.modal-alert').modal('show'); + }, + error (e) { + if (e.responseText === 'email-taken') { + av.showInvalidEmail(); + } else if (e.responseText === 'username-taken') { + av.showInvalidUserName(); + } + } + }); + $('#name-tf').focus(); - $('.modal-alert').modal({ show:false, keyboard : false, backdrop : 'static' }); - $('.modal-alert .modal-header h4').text('Account Created!'); - $('.modal-alert .modal-body p').html('Your account has been created.
    Click OK to return to the login page.'); + // customize the account signup form + $('#account-form h2').text('Signup'); + $('#account-form #sub').text('Please tell us a little about yourself'); + $('#account-form-btn1').html('Cancel'); + $('#account-form-btn2').html('Submit'); + $('#account-form-btn2').addClass('btn-primary'); -}); \ No newline at end of file + // setup the alert that displays when an account is successfully created + $('.modal-alert').modal({ show: false, keyboard: false, backdrop: 'static' }); + $('.modal-alert .modal-header h4').text('Account Created!'); + $('.modal-alert .modal-body p').html( + 'Your account has been created.
    Click OK to return to the login page.' + ); +}); diff --git a/app/server/modules/account-manager.js b/app/server/modules/account-manager.js index 5f5a0016..c1de1c58 100644 --- a/app/server/modules/account-manager.js +++ b/app/server/modules/account-manager.js @@ -1,212 +1,266 @@ +/* eslint-disable callback-return, standard/no-callback-literal */ +/* eslint-disable-next-line no-shadow */ +const crypto = require('crypto'); +const moment = require('moment'); +const { MongoClient, ObjectID } = require('mongodb'); -const crypto = require('crypto'); -const moment = require('moment'); -const MongoClient = require('mongodb').MongoClient; - -var db, accounts; -MongoClient.connect(process.env.DB_URL, { useNewUrlParser: true }, function(e, client) { - if (e){ - console.log(e); - } else{ - db = client.db(process.env.DB_NAME); - accounts = db.collection('accounts'); - // index fields 'user' & 'email' for faster new account validation // - accounts.createIndex({user: 1, email: 1}); - console.log('mongo :: connected to database :: "'+process.env.DB_NAME+'"'); - } -}); - -const guid = function(){return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);});} +const PASS_VER = 1; + +const isNullish = (o) => o === null || o === undefined; + +const guid = function () { + /* eslint-disable no-bitwise */ + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/gu, (c) => { + const r = Math.random() * 16 | 0, + v = c === 'x' ? r : r & 0x3 | 0x8; + return v.toString(16); + }); + /* eslint-enable no-bitwise */ +}; /* - login validation methods + private encryption & validation methods */ -exports.autoLogin = function(user, pass, callback) -{ - accounts.findOne({user:user}, function(e, o) { - if (o){ - o.pass == pass ? callback(o) : callback(null); - } else{ - callback(null); - } - }); -} +const md5 = function (str) { + return crypto.createHash('md5').update(str).digest('hex'); +}; -exports.manualLogin = function(user, pass, callback) -{ - accounts.findOne({user:user}, function(e, o) { - if (o == null){ - callback('user-not-found'); - } else{ - validatePassword(pass, o.pass, function(err, res) { - if (res){ - callback(null, o); - } else{ - callback('invalid-password'); - } - }); - } - }); -} +const saltAndHash = function (pass, callback) { + const hasher = 'sha256'; + const iterations = 10000; + const hashLength = 32; + const saltBytes = 16; + crypto.randomBytes(saltBytes, (err, buf) => { + if (err) throw err; + const salt = buf.toString('hex'); + crypto.pbkdf2(pass, salt, iterations, hashLength, hasher, (err, derivedKey) => { + if (err) throw err; + const hash = derivedKey.toString('hex'); + callback([salt, hash].join('$')); + }); + }); +}; -exports.generateLoginKey = function(user, ipAddress, callback) -{ - let cookie = guid(); - accounts.findOneAndUpdate({user:user}, {$set:{ - ip : ipAddress, - cookie : cookie - }}, {returnOriginal : false}, function(e, o){ - callback(cookie); - }); -} +const validatePasswordV0 = function (plainPass, hashedPass, callback) { + const salt = hashedPass.substr(0, 10); + const validHash = salt + md5(plainPass + salt); + callback(null, hashedPass === validHash); +}; -exports.validateLoginKey = function(cookie, ipAddress, callback) -{ -// ensure the cookie maps to the user's last recorded ip address // - accounts.findOne({cookie:cookie, ip:ipAddress}, callback); -} +const validatePasswordV1 = function (plainPass, hashedPass, callback) { + const hasher = 'sha256'; + const iterations = 10000; + const hashLength = 32; + const salt = hashedPass.split('$')[0]; + crypto.pbkdf2(plainPass, salt, iterations, hashLength, hasher, (err, derivedKey) => { + if (err) throw err; + const plainPassHash = derivedKey.toString('hex'); + const validHash = [salt, plainPassHash].join('$'); + callback(null, hashedPass === validHash); + }); +}; -exports.generatePasswordKey = function(email, ipAddress, callback) -{ - let passKey = guid(); - accounts.findOneAndUpdate({email:email}, {$set:{ - ip : ipAddress, - passKey : passKey - }, $unset:{cookie:''}}, {returnOriginal : false}, function(e, o){ - if (o.value != null){ - callback(null, o.value); - } else{ - callback(e || 'account not found'); - } - }); -} - -exports.validatePasswordKey = function(passKey, ipAddress, callback) -{ -// ensure the passKey maps to the user's last recorded ip address // - accounts.findOne({passKey:passKey, ip:ipAddress}, callback); -} +const getObjectId = function (id) { + return new ObjectID(id); +}; /* - record insertion, update & deletion methods +const listIndexes = function () { + accounts.indexes(null, (e, indexes) => { + // eslint-disable-next-line unicorn/no-for-loop + for (let i = 0; i < indexes.length; i++) { + console.log('index:', i, indexes[i]); + } + }); +}; */ -exports.addNewAccount = function(newData, callback) -{ - accounts.findOne({user:newData.user}, function(e, o) { - if (o){ - callback('username-taken'); - } else{ - accounts.findOne({email:newData.email}, function(e, o) { - if (o){ - callback('email-taken'); - } else{ - saltAndHash(newData.pass, function(hash){ - newData.pass = hash; - // append date stamp when record was created // - newData.date = moment().format('MMMM Do YYYY, h:mm:ss a'); - accounts.insertOne(newData, callback); - }); - } - }); - } - }); -} +class AccountManager { + constructor (config) { + const { + DB_URL, + DB_NAME + } = config; -exports.updateAccount = function(newData, callback) -{ - let findOneAndUpdate = function(data){ - var o = { - name : data.name, - email : data.email, - country : data.country - } - if (data.pass) o.pass = data.pass; - accounts.findOneAndUpdate({_id:getObjectId(data.id)}, {$set:o}, {returnOriginal : false}, callback); - } - if (newData.pass == ''){ - findOneAndUpdate(newData); - } else { - saltAndHash(newData.pass, function(hash){ - newData.pass = hash; - findOneAndUpdate(newData); - }); - } -} + MongoClient.connect(DB_URL, { + useUnifiedTopology: true, + useNewUrlParser: true + }, (e, client) => { + if (e) { + console.log(e); + } else { + this.db = client.db(DB_NAME); + this.accounts = this.db.collection('accounts'); + // index fields 'user' & 'email' for faster new account validation + this.accounts.createIndex({ user: 1, email: 1 }); + console.log( + 'mongo :: connected to database :: "' + DB_NAME + '"' + ); + } + }); + } -exports.updatePassword = function(passKey, newPass, callback) -{ - saltAndHash(newPass, function(hash){ - newPass = hash; - accounts.findOneAndUpdate({passKey:passKey}, {$set:{pass:newPass}, $unset:{passKey:''}}, {returnOriginal : false}, callback); - }); -} + /* + login validation methods + */ -/* - account lookup methods -*/ + autoLogin (user, pass, callback) { + this.accounts.findOne({ user }, (e, o) => { + if (o) { + o.pass === pass ? callback(o) : callback(null); + } else { + callback(null); + } + }); + } -exports.getAllRecords = function(callback) -{ - accounts.find().toArray( - function(e, res) { - if (e) callback(e) - else callback(null, res) - }); -} + manualLogin (user, pass, callback) { + this.accounts.findOne({ user }, (e, o) => { + if (isNullish(o)) { + callback('user-not-found'); + } else { + if (!o.pass_ver || o.pass_ver === 0) { + validatePasswordV0(pass, o.pass, (err, res) => { + if (err) { + callback(err.message); + } else if (res) { + callback(null, o); + } else { + callback('invalid-password'); + } + }); + } else if (o.pass_ver === 1) { + validatePasswordV1(pass, o.pass, (err, res) => { + if (err) { + callback(err.message); + } else if (res) { + callback(null, o); + } else { + callback('invalid-password'); + } + }); + } + } + }); + } -exports.deleteAccount = function(id, callback) -{ - accounts.deleteOne({_id: getObjectId(id)}, callback); -} + generateLoginKey (user, ipAddress, callback) { + const cookie = guid(); + this.accounts.findOneAndUpdate({ user }, { $set: { + ip: ipAddress, + cookie + } }, { returnOriginal: false }, (e, o) => { + callback(cookie); + }); + } -exports.deleteAllAccounts = function(callback) -{ - accounts.deleteMany({}, callback); -} + validateLoginKey (cookie, ipAddress, callback) { + // ensure the cookie maps to the user's last recorded ip address + this.accounts.findOne({ cookie, ip: ipAddress }, callback); + } -/* - private encryption & validation methods -*/ + generatePasswordKey (email, ipAddress, callback) { + const passKey = guid(); + this.accounts.findOneAndUpdate({ email }, { $set: { + ip: ipAddress, + passKey + }, $unset: { cookie: '' } }, { returnOriginal: false }, (e, o) => { + if (!isNullish(o.value)) { + callback(null, o.value); + } else { + callback(e || 'account not found'); + } + }); + } -var generateSalt = function() -{ - var set = '0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ'; - var salt = ''; - for (var i = 0; i < 10; i++) { - var p = Math.floor(Math.random() * set.length); - salt += set[p]; - } - return salt; -} + validatePasswordKey (passKey, ipAddress, callback) { + // ensure the passKey maps to the user's last recorded ip address + this.accounts.findOne({ passKey, ip: ipAddress }, callback); + } -var md5 = function(str) { - return crypto.createHash('md5').update(str).digest('hex'); -} + /* + record insertion, update & deletion methods + */ + addNewAccount (newData, callback) { + this.accounts.findOne({ user: newData.user }, (e, o) => { + if (o) { + callback('username-taken'); + } else { + this.accounts.findOne({ email: newData.email }, (_e, _o) => { + if (_o) { + callback('email-taken'); + } else { + saltAndHash(newData.pass, (hash) => { + newData.pass = hash; + newData.pass_ver = PASS_VER; + // append date stamp when record was created + newData.date = moment().format('MMMM Do YYYY, h:mm:ss a'); + this.accounts.insertOne(newData, callback); + }); + } + }); + } + }); + } -var saltAndHash = function(pass, callback) -{ - var salt = generateSalt(); - callback(salt + md5(pass + salt)); -} + updateAccount (newData, callback) { + const findOneAndUpdate = (data) => { + const o = { + name: data.name, + email: data.email, + country: data.country + }; + if (data.pass) { + o.pass = data.pass; + o.pass_ver = PASS_VER; + } + this.accounts.findOneAndUpdate( + { _id: getObjectId(data.id) }, + { $set: o }, + { upsert: true, returnOriginal: false }, + callback + ); + }; + if (newData.pass === '') { + findOneAndUpdate(newData); + } else { + saltAndHash(newData.pass, (hash) => { + newData.pass = hash; + findOneAndUpdate(newData); + }); + } + } -var validatePassword = function(plainPass, hashedPass, callback) -{ - var salt = hashedPass.substr(0, 10); - var validHash = salt + md5(plainPass + salt); - callback(null, hashedPass === validHash); -} + updatePassword (passKey, newPass, callback) { + saltAndHash(newPass, (hash) => { + newPass = hash; + this.accounts.findOneAndUpdate({ passKey }, { + $set: { pass: newPass, pass_ver: PASS_VER }, $unset: { passKey: '' } + }, { upsert: true, returnOriginal: false }, callback); + }); + } -var getObjectId = function(id) -{ - return new require('mongodb').ObjectID(id); -} + /* + account lookup methods + */ + + getAllRecords (callback) { + this.accounts.find().toArray( + (e, res) => { + if (e) callback(e); + else callback(null, res); + } + ); + } + + deleteAccount (id, callback) { + this.accounts.deleteOne({ _id: getObjectId(id) }, callback); + } -var listIndexes = function() -{ - accounts.indexes(null, function(e, indexes){ - for (var i = 0; i < indexes.length; i++) console.log('index:', i, indexes[i]); - }); + deleteAllAccounts (callback) { + this.accounts.deleteMany({}, callback); + } } +module.exports = AccountManager; diff --git a/app/server/modules/country-list.js b/app/server/modules/country-list.js index 3079655c..b6f5524b 100644 --- a/app/server/modules/country-list.js +++ b/app/server/modules/country-list.js @@ -1,244 +1,244 @@ - +/* eslint-disable quotes */ module.exports = [ - {short:" " , name:"Please select a country"}, - {short:"AF" , name:"Afghanistan"}, - {short:"AL" , name:"Albania"}, - {short:"DZ" , name:"Algeria"}, - {short:"AS" , name:"American Samoa"}, - {short:"AD" , name:"Andorra"}, - {short:"AO" , name:"Angola"}, - {short:"AI" , name:"Anguilla"}, - {short:"AQ" , name:"Antarctica"}, - {short:"AG" , name:"Antigua and Barbuda"}, - {short:"AR" , name:"Argentina"}, - {short:"AM" , name:"Armenia"}, - {short:"AW" , name:"Aruba"}, - {short:"AU" , name:"Australia"}, - {short:"AT" , name:"Austria"}, - {short:"AZ" , name:"Azerbaijan"}, - {short:"BS" , name:"Bahamas"}, - {short:"BH" , name:"Bahrain"}, - {short:"BD" , name:"Bangladesh"}, - {short:"BB" , name:"Barbados"}, - {short:"BY" , name:"Belarus"}, - {short:"BE" , name:"Belgium"}, - {short:"BZ" , name:"Belize"}, - {short:"BJ" , name:"Benin"}, - {short:"BM" , name:"Bermuda"}, - {short:"BT" , name:"Bhutan"}, - {short:"BO" , name:"Bolivia"}, - {short:"BA" , name:"Bosnia and Herzegowina"}, - {short:"BW" , name:"Botswana"}, - {short:"BV" , name:"Bouvet Island"}, - {short:"BR" , name:"Brazil"}, - {short:"IO" , name:"British Indian Ocean Territory"}, - {short:"BN" , name:"Brunei Darussalam"}, - {short:"BG" , name:"Bulgaria"}, - {short:"BF" , name:"Burkina Faso"}, - {short:"BI" , name:"Burundi"}, - {short:"KH" , name:"Cambodia"}, - {short:"CM" , name:"Cameroon"}, - {short:"CA" , name:"Canada"}, - {short:"CV" , name:"Cape Verde"}, - {short:"KY" , name:"Cayman Islands"}, - {short:"CF" , name:"Central African Republic"}, - {short:"TD" , name:"Chad"}, - {short:"CL" , name:"Chile"}, - {short:"CN" , name:"China"}, - {short:"CX" , name:"Christmas Island"}, - {short:"CC" , name:"Cocos (Keeling) Islands"}, - {short:"CO" , name:"Colombia"}, - {short:"KM" , name:"Comoros"}, - {short:"CG" , name:"Congo"}, - {short:"CD" , name:"Congo, the Democratic Republic of the"}, - {short:"CK" , name:"Cook Islands"}, - {short:"CR" , name:"Costa Rica"}, - {short:"CI" , name:"Cote d'Ivoire"}, - {short:"HR" , name:"Croatia (Hrvatska)"}, - {short:"CU" , name:"Cuba"}, - {short:"CY" , name:"Cyprus"}, - {short:"CZ" , name:"Czech Republic"}, - {short:"DK" , name:"Denmark"}, - {short:"DJ" , name:"Djibouti"}, - {short:"DM" , name:"Dominica"}, - {short:"DO" , name:"Dominican Republic"}, - {short:"TP" , name:"East Timor"}, - {short:"EC" , name:"Ecuador"}, - {short:"EG" , name:"Egypt"}, - {short:"SV" , name:"El Salvador"}, - {short:"GQ" , name:"Equatorial Guinea"}, - {short:"ER" , name:"Eritrea"}, - {short:"EE" , name:"Estonia"}, - {short:"ET" , name:"Ethiopia"}, - {short:"FK" , name:"Falkland Islands (Malvinas)"}, - {short:"FO" , name:"Faroe Islands"}, - {short:"FJ" , name:"Fiji"}, - {short:"FI" , name:"Finland"}, - {short:"FR" , name:"France"}, - {short:"FX" , name:"France, Metropolitan"}, - {short:"GF" , name:"French Guiana"}, - {short:"PF" , name:"French Polynesia"}, - {short:"TF" , name:"French Southern Territories"}, - {short:"GA" , name:"Gabon"}, - {short:"GM" , name:"Gambia"}, - {short:"GE" , name:"Georgia"}, - {short:"DE" , name:"Germany"}, - {short:"GH" , name:"Ghana"}, - {short:"GI" , name:"Gibraltar"}, - {short:"GR" , name:"Greece"}, - {short:"GL" , name:"Greenland"}, - {short:"GD" , name:"Grenada"}, - {short:"GP" , name:"Guadeloupe"}, - {short:"GU" , name:"Guam"}, - {short:"GT" , name:"Guatemala"}, - {short:"GN" , name:"Guinea"}, - {short:"GW" , name:"Guinea-Bissau"}, - {short:"GY" , name:"Guyana"}, - {short:"HT" , name:"Haiti"}, - {short:"HM" , name:"Heard and Mc Donald Islands"}, - {short:"VA" , name:"Holy See (Vatican City State)"}, - {short:"HN" , name:"Honduras"}, - {short:"HK" , name:"Hong Kong"}, - {short:"HU" , name:"Hungary"}, - {short:"IS" , name:"Iceland"}, - {short:"IN" , name:"India"}, - {short:"ID" , name:"Indonesia"}, - {short:"IR" , name:"Iran (Islamic Republic of)"}, - {short:"IQ" , name:"Iraq"}, - {short:"IE" , name:"Ireland"}, - {short:"IL" , name:"Israel"}, - {short:"IT" , name:"Italy"}, - {short:"JM" , name:"Jamaica"}, - {short:"JP" , name:"Japan"}, - {short:"JO" , name:"Jordan"}, - {short:"KZ" , name:"Kazakhstan"}, - {short:"KE" , name:"Kenya"}, - {short:"KI" , name:"Kiribati"}, - {short:"KP" , name:"Korea, Democratic People's Republic of"}, - {short:"KR" , name:"Korea, Republic of"}, - {short:"KW" , name:"Kuwait"}, - {short:"KG" , name:"Kyrgyzstan"}, - {short:"LA" , name:"Lao People's Democratic Republic"}, - {short:"LV" , name:"Latvia"}, - {short:"LB" , name:"Lebanon"}, - {short:"LS" , name:"Lesotho"}, - {short:"LR" , name:"Liberia"}, - {short:"LY" , name:"Libyan Arab Jamahiriya"}, - {short:"LI" , name:"Liechtenstein"}, - {short:"LT" , name:"Lithuania"}, - {short:"LU" , name:"Luxembourg"}, - {short:"MO" , name:"Macau"}, - {short:"MK" , name:"Macedonia, The Former Yugoslav Republic of"}, - {short:"MG" , name:"Madagascar"}, - {short:"MW" , name:"Malawi"}, - {short:"MY" , name:"Malaysia"}, - {short:"MV" , name:"Maldives"}, - {short:"ML" , name:"Mali"}, - {short:"MT" , name:"Malta"}, - {short:"MH" , name:"Marshall Islands"}, - {short:"MQ" , name:"Martinique"}, - {short:"MR" , name:"Mauritania"}, - {short:"MU" , name:"Mauritius"}, - {short:"YT" , name:"Mayotte"}, - {short:"MX" , name:"Mexico"}, - {short:"FM" , name:"Micronesia, Federated States of"}, - {short:"MD" , name:"Moldova, Republic of"}, - {short:"MC" , name:"Monaco"}, - {short:"MN" , name:"Mongolia"}, - {short:"MS" , name:"Montserrat"}, - {short:"MA" , name:"Morocco"}, - {short:"MZ" , name:"Mozambique"}, - {short:"MM" , name:"Myanmar"}, - {short:"NA" , name:"Namibia"}, - {short:"NR" , name:"Nauru"}, - {short:"NP" , name:"Nepal"}, - {short:"NL" , name:"Netherlands"}, - {short:"AN" , name:"Netherlands Antilles"}, - {short:"NC" , name:"New Caledonia"}, - {short:"NZ" , name:"New Zealand"}, - {short:"NI" , name:"Nicaragua"}, - {short:"NE" , name:"Niger"}, - {short:"NG" , name:"Nigeria"}, - {short:"NU" , name:"Niue"}, - {short:"NF" , name:"Norfolk Island"}, - {short:"MP" , name:"Northern Mariana Islands"}, - {short:"NO" , name:"Norway"}, - {short:"OM" , name:"Oman"}, - {short:"PK" , name:"Pakistan"}, - {short:"PW" , name:"Palau"}, - {short:"PA" , name:"Panama"}, - {short:"PG" , name:"Papua New Guinea"}, - {short:"PY" , name:"Paraguay"}, - {short:"PE" , name:"Peru"}, - {short:"PH" , name:"Philippines"}, - {short:"PN" , name:"Pitcairn"}, - {short:"PL" , name:"Poland"}, - {short:"PT" , name:"Portugal"}, - {short:"PR" , name:"Puerto Rico"}, - {short:"QA" , name:"Qatar"}, - {short:"RE" , name:"Reunion"}, - {short:"RO" , name:"Romania"}, - {short:"RU" , name:"Russian Federation"}, - {short:"RW" , name:"Rwanda"}, - {short:"KN" , name:"Saint Kitts and Nevis"}, - {short:"LC" , name:"Saint LUCIA"}, - {short:"VC" , name:"Saint Vincent and the Grenadines"}, - {short:"WS" , name:"Samoa"}, - {short:"SM" , name:"San Marino"}, - {short:"ST" , name:"Sao Tome and Principe"}, - {short:"SA" , name:"Saudi Arabia"}, - {short:"SN" , name:"Senegal"}, - {short:"SC" , name:"Seychelles"}, - {short:"SL" , name:"Sierra Leone"}, - {short:"SG" , name:"Singapore"}, - {short:"SK" , name:"Slovakia (Slovak Republic)"}, - {short:"SI" , name:"Slovenia"}, - {short:"SB" , name:"Solomon Islands"}, - {short:"SO" , name:"Somalia"}, - {short:"ZA" , name:"South Africa"}, - {short:"GS" , name:"South Georgia and the South Sandwich Islands"}, - {short:"SS" , name:"South Sudan"}, - {short:"ES" , name:"Spain"}, - {short:"LK" , name:"Sri Lanka"}, - {short:"SH" , name:"St. Helena"}, - {short:"PM" , name:"St. Pierre and Miquelon"}, - {short:"SD" , name:"Sudan"}, - {short:"SR" , name:"Suriname"}, - {short:"SJ" , name:"Svalbard and Jan Mayen Islands"}, - {short:"SZ" , name:"Swaziland"}, - {short:"SE" , name:"Sweden"}, - {short:"CH" , name:"Switzerland"}, - {short:"SY" , name:"Syrian Arab Republic"}, - {short:"TW" , name:"Taiwan, Province of China"}, - {short:"TJ" , name:"Tajikistan"}, - {short:"TZ" , name:"Tanzania, United Republic of"}, - {short:"TH" , name:"Thailand"}, - {short:"TG" , name:"Togo"}, - {short:"TK" , name:"Tokelau"}, - {short:"TO" , name:"Tonga"}, - {short:"TT" , name:"Trinidad and Tobago"}, - {short:"TN" , name:"Tunisia"}, - {short:"TR" , name:"Turkey"}, - {short:"TM" , name:"Turkmenistan"}, - {short:"TC" , name:"Turks and Caicos Islands"}, - {short:"TV" , name:"Tuvalu"}, - {short:"UG" , name:"Uganda"}, - {short:"UA" , name:"Ukraine"}, - {short:"AE" , name:"United Arab Emirates"}, - {short:"GB" , name:"United Kingdom"}, - {short:"US" , name:"United States"}, - {short:"UM" , name:"United States Minor Outlying Islands"}, - {short:"UY" , name:"Uruguay"}, - {short:"UZ" , name:"Uzbekistan"}, - {short:"VU" , name:"Vanuatu"}, - {short:"VE" , name:"Venezuela"}, - {short:"VN" , name:"Viet Nam"}, - {short:"VG" , name:"Virgin Islands (British)"}, - {short:"VI" , name:"Virgin Islands (U.S.)"}, - {short:"WF" , name:"Wallis and Futuna Islands"}, - {short:"EH" , name:"Western Sahara"}, - {short:"YE" , name:"Yemen"}, - {short:"YU" , name:"Yugoslavia"}, - {short:"ZM" , name:"Zambia"}, - {short:"ZW" , name:"Zimbabwe"} -] \ No newline at end of file + { short: " ", name: "Please select a country" }, + { short: "AF", name: "Afghanistan" }, + { short: "AL", name: "Albania" }, + { short: "DZ", name: "Algeria" }, + { short: "AS", name: "American Samoa" }, + { short: "AD", name: "Andorra" }, + { short: "AO", name: "Angola" }, + { short: "AI", name: "Anguilla" }, + { short: "AQ", name: "Antarctica" }, + { short: "AG", name: "Antigua and Barbuda" }, + { short: "AR", name: "Argentina" }, + { short: "AM", name: "Armenia" }, + { short: "AW", name: "Aruba" }, + { short: "AU", name: "Australia" }, + { short: "AT", name: "Austria" }, + { short: "AZ", name: "Azerbaijan" }, + { short: "BS", name: "Bahamas" }, + { short: "BH", name: "Bahrain" }, + { short: "BD", name: "Bangladesh" }, + { short: "BB", name: "Barbados" }, + { short: "BY", name: "Belarus" }, + { short: "BE", name: "Belgium" }, + { short: "BZ", name: "Belize" }, + { short: "BJ", name: "Benin" }, + { short: "BM", name: "Bermuda" }, + { short: "BT", name: "Bhutan" }, + { short: "BO", name: "Bolivia" }, + { short: "BA", name: "Bosnia and Herzegowina" }, + { short: "BW", name: "Botswana" }, + { short: "BV", name: "Bouvet Island" }, + { short: "BR", name: "Brazil" }, + { short: "IO", name: "British Indian Ocean Territory" }, + { short: "BN", name: "Brunei Darussalam" }, + { short: "BG", name: "Bulgaria" }, + { short: "BF", name: "Burkina Faso" }, + { short: "BI", name: "Burundi" }, + { short: "KH", name: "Cambodia" }, + { short: "CM", name: "Cameroon" }, + { short: "CA", name: "Canada" }, + { short: "CV", name: "Cape Verde" }, + { short: "KY", name: "Cayman Islands" }, + { short: "CF", name: "Central African Republic" }, + { short: "TD", name: "Chad" }, + { short: "CL", name: "Chile" }, + { short: "CN", name: "China" }, + { short: "CX", name: "Christmas Island" }, + { short: "CC", name: "Cocos (Keeling) Islands" }, + { short: "CO", name: "Colombia" }, + { short: "KM", name: "Comoros" }, + { short: "CG", name: "Congo" }, + { short: "CD", name: "Congo, the Democratic Republic of the" }, + { short: "CK", name: "Cook Islands" }, + { short: "CR", name: "Costa Rica" }, + { short: "CI", name: "Cote d'Ivoire" }, + { short: "HR", name: "Croatia (Hrvatska)" }, + { short: "CU", name: "Cuba" }, + { short: "CY", name: "Cyprus" }, + { short: "CZ", name: "Czech Republic" }, + { short: "DK", name: "Denmark" }, + { short: "DJ", name: "Djibouti" }, + { short: "DM", name: "Dominica" }, + { short: "DO", name: "Dominican Republic" }, + { short: "TP", name: "East Timor" }, + { short: "EC", name: "Ecuador" }, + { short: "EG", name: "Egypt" }, + { short: "SV", name: "El Salvador" }, + { short: "GQ", name: "Equatorial Guinea" }, + { short: "ER", name: "Eritrea" }, + { short: "EE", name: "Estonia" }, + { short: "ET", name: "Ethiopia" }, + { short: "FK", name: "Falkland Islands (Malvinas)" }, + { short: "FO", name: "Faroe Islands" }, + { short: "FJ", name: "Fiji" }, + { short: "FI", name: "Finland" }, + { short: "FR", name: "France" }, + { short: "FX", name: "France, Metropolitan" }, + { short: "GF", name: "French Guiana" }, + { short: "PF", name: "French Polynesia" }, + { short: "TF", name: "French Southern Territories" }, + { short: "GA", name: "Gabon" }, + { short: "GM", name: "Gambia" }, + { short: "GE", name: "Georgia" }, + { short: "DE", name: "Germany" }, + { short: "GH", name: "Ghana" }, + { short: "GI", name: "Gibraltar" }, + { short: "GR", name: "Greece" }, + { short: "GL", name: "Greenland" }, + { short: "GD", name: "Grenada" }, + { short: "GP", name: "Guadeloupe" }, + { short: "GU", name: "Guam" }, + { short: "GT", name: "Guatemala" }, + { short: "GN", name: "Guinea" }, + { short: "GW", name: "Guinea-Bissau" }, + { short: "GY", name: "Guyana" }, + { short: "HT", name: "Haiti" }, + { short: "HM", name: "Heard and Mc Donald Islands" }, + { short: "VA", name: "Holy See (Vatican City State)" }, + { short: "HN", name: "Honduras" }, + { short: "HK", name: "Hong Kong" }, + { short: "HU", name: "Hungary" }, + { short: "IS", name: "Iceland" }, + { short: "IN", name: "India" }, + { short: "ID", name: "Indonesia" }, + { short: "IR", name: "Iran (Islamic Republic of)" }, + { short: "IQ", name: "Iraq" }, + { short: "IE", name: "Ireland" }, + { short: "IL", name: "Israel" }, + { short: "IT", name: "Italy" }, + { short: "JM", name: "Jamaica" }, + { short: "JP", name: "Japan" }, + { short: "JO", name: "Jordan" }, + { short: "KZ", name: "Kazakhstan" }, + { short: "KE", name: "Kenya" }, + { short: "KI", name: "Kiribati" }, + { short: "KP", name: "Korea, Democratic People's Republic of" }, + { short: "KR", name: "Korea, Republic of" }, + { short: "KW", name: "Kuwait" }, + { short: "KG", name: "Kyrgyzstan" }, + { short: "LA", name: "Lao People's Democratic Republic" }, + { short: "LV", name: "Latvia" }, + { short: "LB", name: "Lebanon" }, + { short: "LS", name: "Lesotho" }, + { short: "LR", name: "Liberia" }, + { short: "LY", name: "Libyan Arab Jamahiriya" }, + { short: "LI", name: "Liechtenstein" }, + { short: "LT", name: "Lithuania" }, + { short: "LU", name: "Luxembourg" }, + { short: "MO", name: "Macau" }, + { short: "MK", name: "Macedonia, The Former Yugoslav Republic of" }, + { short: "MG", name: "Madagascar" }, + { short: "MW", name: "Malawi" }, + { short: "MY", name: "Malaysia" }, + { short: "MV", name: "Maldives" }, + { short: "ML", name: "Mali" }, + { short: "MT", name: "Malta" }, + { short: "MH", name: "Marshall Islands" }, + { short: "MQ", name: "Martinique" }, + { short: "MR", name: "Mauritania" }, + { short: "MU", name: "Mauritius" }, + { short: "YT", name: "Mayotte" }, + { short: "MX", name: "Mexico" }, + { short: "FM", name: "Micronesia, Federated States of" }, + { short: "MD", name: "Moldova, Republic of" }, + { short: "MC", name: "Monaco" }, + { short: "MN", name: "Mongolia" }, + { short: "MS", name: "Montserrat" }, + { short: "MA", name: "Morocco" }, + { short: "MZ", name: "Mozambique" }, + { short: "MM", name: "Myanmar" }, + { short: "NA", name: "Namibia" }, + { short: "NR", name: "Nauru" }, + { short: "NP", name: "Nepal" }, + { short: "NL", name: "Netherlands" }, + { short: "AN", name: "Netherlands Antilles" }, + { short: "NC", name: "New Caledonia" }, + { short: "NZ", name: "New Zealand" }, + { short: "NI", name: "Nicaragua" }, + { short: "NE", name: "Niger" }, + { short: "NG", name: "Nigeria" }, + { short: "NU", name: "Niue" }, + { short: "NF", name: "Norfolk Island" }, + { short: "MP", name: "Northern Mariana Islands" }, + { short: "NO", name: "Norway" }, + { short: "OM", name: "Oman" }, + { short: "PK", name: "Pakistan" }, + { short: "PW", name: "Palau" }, + { short: "PA", name: "Panama" }, + { short: "PG", name: "Papua New Guinea" }, + { short: "PY", name: "Paraguay" }, + { short: "PE", name: "Peru" }, + { short: "PH", name: "Philippines" }, + { short: "PN", name: "Pitcairn" }, + { short: "PL", name: "Poland" }, + { short: "PT", name: "Portugal" }, + { short: "PR", name: "Puerto Rico" }, + { short: "QA", name: "Qatar" }, + { short: "RE", name: "Reunion" }, + { short: "RO", name: "Romania" }, + { short: "RU", name: "Russian Federation" }, + { short: "RW", name: "Rwanda" }, + { short: "KN", name: "Saint Kitts and Nevis" }, + { short: "LC", name: "Saint LUCIA" }, + { short: "VC", name: "Saint Vincent and the Grenadines" }, + { short: "WS", name: "Samoa" }, + { short: "SM", name: "San Marino" }, + { short: "ST", name: "Sao Tome and Principe" }, + { short: "SA", name: "Saudi Arabia" }, + { short: "SN", name: "Senegal" }, + { short: "SC", name: "Seychelles" }, + { short: "SL", name: "Sierra Leone" }, + { short: "SG", name: "Singapore" }, + { short: "SK", name: "Slovakia (Slovak Republic)" }, + { short: "SI", name: "Slovenia" }, + { short: "SB", name: "Solomon Islands" }, + { short: "SO", name: "Somalia" }, + { short: "ZA", name: "South Africa" }, + { short: "GS", name: "South Georgia and the South Sandwich Islands" }, + { short: "SS", name: "South Sudan" }, + { short: "ES", name: "Spain" }, + { short: "LK", name: "Sri Lanka" }, + { short: "SH", name: "St. Helena" }, + { short: "PM", name: "St. Pierre and Miquelon" }, + { short: "SD", name: "Sudan" }, + { short: "SR", name: "Suriname" }, + { short: "SJ", name: "Svalbard and Jan Mayen Islands" }, + { short: "SZ", name: "Swaziland" }, + { short: "SE", name: "Sweden" }, + { short: "CH", name: "Switzerland" }, + { short: "SY", name: "Syrian Arab Republic" }, + { short: "TW", name: "Taiwan, Province of China" }, + { short: "TJ", name: "Tajikistan" }, + { short: "TZ", name: "Tanzania, United Republic of" }, + { short: "TH", name: "Thailand" }, + { short: "TG", name: "Togo" }, + { short: "TK", name: "Tokelau" }, + { short: "TO", name: "Tonga" }, + { short: "TT", name: "Trinidad and Tobago" }, + { short: "TN", name: "Tunisia" }, + { short: "TR", name: "Turkey" }, + { short: "TM", name: "Turkmenistan" }, + { short: "TC", name: "Turks and Caicos Islands" }, + { short: "TV", name: "Tuvalu" }, + { short: "UG", name: "Uganda" }, + { short: "UA", name: "Ukraine" }, + { short: "AE", name: "United Arab Emirates" }, + { short: "GB", name: "United Kingdom" }, + { short: "US", name: "United States" }, + { short: "UM", name: "United States Minor Outlying Islands" }, + { short: "UY", name: "Uruguay" }, + { short: "UZ", name: "Uzbekistan" }, + { short: "VU", name: "Vanuatu" }, + { short: "VE", name: "Venezuela" }, + { short: "VN", name: "Viet Nam" }, + { short: "VG", name: "Virgin Islands (British)" }, + { short: "VI", name: "Virgin Islands (U.S.)" }, + { short: "WF", name: "Wallis and Futuna Islands" }, + { short: "EH", name: "Western Sahara" }, + { short: "YE", name: "Yemen" }, + { short: "YU", name: "Yugoslavia" }, + { short: "ZM", name: "Zambia" }, + { short: "ZW", name: "Zimbabwe" } +]; diff --git a/app/server/modules/email-dispatcher.js b/app/server/modules/email-dispatcher.js index db27848b..488a971a 100644 --- a/app/server/modules/email-dispatcher.js +++ b/app/server/modules/email-dispatcher.js @@ -1,35 +1,50 @@ +const emailjs = require('emailjs/email'); -var EM = {}; -module.exports = EM; +class EmailDispatcher { + constructor (config) { + const { + NL_EMAIL_HOST = 'smtp.gmail.com', + NL_EMAIL_USER = 'your-email-address@gmail.com', + NL_EMAIL_PASS = '1234', + NL_EMAIL_FROM = 'Node Login ', + NL_SITE_URL = 'http://localhost:3000' + } = config; + Object.assign(this, { + NL_EMAIL_HOST, NL_EMAIL_USER, NL_EMAIL_PASS, + NL_EMAIL_FROM, NL_SITE_URL + }); -EM.server = require("emailjs/email").server.connect( -{ - host : process.env.NL_EMAIL_HOST || 'smtp.gmail.com', - user : process.env.NL_EMAIL_USER || 'your-email-address@gmail.com', - password : process.env.NL_EMAIL_PASS || '1234', - ssl : true -}); + this.server = emailjs.server.connect({ + host: NL_EMAIL_HOST, + user: NL_EMAIL_USER, + password: NL_EMAIL_PASS, + ssl: true + }); + } -EM.dispatchResetPasswordLink = function(account, callback) -{ - EM.server.send({ - from : process.env.NL_EMAIL_FROM || 'Node Login ', - to : account.email, - subject : 'Password Reset', - text : 'something went wrong... :(', - attachment : EM.composeEmail(account) - }, callback ); + dispatchResetPasswordLink (account, callback) { + this.server.send({ + from: this.NL_EMAIL_FROM, + to: account.email, + subject: 'Password Reset', + text: 'something went wrong... :(', + attachment: this.composeEmail(account) + }, callback); + } + + composeEmail (o) { + const baseurl = this.NL_SITE_URL; + const html = ` + Hi ${o.name},

    + Your username is ${o.user}

    + + Click here to reset your password +

    + Cheers,
    + braitsch

    + `; + return [{ data: html, alternative: true }]; + } } -EM.composeEmail = function(o) -{ - let baseurl = process.env.NL_SITE_URL || 'http://localhost:3000'; - var html = ""; - html += "Hi "+o.name+",

    "; - html += "Your username is "+o.user+"

    "; - html += "Click here to reset your password

    "; - html += "Cheers,
    "; - html += "braitsch

    "; - html += ""; - return [{data:html, alternative:true}]; -} \ No newline at end of file +module.exports = EmailDispatcher; diff --git a/app/server/routes.js b/app/server/routes.js index 8601d5d8..c91d289c 100644 --- a/app/server/routes.js +++ b/app/server/routes.js @@ -1,192 +1,222 @@ -var CT = require('./modules/country-list'); -var AM = require('./modules/account-manager'); -var EM = require('./modules/email-dispatcher'); - -module.exports = function(app) { - -/* - login & logout -*/ - - app.get('/', function(req, res){ - // check if the user has an auto login key saved in a cookie // - if (req.cookies.login == undefined){ - res.render('login', { title: 'Hello - Please Login To Your Account' }); - } else{ - // attempt automatic login // - AM.validateLoginKey(req.cookies.login, req.ip, function(e, o){ - if (o){ - AM.autoLogin(o.user, o.pass, function(o){ - req.session.user = o; - res.redirect('/home'); - }); - } else{ - res.render('login', { title: 'Hello - Please Login To Your Account' }); - } - }); - } - }); - - app.post('/', function(req, res){ - AM.manualLogin(req.body['user'], req.body['pass'], function(e, o){ - if (!o){ - res.status(400).send(e); - } else{ - req.session.user = o; - if (req.body['remember-me'] == 'false'){ - res.status(200).send(o); - } else{ - AM.generateLoginKey(o.user, req.ip, function(key){ - res.cookie('login', key, { maxAge: 900000 }); - res.status(200).send(o); - }); - } - } - }); - }); - - app.post('/logout', function(req, res){ - res.clearCookie('login'); - req.session.destroy(function(e){ res.status(200).send('ok'); }); - }) - -/* - control panel -*/ - - app.get('/home', function(req, res) { - if (req.session.user == null){ - res.redirect('/'); - } else{ - res.render('home', { - title : 'Control Panel', - countries : CT, - udata : req.session.user - }); - } - }); - - app.post('/home', function(req, res){ - if (req.session.user == null){ - res.redirect('/'); - } else{ - AM.updateAccount({ - id : req.session.user._id, - name : req.body['name'], - email : req.body['email'], - pass : req.body['pass'], - country : req.body['country'] - }, function(e, o){ - if (e){ - res.status(400).send('error-updating-account'); - } else{ - req.session.user = o.value; - res.status(200).send('ok'); - } - }); - } - }); - -/* - new accounts -*/ - - app.get('/signup', function(req, res) { - res.render('signup', { title: 'Signup', countries : CT }); - }); - - app.post('/signup', function(req, res){ - AM.addNewAccount({ - name : req.body['name'], - email : req.body['email'], - user : req.body['user'], - pass : req.body['pass'], - country : req.body['country'] - }, function(e){ - if (e){ - res.status(400).send(e); - } else{ - res.status(200).send('ok'); - } - }); - }); - -/* - password reset -*/ - - app.post('/lost-password', function(req, res){ - let email = req.body['email']; - AM.generatePasswordKey(email, req.ip, function(e, account){ - if (e){ - res.status(400).send(e); - } else{ - EM.dispatchResetPasswordLink(account, function(e, m){ - // TODO this callback takes a moment to return, add a loader to give user feedback // - if (!e){ - res.status(200).send('ok'); - } else{ - for (k in e) console.log('ERROR : ', k, e[k]); - res.status(400).send('unable to dispatch password reset'); - } - }); - } - }); - }); - - app.get('/reset-password', function(req, res) { - AM.validatePasswordKey(req.query['key'], req.ip, function(e, o){ - if (e || o == null){ - res.redirect('/'); - } else{ - req.session.passKey = req.query['key']; - res.render('reset', { title : 'Reset Password' }); - } - }) - }); - - app.post('/reset-password', function(req, res) { - let newPass = req.body['pass']; - let passKey = req.session.passKey; - // destory the session immediately after retrieving the stored passkey // - req.session.destroy(); - AM.updatePassword(passKey, newPass, function(e, o){ - if (o){ - res.status(200).send('ok'); - } else{ - res.status(400).send('unable to update password'); - } - }) - }); - -/* - view, delete & reset accounts -*/ - - app.get('/print', function(req, res) { - AM.getAllRecords( function(e, accounts){ - res.render('print', { title : 'Account List', accts : accounts }); - }) - }); - - app.post('/delete', function(req, res){ - AM.deleteAccount(req.session.user._id, function(e, obj){ - if (!e){ - res.clearCookie('login'); - req.session.destroy(function(e){ res.status(200).send('ok'); }); - } else{ - res.status(400).send('record not found'); - } - }); - }); - - app.get('/reset', function(req, res) { - AM.deleteAllAccounts(function(){ - res.redirect('/print'); - }); - }); - - app.get('*', function(req, res) { res.render('404', { title: 'Page Not Found'}); }); +const AccountManager = require('./modules/account-manager'); +const EmailDispatcher = require('./modules/email-dispatcher'); +const isNullish = (o) => o === null || o === undefined; + +module.exports = function (app, config) { + const { + NL_EMAIL_HOST, + NL_EMAIL_USER, + NL_EMAIL_PASS, + NL_EMAIL_FROM, + NL_SITE_URL, + DB_URL, + DB_NAME, + countries + } = config; + + const AM = new AccountManager({ + DB_URL, + DB_NAME + }); + const ED = new EmailDispatcher({ + NL_EMAIL_HOST, + NL_EMAIL_USER, + NL_EMAIL_PASS, + NL_EMAIL_FROM, + NL_SITE_URL + }); + + /* + login & logout + */ + app.get('/', function (req, res) { + // check if the user has an auto login key saved in a cookie + if (req.cookies.login === undefined) { + res.render('login', { title: 'Hello - Please Login To Your Account' }); + } else { + // attempt automatic login + AM.validateLoginKey(req.cookies.login, req.ip, (e, o) => { + if (o) { + AM.autoLogin(o.user, o.pass, (_o) => { + req.session.user = _o; + res.redirect('/home'); + }); + } else { + res.render('login', { + title: 'Hello - Please Login To Your Account' + }); + } + }); + } + }); + + app.post('/', function (req, res) { + AM.manualLogin(req.body.user, req.body.pass, (e, o) => { + if (!o) { + res.status(400).send(e); + } else { + req.session.user = o; + if (req.body['remember-me'] === 'false') { + res.status(200).send(o); + } else { + AM.generateLoginKey(o.user, req.ip, (key) => { + res.cookie('login', key, { maxAge: 900000 }); + res.status(200).send(o); + }); + } + } + }); + }); + + app.post('/logout', function (req, res) { + res.clearCookie('login'); + req.session.destroy((e) => { res.status(200).send('ok'); }); + }); + + /* + control panel + */ + app.get('/home', function (req, res) { + if (isNullish(req.session.user)) { + res.redirect('/'); + } else { + res.render('home', { + title: 'Control Panel', + countries, + udata: req.session.user + }); + } + }); + + app.post('/home', function (req, res) { + if (isNullish(req.session.user)) { + res.redirect('/'); + } else { + const { name, email, pass, country } = req.body; + AM.updateAccount({ + id: req.session.user._id, + name, + email, + pass, + country + }, (e, o) => { + if (e) { + res.status(400).send('error-updating-account'); + } else { + req.session.user = o.value; + res.status(200).send('ok'); + } + }); + } + }); + + /* + new accounts + */ + app.get('/signup', function (req, res) { + res.render('signup', { title: 'Signup', countries }); + }); + + app.post('/signup', function (req, res) { + const { name, email, user, pass, country } = req.body; + AM.addNewAccount({ + name, + email, + user, + pass, + country + }, (e) => { + if (e) { + res.status(400).send(e); + } else { + res.status(200).send('ok'); + } + }); + }); + + /* + password reset + */ + app.post('/lost-password', function (req, res) { + const { email } = req.body; + AM.generatePasswordKey(email, req.ip, (e, account) => { + if (e) { + res.status(400).send(e); + } else { + ED.dispatchResetPasswordLink(account, (_e, m) => { + // TODO this callback takes a moment to return, add a loader to + // give user feedback + if (!_e) { + res.status(200).send('ok'); + } else { + for (const k in _e) { + if ({}.hasOwnProperty.call(_e, k)) { + console.log('ERROR:', k, _e[k]); + } + } + res.status(400).send('unable to dispatch password reset'); + } + }); + } + }); + }); + + app.get('/reset-password', function (req, res) { + AM.validatePasswordKey(req.query.key, req.ip, (e, o) => { + if (e || isNullish(o)) { + res.redirect('/'); + } else { + req.session.passKey = req.query.key; + res.render('reset', { title: 'Reset Password' }); + } + }); + }); + + app.post('/reset-password', function (req, res) { + const newPass = req.body.pass; + const { passKey } = req.session; + // destory the session immediately after retrieving the stored passkey + req.session.destroy(); + AM.updatePassword(passKey, newPass, (e, o) => { + if (o) { + res.status(200).send('ok'); + } else { + res.status(400).send('unable to update password'); + } + }); + }); + + /* + view, delete & reset accounts + */ + app.get('/print', function (req, res) { + AM.getAllRecords((e, accounts) => { + res.render('print', { title: 'Account List', accts: accounts }); + }); + }); + + app.post('/delete', function (req, res) { + AM.deleteAccount(req.session.user._id, (e, obj) => { + if (!e) { + res.clearCookie('login'); + req.session.destroy((_e) => { + res.status(200).send('ok'); + }); + } else { + res.status(400).send('record not found'); + } + }); + }); + + app.get('/reset', function (req, res) { + AM.deleteAllAccounts(() => { + res.redirect('/print'); + }); + }); + + app.get('*', function (req, res) { + res.render('404', { title: 'Page Not Found' }); + }); }; diff --git a/app/server/views/account.pug b/app/server/views/account.pug index e15553fc..70abc7ff 100644 --- a/app/server/views/account.pug +++ b/app/server/views/account.pug @@ -1,7 +1,7 @@ -// preset form values if we receive a userdata object // +// preset form values if we receive a userdata object - user = typeof(udata) != 'undefined' ? udata : { } -// store the userId on the client side in a hidden input field // +// store the userId on the client side in a hidden input field input(type='hidden', value= user._id)#userId #account-form-container.center-vertical @@ -41,6 +41,6 @@ input(type='hidden', value= user._id)#userId button(type='button')#account-form-btn1.btn.btn-outline-dark button(type='submit')#account-form-btn2.btn.btn-primary -// display form errors in a custom modal window // +// display form errors in a custom modal window include modals/form-errors diff --git a/app/server/views/login.pug b/app/server/views/login.pug index 832ae5e6..90cd0a30 100644 --- a/app/server/views/login.pug +++ b/app/server/views/login.pug @@ -33,4 +33,4 @@ block scripts script(src='/js/views/login.js') script(src='/js/controllers/loginController.js') script(src='/js/form-validators/loginValidator.js') - script(src='/js/form-validators/emailValidator.js') \ No newline at end of file + script(src='/js/form-validators/emailValidator.js') diff --git a/package-lock.json b/package-lock.json index 361d3dc4..5fb89d0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,82 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + } + } + }, + "@mysticatea/eslint-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@mysticatea/eslint-plugin/-/eslint-plugin-11.0.0.tgz", + "integrity": "sha512-MJt/iaAeYeKP7JpTWpGuoLBtyV4o743ipTUC0ZrM2CC7X0HB6PvxGhjQpQEy2IcM1yrwnuZvbIxlg0UComL7uQ==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "~1.11.0", + "@typescript-eslint/parser": "~1.11.0", + "eslint-plugin-eslint-comments": "~3.1.2", + "eslint-plugin-eslint-plugin": "~2.1.0", + "eslint-plugin-node": "~9.1.0", + "eslint-plugin-prettier": "~3.1.0", + "eslint-plugin-vue": "~5.2.3", + "prettier": "~1.18.2", + "vue-eslint-parser": "^5.0.0" + }, + "dependencies": { + "eslint-plugin-node": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-9.1.0.tgz", + "integrity": "sha512-ZwQYGm6EoV2cfLpE1wxJWsfnKUIXfM/KM09/TlorkukgCAwmkgajEJnPCmyzoFPQQkmvo5DrW/nyKutNIw36Mw==", + "dev": true, + "requires": { + "eslint-plugin-es": "^1.4.0", + "eslint-utils": "^1.3.1", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "@types/babel-types": { "version": "7.0.7", "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz", @@ -17,6 +93,65 @@ "@types/babel-types": "*" } }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.11.0.tgz", + "integrity": "sha512-mXv9ccCou89C8/4avKHuPB2WkSZyY/XcTQUXd5LFZAcLw1I3mWYVjUu6eS9Ja0QkP/ClolbcW9tb3Ov/pMdcqw==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "1.11.0", + "eslint-utils": "^1.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^2.0.1", + "tsutils": "^3.7.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.11.0.tgz", + "integrity": "sha512-7LbfaqF6B8oa8cp/315zxKk8FFzosRzzhF8Kn/ZRsRsnpm7Qcu25cR/9RnAQo5utZ2KIWVgaALr+ZmcbG47ruw==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.11.0", + "eslint-scope": "^4.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.11.0.tgz", + "integrity": "sha512-5xBExyXaxVyczrZvbRKEXvaTUFFq7gIM9BynXukXZE0zF3IQP/FxF4mPmmh3gJ9egafZFqByCpPTFm3dk4SY7Q==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "1.11.0", + "@typescript-eslint/typescript-estree": "1.11.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.11.0.tgz", + "integrity": "sha512-fquUHF5tAx1sM2OeRCC7wVxFd1iMELWMGCzOSmJ3pLzArj9+kRixdlC4d5MncuzXpjEqc6045p3KwM0o/3FuUA==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -46,11 +181,29 @@ } } }, + "acorn-jsx": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "dev": true + }, "addressparser": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-0.3.2.tgz", "integrity": "sha1-WYc/Nej89sc2HBAjkmHXbhU0i7I=" }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", @@ -61,16 +214,73 @@ "repeat-string": "^1.5.2" } }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==" + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, + "ast-metadata-inferer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz", + "integrity": "sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw==", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -101,6 +311,12 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, + "bail": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", + "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -132,26 +348,50 @@ "concat-map": "0.0.1" } }, + "browserslist": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz", + "integrity": "sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000989", + "electron-to-chromium": "^1.3.247", + "node-releases": "^1.1.29" + } + }, "bson": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" }, - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" }, + "caniuse-db": { + "version": "1.0.30000992", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000992.tgz", + "integrity": "sha512-9AZRaPuAGg7Dh3iiO5/i8APo9UjVEeyArfW1ZTvYpg0H/Eo4VrAe3ggqOaUY9mhyfxT3CLeAZgEKqo+1nRc0MA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000989", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", + "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==", + "dev": true + }, "center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", @@ -161,6 +401,29 @@ "lazy-cache": "^1.0.3" } }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "character-entities": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz", + "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz", + "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==", + "dev": true + }, "character-parser": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", @@ -169,6 +432,18 @@ "is-regex": "^1.0.3" } }, + "character-reference-invalid": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz", + "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==", + "dev": true + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "clean-css": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", @@ -177,6 +452,30 @@ "source-map": "~0.6.0" } }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -187,29 +486,55 @@ "wordwrap": "0.0.2" } }, + "collapse-white-space": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", + "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "command-line-args": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz", + "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==", + "requires": { + "array-back": "^3.0.1", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "comment-parser": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.6.2.tgz", + "integrity": "sha512-Wdms0Q8d4vvb2Yk72OwZjwNWtMklbC5Re7lD9cjCP/AG1fhocmc0TrxGBBAXPLy8fZQPrfHGgyygwI0lA7pbzA==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "connect-mongo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-2.0.3.tgz", - "integrity": "sha512-Vs+QZ/6X6gbCrP1Ls7Oh/wlyY6pgpbPSrUKF5yRT+zd+4GZPNbjNquxquZ+Clv2+03HBXE7T4lVM0PUcaBhihg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-3.0.0.tgz", + "integrity": "sha512-Y95urWNGrAoKY2w31s7Q9Gs/W3qdMCshUIeDTgulssHi6KueYtz4XrbV3kcnQaR8EcBQvooNNX7aOaAJDgudag==", "requires": { - "mongodb": "^2.0.36" - }, - "dependencies": { - "mongodb": { - "version": "2.2.36", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz", - "integrity": "sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA==", - "requires": { - "es6-promise": "3.2.1", - "mongodb-core": "2.1.20", - "readable-stream": "2.2.7" - } - } + "mongodb": "^3.1.0" } }, "constantinople": { @@ -223,6 +548,12 @@ "babylon": "^6.18.0" } }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -267,10 +598,18 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } }, "css": { "version": "2.2.4", @@ -309,6 +648,21 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -319,16 +673,80 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" }, + "dom-serializer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", + "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "electron-to-chromium": { + "version": "1.3.252", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.252.tgz", + "integrity": "sha512-NWJ5TztDnjExFISZHFwpoJjMbLUifsNBnx7u2JI0gCw6SbKyQYYWWtBHasO/jPtHym69F4EZuTpRNGN11MT/jg==", + "dev": true + }, "emailjs": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/emailjs/-/emailjs-2.2.0.tgz", @@ -344,30 +762,541 @@ "integrity": "sha512-4h0xp1jgVTnIQBHxSJWXWanNnmuc5o+k4aHEpcLXSToN8asjB5qbXAexs7+PEsUKcEyBteNYsSvXUndYT2CGGA==" }, "emailjs-mime-codec": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/emailjs-mime-codec/-/emailjs-mime-codec-2.0.8.tgz", - "integrity": "sha512-Upnk1zSj6wVrKRBdfc0di2eyjyTOatTs8QlZZlBedfGBWalZ6IlEaPbmoCL5Qt4VVTwLp7buYcw0+pu9sB744g==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/emailjs-mime-codec/-/emailjs-mime-codec-2.0.9.tgz", + "integrity": "sha512-7qJo4pFGcKlWh/kCeNjmcgj34YoJWY0ekZXEHYtluWg4MVBnXqGM4CRMtZQkfYwitOhUgaKN5EQktJddi/YIDQ==", "requires": { "emailjs-base64": "^1.1.4", - "ramda": "^0.25.0", - "text-encoding": "^0.6.4" + "ramda": "^0.26.1", + "text-encoding": "^0.7.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "es6-promise": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.1.tgz", + "integrity": "sha512-cp/Tb1oA/rh2X7vqeSOvM+TSo3UkJLX70eNihgVEvnzwAgikjkTFr/QVgRCaxjm0knCNQzNoxxxcw2zO2LJdZA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz", + "integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-ast-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", + "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", + "dev": true, + "requires": { + "lodash.get": "^4.4.2", + "lodash.zip": "^4.2.0" + } + }, + "eslint-config-ash-nazg": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint-config-ash-nazg/-/eslint-config-ash-nazg-8.9.0.tgz", + "integrity": "sha512-sEHKy0leBMaCGZ3GFXNCra8On0xk9l14BdET222fBbBBBl3UamXycDUrWl7I/wA9YmhEPJTdhOx3iRkq7zCPKA==", + "dev": true + }, + "eslint-config-standard": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz", + "integrity": "sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-array-func": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-3.1.3.tgz", + "integrity": "sha512-uRfJ4d9Fyyvxm6/w++++RSQoXZyERFF0+6zqupgg5Mw/+eG4y19yrptTghJlApntKlPZBpA4XCOIBzJbvLrArQ==", + "dev": true + }, + "eslint-plugin-compat": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.3.0.tgz", + "integrity": "sha512-QCgYy3pZ+zH10dkBJus1xER0359h1UhJjufhQRqp9Owm6BEoLZeSqxf2zINwL1OGao9Yc96xPYIW3nQj5HUryg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "ast-metadata-inferer": "^0.1.1", + "browserslist": "^4.6.3", + "caniuse-db": "^1.0.30000977", + "lodash.memoize": "4.1.2", + "mdn-browser-compat-data": "^0.0.84", + "semver": "^6.1.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-es": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz", + "integrity": "sha512-5fa/gR2yR3NxQf+UXkeLeP8FBBl6tSgdrAz1+cF84v1FMM4twGwQoqTnn+QxFLcPOrF4pdKEJKDB/q9GoyJrCA==", + "dev": true, + "requires": { + "eslint-utils": "^1.4.2", + "regexpp": "^2.0.1" + } + }, + "eslint-plugin-eslint-comments": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.2.tgz", + "integrity": "sha512-QexaqrNeteFfRTad96W+Vi4Zj1KFbkHHNMMaHZEYcovKav6gdomyGzaxSDSL3GoIyUOo078wRAdYlu1caiauIQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "ignore": "^5.0.5" + } + }, + "eslint-plugin-eslint-plugin": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz", + "integrity": "sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg==", + "dev": true + }, + "eslint-plugin-html": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.0.0.tgz", + "integrity": "sha512-PQcGippOHS+HTbQCStmH5MY1BF2MaU8qW/+Mvo/8xTa/ioeMXdSP+IiaBw2+nh0KEMfYQKuTz1Zo+vHynjwhbg==", + "dev": true, + "requires": { + "htmlparser2": "^3.10.1" + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-jsdoc": { + "version": "15.9.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-15.9.2.tgz", + "integrity": "sha512-dJjIWFJlh4ti3CegWYN0jUUdjEsWvJ8TZJ/cMQldioVLxMmU3UZeZsHzxYcCicJwSVhQ+uGm+dbUyEIm0slX3Q==", + "dev": true, + "requires": { + "comment-parser": "^0.6.2", + "debug": "^4.1.1", + "jsdoctypeparser": "5.0.1", + "lodash": "^4.17.15", + "object.entries-ponyfill": "^1.0.1", + "regextras": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "eslint-plugin-markdown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-1.0.0.tgz", + "integrity": "sha512-YIrClt3yLgyGov+rInjIoC/05zMxb/c6YXQZkyI9UKuBRFLgCrL37cxthj0JYWiTYtiHq0p8O0Nt0/HrvO48iQ==", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "remark-parse": "^5.0.0", + "unified": "^6.1.2" + } + }, + "eslint-plugin-no-use-extend-native": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.4.1.tgz", + "integrity": "sha512-tDkHM0kvxU0M2TpLRKGfFrpWXctFdTDY7VkiDTLYDaX90hMSJKkr/FiWThEXvKV0Dvffut2Z0B9Y7+h/k6suiA==", + "dev": true, + "requires": { + "is-get-set-prop": "^1.0.0", + "is-js-type": "^2.0.0", + "is-obj-prop": "^1.0.0", + "is-proto-prop": "^2.0.0" + } + }, + "eslint-plugin-node": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz", + "integrity": "sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ==", + "dev": true, + "requires": { + "eslint-plugin-es": "^2.0.0", + "eslint-utils": "^1.4.2", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-plugin-es": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz", + "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==", + "dev": true, + "requires": { + "eslint-utils": "^1.4.2", + "regexpp": "^3.0.0" + } + }, + "regexpp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz", + "integrity": "sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-promise": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true + }, + "eslint-plugin-sonarjs": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.4.0.tgz", + "integrity": "sha512-l8E4ueMKVtEcocINHSNVH/YBSmDDXZlPEbud7bagRGyoCeB0otoyltoro5kdnIvVzS5usUwvjzMocHnPax2FEw==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", + "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", + "dev": true + }, + "eslint-plugin-unicorn": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-10.0.0.tgz", + "integrity": "sha512-hJaDsoquO+2UMtxmURXA/6VNH+sNS4kyO5aaal8fEis7pdCuErwRsGzhhI9fOYmA7985M3XADPEWmK+29T525w==", + "dev": true, + "requires": { + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.1.0", + "import-modules": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "lodash.defaultsdeep": "^4.6.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.topairs": "^4.3.0", + "lodash.upperfirst": "^4.3.1", + "regexpp": "^2.0.1", + "reserved-words": "^0.1.2", + "safe-regex": "^2.0.2" + } + }, + "eslint-plugin-vue": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-5.2.3.tgz", + "integrity": "sha512-mGwMqbbJf0+VvpGR5Lllq0PMxvTdrZ/ZPjmhkacrCHbubJeJOt+T6E3HUzAifa2Mxi7RSdJfC9HFpOeSYVMMIw==", + "dev": true, + "requires": { + "vue-eslint-parser": "^5.0.0" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", + "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -454,6 +1383,65 @@ } } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -468,6 +1456,40 @@ "unpipe": "~1.0.0" } }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "requires": { + "array-back": "^3.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -488,6 +1510,18 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-set-props": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", + "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", + "dev": true + }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", @@ -501,6 +1535,27 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -509,6 +1564,60 @@ "function-bind": "^1.1.1" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -529,6 +1638,42 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz", + "integrity": "sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -543,16 +1688,77 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, "ipaddr.js": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" }, + "is-alphabetical": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", + "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz", + "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-decimal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", + "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==", + "dev": true + }, "is-expression": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", @@ -569,11 +1775,83 @@ } } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-get-set-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", + "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", + "dev": true, + "requires": { + "get-set-props": "^0.1.0", + "lowercase-keys": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz", + "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==", + "dev": true + }, + "is-js-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", + "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", + "dev": true, + "requires": { + "js-types": "^1.0.0" + } + }, + "is-obj-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", + "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0", + "obj-props": "^1.0.0" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, + "is-proto-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz", + "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0", + "proto-props": "^2.0.0" + } + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -582,16 +1860,84 @@ "has": "^1.0.1" } }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-whitespace-character": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz", + "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==", + "dev": true + }, + "is-word-character": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz", + "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz", + "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsdoctypeparser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-5.0.1.tgz", + "integrity": "sha512-dYwcK6TKzvq+ZKtbp4sbQSW9JMo6s+4YFfUs5D/K7bZsn3s1NhEhZ+jmIPzby0HbkbECBe+hNPEa6a+E21o94w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "jstransformer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", @@ -614,16 +1960,128 @@ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "lodash.defaultsdeep": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", + "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", + "dev": true + }, + "lodash.topairs": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.topairs/-/lodash.topairs-4.3.0.tgz", + "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=", + "dev": true + }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", + "dev": true + }, + "lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "markdown-escapes": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz", + "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==", + "dev": true + }, + "mdn-browser-compat-data": { + "version": "0.0.84", + "resolved": "https://registry.npmjs.org/mdn-browser-compat-data/-/mdn-browser-compat-data-0.0.84.tgz", + "integrity": "sha512-fAznuGNaQMQiWLVf+gyp33FaABTglYWqMT7JqvH+4RZn2UQPD12gbMqxwP9m0lj8AAbNpu5/kD6n4Ox1SOffpw==", + "dev": true, + "requires": { + "extend": "3.0.2" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -657,6 +2115,12 @@ "mime-db": "1.40.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -693,37 +2157,96 @@ "safe-buffer": "^5.1.2" } }, - "mongodb-core": { - "version": "2.1.20", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz", - "integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==", - "requires": { - "bson": "~1.0.4", - "require_optional": "~1.0.0" - }, - "dependencies": { - "bson": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", - "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" - } - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-releases": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.29.tgz", + "integrity": "sha512-R5bDhzh6I+tpi/9i2hrrvGJ3yKPYzlVOORDkXhnZuwi5D3q1I5w4vYy24PJXTcLk9Q0kws9TO77T75bcK8/ysQ==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "obj-props": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.2.0.tgz", + "integrity": "sha512-ZYpJyCe7O4rhNxB/2SZy8ADJww8RSRBdG36a4MWWq7JwILGJ1m61B90QJtxwDDNA0KzyR8V12Wikpjuux7Gl9Q==", + "dev": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.entries-ponyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.entries-ponyfill/-/object.entries-ponyfill-1.0.1.tgz", + "integrity": "sha1-Kavfd8v70mVm3RqiTp2I9lQz0lY=", + "dev": true + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -745,16 +2268,121 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -765,10 +2393,56 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prettier": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true }, "promise": { "version": "7.3.1", @@ -778,6 +2452,12 @@ "asap": "~2.0.3" } }, + "proto-props": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz", + "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==", + "dev": true + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -901,15 +2581,21 @@ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz", "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==" }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, "ramda": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", - "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", + "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==" }, "random-bytes": { "version": "1.0.0", @@ -932,18 +2618,25 @@ "unpipe": "1.0.0" } }, - "readable-stream": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "regenerator-runtime": { @@ -951,11 +2644,58 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, + "regexp-tree": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.13.tgz", + "integrity": "sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "regextras": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.6.1.tgz", + "integrity": "sha512-EzIHww9xV2Kpqx+corS/I7OBmf2rZ0pKKJPsw5Dc+l6Zq1TslDmtRIP9maVn3UH+72MIXmn8zzDgP07ihQogUA==", + "dev": true + }, + "remark-parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", @@ -965,6 +2705,12 @@ "semver": "^5.1.0" } }, + "reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", + "dev": true + }, "resolve": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", @@ -983,6 +2729,16 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -991,11 +2747,47 @@ "align-text": "^0.1.1" } }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, + "safe-regex": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.0.2.tgz", + "integrity": "sha512-rRALJT0mh4qVFIJ9HvfjKDN77F9vp7kltOpFFI/8e6oKyHFmmxz4aSkY/YVauRDe7U0RrHdw9Lsxdel3E19s0A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1054,6 +2846,38 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1076,26 +2900,125 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "state-toggle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz", + "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==", + "dev": true + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimleft": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz", + "integrity": "sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.0.2" + } + }, + "string.prototype.trimright": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz", + "integrity": "sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.0.2" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true } } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, "stylus": { "version": "0.54.7", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", @@ -1131,10 +3054,65 @@ } } }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, "text-encoding": { - "version": "0.6.4", - "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } }, "to-fast-properties": { "version": "1.0.3", @@ -1151,6 +3129,48 @@ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=" }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "trim-trailing-lines": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz", + "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==", + "dev": true + }, + "trough": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", + "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==", + "dev": true + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1160,6 +3180,17 @@ "mime-types": "~2.1.24" } }, + "typescript": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", + "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", + "dev": true + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==" + }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", @@ -1191,11 +3222,83 @@ "random-bytes": "~1.0.0" } }, + "unherit": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz", + "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "xtend": "^4.0.1" + } + }, + "unified": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", + "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", + "dev": true, + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" + } + }, + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "unist-util-remove-position": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz", + "integrity": "sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -1204,23 +3307,107 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "vfile": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "dev": true, + "requires": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "vfile-location": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz", + "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==", + "dev": true + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + }, "void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" }, + "vue-eslint-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz", + "integrity": "sha512-JlHVZwBBTNVvzmifwjpZYn0oPWH2SgWv5dojlZBsrhablDu95VFD+hriB1rQGwbD+bms6g+rAFhQHk6+NyiS6g==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.1.0", + "esquery": "^1.0.1", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", @@ -1245,6 +3432,27 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, "yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", diff --git a/package.json b/package.json index 7b78bcab..fb6afe63 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,16 @@ "contributors": [ "Brett Zamir" ], + "scripts": { + "lint": "eslint --ext=js,md,html .", + "start": "node app.js" + }, + "engines": { + "node": ">=10.4.0" + }, "website": { "url": "https://nodejs-login.herokuapp.com" }, - "private": false, "repository": { "type": "git", "url": "git@github.com:braitsch/node-login.git" @@ -21,21 +27,36 @@ "homepage": "https://github.com/braitsch/node-login", "bugs": "https://github.com/braitsch/node-login/issues", "dependencies": { - "body-parser": "^1.18.3", - "connect-mongo": "^2.0.1", - "cookie-parser": "^1.4.3", + "body-parser": "^1.19.0", + "command-line-args": "^5.1.1", + "connect-mongo": "^3.0.0", + "cookie-parser": "^1.4.4", "emailjs": "^2.2.0", - "express": "^4.16.4", - "express-session": "^1.15.6", - "moment": "^2.22.2", - "mongodb": "^3.1.10", - "pug": "^2.0.3", - "stylus": "^0.54.5" + "express": "^4.17.1", + "express-session": "^1.16.2", + "moment": "^2.24.0", + "mongodb": "^3.3.2", + "pug": "^2.0.4", + "stylus": "^0.54.7" }, - "engines": { - "node": ">=10.4.0" - }, - "scripts": { - "start": "node app.js" + "devDependencies": { + "@mysticatea/eslint-plugin": "^11.0.0", + "eslint": "^6.4.0", + "eslint-config-ash-nazg": "^8.9.0", + "eslint-config-standard": "^14.1.0", + "eslint-plugin-array-func": "^3.1.3", + "eslint-plugin-compat": "^3.3.0", + "eslint-plugin-eslint-comments": "^3.1.2", + "eslint-plugin-html": "^6.0.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-jsdoc": "^15.9.2", + "eslint-plugin-markdown": "^1.0.0", + "eslint-plugin-no-use-extend-native": "^0.4.1", + "eslint-plugin-node": "^10.0.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-sonarjs": "^0.4.0", + "eslint-plugin-standard": "^4.0.1", + "eslint-plugin-unicorn": "^10.0.0", + "typescript": "^3.6.3" } }