aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2012-12-06 20:23:34 -0800
committerAdam Soltys <[email protected]>2012-12-06 20:23:34 -0800
commit749787381c3fdcfb45852b2234b8099483ff0cf5 (patch)
tree776f0b44a839426bcdf1e628eadc1b4b57b6638d
parent00a08d7c8b10b726830505b58a045a49bb2046fe (diff)
downloadcoinos-server-749787381c3fdcfb45852b2234b8099483ff0cf5.tar.gz
coinos-server-749787381c3fdcfb45852b2234b8099483ff0cf5.zip
Code re-org
-rw-r--r--app.coffee191
-rw-r--r--passport.coffee30
-rw-r--r--public/css/index.less2
-rw-r--r--public/js/calculator.coffee8
-rw-r--r--public/js/index.coffee2
-rw-r--r--public/js/report.coffee2
-rw-r--r--public/js/setup.coffee15
-rw-r--r--routes/calculator.coffee30
-rw-r--r--routes/sessions.coffee19
-rw-r--r--routes/transactions.coffee39
-rw-r--r--routes/users.coffee45
-rw-r--r--views/calculator/setup.html (renamed from views/setup.html)14
-rw-r--r--views/calculator/show.html (renamed from views/calculator.html)2
-rw-r--r--views/error.html1
-rw-r--r--views/layout.html3
-rw-r--r--views/main/about.html (renamed from views/about.html)0
-rw-r--r--views/main/contact.html (renamed from views/contact.html)0
-rw-r--r--views/main/exchangers.html (renamed from views/exchangers.html)6
-rw-r--r--views/main/index.html (renamed from views/index.html)0
-rw-r--r--views/main/join.html (renamed from views/join.html)0
-rw-r--r--views/main/merchants.html (renamed from views/merchants.html)0
-rw-r--r--views/main/signup.html (renamed from views/signup.html)0
-rw-r--r--views/sessions/new.html (renamed from views/login.html)0
-rw-r--r--views/transactions/index.html (renamed from views/report.html)0
-rw-r--r--views/user.html43
-rw-r--r--views/users/new.html27
26 files changed, 245 insertions, 234 deletions
diff --git a/app.coffee b/app.coffee
index b83f649d..a5c1ecdf 100644
--- a/app.coffee
+++ b/app.coffee
@@ -1,43 +1,15 @@
express = require('express')
-http = require('http')
path = require('path')
engines = require('consolidate')
-passport = require('passport')
-bcrypt = require('bcrypt')
-db = require("redis").createClient()
-ask = bid = 0
+passport = require('./passport').passport
-LocalStrategy = require('passport-local').Strategy
+calculator = require("./routes/calculator")
+sessions = require("./routes/sessions")(passport)
+transactions = require("./routes/transactions")
+users = require("./routes/users")
-passport.serializeUser((user, done) ->
- done(null, user.username)
-)
-
-passport.deserializeUser((id, done) ->
- user = username: 'soltysa', password: 'adam'
- done(null, user)
-)
-
-passport.use(new LocalStrategy(
- (username, password, done) ->
- bcrypt.hash(password, 12, (err, hash) ->
- db.hget(username, 'password', (err, result) ->
- console.log(result)
- if result
- bcrypt.compare(password, result, (err, match) ->
- console.log(match)
- if match
- db.hgetall(username, (err, user) ->
- return done(null, user)
- )
- )
- )
- )
- return done(null, false)
-))
-
-ensureAuthenticated = (req, res, next) ->
- return next() if req.isAuthenticated()
+authorize = (req, res, next) ->
+ return next() if req.isAuthenticated()
res.redirect('/login')
app = express()
@@ -55,13 +27,13 @@ app.use(passport.session())
app.use(app.router)
routes =
- "/": 'index'
- "/about": 'about'
- "/exchangers": 'exchangers'
- "/exchangers/join": 'join'
- "/merchants": 'merchants'
- "/merchants/signup": 'signup'
- "/contact": 'contact'
+ "/": 'main/index'
+ "/about": 'main/about'
+ "/exchangers": 'main/exchangers'
+ "/exchangers/join": 'main/join'
+ "/merchants": 'main/merchants'
+ "/merchants/signup": 'main/signup'
+ "/contact": 'main/contact'
for route, view of routes
((route, view) ->
@@ -74,132 +46,25 @@ for route, view of routes
)
)(route, view)
-app.get('/setup', (req, res) ->
- res.render('setup', js: (-> global.js), css: (-> global.css))
-)
+app.get('/setup', calculator.new)
+app.get('/calculator', calculator.show)
+app.get('/ticker', calculator.ticker)
-app.get('/:user/report', (req, res) ->
- res.render('report',
- user: req.params.user,
- js: (-> global.js),
- css: (-> global.css)
- )
-)
+app.get('/login', sessions.new)
+app.post('/login', sessions.create)
-app.get('/:user.json', (req, res) ->
- db.hgetall(req.params.user, (err, obj) ->
- res.write(JSON.stringify(obj))
- res.end()
- )
-)
-
-app.get('/:user/transactions', (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)
- )
-)
-
-app.get('/ticker', (req, res) ->
- options =
- host: 'bitcoincharts.com',
- path: "/t/depthcalc.json?symbol=#{req.query.symbol}&type=#{req.query.type}&amount=#{req.query.amount}&currency=true"
+app.get('/:user.json', authorize, users.json)
+app.get('/:user', authorize, users.show)
- http.get(options, (r) ->
- r.setEncoding('utf-8')
- r.on('data', (chunk) ->
- try
- exchange = 1000 / JSON.parse(chunk).out
- exchange = (Math.ceil(exchange * 100) / 100).toString()
- catch e
- exchange = ""
+app.get('/users/new', authorize, users.new)
+app.post('/users', authorize, users.create)
- res.writeHead(200,
- 'Content-Length': exchange.length,
- 'Content-Type': 'text/plain')
- res.write(exchange)
- res.end()
- )
- )
-)
+app.get('/:user/edit', authorize, users.edit)
+app.post('/:user/update', authorize, users.update)
-app.get('/login', (req, res) ->
- res.render('login',
- js: (-> global.js),
- css: (-> global.css)
- )
-)
-
-app.post('/login', (req, res, next) ->
- passport.authenticate('local', (err, user, info) ->
- if (err)
- return next(err)
- if (!user)
- return res.redirect('/login')
- req.logIn(user, (err) ->
- if (err)
- return next(err)
- return res.redirect('/' + user.username)
- )
- )(req, res, next)
-)
-
-app.post('/users', (req, res) ->
- params = []
- for k,v of req.body
- params.push(encodeURIComponent(k), '=', encodeURIComponent(v), '&')
- params.pop() if (params.length)
- res.redirect('calculator?' + params.join(''))
-)
-
-app.post('/:user/transactions', (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()
- )
- )
- )
-)
-
-app.get('/calculator', (req, res) ->
- console.log(req.user)
- res.render('calculator',
- js: (-> global.js),
- css: (-> global.css),
- )
-)
-
-app.get('/:user/edit', ensureAuthenticated, (req, res) ->
- res.render('user',
- user: req.params.user,
- js: (-> global.js),
- css: (-> global.css)
- )
-)
-
-app.get('/:user', (req, res) ->
- console.log(req.user)
- res.render('calculator',
- user: req.params.user,
- js: (-> global.js),
- css: (-> global.css)
- )
-)
+app.get('/:user/transactions.json', authorize, transactions.json)
+app.post('/:user/transactions', authorize, transactions.create)
+app.get('/:user/report', authorize, transactions.index)
app.use((err, req, res, next) ->
res.status(500)
diff --git a/passport.coffee b/passport.coffee
new file mode 100644
index 00000000..280117d1
--- /dev/null
+++ b/passport.coffee
@@ -0,0 +1,30 @@
+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(username, (err, user) ->
+ return done(null, user)
+ )
+)
+
+passport.use(new LocalStrategy(
+ (username, password, done) ->
+ db.hget(username, 'password', (err, hash) ->
+ if hash
+ bcrypt.compare(password, hash, (err, match) ->
+ if match
+ db.hgetall(username, (err, user) ->
+ return done(null, user)
+ )
+ )
+ )
+))
+
+exports.passport = passport
diff --git a/public/css/index.less b/public/css/index.less
index cc31fc1b..6cd236ca 100644
--- a/public/css/index.less
+++ b/public/css/index.less
@@ -10,5 +10,5 @@ footer {
}
#ask, #bid { color: white; }
-div.directory img { width: 150px; height: 150px; float: left; padding-right: 20px; }
+div.directory img { width: 150px; height: 150px; float: left; padding-right: 5px; }
div.row-fluid td.first { text-align: right; }
diff --git a/public/js/calculator.coffee b/public/js/calculator.coffee
index ef26fd63..505a1a09 100644
--- a/public/js/calculator.coffee
+++ b/public/js/calculator.coffee
@@ -15,7 +15,7 @@ g = exports ? this
$(->
g.user = $('#user').val()
- g.name = get('name')
+ g.title = get('title')
g.address = get('address')
g.symbol = get('symbol')
g.commission = parseFloat(get('commission'))
@@ -28,7 +28,7 @@ $(->
dataType: 'json',
success: (data) ->
if data?
- g.name = data.name
+ g.title = data.title
g.address = data.address
g.symbol = data.symbol
g.commission = data.commission
@@ -54,10 +54,10 @@ setup = ->
if g.logo
$('#logo').attr('src', g.logo).show()
- else if not g.name
+ else if not g.title
$('#logo').attr('src', 'img/bitcoin.png').show()
else
- $('#name').html(g.name).show()
+ $('#title').html(g.title).show()
address = g.address
if g.user? and g.user
diff --git a/public/js/index.coffee b/public/js/index.coffee
index 2a8a6b5a..b180ee2d 100644
--- a/public/js/index.coffee
+++ b/public/js/index.coffee
@@ -3,6 +3,7 @@
$(->
fetchExchangeRate('ask')
fetchExchangeRate('bid')
+ setTimeout(fetchExchangeRate, 900000)
)
fetchExchangeRate = (type) ->
@@ -20,4 +21,3 @@ fetchExchangeRate = (type) ->
error: ->
$("##{type}").html('??')
)
- setTimeout(fetchExchangeRate, 900000)
diff --git a/public/js/report.coffee b/public/js/report.coffee
index 06c99050..28ec988b 100644
--- a/public/js/report.coffee
+++ b/public/js/report.coffee
@@ -8,7 +8,7 @@ $(->
$('#from').val(moment().subtract('days', 7).format("MM/DD/YYYY"))
$('#to').val(moment().format("MM/DD/YYYY"))
$('.date').datepicker(onClose: filterDates)
- $.getJSON('transactions', (data) ->
+ $.getJSON('transactions.json', (data) ->
g.transactions = data.transactions
display(g.transactions)
filterDates()
diff --git a/public/js/setup.coffee b/public/js/setup.coffee
index d53a4e48..6c38d4b5 100644
--- a/public/js/setup.coffee
+++ b/public/js/setup.coffee
@@ -6,10 +6,14 @@
$(->
symbols = ['mtgoxUSD', 'btceUSD', 'bitstampUSD', 'virwoxSLL', 'btcdeEUR', 'mtgoxEUR', 'btc24EUR', 'mtgoxAUD', 'cryptoxAUD', 'mtgoxGBP', 'btcnCNY', 'intrsngEUR', 'virtexCAD', 'mtgoxPLN', 'cbxUSD', 'bitcurexPLN', 'bitmarketEUR', 'bitfloorUSD', 'mrcdBRL', 'bcEUR']
+ symbols = symbols.sort()
+
+ user = $('#username').val()
$.each(symbols, (i, v) ->
$('#symbol').append("<option value='#{v}'>#{v}</option>")
)
+ $("#symbol option[value='mtgoxUSD']").attr('selected', 'selected')
$('#address').change(->
if check_address($(this).val())
@@ -18,12 +22,13 @@ $(->
$(this).css('color', 'red')
)
- if $('#login').val() != ""
- $.getJSON('/' + $('#login').val() + '.json', (data) ->
- $('#name').val(data.name)
- $('#image').val(data.image)
+ if user
+ $('#setup').attr('action', "/#{user}/update").attr('method', 'post')
+ $.getJSON("/#{user}.json", (data) ->
+ $('#title').val(data.title)
+ $('#logo').val(data.logo)
$('#address').val(data.address)
- $('#symbol option[value=' + data.symbol + ']').attr('selected', 'selected')
+ $("#symbol option[value='#{data.symbol}']").attr('selected', 'selected')
$('#commission').val(data.commission)
)
)
diff --git a/routes/calculator.coffee b/routes/calculator.coffee
new file mode 100644
index 00000000..0fe11a28
--- /dev/null
+++ b/routes/calculator.coffee
@@ -0,0 +1,30 @@
+exports.new = (req, res) ->
+ res.render('calculator/setup', js: (-> global.js), css: (-> global.css))
+
+exports.show = (req, res) ->
+ res.render('calculator/show',
+ js: (-> global.js),
+ css: (-> global.css),
+ )
+
+exports.ticker = (req, res) ->
+ options =
+ host: 'bitcoincharts.com',
+ path: "/t/depthcalc.json?symbol=#{req.query.symbol}&type=#{req.query.type}&amount=#{req.query.amount}&currency=true"
+
+ require('http').get(options, (r) ->
+ r.setEncoding('utf-8')
+ r.on('data', (chunk) ->
+ try
+ exchange = 1000 / JSON.parse(chunk).out
+ exchange = (Math.ceil(exchange * 100) / 100).toString()
+ catch e
+ exchange = ""
+
+ res.writeHead(200,
+ 'Content-Length': exchange.length,
+ 'Content-Type': 'text/plain')
+ res.write(exchange)
+ res.end()
+ )
+ )
diff --git a/routes/sessions.coffee b/routes/sessions.coffee
new file mode 100644
index 00000000..631004ca
--- /dev/null
+++ b/routes/sessions.coffee
@@ -0,0 +1,19 @@
+module.exports = (passport) ->
+ new: (req, res) ->
+ res.render('sessions/new',
+ 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.redirect('/login')
+ req.login(user, (err) ->
+ if (err)
+ return next(err)
+ return res.redirect('/' + user.username)
+ )
+ )(req, res, next)
diff --git a/routes/transactions.coffee b/routes/transactions.coffee
new file mode 100644
index 00000000..92e566fa
--- /dev/null
+++ b/routes/transactions.coffee
@@ -0,0 +1,39 @@
+db = require("redis").createClient()
+
+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,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
diff --git a/routes/users.coffee b/routes/users.coffee
new file mode 100644
index 00000000..ea927583
--- /dev/null
+++ b/routes/users.coffee
@@ -0,0 +1,45 @@
+db = require("redis").createClient()
+bcrypt = require('bcrypt')
+
+module.exports =
+ json: (req, res) ->
+ db.hgetall(req.params.user, (err, obj) ->
+ delete obj['password']
+ res.write(JSON.stringify(obj))
+ res.end()
+ )
+
+ show: (req, res) ->
+ res.render('calculator/show',
+ user: req.params.user,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
+ new: (req, res) ->
+ res.render('users/new',
+ js: (-> global.js),
+ css: (-> global.css),
+ )
+
+ create: (req, res) ->
+ bcrypt.hash(req.body.password, 12, (err, hash) ->
+ req.body.password = hash
+ db.hmset(req.body.username, req.body, ->
+ res.redirect(req.body.username)
+ )
+ )
+
+ edit: (req, res) ->
+ res.render('calculator/setup',
+ user: req.params.user,
+ js: (-> global.js),
+ css: (-> global.css)
+ )
+
+ update: (req, res) ->
+ return unless req.params.user is req.user.username or
+ req.user.username is 'admin'
+ db.hmset(req.params.user, req.body, ->
+ res.redirect("/#{req.params.user}")
+ )
diff --git a/views/setup.html b/views/calculator/setup.html
index 72fbd944..8722a68a 100644
--- a/views/setup.html
+++ b/views/calculator/setup.html
@@ -10,19 +10,15 @@
</head>
<body>
<div class="container-fluid">
- <form action="users" method="post">
+ <form id="setup" action="/calculator" method="get">
<h1>Calculator Setup</h1>
- <label for="login">Username:</label>
- <input type="text" id="login" name="login" value="{{user}}" />
+ <input type="hidden" id="username" name="username" value="{{user}}" />
- <label for="password">Password:</label>
- <input type="password" id="password" name="password" value="" />
+ <label for="title">Title:</label>
+ <input type="text" id="title" name="title" />
- <label for="name">Title:</label>
- <input type="text" id="name" name="name" />
-
- <label for="logo">Image:</label>
+ <label for="logo">Logo:</label>
<input type="text" id="logo" name="logo" />
<label for="address">Bitcoin Address:</label>
diff --git a/views/calculator.html b/views/calculator/show.html
index aa882ee4..a3b632f2 100644
--- a/views/calculator.html
+++ b/views/calculator/show.html
@@ -13,7 +13,7 @@
<div id="calculator" style="display: none">
<input id="user" type="hidden" value="{{user}}" />
- <h1 id="name"></h1>
+ <h1 id="title"></h1>
<img id="logo" src="img/logo.jpg" alt="Logo" />
<label for="exchange">Exchange Rate:</label>
diff --git a/views/error.html b/views/error.html
deleted file mode 100644
index 58edb1a5..00000000
--- a/views/error.html
+++ /dev/null
@@ -1 +0,0 @@
-Error: {{error}}
diff --git a/views/layout.html b/views/layout.html
index 0e84c667..ae4d5b69 100644
--- a/views/layout.html
+++ b/views/layout.html
@@ -15,8 +15,7 @@
<a class="brand" href="/">VanBTC</a>
<div class="nav-collapse collapse">
<p class="navbar-text pull-right">
- Buy: <b id="ask"></b> | Sell: <b id="bid"></b> |
- <a href="/login" class="navbar-link">Login</a>
+ Buy: <b id="ask"></b> | Sell: <b id="bid"></b>
</p>
<ul class="nav">
<li><a href="/about">Info</a></li>
diff --git a/views/about.html b/views/main/about.html
index 6711c039..6711c039 100644
--- a/views/about.html
+++ b/views/main/about.html
diff --git a/views/contact.html b/views/main/contact.html
index 5914db11..5914db11 100644
--- a/views/contact.html
+++ b/views/main/contact.html
diff --git a/views/exchangers.html b/views/main/exchangers.html
index b3d86fa4..6d62697e 100644
--- a/views/exchangers.html
+++ b/views/main/exchangers.html
@@ -24,7 +24,7 @@
<div class="row-fluid">
<div class="span4">
<h2>Adam</h2>
- <img src="img/adam.jpg" />
+ <a href="https://localbitcoins.com/accounts/profile/asoltys/"><img src="img/adam.jpg" alt="Adam" /></a>
<table>
<tr>
<td class="first"><b>Neighbourhood:</b></td>
@@ -37,7 +37,7 @@
</div>
<div class="span4">
<h2>Jackson</h2>
- <img src="img/jackson.jpg" />
+ <a href="https://localbitcoins.com/accounts/profile/stretchwynand/"><img src="img/jackson.jpg" alt="Jackson" /></a>
<table>
<tr>
<td class="first"><b>Neighbourhood:</b></td>
@@ -50,7 +50,7 @@
</div>
<div class="span4">
<h2>Yuri</h2>
- <img src="img/yuri.jpg" />
+ <a href="https://localbitcoins.com/accounts/profile/beeteecee/"><img src="img/yuri.jpg" alt="Yuri" /></a>
<table>
<tr>
<td class="first"><b>Neighbourhood:</b></td>
diff --git a/views/index.html b/views/main/index.html
index 72454ad0..72454ad0 100644
--- a/views/index.html
+++ b/views/main/index.html
diff --git a/views/join.html b/views/main/join.html
index f25c0dea..f25c0dea 100644
--- a/views/join.html
+++ b/views/main/join.html
diff --git a/views/merchants.html b/views/main/merchants.html
index 942e6eda..942e6eda 100644
--- a/views/merchants.html
+++ b/views/main/merchants.html
diff --git a/views/signup.html b/views/main/signup.html
index 3e9dfa7e..3e9dfa7e 100644
--- a/views/signup.html
+++ b/views/main/signup.html
diff --git a/views/login.html b/views/sessions/new.html
index 613762e9..613762e9 100644
--- a/views/login.html
+++ b/views/sessions/new.html
diff --git a/views/report.html b/views/transactions/index.html
index d768da57..d768da57 100644
--- a/views/report.html
+++ b/views/transactions/index.html
diff --git a/views/user.html b/views/user.html
deleted file mode 100644
index 72fbd944..00000000
--- a/views/user.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=480, height=752, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
- <title>Bitcoin Payment Calculator</title>
- <link href="img/favicon.ico" rel="shortcut icon" />
- {{#css}}calculator{{/css}}
- {{#js}}setup{{/js}}
- </head>
- <body>
- <div class="container-fluid">
- <form action="users" method="post">
- <h1>Calculator Setup</h1>
-
- <label for="login">Username:</label>
- <input type="text" id="login" name="login" value="{{user}}" />
-
- <label for="password">Password:</label>
- <input type="password" id="password" name="password" value="" />
-
- <label for="name">Title:</label>
- <input type="text" id="name" name="name" />
-
- <label for="logo">Image:</label>
- <input type="text" id="logo" name="logo" />
-
- <label for="address">Bitcoin Address:</label>
- <input type="text" id="address" name="address" />
-
- <label for="symbol">Market Symbol:</label>
- <select id="symbol" name="symbol">
- </select>
-
- <label for="commission">Commission (%):</label>
- <input type="text" id="commission" name="commission" />
-
- <br />
- <input class="btn" type="submit" value="Go" />
- </form>
- </div>
- </body>
-</html>
diff --git a/views/users/new.html b/views/users/new.html
new file mode 100644
index 00000000..be50f47c
--- /dev/null
+++ b/views/users/new.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=480, height=752, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
+ <title>Bitcoin Payment Calculator</title>
+ <link href="img/favicon.ico" rel="shortcut icon" />
+ {{#css}}calculator{{/css}}
+ {{#js}}setup{{/js}}
+ </head>
+ <body>
+ <div class="container-fluid">
+ <form action="/users" method="post">
+ <h1>New User Account</h1>
+
+ <label for="username">Username:</label>
+ <input type="text" id="username" name="username" />
+
+ <label for="password">Password:</label>
+ <input type="password" id="password" name="password" value="" />
+
+ <br />
+ <input class="btn" type="submit" value="Go" />
+ </form>
+ </div>
+ </body>
+</html>