diff --git a/app-template/config-template.xml b/app-template/config-template.xml
index 8031c8110..39b67d212 100644
--- a/app-template/config-template.xml
+++ b/app-template/config-template.xml
@@ -72,6 +72,8 @@
+
+
diff --git a/src/js/services/desktopSecureStorageService.js b/src/js/services/desktopSecureStorageService.js
new file mode 100644
index 000000000..6e148da2c
--- /dev/null
+++ b/src/js/services/desktopSecureStorageService.js
@@ -0,0 +1,6 @@
+'use strict';
+
+angular.module('copayApp.services').factory('desktopSecureStorageService', function($log) {
+ // Placeholder
+ return {};
+});
\ No newline at end of file
diff --git a/src/js/services/mobileSecureStorageService.js b/src/js/services/mobileSecureStorageService.js
new file mode 100644
index 000000000..f9994fdf8
--- /dev/null
+++ b/src/js/services/mobileSecureStorageService.js
@@ -0,0 +1,88 @@
+'use strict';
+
+angular.module('copayApp.services').factory('mobileSecureStorageService', function($log, appConfigService, platformInfo) {
+ var root = {};
+
+ var isReady = false;
+ var initialisationFailed = false;
+ var pending = [];
+
+ var storage = null;
+
+ if (platformInfo.isCordova) {
+ storage = new cordova.plugins.SecureStorage(
+ function () {
+ isReady = true;
+ for (var i = 0; i < pending.length; i++) {
+ pending[i]();
+ }
+ pending = [];
+ },
+ function (error) {
+ initialisationFailed = true;
+ },
+ appConfigService.packageNameId);
+ }
+
+ root.get = function(key, cb) {
+
+ if (!platformInfo.isMobile) {
+ cb(new Error('mobileSecureStorageService is only available on mobile.'));
+ return;
+ }
+
+ if (!isReady) {
+ if (initialisationFailed) {
+ cb(new Error('mobileSecureStorageService initialisation failed.'));
+ } else {
+ pending.push(function(){ root.get(key, cb); });
+ }
+ return;
+ }
+
+ storage.get(
+ function (value) {
+ cb(null, value);
+ },
+ function (error) {
+ $log.debug('mss get failed. ' + error);
+ if (error.message === 'Failure in SecureStorage.get() - The specified item could not be found in the keychain' || // iOS
+ error.message === 'Key [_SS_profile] not found.') { // Android
+ // The callback expects no error, but also no value, if it cannot be found.
+ cb(null, null);
+ } else {
+ cb(new Error(error));
+ }
+ },
+ key);
+ };
+
+ root.set = function(key, value, cb) {
+
+ if (!platformInfo.isMobile) {
+ cb(new Error('mobileSecureStorageService is only available on mobile.'));
+ }
+
+ if (!isReady) {
+ if (initialisationFailed) {
+ cb(new Error('mobileSecureStorageService initialisation failed.'));
+ } else {
+ pending.push(function(){ root.set(key, value, cb); });
+ }
+ return;
+ }
+
+ storage.set(
+ function (value) {
+ cb();
+ },
+ function (error) {
+ cb(new Error(error));
+ },
+ key, value);
+
+ };
+
+ return root;
+});
+
diff --git a/src/js/services/secureStorageService.js b/src/js/services/secureStorageService.js
new file mode 100644
index 000000000..c066109c2
--- /dev/null
+++ b/src/js/services/secureStorageService.js
@@ -0,0 +1,32 @@
+'use strict';
+
+angular.module('copayApp.services').factory('secureStorageService', function(desktopSecureStorageService, localStorageService, $log, mobileSecureStorageService, platformInfo) {
+ var root = {};
+
+ // To make wrong code look wrong
+ function alteredKeyIndicatingDesireForSecureStorage(key) {
+ return key + ":desiredSecure";
+ }
+
+ root.get = function(k, cb) {
+ if (platformInfo.isMobile) {
+ mobileSecureStorageService.get(k, cb);
+ } else if (platformInfo.isNW) {
+ desktopSecureStorageService.get(k, cb);
+ } else { // Browser
+ localStorageService.get(alteredKeyIndicatingDesireForSecureStorage(k), cb);
+ }
+ }
+
+ root.set = function(k, v, cb) {
+ if (platformInfo.isMobile) {
+ mobileSecureStorageService.set(k, v, cb);
+ } else if (platformInfo.isNW) {
+ desktopSecureStorageService.set(k, v, cb);
+ } else { // Browser
+ localStorageService.set(alteredKeyIndicatingDesireForSecureStorage(k), v, cb);
+ }
+ }
+
+ return root;
+});
\ No newline at end of file
diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js
index 1f46da654..385fd3329 100644
--- a/src/js/services/storageService.js
+++ b/src/js/services/storageService.js
@@ -1,11 +1,9 @@
'use strict';
angular.module('copayApp.services')
- .factory('storageService', function(logHeader, fileStorageService, localStorageService, sjcl, $log, lodash, platformInfo, $timeout, desktopSecureStorageService) {
+ .factory('storageService', function(logHeader, fileStorageService, localStorageService, sjcl, $log, lodash, platformInfo, secureStorageService, $timeout) {
var root = {};
var storage;
- var profileStorage;
- var isNW = platformInfo.isNW;
// File storage is not supported for writing according to
// https://github.com/apache/cordova-plugin-file/#supported-platforms
@@ -19,7 +17,6 @@ angular.module('copayApp.services')
storage = localStorageService;
}
- profileStorage = storage;
/* migration script */
// var migratingProfile = false;
// if (isNW) {
@@ -147,16 +144,16 @@ angular.module('copayApp.services')
};
root.storeNewProfile = function(profile, cb) {
- profileStorage.create('profile', profile.toObj(), cb);
+ secureStorageService.set('profile', profile.toObj(), cb);
};
root.storeProfile = function(profile, cb) {
- profileStorage.set('profile', profile.toObj(), cb);
+ secureStorageService.set('profile', profile.toObj(), cb);
};
root.getProfile = function(cb) {
- // if (!migratingProfile) {
- profileStorage.get('profile', function(err, str) {
+ secureStorageService.get('profile', function(err, str) {
+
if (err || !str)
return cb(err);
@@ -172,16 +169,6 @@ angular.module('copayApp.services')
return cb(err, p);
});
});
- // } else {
- // setTimeout(function() {
- // $log.debug('Wait for a while.. Migrating..');
- // root.getProfile(cb);
- // }, 500);
- // }
- };
-
- root.deleteProfile = function(cb) {
- profileStorage.remove('profile', cb);
};
root.setFeedbackInfo = function(feedbackValues, cb) {