Files
PetitTeton/app.js

414 lines
16 KiB
JavaScript
Raw Normal View History

//NOT USED!!!
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
//var bodyParser = require('body-parser'); //Dup?
var nodeMailer = require('nodeMailer');
var bodyParser = require('body-parser');
var phantom = require('node-phantom');
var fs = require('fs');
var rootPath = path.join(__dirname, 'public');
var config = require('./config');
var moment = require('moment');
var methodOverride = require("method-override");
var session = require("express-session");
var passport = require("passport");
var localStrategy = require("passport-local");
var app = express();
app.use(logger('dev'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(methodOverride('X-HTTP-Method-Override'));
app.use(session({secret: 'au*2(_io?MajesticPeakMountainBoarding', saveUninitialized: true, resave: true}));
app.use(passport.initialize());
app.use(passport.session());
app.use(favicon(__dirname + '/public/images/Chicken.ico'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
//Ensure we have an endsWith method in String.
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
/*
//Check for all calls to content pages with a password attached and log it in the password's counter.
app.use(function(req, res, next) {
if(req.path.endsWith('.html')) {
if(req.query.Password) {
incrementPwdUseCount(req.query.Password);
}
}
next();
});
*/
app.use(express.static(rootPath, {dotfiles: 'deny', index: false}));
//app.use('/', routes);
app.use('/FrameworkController.java', function(req, res) {
console.log("In /FrameworkController.java");
var requestParam = req.query.Request;
if(requestParam == 'CreateId') {
res.type('json');
res.send({result: 0});
}
else {
console.log('unexpected value');
res.status(400).send('Unexpected Param');
}
});
//Handle the getting a brief and contacting us.
var smtpTransport = nodeMailer.createTransport({host: config.smtpHost, port: config.smtpPort, secure: true, ignoreTLS: false, requiresAuth: true, auth: {user: config.smtpUser, pass: config.smtpPassword}});
/*
//TEST CODE!!!//
try {
var name = "Wynne Crisman";
var email = "wynne@petitteton.com";
var textPath = rootPath + '/email/downloadBreifText.txt';
var htmlPath = rootPath + '/email/downloadBriefHtml.txt';
var signaturePath = rootPath + '/email/emailSignature.jpg';
var params = {from: config.fromAddress, to: email, subject: "Payback Brief", text: {path: textPath}, html: {path: htmlPath}, attachments: [{filename:'emailSignature.jpg', cid: 'emailSignature', path: signaturePath}]};
smtpTransport.sendMail(params, function(error, response) {
if(error) {
console.log("Error: " + error);
}
else {
console.log("Successfully sent the email - not an error.");
}
});
}
catch(e) {
console.log(e);
}
//END TEST//
*/
/*
//Setup the passwords used by users to access the content. Allows us to track who has used the site when and how much.
//Note: This is mostly for marketing purposes so it won't be very secure at all (no hashing, salting, SSL, or anything), and it allows the search engines to bypass it to the content.
var pwdData;
try {
if(fs.existsSync('pwdData.json')) {
pwdData = JSON.parse(fs.readFileSync('pwdData.json', 'utf8'));
}
else {
pwdData = [];
pwdData.push({pwd: 'zerotoone'});
pwdData.push({pwd: 'zephyr'});
pwdData.push({pwd: 'borealis'});
pwdData.push({pwd: 'gyroscope'});
pwdData.push({pwd: 'colnago'});
pwdData.push({pwd: 'derosa'});
pwdData.push({pwd: 'wwww&w'});
pwdData.push({pwd: 'catalyst'});
fs.writeFileSync('pwdData.json', JSON.stringify(pwdData), 'utf8');
}
} catch(e) {console.log(e);}
function writePwdData() {
try {
fs.writeFileSync('pwdData.json', JSON.stringify(pwdData), 'utf8');
} catch(e) {console.log(e);}
}
function incrementPwdUseCount(password) {
//Note: This is mostly for marketing purposes so it won't be very secure at all (no hashing, salting, SSL, or anything), and it allows the search engines to bypass it to the content.
try {
if(password) {
var index;
var found = false;
//Convert the password from base64.
password = new Buffer(password, 'base64').toString('utf-8');
//Identify which password was used (note: could use a map, but realistically with so few it is pointless complexity).
for(index = 0; !found && index < pwdData.length; index++) {
if(pwdData[index].pwd == password) {
//Track the number of times a user requests a content page.//
if(pwdData[index].accessCount) pwdData[index].accessCount++;
else pwdData[index].accessCount = 1;
writePwdData();
found = true;
}
}
}
} catch(e) {console.log(e);}
}
app.use('/RequestBrief/', function(req, res) {
try {
var firstName = req.body.FirstName;
var lastName = req.body.LastName;
var email = req.body.Email;
var isPartnership = req.body.PartnershipInterest;
var isInvestment = req.body.InvestmentInterest;
var isOther = req.body.OtherInterest;
var textPath = rootPath + '/email/downloadBriefText.txt';
var htmlPath = rootPath + '/email/downloadBriefHtml.txt';
var signaturePath = rootPath + '/email/emailSignature.jpg';
var params = {from: config.fromAddress, to: email, subject: "Payback Brief", text: {path: textPath}, html: {path: htmlPath}, attachments: [{filename:'emailSignature.jpg', cid: 'emailSignature', path: signaturePath}]};
smtpTransport.sendMail(params, function(error, response) {
try {
if(error) {
console.log("Received an error while sending the download brief email to the user. " + error);
fs.appendFile(rootPath + '/emailFailures.txt', JSON.stringify(params) + '\n', function(err) {if(err) {console.log("Failed to write email data to file! (request brief)");}});
}
else {
params = {from: config.fromAddress, to: config.contactUsRecipient, subject: "Downloaded Brief", text: "A user has requested the Payback brief.\n\nFirst Name: " + firstName + "\nLast Name: " + lastName + "\nEmail: " + email + "\nPartnership: " + isPartnership + "\nInvestment: " + isInvestment + "\nOther: " + isOther};
smtpTransport.sendMail(params, function(error, response) {
if(error) {
try {
console.log("Received an error while sending the request brief 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! (request brief)");}});
} catch(e) {console.log(e);}
}
});
}
res.status(200).send('success');
} catch(e) {console.log(e);}
});
} catch(e) {console.log(e);}
});
app.use('/RequestFinancials/', function(req, res) {
try {
var firstName = req.body.FirstName;
var lastName = req.body.LastName;
var email = req.body.Email;
var phone = req.body.Phone;
var company = req.body.Company;
var message = req.body.Message;
var isPartnership = req.body.PartnershipInterest;
var isInvestment = req.body.InvestmentInterest;
var isOther = req.body.OtherInterest;
var textPath = rootPath + '/email/downloadFinancialsText.txt';
var htmlPath = rootPath + '/email/downloadFinancialsHtml.txt';
var textContents = fs.readFileSync(textPath, "UTF8");
var htmlContents = fs.readFileSync(htmlPath, "UTF8");
var signaturePath = rootPath + '/email/emailSignature.jpg';
textContents = textContents.replace("%%NAME%%", firstName);
htmlContents = htmlContents.replace("%%NAME%%", firstName);
var params = {from: config.fromAddress, to: email, subject: "Payback Financials", text: textContents, html: htmlContents, attachments: [{filename:'emailSignature.jpg', cid: 'emailSignature', path: signaturePath}]};
smtpTransport.sendMail(params, function(error, response) {
try {
if(error) {
console.log("Received an error while sending the request financials email to the user. " + error);
fs.appendFile(rootPath + '/emailFailures.txt', JSON.stringify(params) + '\n', function(err) {if(err) {console.log("Failed to write email data to file! (request financials)");}});
}
else {
params = {from: config.fromAddress, to: config.contactUsRecipient, subject: "Downloaded Financials", text: "A user has requested Payback's financials.\n\nFirst Name: " + firstName + "\nLast Name: " + lastName + "\nEmail: " + email + "\nPhone: " + phone + "\nCompany: " + company + "\nPartnership: " + isPartnership + "\nInvestment: " + isInvestment + "\nOther: " + isOther + "\nMessage: " + message};
smtpTransport.sendMail(params, function(error, response) {
if(error) {
try {
console.log("Received an error while sending the request financials 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! (request financials)");}});
} catch(e) {console.log(e);}
}
});
}
res.status(200).send('success');
} catch(e) {console.log(e);}
});
} 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);}
});
/*
app.use('/LoginUser', function(req, res) {
//Note: This is mostly for marketing purposes so it won't be very secure at all (no hashing, salting, SSL, or anything), and it allows the search engines to bypass it to the content.
try {
var password = req.body.Password;
if(password) {
var index;
var found = false;
//Convert the password from base64.
password = new Buffer(password, 'base64').toString('utf-8');
//Identify which password was used (note: could use a map, but realistically with so few it is pointless complexity).
for(index = 0; !found && index < pwdData.length; index++) {
if(pwdData[index].pwd == password) {
//Track the time of the first and last login.
if(pwdData[index].firstLogin) pwdData[index].lastLogin = new Date();
else pwdData[index].firstLogin = new Date();
writePwdData();
found = true;
}
}
if(found) {
//Notify the client they have logged in.
res.status(200).send('success');
}
else {
res.status(200).send('failed');
}
}
else {
res.status(200).send('failed');
}
} catch(e) {console.log(e);}
});
*/
console.log("Time now is: " + moment(new Date()).format("MMM Do YYYY, h:mm:ss a"));
/*
app.use('/Admin/UserData', function(req, res) {
//TODO: Return a table of user data. This is a hidden function, and since the data is not very sensitive we won't bother with password protection or ssl.
var body = "<html><body><table><thead><tr><th style='padding: 0 20px 0 0'>Password</th><th style='padding: 0 20px 0 20px'>Page Request Count</th><th style='padding: 0 20px 0 20px'>First Login</th><th style='padding: 0 0 0 20px'>Last Login</th></tr></thead><tbody>";
for(var index = 0; index < pwdData.length; index++) {
body += "<tr>";
body += "<td>" + pwdData[index].pwd + "</td>";
body += "<td style='text-align: center'>" + (pwdData[index].accessCount ? pwdData[index].accessCount : 0) + "</td>";
body += "<td style='padding: 0 20px 0 20px'>" + (pwdData[index].firstLogin ? (moment(pwdData[index].firstLogin).format("MMM Do YYYY, h:mm:ss a") + " (" + moment(pwdData[index].firstLogin).fromNow() + ")") : "") + "</td>";
body += "<td style='padding: 0 20px 0 20px'>" + (pwdData[index].lastLogin ? (moment(pwdData[index].lastLogin).format("MMM Do YYYY, h:mm:ss a") + " (" + moment(pwdData[index].lastLogin).fromNow() + ")") : "") + "</td>";
body += "</tr>";
}
body += "</tbody></table></body></html>";
res.send(body);
});
*/
//Handle the root being requested, and the search engine requesting a static page with content.
app.use('/', function(req, res) {
try {
//Note: This is for search engines. It bypasses the password, which is fine since that is mostly a marketing gimmic to make users feel that they have some special access priviliges.
if(typeof(req.query._escaped_fragment_) !== "undefined") {
//The DIY method which is somewhat brittle since it relies on <!--CONTENT--> existing in the index.html 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.html 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(html);
}
else console.log("Error reading the content file '" + file + "'. " + err);
});
}
else console.log("Error reading the index.html file. " + err);
});
/* Does not work! Would be nice, but Phantom doesn't work well with Node.js. Could try using jsdom/io.js or could use prerenderer-node which is a server that runs in parallel with the web server and builds the html as the client would, which is then returned.
phantom.create(function(err, ph) {
if(!err) {
return ph.createPage(function(err, page) {
return page.open(req.protocol + "://" + req.hostname + ':' + req.app.get('port') + req.path + "#!" + req.query._escaped_fragment_, function(status) {
return page.evaluate((function() {
return document.getElementsByTagName('html')[0].innerHTML;
}), function(err, result) {
res.send(result);
return ph.exit();
});
});
});
}
else console.log("Error in Phantom.create: " + err);
});
*/
}
else {
res.sendFile("index.html", {root: rootPath});
}
} catch(e) {console.log(e);}
});
//Schedule a task every 10 minutes to check the email failure log and re-attempt sending.//
/* TODO
setInterval(function() {
//How to remove things from the file without worrying about synchronization between those threads adding to the file?
fs.
}, 600000);
*/
// catch 404 and forward to error handler
app.use(function(req, res, next) {
try {
var err = new Error('Not Found');
err.status = 404;
next(err);
} catch(e) {console.log(e);}
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, nex) {
try {
res.status(err.status || 500);
res.render('error.ejs', {
message: err.message,
error: err
});
} catch(e) {console.log(e);}
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
try {
res.status(err.status || 500);
res.render('error.ejs', {
message: err.message,
error: {}
});
} catch(e) {console.log(e);}
});
//console.log(app._router);
module.exports = app;