diff --git a/gulpfile.js b/gulpfile.js index da6f62241ee117aafa84cb8f83e2e5b1d1ec5b1e..236a7146bcf42fffdae72d956d268d557f440fc6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -260,11 +260,6 @@ gulp.task('copy-files:web', ['clean:tmp', 'clean:web', 'sass', 'config'], functi .pipe(rename("debug.html")) .pipe(gulp.dest(tmpPath)), - // Copy https-storage.html - gulp.src('./www/https-storage.html') - .pipe(htmlmin()) - .pipe(gulp.dest(tmpPath)), - // Copy fonts gulp.src('./www/fonts/**/*.*') .pipe(gulp.dest(tmpPath + '/fonts')), @@ -361,17 +356,7 @@ gulp.task('debug-files:web', ['ng_annotate:web', 'ng_annotate-plugin:web'], func .on('end', done); }); -gulp.task('https-storage-files:web', ['debug-files:web'], function(done) { - var tmpPath = './platforms/web/www'; - - // Process https-storage.html file - gulp.src(tmpPath + '/https-storage.html') - .pipe(useref()) // Concatenate with gulp-useref - .pipe(gulp.dest(tmpPath)) - .on('end', done); -}); - -gulp.task('optimize-files:web', ['https-storage-files:web'], function(done) { +gulp.task('optimize-files:web', ['debug-files:web'], function(done) { var tmpPath = './platforms/web/www'; var jsFilter = filter(["**/*.js", '!**/config.js'], { restore: true }); var cssFilter = filter("**/*.css", { restore: true }); diff --git a/www/https-storage.html b/www/https-storage.html deleted file mode 100644 index 56f67c1262a310767402ef390246082b587d739c..0000000000000000000000000000000000000000 --- a/www/https-storage.html +++ /dev/null @@ -1,11 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <!-- build:js dist_js/https-storage.js --> - <script src="lib/ionic/js/angular/angular-xdLocalStoragePostMessageApi.min.js"></script> - <!-- endbuild --> -</head> -<body> - This is the frame used for Cross-Domain local storage, when using config with httpsMode='clever' -</body> -</html> diff --git a/www/index.html b/www/index.html index 6bbd67a583a5102f74e45bb2da8b3bdcb29bb55f..b22e7854925ba6c54d5b351637f8df2ea685e867 100644 --- a/www/index.html +++ b/www/index.html @@ -43,7 +43,6 @@ <script src="lib/ionic/js/angular/angular-bind-notifier.min.js"></script> <script src="lib/ionic/js/angular/angular-image-crop.js"></script> <script src="lib/ionic/js/angular/angular-file-saver.bundle.js"></script> - <script src="lib/ionic/js/angular/angular-xdLocalStorage.min.js"></script> <script src="js/vendor/base58.js" async></script> <!--removeIf(android)--> diff --git a/www/js/app.js b/www/js/app.js index d44f34880c66be6fdc546beea5a5e05930f2c28e..1a96524e005eb43a74d76869e5a61218c3b6fccc 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -4,7 +4,7 @@ // 'starter' is the name of this angular module example (also set in a <body> attribute in index.html) // the 2nd parameter is an array of 'requires' // 'starter.controllers' is found in controllers.js -angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht.translate', 'xdLocalStorage', +angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht.translate', 'ngApi', 'angular-cache', 'angular.screenmatch', 'angular.bind.notifier','ImageCropper', 'ngFileSaver', // removeIf(no-device) 'ngCordova', @@ -302,7 +302,7 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht $ionicConfigProvider.views.maxCache(5); }) -.run(function($rootScope, $translate, $state, $window, xdLocalStorage, ionicReady, Device, UIUtils, $ionicConfig, PluginService, csWallet, csSettings, csConfig) { +.run(function($rootScope, $translate, $state, $window, ionicReady, Device, UIUtils, $ionicConfig, PluginService, csWallet, csSettings, csConfig) { 'ngInject'; $rootScope.config = csConfig; diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js index bdd69af89d5a316f6b3b0031498fefc48a9265af..7b7c1007971dccaded5c89321842b25ad0927901 100644 --- a/www/js/services/bma-services.js +++ b/www/js/services/bma-services.js @@ -41,12 +41,11 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi regexp: regexp }, listeners, - that = this, - startPromise, - started = false; + that = this; that.date = {now: csHttp.date.now}; that.api = new Api(this, 'BMA-' + that.server); + that.started = false; that.init = init; if (host) { @@ -54,6 +53,7 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi } function init(host, port, useSsl, useCache) { + if (that.started) that.stop(); that.alive = false; that.cache = _emptyCache(); @@ -108,8 +108,10 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi var getRequest = function(params) { - if (!started) { - console.debug('[BMA] get waiting start finished...'); + if (!that.started) { + if (!that._startPromise) { + console.error('[BMA] Trying to get [{0}] before start()...'.format(path)); + } return that.ready().then(function() { return getRequest(params); }); @@ -133,8 +135,10 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi post = function(path) { postRequest = function(obj, params) { - if (!started) { - console.debug('[BMA] post waiting start finished...'); + if (!that.started) { + if (!that._startPromise) { + console.error('[BMA] Trying to post [{0}] before start()...'.format(path)); + } return that.ready().then(function() { return postRequest(obj, params); }); @@ -202,16 +206,17 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi } that.isStarted = function() { - return started; + return that.started; }; that.ready = function() { - if (started) return $q.when(); - return startPromise || that.start(); + if (that.started) return $q.when(); + return that._startPromise || that.start(); }; that.start = function() { - if (startPromise) return startPromise; + if (that._startPromise) return that._startPromise; + if (that.started) return $q.when(that.alive); if (!that.host) { return csSettings.ready() @@ -228,17 +233,17 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi console.debug('[BMA] Starting [{0}]...'.format(that.server)); var now = new Date().getTime(); - startPromise = $q.all([ + that._startPromise = $q.all([ csSettings.ready, that.isAlive() ]) - .then(function(alive) { - that.alive = alive; - if (!alive) { + .then(function(res) { + that.alive = res[1]; + if (!that.alive) { // TODO : alert user ? console.error('[BMA] Could not start [{0}]: node unreachable'.format(that.server)); - started = true; - startPromise = null; + that.started = true; + delete that._startPromise; return false; } @@ -249,18 +254,19 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi console.debug('[BMA] Started in '+(new Date().getTime()-now)+'ms'); that.api.node.raise.start(); - started = true; - startPromise = null; + that.started = true; + delete that._startPromise; return true; }); - return startPromise; + return that._startPromise; }; that.stop = function() { console.debug('[BMA] Stopping...'); - that.alive = false; removeListeners(); that.cleanCache(); + that.alive = false; + that.started = false; that.api.node.raise.stop(); }; @@ -633,9 +639,7 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi }; // default action - Device.ready().then(function() { - return service.start(); - }); + service.start(); return service; }) diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js index 7f632d5a8c0c3f12110e2ab72ea42a46abdd7929..dd9d53d0671ab2f589db01637f012617d5e9e2f4 100644 --- a/www/js/services/settings-services.js +++ b/www/js/services/settings-services.js @@ -89,8 +89,6 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi } }, csConfig), - - data = {}, previousData, started = false, @@ -271,7 +269,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi api.registerEvent('locale', 'changed'); // Apply default settings. This is required on some browser (web or mobile - see #361) - //applyData(defaultSettings); + applyData(defaultSettings); // Default action start(); diff --git a/www/js/services/storage-services.js b/www/js/services/storage-services.js index 5451b6476c19aae85f37208b1b356b712855e565..a5d876e246a0cf704cbbca73092773ee7963d10b 100644 --- a/www/js/services/storage-services.js +++ b/www/js/services/storage-services.js @@ -1,278 +1,177 @@ -angular.module('cesium.storage.services', ['ngResource', 'ngResource', 'xdLocalStorage', 'ngApi', 'cesium.config']) - -.factory('localStorage', function($window, $q, $rootScope, $timeout, ionicReady, csConfig, Api, xdLocalStorage) { - 'ngInject'; - - var - appName = "Cesium", - api = new Api(this, "localStorage"), - started = false, - startPromise, - tryInitSecureStorage = true, // default for device (override later) - exports = { - api: api, - useHttpsFrame: false, - standard: { - storage: null - }, - xd: { - enable: false - }, - secure: { - storage: null - } - }; - - // removeIf(device) - // Use this workaround to avoid the use of Device service (could cause a circular reference) - tryInitSecureStorage = false; - // endRemoveIf(device) +angular.module('cesium.storage.services', ['ngResource', 'ngResource', 'ngApi', 'cesium.config']) + + .factory('localStorage', function($window, $q, $rootScope, $timeout, ionicReady, csConfig, Api) { + 'ngInject'; + + var + appName = "Cesium", + api = new Api(this, "localStorage"), + started = false, + startPromise, + isDevice = true, // default for device (override later) + exports = { + api: api, + useHttpsFrame: false, + standard: { + storage: null + }, + secure: { + storage: null + } + }; - /* -- Use standard browser implementation -- */ + // removeIf(device) + // Use this workaround to avoid to wait ionicReady() event + isDevice = false; + // endRemoveIf(device) - exports.standard.put = function(key, value) { - exports.standard.storage[key] = value; - return $q.when(); - }; + /* -- Use standard browser implementation -- */ - exports.standard.get = function(key, defaultValue) { - return $q.when(exports.standard.storage[key] || defaultValue); - }; + exports.standard.put = function(key, value) { + exports.standard.storage[key] = value; + return $q.when(); + }; - exports.standard.setObject = function(key, value) { - exports.standard.storage[key] = JSON.stringify(value); - return $q.when(); - }; + exports.standard.get = function(key, defaultValue) { + return $q.when(exports.standard.storage[key] || defaultValue); + }; - exports.standard.getObject = function(key) { - return $q.when(JSON.parse(exports.standard.storage[key] || '{}')); - }; + exports.standard.setObject = function(key, value) { + exports.standard.storage[key] = JSON.stringify(value); + return $q.when(); + }; + exports.standard.getObject = function(key) { + return $q.when(JSON.parse(exports.standard.storage[key] || '{}')); + }; - /* -- Use of cross-domain HTTPS iframe -- */ - // See https://github.com/ofirdagan/cross-domain-local-storage + /* -- Use secure storage (using a cordova plugin) -- */ - exports.xd.put = function(key, value) { - if (!started) { - console.debug('[storage] Waiting start finished...'); - return startPromise.then(function(){ - return exports.xd.put(key, value); - }); - } + // Set a value to the secure storage (or remove if value is not defined) + exports.secure.put = function(key, value) { + var deferred = $q.defer(); + if (angular.isDefined(value)) { + exports.secure.storage.set( + function (key) { deferred.resolve(); }, + function (err) { deferred.reject(err); }, + key, value); + } + // Remove + else { + exports.secure.storage.remove( + function (key) { deferred.resolve(); }, + function (err) { deferred.reject(err); }, + key); + } + return deferred.promise; + }; - xdLocalStorage.setItem(key, value); - }; + // Get a value from the secure storage + exports.secure.get = function(key, defaultValue) { + var deferred = $q.defer(); + exports.secure.storage.get( + function (value) { + if (!value && defaultValue) { + deferred.resolve(defaultValue); + } + else { + deferred.resolve(value); + } + }, + function (err) { deferred.reject(err); }, + key); + return deferred.promise; + }; - exports.xd.get = function(key, defaultValue) { - if (!started) { - console.debug('[storage] Waiting start finished...'); - return startPromise.then(function(){ - return exports.xd.get(key, defaultValue); - }); - } + // Set a object to the secure storage + exports.secure.setObject = function(key, value) { + return exports.secure.set(key, JSON.stringify(value)); + }; - return xdLocalStorage.getItem(key).then(function(response){ - return (response && response.value) || defaultValue; - }); - }; + // Get a object from the secure storage + exports.secure.getObject = function(key) { + return exports.secure.get(key) + .then(function(value) { + return (value && JSON.parse(value)) || {}; + }); + }; - exports.xd.setObject = function(key, value) { - if (!started) { - console.debug('[storage] Waiting start finished...'); - return startPromise.then(function(){ - return exports.xd.setObject(key, value); + function initStandardStorage() { + console.debug('[storage] Starting [standard mode]...'); + exports.standard.storage = $window.localStorage; + // Set standard storage as default + _.forEach(_.keys(exports.standard), function(key) { + exports[key] = exports.standard[key]; }); - } - if (!value) { - return xdLocalStorage.removeItem(key); + return $q.when(); } - return xdLocalStorage.setItem(key, JSON.stringify(value)); - }; - exports.xd.getObject = function(key, defaultObject) { - if (!started) { - console.debug('[storage] Waiting start finished...'); - return startPromise.then(function(){ - return exports.xd.getObject(key, defaultObject); + function initSecureStorage() { + console.debug('[storage] Starting [secure mode]...'); + // Set secure storage as default + _.forEach(_.keys(exports.secure), function(key) { + exports[key] = exports.secure[key]; }); - } - - return xdLocalStorage.getItem(key).then(function(response){ - return response && response.value && JSON.parse(response.value) || defaultObject; - }); - }; - /* -- Use secure storage (using a cordova plugin) -- */ + var deferred = $q.defer(); - // Set a value to the secure storage (or remove if value is not defined) - exports.secure.put = function(key, value) { - var deferred = $q.defer(); - if (angular.isDefined(value)) { - exports.secure.storage.set( - function (key) { deferred.resolve(); }, - function (err) { deferred.reject(err); }, - key, value); - } - // Remove - else { - exports.secure.storage.remove( - function (key) { deferred.resolve(); }, - function (err) { deferred.reject(err); }, - key); - } - return deferred.promise; - }; - - // Get a value from the secure storage - exports.secure.get = function(key, defaultValue) { - var deferred = $q.defer(); - exports.secure.storage.get( - function (value) { - if (!value && defaultValue) { - deferred.resolve(defaultValue); - } - else { - deferred.resolve(value); + ionicReady().then(function() { + // No secure storage plugin: fall back to standard storage + if (!cordova.plugins || !cordova.plugins.SecureStorage) { + console.debug('[storage] No cordova plugin. Will use standard....'); + deferred.resolve(initStandardStorage()); + return; } - }, - function (err) { deferred.reject(err); }, - key); - return deferred.promise; - }; - - // Set a object to the secure storage - exports.secure.setObject = function(key, value) { - return exports.secure.set(key, JSON.stringify(value)); - }; - - // Get a object from the secure storage - exports.secure.getObject = function(key) { - return exports.secure.get(key) - .then(function(value) { - return (value && JSON.parse(value)) || {}; + exports.secure.storage = new cordova.plugins.SecureStorage( + function () { + deferred.resolve(); + }, + function (err) { + console.error('[storage] Could not use secure storage. Will use standard.', err); + deferred.resolve(initStandardStorage()); + }, + appName); }); - }; - - function initStandardStorage() { - console.debug('[storage] Starting [standard mode]...'); - exports.standard.storage = $window.localStorage; - // Set standard storage as default - _.forEach(_.keys(exports.standard), function(key) { - exports[key] = exports.standard[key]; - }); - return $q.when(); - } + return deferred.promise; + } - function initXdStorage() { - // Compute the HTTPS iframe url - var href = $window.location.href; - var hashIndex = href.indexOf('#'); - var rootPath = (hashIndex != -1) ? href.substr(0, hashIndex) : href; - var iframeUrl = 'https' + rootPath.substr(4); - if (iframeUrl.charAt(iframeUrl.length-1) != '/') iframeUrl += '/'; // end slash - iframeUrl += 'https-storage.html'; + exports.isStarted = function() { + return started; + }; - console.debug('[storage] Starting [cross-domain mode] using iframe [{0}]'.format(iframeUrl)); + exports.ready = function() { + if (started) return $q.when(); + return startPromise || start(); + }; - // Set cross-domain storage as default - _.forEach(_.keys(exports.xd), function(key) { - exports[key] = exports.xd[key]; - }); + function start() { + if (startPromise) return startPromise; - var isOK = false; - var deferred = $q.defer(); + var now = new Date().getTime(); - // Timeout, in case the frame could not be loaded - $timeout(function() { - if (!isOK) { - // TODO: alert user ? - console.error('[storage] https frame not loaded (timeout). Trying standard mode...'); - deferred.resolve(initStandardStorage()); + // Use Cordova secure storage plugin + if (isDevice) { + startPromise = initSecureStorage(); } - }, csConfig.timeout); - - xdLocalStorage.init({iframeUrl: iframeUrl}) - .then(function() { - isOK = true; - deferred.resolve(); - }) - .catch(function(err) { - console.error('[storage] Could not init cross-domain storage. Trying standard mode...', err); - deferred.resolve(initStandardStorage()); - }); - return deferred.promise; - } - - function initSecureStorage() { - console.debug('[storage] Starting [secure mode]...'); - // Set secure storage as default - _.forEach(_.keys(exports.secure), function(key) { - exports[key] = exports.secure[key]; - }); - - var deferred = $q.defer(); - ionicReady().then(function() { - if (!cordova.plugins || !cordova.plugins.SecureStorage) { - deferred.resolve(initStandardStorage()); - return; + // Use default browser local storage + else { + startPromise = initStandardStorage(); } - exports.secure.storage = new cordova.plugins.SecureStorage( - function () { - deferred.resolve(); - }, - function (err) { - console.error('[storage] Could not use secure storage. Will use standard.', err); - deferred.resolve(initStandardStorage()); - }, - appName); - }); - - return deferred.promise; - } - - exports.isStarted = function() { - return started; - }; - - exports.ready = function() { - if (started) return $q.when(); - return startPromise || start(); - }; - - function start() { - if (startPromise) return startPromise; - var now = new Date().getTime(); - - // Is site on both HTTPS and HTTP: Need to use cross-domain storage - if (csConfig.httpsMode === 'clever' && $window.location.protocol !== 'https:') { - startPromise = initXdStorage(); - } - - // Use Cordova secure storage plugin - else if (tryInitSecureStorage) { - startPromise = initSecureStorage(); + return startPromise + .then(function() { + console.debug('[storage] Started in ' + (new Date().getTime() - now) + 'ms'); + started = true; + startPromise = null; + }); } - // Use default browser local storage - else { - startPromise = initStandardStorage(); - } - - return startPromise - .then(function() { - console.debug('[storage] Started in ' + (new Date().getTime() - now) + 'ms'); - started = true; - startPromise = null; - }); - } - - // default action - start(); + // default action + start(); - return exports; -}) + return exports; + }) ; diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index 28900f88bf3352c09db8eeb23d55444661320c27..b953fca13315d66f035aeed5fa7edecea0400d4c 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -4,7 +4,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser .factory('csWallet', function($q, $rootScope, $timeout, $translate, $filter, Api, localStorage, - CryptoUtils, BMA, csConfig, csSettings, FileSaver, Blob, csWot) { + CryptoUtils, BMA, csConfig, csSettings, FileSaver, Blob, csWot, Device) { 'ngInject'; factory = function(id) { @@ -221,14 +221,16 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser if (csSettings.data.useLocalStorage) { if (isLogin() && csSettings.data.rememberMe) { - var dataToStore = { - pubkey: data.pubkey - }; -/* + // FIXME: #372 + /*var dataToStore = { + pubkey: data.pubkey, + uid: data.uid + };*/ + var dataToStore = { keypair: data.keypair, pubkey: data.pubkey - };*/ + }; if (data.tx && data.tx.pendings && data.tx.pendings.length>0) { var pendings = data.tx.pendings.reduce(function(res, tx){ @@ -262,7 +264,25 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser if (!dataStr) return; return fromJson(dataStr, false) .then(function(storedData){ - if (storedData && storedData.keypair && storedData.pubkey) { + // FIXME: #372 + /*if (storedData && storedData.pubkey) { + data.pubkey = storedData.pubkey; + data.uid = storedData.uid; + data.loaded = false; + + return $q.all([ + // Call extend api + api.data.raisePromise.login(data), + + // Load parameters + // This prevent timeout error, when loading a market record after a browser refresh (e.g. F5) + loadParameters(), + + // Load current UD is need by features tour + loadCurrentUD() + ]); + } + else */if (storedData && storedData.keypair && storedData.pubkey) { data.keypair = storedData.keypair; data.pubkey = storedData.pubkey; if (storedData.tx && storedData.tx.pendings) { @@ -614,24 +634,18 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser }, loadParameters = function() { - return $q(function(resolve, reject) { - if (data.parameters && data.currency) { - resolve(); - return; - } - BMA.blockchain.parameters() + if (data.parameters && data.currency) return $q.when(); + return BMA.blockchain.parameters() .then(function(json){ data.currency = json.currency; data.parameters = json; if (data.currentUD == -1) data.currentUD = data.parameters.ud0; - resolve(); }) .catch(function(err) { data.currency = null; data.parameters = null; - reject(err); + throw err; }); - }); }, loadCurrentUD = function() { @@ -1654,6 +1668,13 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser failIfInvalid = angular.isUndefined(failIfInvalid) ? true : failIfInvalid; return $q(function(resolve, reject) { var obj = JSON.parse(json || '{}'); + // FIXME #379 + /*if (obj && obj.pubkey) { + resolve({ + pubkey: obj.pubkey + }); + } + else */ if (obj && obj.keypair && obj.keypair.signPk && obj.keypair.signSk) { var keypair = {}; var i; @@ -1750,8 +1771,9 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser }; var service = factory('default'); + service.instance = factory; - // try to restore wallet + // Default action: restore wallet, then store it to rootscope csSettings.api.data.on.ready($rootScope, function() { service.restore() .then(function(data) { @@ -1759,6 +1781,5 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser }); }); - service.instance = factory; return service; });