diff --git a/app/application.scss b/app/application.scss index 18fad8bb..8f85ce10 100644 --- a/app/application.scss +++ b/app/application.scss @@ -49,7 +49,7 @@ @import "pages/send/_index"; @import "pages/receive/_index"; @import "pages/history/_index"; -@import "pages/tokens/_index"; +@import "pages/sign/_index"; // loader @import "loader/_index"; diff --git a/app/assets/img/BITLOX_LOGO.png b/app/assets/img/BITLOX_LOGO.png new file mode 100644 index 00000000..b763d6f9 Binary files /dev/null and b/app/assets/img/BITLOX_LOGO.png differ diff --git a/app/assets/img/BITLOX_LOGO_BLACK_WHITE_INLINE.png b/app/assets/img/BITLOX_LOGO_BLACK_WHITE_INLINE.png new file mode 100644 index 00000000..af81fa40 Binary files /dev/null and b/app/assets/img/BITLOX_LOGO_BLACK_WHITE_INLINE.png differ diff --git a/app/assets/img/BITLOX_LOGO_WHITE.png b/app/assets/img/BITLOX_LOGO_WHITE.png new file mode 100644 index 00000000..c9877af0 Binary files /dev/null and b/app/assets/img/BITLOX_LOGO_WHITE.png differ diff --git a/app/assets/img/BITLOX_LOGO_WHITE_BLACK_INLINE.png b/app/assets/img/BITLOX_LOGO_WHITE_BLACK_INLINE.png new file mode 100644 index 00000000..a8d62696 Binary files /dev/null and b/app/assets/img/BITLOX_LOGO_WHITE_BLACK_INLINE.png differ diff --git a/app/assets/img/BITLOX_LOGO_WHITE_OUTLINE.png b/app/assets/img/BITLOX_LOGO_WHITE_OUTLINE.png new file mode 100644 index 00000000..c1d48ad8 Binary files /dev/null and b/app/assets/img/BITLOX_LOGO_WHITE_OUTLINE.png differ diff --git a/app/core_css/_variables.scss b/app/core_css/_variables.scss index 658f0ac0..25b45b3e 100644 --- a/app/core_css/_variables.scss +++ b/app/core_css/_variables.scss @@ -24,28 +24,37 @@ $base_line_height: 1.5; // Brand colours -$grey--light: #FAFAFA; -$grey: #CCCDC8; +$bitlox-white: #F3F3F2; +$bitlox-gray-light: #A6A6A7; +$bitlox-gray: #5B5B5A; +$bitlox-gray-dark: #3F3F40; +$bitlox-red: #860B0B; +$bitlox-red-dark: #5A1010; +$bitlox-green: #0B862E; +$bitlox-yellow: #93911B; +$bitlox-black: #171616; -$blue: #58A1FF; -$yellow: #FBC12C; -$dark-blue: #102E42; +$grey--light: $bitlox-gray-light; +$grey: $bitlox-gray; -$green: #9AD25C; -$red: #FC8276; +$blue: $bitlox-red; +$yellow: $bitlox-yellow; +$dark-blue: $bitlox-red-dark; -$purple: #2E2B44; -$purple--light: #464368; -$purple--highlight: #858DF0; +$green: $bitlox-green; +$red: $bitlox-red; -$silver: #949da1; +$purple: $bitlox-red-dark; +$purple--light: $bitlox-red; +$purple--highlight: $bitlox-white; + +$silver: $bitlox-white; // Sometimes abstract terms are useful: -$foreground: $purple; -$background: #FDFDFD; +$foreground: $bitlox-white; +$background: $bitlox-black; $focus_color: #4fa1fd; $alert_color: #fd9833; - diff --git a/app/core_css/mixins/_snippets.scss b/app/core_css/mixins/_snippets.scss index c85158da..441d6479 100644 --- a/app/core_css/mixins/_snippets.scss +++ b/app/core_css/mixins/_snippets.scss @@ -64,6 +64,10 @@ cursor: pointer; } +@mixin monospaced { + font-family: monospace; + font-size: 1.05em; +} // get rid of z-index glitching @@ -92,5 +96,3 @@ @mixin tabfocus() { outline: 2px solid $focus_color; } - - diff --git a/app/index.html b/app/index.html index d3af596d..e7ca1b27 100644 --- a/app/index.html +++ b/app/index.html @@ -1,103 +1,32 @@ - - Hive Web - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
- - - - - - - -
-
- - - - - - - - - -
-
- - - - - - - -
-
- - - - - - - - - - -
- - - - - - - -
-
-
- - - - - - - -
-
- - - - - - - + + Bitlox Web + + + + + + + + + + +
+
+
+
+
+
+
+ +
+
a
+
a
+
a
+
a
+
-
-
-
a
-
a
-
a
-
a
-
-
- - + + - diff --git a/app/lib/i18n/translations/en.json b/app/lib/i18n/translations/en.json index 1df844f4..341cca9d 100644 --- a/app/lib/i18n/translations/en.json +++ b/app/lib/i18n/translations/en.json @@ -1,108 +1,110 @@ { - "Back to hivewallet.com": "Back to hivewallet.com", - "Create new wallet": "Create new wallet", - "Open existing wallet": "Open existing wallet", - "We are about to generate your very own passphrase": "We're about to generate your very own passphrase", - "This keeps your account secure, and lets you open your wallet on multiple devices.": "This keeps your account secure, and lets you open your wallet on multiple devices.", - "It is very important you write this down.": "It's very important you write this down.", - "Generate passphrase": "Generate passphrase", - "Go back": "Go back", - "Generating": "Generating", - "Decoding passphrase": "Decoding passphrase", - "Synchronizing Wallet": "Synchronizing Wallet", - "Set your PIN": "Set your PIN", - "Your passphrase": "Your passphrase", - "Your passphrase will not be shown again.": "Your passphrase will not be shown again.", - "Without it you will lose access to your wallet.": "Without it you will lose access to your wallet.", - "I have written down or otherwise securely stored my passphrase": "I have written down or otherwise securely stored my passphrase", - "Open wallet": "Open wallet", - "Checking passphrase": "Checking passphrase", - "Enter Passphrase": "Enter Passphrase", - "Invalid passphrase": "Invalid passphrase", - "Enter your PIN": "Enter your PIN", - "Set a PIN for quick access": "Set a PIN for quick access", - "Review passphrase again": "Review passphrase again", - "Open a different wallet": "Open a different wallet", - "Forgot PIN": "Forgot PIN", - "PIN must be a 4-digit number": "PIN must be a 4-digit number", - "Verifying PIN": "Verifying PIN", - "Setting PIN": "Setting PIN", - "This might take some time,": "This might take some time,", - "please be patient.": "please be patient.", - "Your PIN is incorrect": "Your PIN is incorrect", - "Request timeout. Please check your internet connection.": "Request timeout. Please check your internet connection.", - "Could not save your details": "Could not save your details", - "We could not connect you to Waggle, please check your internet connection.": "We couldn't connect you to Waggle, please check your internet connection.", - "Please enter a valid address to send to": "Please enter a valid address to send to", - "Please enter an amount above": "Please enter an amount above %(dust)s", - "Some funds are temporarily unavailable. To send this transaction, you will need to wait for your pending transactions to be confirmed first (this should not take more than a few minutes).": "Some funds are temporarily unavailable. To send this transaction, you'll need to wait for your pending transactions to be confirmed first (this shouldn't take more than a few minutes).", - "What does this mean?": "What does this mean?", - "It seems like you are trying to empty your wallet. Taking transaction fee into account, we estimated that the max amount you can send is. We have amended the value in the amount field for you": "It seems like you are trying to empty your wallet. Taking transaction fee into account, we estimated that the max amount you can send is %(sendableBalance)s. We have amended the value in the amount field for you.", - "You do not have enough funds in your wallet": "You don't have enough funds in your wallet", - "A name is required to set your profile on Hive": "A name is required to set your profile on Hive", - "Uh Oh...": "Uh Oh...", - "Whoops!": "Whoops!", - "Just saying...": "Just saying...", - "Your browser does not support geolocation": "Your browser does not support geolocation", - "Unable to retrieve your location": "Unable to retrieve your location", - "Without a name, the payer would not be able to identify you on Waggle.": "Without a name, the payer wouldn't be able to identify you on Waggle.", - "cannot be blank": "%(blankField)s cannot be blank", - "name": "name", - "email": "email", - "description": "description", - "Change your details": "Change your details", - "Your name": "Your name", - "Gravatar email": "Gravatar email", - "Submit": "Submit", - "Gravatar (globally recognised avatar) is a service that lets you re-use the same avatar across websites and apps by specifying an email address.": "Gravatar (globally recognised avatar) is a service that lets you re-use the same avatar across websites and apps by specifying an email address.", - "Create a gravatar": "Create a gravatar", - "Logout": "Logout", - "Support": "Support", - "Send": "Send", - "Receive": "Receive", - "History": "History", - "Tokens": "Tokens", - "Waggle lets you broadcast your wallet address to other nearby Hive users by comparing GPS data. This data is deleted once you turn Waggle off.": "Waggle lets you broadcast your wallet address to other nearby Hive users by comparing GPS data. This data is deleted once you turn Waggle off.", - "Having problems?": "Having problems?", - "Description": "Description", - "Your email address": "Your email address", - "Nevermind": "Nevermind", - "Before you start using Waggle, you need to enter a name that will help others identify you.": "Before you start using Waggle, you need to enter a name that will help others identify you.", - "Save": "Save", - "Loading transactions...": "Loading transactions...", - "Your transaction history": "Your transaction history", - "pending confirmation": "pending confirmation", - "Received": "Received", - "You do not have any transactions yet": "You don't have any transactions yet", - "Transaction Id:": "Transaction Id:", - "Transaction Fee:": "Transaction Fee:", - "Inputs:": "Inputs:", - "Outputs:": "Outputs:", - "Sent to:": "Sent to:", - "Your wallet address": "Your wallet address", - "Waggle": "Waggle", - "Turn Waggle on": "Turn Waggle on", - "Turn Waggle off": "Turn Waggle off", - "Checking your location": "Checking your location", - "Broadcasting your location...": "Broadcasting your location...", - "Wallet address": "Wallet address", - "Amount": "Amount", - "Exchange rate unavailable for the selected currency": "Exchange rate unavailable for the selected currency", - "Confirm": "Confirm", - "No Hive users found nearby": "No Hive users found nearby", - "Search Again": "Search Again", - "Searching...": "Searching...", - "Searching your area for other Hive Web users": "Searching your area for other Hive Web users", - "Confirm transaction": "Confirm transaction", - "transaction fee": "transaction fee", - "Cancel": "Cancel", - "Transaction Successful": "Transaction Successful", - "Your transaction will appear in your history tab shortly.": "Your transaction will appear in your history tab shortly.", - "Close": "Close", - "Report": "Report", - "Transaction Failed": "Transaction Failed", - "Please make sure you are connected to the internet.": "Please make sure you are connected to the internet.", - "Please describe what happened above. Below are network error logs that could help us identify your issue.": "Please describe what happened above. Below are network error logs that could help us identify your issue.", - "Sorry, Hive Wallet did not load.": "Sorry, Hive Wallet didn't load.", - "Try updating your browser, or switching out of private browsing mode. If all else fails, download Chrome for your device.": "Try updating your browser, or switching out of private browsing mode. If all else fails, download Chrome for your device." + "Back to bitlox.io": "Back to bitlox.io", + "Create new wallet": "Create new wallet", + "Open existing wallet": "Open existing wallet", + "We are about to generate your very own passphrase": "We're about to generate your very own passphrase", + "This keeps your account secure, and lets you open your wallet on multiple devices.": "This keeps your account secure, and lets you open your wallet on multiple devices.", + "It is very important you write this down.": "It's very important you write this down.", + "Generate passphrase": "Generate passphrase", + "Go back": "Go back", + "Generating": "Generating", + "Decoding passphrase": "Decoding passphrase", + "Synchronizing Wallet": "Synchronizing Wallet", + "Set your PIN": "Set your PIN", + "Your passphrase": "Your passphrase", + "Your passphrase will not be shown again.": "Your passphrase will not be shown again.", + "Without it you will lose access to your wallet.": "Without it you will lose access to your wallet.", + "I have written down or otherwise securely stored my passphrase": "I have written down or otherwise securely stored my passphrase", + "Open wallet": "Open wallet", + "Checking passphrase": "Checking passphrase", + "Enter Passphrase": "Enter Passphrase", + "Invalid passphrase": "Invalid passphrase", + "Enter your PIN": "Enter your PIN", + "Set a PIN for quick access": "Set a PIN for quick access", + "Review passphrase again": "Review passphrase again", + "Open a different wallet": "Open a different wallet", + "Forgot PIN": "Forgot PIN", + "PIN must be a 4-digit number": "PIN must be a 4-digit number", + "Verifying PIN": "Verifying PIN", + "Setting PIN": "Setting PIN", + "This might take some time,": "This might take some time,", + "please be patient.": "please be patient.", + "Your PIN is incorrect": "Your PIN is incorrect", + "Request timeout. Please check your internet connection.": "Request timeout. Please check your internet connection.", + "Could not save your details": "Could not save your details", + "We could not connect you to Waggle, please check your internet connection.": "We couldn't connect you to Waggle, please check your internet connection.", + "Please enter a valid address to send to": "Please enter a valid address to send to", + "Please enter an amount above": "Please enter an amount above %(dust)s", + "Some funds are temporarily unavailable. To send this transaction, you will need to wait for your pending transactions to be confirmed first (this should not take more than a few minutes).": "Some funds are temporarily unavailable. To send this transaction, you'll need to wait for your pending transactions to be confirmed first (this shouldn't take more than a few minutes).", + "What does this mean?": "What does this mean?", + "It seems like you are trying to empty your wallet. Taking transaction fee into account, we estimated that the max amount you can send is. We have amended the value in the amount field for you": "It seems like you are trying to empty your wallet. Taking transaction fee into account, we estimated that the max amount you can send is %(sendableBalance)s. We have amended the value in the amount field for you.", + "You do not have enough funds in your wallet": "You don't have enough funds in your wallet", + "A name is required to set your profile on Hive": "A name is required to set your profile on Hive", + "Uh Oh...": "Uh Oh...", + "Whoops!": "Whoops!", + "Just saying...": "Just saying...", + "Your browser does not support geolocation": "Your browser does not support geolocation", + "Unable to retrieve your location": "Unable to retrieve your location", + "Without a name, the payer would not be able to identify you on Waggle.": "Without a name, the payer wouldn't be able to identify you on Waggle.", + "cannot be blank": "%(blankField)s cannot be blank", + "name": "name", + "email": "email", + "description": "description", + "Change your details": "Change your details", + "Your name": "Your name", + "Gravatar email": "Gravatar email", + "Submit": "Submit", + "Gravatar (globally recognised avatar) is a service that lets you re-use the same avatar across websites and apps by specifying an email address.": "Gravatar (globally recognised avatar) is a service that lets you re-use the same avatar across websites and apps by specifying an email address.", + "Create a gravatar": "Create a gravatar", + "Logout": "Logout", + "Support": "Support", + "Send": "Send", + "Receive": "Receive", + "History": "History", + "Sign": "Sign", + "Waggle lets you broadcast your wallet address to other nearby Hive users by comparing GPS data. This data is deleted once you turn Waggle off.": "Waggle lets you broadcast your wallet address to other nearby Hive users by comparing GPS data. This data is deleted once you turn Waggle off.", + "Having problems?": "Having problems?", + "Description": "Description", + "Your email address": "Your email address", + "Nevermind": "Nevermind", + "Before you start using Waggle, you need to enter a name that will help others identify you.": "Before you start using Waggle, you need to enter a name that will help others identify you.", + "Save": "Save", + "Loading transactions...": "Loading transactions...", + "Your transaction history": "Your transaction history", + "pending confirmation": "pending confirmation", + "Received": "Received", + "You do not have any transactions yet": "You don't have any transactions yet", + "Transaction Id:": "Transaction Id:", + "Transaction Fee:": "Transaction Fee:", + "Inputs:": "Inputs:", + "Outputs:": "Outputs:", + "Sent to:": "Sent to:", + "Message": "Message", + "Clear": "Clear", + "Your wallet address": "Your wallet address", + "Waggle": "Waggle", + "Turn Waggle on": "Turn Waggle on", + "Turn Waggle off": "Turn Waggle off", + "Checking your location": "Checking your location", + "Broadcasting your location...": "Broadcasting your location...", + "Wallet address": "Wallet address", + "Amount": "Amount", + "Exchange rate unavailable for the selected currency": "Exchange rate unavailable for the selected currency", + "Confirm": "Confirm", + "No Hive users found nearby": "No Hive users found nearby", + "Search Again": "Search Again", + "Searching...": "Searching...", + "Searching your area for other Hive Web users": "Searching your area for other Hive Web users", + "Confirm transaction": "Confirm transaction", + "transaction fee": "transaction fee", + "Cancel": "Cancel", + "Transaction Successful": "Transaction Successful", + "Your transaction will appear in your history tab shortly.": "Your transaction will appear in your history tab shortly.", + "Close": "Close", + "Report": "Report", + "Transaction Failed": "Transaction Failed", + "Please make sure you are connected to the internet.": "Please make sure you are connected to the internet.", + "Please describe what happened above. Below are network error logs that could help us identify your issue.": "Please describe what happened above. Below are network error logs that could help us identify your issue.", + "Sorry, Hive Wallet did not load.": "Sorry, Hive Wallet didn't load.", + "Try updating your browser, or switching out of private browsing mode. If all else fails, download Chrome for your device.": "Try updating your browser, or switching out of private browsing mode. If all else fails, download Chrome for your device." } diff --git a/app/lib/qrcode/index.js b/app/lib/qrcode/index.js index 3b696270..e6d9aa8e 100644 --- a/app/lib/qrcode/index.js +++ b/app/lib/qrcode/index.js @@ -4,33 +4,32 @@ var qr = require('qr.js') function encode(string, options) { - options = options || {} - var width = options.width || 200 - var height = options.height || 200 + options = options || {} + var width = options.width || 200 + var height = options.height || 200 - var canvas = document.createElement('canvas') - canvas.width = width - canvas.height = height + var canvas = document.createElement('canvas') + canvas.width = width + canvas.height = height - var ctx = canvas.getContext('2d') + var ctx = canvas.getContext('2d') - var cells = qr(string).modules + var cells = qr(string).modules - var tileW = width / cells.length - var tileH = height / cells.length + var tileW = width / cells.length + var tileH = height / cells.length - for (var r = 0; r < cells.length ; ++r) { - var row = cells[r] - for (var c = 0; c < row.length ; ++c) { - ctx.fillStyle = row[c] ? '#000' : '#fff' - var w = (Math.ceil((c+1)*tileW) - Math.floor(c*tileW)) - var h = (Math.ceil((r+1)*tileH) - Math.floor(r*tileH)) - ctx.fillRect(Math.round(c*tileW), Math.round(r*tileH), w, h) - } - } + for (var r = 0; r < cells.length ; ++r) { + var row = cells[r] + for (var c = 0; c < row.length ; ++c) { + ctx.fillStyle = row[c] ? '#000' : '#fff' + var w = (Math.ceil((c+1)*tileW) - Math.floor(c*tileW)) + var h = (Math.ceil((r+1)*tileH) - Math.floor(r*tileH)) + ctx.fillRect(Math.round(c*tileW), Math.round(r*tileH), w, h) + } + } - return canvas + return canvas } module.exports = encode - diff --git a/app/lib/ractive/index.js b/app/lib/ractive/index.js index 36e939aa..1de8da5b 100644 --- a/app/lib/ractive/index.js +++ b/app/lib/ractive/index.js @@ -64,8 +64,7 @@ partials.svg_sendto = require('hive-svg/sendto.ract').template partials.svg_settings = require('hive-svg/settings.ract').template partials.svg_success = require('hive-svg/success.ract').template partials.svg_token_bitcoin = require('hive-svg/token_bitcoin.ract').template -partials.svg_token_litecoin = require('hive-svg/token_litecoin.ract').template -partials.svg_token = require('hive-svg/token.ract').template +partials.svg_sign = require('hive-svg/sign.ract').template partials.svg_user = require('hive-svg/user.ract').template partials.svg_waggle = require('hive-svg/waggle.ract').template partials.svg_warning = require('hive-svg/warning.ract').template diff --git a/app/lib/svg/sign.ract b/app/lib/svg/sign.ract new file mode 100644 index 00000000..e515f5f6 --- /dev/null +++ b/app/lib/svg/sign.ract @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/lib/zendesk/index.js b/app/lib/zendesk/index.js index 81f565ea..8f8e4bc8 100644 --- a/app/lib/zendesk/index.js +++ b/app/lib/zendesk/index.js @@ -13,10 +13,9 @@ function sendRequest(paramsObj, callback) { }).join('&') var uri = "https://hivewallet.zendesk.com/requests/embedded/create/?" + params - var corsUri = process.env.PROXY_URL + "?url=" + encodeURIComponent(uri) xhr({ - uri: corsUri + uri: uri }, function(err, resp, body) { if (resp.statusCode !== 201) { console.error(body) diff --git a/app/loader/index.js b/app/loader/index.js index 5213f920..01f44f56 100644 --- a/app/loader/index.js +++ b/app/loader/index.js @@ -17,47 +17,43 @@ var languages = require('hive-i18n').languages document.getElementsByTagName('html')[0].classList.add(token) var elems = { - block1: document.getElementById('logo_block1'), - block2: document.getElementById('logo_block2'), - block3: document.getElementById('logo_block3'), - block4: document.getElementById('logo_block4'), - block5: document.getElementById('logo_block5'), + block1: document.getElementById('logo_block1'), + block2: document.getElementById('logo_block2'), + block3: document.getElementById('logo_block3'), + block4: document.getElementById('logo_block4'), + block5: document.getElementById('logo_block5'), } var containerEl = document.getElementById('loader') var keyEl = document.getElementById('logo_key') var goodToGo; -animateLogo(elems) Modernizr.on('indexeddb', function(hasIndexedDB){ - var supportsPouchDB = hasIndexedDB || Modernizr.websqldatabase - var language = findTranslation() - - Modernizr.load({ - test: supportsPouchDB && (Modernizr.localstorage && Modernizr.webworkers && Modernizr.blobconstructor && Modernizr.getrandomvalues), - yep: 'assets/js/application-' + language + '.js', - nope: 'assets/js/nope-' + language + '.js', - callback: function(testResult, key) { - goodToGo = key - }, - complete: function() { - if(goodToGo) { - setTimeout(function(){ - fadeOut(containerEl, keyEl) - }, 1000) - } - } - }) + var supportsPouchDB = hasIndexedDB || Modernizr.websqldatabase + var language = findTranslation() + + Modernizr.load({ + test: supportsPouchDB && (Modernizr.localstorage && Modernizr.webworkers && Modernizr.blobconstructor && Modernizr.getrandomvalues), + yep: 'assets/js/application-' + language + '.js', + nope: 'assets/js/nope-' + language + '.js', + callback: function(testResult, key) { + goodToGo = key + }, + complete: function() { + if(goodToGo) { + window.initHiveApp() + } + } + }) }) function findTranslation(){ - var language = navigator.language.toLocaleLowerCase() || 'en' - return languages.filter(function(l){ - return language === l || language.substr(0, 2) === l - })[0] || 'en' + var language = navigator.language.toLocaleLowerCase() || 'en' + return languages.filter(function(l){ + return language === l || language.substr(0, 2) === l + })[0] || 'en' } //monkey patch URL for safari 6 window.URL = window.URL || window.webkitURL - diff --git a/app/pages/history/index.ract b/app/pages/history/index.ract index 115f4c24..0a9ec001 100644 --- a/app/pages/history/index.ract +++ b/app/pages/history/index.ract @@ -1,44 +1,44 @@
- {{#loadingTx}} + {{#loadingTx}}
-
{{translate("Loading transactions...")}}
+
{{translate("Loading transactions...")}}
- {{/loadingTx}} - {{#transactions.length}} + {{/loadingTx}} + {{#transactions.length}}

{{translate("Your transaction history")}}

- {{/transactions.length}} - {{#transactions:index}} + {{/transactions.length}} + {{#transactions:index}}
-
+
-
- {{amount > 0 ? '+' : ''}} {{satoshiToBtc(amount)}} -
+
+ {{amount > 0 ? '+' : ''}} {{satoshiToBtc(amount)}} +
- {{#confirmations}} - {{formatTimestamp(timestamp)}} - {{/confirmations}} + {{#confirmations}} + {{formatTimestamp(timestamp)}} + {{/confirmations}} - {{^confirmations}} - {{translate("pending confirmation")}} - {{/confirmations}} + {{^confirmations}} + {{translate("pending confirmation")}} + {{/confirmations}} -
+
-
{{amount > 0 ? translate('Received') : outs[0].address}}
+
{{amount > 0 ? translate('Received') : outs[0].address}}
- {{/transactions}} - {{^transactions}} + {{/transactions}} + {{^transactions}} {{^loadingTx}} -
+
- {{>svg_help}} + {{>svg_help}}
{{translate("You do not have any transactions yet")}}
-
+
{{/loadingTx}} - {{/transactions}} + {{/transactions}}
diff --git a/app/pages/receive/_index.scss b/app/pages/receive/_index.scss index 7cc125a6..62b6e411 100644 --- a/app/pages/receive/_index.scss +++ b/app/pages/receive/_index.scss @@ -7,6 +7,14 @@ } } +#qr-canvas { + margin: 0 auto; + width: 200px; + height: 200px; + padding: 10px; + background-color: $foreground; +} + .address__box { @extend .generic_box; margin-top: 5px; @@ -23,7 +31,7 @@ @include textselect; @extend .jigsaw-light; display: block; - padding-right: 40px; + font-size: 14px; } ._btn { diff --git a/app/pages/receive/index.js b/app/pages/receive/index.js index 11f8b56a..d4364fad 100644 --- a/app/pages/receive/index.js +++ b/app/pages/receive/index.js @@ -8,99 +8,105 @@ var showQr = require('hive-modal-qr') var geo = require('hive-geo') var showError = require('hive-modal-flash').showError var showSetDetails = require('hive-modal-set-details') -var fadeIn = require('hive-transitions/fade.js').fadeIn -var fadeOut = require('hive-transitions/fade.js').fadeOut +var qrcode = require('hive-qrcode') +var getNetwork = require('hive-network') module.exports = function(el){ - var ractive = new Ractive({ - el: el, - template: require('./index.ract').template, - data: { - address: '', - qrVisible: false, - btn_message: 'Turn Waggle on', - connecting: false, - broadcasting: false + var ractive = new Ractive({ + el: el, + template: require('./index.ract').template, + data: { + address: '', + qrVisible: false, + btn_message: 'Turn Waggle on', + connecting: false, + broadcasting: false + } + }) + + emitter.on('balance-ready', function(){ + ractive.set('address', getAddress()) + var canvas = ractive.nodes['qr-canvas'] + var qr = qrcode(getNetwork() + ':' + ractive.get('address'), { + width: 180, + height: 180, + }); + canvas.appendChild(qr) + }) + + emitter.on('wallet-ready', function(){ + ractive.set('address', getAddress()) + }) + + ractive.on('toggle-broadcast', function(){ + if(ractive.get('connecting')) return; + + if(ractive.get('broadcasting')) { + waggleOff() + } else { + showSetDetails(function(err){ + if(err) return showError({message: 'Could not save your details'}) + waggleOn() + }) + } + }) + + function waggleOff(){ + ractive.set('broadcasting', false) + ractive.set('btn_message', 'Turn Waggle on') + geo.remove(true) } - }) - - emitter.on('balance-ready', function(){ - ractive.set('address', getAddress()) - }) - - emitter.on('wallet-ready', function(){ - ractive.set('address', getAddress()) - }) - - ractive.on('toggle-broadcast', function(){ - if(ractive.get('connecting')) return; - - if(ractive.get('broadcasting')) { - waggleOff() - } else { - showSetDetails(function(err){ - if(err) return showError({message: 'Could not save your details'}) - waggleOn() - }) + + function waggleOn(){ + ractive.set('connecting', true) + ractive.set('btn_message', 'Checking your location') + geo.save(function(err){ + if(err) return handleWaggleError(err) + ractive.set('connecting', false) + ractive.set('broadcasting', true) + ractive.set('btn_message', 'Turn Waggle off') + }) } - }) - - function waggleOff(){ - ractive.set('broadcasting', false) - ractive.set('btn_message', 'Turn Waggle on') - geo.remove(true) - } - - function waggleOn(){ - ractive.set('connecting', true) - ractive.set('btn_message', 'Checking your location') - geo.save(function(err){ - if(err) return handleWaggleError(err) - ractive.set('connecting', false) - ractive.set('broadcasting', true) - ractive.set('btn_message', 'Turn Waggle off') - }) - } - window.addEventListener('beforeunload', removeGeoData) + window.addEventListener('beforeunload', removeGeoData) - function removeGeoData() { - geo.remove(true) - } + function removeGeoData() { + geo.remove(true) + } - ractive.on('teardown', function(){ - window.removeEventListener('beforeunload', removeGeoData) - }, false) + ractive.on('teardown', function(){ + window.removeEventListener('beforeunload', removeGeoData) + }, false) - ractive.on('show-qr', function(){ - showQr({ - address: ractive.get('address') + ractive.on('show-qr', function(){ + showQr({ + address: ractive.get('address') + }) }) - }) - ractive.on('help', function() { - showTooltip({ - message: 'Waggle lets you broadcast your wallet address to other nearby Hive users by comparing GPS data. This data is deleted once you turn Waggle off.' + ractive.on('help', function() { + showTooltip({ + message: 'Waggle lets you broadcast your wallet address to other nearby Hive users by comparing GPS data. This data is deleted once you turn Waggle off.' + }) }) - }) - function getAddress(){ - return Hive.getWallet().getNextAddress() - } + function getAddress(){ + return Hive.getWallet().getNextAddress() + } - function handleWaggleError(err) { - console.error(err) + function handleWaggleError(err) { + console.error(err) - var data = { - title: 'Uh Oh...', - message: "We could not connect you to Waggle, please check your internet connection." - } + var data = { + title: 'Uh Oh...', + message: "We could not connect you to Waggle, please check your internet connection." + } - showError(data) - ractive.set('connecting', false) - ractive.set('broadcasting', false) - ractive.set('btn_message', 'Turn Waggle on') - } + showError(data) + ractive.set('connecting', false) + ractive.set('broadcasting', false) + ractive.set('btn_message', 'Turn Waggle on') + } - return ractive + return ractive } diff --git a/app/pages/receive/index.ract b/app/pages/receive/index.ract index 54a94218..f4a398eb 100644 --- a/app/pages/receive/index.ract +++ b/app/pages/receive/index.ract @@ -1,25 +1,6 @@

{{translate("Your wallet address")}}

- {{address}} -
- - {{>svg_expand}} - -
+ {{address}}
-
-{{^broadcasting}} -

{{translate("Waggle")}}

-{{/broadcasting}} -{{#broadcasting}} -

{{translate("Broadcasting your location...")}}

-{{/broadcasting}} - - {{>svg_help}} - -
-
- {{translate(btn_message)}} -
- +
diff --git a/app/pages/send/_index.scss b/app/pages/send/_index.scss index 0916d926..c5d948d1 100644 --- a/app/pages/send/_index.scss +++ b/app/pages/send/_index.scss @@ -1,271 +1,265 @@ .send__address { - display: flex; - margin-bottom: 20px; - - .input__container { position: relative; - margin-top: 5px; - } + margin-bottom: 20px; - .close__input { - ._icon{ - .svg-close { - fill: #969594; - } + .input__container { + position: relative; + margin-top: 5px; } - } - ._label { - @include noselect; - cursor: pointer; - display: block; - flex: 1; - margin-right: 10px; + ._label { + @include noselect; + cursor: pointer; + display: block; + flex: 1; + margin-right: 10px; - @include breakpoint(portrait) { - font-size: 20px; + @include breakpoint(portrait) { + font-size: 20px; + } } - } - - ._btn { - @extend .hivebtn; - margin-top: 29px; - padding: 0; - width: 42px; - height: 42px; - position: relative; - @include breakpoint(portrait) { - margin-top: 35px; - width: 59px; - height: 59px; + ._btn { + @extend .hivebtn; + margin-top: 29px; + padding: 0; + width: 42px; + height: 42px; + position: relative; + + @include breakpoint(portrait) { + margin-top: 35px; + width: 59px; + height: 59px; + } + + ._icon { + width: 30px; + height: 30px; + position: absolute; + top: 50%; + left: 50%; + margin-top: -15px; + margin-left: -15px; + + @include breakpoint(portrait) { + width: 44px; + height: 44px; + margin-top: -22px; + margin-left: -22px; + } + } } - ._icon { - width: 30px; - height: 30px; - position: absolute; - top: 50%; - left: 50%; - margin-top: -15px; - margin-left: -15px; - - @include breakpoint(portrait) { - width: 44px; - height: 44px; - margin-top: -22px; - margin-left: -22px; - } - } - } - - ._input { - @extend .generic_box; - @extend .jigsaw-light; - padding-left: 10px; - padding-right: 38px; - border-radius: 2px; - - height: auto; - - &:active, &:focus { - outline: 0; - border: 1px solid $blue; + ._input { + @extend .generic_box; + @extend .jigsaw-light; + padding-left: 10px; + height: auto; + margin: 0; + border-radius: 0; + border-top-right-radius: 2px; + border-top-left-radius: 2px; + position: relative; + z-index: 200; + + &:active, &:focus { + outline: 0; + border: 1px solid $blue; + } + + @include breakpoint(portrait) { + font-size: 26px; + border-radius: 3px; + } } - @include breakpoint(portrait) { - font-size: 26px; - border-radius: 3px; - padding-right: 58px; - } - } } .send__amount { - position: relative; - - ._label { - @include noselect; - cursor: pointer; - display: block; - - @include breakpoint(portrait) { - font-size: 20px; - margin-top: 40px; - } - } - - ._currency { - @include noselect; - @extend .jigsaw-light; - position: absolute; - z-index: 500; - cursor: pointer; - display: block; - text-align: right; - font-size: 18px; - right: 10px; - top: 11px; - opacity: 0.4; - - @include breakpoint(portrait) { - top: 14px; - } - - select { - @extend .jigsaw-light; - padding-right: 20px; - font-size: 18px; - border: none; - background-color: transparent; + position: relative; - &:focus { - outline: none; - } + ._label { + @include noselect; + cursor: pointer; + display: block; - @include breakpoint(portrait) { - font-size: 24px; - } + @include breakpoint(portrait) { + font-size: 20px; + margin-top: 40px; + } } - &.dropdown { - top: 5px; - right: 3px; - @include breakpoint(portrait) { - top: 7px; - } + ._currency { + @include noselect; + @extend .jigsaw-light; + position: absolute; + z-index: 500; + cursor: pointer; + display: block; + text-align: right; + font-size: 18px; + right: 10px; + top: 11px; + + @include breakpoint(portrait) { + top: 14px; + } + + select { + @extend .jigsaw-light; + padding-right: 20px; + font-size: 18px; + border: none; + background-color: transparent; + + &:focus { + outline: none; + } + + @include breakpoint(portrait) { + font-size: 24px; + } + } + + &.dropdown { + top: 5px; + right: 3px; + @include breakpoint(portrait) { + top: 7px; + } + } + + @include breakpoint(portrait) { + font-size: 24px; + } } - @include breakpoint(portrait) { - font-size: 24px; + ._currency--error { + @include noselect; + @extend .jigsaw-light; + position: absolute; + z-index: 500; + cursor: pointer; + display: block; + text-align: right; + font-size: 18px; + right: 10px; + top: 9px; + opacity: 0.4; + + select { + @extend .jigsaw-light; + padding-right: 20px; + font-size: 18px; + border: none; + background-color: transparent; + + &:focus { + outline: none; + } + + } + + &.dropdown { + top: 4px; + right: 3px; + } } - } - - ._currency--error { - @include noselect; - @extend .jigsaw-light; - position: absolute; - z-index: 500; - cursor: pointer; - display: block; - text-align: right; - font-size: 18px; - right: 10px; - top: 9px; - opacity: 0.4; - - select { - @extend .jigsaw-light; - padding-right: 20px; - font-size: 18px; - border: none; - background-color: transparent; - - &:focus { - outline: none; - } - } - &.dropdown { - top: 4px; - right: 3px; - } - } - - - ._input { - @extend .generic_box; - @extend .jigsaw-light; - padding-left: 10px; - height: auto; - margin: 0; - border-radius: 0; - border-top-right-radius: 2px; - border-top-left-radius: 2px; - position: relative; - z-index: 200; - - &:active, &:focus { - outline: 0; - border: 1px solid $blue; + ._input { + @extend .generic_box; + @extend .jigsaw-light; + padding-left: 10px; + height: auto; + margin: 0; + border-radius: 0; + border-top-right-radius: 2px; + border-top-left-radius: 2px; + position: relative; + z-index: 200; + + &:active, &:focus { + outline: 0; + border: 1px solid $blue; + } + + @include breakpoint(portrait) { + font-size: 26px; + border-radius: 3px; + } } - @include breakpoint(portrait) { - font-size: 26px; - border-radius: 3px; + ._error { + background-color: lighten(red, 40%); + border: 1px solid red; } - } - - ._error { - background-color: lighten(red, 40%); - border: 1px solid red; - } } ._input-group { - position: relative; - margin-top: 5px; + position: relative; + margin-top: 5px; - & + ._input-group { - margin-top: 0; - ._input { - margin-top: -1px; - border-radius: 2px; - border-top-right-radius: 0; - border-top-left-radius: 0; - z-index: 300; - &:focus { - z-index: 300; - } + & + ._input-group { + margin-top: 0; + ._input { + margin-top: -1px; + border-radius: 2px; + border-top-right-radius: 0; + border-top-left-radius: 0; + z-index: 300; + &:focus { + z-index: 300; + } + } } - } } .send__buttons { - margin-top: 20px; - @include breakpoint(portrait) { - margin-top: 40px; - } + margin-top: 20px; + @include breakpoint(portrait) { + margin-top: 40px; + } } .send__btn { - @extend .hivebtn; + @extend .hivebtn; - @include breakpoint(portrait) { - font-size: 26px; - border-radius: 3px; - } + @include breakpoint(portrait) { + font-size: 26px; + border-radius: 3px; + } } .send__btn--validating { - @extend .hivebtn; - position: relative; - margin-left: 5px; - color: darken($grey, 20%); - background-color: $grey; - transform: translate(0px, 3px); - box-shadow: 0 0px 0 0; - &:hover { + @extend .hivebtn; + position: relative; + margin-left: 5px; color: darken($grey, 20%); - } - ._icon { - position: absolute; - top: 50%; - left: 50%; - margin-top: -15px; - margin-left: -15px; - width: 30px; - height: 30px; - display: inline; - animation: infinite-spinning 1s linear infinite; - .svg-refresh { - fill: darken($grey, 20%); + background-color: $grey; + transform: translate(0px, 3px); + box-shadow: 0 0px 0 0; + &:hover { + color: darken($grey, 20%); + } + ._icon { + position: absolute; + top: 50%; + left: 50%; + margin-top: -15px; + margin-left: -15px; + width: 30px; + height: 30px; + display: inline; + animation: infinite-spinning 1s linear infinite; + .svg-refresh { + fill: darken($grey, 20%); + } } - } } diff --git a/app/pages/send/index.js b/app/pages/send/index.js index 1e51407f..ae8098c6 100644 --- a/app/pages/send/index.js +++ b/app/pages/send/index.js @@ -13,143 +13,141 @@ var showConfirmation = require('hive-modal-confirm-send') var validateSend = require('hive-wallet').validateSend module.exports = function(el){ - var ractive = new Ractive({ - el: el, - template: require('./index.ract').template, - data: { - currencies: currencies, - exchangeRates: {} - } - }) - - emitter.on('clear-send-form', function(){ - ractive.set('to', '') - ractive.set('value', '') - ractive.set('fiatValue', '') - }) - - emitter.on('prefill-wallet', function(address) { - ractive.set('to', address) - }) - - ractive.on('open-geo', function(){ - var data = { - overlay: 'geo', - context: 'send' - } - emitter.emit('open-overlay', data) - }) - - emitter.on('send-confirm-open', function() { - ractive.set('validating', false) - }) - - ractive.on('open-send', function(){ - var to = ractive.get('to') - var amount = ractive.get('value') - - validateSend(getWallet(), to, amount, function(err, fee){ - if(err) { - var interpolations = err.interpolations - if(err.message.match(/trying to empty your wallet/)){ - ractive.set('value', interpolations.sendableBalance) - return showInfo({message: err.message, interpolations: interpolations}) + var ractive = new Ractive({ + el: el, + template: require('./index.ract').template, + data: { + currencies: currencies, + exchangeRates: {} } - return showError({title: 'Uh Oh...', message: err.message, href: err.href, linkText: err.linkText, interpolations: interpolations}) - } - - showConfirmation({ - to: to, - amount: ractive.get('value'), // don't change this to amount. 'value' could be modified above - denomination: ractive.get('denomination'), - fee: fee - }) }) - }) - emitter.on('wallet-ready', function(){ - ractive.set('denomination', getWallet().denomination) - }) + emitter.on('clear-send-form', function(){ + ractive.set('to', '') + ractive.set('value', '') + ractive.set('fiatValue', '') + }) - emitter.on('db-ready', function(){ - db.get(function(err, doc){ - if(err) return console.error(err); + emitter.on('prefill-wallet', function(address) { + ractive.set('to', address) + }) - ractive.set('selectedFiat', doc.systemInfo.preferredCurrency) + emitter.on('send-confirm-open', function() { + ractive.set('validating', false) }) - }) - emitter.on('ticker', function(rates){ - ractive.set('exchangeRates', rates) - }) + ractive.on('open-send', function(){ + var to = ractive.get('to') + var amount = ractive.get('value') + + validateSend(getWallet(), to, amount, function(err, fee){ + if(err) { + var interpolations = err.interpolations + if(err.message.match(/trying to empty your wallet/)){ + ractive.set('value', interpolations.sendableBalance) + return showInfo({message: err.message, interpolations: interpolations}) + } + return showError({ + title: 'Uh Oh...', + message: err.message, + href: err.href, + linkText: err.linkText, + interpolations: interpolations + }); + } + + showConfirmation({ + to: to, + amount: ractive.get('value'), // don't change this to amount. 'value' could be modified above + denomination: ractive.get('denomination'), + fee: fee + }) + }) + }) - ractive.observe('selectedFiat', setPreferredCurrency) + emitter.on('wallet-ready', function(){ + ractive.set('denomination', getWallet().denomination) + }) - ractive.on('fiat-to-bitcoin', function(){ - var fiat = ractive.nodes.fiat.value - if(fiat == undefined || fiat === '') return; + emitter.on('db-ready', function(){ + db.get(function(err, doc){ + if(err) return console.error(err); - var exchangeRate = getExchangeRate() - if(!exchangeRate) return; + ractive.set('selectedFiat', doc.systemInfo.preferredCurrency) + }) + }) - var bitcoin = toFixedFloor(new Big(fiat).div(exchangeRate), 8) + emitter.on('ticker', function(rates){ + ractive.set('exchangeRates', rates) + }) - ractive.set('value', bitcoin) - }) + ractive.observe('selectedFiat', setPreferredCurrency) - ractive.on('bitcoin-to-fiat', function(){ - var bitcoin = ractive.nodes.bitcoin.value - if(bitcoin == undefined || bitcoin === '') return; + ractive.on('fiat-to-bitcoin', function(){ + var fiat = ractive.nodes.fiat.value + if(fiat === undefined || fiat === '') return; + var exchangeRate = getExchangeRate() + if(!exchangeRate) return; - var exchangeRate = getExchangeRate() - if(!exchangeRate) return; + var bitcoin = toFixedFloor(new Big(fiat).div(exchangeRate), 8) - var val = new Big(bitcoin).times(exchangeRate) - var fiat = toFixedFloor(val, 2) + ractive.set('value', bitcoin) + }) - ractive.set('fiatValue', fiat) - }) + ractive.on('bitcoin-to-fiat', function(){ + var bitcoin = ractive.nodes.bitcoin.value + if(bitcoin === undefined || bitcoin === '') return; - ractive.observe('to', function() { - if(ractive.nodes.to.value.length === 0) { - ractive.set('toEntered', false) - } else { - ractive.set('toEntered', true) - } - }) - ractive.on('clearTo', function(){ - var passfield = ractive.nodes.to - ractive.set('to', '') - ractive.set('toEntered', false) - passfield.focus() - }) + var exchangeRate = getExchangeRate() + if(!exchangeRate) return; - ractive.on('focusAmountInput', function(event) { - event.node.parentNode.style.zIndex = 5000 - }) + var val = new Big(bitcoin).times(exchangeRate) + var fiat = toFixedFloor(val, 2) - ractive.on('blurAmountInput', function(event) { - event.node.parentNode.style.zIndex = '' - }) + ractive.set('fiatValue', fiat) + }) - function getExchangeRate(){ - var exchangeRate = ractive.get('exchangeRates')[ractive.get('selectedFiat')] - ractive.set("exchangeRateUnavailable", exchangeRate == undefined) - return exchangeRate - } + ractive.observe('to', function() { + if(ractive.nodes.to.value.length === 0) { + ractive.set('toEntered', false) + } else { + ractive.set('toEntered', true) + } + }) - function setPreferredCurrency(currency, old){ - if(old == undefined) return; //when loading wallet + ractive.on('clearTo', function(){ + var passfield = ractive.nodes.to + ractive.set('to', '') + ractive.set('toEntered', false) + passfield.focus() + }) - db.set('systemInfo', {preferredCurrency: currency}, function(err, response){ - if(err) return console.error(response); + ractive.on('focusAmountInput', function(event) { + event.node.parentNode.style.zIndex = 5000 + }) - emitter.emit('preferred-currency-changed', currency) - ractive.fire('bitcoin-to-fiat') + ractive.on('blurAmountInput', function(event) { + event.node.parentNode.style.zIndex = '' }) - } - return ractive + function getExchangeRate(){ + var exchangeRate = ractive.get('exchangeRates')[ractive.get('selectedFiat')] + ractive.set("exchangeRateUnavailable", exchangeRate === undefined) + return exchangeRate + } + + function setPreferredCurrency(currency, old){ + if(old === undefined) return; //when loading wallet + + db.set('systemInfo', {preferredCurrency: currency}, function(err, response){ + if(err) return console.error(response); + + emitter.emit('preferred-currency-changed', currency) + ractive.fire('bitcoin-to-fiat') + }) + } + + return ractive } diff --git a/app/pages/send/index.ract b/app/pages/send/index.ract index e0f1b6e3..0eb3ca6f 100644 --- a/app/pages/send/index.ract +++ b/app/pages/send/index.ract @@ -1,79 +1,73 @@ -
+
-
- - -
- - {{>svg_waggle}} - +
+ +
+ + {{#toEntered}} +
+ {{> svg_close}} +
+ {{/toEntered}} +
-
-
+
- + -
- - {{denomination}} -
+
+ + {{denomination}} +
- {{^exchangeRateUnavailable}} -
- - - - -
- {{/exchangeRateUnavailable}} + {{^exchangeRateUnavailable}} +
+ + + + +
+ {{/exchangeRateUnavailable}} - {{#exchangeRateUnavailable}} -
- - - - -
-
- {{translate("Exchange rate unavailable for the selected currency")}} -
- {{/exchangeRateUnavailable}} + {{#exchangeRateUnavailable}} +
+ + + + +
+
+ {{translate("Exchange rate unavailable for the selected currency")}} +
+ {{/exchangeRateUnavailable}} -
+
-
+
-
+
{{^validating}} -
{{translate("Confirm")}}
+
{{translate("Confirm")}}
{{/validating}} {{#validating}} -
+
- {{>svg_refresh}} + {{>svg_refresh}} -
+
{{/validating}} -
- +
diff --git a/app/pages/sign/_index.scss b/app/pages/sign/_index.scss new file mode 100644 index 00000000..362bb228 --- /dev/null +++ b/app/pages/sign/_index.scss @@ -0,0 +1,162 @@ +#sign { + + &.content { + padding: 0px; + } + + ._title { + padding-left: 20px; + padding-right: 20px; + padding-bottom: 5px; + + @include breakpoint(portrait) { + font-size: 20px; + padding-left: 40px; + } + } + +} + +.sign { + display: block; +} + +.sign__form { + padding: 20px; +} + +.sign__message { + + position: relative; + margin-bottom: 20px; + + .input__container { + position: relative; + margin-top: 5px; + } + + ._label { + @include noselect; + cursor: pointer; + display: block; + flex: 1; + margin-right: 10px; + + @include breakpoint(portrait) { + font-size: 20px; + } + } + + ._btn { + @extend .hivebtn; + margin-top: 29px; + padding: 0; + width: 42px; + height: 42px; + position: relative; + + @include breakpoint(portrait) { + margin-top: 35px; + width: 59px; + height: 59px; + } + + ._icon { + width: 30px; + height: 30px; + position: absolute; + top: 50%; + left: 50%; + margin-top: -15px; + margin-left: -15px; + + @include breakpoint(portrait) { + width: 44px; + height: 44px; + margin-top: -22px; + margin-left: -22px; + } + } + } + + ._input { + @extend .generic_box; + @extend .jigsaw-light; + padding-left: 10px; + height: auto; + margin: 0; + border-radius: 0; + border-top-right-radius: 2px; + border-top-left-radius: 2px; + position: relative; + z-index: 200; + + &:active, &:focus { + outline: 0; + border: 1px solid $blue; + } + + @include breakpoint(portrait) { + font-size: 26px; + border-radius: 3px; + } + } + +} + +.sign__result { + @include monospaced; + @include border-radius(2px); + margin: 15px auto; + max-width: 280px; + padding: 5px; + background-color: $bitlox-gray-dark; + word-wrap: break-word; +} + +.sign__btn { + @extend .hivebtn; + + @include breakpoint(portrait) { + font-size: 26px; + border-radius: 3px; + } +} + +.sign__item { + @include clear; + @include clickbtn; + padding: 15px; + + @include breakpoint(portrait) { + padding: 30px; + } + + ._name { + @include ellipsis(); + @include media-obj; + font-size: 15px; + padding-top: 12px; + + @include breakpoint(portrait) { + font-size: 26px; + padding-top: 22px; + } + } + + ._arrow { + opacity: 0.6; + float: right; + width: 25px; + height: 25px; + margin-top: 13px; + transform: rotate(270deg); + + @include breakpoint(portrait) { + width: 40px; + height: 40px; + margin-top: 22px; + } + } + +} \ No newline at end of file diff --git a/app/pages/sign/index.js b/app/pages/sign/index.js new file mode 100644 index 00000000..db2e7e54 --- /dev/null +++ b/app/pages/sign/index.js @@ -0,0 +1,47 @@ +'use strict'; + +var Ractive = require('hive-ractive') +var emitter = require('hive-emitter') +var getWallet = require('hive-wallet').getWallet +var bitcoin = require('bitcoinjs-lib') + +module.exports = function(el){ + var ractive = new Ractive({ + el: el, + template: require('./index.ract').template, + data: { + } + }) + + emitter.on('balance-ready', function() { + var wallet = getWallet(); + var currentAddr = wallet.getNextAddress(); + var addresses = wallet.addresses.slice(); + addresses.push(currentAddr); + ractive.set('addresses', addresses); + }); + + ractive.on('clear-signature', function() { + ractive.set('signature', false); + }); + + ractive.on('sign-message', function(event) { + var address = event.node.childNodes[2].innerHTML; + var privKey; + var wallet = getWallet(); + if (address === wallet.getNextAddress()) { + privKey = wallet.externalAccount.derive(wallet.addresses.length).privKey; + } else { + privKey = wallet.getPrivateKeyForAddress(address); + } + var message = ractive.get('message'); + var sig = bitcoin.Message.sign(privKey, message).toString('base64'); + ractive.set('signature', sig); + console.log("bitcoin-cli verifymessage '" + + address + "' '" + + sig + "' '" + + message + "'"); + }); + + return ractive +} diff --git a/app/pages/sign/index.ract b/app/pages/sign/index.ract new file mode 100644 index 00000000..f10660dd --- /dev/null +++ b/app/pages/sign/index.ract @@ -0,0 +1,46 @@ + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + + {{#signature}} +
+
+ {{signature}} +
+
{{translate("Clear")}}
+
+ {{/signature}} + + {{^signature}} + {{#addresses}} +
+ {{>svg_arrow}} +

{{this}}

+
+ {{/addresses}} + {{/signature}} + +
diff --git a/app/pages/tokens/package.json b/app/pages/sign/package.json similarity index 88% rename from app/pages/tokens/package.json rename to app/pages/sign/package.json index 5455cd2f..596a5a13 100644 --- a/app/pages/tokens/package.json +++ b/app/pages/sign/package.json @@ -1,5 +1,5 @@ { - "name": "hive-tokens", + "name": "hive-sign", "version": "0.0.0", "description": "", "main": "index.js", diff --git a/app/pages/tokens/_index.scss b/app/pages/tokens/_index.scss deleted file mode 100644 index f887f2fa..00000000 --- a/app/pages/tokens/_index.scss +++ /dev/null @@ -1,90 +0,0 @@ -#tokens { - - &.content { - padding: 0px; - } - - ._title { - padding-left: 20px; - padding-right: 20px; - padding-bottom: 5px; - - @include breakpoint(portrait) { - font-size: 20px; - padding-left: 40px; - } - } -} -.tokens { - display: block; -} - -.token__item { - @include clear; - @include clickbtn; - padding: 15px; - - @include breakpoint(portrait) { - padding: 30px; - } - - ._icon { - border-radius: 50%; - width: 50px; - height: 50px; - display: inline-block; - float: left; - border: 2px solid white; - margin-right: 20px; - - @include breakpoint(portrait) { - width: 80px; - height: 80px; - } - } - - ._name { - @include media-obj; - font-size: 18px; - padding-top: 13px; - - @include breakpoint(portrait) { - font-size: 26px; - padding-top: 22px; - } - } - - ._arrow { - opacity: 0.6; - float: right; - width: 25px; - height: 25px; - margin-top: 13px; - transform: rotate(270deg); - - @include breakpoint(portrait) { - width: 40px; - height: 40px; - margin-top: 22px; - } - } - - &.current { - display: none; - } -} - - -.token--bitcoin { - background-color: $purple--light; - ._name { - color: white; - } -} - -.token--litecoin { - background-color: #b1b1b1; - ._name { - color: white; - } -} diff --git a/app/pages/tokens/index.js b/app/pages/tokens/index.js deleted file mode 100644 index 93baac49..00000000 --- a/app/pages/tokens/index.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -var Ractive = require('hive-ractive') -var getNetwork = require('hive-network') - -module.exports = function(el){ - var ractive = new Ractive({ - el: el, - template: require('./index.ract').template, - data: { - title: 'Available Tokens', - id: 'token_dropdown', - tokens: [ - { - token: 'bitcoin', - bitcoin: true - }, - { - token: 'litecoin', - litecoin: true - } - ], - capitalize: function(str){ - return str.replace(/^.|\s\S/g, function(a) { - return a.toUpperCase() - }) - }, - getNetworkClass: function(elId){ - return getNetwork() === elId ? "current" : "" - } - } - }) - - ractive.on('switch-token', function(event) { - var token = event.node.id - if(token === getNetwork()) return; - - var url = window.location.href.replace(/\?network=\w+/, '') + '?network=' + token - window.location.assign(url); - }) - - return ractive -} diff --git a/app/pages/tokens/index.ract b/app/pages/tokens/index.ract deleted file mode 100644 index 89eced1a..00000000 --- a/app/pages/tokens/index.ract +++ /dev/null @@ -1,18 +0,0 @@ - -
- {{#tokens}} -
- - {{>svg_arrow}} - - {{#bitcoin}} - {{>svg_token_bitcoin}} - {{/bitcoin}} - {{#litecoin}} - {{>svg_token_litecoin}} - {{/litecoin}} - -

{{capitalize(token)}}

-
- {{/tokens}} -
diff --git a/app/widgets/auth/_index.scss b/app/widgets/auth/_index.scss index 411992c6..c6491a52 100644 --- a/app/widgets/auth/_index.scss +++ b/app/widgets/auth/_index.scss @@ -50,8 +50,6 @@ max-width: 300px; ._img { - width: 105px; - height: 99px; display: block; margin: 0 auto; margin-bottom: 10px; @@ -216,7 +214,7 @@ margin-right: 20px; margin-bottom: 20px; padding: 10px; - background-color: #343157; + background-color: $background; border: 1px solid; border-radius: 4px; box-shadow: inset 0px 1px 3px 0px rgba(0,0,0,0.25); @@ -254,11 +252,10 @@ user-select: none; text-align: center; font-size: 18px; - background-color: $blue; + background-color: $grey; border-radius: 2px; color: rgba(255,255,255, 0.3); - background-color: #2d5f8d; box-shadow:inset 0 1px 1px 1px darken(#2d5f8d, 20%); transform: translate(0px, 3px); @@ -286,7 +283,7 @@ @extend .hivebtn; position: relative; color: rgba(255,255,255, 0.3); - background-color: #2d5f8d; + background-color: $bitlox-gray-dark; box-shadow:inset 0 1px 1px 1px darken(#2d5f8d, 20%); transform: translate(0px, 3px); margin-bottom: 5px; @@ -300,7 +297,7 @@ padding: 22px 30px 20px 30px; } - &:active { + &:tive { box-shadow:inset 0 1px 1px 1px darken(#2d5f8d, 20%); transform: translate(0px, 3px); } @@ -310,20 +307,11 @@ } } -.litecoin { - .auth__btn--loading { - background-color: $silver; - box-shadow:inset 0 1px 1px 1px darken($silver, 30%); - &:active { - box-shadow:inset 0 1px 1px 1px darken($silver, 30%); - } - } -} .auth__btn--existing { @extend .hivebtn; color: white; - background-color: #5B5582; + background-color: $bitlox-gray-dark; box-shadow: 0 3px 0 0 darken(#5B5582, 20%); margin-bottom: 5px; diff --git a/app/widgets/auth/choose/footer.ract b/app/widgets/auth/choose/footer.ract index 6fddd80f..8bdd41f5 100644 --- a/app/widgets/auth/choose/footer.ract +++ b/app/widgets/auth/choose/footer.ract @@ -1 +1 @@ -{{translate("Back to hivewallet.com")}} +{{translate("Back to bitlox.io")}} diff --git a/app/widgets/auth/header.ract b/app/widgets/auth/header.ract index 6357c7e3..68a6c365 100644 --- a/app/widgets/auth/header.ract +++ b/app/widgets/auth/header.ract @@ -1,3 +1,3 @@
- {{>svg_logo_stack}} +
diff --git a/app/widgets/auth/index.ract b/app/widgets/auth/index.ract index 7a6e925e..2723208f 100644 --- a/app/widgets/auth/index.ract +++ b/app/widgets/auth/index.ract @@ -1,17 +1,16 @@
-
-
- {{>header}} -
+
+
+ {{>header}} +
-
- {{>content}} - {{>actions}} -
+
+ {{>content}} + {{>actions}} +
- -
- diff --git a/app/widgets/auth/pin/content.ract b/app/widgets/auth/pin/content.ract index b64cabb0..81e26961 100644 --- a/app/widgets/auth/pin/content.ract +++ b/app/widgets/auth/pin/content.ract @@ -1,36 +1,36 @@
-
- {{^opening}} -
diff --git a/app/widgets/frame/index.js b/app/widgets/frame/index.js index 6638a8b7..1b29d919 100644 --- a/app/widgets/frame/index.js +++ b/app/widgets/frame/index.js @@ -8,7 +8,7 @@ var initSidebar = require('hive-sidebar') var initSend = require('hive-send') var initReceive = require('hive-receive') var initHistory = require('hive-history') -var initTokens = require('hive-tokens') +var initSign = require('hive-sign') module.exports = function(el){ var ractive = new Ractive({ @@ -26,7 +26,7 @@ module.exports = function(el){ send: initSend(ractive.nodes['send']), receive: initReceive(ractive.nodes['receive']), history: initHistory(ractive.nodes['history']), - tokens: initTokens(ractive.nodes['tokens']) + sign: initSign(ractive.nodes['sign']) } var currentPage = tabs.send diff --git a/app/widgets/frame/index.ract b/app/widgets/frame/index.ract index d33f5caa..6ff19c31 100644 --- a/app/widgets/frame/index.ract +++ b/app/widgets/frame/index.ract @@ -1,7 +1,5 @@
- -
@@ -10,7 +8,7 @@
-
+
diff --git a/app/widgets/header/index.js b/app/widgets/header/index.js index 1b0beadb..c5f603df 100644 --- a/app/widgets/header/index.js +++ b/app/widgets/header/index.js @@ -4,6 +4,7 @@ var Ractive = require('hive-ractive') var emitter = require('hive-emitter') var sync = require('hive-wallet').sync var getWallet = require('hive-wallet').getWallet +var openSupportModal = require('hive-modal-support') var satoshiToBtc = require('hive-convert').satoshiToBtc var toFixedFloor = require('hive-convert').toFixedFloor var Big = require('big.js') @@ -47,9 +48,8 @@ module.exports = function(el){ ractive.set('bitcoinBalance', getWallet().getBalance()) }) - ractive.on('toggle', function(){ - window.scrollTo(0, 0); - emitter.emit('toggle-menu', !ractive.get('menuOpen')) + ractive.on('support', function(){ + openSupportModal() }) function toggleIcon(open){ diff --git a/app/widgets/header/index.ract b/app/widgets/header/index.ract index dcc29557..a7eb2ab2 100644 --- a/app/widgets/header/index.ract +++ b/app/widgets/header/index.ract @@ -1,17 +1,8 @@
- {{#menuOpen}} -
- {{/menuOpen}} - -
- diff --git a/app/widgets/modal-confirm-send/_index.scss b/app/widgets/modal-confirm-send/_index.scss index 69d468a2..99dd340f 100644 --- a/app/widgets/modal-confirm-send/_index.scss +++ b/app/widgets/modal-confirm-send/_index.scss @@ -1,230 +1,230 @@ .overlay--confirm { - @extend .overlay; - overflow-y: auto; - background-color: rgba(0,0,0,0.6x); + @extend .overlay; + overflow-y: auto; + background-color: rgba(0,0,0,0.6x); } .confirm { - padding: 0; - padding-top: 20px; - background-color: white; - min-width: 280px; - max-width: 450px; - - @include breakpoint(portrait) { - width: 450px; - padding-top: 30px; - } - - &._error { - background-color: $red; - } - &._success { - background-color: $green; - } + padding: 0; + padding-top: 20px; + background-color: $background; + min-width: 280px; + max-width: 450px; + + @include breakpoint(portrait) { + width: 450px;s + padding-top: 30px; + } + + &._error { + background-color: $red; + } + &._success { + background-color: $green; + } } .confirm__header { - font-size: 21px; - text-align: center; - padding-bottom: 10px; - border-bottom: 1px solid $grey; - - @include breakpoint(portrait) { - font-size: 24px; - padding-bottom: 20px; - } + font-size: 21px; + text-align: center; + padding-bottom: 10px; + border-bottom: 1px solid $grey; + + @include breakpoint(portrait) { + font-size: 24px; + padding-bottom: 20px; + } } .confirm__transaction{ - text-align: center; - padding-left: 20px; - padding-right: 20px; - - ._amount { - padding-top: 20px; + text-align: center; padding-left: 20px; padding-right: 20px; - display: flex; - justify-content: center; - - ._value { - @extend .jigsaw-light; - font-size: 32px; - @include breakpoint(portrait) { - font-size: 48px; - } + ._amount { + padding-top: 20px; + padding-left: 20px; + padding-right: 20px; + display: flex; + justify-content: center; + + ._value { + @extend .jigsaw-light; + font-size: 32px; + + @include breakpoint(portrait) { + font-size: 48px; + } + } + + ._currency { + @extend .jigsaw-light; + font-size: 14px; + padding-top: 6px; + margin-left: 3px; + + @include breakpoint(portrait) { + font-size: 18px; + } + } } - ._currency { - @extend .jigsaw-light; - font-size: 14px; - padding-top: 6px; - margin-left: 3px; + ._fee { + display: block; + font-size: 12px; + color: $grey; + text-align: center; + padding-top: 10px; - @include breakpoint(portrait) { - font-size: 18px; - } + @include breakpoint(portrait) { + font-size: 18px; + } } - } - ._fee { - display: block; - font-size: 12px; - color: $grey; - text-align: center; - padding-top: 10px; - - @include breakpoint(portrait) { - font-size: 18px; - } - } - - ._icon { - display: inline-block; - width: 25px; - height: 25px; - margin-top: 5px; - color: $grey; - - @include breakpoint(portrait) { - width: 40px; - height: 40px; + ._icon { + display: inline-block; + width: 25px; + height: 25px; + margin-top: 5px; + color: $grey; + + @include breakpoint(portrait) { + width: 40px; + height: 40px; + } } - } - ._address { - @include wrapdat; - @extend .jigsaw-light; - font-size: 13px; - display: block; - text-align: center; - @include breakpoint(portrait) { - font-size: 18px; + ._address { + @include wrapdat; + @extend .jigsaw-light; + font-size: 13px; + display: block; + text-align: center; + @include breakpoint(portrait) { + font-size: 18px; + } } - } } .confirm__inputs { - padding: 20px; - background-color: white; - border-radius: 3px; + padding: 20px; + background-color: $background; + border-radius: 3px; - display: flex; + display: flex; - ._cancel { - @extend .hivebtn; - margin-right: 5px; + ._cancel { + @extend .hivebtn; + margin-right: 5px; - color: darken($grey, 20%); - background-color: $grey; - box-shadow: 0 2px 0 0 darken($grey, 20%); + color: darken($grey, 20%); + background-color: $grey; + box-shadow: 0 2px 0 0 darken($grey, 20%); - @include breakpoint(portrait) { - font-size: 24px; - } + @include breakpoint(portrait) { + font-size: 24px; + } - &:hover { - color: darken($grey, 20%); + &:hover { + color: darken($grey, 20%); + } } - } - ._report { - @extend .hivebtn; - margin-right: 5px; + ._report { + @extend .hivebtn; + margin-right: 5px; - @include breakpoint(portrait) { - font-size: 24px; + @include breakpoint(portrait) { + font-size: 24px; + } } - } - ._send { - @extend .hivebtn; - margin-left: 5px; + ._send { + @extend .hivebtn; + margin-left: 5px; - @include breakpoint(portrait) { - font-size: 24px; + @include breakpoint(portrait) { + font-size: 24px; + } } - } - - ._send--sending { - @extend .hivebtn; - position: relative; - margin-left: 5px; - color: darken($grey, 20%); - background-color: $grey; - transform: translate(0px, 3px); - box-shadow: 0 0px 0 0; - &:hover { - color: darken($grey, 20%); - } - ._icon { - position: absolute; - top: 50%; - left: 50%; - margin-top: -15px; - margin-left: -15px; - width: 30px; - height: 30px; - display: inline; - animation: infinite-spinning 1s linear infinite; - .svg-refresh { - fill: darken($grey, 20%); - } + + ._send--sending { + @extend .hivebtn; + position: relative; + margin-left: 5px; + color: darken($grey, 20%); + background-color: $grey; + transform: translate(0px, 3px); + box-shadow: 0 0px 0 0; + &:hover { + color: darken($grey, 20%); + } + ._icon { + position: absolute; + top: 50%; + left: 50%; + margin-top: -15px; + margin-left: -15px; + width: 30px; + height: 30px; + display: inline; + animation: infinite-spinning 1s linear infinite; + .svg-refresh { + fill: darken($grey, 20%); + } + } } - } } .confirm__responseIcon { - margin: 0 auto; - margin-bottom: 20px; - width: 120px; - height: 120px; - display: block; + margin: 0 auto; + margin-bottom: 20px; + width: 120px; + height: 120px; + display: block; } .confirm__responseTitle { - color: white; - font-size: 21px; - text-align: center; - padding-bottom: 10px; - - @include breakpoint(portrait) { - font-size: 28px; - } + color: white; + font-size: 21px; + text-align: center; + padding-bottom: 10px; + + @include breakpoint(portrait) { + font-size: 28px; + } } .confirm__responseMsg { - color: white; - text-align: center; - max-width: 180px; - margin: 0 auto; - padding-bottom: 40px; - line-height: 1.3; - font-size: 13px; - - @include breakpoint(portrait) { - font-size: 18px; - max-width: 250px; - } + color: white; + text-align: center; + max-width: 180px; + margin: 0 auto; + padding-bottom: 40px; + line-height: 1.3; + font-size: 13px; + + @include breakpoint(portrait) { + font-size: 18px; + max-width: 250px; + } } ._error, ._success { - .confirm__inputs { + .confirm__inputs { - background-color: white; - display: flex; + background-color: $background; + display: flex; - ._cancel { - max-width: 140px; - margin: 0 auto; - } + ._cancel { + max-width: 140px; + margin: 0 auto; + } - } + } } diff --git a/app/widgets/modal-qr/_content.scss b/app/widgets/modal-qr/_content.scss index 26384f95..3dccf81f 100644 --- a/app/widgets/modal-qr/_content.scss +++ b/app/widgets/modal-qr/_content.scss @@ -3,6 +3,8 @@ margin: 0 auto; width: 200px; height: 200px; + padding: 10px; + background-color: $foreground; } .qr__container { @@ -88,4 +90,3 @@ } } } - diff --git a/app/widgets/modal-qr/content.ract b/app/widgets/modal-qr/content.ract index e2cfe527..aa11f041 100644 --- a/app/widgets/modal-qr/content.ract +++ b/app/widgets/modal-qr/content.ract @@ -1,20 +1,20 @@ diff --git a/server/express.js b/server/express.js index 3391f704..e1363ff4 100644 --- a/server/express.js +++ b/server/express.js @@ -11,210 +11,231 @@ var geo = require('./geo') var validatePin = require('hive-pin-validator') var crypto = require('crypto') var helmet = require('helmet') +var parseUrl = require('url').parse; +var https = require('https'); module.exports = function (){ - var app = express() - - app.use(requireHTTPS) - - if(isProduction()){ - app.set('trust proxy', true) - var proxyHost = process.env.PROXY_URL.replace("https://", '') - var proxyQueryIndex = proxyHost.indexOf('/?') - if(proxyQueryIndex > 0) { - proxyHost = proxyHost.substring(0, proxyQueryIndex) + var app = express() + + app.use(requireHTTPS) + + if(isProduction()){ + app.set('trust proxy', true) + app.use(helmet.csp({ + 'default-src': ["'self'"], + 'child-src': ["'self'", "blob:"], + 'connect-src': [ + "'self'", "blob:", + 'api.bitcoinaverage.com', 'chain.so', // tickers + 'btc.blockr.io', 'tbtc.blockr.io', 'ltc.blockr.io', // blockchain APIs + ], + 'font-src': ['s3.amazonaws.com'], + 'img-src': ["'self'", 'data:', 'www.gravatar.com'], + 'style-src': ["'self'", 's3.amazonaws.com'], + // http://lists.w3.org/Archives/Public/public-webappsec/2014Apr/0021.html, + // https://github.com/ractivejs/ractive/issues/285 + 'script-src': ["'self'", 'blob:', "'unsafe-eval'"], + reportOnly: false, + setAllHeaders: false, + safari5: true + })) + app.use(helmet.xssFilter()) + app.use(helmet.nosniff()) + app.use(helmet.xframe('sameorigin')) + + var hundredEightyDaysInMilliseconds = 180 * 24 * 60 * 60 * 1000 + app.use(helmet.hsts({ + maxAge: hundredEightyDaysInMilliseconds, + includeSubdomains: true + })) } - app.use(helmet.csp({ - 'default-src': ["'self'"], - 'child-src': ["'self'", "blob:"], - 'connect-src': [ - "'self'", "blob:", - 'api.bitcoinaverage.com', 'chain.so', // tickers - 'btc.blockr.io', 'tbtc.blockr.io', 'ltc.blockr.io', // blockchain APIs - process.env.DB_HOST, proxyHost - ], - 'font-src': ['s3.amazonaws.com'], - 'img-src': ["'self'", 'data:', 'www.gravatar.com'], - 'style-src': ["'self'", 's3.amazonaws.com'], - 'script-src': ["'self'", 'blob:', "'unsafe-eval'"], // http://lists.w3.org/Archives/Public/public-webappsec/2014Apr/0021.html, https://github.com/ractivejs/ractive/issues/285 - reportOnly: false, - setAllHeaders: false, - safari5: true - })) - app.use(helmet.xssFilter()) - app.use(helmet.nosniff()) - app.use(helmet.xframe('sameorigin')) - - var hundredEightyDaysInMilliseconds = 180 * 24 * 60 * 60 * 1000 - app.use(helmet.hsts({ - maxAge: hundredEightyDaysInMilliseconds, - includeSubdomains: true + + var anHour = 1000*60*60 + app.use(bodyParser()) + app.use(cookieParser(process.env.COOKIE_SALT)) + app.use(cookieSession({ + signed: false, + overwrite: false, + maxAge: anHour, + httpOnly: true, + secure: isProduction() })) - } - - var anHour = 1000*60*60 - app.use(bodyParser()) - app.use(cookieParser(process.env.COOKIE_SALT)) - app.use(cookieSession({ - signed: false, - overwrite: false, - maxAge: anHour, - httpOnly: true, - secure: isProduction() - })) - app.use(compress()) - - var cacheControl = isProduction() ? { maxAge: anHour } : null - app.use(express.static(path.join(__dirname, '..', 'build'), cacheControl)) - - app.post('/register', validateAuthParams(false), function(req, res) { - var name = req.body.wallet_id - auth.register(name, req.body.pin, function(err, token){ - if(err) { - console.error('error', err) - return res.status(400).send(err) - } - - setCookie(req, name, function(){ - console.log('registered wallet %s', name) - res.status(200).send(token) - }) + app.use(compress()) + + var cacheControl = isProduction() ? { maxAge: anHour } : null + app.use(express.static(path.join(__dirname, '..', 'build'), cacheControl)) + + app.get('/proxy', function (req, res) { + var rqst = https.get(req.query.url, function(resp) { + resp.pipe(res); + }); + rqst.on('error', function(err) { + res.status(500); + res.json(err); + }); + }); + + app.post('/proxy', function (req, res) { + var url = parseUrl(req.query.url); + url.method = 'POST'; + var rqst = https.request(url, function(resp) { + resp.pipe(res); + }); + rqst.on('error', function(err) { + res.status(500); + res.json(err); + }); + rqst.write(JSON.stringify(req.body)); + rqst.end(); + }); + + app.post('/register', validateAuthParams(false), function(req, res) { + var name = req.body.wallet_id + auth.register(name, req.body.pin, function(err, token){ + if(err) { + console.error('error', err) + return res.status(400).send(err) + } + + setCookie(req, name, function(){ + console.log('registered wallet %s', name) + res.status(200).send(token) + }) + }) }) - }) - - app.post('/login', validateAuthParams(true), function(req, res) { - var name = req.body.wallet_id - auth.login(name, req.body.pin, function(err, token){ - if(err) { - console.error('error', err) - return res.status(400).send(err) - } - - setCookie(req, name, function(){ - console.log('authenticated wallet %s', name) - res.status(200).send(token) - }) + + app.post('/login', validateAuthParams(true), function(req, res) { + var name = req.body.wallet_id + auth.login(name, req.body.pin, function(err, token){ + if(err) { + console.error('error', err) + return res.status(400).send(err) + } + + setCookie(req, name, function(){ + console.log('authenticated wallet %s', name) + res.status(200).send(token) + }) + }) }) - }) - app.get('/exist', function(req, res){ - var name = req.query.wallet_id - if (!name) return res.status(400).json({error: 'Bad request'}); + app.get('/exist', function(req, res){ + var name = req.query.wallet_id + if (!name) return res.status(400).json({error: 'Bad request'}); - auth.exist(name, function(err, userExist){ - if(err) { - console.error('error', err) - return res.status(400).send(err) - } + auth.exist(name, function(err, userExist){ + if(err) { + console.error('error', err) + return res.status(400).send(err) + } - res.status(200).send(userExist) + res.status(200).send(userExist) + }) }) - }) - app.delete('/pin', restrict, function(req, res) { - var id = req.body.id - var pin = req.body.pin + app.delete('/pin', restrict, function(req, res) { + var id = req.body.id + var pin = req.body.pin - auth.disablePin(id, pin, function(err){ - if(err) return res.status(400).send(err) - res.status(200).send() + auth.disablePin(id, pin, function(err){ + if(err) return res.status(400).send(err) + res.status(200).send() + }) }) - }) - app.get('/reset', function(req, res){ - var name = req.query.wallet_id - if (!name) return res.status(400).json({error: 'Bad request'}); + app.get('/reset', function(req, res){ + var name = req.query.wallet_id + if (!name) return res.status(400).json({error: 'Bad request'}); - auth.resetPin(name, function(err){ - res.status(200).send(err) + auth.resetPin(name, function(err){ + res.status(200).send(err) + }) }) - }) - app.post('/location', function(req, res) { - var args = prepareGeoData(req, res) + app.post('/location', function(req, res) { + var args = prepareGeoData(req, res) + + args.push(function(err) { + if(err) return res.status(400).json(err); + res.status(201).send() + }) - args.push(function(err) { - if(err) return res.status(400).json(err); - res.status(201).send() + geo.save.apply(null, args) }) - geo.save.apply(null, args) - }) + app.put('/location', function(req, res) { + var args = prepareGeoData(req, res) + args.push(function(err, results) { + if(err) return res.status(400).json(err) + res.status(200).json(results) + }) - app.put('/location', function(req, res) { - var args = prepareGeoData(req, res) - args.push(function(err, results) { - if(err) return res.status(400).json(err) - res.status(200).json(results) + geo.search.apply(null, args) }) - geo.search.apply(null, args) - }) + function prepareGeoData(req){ + var data = req.body - function prepareGeoData(req, res){ - var data = req.body + var lat = data.lat + var lon = data.lon + delete data.lat + delete data.lon - var lat = data.lat - var lon = data.lon - delete data.lat - delete data.lon + var id = req.session.tmpSessionID + if(!id) { + id = crypto.randomBytes(16).toString('base64') + req.session.tmpSessionID = id + } + data.id = id - var id = req.session.tmpSessionID - if(!id) { - id = crypto.randomBytes(16).toString('base64') - req.session.tmpSessionID = id + return [lat, lon, data] } - data.id = id - - return [lat, lon, data] - } - app.delete('/location', function(req, res) { - geo.remove(req.session.tmpSessionID) - res.status(200).send() - }) + app.delete('/location', function(req, res) { + geo.remove(req.session.tmpSessionID) + res.status(200).send() + }) - app.use(function(err, req, res, next){ - console.error(err.stack); - res.status(500).send('Oops! something went wrong.'); - }) + app.use(function(err, req, res){ + console.error(err.stack); + res.status(500).send('Oops! something went wrong.'); + }) - function validateAuthParams(allowMissingPin) { - return function (req, res, next) { - if (!req.body.wallet_id || !validatePin(req.body.pin, allowMissingPin)) { - return res.status(400).json({error: 'Bad request'}) - } + function validateAuthParams(allowMissingPin) { + return function (req, res, next) { + if (!req.body.wallet_id || !validatePin(req.body.pin, allowMissingPin)) { + return res.status(400).json({error: 'Bad request'}) + } - next() + next() + } } - } - - function restrict(req, res, next) { - var session_id = req.session.wallet_id - if (session_id && session_id === req.body.id) { - next() - } else { - return res.status(401).send() + + function restrict(req, res, next) { + var session_id = req.session.wallet_id + if (session_id && session_id === req.body.id) { + next() + } else { + return res.status(401).send() + } } - } - function setCookie(req, wallet_id, callback){ - req.session.wallet_id = wallet_id - callback() - } + function setCookie(req, wallet_id, callback){ + req.session.wallet_id = wallet_id + callback() + } - function requireHTTPS(req, res, next) { - var herokuForwardedFromHTTPS = req.headers['x-forwarded-proto'] === 'https' - if (!herokuForwardedFromHTTPS && isProduction()) { - return res.redirect('https://' + req.get('host') + req.url) + function requireHTTPS(req, res, next) { + var herokuForwardedFromHTTPS = req.headers['x-forwarded-proto'] === 'https' + if (!herokuForwardedFromHTTPS && isProduction()) { + return res.redirect('https://' + req.get('host') + req.url) + } + next() } - next() - } - function isProduction(){ - return process.env.NODE_ENV === 'production' - } - return app + function isProduction(){ + return process.env.NODE_ENV === 'production' + } + return app } -