442 lines
15 KiB
JavaScript
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');
|
|
} |