Browse Source

implement the 2-stage email verification process

2015
joates 7 years ago
parent
commit
756cf4ab72
  1. 16
      config.js
  2. 13
      config.json
  3. 4
      package.json
  4. 100
      server.js
  5. 39
      src/email-confirm.js
  6. 54
      src/email-submit.js

16
config.js

@ -0,0 +1,16 @@
var join = require('path').join
, name = 'squatconf'
, cwd = process.cwd()
module.exports = require('rc')(name, {
db_opts: { valueEncoding: 'json' }
, db_path: join(cwd, 'db', name)
, port: 8000
, host: "squatconf.eu"
, email: {
from : "no-reply@squatconf.eu"
, subject : "Hello, everyone is welcome at SquatConf.."
, bodyText : "Please verify that you wish to signup by following this link\n%link%\nYou can ignore this message if you DID NOT request to signup at our website\nhttp://squatconf.eu\n\nThe next event is in Paris, we hope to see you there !!\n\nKind regards from the team,\nSquatConf Paris 2014"
}
})

13
config.json

@ -1,13 +0,0 @@
{
"db": {
"path": ""
},
"email": {
"from" : "no-reply@squatconf.eu"
, "subject" : "Hello, everyone is welcome at SquatConf.."
, "bodyText": "Please verify that you wish to signup by following this link\n%link%\nYou can ignore this message if you DID NOT request to signup at our website\nhttp://squatconf.eu\n\nThe next event is in Paris, we hope to see you there !!\n\nKind regards from the team,\nSquatConf Paris 2014"
}
}

4
package.json

@ -26,7 +26,11 @@
"browserify": "^5.11.2",
"domready": "^1.0.7",
"level": "^0.18.0",
"ecstatic": "^0.5.4",
"nodemailer": "^1.3.0",
"rc": "^0.5.1",
"stack": "^0.1.0",
"tiny-route": "^2.1.1",
"valid-email": "0.0.1",
"xss-escape": "0.0.5"
}

100
server.js

@ -1,13 +1,14 @@
#!/usr/bin/env node
var server = require('http').createServer(handler)
, sanitize = require('xss-escape')
, rn = require('./src/rng')
, fs = require('fs')
, re = new RegExp('\.js$', 'i')
, ip = require('./src/ip-trace')
, db = require('level')('./db/squatconf', { valueEncoding: 'json' })
, port = process.env.PORT || /*80*/ 8000
var fs = require('fs')
, http = require('http')
, stack = require('stack')
, route = require('tiny-route')
, assets = require('ecstatic')
, join = require('path').join
, config = require('./config')
, db = require('level')(config.db_path, config.db_opts)
, port = process.env.PORT || config.port
// create the level db folder if it does not exists
if(!fs.existsSync('./db/squatconf')){
@ -18,84 +19,19 @@ if(!fs.existsSync('./db/squatconf')){
});
}
function handler(req, res) {
// process incoming requests.
if (req.url == '/') req.url = '/index.html'
else if (re.test(req.url))
res.setHeader('Content-Type', 'application/javascript')
if (/^\/confirm\?/.test(req.url)) {
// @TODO
// compare submitted token with the token stored in our database.
res.statusCode = 302
res.setHeader('Location', '/')
return res.end()
}
if (/^\/email\?/.test(req.url)) {
var params = require('url').parse(req.url, true)
if (params && params.query.email) {
//console.log('got email:', params.query)
var obj = {}
, email = sanitize(params.query.email)
obj.token = rn()
obj.verified = false
obj.events = { paris: params.query.paris ? true : false }
obj.trace = ip(req)
db.put(email, obj, function(err) {
if (err) throw err
// else.. db updated OK
db.get(email, function (err, value) {
if (err) return console.error('Ooops!', err)
console.log('> '+ email, value)
})
})
var nodemailer = require('nodemailer')
, transporter = nodemailer.createTransport()
, config = require('./config.json')
, url = 'http://squatconf.eu/confirm'
, link = url +'?email='+ email +'&token='+ obj.token +'\n\n'
var opts = {
from : config.email.from
, to : email
, subject: config.email.subject
//, text : config.email.bodyText.replace(/\%link\%/, link)
}
console.log('mockmail sent...', opts)
/*
transporter.sendMail(opts, function(err, data) {
if (err) throw err
// validation email sent
console.log('email sent..', data)
})
*/
}
res.statusCode = 302
res.setHeader('Location', '/')
return res.end()
}
// serve static assets
var rs = fs.createReadStream(__dirname +'/html'+ req.url)
rs.pipe(res)
}
var app = stack(
route('/email', require('./src/email-submit')(db))
, route('/confirm', require('./src/email-confirm')(db))
, assets(join(__dirname, 'html'))
)
process.on('uncaughtException', function (err) {
console.error('Error at:', new Date)
console.error(err.stack)
})
server.listen(port)
console.log('['+ process.pid +'] server started on port '+ port)
console.log('(use Ctrl+c to stop the server)')
http.createServer(app).listen(port, function() {
console.log('['+ process.pid +'] server started on port '+ port)
console.log('(use Ctrl+c to stop the server)')
})

39
src/email-confirm.js

@ -0,0 +1,39 @@
var sanitize = require('xss-escape')
, ip = require('./ip-trace')
module.exports = function(db) {
return function (req, res, next) {
req.resume()
var params = require('url').parse(req.url, true)
if (params && params.query.email && params.query.token) {
//console.log('got token:', params.query)
var email = sanitize(params.query.email)
, token = sanitize(params.query.token)
db.get(email, function(err, obj) {
if (err) next(err)
// db read OK..
if (obj && obj.token === token) {
obj.verified = true
obj.trace = obj.trace.concat(ip(req))
db.put(email, obj, function(err) {
if (err) next(err)
// db write OK..
res.statusCode = 302
res.setHeader('Location', '/verified.html')
return res.end()
})
}
})
if (next) return next()
}
}
}

54
src/email-submit.js

@ -0,0 +1,54 @@
var sanitize = require('xss-escape')
, rn = require('./rng')
, ip = require('./ip-trace')
, config = require('../config')
module.exports = function(db) {
return function (req, res, next) {
req.resume()
var params = require('url').parse(req.url, true)
if (params && params.query.email) {
console.log('got email:', params.query)
var obj = {}
, email = sanitize(params.query.email)
obj.token = rn()
obj.verified = false
obj.events = { paris: params.query.paris ? true : false }
obj.trace = ip(req)
db.put(email, obj, function(err) {
if (err) next(err)
// db write OK..
var nodemailer = require('nodemailer')
, transporter = nodemailer.createTransport()
, url = 'http://squatconf.eu/confirm'
, link = url +'?email='+ email +'&token='+ obj.token +'\n\n'
var opts = {
from : config.email.from
, to : email
, subject: config.email.subject
, text : config.email.bodyText.replace(/\%link\%/, link)
}
transporter.sendMail(opts, function(err, data) {
if (err) throw err
// validation email sent
console.log('email sent..', data)
})
res.statusCode = 302
res.setHeader('Location', '/')
return res.end()
})
}
if (next) return next()
}
}
Loading…
Cancel
Save