Merge pull request #13 from RedDuckss/dev

Added more locale stuff, added morgan, removed body-parser, misc changes
This commit is contained in:
mrjvs 2018-11-25 12:22:44 +01:00 committed by GitHub
commit 908269d20c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 2958 additions and 702 deletions

View File

@ -6,8 +6,8 @@ common api returns
*/
// use for any api return. it has basic layout used for every return.
function sendReturn(res, data, errors) {
res.status(200).json(
function sendReturn(response, data, errors) {
response.status(200).json(
// combine 2 objects
Object.assign({
code: 200,
@ -17,10 +17,9 @@ function sendReturn(res, data, errors) {
);
}
// use if api endpoint doesnt exist
function sendApi404(res) {
res.status(404).json({
function sendApi404(response) {
response.status(404).json({
code: 404,
errors: [
'Endpoint not in use'
@ -29,8 +28,8 @@ function sendApi404(res) {
}
// use if not logged in and is required (handled with middleware)
function sendApiAuthError(res) {
res.status(401).json({
function sendApiAuthError(response) {
response.status(401).json({
code: 401,
errors: [
'Not authenticated'
@ -39,8 +38,8 @@ function sendApiAuthError(res) {
}
// use for completely broken requests
function sendApiGenericError(res) {
res.status(400).json({
function sendApiGenericError(response) {
response.status(400).json({
code: 400,
success: false,
errors: [
@ -50,8 +49,8 @@ function sendApiGenericError(res) {
}
// use for any api not successfull
function sendApiError(res, code, errors) {
res.status(code).json({
function sendApiError(response, code, errors) {
response.status(code).json({
code,
success: false,
errors

View File

@ -5,6 +5,8 @@ small commonly used utilities
*/
const fs = require('fs-extra');
// shows 404 template. takes express response object
function send404(res) {
res.status(404).send('404');
@ -20,12 +22,44 @@ function templateReadyUser(req) {
};
}
// 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 require('../locales/US_en.json');
return [];
}
// Returns a locale
function getLocale(region, language) {
const path = `${__dirname}/../locales/${region}_${language}.json`;
if (fs.pathExistsSync(path)) {
return require(path);
}
console.warn(`Could not find locale ${region}_${language}! Loading default`);
return getDefaultLocale();
}
// Returns the default locale
function getDefaultLocale(locale='default') {
return require(`${__dirname}/../locales/${locale}.json`);
}
module.exports = {
send404,
templateReadyUser,
getLocales
getLocales,
getLocale,
getDefaultLocale
};

View File

@ -10,12 +10,23 @@
"logout": "Logout"
}
},
"about": {
"title": "About",
"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 family of console games to their fullest capacity."
"home": {
"header": {
"title": "Pretendo",
"text": "An open source Nintendo Network replacement service"
}
},
"credits": {
"title": "Credits"
"progress": {
"summary": {
"title": "Progress Summary",
"text": "We should probably pull this from a database ngl"
},
"compatability": {
"title": "Game Compatability"
},
"misc": {
"title": "Other"
}
},
"contact": {
"title": "Contact Us",
@ -24,23 +35,34 @@
"subject_placeholder": "Subject",
"message_placeholder": "Message"
},
"login_card": {
"title": "Login",
"email_text": "Username or Email",
"password_text": "Password",
"email_placeholder": "email@provider.com",
"password_placeholder": "••••••••",
"button_text": "Sign In"
"login": {
"card": {
"title": "Login",
"email_text": "Username or Email",
"password_text": "Password",
"email_placeholder": "email@provider.com",
"password_placeholder": "••••••••",
"button_text": "Sign In"
}
},
"register_card": {
"title": "Register",
"email_text": "Email Address",
"username_text": "Username",
"password_text": "Password",
"password_confirm_text": "Confirm Password",
"email_placeholder": "email@provider.com",
"password_placeholder": "••••••••",
"caption": "Sign Up"
"register": {
"card": {
"title": "Register",
"email_text": "Email Address",
"username_text": "Username",
"password_text": "Password",
"password_confirm_text": "Confirm Password",
"email_placeholder": "email@provider.com",
"password_placeholder": "••••••••",
"caption": "Sign Up"
}
},
"about": {
"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."
},
"credits": {
"title": "Credits"
},
"errors": {
"invalid_login": "Invalid username/password combination",

74
locales/default.json Normal file
View File

@ -0,0 +1,74 @@
{
"nav": {
"brand": "ERROR",
"links": {
"news": "ERROR",
"progress": "ERROR",
"contact": "ERROR",
"login": "ERROR",
"register": "ERROR",
"logout": "ERROR"
}
},
"home": {
"header": {
"title": "ERROR",
"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",
"email_text": "ERROR",
"username_text": "ERROR",
"password_text": "ERROR",
"password_confirm_text": "ERROR",
"email_placeholder": "ERROR",
"password_placeholder": "ERROR",
"caption": "ERROR"
}
},
"about": {
"title": "ERROR",
"text": "ERROR"
},
"credits": {
"title": "ERROR"
},
"errors": {
"invalid_login": "ERROR",
"account_exists": "ERROR"
},
"footer": {
"text": "ERROR"
}
}

3007
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,28 +10,30 @@
},
"author": "The Pretendo Network (@PretendoNetwork)",
"authors": [
"@superwhiskers",
"@lukeeey"
"@mrjvs",
"@jip"
],
"license": "ISC",
"dependencies": {
"bcrypt": "^3.0.1",
"body-parser": "^1.18.3",
"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",
"passport": "^0.4.0",
"passport-local": "^1.0.0",
"python-struct": "^1.0.6",
"showdown": "^1.8.6"
},
"devDependencies": {
"eslint": "^5.6.1"
"eslint": "^5.6.1",
"nodemon": "^1.18.6"
}
}

View File

@ -10,7 +10,6 @@ const router = require('express').Router();
const passport = require('passport');
const moment = require('moment');
const apiHelper = require('../helpers/api');
const utilHelper = require('../helpers/util');
const userMiddleware = require('../middleware/authentication');
// database models
@ -20,8 +19,10 @@ const postAuthor = require('../models/post-author');
const progressList = require('../models/progress-list');
// renders admin.hbs
router.get('/admin', (req, res) => {
res.render('admin');
router.get('/admin', (request, response) => {
response.render('admin', {
title: 'Pretendo | Admin',
});
});
/*
@ -43,11 +44,13 @@ router.get('/admin', (req, res) => {
*/
// 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'), function (req, res) {
apiHelper.sendReturn(res, {
username: req.user.username,
locales: utilHelper.getLocales(),
role: req.user.role ? req.user.role : undefined
router.post('/admin/api/v1/login', passport.authenticate('adminUserStrategy'), (request, response) => {
const user = request.user;
return apiHelper.sendReturn(response, {
username: user.username,
locale: user.getLocale(), // calls 'utilHelper.getLocale(user.region, user.language)' maybe?
role: user.role ? user.role : undefined
});
});
@ -69,14 +72,13 @@ router.post('/admin/api/v1/login', passport.authenticate('adminUserStrategy'), f
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/register', userMiddleware.adminAuthNeeded, (req, res) => {
if (!req.body) {
router.post('/admin/api/v1/register', userMiddleware.adminAuthNeeded, (request, response) => {
if (!request.body) {
// no post body
apiHelper.sendApiGenericError(res);
return;
return apiHelper.sendApiGenericError(response);
}
const { username, password } = req.body;
const { username, password } = request.body;
const newUser = new adminUser.adminUserModel({
username,
password
@ -84,15 +86,13 @@ router.post('/admin/api/v1/register', userMiddleware.adminAuthNeeded, (req, res)
// saving to database
newUser.save().then((user) => {
apiHelper.sendReturn(res, {
return apiHelper.sendReturn(response, {
username: user.username,
role: user.role ? user.role : undefined
});
return;
}).catch((rejection) => {
// TODO format exception so it doesnt have a huge list of errors
apiHelper.sendApiError(res, 500, [rejection]);
return;
return apiHelper.sendApiError(response, 500, [rejection]);
});
});
@ -111,18 +111,19 @@ router.post('/admin/api/v1/register', userMiddleware.adminAuthNeeded, (req, res)
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/removeadmin', userMiddleware.adminAuthNeeded, (req, res) => {
if (!req.body) {
router.post('/admin/api/v1/removeadmin', userMiddleware.adminAuthNeeded, (request, response) => {
if (!request.body) {
// no post body
apiHelper.sendApiGenericError(res);
return;
return apiHelper.sendApiGenericError(response);
}
const { id } = req.body;
adminUser.adminUserModel.findByIdAndDelete(id, (err) => {
if (err) return apiHelper.sendApiError(res, 500, [err]);
const { id } = request.body;
adminUser.adminUserModel.findByIdAndDelete(id, (error) => {
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
// successfull
apiHelper.sendReturn(res, {});
return apiHelper.sendReturn(response, {});
});
});
@ -138,10 +139,12 @@ router.post('/admin/api/v1/removeadmin', userMiddleware.adminAuthNeeded, (req, r
* errors: Strings[messages]
* }
*/
router.get('/admin/api/v1/listadmins', userMiddleware.adminAuthNeeded, (req, res) => {
adminUser.adminUserModel.find({}, (err, admins) => {
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 (err) return apiHelper.sendApiError(res, 500, [err]);
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
// formats admin list and removes password hash
const output = [];
@ -150,7 +153,7 @@ router.get('/admin/api/v1/listadmins', userMiddleware.adminAuthNeeded, (req, res
output.push(admins[i]);
}
apiHelper.sendReturn(res, {
return apiHelper.sendReturn(response, {
admins: output
});
});
@ -169,10 +172,12 @@ router.get('/admin/api/v1/listadmins', userMiddleware.adminAuthNeeded, (req, res
* errors: Strings[messages]
* }
*/
router.get('/admin/api/v1/check', userMiddleware.authOptional, (req, res) => {
apiHelper.sendReturn(res, {
isAuthed: req.user ? true : false,
role: req.user ? (req.user.role ? req.user.role : undefined) : undefined
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
});
});
@ -187,9 +192,9 @@ router.get('/admin/api/v1/check', userMiddleware.authOptional, (req, res) => {
* errors: Strings[messages]
* }
*/
router.get('/admin/api/v1/logout', userMiddleware.adminAuthNeeded, (req, res) => {
req.logout();
apiHelper.sendReturn(res, {});
router.get('/admin/api/v1/logout', userMiddleware.adminAuthNeeded, (request, response) => {
request.logout();
return apiHelper.sendReturn(response, {});
});
/*
@ -212,11 +217,13 @@ router.get('/admin/api/v1/logout', userMiddleware.adminAuthNeeded, (req, res) =>
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/newpost', userMiddleware.adminAuthNeeded, function (req, res) {
router.post('/admin/api/v1/newpost', userMiddleware.adminAuthNeeded, (request, response) => {
if (!req.body) return apiHelper.sendApiGenericError(res);
if (!request.body) {
return apiHelper.sendApiGenericError(response);
}
const { content, title, author, category, short } = req.body;
const { content, title, author, category, short } = request.body;
const newBlogPost = new blogPost.blogPostModel({
content: blogPost.blogPostModel.markdownToHtml(content),
name: title,
@ -234,13 +241,12 @@ router.post('/admin/api/v1/newpost', userMiddleware.adminAuthNeeded, function (r
// saving post to database
newBlogPost.save().then((post) => {
apiHelper.sendReturn(res, {
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
apiHelper.sendApiError(res, 500, [rejection]);
return;
return apiHelper.sendApiError(response, 500, [rejection]);
});
});
@ -264,21 +270,25 @@ router.post('/admin/api/v1/newpost', userMiddleware.adminAuthNeeded, function (r
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/editpost', userMiddleware.adminAuthNeeded, function (req, res) {
router.post('/admin/api/v1/editpost', userMiddleware.adminAuthNeeded, (request, response) => {
if (!req.body) return apiHelper.sendApiGenericError(res);
if (!request.body) {
return apiHelper.sendApiGenericError(response);
}
const { id, content, title, author, category, short } = req.body;
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
}, (err, post) => {
if (err) return apiHelper.sendApiError(res, 500, [err]);
}, (error, post) => {
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
apiHelper.sendReturn(res, {
return apiHelper.sendReturn(response, {
url: moment(post.meta.date, 'YYYY-MM-DD') + '/' + post.meta.slug
});
});
@ -301,11 +311,13 @@ router.post('/admin/api/v1/editpost', userMiddleware.adminAuthNeeded, function (
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/newauthor', userMiddleware.adminAuthNeeded, function (req, res) {
router.post('/admin/api/v1/newauthor', userMiddleware.adminAuthNeeded, (request, response) => {
if (!req.body) return apiHelper.sendApiGenericError(res);
if (!request.body) {
return apiHelper.sendApiGenericError(response);
}
const { name, description, image } = req.body;
const { name, description, image } = request.body;
const newAuthor = new postAuthor.postAuthorModel({
name,
description,
@ -314,13 +326,12 @@ router.post('/admin/api/v1/newauthor', userMiddleware.adminAuthNeeded, function
// saving author to database
newAuthor.save().then((author) => {
apiHelper.sendReturn(res, {
return apiHelper.sendReturn(response, {
id: author.id
});
}).catch((rejection) => {
// TODO format exception so it doesnt have a huge list of errors
apiHelper.sendApiError(res, 500, [rejection]);
return;
return apiHelper.sendApiError(response, 500, [rejection]);
});
});
@ -342,21 +353,26 @@ router.post('/admin/api/v1/newauthor', userMiddleware.adminAuthNeeded, function
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/editauthor', userMiddleware.adminAuthNeeded, function (req, res) {
router.post('/admin/api/v1/editauthor', userMiddleware.adminAuthNeeded, (request, response) => {
if (!req.body) return apiHelper.sendApiGenericError(res);
if (!request.body) {
return apiHelper.sendApiGenericError(response);
}
const { id, name, description, image } = req.body;
const { id, name, description, image } = request.body;
// updating author in database
postAuthor.postAuthorModel.findByIdAndUpdate(id, {
name,
description,
image
}, (err, author) => {
}, (error, author) => {
// TODO format exception so it doesnt have a huge list of errors
if (err) return apiHelper.sendApiError(res, 500, [err]);
apiHelper.sendReturn(res, {
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
return apiHelper.sendReturn(response, {
id: author.id
});
});
@ -379,13 +395,15 @@ router.post('/admin/api/v1/editauthor', userMiddleware.adminAuthNeeded, function
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/newprogress', userMiddleware.adminAuthNeeded, function (req, res) {
router.post('/admin/api/v1/newprogress', userMiddleware.adminAuthNeeded, (request, response) => {
if (!req.body) return apiHelper.sendApiGenericError(res);
if (!request.body) {
return apiHelper.sendApiGenericError(response);
}
// parses state and isGame to be valid
const { title, description } = req.body;
let { state } = req.body;
const { title, description } = request.body;
let { state } = request.body;
let isGame = false;
if (state != '1' && state != '2' && state != '3') {
state = undefined;
@ -403,13 +421,12 @@ router.post('/admin/api/v1/newprogress', userMiddleware.adminAuthNeeded, functio
// saving progress to database
newProgress.save().then((progress) => {
apiHelper.sendReturn(res, {
return apiHelper.sendReturn(response, {
id: progress.id
});
}).catch((rejection) => {
// TODO format exception so it doesnt have a huge list of errors
apiHelper.sendApiError(res, 500, [rejection]);
return;
return apiHelper.sendApiError(response, 500, [rejection]);
});
});
@ -431,13 +448,15 @@ router.post('/admin/api/v1/newprogress', userMiddleware.adminAuthNeeded, functio
* errors: Strings[messages]
* }
*/
router.post('/admin/api/v1/editprogress', userMiddleware.adminAuthNeeded, function (req, res) {
router.post('/admin/api/v1/editprogress', userMiddleware.adminAuthNeeded, (request, response) => {
if (!req.body) return apiHelper.sendApiGenericError(res);
if (!request.body) {
return apiHelper.sendApiGenericError(response);
}
// parsing state and isGame to be valid
const { title, description, id } = req.body;
let { state } = req.body;
const { title, description, id } = request.body;
let { state } = request.body;
let isGame = false;
if (state != '1' && state != '2' && state != '3') {
state = undefined;
@ -452,18 +471,21 @@ router.post('/admin/api/v1/editprogress', userMiddleware.adminAuthNeeded, functi
description,
state,
isGame
}, (err, progress) => {
}, (error, progress) => {
// TODO format exception so it doesnt have a huge list of errors
if (err) return apiHelper.sendApiError(res, 500, [err]);
apiHelper.sendReturn(res, {
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
return apiHelper.sendReturn(response, {
id: progress.id
});
});
});
// api 404
router.use('/admin/api', (req, res) => {
apiHelper.sendApi404(res);
router.use('/admin/api', (request, response) => {
return apiHelper.sendApi404(response);
});
// export the router

View File

@ -14,39 +14,47 @@ const blogPostModel = require('../models/blog-post').blogPostModel;
const postAuthorModel = require('../models/post-author').postAuthorModel;
// display single blog post
router.get('/news/:date/:title', (req, res) => {
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(req.params.date) && /([a-z]|[0-9]|-)+/.test(req.params.title.toLowerCase())) {
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(req.params.date), req.params.title.toLowerCase(), (err, post) => {
blogPostModel.getPost(moment(date), title_lower, (error, post) => {
// error exists or no post exists with the date and name
if (err || !post) {
console.log('error: ' + err + ' and post: ' + post);
return utilHelper.send404(res);
if (error || !post) {
console.warn(`'error: ${error} and post: ${post}`);
return utilHelper.send404(response);
}
// render blogpost
post.postTemplate((err, postTemplate) => {
if (err) return utilHelper.send404(res);
res.render('post', {
post.postTemplate((error, postTemplate) => {
if (error) {
return utilHelper.send404(response);
}
return response.render('post', {
title,
post: postTemplate,
user: utilHelper.templateReadyUser(req),
locales: utilHelper.getLocales()
user: utilHelper.templateReadyUser(request),
locale: utilHelper.getLocale('US', 'en')
});
});
});
} else {
// params are incorrect
utilHelper.send404(res);
return utilHelper.send404(response);
}
});
// display latest blogposts
router.get('/news', (req, res) => {
router.get('/news', (request, response) => {
// sort blogposts on date descending
blogPostModel.find({}).sort({'meta.date': 'desc'}).exec(function(err, posts) {
if (err || !posts) {
return utilHelper.send404(res);
blogPostModel.find({}).sort({'meta.date': 'desc'}).exec((error, posts) => {
if (error || !posts) {
return utilHelper.send404(response);
}
// makes posts template ready
@ -55,10 +63,11 @@ router.get('/news', (req, res) => {
postCollection.push(posts[i].postShortTemplate());
}
res.render('post-collection', {
return response.render('post-collection', {
title: 'Pretendo | News',
posts: postCollection,
user: utilHelper.templateReadyUser(req),
locales: utilHelper.getLocales(),
user: utilHelper.templateReadyUser(request),
locale: utilHelper.getLocale('US', 'en'),
page: 'news'
});
});
@ -76,11 +85,14 @@ router.get('/news', (req, res) => {
* errors: Strings[messages]
* }
*/
router.get('/api/v1/listauthors', function (req, res) {
postAuthorModel.find({}, (err, authors) => {
router.get('/api/v1/listauthors', (request, response) => {
postAuthorModel.find({}, (error, authors) => {
// TODO format exception so it doesnt have a huge list of errors
if (err) return apiHelper.sendApiError(res, 500, [err]);
apiHelper.sendReturn(res, {
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
return apiHelper.sendReturn(response, {
authorList: authors
});
});
@ -98,11 +110,14 @@ router.get('/api/v1/listauthors', function (req, res) {
* errors: Strings[messages]
* }
*/
router.get('/api/v1/listblog', function (req, res) {
blogPostModel.find({}, (err, posts) => {
router.get('/api/v1/listblog', (request, response) => {
blogPostModel.find({}, (error, posts) => {
// TODO format exception so it doesnt have a huge list of errors
if (err) return apiHelper.sendApiError(res, 500, [err]);
apiHelper.sendReturn(res, {
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
apiHelper.sendReturn(response, {
postList: posts
});
});

View File

@ -13,10 +13,11 @@ const config = require('../config.json');
const https = require('https');
// display contact page
router.get('/contact', (req, res) => {
res.render('contact', {
user: utilHelper.templateReadyUser(req),
locales: utilHelper.getLocales(),
router.get('/contact', (request, response) => {
return response.render('contact', {
title: 'Pretendo | Contact',
user: utilHelper.templateReadyUser(request),
locale: utilHelper.getLocale('US', 'en'),
page: 'contact'
});
});
@ -37,8 +38,10 @@ router.get('/contact', (req, res) => {
* errors: Strings[messages]
* }
*/
router.post('/api/v1/sendmessage', function (req, res) {
if (!req.body) return apiHelper.sendApiGenericError(res);
router.post('/api/v1/sendmessage', (req, response) => {
if (!req.body) {
return apiHelper.sendApiGenericError(response);
}
const { email, subject, message } = req.body;
@ -61,13 +64,13 @@ router.post('/api/v1/sendmessage', function (req, res) {
}
}, () => {
// sends success
apiHelper.sendReturn(res, {});
return apiHelper.sendReturn(response, {});
});
// error handling
request.on('error', (e) => {
apiHelper.sendApiGenericError(res);
console.log('request errored' + e);
request.on('error', (error) => {
console.warn('request errored' + error);
return apiHelper.sendApiGenericError(response);
});
// write post data to request
@ -75,7 +78,7 @@ router.post('/api/v1/sendmessage', function (req, res) {
request.end();
} else {
// TODO give more detailed response
return apiHelper.sendApiGenericError(res);
return apiHelper.sendApiGenericError(response);
}
});

View File

@ -12,12 +12,13 @@ const utilHelper = require('../helpers/util');
const blogPostModel = require('../models/blog-post').blogPostModel;
// display home page
router.get('/', (req, res) => {
router.get('/', (request, response) => {
// needs callback because mongoose is inconsistent
blogPostModel.latestPostsShortTemlate(2, (err, result) => {
res.render('home', {
user: utilHelper.templateReadyUser(req),
locales: utilHelper.getLocales(),
blogPostModel.latestPostsShortTemlate(2, (error, result) => {
return response.render('home', {
title: 'Pretendo | Home',
user: utilHelper.templateReadyUser(request),
locale: utilHelper.getLocale('US', 'en'),
posts: result,
page: 'home'
});

View File

@ -19,28 +19,31 @@ 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, (req, res) => {
res.render('register', {
captcha: res.recaptcha,
locales: utilHelper.getLocales()
router.get('/pnid/register', recaptcha.middleware.render, (request, response) => {
return response.render('register', {
title: 'Pretendo | Register',
captcha: response.recaptcha,
locale: utilHelper.getLocale('US', 'en')
});
});
// renders login page
router.get('/pnid/login', (req, res) => {
res.render('login', {
locales: utilHelper.getLocales()
router.get('/pnid/login', (request, response) => {
return response.render('login', {
title: 'Pretendo | Login',
locale: utilHelper.getLocale('US', 'en')
});
});
// logout
router.get('/pnid/logout', userMiddleware.pnidAuthNeeded, (req, res) => {
req.logout();
res.redirect('/');
router.get('/pnid/logout', userMiddleware.pnidAuthNeeded, (request, response) => {
request.logout();
return response.redirect('/');
});
// renders pnid dashboard
router.get('/pnid/dashboard', userMiddleware.pnidAuthNeeded, (req, res) => {
res.render('dashboard', {
locales: utilHelper.getLocales(),
user: utilHelper.templateReadyUser(req)
router.get('/pnid/dashboard', userMiddleware.pnidAuthNeeded, (request, response) => {
return response.render('dashboard', {
title: 'Pretendo | Dash',
locale: utilHelper.getLocale('US', 'en'),
user: utilHelper.templateReadyUser(request)
});
});
@ -63,11 +66,11 @@ router.get('/pnid/dashboard', userMiddleware.pnidAuthNeeded, (req, res) => {
*/
// 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 (req, res) {
apiHelper.sendReturn(res, {
email: req.user.email,
email_validated: req.user.email_validated,
pnid: req.user.pnid.key
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
});
});
@ -87,18 +90,17 @@ router.post('/api/v1/login', passport.authenticate('PNIDStrategy'), function (re
* errors: Strings[messages]
* }
*/
router.post('/api/v1/register', recaptcha.middleware.verify, async (req, res) => {
if (!req.body) {
router.post('/api/v1/register', recaptcha.middleware.verify, async (request, response) => {
if (!request.body) {
// no post body
apiHelper.sendApiGenericError(res);
return;
return apiHelper.sendApiGenericError(response);
}
/*if (req.recaptcha.error) {
apiHelper.sendApiError(res, 500, ['Captcha error']);
/*if (request.recaptcha.error) {
apiHelper.sendApiError(response, 500, ['Captcha error']);
return;
}*/
const { email, password } = req.body;
const { email, password } = request.body;
const newUser = new PNID.PNIDModel({
email,
password,
@ -112,17 +114,15 @@ router.post('/api/v1/register', recaptcha.middleware.verify, async (req, res) =>
// saving to database
newUser.save().then((user) => {
apiHelper.sendReturn(res, {
return apiHelper.sendReturn(response, {
email: user.email,
email_validated: user.email_validated,
pnid: user.pnid.key
});
return;
}).catch((rejection) => {
// TODO format exception so it doesnt have a huge list of errors
console.log(rejection);
apiHelper.sendApiError(res, 500, [rejection]);
return;
console.warn(rejection);
return apiHelper.sendApiError(response, 500, [rejection]);
});
});

View File

@ -12,20 +12,23 @@ const utilHelper = require('../helpers/util');
const progressListModel = require('../models/progress-list').progressListModel;
// display progress
router.get('/progress', (req, res) => {
router.get('/progress', (request, response) => {
progressListModel.find({}, (err, progress) => {
if (err) return utilHelper.send404(res);
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);
res.render('progress', {
return response.render('progress', {
title: 'Pretendo | Progress',
games,
backends,
user: utilHelper.templateReadyUser(req),
locales: utilHelper.getLocales(),
user: utilHelper.templateReadyUser(request),
locale: utilHelper.getLocale('US', 'en'),
page: 'progress'
});
});
@ -43,11 +46,14 @@ router.get('/progress', (req, res) => {
* errors: Strings[messages]
* }
*/
router.get('/api/v1/listprogress', function (req, res) {
progressListModel.find({}, (err, progress) => {
router.get('/api/v1/listprogress', (request, response) => {
progressListModel.find({}, (error, progress) => {
// TODO format exception so it doesnt have a huge list of errors
if (err) return apiHelper.sendApiError(res, 500, [err]);
apiHelper.sendReturn(res, {
if (error) {
return apiHelper.sendApiError(response, 500, [error]);
}
apiHelper.sendReturn(response, {
progressList: progress
});
});

View File

@ -11,7 +11,7 @@ const handlebars = require('express-handlebars');
const session = require('express-session');
const mongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const config = require('./config.json');
const utilHelper = require('./helpers/util');
const passportconfig = require('./passport.config.js');
@ -29,8 +29,11 @@ connection.on('error', console.error.bind(console, 'connection error:'));
// setup express
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(morgan('dev'));
app.use(express.json());
app.use(express.urlencoded({
extended: true
}));
app.use(session({
secret: config.secrets.session,
saveUninitialized: true,
@ -87,16 +90,16 @@ app.use('/', locations.posts);
app.use('/', locations.admin);
app.use('/', locations.progress);
app.use('/', locations.pnid);
app.use((req, res) => {
utilHelper.send404(res);
app.use((request, response) => {
return utilHelper.send404(response);
});
// TODO improve error handling
// TODO remove param decoding errors from logs example: "host/test/%"
// 4 parameters required to read the error, cant help the eslint error
app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
console.error(err.stack);
return res.status(500).send('Something broke!');
app.use((error, request, response, next) => { // eslint-disable-line no-unused-vars
console.warn(error.stack);
return response.status(500).send('Something broke!');
});
// startup

View File

@ -12,15 +12,15 @@
<section class="bigCardWrapper">
<div class="bigCard">
<p class="txt-highlight">ERROR</p>
<h1 class="txt-title">{{ locales.contact.title }}</h1>
<h1 class="txt-title">{{ locale.contact.title }}</h1>
<form action="/api/v1/sendmessage" method="POST">
<div class="input-container">
<input type="text" name="email" placeholder="{{ locales.contact.email_placeholder }}">
<input type="text" name="subject" placeholder="{{ locales.contact.subject_placeholder }}">
<input type="text" name="email" placeholder="{{ locale.contact.email_placeholder }}">
<input type="text" name="subject" placeholder="{{ locale.contact.subject_placeholder }}">
</div>
<textarea name="message" placeholder="{{ locales.contact.message_placeholder }}"></textarea>
<textarea name="message" placeholder="{{ locale.contact.message_placeholder }}"></textarea>
<div class="txt-center">
<button class="btn">{{ locales.contact.button_text }}</button>
<button class="btn">{{ locale.contact.button_text }}</button>
</div>
</form>
</div>

View File

@ -9,9 +9,9 @@
{{> nav-default }}
<div class="contentWrapper">
<header>
<h1>ERROR</h1>
<h1>{{ locale.home.header.title }}</h1>
<hr>
<h3>ERROR</h3>
<h3>{{ locale.home.header.text }}</h3>
</header>
</div>
<div class="contentWrapper bgLines">
@ -19,15 +19,15 @@
<section class="bigCardWrapper">
<div class="bigCard">
<p class="txt-highlight">ERROR</p>
<h1 class="txt-title">{{ locales.about.title }}</h1>
<p>{{ locales.about.text }}</p>
<h1 class="txt-title">{{ locale.about.title }}</h1>
<p>{{ locale.about.text }}</p>
</div>
</section>
<section class="bigCardWrapper">
<div class="bigCard">
<p class="txt-highlight">ERROR</p>
<h1 class="txt-title">{{ locales.credits.title }}</h1>
<h1 class="txt-title">{{ locale.credits.title }}</h1>
<div class="cardProfiles">
<!-- profile -->
<div class="profile">

View File

@ -8,17 +8,17 @@
</head>
<body class="flex center">
<div class="card">
<h2 class="head">{{ locales.nav.brand }}</h2>
<h2 class="head">{{ locale.nav.brand }}</h2>
<div class="content">
<p class="txt-highlight">ERROR</p>
<h1 class="txt-title small">{{ locales.login_card.title }}</h1>
<h1 class="txt-title small">{{ locale.login.card.title }}</h1>
<form action="/api/v1/sendmessage" method="POST">
<label for="email">{{ locales.login_card.email_text }}</label>
<label for="email">{{ locale.login.card.email_text }}</label>
<input type="text" class="hasLabel" id="email_input" name="email">
<label for="email">{{ locales.login_card.password_text }}</label>
<label for="email">{{ locale.login.card.password_text }}</label>
<input type="password" class="hasLabel" id="password_input" name="password">
</form>
<button class="btn btnMargin" onclick="login()">{{ locales.login_card.button_text }}</button>
<button class="btn btnMargin" onclick="login()">{{ locale.login.card.button_text }}</button>
<p class="lowText">ERROR <a href="#">ERROR</a></p>
</div>
</div>

View File

@ -1,5 +1,5 @@
<footer>
<div class="content">
<p>{{ locales.footer.text }}</p>
<p>{{ locale.footer.text }}</p>
</div>
</footer>

View File

@ -1,5 +1,5 @@
{{> metatags }}
<title>ERROR</title>
<title>{{ title }}</title>
<!-- css files -->
<link rel="stylesheet" href="/assets/css/pretendo-common.css">
<!-- scripts -->

View File

@ -1,8 +1,8 @@
<nav class="navWrapper" id="nav">
<a class="navItem brand{{#if_eq page 'home'}} active{{/if_eq}}" {{#if_neq page 'home'}}href="/"{{/if_neq}}>{{ locales.nav.brand }}</a>
<a class="navItem{{#if_eq page 'news'}} active{{/if_eq}}" {{#if_neq page 'news'}}href="/news"{{/if_neq}}>{{ locales.nav.links.news }}</a>
<a class="navItem{{#if_eq page 'progress'}} active{{/if_eq}}" {{#if_neq page 'progress'}}href="/progress"{{/if_neq}}>{{ locales.nav.links.progress }}</a>
<a class="navItem{{#if_eq page 'contact'}} active{{/if_eq}}" {{#if_neq page 'contact'}}href="/contact"{{/if_neq}}>{{ locales.nav.links.contact }}</a>
<a class="navItem brand{{#if_eq page 'home'}} active{{/if_eq}}" {{#if_neq page 'home'}}href="/"{{/if_neq}}>{{ locale.nav.brand }}</a>
<a class="navItem{{#if_eq page 'news'}} active{{/if_eq}}" {{#if_neq page 'news'}}href="/news"{{/if_neq}}>{{ locale.nav.links.news }}</a>
<a class="navItem{{#if_eq page 'progress'}} active{{/if_eq}}" {{#if_neq page 'progress'}}href="/progress"{{/if_neq}}>{{ locale.nav.links.progress }}</a>
<a class="navItem{{#if_eq page 'contact'}} active{{/if_eq}}" {{#if_neq page 'contact'}}href="/contact"{{/if_neq}}>{{ locale.nav.links.contact }}</a>
<div class="navSpread"></div>
{{#if user.isLoggedIn }}
<a class="navItem navProfile" href="/pnid/dashboard">
@ -11,8 +11,8 @@
</a>
<a class="navItem navBtn" href="/pnid/logout">logout</a>
{{else}}
<a class="navItem navBtnAlt" href="/pnid/login">{{ locales.nav.links.login }}</a>
<a class="navItem navBtn" href="/pnid/register">{{ locales.nav.links.register }}</a>
<a class="navItem navBtnAlt" href="/pnid/login">{{ locale.nav.links.login }}</a>
<a class="navItem navBtn" href="/pnid/register">{{ locale.nav.links.register }}</a>
{{/if}}
<a class="navItem hamburger" id="navToggle">ICON</a>
</nav>

View File

@ -8,18 +8,18 @@
</head>
<body class="flex center">
<div class="card">
<h2 class="head">{{ locales.nav.brand }}</h2>
<h2 class="head">{{ locale.nav.brand }}</h2>
<div class="content">
<p class="txt-highlight">{{ locales.register_card.caption }}</p>
<h1 class="txt-title small">{{ locales.register_card.title }}</h1>
<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">
<label for="email">{{ locales.register_card.email_text }}</label>
<label for="email">{{ locale.register.card.email_text }}</label>
<input type="text" class="hasLabel" id="email_input" name="email">
<label for="email">{{ locales.register_card.username_text }}</label>
<label for="email">{{ locale.register.card.username_text }}</label>
<input type="text" class="hasLabel" id="username_input" name="username">
<label for="email">{{ locales.register_card.password_text }}</label>
<label for="email">{{ locale.register.card.password_text }}</label>
<input type="password" class="hasLabel" id="password_input" name="password">
<label for="email">{{ locales.register_card.password_confirm_text }}</label>
<label for="email">{{ locale.register.card.password_confirm_text }}</label>
<input type="password" class="hasLabel" id="password_confirm_input" name="confirm_password">
</form>
<button class="btn btnMargin" onclick="register()">ERROR</button>