diff --git a/app/index.js b/app/index.js index a5c70570..285aaa33 100644 --- a/app/index.js +++ b/app/index.js @@ -8,12 +8,10 @@ app.engine('html', require('ejs').renderFile); // Force HTTPS on stackedit.io app.all('*', function(req, res, next) { if (req.headers.host == 'stackedit.io' && req.headers['x-forwarded-proto'] != 'https') { - res.redirect('https://stackedit.io' + req.url); - } - else { - /\.(eot|ttf|woff)$/.test(req.url) && res.header('Access-Control-Allow-Origin', '*'); - next(); + return res.redirect('https://stackedit.io' + req.url); } + /\.(eot|ttf|woff)$/.test(req.url) && res.header('Access-Control-Allow-Origin', '*'); + next(); }); // Use gzip compression diff --git a/app/pdf.js b/app/pdf.js index 7c580b92..bd3074da 100644 --- a/app/pdf.js +++ b/app/pdf.js @@ -1,5 +1,8 @@ var spawn = require('child_process').spawn; var fs = require('fs'); +var path = require('path'); +var os = require('os'); +var request = require('request'); function waitForJavaScript() { if(window.MathJax) { @@ -37,53 +40,6 @@ var authorizedPageSizes = [ ]; module.exports = function(req, res, next) { - var options, params = []; - try { - options = JSON.parse(req.query.options); - } - catch(e) { - options = {}; - } - - // Margins - var marginTop = parseInt(options.marginTop); - params.push('-T', isNaN(marginTop) ? 25 : marginTop); - var marginRight = parseInt(options.marginRight); - params.push('-R', isNaN(marginRight) ? 25 : marginRight); - var marginBottom = parseInt(options.marginBottom); - params.push('-B', isNaN(marginBottom) ? 25 : marginBottom); - var marginLeft = parseInt(options.marginLeft); - params.push('-L', isNaN(marginLeft) ? 25 : marginLeft); - - // Header - options.headerCenter && params.push('--header-center', options.headerCenter); - options.headerLeft && params.push('--header-left', options.headerLeft); - options.headerRight && params.push('--header-left', options.headerRight); - options.headerFontName && params.push('--header-font-name ', options.headerFontName); - options.headerFontSize && params.push('--header-font-size ', options.headerFontSize); - - // Footer - options.footerCenter && params.push('--footer-center', options.footerCenter); - options.footerLeft && params.push('--footer-left', options.footerLeft); - options.footerRight && params.push('--footer-left', options.footerRight); - options.footerFontName && params.push('--footer-font-name ', options.footerFontName); - options.footerFontSize && params.push('--footer-font-size ', options.footerFontSize); - - // Page size - params.push('--page-size', authorizedPageSizes.indexOf(options.pageSize) === -1 ? 'A4' : options.pageSize); - - // wkhtmltopdf can't access /dev/stdout on Amazon EC2 for some reason - var filePath = '/tmp/' + Date.now() + '.pdf'; - var binPath = process.env.WKHTMLTOPDF_PATH || 'wkhtmltopdf'; - params.push('--run-script', waitForJavaScript.toString() + 'waitForJavaScript()'); - params.push('--window-status', 'done'); - var wkhtmltopdf = spawn(binPath, params.concat('-', filePath), { - stdio: [ - 'pipe', - 'ignore', - 'ignore' - ] - }); function onError(err) { next(err); } @@ -91,33 +47,98 @@ module.exports = function(req, res, next) { res.statusCode = 400; res.end('Unknown error'); } + function onUnauthorizedError() { + res.statusCode = 401; + res.end('Unauthorized'); + } function onTimeout() { res.statusCode = 408; res.end('Request timeout'); } - var timeoutId = setTimeout(function() { - timeoutId = undefined; - wkhtmltopdf.kill(); - }, 30000); - wkhtmltopdf.on('error', onError); - wkhtmltopdf.stdin.on('error', onError); - wkhtmltopdf.on('close', function(code) { - if(!timeoutId) { - return onTimeout(); + request({ + uri: 'https://monetizejs.com/api/payments', + qs: { + access_token: req.query.token + }, + json: true + }, function (err, paymentsRes, payments) { + var authorized = payments && payments.app == 'ESTHdCYOi18iLhhO' && ( + (payments.chargeOption && payments.chargeOption.alias == 'once') || + (payments.subscriptionOption && payments.subscriptionOption.alias == 'yearly')); + if(err || paymentsRes.statusCode != 200 || !authorized) { + return onUnauthorizedError(); } - clearTimeout(timeoutId); - if(code) { - return onUnknownError(); + var options, params = []; + try { + options = JSON.parse(req.query.options); } - var readStream = fs.createReadStream(filePath); - readStream.on('open', function() { - readStream.pipe(res); + catch(e) { + options = {}; + } + + // Margins + var marginTop = parseInt(options.marginTop); + params.push('-T', isNaN(marginTop) ? 25 : marginTop); + var marginRight = parseInt(options.marginRight); + params.push('-R', isNaN(marginRight) ? 25 : marginRight); + var marginBottom = parseInt(options.marginBottom); + params.push('-B', isNaN(marginBottom) ? 25 : marginBottom); + var marginLeft = parseInt(options.marginLeft); + params.push('-L', isNaN(marginLeft) ? 25 : marginLeft); + + // Header + options.headerCenter && params.push('--header-center', options.headerCenter); + options.headerLeft && params.push('--header-left', options.headerLeft); + options.headerRight && params.push('--header-left', options.headerRight); + options.headerFontName && params.push('--header-font-name ', options.headerFontName); + options.headerFontSize && params.push('--header-font-size ', options.headerFontSize); + + // Footer + options.footerCenter && params.push('--footer-center', options.footerCenter); + options.footerLeft && params.push('--footer-left', options.footerLeft); + options.footerRight && params.push('--footer-left', options.footerRight); + options.footerFontName && params.push('--footer-font-name ', options.footerFontName); + options.footerFontSize && params.push('--footer-font-size ', options.footerFontSize); + + // Page size + params.push('--page-size', authorizedPageSizes.indexOf(options.pageSize) === -1 ? 'A4' : options.pageSize); + + // Use a temp file as wkhtmltopdf can't access /dev/stdout on Amazon EC2 for some reason + var filePath = path.join(os.tmpDir(), Date.now() + '.pdf'); + var binPath = process.env.WKHTMLTOPDF_PATH || 'wkhtmltopdf'; + params.push('--run-script', waitForJavaScript.toString() + 'waitForJavaScript()'); + params.push('--window-status', 'done'); + var wkhtmltopdf = spawn(binPath, params.concat('-', filePath), { + stdio: [ + 'pipe', + 'ignore', + 'ignore' + ] }); - readStream.on('close', function() { - fs.unlink(filePath, function() { + var timeoutId = setTimeout(function() { + timeoutId = undefined; + wkhtmltopdf.kill(); + }, 30000); + wkhtmltopdf.on('error', onError); + wkhtmltopdf.stdin.on('error', onError); + wkhtmltopdf.on('close', function(code) { + if(!timeoutId) { + return onTimeout(); + } + clearTimeout(timeoutId); + if(code) { + return onUnknownError(); + } + var readStream = fs.createReadStream(filePath); + readStream.on('open', function() { + readStream.pipe(res); }); + readStream.on('close', function() { + fs.unlink(filePath, function() { + }); + }); + readStream.on('error', onUnknownError); }); - readStream.on('error', onUnknownError); + req.pipe(wkhtmltopdf.stdin); }); - req.pipe(wkhtmltopdf.stdin); }; diff --git a/package.json b/package.json index 303b032f..7150c6f5 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,9 @@ "doc": "doc" }, "dependencies": { - "express": "3.x", - "ejs": "~0.8.4" + "express": "~3.16.6", + "ejs": "~0.8.4", + "request": "~2.40.0" }, "devDependencies": { "grunt-contrib-requirejs": "~0.4.3",