Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 17 additions & 23 deletions src/browser/SecureStorageProxy.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
cordova.define("airgap-secure-storage.SecureStorageProxy", function(require, exports, module) {
cordova.define("airgap-secure-storage.SecureStorageProxy", function(require, exports, module) {


/**
* Warn users about unsecure implementation of browser platform
* @param {*} handler
* @param {*} handler
*/
const warn = function (handler) {
console.warn('Browser storage is not securely implemented in airgap-secure-storage. Only use for testing / debugging!')
Expand All @@ -12,60 +12,54 @@ cordova.define("airgap-secure-storage.SecureStorageProxy", function(require, exp

/**
* Gets a specific key from localStorage
* @param {*} key
* @param {*} key
*/
const getItem = function (success, error, args) {
const getItem = function (args) {
const alias = args[0]
const isParanoia = args[1]
const key = args[2]

try {
const value = JSON.parse(localStorage.getValue(alias + '_' + key))
success(value)
return Promise.resolve(JSON.parse(localStorage.getValue(alias + '_' + key)))
} catch (error) {
error(error)
return Promise.reject(error)
}
}

/**
* Sets a specific value for a given key in localStorage
* @param {*} key
* @param {*} value
* @param {*} key
* @param {*} value
*/
const setItem = function (success, error, args) {
const setItem = function (args) {
const alias = args[0]
const isParanoia = args[1]
const key = args[2]
const value = args[3]

try {
localStorage.setItem(alias + '_' + key, value)
getItem(success, error, [alias, isParanoia, key])
return Promise.resolve()
} catch (error) {
error(error)
return Promise.reject(error)
}
}

const initialize = function (success, error) {
const initialize = function () {
console.log('initialize is done!')
return Promise.resolve()
}

const removeAll = function (success, error) {
localStorage.clear()
success()
}

const destroy = function (success, error) {
const removeAll = function () {
localStorage.clear()
success()
return Promise.resolve()
}

module.exports = {
initialize: warn(unlock),
initialize: warn(initialize),
getItem: warn(getItem),
setItem: warn(setItem),
removeAll: warn(removeAll),
destroy: warn(destroy)
destroy: warn(removeAll)
};

require('cordova/exec/proxy').add('SecureStorage', module.exports)
Expand Down
153 changes: 58 additions & 95 deletions www/securestorage.js
Original file line number Diff line number Diff line change
@@ -1,137 +1,100 @@
var exec = require('cordova/exec');
var cordova = require('cordova');

const execSecureStorage = (methodName, args) =>
new Promise((resolve, reject) =>
exec(resolve, reject, 'SecureStorage', methodName, args));

/**
*
* @param {*} alias
* @param {*} isParanoia
*
* @param {*} alias
* @param {*} isParanoia
* - requires passcode (PBKDF) and is encrypted with secured hardware key (secure enclave or KeyStore)
* - requires biometrics (touch id or face id) and is encrypted with secured hardware key (secure enclave or KeyStore)
* - requires biometrics (touch id or face id) and passcode (PBKDF) is encrypted with secured hardware key (secure enclave or KeyStore)
*/
function SecureStorage (alias, isParanoia) {
this.alias = alias
this.isParanoia = isParanoia === true ? true : false
this.isInitiated = false;
function SecureStorage(alias, isParanoia) {
this.alias = alias;
this.isParanoia = isParanoia === true;
this.isInitiated = false;
}

/**
*
* @param {*} successCallback
* @param {*} errorCallback
*
*/
SecureStorage.prototype.isDeviceSecure = function (successCallback, errorCallback) {
exec(successCallback, errorCallback, "SecureStorage", "isDeviceSecure", []);
}
SecureStorage.prototype.isDeviceSecure = () => execSecureStorage('isDeviceSecure');

/**
*
* @param {*} successCallback
* @param {*} errorCallback
*
*/
SecureStorage.prototype.secureDevice = function (successCallback, errorCallback) {
exec(successCallback, errorCallback, "SecureStorage", "secureDevice", []);
}
SecureStorage.prototype.secureDevice = () => execSecureStorage('secureDevice');

/**
*
* @param {*} successCallback
* @param {*} errorCallback
*
*/
SecureStorage.prototype.isParanoia = function (successCallback, errorCallback) {
return this.isParanoia
}
SecureStorage.prototype.init = function () {
return execSecureStorage('initialize', [this.alias, this.isParanoia])
.then(() => this.isParanoia && cordova.platformId === 'android' && this.setupParanoiaPassword())
.then(() => this.isInitiated = true)
};

/**
*
* @param {*} successCallback
* @param {*} errorCallback
/**
*
*/
SecureStorage.prototype.init = function (successCallback, errorCallback) {
exec(() => {
if (this.isParanoia && cordova.platformId === 'android') {
this.setupParanoiaPassword(() => {
this.isInitiated = true
successCallback()
}, errorCallback)
} else {
this.isInitiated = true
successCallback()
}
}, errorCallback, "SecureStorage", "initialize", [this.alias, this.isParanoia]);
}
SecureStorage.prototype.setupParanoiaPassword = function () {
return execSecureStorage('setupParanoiaPassword', [this.alias, this.isParanoia])
.then(() => this.isInitiated = true);
};

/**
*
* @param {*} successCallback
* @param {*} errorCallback
*
*/
SecureStorage.prototype.setupParanoiaPassword = function (successCallback, errorCallback) {
this.isInitiated = true;
exec(successCallback, errorCallback, "SecureStorage", "setupParanoiaPassword", [this.alias, this.isParanoia]);
}
SecureStorage.prototype.destroy = () => execSecureStorage('destroy');

/**
*
* @param {*} successCallback
* @param {*} errorCallback
*
*/
SecureStorage.prototype.destroy = function (successCallback, errorCallback) {
exec(successCallback, errorCallback, "SecureStorage", "destroy");
SecureStorage.prototype.ensureInitialized = function () {
if (!this.isInitiated) {
throw new Error('call initialize() first.');
}
}

/**
*
*
* @param {*} key
* @param {*} item
* @param {*} successCallback
* @param {*} errorCallback
* @param {*} item
*/
SecureStorage.prototype.setItem = function (key, item, successCallback, errorCallback) {
if (!this.isInitiated) {
return errorCallback("call initialize() first.")
}
exec(successCallback, errorCallback, "SecureStorage", "setItem", [this.alias, this.isParanoia, key, item]);
}
SecureStorage.prototype.setItem = function (key, item) {
this.ensureInitialized()
return execSecureStorage('setItem', [this.alias, this.isParanoia, key, item]);
};

/**
*
* @param {*} key
* @param {*} successCallback
* @param {*} errorCallback
*
* @param {*} key
*/
SecureStorage.prototype.getItem = function (key, successCallback, errorCallback) {
if (!this.isInitiated) {
return errorCallback("call initialize() first.")
}
exec(successCallback, errorCallback, "SecureStorage", "getItem", [this.alias, this.isParanoia, key]);
}
SecureStorage.prototype.getItem = function (key) {
this.ensureInitialized()
return execSecureStorage('getItem', [this.alias, this.isParanoia, key]);
};

/**
*
* @param {*} key
* @param {*} successCallback
* @param {*} errorCallback
*
* @param {*} key
*/
SecureStorage.prototype.removeItem = function (key, successCallback, errorCallback) {
if (!this.isInitiated) {
return errorCallback("call initialize() first.")
}
exec(successCallback, errorCallback, "SecureStorage", "removeItem", [this.alias, this.isParanoia, key]);
}
SecureStorage.prototype.removeItem = function (key) {
this.ensureInitialized()
return execSecureStorage('removeItem', [this.alias, this.isParanoia, key]);
};

/**
*
* @param {*} key
* @param {*} successCallback
* @param {*} errorCallback
*
* @param {*} key
*/
SecureStorage.prototype.removeAll = function (successCallback, errorCallback) {
if (!this.isInitiated) {
return errorCallback("call initialize() first.")
}
exec(successCallback, errorCallback, "SecureStorage", "removeAll", [this.alias]);
}

SecureStorage.prototype.removeAll = function () {
this.ensureInitialized()
return execSecureStorage('removeAll', [this.alias]);
};

module.exports = SecureStorage;