diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json index 681aabdd04c6d26081c68b65d440ab5af70fc51d..8704a380c1b7e888b2c8fa090272d415d5d1c936 100644 --- a/www/i18n/locale-en-GB.json +++ b/www/i18n/locale-en-GB.json @@ -135,6 +135,9 @@ "PEER_CHANGED_TEMPORARY": "Address used temporarily", "USE_LOCAL_STORAGE": "Enable local storage", "USE_LOCAL_STORAGE_HELP": "Allows you to save your settings", + "WALLETS_SETTINGS": "My wallets", + "USE_WALLETS_ENCRYPTION": "Secure the list", + "USE_WALLETS_ENCRYPTION_HELP": "Enables you to encrypt the list of your wallets. Authentication required to access it.", "ENABLE_HELPTIP": "Enable contextual help tips", "ENABLE_UI_EFFECTS": "Enable visual effects", "HISTORY_SETTINGS": "Account operations", diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index a9cc920ff94e084c9c4942abb81b1f593e9826f3..13310cd1c256c0b9272dca52f7d0e43ae67f8dc0 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -135,6 +135,9 @@ "PEER_CHANGED_TEMPORARY": "Address used temporarily", "USE_LOCAL_STORAGE": "Enable local storage", "USE_LOCAL_STORAGE_HELP": "Allows you to save your settings", + "WALLETS_SETTINGS": "My wallets", + "USE_WALLETS_ENCRYPTION": "Secure the list", + "USE_WALLETS_ENCRYPTION_HELP": "Enables you to encrypt the list of your wallets. Authentication required to access it.", "ENABLE_HELPTIP": "Enable contextual help tips", "ENABLE_UI_EFFECTS": "Enable visual effects", "HISTORY_SETTINGS": "Account operations", diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json index 77dd988a3c6aa76412e6e99e3ecf9c82b15ad1b4..a526546bf25f017b64b5bebde6ccf240638c6bf5 100644 --- a/www/i18n/locale-fr-FR.json +++ b/www/i18n/locale-fr-FR.json @@ -135,11 +135,14 @@ "PEER_CHANGED_TEMPORARY": "Adresse utilisée temporairement", "USE_LOCAL_STORAGE": "Activer le stockage local", "USE_LOCAL_STORAGE_HELP": "Permet de sauvegarder vos paramètres", + "WALLETS_SETTINGS": "Mes portefeuilles", + "USE_WALLETS_ENCRYPTION": "Sécuriser la liste (chiffrement)", + "USE_WALLETS_ENCRYPTION_HELP": "Permet de chiffrer la liste de vos portefeuilles. Authentification requise pour y accéder.", "ENABLE_HELPTIP": "Activer les bulles d'aide contextuelles", "ENABLE_UI_EFFECTS": "Activer les effets visuels", - "HISTORY_SETTINGS": "Liste des opérations", + "HISTORY_SETTINGS": "Mes opérations", "DISPLAY_UD_HISTORY": "Afficher les dividendes produits ?", - "TX_HISTORY_AUTO_REFRESH": "Activer le rafraichissement automatique ?", + "TX_HISTORY_AUTO_REFRESH": "Rafraichir automatiquement", "TX_HISTORY_AUTO_REFRESH_HELP": "Rafraîchi le solde et les opérations automatiquement, à chaque nouveau bloc du réseau.", "AUTHENTICATION_SETTINGS": "Authentification", "KEEP_AUTH": "Expiration de l'authentification", @@ -159,7 +162,7 @@ "PLUGINS_SETTINGS": "Extensions", "BTN_RESET": "Restaurer les valeurs par défaut", "EXPERT_MODE": "Activer le mode expert", - "EXPERT_MODE_HELP": "Permet un affichage plus détaillé", + "EXPERT_MODE_HELP": "Permet un affichage plus détaillé.", "BLOCK_VALIDITY_WINDOW": "Délai d'incertitude des blocs", "BLOCK_VALIDITY_WINDOW_SHORT": "Délai d'incertitude", "BLOCK_VALIDITY_WINDOW_HELP": "Délai avant de considérer qu'une information est validée", diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js index 56f53743ca3f7906865234e8eef6af5bf9cb10b9..163c1d9db39d4d4a7329b2a1775bca79ec608e2f 100644 --- a/www/js/controllers/settings-controllers.js +++ b/www/js/controllers/settings-controllers.js @@ -121,9 +121,9 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti $scope.formData.locale = (csSettings.data.locale && csSettings.data.locale.id && _.findWhere($scope.locales, {id: csSettings.data.locale.id})) || _.findWhere($scope.locales, {id: csSettings.defaultSettings.locale.id}); - $scope.loading = false; - $timeout(function() { + return $timeout(function() { + $scope.loading = false; // Set Ink UIUtils.ink({selector: '.item'}); $scope.showHelpTip(); @@ -284,14 +284,22 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti $scope.saving = true; // Async - to avoid UI lock - $timeout(function() { + return $timeout(function() { // Make sure to format helptip $scope.cleanupHelpTip(); + // Applying csSettings.apply($scope.formData); - csSettings.store(); - $scope.saving = false; - }, 100); + + // Store + return csSettings.store(); + + }, 100) + .then(function() { + //return $timeout(function() { + $scope.saving = false; + //}, 100); + }); }; $scope.onDataChanged = function(oldValue, newValue, scope) { @@ -305,14 +313,24 @@ function SettingsController($scope, $q, $window, $ionicHistory, $ionicPopup, $ti }, 500); } - var updated = !angular.equals(oldValue, newValue); - if (updated) { - //console.debug('Detected settings update: will save it'); + // Changes from the current scope: save changes + if ((scope === $scope) && !angular.equals(oldValue, newValue)) { $scope.save(); } }; $scope.$watch('formData', $scope.onDataChanged, true); + // Detected changes from outside (e.g. enabling encryption on wallet can be rollback if user cancel auth) + csSettings.api.data.on.changed($scope, function(data) { + if ($scope.loading || $scope.saving || $scope.pendingSaving) return; + + var updated = !angular.equals(data.useLocalStorageEncryption, $scope.formData.useLocalStorageEncryption); + if (updated) { + console.debug('[settings] Settings changed (outside the settings page). Reloading...'); + $scope.load(); + } + }); + $scope.getServer = function() { if (!$scope.formData.node || !$scope.formData.node.host) return ''; return csHttp.getServer($scope.formData.node.host, $scope.formData.node.port); diff --git a/www/js/controllers/wallets-controllers.js b/www/js/controllers/wallets-controllers.js index 0c4649196f4d7c989ecdbb36f7a969b5b2dc314b..04cc8f0497bd9f7390904d54f31cb244ac8fafe2 100644 --- a/www/js/controllers/wallets-controllers.js +++ b/www/js/controllers/wallets-controllers.js @@ -71,8 +71,7 @@ angular.module('cesium.wallets.controllers', ['cesium.services', 'cesium.currenc ; function WalletListController($scope, $controller, $state, $timeout, $q, $translate, $ionicPopover, $ionicPopup, - ModalUtils, - UIUtils, Modals, csCurrency, csSettings, csWallet){ + ModalUtils, UIUtils, Modals, csCurrency, csSettings, csWallet){ 'ngInject'; $scope.settings = csSettings.data; @@ -175,7 +174,7 @@ function WalletListController($scope, $controller, $state, $timeout, $q, $transl if (!wallet) return $q.reject("Missing 'wallet' argument"); // Make sure auth on the main wallet - if (!csWallet.isAuth()) { + if (!csWallet.isAuth() && csSettings.data.useLocalStorageEncryption) { return csWallet.auth({minData: true}) .then(function() { return $scope.addNewWallet(wallet); // loop @@ -464,7 +463,7 @@ function WalletListController($scope, $controller, $state, $timeout, $q, $transl // Detect changes in settings useRelative $scope.$watch('settings.useRelative', function(newVal, oldVal) { if (!$scope.formData || $scope.loading || (newVal === oldVal)) return; - $scope.formData.useRelative = $scope.settings.useRelative; + $scope.formData.useRelative = csSettings.data.useRelative; $scope.updateView(); }, true); } diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js index d2dd574d94391c9a1833d1e1bf3f31ee9bbda3f7..84e41195033ec6c6f116fceb35a844204a485cf8 100644 --- a/www/js/services/settings-services.js +++ b/www/js/services/settings-services.js @@ -68,7 +68,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) }, defaultSettings = angular.merge({ useLocalStorage: true, // override to false if no device - useLocalStorageEncryption: true, + useLocalStorageEncryption: false, walletHistoryTimeSecond: 30 * 24 * 60 * 60 /*30 days*/, walletHistorySliceSecond: 5 * 24 * 60 * 60 /*download using 5 days slice*/, walletHistoryAutoRefresh: true, // override to false if device @@ -148,7 +148,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) var hasChanged = previousData && !angular.equals(previousData, data); previousData = angular.copy(data); if (hasChanged) { - api.data.raise.changed(data); + return api.data.raise.changed(data); } }, @@ -192,7 +192,13 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) .then(emitChangedEvent); }, + /** + * Apply new settings (can be partial) + * @param newData + */ applyData = function(newData) { + if (!newData) return; // skip empty + var localeChanged = false; if (newData.locale && newData.locale.id) { // Fix previously stored locale (could use bad format) @@ -200,16 +206,16 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) localeChanged = !data.locale || newData.locale.id !== data.locale.id || newData.locale.id !== $translate.use(); } - // Apply stored settings + // Force some fixed settings, before merging + _.keys(fixedSettings).forEach(function(key) { + newData[key] = defaultSettings[key]; // This will apply fixed value (override by config.js file) + }); + + // Apply new settings angular.merge(data, newData); // Delete temporary properties, if false - if (!newData.node.temporary || !data.node.temporary) delete data.node.temporary; - - // Force some fixed settings - _.keys(fixedSettings).forEach(function(key) { - data[key] = defaultSettings[key]; // This will apply fixed value (override by config.js file) - }); + if (newData && newData.node && !newData.node.temporary || !data.node.temporary) delete data.node.temporary; // Apply the new locale (only if need) // will produce an event cached by onLocaleChange(); diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js index 5a058037662fb25f88b06294fa364a945d4f78e5..bf51522776859778a86f0b335d95b6e93c2aace5 100644 --- a/www/js/services/utils-services.js +++ b/www/js/services/utils-services.js @@ -15,11 +15,12 @@ angular.module('cesium.utils.services', []) }; }) -.factory('UIUtils', function($ionicLoading, $ionicPopup, $ionicConfig, $translate, $q, ionicMaterialInk, ionicMaterialMotion, $window, $timeout, +.factory('UIUtils', function($ionicLoading, $ionicPopup, $ionicConfig, $ionicHistory, $translate, $q, + ionicMaterialInk, ionicMaterialMotion, $window, $timeout, // removeIf(no-device) $cordovaToast, // endRemoveIf(no-device) - $ionicPopover, $state, $rootScope, screenmatch, csSettings) { + $ionicPopover, $state, $rootScope, screenmatch) { 'ngInject'; @@ -692,9 +693,10 @@ angular.module('cesium.utils.services', []) if (exports.motion.enable === enable) return; // same console.debug('[UI] [effects] ' + (enable ? 'Enable' : 'Disable')); + exports.motion.enable = enable; if (enable) { $ionicConfig.views.transition('platform'); - exports.motion = raw.motion; + angular.merge(exports.motion, raw.motion); } else { $ionicConfig.views.transition('none'); @@ -702,7 +704,7 @@ angular.module('cesium.utils.services', []) class: undefined, show: function(){} }; - exports.motion = { + angular.merge(exports.motion, { enable : false, default: nothing, fadeSlideIn: nothing, @@ -714,8 +716,10 @@ angular.module('cesium.utils.services', []) fadeIn: nothing, toggleOn: toggleOn, toggleOff: toggleOff - }; + }); + $rootScope.motion = nothing; } + $ionicHistory.clearCache(); } raw.motion = { @@ -784,10 +788,6 @@ angular.module('cesium.utils.services', []) }, timeout || 900); } - csSettings.api.data.on.changed($rootScope, function(data) { - setEffects(data.uiEffects); - }); - exports = { alert: { error: alertError, diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index 5762f3ce98367c132ce26faccc3567f4d765d021..09408729dde29d7cff7d9325e355e27aacb02f1a 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -468,17 +468,17 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se var content; // Init only if used var secureContent; // Init only if used - // Add readTime - if (data.notifications && data.notifications.readTime) { + // Add time + if (data.notifications && data.notifications.time) { content = content || {}; content.notifications = { - readTime: data.notifications.readTime + time: data.notifications.time }; } - if (data.invitations && data.invitations.readTime) { + if (data.invitations && data.invitations.time) { content = content || {}; content.invitations = { - readTime: data.invitations.readTime + time: data.invitations.time }; } @@ -510,7 +510,9 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se // Encryption is enable, but user not auth: use the session storage // (and keep the local storage value) - if (!isAuth()) return sessionStorage.put(storageKey, contentStr||null); + if (!isAuth()) { + return sessionStorage.put(storageKey, contentStr||null); + } return $q.all([ // Get a unique nonce @@ -1924,16 +1926,6 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se if (isAuth()) unauth(); }, this); listeners.push(listener); - - // Delegate start() to the parent wallet - /*exports.start = function() { - if (started) return $q.when(); - return parentWallet.start() - .then(function() { - started = true; - startPromise=null; - }); - };*/ }, createNewChildWallet = function(options) { @@ -2181,27 +2173,49 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se function onSettingsChanged(allSettings) { var newSettings = getWalletSettings(allSettings); var hasChanged = !angular.equals(settings, newSettings); - if (hasChanged) { - var useStorageChanged = !angular.equals(settings.useLocalStorage, newSettings.useLocalStorage) || - !angular.equals(settings.useLocalStorageEncryption, newSettings.useLocalStorageEncryption); - var keepAuthIdleChanged = !angular.equals(settings.keepAuthIdle, newSettings.keepAuthIdle); + if (!hasChanged) return; // skip + + var useEncryptionChanged = !angular.equals(settings.useLocalStorageEncryption, newSettings.useLocalStorageEncryption); + var useStorageChanged = !angular.equals(settings.useLocalStorage, newSettings.useLocalStorage) || useEncryptionChanged; + var keepAuthIdleChanged = !angular.equals(settings.keepAuthIdle, newSettings.keepAuthIdle); - settings = newSettings; + settings = newSettings; - if (keepAuthIdleChanged) { - checkAuthIdle(); + if (keepAuthIdleChanged) { + checkAuthIdle(); + } + + // Local storage option changed + if (useStorageChanged) { + + // If disabled, then reset the store + if (!settings.useLocalStorage) { + resetStore(data.pubkey); } + // If storage enable + else { + // Store login data + return store() + .then(function() { - if (useStorageChanged) { - // Reset stored data - if (!settings.useLocalStorage) { - resetStore(data.pubkey); - } - else { - // Or stored login data - store(); - storeData(); - } + // Encryption enable: auth before saving data + if (data.childrenCount > 0 && useEncryptionChanged && settings.useLocalStorageEncryption) { + return auth({minData: true, silent: true}) + .catch(function(err){ + // user not auth: revert encryption to false + if (err == 'CANCELLED') { + csSettings.apply({useLocalStorageEncryption: false}); + return csSettings.store(); + } + else { + throw err; + } + }); + } + }) + + // Store other data (children wallet, ...) + .then(storeData); } } } diff --git a/www/plugins/es/js/services/notification-services.js b/www/plugins/es/js/services/notification-services.js index d7faaaed3972b22767ecb0b07ad95fa9f7b83db4..630c0dcf29372b2c16a6c8930f04afa02bf839a2 100644 --- a/www/plugins/es/js/services/notification-services.js +++ b/www/plugins/es/js/services/notification-services.js @@ -350,7 +350,7 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es // Load unread notifications count loadUnreadNotificationsCount( data.pubkey, { - readTime: data.notifications && data.notifications.readTime || 0, + readTime: data.notifications && data.notifications.time || 0, excludeCodes: constants.EXCLUDED_CODES }) .then(function(unreadCount) { @@ -365,7 +365,7 @@ angular.module('cesium.es.notification.services', ['cesium.platform', 'cesium.es message: 'COMMON.NOTIFICATION.HAS_UNREAD', count: unreadCount, state: 'app.view_notifications' - }, data.ui || data.name || data.pubkey.substr(0,8)); + }, data.ui || data.name || data.pubkey && data.pubkey.substr(0,8)); }, 500); } diff --git a/www/plugins/es/js/services/social-services.js b/www/plugins/es/js/services/social-services.js index 37305a2d62ef2c2adc1acb720b669d0295c9c270..ee9ad619df470eaf45da042706f94bc150cbfbd2 100644 --- a/www/plugins/es/js/services/social-services.js +++ b/www/plugins/es/js/services/social-services.js @@ -52,7 +52,7 @@ angular.module('cesium.es.social.services', ['cesium.es.crypto.services']) urlToMatch = url.substring(0, slashPathIndex); } } - //console.log("match URI, try to match: " + urlToMatch); + //console.debug("match URI, try to match: " + urlToMatch); _.keys(regexp.socials).forEach(function(key){ if (regexp.socials[key].test(urlToMatch)) { type = key; diff --git a/www/templates/settings/settings.html b/www/templates/settings/settings.html index 5a0ba402e4face69c8a55e235a78fa5568d5348b..226af7bfbe2c6dd22e7c62425d216adb8be28b86 100644 --- a/www/templates/settings/settings.html +++ b/www/templates/settings/settings.html @@ -74,16 +74,17 @@ </label> </div> - <!-- <div class="item item-toggle dark item-text-wrap"> + <!--div class="item item-toggle dark item-text-wrap"> <div class="input-label" ng-bind-html="'SETTINGS.ENABLE_UI_EFFECTS' | translate"> </div> <label class="toggle toggle-royal"> - <input type="checkbox" ng-model="formData.enableUuiEffects" > + <input type="checkbox" ng-model="formData.uiEffects" > <div class="track"> <div class="handle"></div> </div> </label> - </div>--> + </div--> + <!-- Allow extension here --> <cs-extension-point name="common"></cs-extension-point> @@ -127,6 +128,22 @@ <div class="item-note dark">{{formData.keyringFile}}</div> </div> + <span class="item item-divider"> + {{'SETTINGS.WALLETS_SETTINGS' | translate}} + </span> + + <div class="item item-toggle item-text-wrap dark"> + <span class="input-label" ng-class="{'gray': !formData.useLocalStorage}" translate>SETTINGS.USE_WALLETS_ENCRYPTION</span> + <h4 class="gray" ng-bind-html="'SETTINGS.USE_WALLETS_ENCRYPTION_HELP' | translate"> + </h4> + <label class="toggle toggle-royal"> + <input type="checkbox" ng-model="formData.useLocalStorageEncryption" ng-disabled="!formData.useLocalStorage"> + <div class="track"> + <div class="handle"></div> + </div> + </label> + </div> + <span class="item item-divider" translate>SETTINGS.HISTORY_SETTINGS</span> <div class="item item-toggle dark">