aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.coffee69
-rw-r--r--src/config.coffee.sample0
-rw-r--r--src/install.coffee16
-rw-r--r--src/passport.coffee35
-rw-r--r--src/redis.coffee5
-rw-r--r--src/routes/calculator.coffee27
-rw-r--r--src/routes/sessions.coffee35
-rw-r--r--src/routes/transactions.coffee41
-rw-r--r--src/routes/users.coffee97
-rw-r--r--src/socket_test.coffee14
10 files changed, 339 insertions, 0 deletions
diff --git a/src/app.coffee b/src/app.coffee
new file mode 100644
index 00000000..538dfa05
--- /dev/null
+++ b/src/app.coffee
@@ -0,0 +1,69 @@
+express = require('express')
+bodyParser = require('body-parser')
+cookieParser = require('cookie-parser')
+path = require('path')
+passport = require('./passport')
+config = require('./config')
+
+calculator = require("./routes/calculator")
+sessions = require("./routes/sessions")(passport)
+transactions = require("./routes/transactions")
+users = require("./routes/users")(sessions)
+
+session = require('express-session')
+RedisStore = require('connect-redis')(session)
+sessionStore = new RedisStore(require('./redis').host, ttl: 172800)
+
+
+app = express()
+app.enable('trust proxy')
+app.engine('html', require('hogan-express'))
+app.set('view engine', 'html')
+app.set('views', __dirname + '/views')
+app.use(express.static(__dirname + '/public'))
+app.use(bodyParser.urlencoded({ extended: true}))
+app.use(bodyParser.json())
+app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
+app.use(cookieParser(config.secret))
+app.use(session(resave: true, saveUninitialized: true, secret: config.secret, store: sessionStore, cookie: { maxAge: 1209600000 }, key: 'vanbtc.sid'))
+app.use(passport.initialize())
+app.use(passport.session())
+
+authorize = (req, res, next) ->
+ if req.params.user is req.user?.username or
+ req.user?.username is 'admin'
+ return next()
+ res.redirect('/login')
+
+app.get('/', sessions.new)
+app.get('/register', users.new)
+app.get('/ticker', calculator.ticker)
+app.get('/sweep', calculator.sweep)
+
+app.get('/login', sessions.new)
+app.post('/login', sessions.create)
+app.get('/logout', sessions.destroy)
+
+app.get('/users/new', users.new)
+app.post('/users', users.create)
+
+app.get('/:user/edit', authorize, users.edit)
+app.post('/:user', authorize, users.update)
+
+app.get('/:user/transactions.json', authorize, transactions.json)
+app.post('/:user/transactions', authorize, transactions.create)
+app.get('/:user/report', authorize, transactions.index)
+
+app.get('/:user.json', authorize, users.json)
+app.get('/:user', authorize, users.show)
+
+app.use(require('connect-assets')(src: 'public', servePath: '/'))
+
+app.use((err, req, res, next) ->
+ res.status(500)
+ res.send('An error occurred');
+ console.error(err.stack)
+ res.end()
+)
+
+app.listen(3000)
diff --git a/src/config.coffee.sample b/src/config.coffee.sample
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/config.coffee.sample
diff --git a/src/install.coffee b/src/install.coffee
new file mode 100644
index 00000000..38e32b6f
--- /dev/null
+++ b/src/install.coffee
@@ -0,0 +1,16 @@
+db = require("./redis")
+bcrypt = require('bcrypt')
+
+db.get("user:admin", (err, res) ->
+ if !res
+ bcrypt.hash('admin', 12, (err, hash) ->
+ db.sadd("users","user:admin")
+ db.hmset("user:admin",
+ username: 'admin'
+ password: hash,
+ , ->
+ console.log("Created admin user with password 'admin'")
+ process.exit()
+ )
+ )
+)
diff --git a/src/passport.coffee b/src/passport.coffee
new file mode 100644
index 00000000..12913424
--- /dev/null
+++ b/src/passport.coffee
@@ -0,0 +1,35 @@
+db = require("redis").createClient()
+bcrypt = require('bcrypt')
+
+passport = require('passport')
+LocalStrategy = require('passport-local').Strategy
+
+passport.serializeUser((user, done) ->
+ done(null, user.username)
+)
+
+passport.deserializeUser((username, done) ->
+ db.hgetall("user:"+username, (err, user) ->
+ return done(null, user)
+ )
+)
+
+passport.use(new LocalStrategy(
+ (username, password, done) ->
+ db.hget("user:"+username, 'password', (err, hash) ->
+ return done(err) if err
+ if hash
+ bcrypt.compare(password, hash, (err, match) ->
+ if match
+ db.hgetall("user:"+username, (err, user) ->
+ return done(null, user)
+ )
+ else
+ return done(null, false)
+ )
+ else
+ return done(null, false)
+ )
+))
+
+module.exports = passport
diff --git a/src/redis.coffee b/src/redis.coffee
new file mode 100644
index 00000000..38524595
--- /dev/null
+++ b/src/redis.coffee
@@ -0,0 +1,5 @@
+settings =
+ port: 6379
+ host: '127.0.0.1'
+
+module.exports = require('redis').createClient(settings.port, settings.host)
diff --git a/src/routes/calculator.coffee b/src/routes/calculator.coffee
new file mode 100644
index 00000000..4f3ac0b5
--- /dev/null
+++ b/src/routes/calculator.coffee
@@ -0,0 +1,27 @@
+exports.sweep = (req, res) ->
+ res.render('calculator/sweep',
+ layout: 'layout',
+ navigation: true,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
+exports.ticker = (req, res) ->
+ fs = require('fs')
+ fs.readFile("./public/js/rates.json", (err, data) ->
+ req.query.currency ||= 'CAD'
+ req.query.symbol ||= 'quadrigacx'
+ req.query.type ||= 'bid'
+
+ try
+ exchange = JSON.parse(data)[req.query.currency][req.query.symbol]['rates'][req.query.type].toString()
+ catch e
+ exchange = "0"
+
+ res.writeHead(200,
+ 'Content-Length': exchange.length,
+ 'Content-Type': 'text/plain')
+ res.write(exchange)
+ res.end()
+ )
+
diff --git a/src/routes/sessions.coffee b/src/routes/sessions.coffee
new file mode 100644
index 00000000..67efba75
--- /dev/null
+++ b/src/routes/sessions.coffee
@@ -0,0 +1,35 @@
+module.exports = (passport) ->
+ new: (req, res) ->
+ res.render('sessions/new',
+ layout: 'layout',
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
+ create: (req, res, next) ->
+ passport.authenticate('local', (err, user, info) ->
+ if (err)
+ return next(err)
+ if (!user)
+ return res.render('sessions/new',
+ layout: 'layout',
+ js: (-> global.js),
+ css: (-> global.css),
+ badpw: true
+ )
+ req.login(user, (err) ->
+ if (err)
+ return next(err)
+
+ if /edit/.test(req.headers['referer'])
+ url = "/#{user.username}/edit"
+ else
+ url = "/#{user.username}"
+
+ return res.redirect(url)
+ )
+ )(req, res, next)
+
+ destroy: (req, res) ->
+ req.logout()
+ res.redirect('/login')
diff --git a/src/routes/transactions.coffee b/src/routes/transactions.coffee
new file mode 100644
index 00000000..b4653362
--- /dev/null
+++ b/src/routes/transactions.coffee
@@ -0,0 +1,41 @@
+db = require('../redis')
+
+module.exports =
+ json: (req, res) ->
+ user = req.params.user
+ r = 'transactions': []
+
+ db.lrange("#{user}:transactions", 0, -1, (err, transactions) ->
+ process = (err, t) ->
+ r.transactions.push t
+
+ if i >= transactions.length
+ res.write(JSON.stringify(r))
+ res.end()
+ else
+ db.hgetall("#{user}:transactions:#{transactions[i++]}", process)
+
+ i = 0
+ db.hgetall("#{user}:transactions:#{transactions[i++]}", process)
+ )
+
+ create: (req, res) ->
+ user = req.params.user
+ db.incr('transactions', (err, id) ->
+ db.hmset("#{user}:transactions:#{id}", req.body, ->
+ db.rpush("#{user}:transactions", id, ->
+ res.write(JSON.stringify(req.body))
+ res.end()
+ )
+ )
+ )
+
+ index: (req, res) ->
+ res.render('transactions/index',
+ user: req.params.user,
+ layout: 'layout',
+ navigation: true,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
diff --git a/src/routes/users.coffee b/src/routes/users.coffee
new file mode 100644
index 00000000..a213f678
--- /dev/null
+++ b/src/routes/users.coffee
@@ -0,0 +1,97 @@
+db = require("../redis")
+bcrypt = require('bcrypt')
+
+module.exports = (sessions) ->
+ exists: (req, res) ->
+ db.hgetall("user:"+req.params.user, (err, obj) ->
+ if obj? then res.write('true') else res.write('false')
+ res.end()
+ )
+
+ json: (req, res) ->
+ db.hgetall("user:"+req.params.user, (err, obj) ->
+ delete obj['password']
+ res.writeHead(200, {"Content-Type": "application/json"});
+ res.write(JSON.stringify(obj))
+ res.end()
+ )
+
+ show: (req, res) ->
+ db.hgetall("user:"+req.params.user, (err, obj) ->
+ if obj
+ res.render('users/show',
+ user: req.params.user,
+ layout: 'layout',
+ navigation: true,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+ else
+ res.render('sessions/new',
+ notice: true,
+ layout: 'layout',
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+ )
+
+ new: (req, res) ->
+ res.render('users/new',
+ layout: 'layout',
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
+ create: (req, res) ->
+ errormsg = ""
+ userkey = "user:"+req.body.username
+ db.hgetall(userkey, (err, obj) ->
+ if obj
+ res.redirect(req.body.username)
+ else
+ if req.body.confirm != req.body.password
+ errormsg += "Passwords must match"
+ return res.render('users/new',
+ layout: 'layout',
+ js: (-> global.js),
+ css: (-> global.css),
+ error: errormsg
+ )
+
+ bcrypt.hash(req.body.password, 12, (err, hash) ->
+ db.sadd("users",userkey)
+ db.hmset(userkey,
+ username: req.body.username,
+ password: hash,
+ email: req.body.email
+ , ->
+ req.headers['referer'] = "/#{req.body.username}/edit"
+ sessions.create(req, res)
+ )
+ )
+ )
+
+ edit: (req, res) ->
+ res.render('users/edit',
+ user: req.params.user,
+ layout: 'layout',
+ navigation: true,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
+ update: (req, res) ->
+ return unless req.params.user is req.user.username or
+ req.user.username is 'admin'
+ if req.body.password is ''
+ delete req.body.password
+ db.hmset("user:"+req.params.user, req.body, ->
+ if not req.body.password?
+ res.redirect("/#{req.params.user}")
+ else
+ bcrypt.hash(req.body.password, 12, (err, hash) ->
+ db.hmset("user:"+req.params.user,password: hash, ->
+ res.redirect("/#{req.params.user}")
+ )
+ )
+ )
diff --git a/src/socket_test.coffee b/src/socket_test.coffee
new file mode 100644
index 00000000..315be3a3
--- /dev/null
+++ b/src/socket_test.coffee
@@ -0,0 +1,14 @@
+ transaction = {"hash":{},"version":1,"lock_time":0,"ins":[{"s":{},"q":4294967295,"o":{}}],"outs":[{"v":{},"s":{}},{"v":{},"s":{}}],"_buffer":{},"txid":"8500a0893a2d83a17819673884ade21bbef07d8c92bfe51682e45873cc2d3720","vin":[{"n":0,"txid":"1549415465c84fb519ffb92339ef80461427502c90d5d3ac5d01f27d824feabd","vout":1}],"vout":[{"valueSat":10000,"scriptPubKey":{"addresses":["1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr"]},"n":0},{"valueSat":3966838180,"scriptPubKey":{"addresses":["1Ao8Swc6vSosrjednQkNZeXEXVu1ZcxYZE"]},"n":1}],"time":1405573125}
+
+ $('body').append(transaction.vout[0].valueSat)
+
+ socket = io('ws://insight.bitpay.com')
+ socket.on('connect', ->
+ $('body').append('connected')
+ this.emit('subscribe', '1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr')
+ )
+
+ socket.on('1VAnbtCAnYccECnjaMCPnWwt81EHCVgNr', (data) ->
+ $('body').append(JSON.stringify(data))
+ )
+