Files
PetitTeton/app/routes.js
2016-10-26 14:59:39 -07:00

442 lines
15 KiB
JavaScript

var ejs = require('ejs');
var fs = require('fs');
var path = require('path');
var adminPath;
var PRODUCT_LIST_PATH = "VAP_Availability_List_Oct2016.pdf";
//Notes:
//Use res.send or res.sendFile for static resources (like images or html)
//Use res.send(ejs.render(htmlStr, viewArgs)) to manually render EJS files
//Use res.render("my.ejs", {root: adminPath}) to render EJS files (if you have setup the ejs renderer
module.exports = function(app, rootPath, passport, smtpTransport, sequelize) {
adminPath = path.join(rootPath, 'admin');
// =====================================
// HOME PAGE (with login links)
// =====================================
//app.get('/', isLoggedIn, function(req, res) {
// res.render('index.ejs'); // load the index.ejs file
//});
//Handle the root being requested, and the search engine requesting a static page with content.
app.get('/', function(req, res) {
try {
//Note: This is for search engines.
if(typeof(req.query._escaped_fragment_) !== "undefined") {
console.log("Search Engine Detected");
var viewArgs = {}; //What args to use for a search engine?
//The DIY method which is somewhat brittle since it relies on <!--CONTENT--> existing in the index file, and it replaces that with the contents of the passed parameter (what is after the #!) for the content html which is inserted into the index file in place of <!--CONTENT-->.
fs.readFile(rootPath + '/index.html', {encoding: "UTF8"}, function(err, indexContent) {
if(!err) {
var file = rootPath + '/' + req.query._escaped_fragment_ + '.html';
fs.readFile(file, {encoding: "UTF8"}, function(err, content) {
if(!err) {
//Non-regex method.//
if(content.indexOf("<runonce>") != -1 && content.indexOf("</runonce>") != -1) {
content = content.substr(0, content.indexOf("<runonce>")) + content.substr(content.indexOf("</runonce>") + 10, -1);
}
//Doesn't work? Not sure why. Works in the regex test tools.//
//content = content.replace(/<runonce>(.|\n)*?<\x2frunonce>/, " ");
//Doesn't work? Based on the regex failure above, I think that replace is failing.//
var html = indexContent.replace(/<!--CONTENT-->/g, content);
//console.log(html);
//res.send(ejs.render(html, viewArgs));
res.send(html);
}
else console.log("Error reading the content file '" + file + "'. " + err);
});
}
else console.log("Error reading the index.html file. " + err);
});
}
else {
//res.render("index.html", {root: rootPath});
res.sendFile("index.html", {root: rootPath});
}
} catch(e) {
console.log(e);
}
});
app.get('/admin', isLoggedIn, function(req, res) {
try {
//Note: This is for search engines.
if(typeof(req.query._escaped_fragment_) !== "undefined") {
var viewArgs = {}; //What args to use for a search engine?
//The DIY method which is somewhat brittle since it relies on <!--CONTENT--> existing in the index file, and it replaces that with the contents of the passed parameter (what is after the #!) for the content html which is inserted into the index file in place of <!--CONTENT-->.
fs.readFile(adminPath + '/index.ejs', {encoding: "UTF8"}, function(err, indexContent) {
if(!err) {
var file = adminPath + '/' + req.query._escaped_fragment_ + '.ejs';
fs.readFile(file, {encoding: "UTF8"}, function(err, content) {
if(!err) {
//Non-regex method.//
if(content.indexOf("<runonce>") != -1 && content.indexOf("</runonce>") != -1) {
content = content.substr(0, content.indexOf("<runonce>")) + content.substr(content.indexOf("</runonce>") + 10, -1);
}
//Doesn't work? Not sure why. Works in the regex test tools.//
//content = content.replace(/<runonce>(.|\n)*?<\x2frunonce>/, " ");
//Doesn't work? Based on the regex failure above, I think that replace is failing.//
var html = indexContent.replace(/<!--CONTENT-->/g, content);
//console.log(html);
res.send(ejs.render(html, viewArgs));
}
else console.log("Error reading the content file '" + file + "'. " + err);
});
}
else console.log("Error reading the index.ejs file. " + err);
});
}
else {
//console.log("Looking for index.ejs in " + adminPath);
//res.render("index.ejs", {root: adminPath});
res.render(path.join(adminPath, req.baseUrl, "index"));
}
} catch(e) {console.log(e);}
});
app.use('/ContactUs', function(req, res) {
try {
var firstName = req.body.FirstName;
var lastName = req.body.LastName;
var email = req.body.Email;
var message = req.body.Text;
var params = {from: config.fromAddress, to: config.contactUsRecipient, subject: "Contact Us", text: "A user has commented via the Petit Teton website.\n\nFirst Name: " + firstName + "\nLast Name: " + lastName + "\nEmail: " + email + "\n" + message};
smtpTransport.sendMail(params, function(error, response) {
if(error) {
try {
console.log("Received an error while sending the contact us email to the admin. " + error);
fs.appendFile(rootPath + '/emailFailures.txt', JSON.stringify(params) + '\n', function(err) {if(err) {console.log("Failed to write email data to file! (contact us)");}});
} catch(e) {console.log(e);}
}
});
res.status(200).send('success');
} catch(e) {console.log(e);}
});
// =====================================
// LOGIN
// =====================================
// show the login form
app.get('/admin/login', function(req, res) {
// render the page and pass in any flash data if it exists
res.render(path.join(adminPath, req.baseUrl, 'login.ejs'), { message: req.flash('loginMessage') });
});
// process the login form
app.post('/admin/login', passport.authenticate('local-login', {successRedirect: '/admin', failureRedirect: '/admin/login', failureFlash: true}));
// =====================================
// SIGNUP
// =====================================
// show the signup form
/* Turned off since only admin users can add admin users.
app.get('/admin/signup', function(req, res) {
// render the page and pass in any flash data if it exists
res.render(path.join(adminPath, req.baseUrl, 'signup.ejs'), { message: req.flash('signupMessage') });
});
app.post('/admin/signup', passport.authenticate('local-signup', {successRedirect: '/admin', failureRedirect: '/admin/signup', failureFlash: true}));
*/
// =====================================
// PROFILE SECTION
// =====================================
// we will want this protected so you have to be logged in to visit
// we will use route middleware to verify this (the isLoggedIn function)
app.get('/admin/profile', isLoggedIn, function(req, res) {
res.render(path.join(adminPath, req.baseUrl, 'profile.ejs'), {
user : req.user // get the user out of session and pass to template
});
});
// =====================================
// LOGOUT
// =====================================
app.get('/admin/logout', function(req, res) {
req.logout();
res.redirect('/');
});
// Check for an ejs first even if an html is requested.
app.get('/admin/*.html', isLoggedIn, function(req, res) {
var ejs = req.path.substring(0, req.path.length - 4) + "ejs";
//console.log("Checking for an ejs: " + ejs);
fs.stat(path.join(rootPath, ejs), function(err, stats) {
if(!err) {
res.render(path.join(rootPath, ejs));
}
else {
res.sendFile(path.join(rootPath, req.path));
//res.sendFile(req.path);
}
});
});
/* Test code to find all Categories and Subcategories.
sequelize.models.Category.findAll({
include:
[
{model: sequelize.models.Subcategory, paranoid: true, as: 'subcategories'}
],
order: ['name', ['name']]
}).then(function(values) {
console.log(values);
}).catch(function(err) {
console.log(err);
});
*/
app.use('/ProductList', function(req, res) {
try {
res.sendFile(path.join(rootPath, PRODUCT_LIST_PATH));
}
catch(e) {
console.log(e);
}
});
//Allows the client to query using the models defined by the application. Returns status codes or the results of the queries.
app.use('/admin/data/:cls/:query', isLoggedIn, function(req, res) {
try {
if(req.user.admin) {
//var params = Object.keys(req.body).length == 0 ? req.query : req.body; //Use the Request.query if Request.body is empty.
var params = req.query;
var cls = req.params.cls;
var query = req.params.query;
var model = sequelize.models[cls];
//Merge the Request.body parameters into the params object.
//TODO: Can we just use extend?
Object.keys(req.body).forEach(function(key) {params[key] = req.body[key]});
// if(params.msgpack) {
// params = msgpack.decode(params.msgpack);
// }
if(!model) {
res.status(400).end();
}
else {
res.header("Cache-Control", "no-cache, no-store, must-revalidate");
res.header("Pragma", "no-cache");
res.header("Expires", 0);
switch(query) {
case 'readAll':
case 'findAll':
case 'getAll': {
//Check the params for model references that need to be linked to the correct class. Example:
//{include: [{model: 'Subcategory', paranoid: true, as: 'subcategories'}], order: ['name', ['name']]}
if(params.include) {
var include = params.include;
for(var includeIndex = 0; includeIndex < include.length; includeIndex++) {
var nextInclude = include[includeIndex];
if(nextInclude.model) {
nextInclude.model = sequelize.models[nextInclude.model];
}
}
}
model.findAll(params).then(function(values) {
res.json(values);
}).catch(function(err) {
console.log(err);
res.status(400).end();
});
break;
}
case 'read':
case 'readOne':
case 'readFirst':
case 'find':
case 'findOne':
case 'findFirst':
case 'get':
case 'getFirst':
case 'getOne': {
//Check the params for model references that need to be linked to the correct class. Example:
//{include: [{model: 'Subcategory', paranoid: true, as: 'subcategories'}], order: ['name', ['name']]}
if(params.include) {
var include = params.include;
for(var includeIndex = 0; includeIndex < include.length; includeIndex++) {
var nextInclude = include[includeIndex];
if(nextInclude.model) {
nextInclude.model = sequelize.models[nextInclude.model];
}
}
}
model.find(params).then(function(value) {
res.json(value);
}).catch(function(err) {
console.log(err);
res.status(400).end();
});
break;
}
case 'create':
case 'insert':
case 'new': {
model.create(params).then(function(user) {
//res.json({result: 'success'});
res.status(200).end();
}).catch(function(err) {
console.log(err);
//res.json({result: 'duplicate'});
res.status(400).end();
});
break;
}
case 'delete':
case 'remove':
case 'destroy': {
//params: {where: {id: myId}}
model.destroy(params).then(function(count) {
if(count == 1) {
//res.json({result: 'success'});
res.status(200).end();
}
else {
//res.json({result: 'failure'});
res.status(400).end();
}
}).catch(function(err) {
console.log(err);
//res.json({result: 'failure'});
res.status(400).end();
});
break;
}
case 'restore': {
model.find(params).then(function(value) {
if(value) {
value.deletedAt = null;
value.save().then(function() {
res.status(200).end();
}).catch(function(err) {
console.log(err);
res.status(400).end();
});
}
else {
res.status(400).end();
}
}).catch(function(err) {
console.log(err);
res.status(400).end();
});
break;
}
case 'update':
case 'change':
case 'edit':
case 'modify': {
model.findById(params.id, {}).then(function(myModel) {
for(var key in params) {
if(key != 'id') {
myModel[key] = params[key];
}
}
return myModel.save();
}).then(function() {
//res.json({result: 'success'});
res.status(200).end();
}).catch(function(err) {
console.log(err);
//res.json({result: 'failure'});
res.status(400).end();
});
break;
}
default: {
res.status(400).end();
break;
}
}
}
}
else {
//TODO: Return some kind of error.
res.status(400).end();
}
}
catch(e) {console.log(e); res.status(400).end();}
});
/*
app.get('/admin/getCategories', isLoggedIn, function(req, res) {
sequelize.models.Category.findAll({attributes: ['id', 'name', 'visible'], order: [['name', 'DESC'], ['visible', 'DESC']]}).then(function(values) {
res.json(values);
});
});
app.get('/admin/getSubcategories', isLoggedIn, function(req, res) {
sequelize.models.Subcategory.findAll({where: {categoryId: req.query.id}, attributes: ['id', 'name', 'visible'], order: [['name', 'DESC'], ['visible', 'DESC']]}).then(function(values) {
res.json(values);
}).catch(function(error) {
console.log(error);
res.json("[]");
});
});
app.get('/admin/getItems', isLoggedIn, function(req, res) {
sequelize.models.Item.findAll({where: {subcategoryId: req.query.id}, attributes: ['id', 'name', 'counts', 'visible', 'subcategoryId'], order: [['name', 'DESC'], ['visible', 'DESC']]}).then(function(values) {
res.json(values);
});
});
app.get('/admin/getMeasures', isLoggedIn, function(req, res) {
sequelize.models.Measure.findAll({attributes: ['id', 'name', "image", 'postfix', 'visible'], order: [['name', 'DESC'], ['visible', 'DESC']]}).then(function(values) {
res.json(values);
});
});
app.get('/admin/getVenues', isLoggedIn, function(req, res) {
sequelize.models.Venue.findAll({attributes: ['id', 'name', 'visible'], order: [['name', 'DESC'], ['visible', 'DESC']]}).then(function(values) {
res.json(values);
});
});
app.get('/admin/toggleVenueVisibility', isLoggedIn, function(req, res) {
sequelize.models.Venue.find({where: {id: req.query.id}, attributes: ['id', 'name', 'visible']}).then(function(venue) {
if(venue) {
venue.visible = venue.visible ? false : true;
venue.save().then(function() {
res.json({visible: venue.visible});
}).catch(function(error) {
res.json({error: error});
});
}
else {
res.json({error: "Can't find the venue!"});
}
});
});
*/
};
// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {
if(req.isAuthenticated()) return next();
//Redirect if the user isn't logged in.
res.redirect('/admin/login');
}