mirror of
https://github.com/PretendoNetwork/website.git
synced 2026-08-28 11:36:53 -05:00
Starting bringing over a better comment scheme for methods (see helpers/api.js), addedemail confirmation sending, proper logging, fixed registration
Server now sends confirmation emails to the provided email address. The values can not yet be validated, but they are stored so validation can be added at any time. Added Winston for event logging. Winston has a log level system that merges certain log types into the same file. Maybe we should use a custom logger solution? Registration now works (was not working for me), with added reCaptcha protection, password validation, and the storing of usernames/email validation values. Also changed the PID to a number, cuz it's a number
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
# web javascript causes a lot of eslint warnings
|
||||
assets/js/*.js
|
||||
assets/js
|
||||
@@ -13,6 +13,13 @@
|
||||
"secrets": {
|
||||
"session": "session secret here"
|
||||
},
|
||||
"email": {
|
||||
"service": "gmail",
|
||||
"auth": {
|
||||
"user": "example@email.com",
|
||||
"pass": "password"
|
||||
}
|
||||
},
|
||||
"recaptcha": {
|
||||
"siteKey": "abcd",
|
||||
"secretKey": "1234"
|
||||
|
||||
@@ -5,10 +5,14 @@ common api returns
|
||||
|
||||
*/
|
||||
|
||||
// use for any api return. it has basic layout used for every return.
|
||||
/**
|
||||
* 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) {
|
||||
response.status(200).json(
|
||||
// combine 2 objects
|
||||
return response.status(data.code || 200).json(
|
||||
Object.assign({
|
||||
code: 200,
|
||||
success: true,
|
||||
@@ -17,44 +21,45 @@ function sendReturn(response, data, errors) {
|
||||
);
|
||||
}
|
||||
|
||||
// use if api endpoint doesnt exist
|
||||
/**
|
||||
* Send API 404
|
||||
* @param {ServerResponse} response An express ServerResponse response
|
||||
*/
|
||||
function sendApi404(response) {
|
||||
response.status(404).json({
|
||||
code: 404,
|
||||
errors: [
|
||||
'Endpoint not in use'
|
||||
]
|
||||
});
|
||||
return sendApiError(response, 404, [
|
||||
'Endpoint not in use'
|
||||
]);
|
||||
}
|
||||
|
||||
// use if not logged in and is required (handled with middleware)
|
||||
/**
|
||||
* Send user not authenticated error
|
||||
* @param {ServerResponse} response An express ServerResponse response
|
||||
*/
|
||||
function sendApiAuthError(response) {
|
||||
response.status(401).json({
|
||||
code: 401,
|
||||
errors: [
|
||||
'Not authenticated'
|
||||
]
|
||||
});
|
||||
return sendApiError(response, 401, [
|
||||
'Not authenticated'
|
||||
]);
|
||||
}
|
||||
|
||||
// use for completely broken requests
|
||||
/**
|
||||
* Send a generic API error
|
||||
* @param {ServerResponse} response An express ServerResponse response
|
||||
*/
|
||||
function sendApiGenericError(response) {
|
||||
response.status(400).json({
|
||||
code: 400,
|
||||
success: false,
|
||||
errors: [
|
||||
'Bad request'
|
||||
]
|
||||
});
|
||||
return sendApiError(response, 400, [
|
||||
'Bad request'
|
||||
]);
|
||||
}
|
||||
|
||||
// use for any api not successfull
|
||||
/**
|
||||
* Send an API error
|
||||
* @param {ServerResponse} response An express ServerResponse response
|
||||
*/
|
||||
function sendApiError(response, code, errors) {
|
||||
response.status(code).json({
|
||||
return sendReturn(response, {
|
||||
code,
|
||||
success: false,
|
||||
errors
|
||||
});
|
||||
success: false
|
||||
}, errors);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -6,6 +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) {
|
||||
@@ -46,7 +47,7 @@ function getLocale(region, language) {
|
||||
return require(path);
|
||||
}
|
||||
|
||||
console.warn(`Could not find locale ${region}_${language}! Loading default`);
|
||||
logger.log('warn', `Could not find locale ${region}_${language}! Loading default`);
|
||||
|
||||
return getDefaultLocale();
|
||||
}
|
||||
@@ -56,10 +57,15 @@ 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
|
||||
getDefaultLocale,
|
||||
generateRandomInt
|
||||
};
|
||||
41
logger.js
Normal file
41
logger.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const winston = require('winston');
|
||||
|
||||
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'
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
winston.add(logger);
|
||||
|
||||
module.exports = winston;
|
||||
31
mailer.js
Normal file
31
mailer.js
Normal file
@@ -0,0 +1,31 @@
|
||||
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
|
||||
};
|
||||
@@ -8,7 +8,9 @@ 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({
|
||||
@@ -23,6 +25,14 @@ const PNIDSchema = new mongoose.Schema({
|
||||
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,
|
||||
@@ -32,10 +42,15 @@ const PNIDSchema = new mongoose.Schema({
|
||||
trim: true
|
||||
},
|
||||
pnid: {
|
||||
key: {
|
||||
type: String // not sure what this should be
|
||||
},
|
||||
pid: {
|
||||
type: Number,
|
||||
unique: true
|
||||
},
|
||||
username: {
|
||||
type: String,
|
||||
unique: true
|
||||
},
|
||||
username_lower: {
|
||||
type: String,
|
||||
unique: true
|
||||
}
|
||||
@@ -79,7 +94,7 @@ PNIDSchema.statics.hashPasswordPrimary = function(password, pid) {
|
||||
const buff1 = require('python-struct').pack('<I', pid);
|
||||
const buff2 = Buffer.from(password).toString('ascii');
|
||||
|
||||
const unpacked = new Buffer(bufferToHex(buff1) + '\x02eCF' + buff2, 'ascii');
|
||||
const unpacked = Buffer.from(bufferToHex(buff1) + '\x02eCF' + buff2, 'ascii');
|
||||
const hashed = require('crypto').createHash('sha256').update(unpacked).digest().toString('hex');
|
||||
|
||||
return hashed;
|
||||
@@ -96,18 +111,44 @@ function bufferToHex(buff) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PNIDSchema.statics.generatePID = async function() {
|
||||
PNIDSchema.statics.generatePID = async function() {
|
||||
// Quick, dirty fix for PIDs
|
||||
const pid = Math.floor(Math.random() * (4294967295 - 1000000000) + 1000000000);
|
||||
const does_pid_inuse = await PNIDModel.findOne({
|
||||
const pid_inuse = await PNIDModel.findOne({
|
||||
'pnid.pid': pid
|
||||
});
|
||||
|
||||
if (does_pid_inuse) {
|
||||
return '' + await PNIDModel.generatePID();
|
||||
if (pid_inuse) {
|
||||
return await PNIDModel.generatePID();
|
||||
}
|
||||
|
||||
return '' + pid;
|
||||
return pid;
|
||||
};
|
||||
|
||||
PNIDSchema.statics.generateEmailValidationCode = async function() {
|
||||
const code = utilHelper.generateRandomInt(6);
|
||||
const code_inuse = await PNIDModel.findOne({
|
||||
'email_validation_code': code
|
||||
});
|
||||
|
||||
if (code_inuse) {
|
||||
return await PNIDModel.generateEmailValidationCode();
|
||||
}
|
||||
|
||||
return code;
|
||||
};
|
||||
|
||||
PNIDSchema.statics.generateEmailValidationToken = async function() {
|
||||
const token = randtoken.generate(32);
|
||||
const token_inuse = await PNIDModel.findOne({
|
||||
'email_validation_token': token
|
||||
});
|
||||
|
||||
if (token_inuse) {
|
||||
return await PNIDModel.generateEmailValidationToken();
|
||||
}
|
||||
|
||||
return token;
|
||||
};
|
||||
|
||||
const PNIDModel = mongoose.model('pnid', PNIDSchema);
|
||||
|
||||
235
package-lock.json
generated
235
package-lock.json
generated
@@ -993,11 +993,19 @@
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
|
||||
"integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.1",
|
||||
"color-string": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
@@ -1005,14 +1013,36 @@
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
|
||||
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
|
||||
"requires": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"colornames": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
|
||||
"integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y="
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.2.0.tgz",
|
||||
"integrity": "sha512-lweugcX5nailCqZBttArTojZZpHGWhmFJX78KJHlxwhM8tLAy5QCgRgRxrubrksdvA+2Y3inWG5TToyyjL82BQ=="
|
||||
},
|
||||
"colorspace": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.1.tgz",
|
||||
"integrity": "sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw==",
|
||||
"requires": {
|
||||
"color": "3.0.x",
|
||||
"text-hex": "1.0.x"
|
||||
}
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||
@@ -1240,6 +1270,16 @@
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"diagnostics": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
|
||||
"integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
|
||||
"requires": {
|
||||
"colorspace": "1.1.x",
|
||||
"enabled": "1.0.x",
|
||||
"kuler": "1.0.x"
|
||||
}
|
||||
},
|
||||
"doctrine": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||
@@ -1269,11 +1309,24 @@
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"enabled": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "http://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
|
||||
"integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
|
||||
"requires": {
|
||||
"env-variable": "0.0.x"
|
||||
}
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"env-variable": {
|
||||
"version": "0.0.5",
|
||||
"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",
|
||||
@@ -1739,6 +1792,16 @@
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
|
||||
"integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg=="
|
||||
},
|
||||
"fecha": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "http://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
|
||||
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
|
||||
},
|
||||
"figures": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
||||
@@ -2680,6 +2743,11 @@
|
||||
"kind-of": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||
},
|
||||
"is-binary-path": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
|
||||
@@ -2921,6 +2989,14 @@
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
},
|
||||
"kuler": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz",
|
||||
"integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==",
|
||||
"requires": {
|
||||
"colornames": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"latest-version": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
|
||||
@@ -2984,6 +3060,30 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
|
||||
},
|
||||
"logform": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz",
|
||||
"integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==",
|
||||
"requires": {
|
||||
"colors": "^1.2.1",
|
||||
"fast-safe-stringify": "^2.0.4",
|
||||
"fecha": "^2.3.3",
|
||||
"ms": "^2.1.1",
|
||||
"triple-beam": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"colors": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz",
|
||||
"integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"long": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
|
||||
@@ -3370,6 +3470,11 @@
|
||||
"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",
|
||||
@@ -3519,6 +3624,11 @@
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"one-time": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
|
||||
"integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4="
|
||||
},
|
||||
"onetime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
|
||||
@@ -3786,6 +3896,11 @@
|
||||
"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",
|
||||
@@ -4178,6 +4293,14 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
|
||||
"requires": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"slice-ansi": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
|
||||
@@ -4351,6 +4474,11 @@
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
|
||||
},
|
||||
"static-extend": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
|
||||
@@ -4445,6 +4573,11 @@
|
||||
"execa": "^0.7.0"
|
||||
}
|
||||
},
|
||||
"text-hex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
@@ -4512,6 +4645,11 @@
|
||||
"nopt": "~1.0.10"
|
||||
}
|
||||
},
|
||||
"triple-beam": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||
@@ -4775,6 +4913,97 @@
|
||||
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
|
||||
"optional": true
|
||||
},
|
||||
"winston": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/winston/-/winston-3.1.0.tgz",
|
||||
"integrity": "sha512-FsQfEE+8YIEeuZEYhHDk5cILo1HOcWkGwvoidLrDgPog0r4bser1lEIOco2dN9zpDJ1M88hfDgZvxe5z4xNcwg==",
|
||||
"requires": {
|
||||
"async": "^2.6.0",
|
||||
"diagnostics": "^1.1.1",
|
||||
"is-stream": "^1.1.0",
|
||||
"logform": "^1.9.1",
|
||||
"one-time": "0.0.4",
|
||||
"readable-stream": "^2.3.6",
|
||||
"stack-trace": "0.0.x",
|
||||
"triple-beam": "^1.3.0",
|
||||
"winston-transport": "^4.2.0"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"winston-transport": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.2.0.tgz",
|
||||
"integrity": "sha512-0R1bvFqxSlK/ZKTH86nymOuKv/cT1PQBMuDdA7k7f0S9fM44dNH6bXnuxwXPrN8lefJgtZq08BKdyZ0DZIy/rg==",
|
||||
"requires": {
|
||||
"readable-stream": "^2.3.6",
|
||||
"triple-beam": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
|
||||
@@ -27,10 +27,13 @@
|
||||
"mongoose": "^5.3.2",
|
||||
"mongoose-unique-validator": "^2.0.2",
|
||||
"morgan": "^1.9.1",
|
||||
"nodemailer": "^4.7.0",
|
||||
"passport": "^0.4.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"python-struct": "^1.0.6",
|
||||
"showdown": "^1.8.6"
|
||||
"rand-token": "^0.4.0",
|
||||
"showdown": "^1.8.6",
|
||||
"winston": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^5.6.1",
|
||||
|
||||
@@ -6,6 +6,7 @@ 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');
|
||||
@@ -25,7 +26,7 @@ router.get('/news/:date/:title', (request, response) => {
|
||||
blogPostModel.getPost(moment(date), title_lower, (error, post) => {
|
||||
// error exists or no post exists with the date and name
|
||||
if (error || !post) {
|
||||
console.warn(`'error: ${error} and post: ${post}`);
|
||||
logger.log('warn', `error: ${error} and post: ${post}`);
|
||||
return utilHelper.send404(response);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ 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');
|
||||
@@ -69,7 +70,7 @@ router.post('/api/v1/sendmessage', (req, response) => {
|
||||
|
||||
// error handling
|
||||
request.on('error', (error) => {
|
||||
console.warn('request errored' + error);
|
||||
logger.log('warn', 'request errored' + error);
|
||||
return apiHelper.sendApiGenericError(response);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,11 +6,13 @@ 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('../mailer');
|
||||
const config = require('../config.json');
|
||||
const Recaptcha = require('express-recaptcha').Recaptcha;
|
||||
const recaptcha = new Recaptcha(config.recaptcha.siteKey, config.recaptcha.secretKey);
|
||||
@@ -19,11 +21,11 @@ const recaptcha = new Recaptcha(config.recaptcha.siteKey, config.recaptcha.secre
|
||||
const PNID = require('../models/pnid');
|
||||
|
||||
// renders register page
|
||||
router.get('/pnid/register', recaptcha.middleware.render, (request, response) => {
|
||||
router.get('/pnid/register', (request, response) => {
|
||||
return response.render('register', {
|
||||
title: 'Pretendo | Register',
|
||||
captcha: response.recaptcha,
|
||||
locale: utilHelper.getLocale('US', 'en')
|
||||
locale: utilHelper.getLocale('US', 'en'),
|
||||
recaptcha_sitekey: config.recaptcha.siteKey
|
||||
});
|
||||
});
|
||||
// renders login page
|
||||
@@ -92,36 +94,58 @@ router.post('/api/v1/login', passport.authenticate('PNIDStrategy'), function (re
|
||||
*/
|
||||
router.post('/api/v1/register', recaptcha.middleware.verify, async (request, response) => {
|
||||
if (!request.body) {
|
||||
// no post body
|
||||
return apiHelper.sendApiGenericError(response);
|
||||
}
|
||||
/*if (request.recaptcha.error) {
|
||||
apiHelper.sendApiError(response, 500, ['Captcha error']);
|
||||
return;
|
||||
}*/
|
||||
|
||||
const { email, password } = 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: {
|
||||
key: 'abcd',
|
||||
pid: await PNID.PNIDModel.generatePID()
|
||||
pid: await PNID.PNIDModel.generatePID(),
|
||||
username,
|
||||
username_lower: username.toLowerCase()
|
||||
}
|
||||
});
|
||||
|
||||
// TODO verify password
|
||||
|
||||
// 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.key
|
||||
pnid: user.pnid.pid
|
||||
});
|
||||
}).catch((rejection) => {
|
||||
// TODO format exception so it doesnt have a huge list of errors
|
||||
console.warn(rejection);
|
||||
logger.log('warn', rejection);
|
||||
return apiHelper.sendApiError(response, 500, [rejection]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ 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');
|
||||
@@ -98,11 +99,12 @@ app.use((request, response) => {
|
||||
// TODO remove param decoding errors from logs example: "host/test/%"
|
||||
// 4 parameters required to read the error, cant help the eslint error
|
||||
app.use((error, request, response, next) => { // eslint-disable-line no-unused-vars
|
||||
console.warn(error.stack);
|
||||
logger.log('warn', 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}`);
|
||||
});
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
{{> head-common }}
|
||||
<!-- page specific -->
|
||||
<link rel="stylesheet" href="/assets/css/pretendo-auth.css">
|
||||
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||
<script src="/assets/js/auth.js" defer></script>
|
||||
</head>
|
||||
<body class="flex center">
|
||||
@@ -12,17 +14,20 @@
|
||||
<div class="content">
|
||||
<p class="txt-highlight">{{ locale.register.card.caption }}</p>
|
||||
<h1 class="txt-title small">{{ locale.register.card.title }}</h1>
|
||||
<form action="/api/v1/sendmessage" method="POST">
|
||||
<form action="/api/v1/register" method="POST">
|
||||
<label for="email">{{ locale.register.card.email_text }}</label>
|
||||
<input type="text" class="hasLabel" id="email_input" name="email">
|
||||
<label for="email">{{ locale.register.card.username_text }}</label>
|
||||
<label for="username">{{ locale.register.card.username_text }}</label>
|
||||
<input type="text" class="hasLabel" id="username_input" name="username">
|
||||
<label for="email">{{ locale.register.card.password_text }}</label>
|
||||
<label for="password">{{ locale.register.card.password_text }}</label>
|
||||
<input type="password" class="hasLabel" id="password_input" name="password">
|
||||
<label for="email">{{ locale.register.card.password_confirm_text }}</label>
|
||||
<label for="confirm_password">{{ locale.register.card.password_confirm_text }}</label>
|
||||
<input type="password" class="hasLabel" id="password_confirm_input" name="confirm_password">
|
||||
|
||||
<div class="g-recaptcha" data-sitekey="{{ recaptcha_sitekey }}"></div>
|
||||
|
||||
<button type="submit" class="btn btnMargin">ERROR</button>
|
||||
</form>
|
||||
<button class="btn btnMargin" onclick="register()">ERROR</button>
|
||||
<p class="lowText">ERROR <a href="#">ERROR</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user