diff options
| author | Adam Soltys <[email protected]> | 2014-09-02 01:53:43 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2014-09-02 16:11:15 -0700 |
| commit | 2f65c2ad5d2c4b9fd2ec143aedf60cce01eef660 (patch) | |
| tree | 1a664d4db6fb21d351d761cc89b3c05985421c56 | |
| parent | 8426aa8ef3a97d8d8fda7eb70bab8efe74b3c3f3 (diff) | |
| download | coinos-server-2f65c2ad5d2c4b9fd2ec143aedf60cce01eef660.tar.gz coinos-server-2f65c2ad5d2c4b9fd2ec143aedf60cce01eef660.zip | |
Start work on profile page
| -rw-r--r-- | app.js | 2 | ||||
| -rw-r--r-- | public/js/profile.coffee | 151 | ||||
| -rw-r--r-- | routes/users.js | 13 | ||||
| -rw-r--r-- | src/app.coffee | 1 | ||||
| -rw-r--r-- | src/routes/users.coffee | 9 | ||||
| -rw-r--r-- | views/users/profile.html | 35 |
6 files changed, 211 insertions, 0 deletions
@@ -123,6 +123,8 @@ app.get('/verify/:token', users.verify); + app.get('/:user/profile', authorize, users.profile); + app.get('/:user/edit', authorize, users.edit); app.post('/:user', authorize, users.update); diff --git a/public/js/profile.coffee b/public/js/profile.coffee new file mode 100644 index 00000000..1e929d60 --- /dev/null +++ b/public/js/profile.coffee @@ -0,0 +1,151 @@ +#= require ../js/jquery-1.8.2.min.js +#= require ../js/bootstrap.min.js + +g = exports ? this +g.proceed = false + +$(-> + $('[data-toggle=popover]').popover() + $('#title').focus() + + user = $('#username').val() + $.getJSON("/#{user}.json", (data) -> + $('#username').val(data.title) + $('#email').val(data.logo) + $('#profile').fadeIn() + ) + + units = ['BTC', 'mBTC', 'µBTC', 'satoshis'] + $.each(units, (i, v) -> + $('#unit').append("<option value='#{v}'>#{v}</option>") + ) + + $('#title').blur(-> + if $(this).val() == '' and $('#logo').val() == '' + $(this).parent().addClass('has-error') + else + $(this).parent().removeClass('has-error') + ) + + $('#bip32').blur(-> + try + new BIP32($(this).val()) + $(this).parent().removeClass('has-error') + catch + $(this).parent().addClass('has-error') + ) + + $('#generate').click(-> + rng = new SecureRandom() + bytes = new Array(256) + rng.nextBytes(bytes) + + hasher = new jsSHA(bytes.toString(), 'TEXT') + rng.nextBytes(bytes) + + I = hasher.getHMAC(bytes.toString(), "TEXT", "SHA-512", "HEX") + il = Crypto.util.hexToBytes(I.slice(0, 64)) + ir = Crypto.util.hexToBytes(I.slice(64, 128)) + + key = new BIP32() + key.eckey = new Bitcoin.ECKey(il) + key.eckey.pub = key.eckey.getPubPoint() + key.eckey.setCompressed(true) + key.eckey.pubKeyHash = Bitcoin.Util.sha256ripe160(key.eckey.pub.getEncoded(true)) + key.has_private_key = true + + key.chain_code = ir + key.child_index = 0 + key.parent_fingerprint = Bitcoin.Util.hexToBytes("00000000") + key.version = BITCOIN_MAINNET_PRIVATE + key.depth = 0 + + key.build_extended_public_key() + key.build_extended_private_key() + + g.pubkey = key.extended_public_key_string() + g.privkey = key.extended_private_key_string() + + $('#modal').modal() + $('#privkey').html(g.privkey) + $('#qr').html('') + new QRCode('qr', text: g.privkey, width: 260, height: 260) + ) + + $('#encryption-password').keyup((e) -> + return if e.keyCode is 9 or e.keyCode is 16 + enc_privkey = CryptoJS.AES.encrypt(g.privkey, $(this).val()).toString() + enc_privkey = g.privkey if $(this).val() == '' + $('#privkey').html(enc_privkey) + $('#qr').html('') + new QRCode('qr', text: enc_privkey, width: 260, height: 260) + + if $(this).val() + $('#status').html('(Encrypted)') + else + $('#status').html('(Unencrypted Plaintext)') + ) + + $('#confirm').blur(-> + $('#confirm_error').remove() + if $('#password').val() != $('#confirm').val() + $('#password, #confirm').parent().addClass('has-error') + $('#confirm').parent().after('<div id="confirm_error" class="alert alert-danger">Passwords don\'t match</div>') + else + $('#password, #confirm').parent().removeClass('has-error') + ) + + $('#encryption-password, #encryption-confirm').keyup((e) -> check_passwords(e) unless e.keyCode is 9) + $('#encryption-password, #encryption-confirm').blur((e) -> check_passwords(e)) + + check_passwords = (e) -> + if $('#encryption-password').val() != $('#encryption-confirm').val() or $('#encryption-password').val() is '' + $('#encryption-password, #encryption-confirm').parent().addClass('has-error') + $('#modal .alert').removeClass('alert-success').addClass('alert-danger') + else + $('#encryption-password, #encryption-confirm').parent().removeClass('has-error') + $('#modal .alert').removeClass('alert-danger').addClass('alert-success') + + $('#print').click(-> + $('#key-dialog').printElement(printMode: 'popup') + ) + + $('a[data-toggle="tab"]').on('shown.bs.tab', (e) -> + $('#encryption-password').focus() + switch e.target.attributes.href.value + when '#step1' + $('.modal-footer button:first').hide() + $('.modal-footer button:last').html('Next').off().on('click', -> $('a[data-toggle="tab"]:eq(1)').click()) + when '#step2' + $('.modal-footer button:first').show().html('Back').off().on('click', -> $('a[data-toggle="tab"]:eq(0)').click()) + $('.modal-footer button:last').html('Next').off().on('click', -> $('a[data-toggle="tab"]:eq(2)').click()) + when '#step3' + $('.modal-footer button:first').show().html('Back').off().on('click', -> $('a[data-toggle="tab"]:eq(1)').click()) + $('.modal-footer button:last').html('Got it!').off().on('click', -> + $('#modal .form-control').blur() + if $('#modal .has-error').length > 0 + $('a[data-toggle="tab"]:eq(1)').click() + $('#modal .has-error').effect('shake', 500) + else + g.update_pub_key = true + $('#modal').modal('hide') + ) + ) + + $('.modal-footer button:last').on('click', -> $('a[data-toggle="tab"]:eq(1)').click()) + $('#modal').on('shown.bs.modal', -> + g.update_pub_key = false + $('#encryption-password, #encryption-confirm').val('').blur() + if $('.tab-pane:eq(2)').hasClass('active') + $('a[data-toggle="tab"]:eq(1)').click() + ).on('hidden.bs.modal', -> + $('#bip32').val(g.pubkey) if g.update_pub_key + ) + + $('#setup').submit(-> + $('#setup .form-control').blur() + if $('#setup .has-error').length > 0 + $('#setup .has-error').effect('shake', 500) + return false + ) +) diff --git a/routes/users.js b/routes/users.js index 31912c40..ad3fa165 100644 --- a/routes/users.js +++ b/routes/users.js @@ -152,6 +152,19 @@ }) }); }, + profile: function(req, res) { + return res.render('users/profile', { + user: req.params.user, + layout: 'layout', + navigation: true, + js: (function() { + return global.js; + }), + css: (function() { + return global.css; + }) + }); + }, update: function(req, res) { if (req.body.password === '') { delete req.body.password; diff --git a/src/app.coffee b/src/app.coffee index ae709fd0..b917cca1 100644 --- a/src/app.coffee +++ b/src/app.coffee @@ -75,6 +75,7 @@ app.get('/users/new', cache, users.new) app.post('/users', users.create) app.get('/verify/:token', users.verify) +app.get('/:user/profile', authorize, users.profile) app.get('/:user/edit', authorize, users.edit) app.post('/:user', authorize, users.update) diff --git a/src/routes/users.coffee b/src/routes/users.coffee index d2c88dc2..88379884 100644 --- a/src/routes/users.coffee +++ b/src/routes/users.coffee @@ -114,6 +114,15 @@ module.exports = (sessions) -> css: (-> global.css) ) + profile: (req, res) -> + res.render('users/profile', + user: req.params.user, + layout: 'layout', + navigation: true, + js: (-> global.js), + css: (-> global.css) + ) + update: (req, res) -> if req.body.password is '' delete req.body.password diff --git a/views/users/profile.html b/views/users/profile.html new file mode 100644 index 00000000..048b11fb --- /dev/null +++ b/views/users/profile.html @@ -0,0 +1,35 @@ +{{#yield-scripts}} + {{#js}}js/profile{{/js}} +{{/yield-scripts}} + +<form id="profile" action="/{{user}}" method="post" style="display: none"> + <h1>Profile</h1> + + <div class="form-group"> + <label for="username">Username:</label> + <input type="text" id="username" name="username" value="{{user}}" class="form-control" /> + </div> + + <div class="form-group"> + <label for="email">Email:</label> + <input type="text" id="email" name="email" class="form-control" /> + </div> + + <div class="form-group"> + <label for="password">New Password <small>(blank = no change)</small>:</label> + <input type="password" id="password" name="password" class="form-control" /> + </div> + + <div class="form-group"> + <label for="confirm">Confirm New Password:</label> + <input type="password" id="confirm" name="confirm" class="form-control" /> + </div> + + <br /> + <input class="btn btn-primary" type="submit" value="Done" /> +</form> + +<div class="jumbotron"> + <h3>Wallet Balance</h3> + <h1>0.01982001</h1> +</div> |
