From 6d65ac391251a9acee47ef295636b65386be2f86 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 8 Mar 2020 22:25:38 -0400 Subject: [PATCH] Stripped down and reworked pages Stripped down the website to remove account managment and API handling. These features may be brought back in the future when the network goes live. A few new pages such as the Cemu and FAQ pages were added along with a finished credits list --- assets/css/pretendo-auth.css | 45 - assets/css/pretendo-common.css | 6 +- assets/css/pretendo-contact.css | 15 - assets/css/pretendo-faq.css | 29 + assets/css/pretendo-news.css | 26 - assets/css/pretendo-pnid.css | 176 -- assets/css/pretendo-progress.css | 68 - assets/js/api.js | 150 -- assets/js/pnid.js | 4 - config.example.json | 28 +- helpers/api.js | 71 - helpers/mailer.js | 31 - helpers/util.js | 45 +- locales/US_en.json | 117 +- locales/default.json | 59 +- logger.js | 89 +- middleware/authentication.js | 48 - models/admin-user.js | 69 - models/blog-post.js | 105 -- models/pnid.js | 184 --- models/post-author.js | 43 - models/progress-list.js | 36 - package-lock.json | 2583 ++++++++++-------------------- package.json | 15 +- passport.config.js | 100 -- public/robots.txt | 6 - routes/admin.js | 494 ------ routes/blog.js | 134 -- routes/cemu.js | 16 + routes/connecting.js | 16 + routes/contact.js | 91 -- routes/faq.js | 16 + routes/home.js | 21 +- routes/pnid.js | 212 --- routes/progress.js | 66 - server.js | 88 +- setupAdminUser.js | 22 - views/404.hbs | 4 +- views/admin.hbs | 134 -- views/cemu.hbs | 21 + views/connecting.hbs | 21 + views/contact.hbs | 35 - views/faq.hbs | 62 + views/home.hbs | 121 +- views/partials/nav-dashboard.hbs | 10 - views/partials/nav-default.hbs | 22 - views/partials/navbar.hbs | 14 + views/pnid/dashboard.hbs | 38 - views/pnid/forgotpassword.hbs | 28 - views/pnid/login.hbs | 32 - views/pnid/passwordreset.hbs | 30 - views/pnid/register.hbs | 147 -- views/post-collection.hbs | 29 - views/post.hbs | 28 - views/progress.hbs | 44 - 55 files changed, 1180 insertions(+), 4964 deletions(-) delete mode 100644 assets/css/pretendo-auth.css delete mode 100644 assets/css/pretendo-contact.css create mode 100644 assets/css/pretendo-faq.css delete mode 100644 assets/css/pretendo-news.css delete mode 100644 assets/css/pretendo-pnid.css delete mode 100644 assets/css/pretendo-progress.css delete mode 100644 assets/js/api.js delete mode 100644 assets/js/pnid.js delete mode 100644 helpers/api.js delete mode 100644 helpers/mailer.js delete mode 100644 middleware/authentication.js delete mode 100644 models/admin-user.js delete mode 100644 models/blog-post.js delete mode 100644 models/pnid.js delete mode 100644 models/post-author.js delete mode 100644 models/progress-list.js delete mode 100644 passport.config.js delete mode 100644 public/robots.txt delete mode 100644 routes/admin.js delete mode 100644 routes/blog.js create mode 100644 routes/cemu.js create mode 100644 routes/connecting.js delete mode 100644 routes/contact.js create mode 100644 routes/faq.js delete mode 100644 routes/pnid.js delete mode 100644 routes/progress.js delete mode 100644 setupAdminUser.js delete mode 100644 views/admin.hbs create mode 100644 views/cemu.hbs create mode 100644 views/connecting.hbs delete mode 100644 views/contact.hbs create mode 100644 views/faq.hbs delete mode 100644 views/partials/nav-dashboard.hbs delete mode 100644 views/partials/nav-default.hbs create mode 100644 views/partials/navbar.hbs delete mode 100644 views/pnid/dashboard.hbs delete mode 100644 views/pnid/forgotpassword.hbs delete mode 100644 views/pnid/login.hbs delete mode 100644 views/pnid/passwordreset.hbs delete mode 100644 views/pnid/register.hbs delete mode 100644 views/post-collection.hbs delete mode 100644 views/post.hbs delete mode 100644 views/progress.hbs diff --git a/assets/css/pretendo-auth.css b/assets/css/pretendo-auth.css deleted file mode 100644 index 76526d9..0000000 --- a/assets/css/pretendo-auth.css +++ /dev/null @@ -1,45 +0,0 @@ -body.flex.center { - justify-content: center; - align-items: center; -} - -body footer { - padding: 0; - background-color: transparent; -} -body footer .content { - border-radius: 0; - background-color: transparent; - padding: 1em 0; - box-shadow: none; - width: 30rem; - max-width: 100vw; -} - -/* login/register card */ -.card { - background-color: white; - box-shadow: 0 3px 10px 0px rgba(0, 0, 0, 0.07); - width: 35rem; - max-width: 100%; -} -.card .content { - padding: 0 3em 4em 3em; -} -.card .head { - background-color: #673ab7; - color: white; - font-size: 1em; - font-weight: normal; - padding: 1.5em 2em; - margin: 0; -} -.card .content .btnMargin { - display: block; - width: 100%; - margin: 3em 0 0 0; -} -.card .content .lowText { - text-align: right; - color: #707070; -} \ No newline at end of file diff --git a/assets/css/pretendo-common.css b/assets/css/pretendo-common.css index f8c7c97..6b0ab4d 100644 --- a/assets/css/pretendo-common.css +++ b/assets/css/pretendo-common.css @@ -91,7 +91,8 @@ nav.navWrapper .navProfile { } nav.navWrapper .navProfile img { border-radius: 50%; - width: 2em; height: 2em; + width: 2em; + height: 2em; background-color: white; border: 1px solid rgba(0, 0, 0, 0.5); } @@ -156,7 +157,8 @@ nav.navWrapper.open .navItem.hamburger { /* content wrapper */ .contentWrapper { position: relative; - width: 100%; + max-width: 100%; + overflow-x: hidden; } nav.navWrapper ~ .contentWrapper:nth-child(2) { margin-top: 3rem; diff --git a/assets/css/pretendo-contact.css b/assets/css/pretendo-contact.css deleted file mode 100644 index fb7fa2b..0000000 --- a/assets/css/pretendo-contact.css +++ /dev/null @@ -1,15 +0,0 @@ -.input-container { - display: flex; - flex-direction: row; -} -.input-container > * { - flex: 1; -} -.input-container > *:first-child { - margin-right: 3em; -} -@media screen and (max-width: 1000px) { - .input-container { - flex-direction: column; - } -} \ No newline at end of file diff --git a/assets/css/pretendo-faq.css b/assets/css/pretendo-faq.css new file mode 100644 index 0000000..4990f49 --- /dev/null +++ b/assets/css/pretendo-faq.css @@ -0,0 +1,29 @@ +::-webkit-details-marker { + float: right; + margin-top: 3px; +} + +details { + background: #f6f6f6; + border-radius: 7px; + margin-top: 20px; + cursor: pointer; +} + +details[open] summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +details summary { + border-radius: 7px; + padding: 10px 20px; + background: #673db6; + color: white; + outline: none; +} + +details .text { + margin-left: 10px; + padding-bottom: 10px; +} \ No newline at end of file diff --git a/assets/css/pretendo-news.css b/assets/css/pretendo-news.css deleted file mode 100644 index 9ef438f..0000000 --- a/assets/css/pretendo-news.css +++ /dev/null @@ -1,26 +0,0 @@ -/* news cards */ -.smallCard { - padding: 2em; - border: 1px solid rgb(165, 165, 165); - border-radius: 10px; - box-shadow: 0 5px 20px rgba(0, 0, 0, 0.07); - position: relative; - margin: .5em; - width: calc(50% - 1em ); - box-sizing: border-box; - display: inline-block; -} -.smallCard h3 { - font-size: 1.5em; - margin: 0; -} -.smallCard a { - display: inline-block; -} - -@media screen and (max-width: 720px) { - .smallCard { - width: 100%; - display: block; - } -} \ No newline at end of file diff --git a/assets/css/pretendo-pnid.css b/assets/css/pretendo-pnid.css deleted file mode 100644 index 9be911f..0000000 --- a/assets/css/pretendo-pnid.css +++ /dev/null @@ -1,176 +0,0 @@ -body .contentWrapper.userPage { - display: flex; - justify-content: center; - height: 100%; - margin: 10rem 0 7rem 0 !important; /*im sorry, I had to*/ -} -body footer { - padding: 0; - box-shadow: 0 -3px 10px 0px rgba(0, 0, 0, 0.07); -} -body footer .content { - border-radius: 0; -} - -/* content card */ -.contentCard { - background-color: white; - box-shadow: 0 3px 10px 0px rgba(0, 0, 0, 0.07); - box-sizing: border-box; - color: #707070; - width: 40rem; - max-width: 100vw; - padding: 3rem 4rem; -} -.infoContainer.hide { - display: none; -} -.infoList { - display: block; - padding: 1em 0; - font-weight: bold; - color: #000; - margin: 0; -} -.infoList span { - font-weight: normal; - display: inline-block; - color: #707070; - width: 6em; -} -.infoList + .infoList { - border-top: 1px solid #afafaf; -} -.infoContainer .btn { - margin-top: 1em; -} -.link-margin { - margin: 0 1em; -} - -/* aside navigation */ -nav.userNav { - padding: 1em 3em 1em 1em; -} -nav.userNav .userNavProfile { - text-align: center; -} -nav.userNav .userNavProfile::after { - content: ""; - width: 10em; - display: inline-block; - height: 1px; - background-color: rgba(0, 0, 0, 0.5);; -} -nav.userNav .userNavProfile img { - width: 7em; - height: 7em; - background-color: white; - border: 1px solid rgba(0, 0, 0, 0.5); - border-radius: 50%; - display: inline-block; -} -nav.userNav .userNavProfile .name { - font-size: 1.5em; - font-weight: bold; - color: #353535; - margin: .5em 1em 0 1em; -} -nav.userNav .links { - padding: .7em 0; -} -nav.userNav .links .navItem { - display: block; - margin: .3em .5em; - font-size: 1em; - color: #707070; - text-decoration: none; -} -nav.userNav .links .navItem:hover { - color: #505050; - font-weight: bold; - text-decoration: none; -} -nav.userNav .links .navItem.active { - color: #673ab7; - font-weight: bold; -} - -/* email popup */ -.email_popup { - margin: 10px 4em; - margin-top: 55px; - background-color: white; - border: 1px solid #d1d1d1; - padding: 1em 2em; - transition: transform .2s ease-in, max-height .2s, padding .5s; - overflow: hidden; - max-height: 100vh; -} -.email_popup.closed { - transform: translateY(-15rem); - max-height: 0; - padding: 0; -} -.email_popup p { - padding: 0; - display: inline-block; -} -.email_popup span { - float: right; -} -.email_popup button { - margin: .4em; -} - -@media screen and (max-width: 950px) { - body .contentWrapper.userPage { - flex-direction: column; - } - nav.userNav { - display: flex; - flex-direction: row; - justify-content: center; - } - .email_popup { - margin: 10px; - margin-top: 55px; - } - .contentCard { - display: block; - margin: auto; - } - nav.userNav .links { - display: flex; - flex-direction: row; - align-items: flex-end; - } - nav.userNav .links .navItem { - display: inline-block; - } - nav.userNav .userNavProfile::after { - display: none; - } -} - -@media screen and (max-width: 500px) { - .contentCard { - width: 100vw; - } -} - -@media screen and (max-width: 450px) { - nav.userNav { - display: flex; - flex-direction: column; - justify-content: center; - } - nav.userNav .links { - display: flex; - flex-direction: column; - align-items: center; - } - nav.userNav .userNavProfile::after { - display: inline-block; - } -} \ No newline at end of file diff --git a/assets/css/pretendo-progress.css b/assets/css/pretendo-progress.css deleted file mode 100644 index ff91476..0000000 --- a/assets/css/pretendo-progress.css +++ /dev/null @@ -1,68 +0,0 @@ -section.bigCardWrapper.double { - display: flex; - flex-direction: row; - max-width: 80vw; - margin: auto; -} -section.bigCardWrapper.double > .bigCard { - flex: 1; - padding: 1em 6em; - margin: 0; -} -section.bigCardWrapper.double > .bigCard:first-child { - margin-right: 3em; -} - -.listItem { - position: relative; -} - -.listItem h2 { - font-size: 1rem; - color: #353535; - margin: 1em 0 0 0; -} -.listItem p { - margin: .2em 0 0 0; -} - -.listItem.state1::before, .listItem.state2::before, .listItem.state3::before { - content: ""; - position: absolute; - top: .2em; - left: -1.5em; - width: 1em; - height: 1em; - border-radius: 50%; - background-color: #f57c7c; /* state 1: no support */ -} -.listItem.state2::before { - background-color: #e6ae65; /* state 2: partial support/bugged */ -} -.listItem.state3::before { - background-color: #58ef81; /* state 3: full support/working */ -} - -@media screen and (max-width: 1000px) { - section.bigCardWrapper.double { - display: flex; - flex-direction: column; - } - section.bigCardWrapper.double > .bigCard { - flex: 0; - } - section.bigCardWrapper.double > .bigCard:first-child { - margin-right: 0; - margin-bottom: 3em; - } -} - -@media screen and (max-width: 500px) { - section.bigCardWrapper.double { - max-width: 100vw; - margin: 0; - } - section.bigCardWrapper.double > .bigCard { - padding: 50px; - } -} \ No newline at end of file diff --git a/assets/js/api.js b/assets/js/api.js deleted file mode 100644 index fe5eec3..0000000 --- a/assets/js/api.js +++ /dev/null @@ -1,150 +0,0 @@ -function postAjax(url, data, callbacks={}) { - const params = (typeof data == 'string') ? data : Object.keys(data).map(function (k) { - return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) - }).join('&'); - - const xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); - for (const event in callbacks) { - const handler = callbacks[event]; - - if (handler instanceof Function) { - xhr.addEventListener(event, handler); - } - } - - xhr.open('POST', url); - xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xhr.send(data); - return xhr; -} - -function showErrorPopup(errorText) { - console.log(errorText); - document.getElementById('errorBox').innerHTML = errorText; - document.getElementById('errorBox').classList.remove('hide'); -} - -function showSuccessPopup(successText) { - document.getElementById('successBox').innerHTML = successText; - document.getElementById('successBox').classList.remove('hide'); -} - -function login() { - var xhr = postAjax('/api/v1/login', { - email: document.getElementById('email_input').value, - password: document.getElementById('password_input').value - }); - xhr.onload = function () { - if (xhr.responseText.charAt(0) !== "{") { - return showErrorPopup('Whoops, something went wrong. Try again later.'); - } - response = JSON.parse(xhr.responseText); - if (response.success === true) { - location.pathname = '/pnid/dashboard'; - } else if (response.errors) { - showErrorPopup(response.errors); - } - } -} - -function editInfo() { - var xhr = postAjax('/api/v1/editaccount', { - email: document.getElementById('email_input').value, - username: document.getElementById('username_input').value - }); - xhr.onload = function () { - if (xhr.responseText.charAt(0) !== "{") { - return showErrorPopup('Whoops, something went wrong. Try again later.'); - } - response = JSON.parse(xhr.responseText); - if (response.success === true) { - location.pathname = '/pnid/dashboard'; - } else if (response.errors) { - showErrorPopup(response.errors); - } - } -} - -function passwordForgot() { - var xhr = postAjax('/api/v1/passwordforgot', { - email: document.getElementById('email_input').value - }); - xhr.onload = function () { - if (xhr.responseText.charAt(0) !== "{") { - return showErrorPopup('Whoops, something went wrong. Try again later.'); - } - response = JSON.parse(xhr.responseText); - if (response.success === true) { - document.getElementById('email_input').value = ''; - return showSuccessPopup('An email has been sent to your email address.'); - } else if (response.errors) { - showErrorPopup(response.errors); - } - } -} - -function passwordReset() { - var xhr = postAjax('/api/v1/passwordreset', { - password: document.getElementById('password_input').value, - password_confirm: document.getElementById('password_confirm').value - }); - xhr.onload = function () { - if (xhr.responseText.charAt(0) !== "{") { - return showErrorPopup('Whoops, something went wrong. Try again later.'); - } - response = JSON.parse(xhr.responseText); - if (response.success === true) { - location.pathname = '/pnid/login'; - } else if (response.errors) { - showErrorPopup(response.errors); - } - } -} - -function register() { - var xhr = postAjax('/api/v1/register', { - email: document.getElementById('email_input').value, - username: document.getElementById('username_input').value, - password: document.getElementById('password_input').value, - confirm_password: document.getElementById('password_confirm_input').value - }); - xhr.onload = function () { - if (xhr.responseText.charAt(0) !== "{") { - return showErrorPopup('Whoops, something went wrong. Try again later.'); - } - response = JSON.parse(xhr.responseText); - if (response.success === true) { - login(); - } else if (response.errors) { - showErrorPopup(response.errors); - } - } -} - -function sendMessage() { - var xhr = postAjax('/api/v1/sendmessage', { - email: document.getElementById('email_input').value, - subject: document.getElementById('subject_input').value, - message: document.getElementById('message_input').value - }); - xhr.onload = function () { - if (xhr.responseText.charAt(0) !== "{") { - return showErrorPopup('Whoops, something went wrong. Try again later.'); - } - response = JSON.parse(xhr.responseText); - if (response.success === true) { - document.getElementById('email_input').value = ''; - document.getElementById('subject_input').value = ''; - document.getElementById('message_input').value = ''; - return showSuccessPopup('Your message has been sent.'); - } else if (response.errors) { - showErrorPopup(response.errors); - } - } -} - -function email_resend() { - var xhr = postAjax('/api/v1/resendemail', {}); - document.getElementById('email_verification_popup').classList.add('closed'); -} \ No newline at end of file diff --git a/assets/js/pnid.js b/assets/js/pnid.js deleted file mode 100644 index 571669a..0000000 --- a/assets/js/pnid.js +++ /dev/null @@ -1,4 +0,0 @@ -function toggleEditInfo() { - document.getElementById('userInfo').classList.toggle('hide'); - document.getElementById('editInfo').classList.toggle('hide'); -} \ No newline at end of file diff --git a/config.example.json b/config.example.json index 0fcfe1f..c882706 100644 --- a/config.example.json +++ b/config.example.json @@ -1,27 +1,5 @@ { - "http": { - "port": 8080 - }, - "database": { - "url": "mongodb://localhost:27017/pretendo_website" - }, - "contactWebhook": { - "port": 443, - "host": "host.com", - "path": "/webhookurl" - }, - "secrets": { - "session": "session secret here" - }, - "email": { - "service": "gmail", - "auth": { - "user": "example@email.com", - "pass": "password" - } - }, - "recaptcha": { - "siteKey": "abcd", - "secretKey": "1234" - } + "http": { + "port": 8080 + } } diff --git a/helpers/api.js b/helpers/api.js deleted file mode 100644 index 0f37cd4..0000000 --- a/helpers/api.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - -api.js - -common api returns - -*/ - -/** - * Send generic API response - * @param {ServerResponse} response An express ServerResponse response - * @param {Object} data Response data - * @param {Array} errors Request errors - */ -function sendReturn(response, data, errors) { - return response.status(data.code || 200).json( - Object.assign({ - code: 200, - success: true, - errors: [] + (errors ? errors : []) - }, data) - ); -} - -/** - * Send API 404 - * @param {ServerResponse} response An express ServerResponse response - */ -function sendApi404(response) { - return sendApiError(response, 404, [ - 'Endpoint not in use' - ]); -} - -/** - * Send user not authenticated error - * @param {ServerResponse} response An express ServerResponse response - */ -function sendApiAuthError(response) { - return sendApiError(response, 401, [ - 'Not authenticated' - ]); -} - -/** - * Send a generic API error - * @param {ServerResponse} response An express ServerResponse response - */ -function sendApiGenericError(response) { - return sendApiError(response, 400, [ - 'Bad request' - ]); -} - -/** - * Send an API error - * @param {ServerResponse} response An express ServerResponse response - */ -function sendApiError(response, code, errors) { - return sendReturn(response, { - code, - success: false - }, errors); -} - -module.exports = { - sendReturn, - sendApi404, - sendApiGenericError, - sendApiError, - sendApiAuthError -}; \ No newline at end of file diff --git a/helpers/mailer.js b/helpers/mailer.js deleted file mode 100644 index 7b0708c..0000000 --- a/helpers/mailer.js +++ /dev/null @@ -1,31 +0,0 @@ -const nodemailer = require('nodemailer'); -const config = require('../config'); - -const transporter = nodemailer.createTransport(config.email); - -/** - * Sends an email with the specified subject and message to an email address - * @param {String} email the destination email address - * @param {String} subject The Subject of the email - * @param {String} message The body of the email - */ -function send(email, subject = 'No email subject provided', message = 'No email body provided') { - const options = { - from: config.email.address, - to: email, - subject: subject, - html: message - }; - - transporter.sendMail(options, (error, info) => { - if (error) { - console.warn(error); - } else { - console.log(info); - } - }); -} - -module.exports = { - send: send -}; \ No newline at end of file diff --git a/helpers/util.js b/helpers/util.js index 3faccc2..5078527 100644 --- a/helpers/util.js +++ b/helpers/util.js @@ -6,38 +6,7 @@ small commonly used utilities */ const fs = require('fs-extra'); -const logger = require('winston'); - -// shows 404 template. takes express response object -function send404(res) { - res.status(404).render('404'); -} - -function templateReadyUser(req) { - // normal user logged in - const isLoggedIn = req.user ? req.user.role != 'admin' : false; - const user = req.user ? req.user.toObject() : undefined; - return { - isLoggedIn, - user - }; -} - -// Returns a list of possible locales: -/* -* [ -* { -* region: 'US', -* language: 'en', -* display: 'American English', -* flag_id: 1 // I dunno maybe we display a local list that also displays flags? -* } -* ] -* -*/ -function getLocales() { - return []; -} +const logger = require('../logger'); // Returns a locale function getLocale(region, language) { @@ -47,7 +16,7 @@ function getLocale(region, language) { return require(path); } - logger.log('warn', `Could not find locale ${region}_${language}! Loading default`); + logger.warn(`Could not find locale ${region}_${language}! Loading default`); return getDefaultLocale(); } @@ -57,15 +26,7 @@ function getDefaultLocale(locale='default') { return require(`${__dirname}/../locales/${locale}.json`); } -function generateRandomInt(length = 4) { - return Math.floor(Math.pow(10, length-1) + Math.random() * 9 * Math.pow(10, length-1)); -} - module.exports = { - send404, - templateReadyUser, - getLocales, getLocale, - getDefaultLocale, - generateRandomInt + getDefaultLocale }; \ No newline at end of file diff --git a/locales/US_en.json b/locales/US_en.json index ed012dd..90b1d31 100644 --- a/locales/US_en.json +++ b/locales/US_en.json @@ -1,14 +1,6 @@ { "nav": { - "brand": "Pretendo", - "links": { - "news": "News", - "progress": "Progress", - "contact": "Contact", - "login": "Login", - "register": "Register", - "logout": "Logout" - } + "brand": "Pretendo" }, "home": { "header": { @@ -16,117 +8,16 @@ "text": "An open source Nintendo Network replacement service" } }, - "progress": { - "summary": { - "caption": "All in one", - "title": "Progress Summary", - "text": "We should probably pull this from a database ngl" - }, - "compatibility": { - "caption": "Useful info", - "title": "Game Compatibility" - }, - "misc": { - "caption": "Less useful info", - "title": "Other" - } - }, - "news": { - "caption": "Read up", - "title": "All news", - "button_text": "Read more" - }, - "contact": { - "caption": "Have a question?", - "title": "Contact Us", - "button_text": "Send Message", - "email_placeholder": "email@provider.com", - "subject_placeholder": "Subject", - "message_placeholder": "Message" - }, - "login": { - "card": { - "caption": "Sign in", - "title": "Login", - "email_text": "Username or Email", - "password_text": "Password", - "button_text": "Sign In", - "forgotpass_introduction": "Forgot password?", - "forgotpass_text": "Click here to reset it.", - "link_introduction": "Don't have an account yet?", - "link_text": "Click here to register." - } - }, - "register": { - "card": { - "title": "Register", - "birthdate_text": "Birthday", - "gender_text": "Gender", - "email_text": "Email Address", - "username_text": "Username", - "password_text": "Password", - "password_confirm_text": "Confirm Password", - "caption": "Sign Up", - "button_text": "Sign up", - "link_introduction": "Already have an account?", - "link_text": "Click here to login." - } - }, - "password": { - "card": { - "caption": "Forgot password?", - "title": "Reset password", - "password_text": "New password", - "password_confirm_text": "Confirm password", - "button_text": "Reset password" - } - }, - "forgot": { - "card": { - "caption": "Did you forget something?", - "title": "Forgot password", - "email_text": "Email address", - "button_text": "Send email" - } - }, "about": { "caption": "What is this?", "title": "About", - "text": "Pretendo is an open source Nintendo Network replacement that aims to build custom servers for the WiiU and 3DS/2DS family of consoles. Our goal is to preserve the online functionality of these consoles, to allow players to continue to play their favorite WiiU and 3DS/2DS games to their fullest capacity." + "text": "Pretendo is an open source Nintendo Network replacement that aims to build custom servers for the WiiU and 3DS family of consoles. Our goal is to preserve the online functionality of these consoles, to allow players to continue to play their favorite WiiU and 3DS games to their fullest capacity." }, "credits": { - "caption": "Who are responsible?", + "caption": "The people responsible", "title": "Credits" }, - "latest_news": { - "caption": "Catch up", - "title": "Latest news", - "description": "Pretendo is constantly evolving to create the best possible servers. We release posts to showcase what we have been working on and how far we got with certain things.", - "button_text": "All posts", - "news_button_text": "Read more" - }, - "errors": { - "invalid_login": "Invalid username/password combination", - "account_exists": "An account with that username already exists!" - }, - "verify_email_popup": { - "text": "Your email has not been verified yet. You are restricted from certain features.", - "change_button_text": "Change email", - "repeat_button_text": "Send again" - }, - "dashboard": { - "navigation": { - "links": { - "account": "Account", - "soon": "Coming soon" - } - }, - "account": { - "caption": "Pretendo Network ID", - "title": "Account information" - } - }, "footer": { - "text": "Copyright 2019 PretendoNetwork - Site designed and developed by MrJVS, ben and Jip" + "text": "Copyright 2020 PretendoNetwork - Site designed and developed by mrjvs, ben and jip" } } \ No newline at end of file diff --git a/locales/default.json b/locales/default.json index a539797..2b7f470 100644 --- a/locales/default.json +++ b/locales/default.json @@ -1,14 +1,6 @@ { "nav": { - "brand": "ERROR", - "links": { - "news": "ERROR", - "progress": "ERROR", - "contact": "ERROR", - "login": "ERROR", - "register": "ERROR", - "logout": "ERROR" - } + "brand": "ERROR" }, "home": { "header": { @@ -16,60 +8,15 @@ "text": "ERROR" } }, - "progress": { - "summary": { - "title": "ERROR", - "text": "ERROR" - }, - "compatability": { - "title": "ERROR" - }, - "misc": { - "title": "ERROR" - } - }, - "contact": { - "title": "ERROR", - "button_text": "ERROR", - "email_placeholder": "ERROR", - "subject_placeholder": "ERROR", - "message_placeholder": "ERROR" - }, - "login": { - "card": { - "title": "ERROR", - "email_text": "ERROR", - "password_text": "ERROR", - "email_placeholder": "ERROR", - "password_placeholder": "ERROR", - "button_text": "Sign In" - } - }, - "register": { - "card": { - "title": "ERROR", - "birthdate_text": "ERROR", - "gender_text": "ERROR", - "email_text": "ERROR", - "username_text": "ERROR", - "password_text": "ERROR", - "password_confirm_text": "ERROR", - "email_placeholder": "ERROR", - "password_placeholder": "ERROR", - "caption": "ERROR" - } - }, "about": { + "caption": "ERROR", "title": "ERROR", "text": "ERROR" }, "credits": { + "caption": "ERROR", "title": "ERROR" }, - "errors": { - "invalid_login": "ERROR", - "account_exists": "ERROR" - }, "footer": { "text": "ERROR" } diff --git a/logger.js b/logger.js index 327e92d..cb37729 100644 --- a/logger.js +++ b/logger.js @@ -1,41 +1,54 @@ -const winston = require('winston'); +const fs = require('fs-extra'); +require('colors'); -const logger = winston.createLogger({ - level: 'verbose', - format: winston.format.combine( - winston.format.timestamp(), - winston.format.printf(log => { - return `${log.timestamp} | ${log.level}: ${log.message}`; - }) - ), - transports: [ - new winston.transports.Console({ colorize: true }), - new winston.transports.File({ - colorize: false, - json: false, - filename: `${__dirname}/logs/events.log` - }), - new winston.transports.File({ - colorize: false, - json: false, - filename: `${__dirname}/logs/error.log`, - level: 'error' - }), - new winston.transports.File({ - colorize: false, - json: false, - filename: `${__dirname}/logs/warn.log`, - level: 'warn' - }), - new winston.transports.File({ - colorize: false, - json: false, - filename: `${__dirname}/logs/debug.log`, - level: 'debug' - }) - ] -}); +class Logger { + constructor(root = '') { + fs.ensureDirSync(`${root}/logs`); -winston.add(logger); + this.root = root; + this.streams = { + latest: fs.createWriteStream(`${this.root}/logs/latest.log`), + success: fs.createWriteStream(`${this.root}/logs/success.log`), + error: fs.createWriteStream(`${this.root}/logs/error.log`), + warn: fs.createWriteStream(`${this.root}/logs/warn.log`), + info: fs.createWriteStream(`${this.root}/logs/info.log`) + }; + } + -module.exports = winston; \ No newline at end of file + success(input) { + const time = new Date(); + input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [SUCCESS]: ${input}`; + this.streams.success.write(`${input}\n`); + + console.log(`${input}`.green.bold); + } + + error(input) { + const time = new Date(); + input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [ERROR]: ${input}`; + this.streams.error.write(`${input}\n`); + + console.log(`${input}`.red.bold); + } + + warn(input) { + const time = new Date(); + input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [WARN]: ${input}`; + this.streams.warn.write(`${input}\n`); + + console.log(`${input}`.yellow.bold); + } + + info(input) { + const time = new Date(); + input = `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}] [INFO]: ${input}`; + this.streams.info.write(`${input}\n`); + + console.log(`${input}`.cyan.bold); + } +} + +const logger = new Logger(__dirname); + +module.exports = logger; \ No newline at end of file diff --git a/middleware/authentication.js b/middleware/authentication.js deleted file mode 100644 index 54fb7a4..0000000 --- a/middleware/authentication.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - -admin-authentication.js - -Middleware file for authentication checking - -*/ - -// imports -const apiHelper = require('../helpers/api'); - -// middleware to use if admin authentication is required -function adminAuthNeeded(req, res, next) { - if (req.isAuthenticated() && req.user.role && req.user.role === 'admin') { - return next(); - } else { - apiHelper.sendApiAuthError(res); - } -} - -// middleware to use if pnid auth authentication is required -function pnidApiAuthNeeded(req, res, next) { - if (req.isAuthenticated() && !req.user.role) { // having no role means its a normal account. only admin accounts have roles - return next(); - } else { - apiHelper.sendApiAuthError(res); - } -} - -// middleware to use if pnid authentication is required -function pnidAuthNeeded(req, res, next) { - if (req.isAuthenticated() && !req.user.role) { // having no role means its a normal account. only admin accounts have roles - return next(); - } else { - res.redirect('/pnid/login'); - } -} - -// middleware to use if authentication is optional -function authOptional(req, res, next) { - return next(); -} - -module.exports = { - adminAuthNeeded, - pnidAuthNeeded, - pnidApiAuthNeeded, - authOptional -}; \ No newline at end of file diff --git a/models/admin-user.js b/models/admin-user.js deleted file mode 100644 index 84a7127..0000000 --- a/models/admin-user.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - -admin-user.js - -file containing the model file for admin user - -*/ - -// imports -const mongoose = require('mongoose'); -const uniqueValidator = require('mongoose-unique-validator'); -const bcrypt = require('bcrypt'); - -// admin user database layout -const adminUserSchema = new mongoose.Schema({ - username: { - type: String, - required: [true, 'Username is required.'], - minlength: [1, 'Username must be at-least 1 character.'], - maxlength: [42, 'Username cannot be more than 42 characters long.'], - unique: true, - trim: true - }, - // non hashed, gets hashed at save - password: { - type: String, - required: [true, 'Password is required.'], - minlength: [7, 'Password must be at-least 7 characters.'], - maxlength: [256, 'Password cannot be more than 256 characters long.'], - trim: true - }, - role: { - type: String, - required: true, - default: 'admin' - } -}); - -adminUserSchema.plugin(uniqueValidator, {message: '{PATH} already in use.'}); - -// hashing password -adminUserSchema.pre('save', function(next) { - // only if modified - if (!this.isModified('password')) { - return next(); - } - - // hashing - bcrypt.hash(this.get('password'), 10, (err, hash) => { - if (err) { - return next(err); - } - - this.set('password', hash); - next(); - }); -}); - -adminUserSchema.statics.findByUsername = function(username) { - return this.model('adminUser').findOne({ - username - }); -}; - -const adminUserModel = mongoose.model('adminUser', adminUserSchema); - -module.exports = { - adminUserModel, - adminUserSchema -}; \ No newline at end of file diff --git a/models/blog-post.js b/models/blog-post.js deleted file mode 100644 index b2ccce5..0000000 --- a/models/blog-post.js +++ /dev/null @@ -1,105 +0,0 @@ -/* - -blog-post.js - -file containing the model file for a blog post - -*/ - -// imports -const mongoose = require('mongoose'); -const postAuthor = require('./post-author').postAuthorModel; -const showdown = require('showdown'); -const moment = require('moment'); -const converter = new showdown.Converter(); -converter.setFlavor('github'); - -// admin user database layout -const blogPostSchema = new mongoose.Schema({ - // html in content - content: { - type: String, - required: [true, 'Content is required.'], - trim: true - }, - // title of blog post - name: { - type: String, - required: [true, 'Name is required'] - }, - // short description of blog post - short: { - type: String, - required: [true, 'Short version is required'] - }, - meta: { - slug: { - type: String, - required: [true, 'Author is required'], - trim: true - }, - author: { - type: String, - required: [true, 'Author is required'], - trim: true - }, - date: { - type: Date, - default: () => { - return moment(moment().format('YYYY-MM-DD')); - } - }, - category: { - type: String, - required: [true, 'category is required'], - trim: true - } - } -}); - -blogPostSchema.methods.postTemplate = function(callback) { - const self = this; - postAuthor.findById(this.meta.author, function (err, author) { - callback(err, { - content: self.content, - title: self.name, - date: self.meta.date, - dateString: moment(self.meta.date).format('YYYY-MM-DD'), - category: self.meta.category, - author: author.authorTemplate() - }); - }); -}; -blogPostSchema.methods.postShortTemplate = function() { - return { - content: this.short, - title: this.name, - url: moment(this.meta.date).format('YYYY-MM-DD') + '/' + this.meta.slug - }; -}; - -blogPostSchema.statics.markdownToHtml = function(markdown) { - return converter.makeHtml(markdown); -}; -blogPostSchema.statics.getPost = function(date, slug, callback) { - return blogPostModel.findOne({ - 'meta.date': date, - 'meta.slug': slug - }, callback); -}; - -blogPostSchema.statics.latestPostsShortTemlate = function(amount, callback) { - blogPostModel.find({}).sort({'meta.date': 'desc'}).exec(function(err, posts) { - if (err) return callback(err); - const out = []; - for (let i = 0, l = posts.length; i < ( amount+1 < l ? amount : l); i++) - out.push(posts[i].postShortTemplate()); - callback(err, out); - }); -}; - -const blogPostModel = mongoose.model('blogPost', blogPostSchema); - -module.exports = { - blogPostModel, - blogPostSchema -}; \ No newline at end of file diff --git a/models/pnid.js b/models/pnid.js deleted file mode 100644 index 4f161d8..0000000 --- a/models/pnid.js +++ /dev/null @@ -1,184 +0,0 @@ -/* - -pnid.js - -file containing the model for pretendo network id's - -*/ - -// imports -const mongoose = require('mongoose'); -const uniqueValidator = require('mongoose-unique-validator'); -const randtoken = require('rand-token'); -const bcrypt = require('bcrypt'); -const utilHelper = require('../helpers/util'); - -// admin user database layout -const PNIDSchema = new mongoose.Schema({ - email: { - type: String, - required: [true, 'Email is required.'], - unique: true, - trim: true, - uppercase: true, - validate: [validateEmail, 'Please fill a valid email address'] - }, - email_validated: { - type: Boolean, - default: false - }, - email_validation_code: { - type: Number, - required: [true, 'Email validation code is required.'], - }, - email_validation_token: { - type: String, - required: [true, 'Email validation token is required.'], - }, - // non hashed, gets hashed at save - password: { - type: String, - required: [true, 'Password is required.'], - minlength: [7, 'Password must be at-least 7 characters.'], - maxlength: [256, 'Password cannot be more than 256 characters long.'], - trim: true - }, - pnid: { - pid: { - type: Number, - unique: true - }, - username: { - type: String, - unique: true, - validate: [validateUsername, 'Please fill a valid username'], - required: true - }, - username_lower: { - type: String, - unique: true - }, - avatar_url: { - type: String, - default: '/assets/images/default_avatar.png' - } - }, - consoles: [] -}); - -function validateEmail(email) { - // eslint throws "unnecesary character escape" - const re = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/; // eslint-disable-line - return re.test(email); -} - -function validateUsername(username) { - // eslint throws "unnecesary character escape" - const re = /^[a-zA-Z0-9]+([_ -]?[a-zA-Z0-9])*$/; // eslint-disable-line - return re.test(username); -} - -PNIDSchema.plugin(uniqueValidator, {message: '{PATH} already in use.'}); - -// hashing password -PNIDSchema.pre('save', function(next) { - // only if modified - if (!this.isModified('password')) { - return next(); - } - // hashing - const primaryhash = PNIDModel.hashPasswordPrimary(this.get('password'), this.get('pnid.pid')); - bcrypt.hash(primaryhash, 10, (err, hash) => { - if (err) { - return next(err); - } - - this.set('password', hash); - next(); - }); -}); - -PNIDSchema.statics.findByEmail = function(email) { - return this.model('pnid').findOne({ - email: email.toUpperCase() - }); -}; - -PNIDSchema.statics.findUser = async function(key) { - const user = await this.model('pnid').findOne({ - email: key.toUpperCase() - }); - if (!user) { - return await this.model('pnid').findOne({ - 'pnid.username_lower': key.toLowerCase() - }); - } - return user; -}; - -PNIDSchema.statics.hashPasswordPrimary = function(password, pid) { - const buff1 = require('python-struct').pack('= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.5", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "minipass": { - "version": "2.3.4", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "bundled": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true - } - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true - }, - "needle": { - "version": "2.2.3", - "bundled": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.11.0", - "bundled": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.5", - "bundled": true - }, - "npm-packlist": { - "version": "1.1.11", - "bundled": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } - } - }, - "readable-stream": { - "version": "2.3.5", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true - }, - "sax": { - "version": "1.2.4", - "bundled": true - }, - "semver": { - "version": "5.5.1", - "bundled": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.0.3", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - }, - "tar": { - "version": "4.4.6", - "bundled": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.3", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "bundled": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - } - } - }, "binary-extensions": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", "dev": true }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } }, "boxen": { "version": "1.3.0", @@ -802,52 +351,11 @@ } } }, - "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==" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, "buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" - }, - "busboy": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", - "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", - "requires": { - "dicer": "0.2.5", - "readable-stream": "1.1.x" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true }, "bytes": { "version": "3.0.0", @@ -886,28 +394,12 @@ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "optional": true - }, "capture-stack-trace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", "dev": true }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", @@ -926,24 +418,602 @@ "dev": true }, "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", "glob-parent": "^3.1.0", - "inherits": "^2.0.1", + "inherits": "^2.0.3", "is-binary-path": "^1.0.0", "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", + "normalize-path": "^3.0.0", "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "fsevents": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + } } }, "ci-info": { @@ -1002,30 +1072,6 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "optional": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "optional": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -1086,6 +1132,12 @@ "text-hex": "1.0.x" } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -1097,17 +1149,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", @@ -1122,35 +1163,6 @@ "xdg-basedir": "^3.0.0" } }, - "connect-mongo": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-2.0.1.tgz", - "integrity": "sha512-ghBvVq0SA0SkTFsbAB8HdF1+uoHdFJICSlrTklNloMKXuRpX9IuVBnG0DlKnXBZSQI0Joyaq22cazsrV9+5g2A==", - "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-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" - } - } - } - }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -1182,11 +1194,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "crc": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", - "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=" - }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -1200,6 +1207,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -1334,38 +1342,6 @@ "kuler": "1.0.x" } }, - "dicer": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", - "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", - "requires": { - "readable-stream": "1.1.x", - "streamsearch": "0.1.2" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -1395,6 +1371,11 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, "enabled": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", @@ -1413,11 +1394,6 @@ "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" }, - "es6-promise": { - "version": "3.2.1", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1530,10 +1506,21 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "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 + } + } }, "eslint-visitor-keys": { "version": "1.0.0", @@ -1596,6 +1583,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, "requires": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", @@ -1725,27 +1713,6 @@ "promise": "^7.0.0" } }, - "express-recaptcha": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/express-recaptcha/-/express-recaptcha-4.0.3.tgz", - "integrity": "sha512-DUNGjloA7pDeTT//CP0Dv/gZmYU+Nv/ZL/KPHKsNknI2m1epFTc9BFR/oDdmsP1pklNJEZ4wQtDoeaiFYZK2hw==" - }, - "express-session": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", - "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "crc": "3.4.4", - "debug": "2.6.9", - "depd": "~1.1.1", - "on-headers": "~1.0.1", - "parseurl": "~1.3.2", - "uid-safe": "~2.1.5", - "utils-merge": "1.0.1" - } - }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -1907,6 +1874,13 @@ "object-assign": "^4.0.1" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -1945,11 +1919,11 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "requires": { - "locate-path": "^2.0.0" + "locate-path": "^3.0.0" } }, "flat-cache": { @@ -2010,554 +1984,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - } - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2570,14 +1996,15 @@ "dev": true }, "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true }, "get-value": { "version": "2.0.6", @@ -2688,14 +2115,31 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "handlebars": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", - "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.2.tgz", + "integrity": "sha512-4PwqDL2laXtTWZghzzCtunQUTLbo31pcCJrd/B/9JP8XbhVzpS5ZXuKqlOzsd1rtcaLo4KqAn8nl8mkknS4MHw==", "requires": { - "async": "^1.4.0", + "neo-async": "^2.6.0", "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "uglify-js": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.6.tgz", + "integrity": "sha512-yYqjArOYSxvqeeiYH2VGjZOqq6SVmhxzaPjJC1W2F9e+bqvFL9QXQ2osQuKUFjM2hGjKG2YclQnRKWQSt/nOTQ==", + "optional": true, + "requires": { + "commander": "~2.20.3", + "source-map": "~0.6.1" + } + } } }, "has-flag": { @@ -2829,11 +2273,6 @@ "through": "^2.3.6" } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, "ipaddr.js": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", @@ -2865,7 +2304,8 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true }, "is-ci": { "version": "1.2.1", @@ -3037,7 +2477,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "isobject": { "version": "3.0.1", @@ -3052,9 +2493,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "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", @@ -3081,15 +2522,11 @@ "graceful-fs": "^4.1.6" } }, - "kareem": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", - "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -3111,20 +2548,6 @@ "package-json": "^4.0.0" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "optional": true - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -3136,34 +2559,18 @@ } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "requires": { - "p-locate": "^2.0.0", + "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.foreach": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", - "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "logform": { "version": "1.10.0", @@ -3189,17 +2596,6 @@ } } }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "optional": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -3210,6 +2606,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -3252,20 +2649,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "memory-pager": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.1.0.tgz", - "integrity": "sha512-Mf9OHV/Y7h6YWDxTzX/b4ZZ4oh9NSXblQL8dtPCOomOtZciEHxePR78+uHFLLlsk01A6jVHhHsQZZ/WcIPpnzg==", - "optional": true - }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -3326,7 +2709,8 @@ "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==" + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true }, "minimatch": { "version": "3.0.4", @@ -3342,9 +2726,9 @@ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -3366,6 +2750,7 @@ "version": "0.5.1", "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, "requires": { "minimist": "0.0.8" }, @@ -3373,103 +2758,11 @@ "minimist": { "version": "0.0.8", "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true } } }, - "moment": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" - }, - "mongodb": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.6.tgz", - "integrity": "sha512-E5QJuXQoMlT7KyCYqNNMfAkhfQD79AT4F8Xd+6x37OX+8BL17GyXyWvfm6wuyx4wnzCCPoCSLeMeUN2S7dU9yw==", - "requires": { - "mongodb-core": "3.1.5", - "safe-buffer": "^5.1.2" - }, - "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==" - } - } - }, - "mongodb-core": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.5.tgz", - "integrity": "sha512-emT/tM4ZBinqd6RZok+EzDdtN4LjYJIckv71qQVOEFmvXgT5cperZegVmTgox/1cx4XQu6LJ5ZuIwipP/eKdQg==", - "requires": { - "bson": "^1.1.0", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" - }, - "dependencies": { - "bson": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", - "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" - }, - "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==" - } - } - }, - "mongoose": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.3.2.tgz", - "integrity": "sha512-07fpCMqvCiSdKXIygt3aAeNFJYjQPjDXILbwBEmF0e8gy2hSKMNuP5QG4J6L8m9BhjVxcvoLiPzaGKN7I/7lLg==", - "requires": { - "async": "2.6.1", - "bson": "~1.0.5", - "kareem": "2.3.0", - "lodash.get": "4.4.2", - "mongodb": "3.1.6", - "mongodb-core": "3.1.5", - "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.5.1", - "mquery": "3.2.0", - "ms": "2.0.0", - "regexp-clone": "0.0.1", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "requires": { - "lodash": "^4.17.10" - } - }, - "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==" - } - } - }, - "mongoose-legacy-pluralize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", - "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" - }, - "mongoose-unique-validator": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mongoose-unique-validator/-/mongoose-unique-validator-2.0.2.tgz", - "integrity": "sha512-gbKFiEzWQi8wZvZFeeEkx4nCV1qWaeRoQBNm+672+h54/0u/Y8rSdNubScn/1H2ScCPO55asDow+OXq67RQDmg==", - "requires": { - "lodash.foreach": "^4.1.0", - "lodash.get": "^4.0.2" - } - }, "morgan": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", @@ -3482,69 +2775,17 @@ "on-headers": "~1.0.1" } }, - "mpath": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.5.1.tgz", - "integrity": "sha512-H8OVQ+QEz82sch4wbODFOz+3YQ61FYz/z3eJ5pIdbMEaUzDqA268Wd+Vt4Paw9TJfvDgVKaayC0gBzMIw2jhsg==" - }, - "mquery": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz", - "integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==", - "requires": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "0.0.1", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "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==" - } - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "multer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.1.tgz", - "integrity": "sha512-zzOLNRxzszwd+61JFuAo0fxdQfvku12aNJgnla0AQ+hHxFmfc/B7jBVuPr5Rmvu46Jze/iJrFpSOsD7afO8SDw==", - "requires": { - "append-field": "^1.0.0", - "busboy": "^0.2.11", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.1", - "on-finished": "^2.3.0", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - } - }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, - "nan": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", - "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==" - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -3583,17 +2824,17 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "nodemailer": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.7.0.tgz", - "integrity": "sha512-IludxDypFpYw4xpzKdMAozBSkzKHmNBvGanUREjJItgJ2NYcK/s8+PggVhj7c2yGFQykKsnnmv1+Aqo0ZfjHmw==" - }, "nodemon": { "version": "1.18.6", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.6.tgz", @@ -3651,19 +2892,16 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, "requires": { "path-key": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true }, "object-copy": { "version": "0.1.0", @@ -3787,16 +3025,6 @@ } } }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -3806,28 +3034,29 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "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==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.0.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=" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-json": { "version": "4.0.1", @@ -3852,28 +3081,6 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, - "passport": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", - "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", - "requires": { - "passport-strategy": "1.x.x", - "pause": "0.0.1" - } - }, - "passport-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", - "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", - "requires": { - "passport-strategy": "1.x.x" - } - }, - "passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" - }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -3899,18 +3106,14 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, - "pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" - }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -3959,7 +3162,8 @@ "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=" + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true }, "progress": { "version": "2.0.0", @@ -3987,7 +3191,8 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true }, "pstree.remy": { "version": "1.1.2", @@ -4001,29 +3206,11 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "python-struct": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/python-struct/-/python-struct-1.0.6.tgz", - "integrity": "sha512-r40v2MDFZKNBECMuo/oih6wInNEFXX0gmQgCJH4R7VULJsQDwcE95004r7A8iy1tDipgcZDyF8H6Tc2bhJdRZQ==", - "requires": { - "long": "^3.2.0" - } - }, "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, - "rand-token": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/rand-token/-/rand-token-0.4.0.tgz", - "integrity": "sha512-FLNNsir2R+XY8LKsZ+8u/w0qZ4sGit7cpNdznsI77cAVob6UlVPueDKRyjJ3W1Q6FJLgAVH98JvlqqpSaL7NEQ==" - }, - "random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" - }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -4053,6 +3240,7 @@ "version": "2.2.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "dev": true, "requires": { "buffer-shims": "~1.0.0", "core-util-is": "~1.0.0", @@ -4084,11 +3272,6 @@ "safe-regex": "^1.1.0" } }, - "regexp-clone": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", - "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" - }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -4129,7 +3312,8 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true }, "require-directory": { "version": "2.1.1", @@ -4137,9 +3321,9 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "require-uncached": { "version": "1.0.3", @@ -4159,20 +3343,6 @@ } } }, - "require_optional": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", - "requires": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" - } - }, - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" - }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -4195,15 +3365,6 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "optional": true, - "requires": { - "align-text": "^0.1.1" - } - }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -4267,19 +3428,11 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "saslprep": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz", - "integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==", - "optional": true, - "requires": { - "sparse-bitfield": "^3.0.3" - } - }, "semver": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==" + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "dev": true }, "semver-diff": { "version": "2.1.0", @@ -4327,9 +3480,9 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -4358,6 +3511,7 @@ "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" } @@ -4365,43 +3519,66 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true }, "showdown": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.8.6.tgz", - "integrity": "sha1-kepO47elRIqspoIKTifmkMatdxw=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz", + "integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==", "requires": { - "yargs": "^10.0.3" + "yargs": "^14.2" }, "dependencies": { - "cliui": { + "ansi-regex": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "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==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" } }, "yargs": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", - "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz", + "integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==", "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^8.1.0" + "y18n": "^4.0.0", + "yargs-parser": "^15.0.0" } } } @@ -4409,7 +3586,8 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true }, "simple-swizzle": { "version": "0.2.2", @@ -4428,11 +3606,6 @@ "is-fullwidth-code-point": "^2.0.0" } }, - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -4541,14 +3714,6 @@ "kind-of": "^3.2.0" } }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": ">=0.0.4" - } - }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", @@ -4568,15 +3733,6 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, - "sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", - "optional": true, - "requires": { - "memory-pager": "^1.0.2" - } - }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -4623,15 +3779,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" - }, "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": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -4641,6 +3793,7 @@ "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==", + "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -4649,6 +3802,7 @@ "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" } @@ -4656,7 +3810,8 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true }, "strip-json-comments": { "version": "2.0.1", @@ -4797,44 +3952,6 @@ "mime-types": "~2.1.18" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "optional": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "optional": true - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "optional": true - }, - "uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "requires": { - "random-bytes": "~1.0.0" - } - }, "undefsafe": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", @@ -4845,38 +3962,15 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unique-string": { @@ -4944,12 +4038,6 @@ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", "dev": true }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true - }, "update-notifier": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", @@ -5017,6 +4105,7 @@ "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" } @@ -5035,12 +4124,6 @@ "string-width": "^2.1.1" } }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "optional": true - }, "winston": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.1.0.tgz", @@ -5138,43 +4221,36 @@ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" }, "dependencies": { "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^4.1.0" } } } @@ -5210,45 +4286,30 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true }, "yargs-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" }, "dependencies": { "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" } } } diff --git a/package.json b/package.json index 374532d..0c359a0 100644 --- a/package.json +++ b/package.json @@ -15,25 +15,12 @@ ], "license": "ISC", "dependencies": { - "bcrypt": "^3.0.1", "colors": "^1.1.2", - "connect-mongo": "^2.0.1", "express": "^4.16.2", "express-handlebars": "^3.0.0", - "express-recaptcha": "^4.0.3", - "express-session": "^1.15.6", "fs-extra": "^7.0.1", - "moment": "^2.22.2", - "mongoose": "^5.3.2", - "mongoose-unique-validator": "^2.0.2", "morgan": "^1.9.1", - "multer": "^1.4.1", - "nodemailer": "^4.7.0", - "passport": "^0.4.0", - "passport-local": "^1.0.0", - "python-struct": "^1.0.6", - "rand-token": "^0.4.0", - "showdown": "^1.8.6", + "showdown": "^1.9.1", "winston": "^3.1.0" }, "devDependencies": { diff --git a/passport.config.js b/passport.config.js deleted file mode 100644 index f1722d9..0000000 --- a/passport.config.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - -passport.config.js - -Passport setup file. handles authentication strategy and session setup - -*/ - -// imports -const LocalStrategy = require('passport-local').Strategy; -const passport = require('passport'); -const bcrypt = require('bcrypt'); -const adminUserModel = require('./models/admin-user').adminUserModel; -const PNIDModel = require('./models/pnid').PNIDModel; - -// setup authentication -module.exports = (app) => { - app.use(passport.initialize()); - app.use(passport.session()); - passport.use('adminUserStrategy', new LocalStrategy( - - (username, password, done) => { - // find user in database - adminUserModel.findByUsername(username).then((user) => { - if (!user) { - // user doesnt exist - return done(null, false, {message: 'Incorrect user'}); - } - - bcrypt.compare(password, user.password, (err, res) => { - if (err || !res) { - // error comparing hashes - return done(null, false, {message: 'Incorrect password'}); - } - - // password is correct, return user - return done(null, user); - - }); - }).catch((err) => { - if (err) { - // error finding in database - return done(null, false, {code: 500}); - } - }); - } - )); - passport.use('PNIDStrategy', new LocalStrategy({ - usernameField: 'email' - }, (email, password, done) => { - // find user in database, email = username or email - PNIDModel.findUser(email).then((user) => { - if (!user) { - // user doesnt exist - return done(null, false, {message: 'Incorrect email'}); - } - bcrypt.compare(password, user.password, (err, res) => { - if (err || !res) { - // error comparing hashes - // try primary hash on password and checking again. - bcrypt.compare(PNIDModel.hashPasswordPrimary(password, user.pnid.pid), user.password, (err, res) => { - if (err || !res) { - // error comparing hashes - // password hashed and non hashed both incorrect. - return done(null, false, {message: 'Incorrect password'}); - } - // password is correct, return user - return done(null, user); - }); - } else { - // password is correct, return user - return done(null, user); - } - }); - }).catch((err) => { - if (err) { - // error finding in database - return done(null, false, {code: 500}); - } - }); - } - )); - - //Configuring app to have sessions, dont change since it would break everything - passport.serializeUser(function(user, done) { - done(null, user.id); - }); - - //SERIOUSLY. DONT TOUCH THIS SPAGHETTI, IT TOOK ME FOREVER TO GET THIS TO WORK!!!!1!! - passport.deserializeUser(function(id, done) { - adminUserModel.findById(id, function(err, user) { - if (err || !user) { - PNIDModel.findById(id, function(err, user) { - done(err, user); - }); - } else { - done(err, user); - } - }); - }); -}; diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index 90ef44c..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,6 +0,0 @@ -User-agent: * -Disallow: /api/ -Disallow: /admin -Disallow: /admin/ -Disallow: /pnid/dashboard -Disallow: /pnid/dashboard/ \ No newline at end of file diff --git a/routes/admin.js b/routes/admin.js deleted file mode 100644 index c7271b1..0000000 --- a/routes/admin.js +++ /dev/null @@ -1,494 +0,0 @@ -/* - -admin.js - -file for handling admin api. - -*/ - -// imports -const router = require('express').Router(); -const passport = require('passport'); -const moment = require('moment'); -const apiHelper = require('../helpers/api'); -const userMiddleware = require('../middleware/authentication'); - -// database models -const adminUser = require('../models/admin-user'); -const blogPost = require('../models/blog-post'); -const postAuthor = require('../models/post-author'); -const progressList = require('../models/progress-list'); - -// renders admin.hbs -router.get('/admin', (request, response) => { - response.render('admin', { - title: 'Pretendo | Admin', - description: '', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - }); -}); - -/* -* /admin/api/v1/login -* -* signs admin user in -* -* post { -* username -* password -* } -* return { -* code: http code -* success: boolean -* username: undefined | string - only if login was successfull -* role: undefined | string - role of user if login was successfull -* errors: Strings[messages] - not yet :( -* } -*/ -// TODO make login somehow display errors in correct format. -// middleware does the authentication work. this just returns a success -router.post('/admin/api/v1/login', passport.authenticate('adminUserStrategy'), (request, response) => { - const user = request.user; - - return apiHelper.sendReturn(response, { - username: user.username, - role: user.role ? user.role : undefined - }); -}); - -/* -* /admin/api/v1/register -* - requires admin auth -* -* registers a new admin user -* -* post { -* username - username of new admin account -* password - password of new admin account -* } -* return { -* code: httpcode -* success: boolean - true if register was successull -* username: undefined | string - username if register was successfull -* role: undefined | string - role of user if register was successfull -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/register', userMiddleware.adminAuthNeeded, (request, response) => { - if (!request.body) { - // no post body - return apiHelper.sendApiGenericError(response); - } - - const { username, password } = request.body; - const newUser = new adminUser.adminUserModel({ - username, - password - }); - - // saving to database - newUser.save().then((user) => { - return apiHelper.sendReturn(response, { - username: user.username, - role: user.role ? user.role : undefined - }); - }).catch((rejection) => { - // TODO format exception so it doesnt have a huge list of errors - return apiHelper.sendApiError(response, 500, [rejection]); - }); -}); - -/* -* /admin/api/v1/removeadmin -* - requires admin auth -* -* registers a new admin user -* -* post { -* id - id of the admin user -* } -* return { -* code: httpcode -* success: boolean - true if delete was successull -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/removeadmin', userMiddleware.adminAuthNeeded, (request, response) => { - if (!request.body) { - // no post body - return apiHelper.sendApiGenericError(response); - } - - const { id } = request.body; - adminUser.adminUserModel.findByIdAndDelete(id, (error) => { - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - // successfull - return apiHelper.sendReturn(response, {}); - }); -}); - -/* -* /admin/api/v1/listadmins -* - requires admin auth -* -* gets list of admins -* -* return { -* code: httpcode -* success: boolean - true if delete was successull -* errors: Strings[messages] -* } -*/ -router.get('/admin/api/v1/listadmins', userMiddleware.adminAuthNeeded, (request, response) => { - adminUser.adminUserModel.find({}, (error, admins) => { - // TODO format exception so it doesnt have a huge list of errors - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - - // formats admin list and removes password hash - const output = []; - for (let i = 0, l = admins.length; i < l; i++) { - admins[i].password = undefined; - output.push(admins[i]); - } - - return apiHelper.sendReturn(response, { - admins: output - }); - }); -}); - -/* -* /admin/api/v1/check -* -* checks if admin logged in -* -* return { -* code: httpcode -* success: boolean - true if request was without errors -* isAuthed: boolean - true if logged in -* role: undefined | string - returns user role -* errors: Strings[messages] -* } -*/ -router.get('/admin/api/v1/check', userMiddleware.authOptional, (request, response) => { - const user = request.user; - - return apiHelper.sendReturn(response, { - isAuthed: user ? true : false, - role: user ? (user.role ? user.role : undefined) : undefined - }); -}); - -/* -* /admin/api/v1/logout -* -* logs out admin user -* -* return { -* code: httpcode -* success: boolean - true if logout is successfull -* errors: Strings[messages] -* } -*/ -router.get('/admin/api/v1/logout', userMiddleware.adminAuthNeeded, (request, response) => { - request.logout(); - return apiHelper.sendReturn(response, {}); -}); - -/* -* /admin/api/v1/newpost -* -* posts a new blog post -* -* post { -* content - content of the blog post in markdown -* title - title of the blog post -* author - id of the author -* short - short description of content in plain text -* category - category name of the blog post -* -* } -* return { -* code: http code -* success: boolean - true if login succesfull -* url: string | undefined - url of the blog post if successfull -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/newpost', userMiddleware.adminAuthNeeded, (request, response) => { - - if (!request.body) { - return apiHelper.sendApiGenericError(response); - } - - const { content, title, author, category, short } = request.body; - const newBlogPost = new blogPost.blogPostModel({ - content: blogPost.blogPostModel.markdownToHtml(content), - name: title, - short, - meta: { - author, - category, - slug: title // convert title to slug - .trim() - .replace(/\s/g, '-') - .replace(/[^A-z0-9-]/g, '') - .toLowerCase() - } - }); - - // saving post to database - newBlogPost.save().then((post) => { - return apiHelper.sendReturn(response, { - url: moment(post.meta.date).format('YYYY-MM-DD') + '/' + post.meta.slug - }); - }).catch((rejection) => { - // TODO format exception so it doesnt have a huge list of errors - return apiHelper.sendApiError(response, 500, [rejection]); - }); -}); - -/* -* /admin/api/v1/editpost -* -* edits a blog post -* -* post { -* id - id of the blog post to be edited -* content - content of the blog post IN HTML -* title - title of the blog post -* author - id of the author -* short - short description of content in plain text -* category - category name of the blog post -* } -* return { -* code: http code -* success: boolean - true if login succesfull -* url: string | undefined - url of the blog post if successfull -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/editpost', userMiddleware.adminAuthNeeded, (request, response) => { - - if (!request.body) { - return apiHelper.sendApiGenericError(response); - } - - const { id, content, title, author, category, short } = request.body; - blogPost.blogPostModel.findByIdAndUpdate(id, { - 'content': content, - 'name': title, - 'short': short, - 'meta.author': author, - 'meta.category': category - }, (error, post) => { - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - - return apiHelper.sendReturn(response, { - url: moment(post.meta.date, 'YYYY-MM-DD') + '/' + post.meta.slug - }); - }); -}); - -/* -* /admin/api/v1/newauthor -* -* creates new author -* -* post { -* name - author name -* description - author description -* image - image url for profile picture -* } -* return { -* code: http code -* success: boolean - true if author succesfull -* id: string | undefined - id of the new author if successfull -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/newauthor', userMiddleware.adminAuthNeeded, (request, response) => { - - if (!request.body) { - return apiHelper.sendApiGenericError(response); - } - - const { name, description, image } = request.body; - const newAuthor = new postAuthor.postAuthorModel({ - name, - description, - image - }); - - // saving author to database - newAuthor.save().then((author) => { - return apiHelper.sendReturn(response, { - id: author.id - }); - }).catch((rejection) => { - // TODO format exception so it doesnt have a huge list of errors - return apiHelper.sendApiError(response, 500, [rejection]); - }); -}); - -/* -* /admin/api/v1/editauthor -* -* edit an existing author -* -* post { -* id - id of author to edit -* name - author name -* description - author description -* image - image url for profile picture -* } -* return { -* code: http code -* success: boolean - true if author succesfull -* id: String - id of the edited author -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/editauthor', userMiddleware.adminAuthNeeded, (request, response) => { - - if (!request.body) { - return apiHelper.sendApiGenericError(response); - } - - const { id, name, description, image } = request.body; - - // updating author in database - postAuthor.postAuthorModel.findByIdAndUpdate(id, { - name, - description, - image - }, (error, author) => { - // TODO format exception so it doesnt have a huge list of errors - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - - return apiHelper.sendReturn(response, { - id: author.id - }); - }); -}); - -/* -* /admin/api/v1/newprogress -* -* creates a new progress entry -* -* post { -* title - progress entry name -* description - progress entry description -* state - 0: backend service entry, 1: no support, 2: partial support, 3: fullly working -* } -* return { -* code: http code -* success: boolean - true if progress succesfull -* id: String | undefined - sends if successfull -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/newprogress', userMiddleware.adminAuthNeeded, (request, response) => { - - if (!request.body) { - return apiHelper.sendApiGenericError(response); - } - - // parses state and isGame to be valid - const { title, description } = request.body; - let { state } = request.body; - let isGame = false; - if (state != '1' && state != '2' && state != '3') { - state = undefined; - } else { - state = parseInt(state); - isGame = true; - } - - const newProgress = new progressList.progressListModel({ - title, - description, - isGame, - state - }); - - // saving progress to database - newProgress.save().then((progress) => { - return apiHelper.sendReturn(response, { - id: progress.id - }); - }).catch((rejection) => { - // TODO format exception so it doesnt have a huge list of errors - return apiHelper.sendApiError(response, 500, [rejection]); - }); -}); - -/* -* /admin/api/v1/editprogress -* -* edit an existing progress entry -* -* post { -* title - progress entry name -* description - progress entry description -* state - 0: backend service entry, 1: no support, 2: partial support, 3: fullly working -* id - id of entry you want to edit -* } -* return { -* code: http code -* success: boolean - true if progress succesfull -* id: String - id of the edited progress entry -* errors: Strings[messages] -* } -*/ -router.post('/admin/api/v1/editprogress', userMiddleware.adminAuthNeeded, (request, response) => { - - if (!request.body) { - return apiHelper.sendApiGenericError(response); - } - - // parsing state and isGame to be valid - const { title, description, id } = request.body; - let { state } = request.body; - let isGame = false; - if (state != '1' && state != '2' && state != '3') { - state = undefined; - } else { - state = parseInt(state); - isGame = true; - } - - // updating progress in database - progressList.progressListModel.findByIdAndUpdate(id, { - title, - description, - state, - isGame - }, (error, progress) => { - // TODO format exception so it doesnt have a huge list of errors - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - - return apiHelper.sendReturn(response, { - id: progress.id - }); - }); -}); - -// api 404 -router.use('/admin/api', (request, response) => { - return apiHelper.sendApi404(response); -}); - -// export the router -module.exports = router; diff --git a/routes/blog.js b/routes/blog.js deleted file mode 100644 index 1151819..0000000 --- a/routes/blog.js +++ /dev/null @@ -1,134 +0,0 @@ -/* - -blog.js - -file for handling routes regarding blog posts. - -*/ - -// imports -const logger = require('winston'); -const router = require('express').Router(); -const moment = require('moment'); -const apiHelper = require('../helpers/api'); -const utilHelper = require('../helpers/util'); -const blogPostModel = require('../models/blog-post').blogPostModel; -const postAuthorModel = require('../models/post-author').postAuthorModel; - -// display single blog post -router.get('/news/:date/:title', (request, response) => { - const date = request.params.date; - const title = request.params.title; - const title_lower = title.toLowerCase(); - - // date format YYYY-MM-DD - if (/[0-9]{4}-[0-9]{2}-[0-9]{2}/.test(date) && /([a-z]|[0-9]|-)+/.test(title_lower)) { - // params are correct format - blogPostModel.getPost(moment(date), title_lower, (error, post) => { - // error exists or no post exists with the date and name - if (error || !post) { - logger.log('warn', `error: ${error} and post: ${post}`); - return utilHelper.send404(response); - } - - // render blogpost - post.postTemplate((error, postTemplate) => { - if (error) { - return utilHelper.send404(response); - } - - return response.render('post', { - title, - description: 'On the Pretendo Network ID Dashboard you can manage your personal information and make new virtual consoles to use for login on your home console.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - post: postTemplate, - user: utilHelper.templateReadyUser(request), - locale: utilHelper.getLocale('US', 'en') - }); - }); - }); - } else { - // params are incorrect - return utilHelper.send404(response); - } -}); - -// display latest blogposts -router.get('/news', (request, response) => { - // sort blogposts on date descending - blogPostModel.find({}).sort({'meta.date': 'desc'}).exec((error, posts) => { - if (error || !posts) { - return utilHelper.send404(response); - } - - // makes posts template ready - const postCollection = []; - for (let i = 0, l = posts.length; i < l; i++) { - postCollection.push(posts[i].postShortTemplate()); - } - - return response.render('post-collection', { - title: 'Pretendo | News', - description: 'The Pretendo news page has a place for all of the update posts the Pretendo developer team has made. It contains everything you need to know about pretendo.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - posts: postCollection, - user: utilHelper.templateReadyUser(request), - locale: utilHelper.getLocale('US', 'en'), - page: 'news' - }); - }); -}); - -/* -* /api/v1/listauthors -* -* gets a list of all authors -* -* return { -* code: http code -* success: boolean - true if author succesfull -* authorList: Objects[{_id, name, description, image}] - list of authors with information -* errors: Strings[messages] -* } -*/ -router.get('/api/v1/listauthors', (request, response) => { - postAuthorModel.find({}, (error, authors) => { - // TODO format exception so it doesnt have a huge list of errors - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - - return apiHelper.sendReturn(response, { - authorList: authors - }); - }); -}); - -/* -* /api/v1/listblog -* -* gets a list of all posts -* -* return { -* code: http code -* success: boolean - true if post succesfull -* postList: Objects[{_id, content, meta}] - list of posts with information -* errors: Strings[messages] -* } -*/ -router.get('/api/v1/listblog', (request, response) => { - blogPostModel.find({}, (error, posts) => { - // TODO format exception so it doesnt have a huge list of errors - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - - apiHelper.sendReturn(response, { - postList: posts - }); - }); -}); - -// export router -module.exports = router; diff --git a/routes/cemu.js b/routes/cemu.js new file mode 100644 index 0000000..541a553 --- /dev/null +++ b/routes/cemu.js @@ -0,0 +1,16 @@ +const router = require('express').Router(); +const utilHelper = require('../helpers/util'); + +router.get('/cemu', (request, response) => { + const locale = utilHelper.getLocale('US', 'en'); + + return response.render('cemu', { + title: 'Pretendo | Cemu', + description: locale.about.text, + url: request.protocol + '://' + request.get('host') + request.originalUrl, + baseurl: request.protocol + '://' + request.get('host'), + locale + }); +}); + +module.exports = router; \ No newline at end of file diff --git a/routes/connecting.js b/routes/connecting.js new file mode 100644 index 0000000..95386c8 --- /dev/null +++ b/routes/connecting.js @@ -0,0 +1,16 @@ +const router = require('express').Router(); +const utilHelper = require('../helpers/util'); + +router.get('/connecting', (request, response) => { + const locale = utilHelper.getLocale('US', 'en'); + + return response.render('connecting', { + title: 'Pretendo | Connecting', + description: locale.about.text, + url: request.protocol + '://' + request.get('host') + request.originalUrl, + baseurl: request.protocol + '://' + request.get('host'), + locale + }); +}); + +module.exports = router; \ No newline at end of file diff --git a/routes/contact.js b/routes/contact.js deleted file mode 100644 index d4fa28f..0000000 --- a/routes/contact.js +++ /dev/null @@ -1,91 +0,0 @@ -/* - -contact.js - -file for handling routes regarding contact - -*/ - -// imports -const logger = require('winston'); -const router = require('express').Router(); -const apiHelper = require('../helpers/api'); -const utilHelper = require('../helpers/util'); -const config = require('../config.json'); -const https = require('https'); - -// display contact page -router.get('/contact', (request, response) => { - return response.render('contact', { - title: 'Pretendo | Contact', - description: 'The Pretendo Contact page offers a way to ask questions and communicate with the Pretendo developer team. Its the perfect place to get answers.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - user: utilHelper.templateReadyUser(request), - locale: utilHelper.getLocale('US', 'en'), - page: 'contact' - }); -}); - -/* -* /api/v1/sendmessage -* -* registers a new admin user -* -* post { -* email - email of sender -* subject - subject of message -* message - actual message -* } -* return { -* code: httpcode -* success: boolean - true if sending was successull -* errors: Strings[messages] -* } -*/ -router.post('/api/v1/sendmessage', (req, response) => { - if (!req.body) { - return apiHelper.sendApiGenericError(response); - } - - - const { email, subject, message } = req.body; - if (email && subject && message && message.length < 2000) { - // request body has everything - const postData = JSON.stringify({ - content: 'email: ' + email + ' \n subject: ' + subject + ' \n\n' + message - }); - - // request object - const request = https.request({ - hostname: config.contactWebhook.host, - port: config.contactWebhook.port, - path: config.contactWebhook.path, - method : 'POST', - headers : { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-cache', - 'Content-Length': postData.length - } - }, () => { - // sends success - return apiHelper.sendReturn(response, {}); - }); - - // error handling - request.on('error', (error) => { - logger.log('warn', 'request errored' + error); - return apiHelper.sendApiGenericError(response); - }); - - // write post data to request - request.write(postData); - request.end(); - } else { - // TODO give more detailed response - return apiHelper.sendApiGenericError(response); - } - -}); - -// export router -module.exports = router; diff --git a/routes/faq.js b/routes/faq.js new file mode 100644 index 0000000..218be1a --- /dev/null +++ b/routes/faq.js @@ -0,0 +1,16 @@ +const router = require('express').Router(); +const utilHelper = require('../helpers/util'); + +router.get('/faq', (request, response) => { + const locale = utilHelper.getLocale('US', 'en'); + + return response.render('faq', { + title: 'Pretendo | FAQ', + description: locale.about.text, + url: request.protocol + '://' + request.get('host') + request.originalUrl, + baseurl: request.protocol + '://' + request.get('host'), + locale + }); +}); + +module.exports = router; \ No newline at end of file diff --git a/routes/home.js b/routes/home.js index cce0578..e25d360 100644 --- a/routes/home.js +++ b/routes/home.js @@ -9,22 +9,17 @@ for routes on the root path // imports const router = require('express').Router(); const utilHelper = require('../helpers/util'); -const blogPostModel = require('../models/blog-post').blogPostModel; // display home page router.get('/', (request, response) => { - // needs callback because mongoose is inconsistent - blogPostModel.latestPostsShortTemlate(2, (error, result) => { - return response.render('home', { - title: 'Pretendo | Home', - description: 'Pretendo is a as close as possible recreation of the original Nintendo Network for 3ds and Wiiu. It is an replacement for if the original servers shut down.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - user: utilHelper.templateReadyUser(request), - locale: utilHelper.getLocale('US', 'en'), - posts: result, - page: 'home' - }); + const locale = utilHelper.getLocale('US', 'en'); + + return response.render('home', { + title: 'Pretendo | Home', + description: locale.about.text, + url: request.protocol + '://' + request.get('host') + request.originalUrl, + baseurl: request.protocol + '://' + request.get('host'), + locale }); }); diff --git a/routes/pnid.js b/routes/pnid.js deleted file mode 100644 index bc2411f..0000000 --- a/routes/pnid.js +++ /dev/null @@ -1,212 +0,0 @@ -/* - -admin.js - -file for handling admin api. - -*/ - -// imports -const logger = require('winston'); -const router = require('express').Router(); -const passport = require('passport'); -const userMiddleware = require('../middleware/authentication'); -const apiHelper = require('../helpers/api'); -const utilHelper = require('../helpers/util'); -const mailer = require('../helpers/mailer'); -const config = require('../config.json'); -const Recaptcha = require('express-recaptcha').Recaptcha; -const recaptcha = new Recaptcha(config.recaptcha.siteKey, config.recaptcha.secretKey); - -// database models -const PNID = require('../models/pnid'); - -// renders register page -router.get('/pnid/register', (request, response) => { - return response.render('pnid/register', { - title: 'Pretendo | Register', - description: 'On the Pretendo Network ID Dashboard you can manage your personal information and make new virtual consoles to use for login on your home console.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - locale: utilHelper.getLocale('US', 'en'), - recaptcha_sitekey: config.recaptcha.siteKey - }); -}); -// renders login page -router.get('/pnid/login', (request, response) => { - return response.render('pnid/login', { - title: 'Pretendo | Login', - description: 'On the Pretendo Network ID Dashboard you can manage your personal information and make new virtual consoles to use for login on your home console.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - locale: utilHelper.getLocale('US', 'en') - }); -}); -// renders password forget -router.get('/pnid/forgotpassword', (request, response) => { - return response.render('pnid/forgotpassword', { - title: 'Pretendo | Forgot password', - description: 'On the Pretendo Network ID Dashboard you can manage your personal information and make new virtual consoles to use for login on your home console.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - locale: utilHelper.getLocale('US', 'en'), - user: utilHelper.templateReadyUser(request) - }); -}); -// renders password reset page -router.get('/pnid/passwordreset', (request, response) => { - return response.render('passwordreset', { - title: 'Pretendo | Password reset', - description: 'On the Pretendo Network ID Dashboard you can manage your personal information and make new virtual consoles to use for login on your home console.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - locale: utilHelper.getLocale('US', 'en'), - user: utilHelper.templateReadyUser(request) - }); -}); -// logout -router.get('/pnid/logout', userMiddleware.pnidAuthNeeded, (request, response) => { - request.logout(); - return response.redirect('/'); -}); -// renders pnid dashboard -router.get('/pnid/dashboard', userMiddleware.pnidAuthNeeded, (request, response) => { - return response.render('pnid/dashboard', { - title: 'Pretendo | Dash', - description: 'On the Pretendo Network ID Dashboard you can manage your personal information and make new virtual consoles to use for login on your home console.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - locale: utilHelper.getLocale('US', 'en'), - user: utilHelper.templateReadyUser(request) - }); -}); - -/* -* /api/v1/login -* -* signs user in -* -* post { -* email -* password -* } -* return { -* code: http code -* success: boolean -* username: undefined | string - only if login was successfull -* role: undefined | string - role of user if login was successfull -* errors: Strings[messages] - not yet :( -* } -*/ -// TODO make login somehow display errors in correct format. -// middleware does the authentication work. this just returns a success -router.post('/api/v1/login', passport.authenticate('PNIDStrategy'), function (request, response) { - return apiHelper.sendReturn(response, { - email: request.user.email, - email_validated: request.user.email_validated, - pnid: request.user.pnid.key - }); -}); - -/* -* /api/v1/passwordreset -* -* signs user in -* -* post { -* password -* password_confirm -* } -* return { -* code: http code -* success: boolean -* errors: Strings[messages] -* } -*/ -router.post('/api/v1/passwordreset', function (request, response) { - //TODO make the actual password change - return apiHelper.sendReturn(response, {}); -}); - -/* -* /api/v1/register -* -* registers a new admin user -* -* post { -* username -* password -* } -* return { -* code: httpcode -* success: boolean - true if register was successull -* username: undefined | string - username if register was successfullW -* errors: Strings[messages] -* } -*/ - -const multer = require('multer')(); - -router.post('/api/v1/register', multer.none(), recaptcha.middleware.verify, async (request, response) => { - if (!request.body) { - return apiHelper.sendApiGenericError(response); - } - - console.log(request.body); - - return response.send(request.body); - - if (request.recaptcha.error) { - logger.log('warn', `[reCaptcha ERROR] ${request.recaptcha.error} | IP: ${request.ip} | Data: ${JSON.stringify(request.body)}`); - return apiHelper.sendApiError(response, 500, ['Captcha error']); - } - - const { email, password, confirm_password, username } = request.body; - - if (password !== confirm_password) { - return apiHelper.sendApiError(response, 400, ['Passwords do not match']); - } - - const email_validation_code = await PNID.PNIDModel.generateEmailValidationCode(); - const email_validation_token = await PNID.PNIDModel.generateEmailValidationToken(); - - const newUser = new PNID.PNIDModel({ - email, - email_validation_code, - email_validation_token, - password, - pnid: { - pid: await PNID.PNIDModel.generatePID(), - username, - username_lower: username.toLowerCase() - } - }); - - // saving to database - newUser.save().then((user) => { - mailer.send( - user.get('email'), - '[Pretendo Network] Please confirm your e-mail address', - `Hello, - Your Pretendo Network ID activation is almost complete. Please click the link below to confirm your e-mail address and complete the activation process. - - https://account.pretendo.cc/account/email-confirmation?token${user.get('email_validation_token')} - - If you are unable to connect to the above URL, please enter the following confirmation code on the device to which your Pretendo Network ID is linked. - - <<Confirmation code: ${user.get('email_validation_code')}>>` - ); - - return apiHelper.sendReturn(response, { - email: user.email, - email_validated: user.email_validated, - pnid: user.pnid.pid - }); - }).catch((rejection) => { - // TODO format exception so it doesnt have a huge list of errors - logger.log('warn', rejection); - return apiHelper.sendApiError(response, 500, [rejection]); - }); -}); - -// export the router -module.exports = router; diff --git a/routes/progress.js b/routes/progress.js deleted file mode 100644 index cc35544..0000000 --- a/routes/progress.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - -progress.js - -file for handling routes regarding progress - -*/ - -// imports -const router = require('express').Router(); -const apiHelper = require('../helpers/api'); -const utilHelper = require('../helpers/util'); -const progressListModel = require('../models/progress-list').progressListModel; - -// display progress -router.get('/progress', (request, response) => { - - progressListModel.find({}, (error, progress) => { - if (error) { - return utilHelper.send404(response); - } - - // filtering games and backend - const games = progress.filter(i => i.isGame); - const backends = progress.filter(i => !i.isGame); - - return response.render('progress', { - title: 'Pretendo | Progress', - description: 'The Pretendo progress page shows the progress the Pretendo developer team made. It shows how much is working and if it can be used for the end user yet.', - url: request.protocol + '://' + request.get('host') + request.originalUrl, - baseurl: request.protocol + '://' + request.get('host'), - games, - backends, - user: utilHelper.templateReadyUser(request), - locale: utilHelper.getLocale('US', 'en'), - page: 'progress' - }); - }); -}); - -/* -* /api/v1/listprogress -* -* gets a list of progress -* -* return { -* code: http code -* success: boolean - true if progress succesfull -* progressList: Objects[{_id, title, description, state}] - list of progress with information -* errors: Strings[messages] -* } -*/ -router.get('/api/v1/listprogress', (request, response) => { - progressListModel.find({}, (error, progress) => { - // TODO format exception so it doesnt have a huge list of errors - if (error) { - return apiHelper.sendApiError(response, 500, [error]); - } - - apiHelper.sendReturn(response, { - progressList: progress - }); - }); -}); - -// export router -module.exports = router; diff --git a/server.js b/server.js index 8a908d8..4724135 100644 --- a/server.js +++ b/server.js @@ -1,33 +1,13 @@ -/* +process.on('uncaughtException', console.warn); -server.js - -the file that contains the startup code - -*/ - -// imports -const logger = require('./logger'); const express = require('express'); const handlebars = require('express-handlebars'); -const session = require('express-session'); -const mongoStore = require('connect-mongo')(session); -const mongoose = require('mongoose'); const morgan = require('morgan'); +const logger = require('./logger'); const config = require('./config.json'); const utilHelper = require('./helpers/util'); -const passportconfig = require('./passport.config.js'); - -// setup console colors require('colors'); -// fix database deprecation warnings -mongoose.set('useCreateIndex', true); -mongoose.set('useNewUrlParser', true); -// setup database connection -mongoose.connect(config.database.url); -const connection = mongoose.connection; -connection.on('error', console.error.bind(console, 'connection error:')); - // setup express const app = express(); app.use(morgan('dev')); @@ -35,39 +15,12 @@ app.use(express.json()); app.use(express.urlencoded({ extended: true })); -app.use(session({ - secret: config.secrets.session, - saveUninitialized: true, - resave: true, - cookie: { - maxAge: 3600000, - httpOnly: true//, // remove on production - /*secure: true*/ // uncomment on production - }, - // permanent session storing for MongoDB - store: new mongoStore({ - mongooseConnection: connection, - collection: 'sessions' - }) -})); -// setups up passportjs authentication -passportconfig(app); // handlebars templating setup const hbsEngine = handlebars({ extname: '.hbs', layoutsDir: 'views', - partialsDir: 'views/partials', - helpers: { - 'if_eq': function(a, b, opts) { - if(a == b) return opts.fn(this); - else return opts.inverse(this); - }, - 'if_neq': function(a, b, opts) { - if(a != b) return opts.fn(this); - else return opts.inverse(this); - } - } + partialsDir: 'views/partials' }); app.engine('.hbs', hbsEngine); app.set('view engine', '.hbs'); @@ -75,35 +28,38 @@ app.set('view engine', '.hbs'); // locations and routes setup const locations = { home: require('./routes/home'), - posts: require('./routes/blog'), - admin: require('./routes/admin'), - contact: require('./routes/contact'), - progress: require('./routes/progress'), - pnid: require('./routes/pnid') + connecting: require('./routes/connecting'), + cemu: require('./routes/cemu'), + faq: require('./routes/faq'), }; // static files -app.use('/assets', express.static('assets')); -app.use('/', express.static('public')); +app.use('/assets', express.static(__dirname + '/assets')); + // page map app.use('/', locations.home); -app.use('/', locations.contact); -app.use('/', locations.posts); -app.use('/', locations.admin); -app.use('/', locations.progress); -app.use('/', locations.pnid); +app.use('/', locations.connecting); +app.use('/', locations.cemu); +app.use('/', locations.faq); app.use((request, response) => { - return utilHelper.send404(response); + const locale = utilHelper.getLocale('US', 'en'); + + return response.status(404).render('404', { + title: 'Pretendo | 404', + description: locale.about.text, + url: request.protocol + '://' + request.get('host') + request.originalUrl, + baseurl: request.protocol + '://' + request.get('host'), + locale + }); }); // 4 parameters required to read the error, cant help the eslint error app.use((error, request, response, next) => { // eslint-disable-line no-unused-vars - logger.log('warn', error.stack); + logger.error(error.stack); return response.status(500).send('Something broke!'); }); // startup app.listen(config.http.port, () => { - logger.log('debug', `started the server on port: ${config.http.port}`); - console.log(`started the server on port: ${new String(config.http.port).green}`); + logger.success(`started the server on port: ${config.http.port}`); }); diff --git a/setupAdminUser.js b/setupAdminUser.js deleted file mode 100644 index 6a8066c..0000000 --- a/setupAdminUser.js +++ /dev/null @@ -1,22 +0,0 @@ -const mongoose = require('mongoose'); -// fix database deprecation warnings -mongoose.set('useCreateIndex', true); -mongoose.set('useNewUrlParser', true); -// setup database connection -mongoose.connect(require('./config.json').database.url); -const connection = mongoose.connection; -connection.on('error', console.error.bind(console, 'connection error:')); - -const adminUser = require('./models/admin-user'); - - -const newUser = new adminUser.adminUserModel({ - username: 'admin', - password: 'rootroot' -}); - -newUser.save().then(() => { - console.log('success, user admin pass root'); -}).catch((rejection) => { - console.log(rejection); -}); \ No newline at end of file diff --git a/views/404.hbs b/views/404.hbs index c3b392a..1af63e0 100644 --- a/views/404.hbs +++ b/views/404.hbs @@ -6,11 +6,13 @@ + {{> navbar }} +
-

ERROR

+

404

{{ locale.404.title }}

diff --git a/views/admin.hbs b/views/admin.hbs deleted file mode 100644 index 27edbb5..0000000 --- a/views/admin.hbs +++ /dev/null @@ -1,134 +0,0 @@ - - - - {{> head-common }} - - - {{> nav-default }} -
-
-
-
-

login

-
- - - -
- -
-

register new admin

-
- - - -
- -

delete admin

-
-

id

- - -
- -

new blogpost

-
-

content

- -

short version

- -

category

- -

title

- -

author id

- - -
- -

edit blogpost

-
-

content

- -

short version

- -

id

- -

category

- -

title

- -

author id

- - -
- -

new blogpost author

-
-

name

- -

description

- -

image link

- - -
- -

edit author info

-
-

id

- -

name

- -

description

- -

image link

- - -
- -

new progress entry

-
-

title

- -

description

- -

state

-

0 - backend service
1 - no support
2 - partial support
3 - fully working

- - -
- -

edit progress entry

-
-

id

- -

title

- -

description

- -

state

-

0 - backend service
1 - no support
2 - partial support
3 - fully working

- - -
- -
- List of admin users -
- List of blog posts -
- List of progress -
- List of authors -
- Check if logged in -
- Logout -
-
-
-
- {{> footer-default }} - - diff --git a/views/cemu.hbs b/views/cemu.hbs new file mode 100644 index 0000000..ebcbf20 --- /dev/null +++ b/views/cemu.hbs @@ -0,0 +1,21 @@ + + + + {{> head-common }} + + + {{> navbar }} + +
+
+ +
+
+

Cemu

+

Pretendo is currently not usable by the general public. When the network becomes public, this will contain steps on connecting to the network using Cemu

+
+
+
+ {{> footer-default }} + + \ No newline at end of file diff --git a/views/connecting.hbs b/views/connecting.hbs new file mode 100644 index 0000000..259b2cd --- /dev/null +++ b/views/connecting.hbs @@ -0,0 +1,21 @@ + + + + {{> head-common }} + + + {{> navbar }} + +
+
+ +
+
+

Connecting

+

Pretendo is currently not usable by the general public. When the network becomes public, this will contain steps on connecting to the network

+
+
+
+ {{> footer-default }} + + \ No newline at end of file diff --git a/views/contact.hbs b/views/contact.hbs deleted file mode 100644 index 1e84408..0000000 --- a/views/contact.hbs +++ /dev/null @@ -1,35 +0,0 @@ - - - - {{> head-common }} - - - - - - - {{> nav-default }} -
-
-
-
-

{{ locale.contact.caption }}

-

{{ locale.contact.title }}

-
-
-
-
- - -
- -
-
- -
-
-
-
- {{> footer-default }} - - diff --git a/views/faq.hbs b/views/faq.hbs new file mode 100644 index 0000000..18b95a2 --- /dev/null +++ b/views/faq.hbs @@ -0,0 +1,62 @@ + + + + {{> head-common }} + + + + + {{> navbar }} + +
+
+ +
+
+

FAQ

+
+
+ What is Pretendo? +

Pretendo is an open source Nintendo Network replacement that aims to build custom servers for the WiiU and 3DS family of consoles. Our goal is to preserve the online functionality of these consoles, to allow players to continue to play their favorite WiiU and 3DS games to their fullest capacity

+
+ +
+ How do can I use Pretendo? +

Pretendo is currently not in a state that is ready for public use. However, once it is you will be able to use Pretendo simply by running our homebrew patcher on your console

+
+ +
+ Is there an ETA for XYZ? +

We do not have an exact ETA for any specific features or the project as a whole. There are many parts to the network, updates release for them individually whenever they are ready (for example updates to the account server are (almost always) independent on other parts of the network, such as the friends server). Due to that we cannot give an exact ETA

+
+ +
+ Does Pretendo work on Cemu/emulators? +

+ Pretendo is designed for the WiiU and (eventually) 3DS. At this time the only emulator for these consoles with real online capability is Cemu. Cemu does not officially support custom servers, but it will still be possible to use Pretendo with Cemu +
+ See the Cemu page for more details +

+
+ +
+ Will my existing NNIDs work on Pretendo? +

Sadly, no. The only ones with access to the data about your existing NNIDs is Nintendo. A NNID-to-PNID migration could theoretically be possible, but it would be a slow and lengthy process requiring sensitive user information

+
+ +
+ If I am account/console banned on Nintendo Network, will I stay banned when using Pretendo? +

Any account/console bans only exist server-side. This means any existing bans would not carry over to Pretendo. However Pretendo still reserves the right to issue a ban for our network if we see fit

+
+ +
+ Will Pretendo support the Wii/Switch? +

The Wii already has custom servers provided by Wiimmfi. We currently have no plans on supporting the Switch, as not only is it a completely different platform with a different online network, but Switch online is a paid service

+
+
+
+
+
+ {{> footer-default }} + + \ No newline at end of file diff --git a/views/home.hbs b/views/home.hbs index 5998902..a836aa6 100644 --- a/views/home.hbs +++ b/views/home.hbs @@ -6,7 +6,8 @@ - {{> nav-default }} + {{> navbar }} +

{{ locale.home.header.title }}

@@ -26,74 +27,74 @@
-

{{ locale.about.caption }}

+

{{ locale.credits.caption }}

{{ locale.credits.title }}

- +
-

RedDucks

-

Project owner, lead developer, very violent young man. Splatoon obsessed as well.

-
-
- -
-

RedDucks

-

Project owner, lead developer, very violent young man. Splatoon obsessed as well.

-
-
- -
-

RedDucks

-

Project owner, lead developer, very violent young man. Splatoon obsessed as well.

-
-
- -
-

RedDucks

-

Project owner, lead developer, very violent young man. Splatoon obsessed as well.

-
-
- -
-

RedDucks

-

Project owner, lead developer, very violent young man. Splatoon obsessed as well.

-
-
- -
-

RedDucks

-

Project owner, lead developer, very violent young man. Splatoon obsessed as well.

+

Jonathan Barrow (RedDucks)

+

Project owner and lead developer

+
-
-
-
- -
-
-
-

{{ locale.latest_news.caption }}

-

{{ locale.latest_news.title }}

-

{{ locale.latest_news.description }}

- {{ locale.latest_news.button_text }} -
-
- {{#each posts as |post| }} -
-
-

{{ post.title }}

-

{{ post.content }}

- {{ ../locale.latest_news.news_button_text }} +
+ +
+

Jemma (CaramelKat)

+

Miiverse research and development

+ +
+
+
+ +
+

superwhiskers

+

crunch library development

+ +
+
+
+ +
+

SuperMarioDaBom

+

Console and other system research

+ +
+
+
+ +
+

Rambo6Glaz

+

Network installer and console research

+ +
+
+
+ +
+

mrjvs

+

Web development and early eShop research

+ +
+
+
+ +
+

Benjamin Moss (kxpler442b)

+

Web development

+ +
+
+
+ +
+

Kinnay

+

None of this would be possible without the research and help done by Kinnay on PRUDP and nex

+
- {{/each }}
diff --git a/views/partials/nav-dashboard.hbs b/views/partials/nav-dashboard.hbs deleted file mode 100644 index 52c845d..0000000 --- a/views/partials/nav-dashboard.hbs +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/views/partials/nav-default.hbs b/views/partials/nav-default.hbs deleted file mode 100644 index 74d6859..0000000 --- a/views/partials/nav-default.hbs +++ /dev/null @@ -1,22 +0,0 @@ - \ No newline at end of file diff --git a/views/partials/navbar.hbs b/views/partials/navbar.hbs new file mode 100644 index 0000000..6f7a895 --- /dev/null +++ b/views/partials/navbar.hbs @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/views/pnid/dashboard.hbs b/views/pnid/dashboard.hbs deleted file mode 100644 index ef5f246..0000000 --- a/views/pnid/dashboard.hbs +++ /dev/null @@ -1,38 +0,0 @@ - - - - {{> head-common }} - - - - - - - - {{> nav-default }} - -
- {{> nav-dashboard }} -
-

{{ locale.dashboard.account.caption }}

-

{{ locale.dashboard.account.title }}

-
-

Username: {{ user.user.pnid.username }}

-

Email: {{ user.user.email }}

- -
-
-
-

Username: - -

-

Email: - -

- Cancel -
-
-
- {{> footer-default }} - - diff --git a/views/pnid/forgotpassword.hbs b/views/pnid/forgotpassword.hbs deleted file mode 100644 index ed2087e..0000000 --- a/views/pnid/forgotpassword.hbs +++ /dev/null @@ -1,28 +0,0 @@ - - - - {{> metatags }} - {{ title }} - - - - - - - -
-

{{ locale.nav.brand }}

-
-

{{ locale.forgot.card.caption }}

-

{{ locale.forgot.card.title }}

-
-
- - -
- -
-
- {{> footer-default }} - - diff --git a/views/pnid/login.hbs b/views/pnid/login.hbs deleted file mode 100644 index 56055af..0000000 --- a/views/pnid/login.hbs +++ /dev/null @@ -1,32 +0,0 @@ - - - - {{> metatags }} - {{ title }} - - - - - - - -
-

{{ locale.nav.brand }}

-
-

{{ locale.login.card.caption }}

-

{{ locale.login.card.title }}

-
-
- - - - -

{{ locale.login.card.forgotpass_introduction }} {{ locale.login.card.forgotpass_text }}

-
- -

{{ locale.login.card.link_introduction }} {{ locale.login.card.link_text }}

-
-
- {{> footer-default }} - - diff --git a/views/pnid/passwordreset.hbs b/views/pnid/passwordreset.hbs deleted file mode 100644 index 50062a2..0000000 --- a/views/pnid/passwordreset.hbs +++ /dev/null @@ -1,30 +0,0 @@ - - - - {{> metatags }} - {{ title }} - - - - - - - -
-

{{ locale.nav.brand }}

-
-

{{ locale.password.card.caption }}

-

{{ locale.password.card.title }}

-
-
- - - - -
- -
-
- {{> footer-default }} - - diff --git a/views/pnid/register.hbs b/views/pnid/register.hbs deleted file mode 100644 index bde9a20..0000000 --- a/views/pnid/register.hbs +++ /dev/null @@ -1,147 +0,0 @@ - - - - {{> metatags }} - {{ title }} - - - - - - - - - - - - - - -
-

{{ locale.nav.brand }}

-
-

{{ locale.register.card.caption }}

-

{{ locale.register.card.title }}

-
- -
- - - - - - - - - - - - - - - - - -
- - -
- -

{{ locale.register.card.link_introduction }} {{ locale.register.card.link_text }}

-
-
- - - {{> footer-default }} - - diff --git a/views/post-collection.hbs b/views/post-collection.hbs deleted file mode 100644 index 82f4698..0000000 --- a/views/post-collection.hbs +++ /dev/null @@ -1,29 +0,0 @@ - - - - {{> head-common }} - - - - - {{> nav-default }} -
-
-
-
-

{{ locale.news.caption }}

-

{{ locale.news.title }}

-
-
-
- {{> footer-default }} - - \ No newline at end of file diff --git a/views/post.hbs b/views/post.hbs deleted file mode 100644 index 70c66a1..0000000 --- a/views/post.hbs +++ /dev/null @@ -1,28 +0,0 @@ - - - - {{> head-common }} - - - - {{> nav-default }} -
-
-
-
-

{{ post.category }} — {{ post.dateString }}

-

{{ post.title }}

- {{{ post.content }}} -
- -
-

{{ post.author.name }}

-

{{ post.author.description }}

-
-
-
-
-
- {{> footer-default }} - - diff --git a/views/progress.hbs b/views/progress.hbs deleted file mode 100644 index fb69398..0000000 --- a/views/progress.hbs +++ /dev/null @@ -1,44 +0,0 @@ - - - - {{> head-common }} - - - - - {{> nav-default }} -
-
-
-
-

{{ locale.progress.summary.caption }}

-

{{ locale.progress.summary.title }}

-

{{ locale.progress.summary.text }}

-
-
-
-
-

{{ locale.progress.compatibility.caption }}

-

{{ locale.progress.compatibility.title }}

- {{#each games }} -
-

{{ this.title }}

-

{{ this.description }}

-
- {{/each}} -
-
-

{{ locale.progress.misc.caption }}

-

{{ locale.progress.misc.title }}

- {{#each backends }} -
-

{{ this.title }}

-

{{ this.description }}

-
- {{/each}} -
-
-
- {{> footer-default }} - -