最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Ionic secure storage - Ask the user to set a lock screen - Stack Overflow

programmeradmin2浏览0评论

I'm trying to initialize the secure storage plugin. When this fails it means the user does not have a secure lockscreen set. Using the github page i'm trying to recreate the sample provided:

var ss;
var _init = function () {
    ss = new cordova.plugins.SecureStorage(
        function () {
            console.log('OK');
        },
        function () {
            navigator.notification.alert(
                'Please enable the screen lock on your device. This app cannot operate securely without it.',
                function () {
                    ss.secureDevice(
                        function () {
                            _init();
                        },
                        function () {
                            _init();
                        }
                    );
                },
                'Screen lock is disabled'
            );
        },
        'my_app');
};
_init();

This is my attempt:

private createSecureStorage() {
    this.secureStorageAPI.create(this.storeName).then( 
        (storage: SecureStorageObject) => {
            this.secureStorage = storage;
    }).catch( 
        (error) => {
            this.dialogs.alert( 'Please enable the screen lock on your device. This app cannot operate securely without it.').then( 
                () => {
                // Alert Dismissed, should open the secure lockscreen settings here
                  this.secureStorage.secureDevice().then( 
                      () => {
                          // Try again
                          this.createSecureStorage();
                      }
                  ).catch( () => { 
                    // Try again
                    this.createSecureStorage();
                  })
               } )
      } );
  }

The problem i'm having is that when the secureStorageApi.create call fails, secureStorage will be undefined so I can't use it to call call secureDevice().

Any help would be much appreciated.

I'm trying to initialize the secure storage plugin. When this fails it means the user does not have a secure lockscreen set. Using the github page i'm trying to recreate the sample provided:

var ss;
var _init = function () {
    ss = new cordova.plugins.SecureStorage(
        function () {
            console.log('OK');
        },
        function () {
            navigator.notification.alert(
                'Please enable the screen lock on your device. This app cannot operate securely without it.',
                function () {
                    ss.secureDevice(
                        function () {
                            _init();
                        },
                        function () {
                            _init();
                        }
                    );
                },
                'Screen lock is disabled'
            );
        },
        'my_app');
};
_init();

This is my attempt:

private createSecureStorage() {
    this.secureStorageAPI.create(this.storeName).then( 
        (storage: SecureStorageObject) => {
            this.secureStorage = storage;
    }).catch( 
        (error) => {
            this.dialogs.alert( 'Please enable the screen lock on your device. This app cannot operate securely without it.').then( 
                () => {
                // Alert Dismissed, should open the secure lockscreen settings here
                  this.secureStorage.secureDevice().then( 
                      () => {
                          // Try again
                          this.createSecureStorage();
                      }
                  ).catch( () => { 
                    // Try again
                    this.createSecureStorage();
                  })
               } )
      } );
  }

The problem i'm having is that when the secureStorageApi.create call fails, secureStorage will be undefined so I can't use it to call call secureDevice().

Any help would be much appreciated.

Share Improve this question edited Oct 2, 2017 at 6:48 Juxture asked Oct 2, 2017 at 6:29 JuxtureJuxture 2533 silver badges15 bronze badges 1
  • No one able to help with this one? I think this might be a faulty design because you need the SecureStorage object in order to call secureDevice() – Juxture Commented Oct 3, 2017 at 11:17
Add a ment  | 

3 Answers 3

Reset to default 3

For everyone that needs this to work right now modify:

node_modules\@ionic-native\secure-storage\index.js

Working code

It should look like this:

 var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Injectable } from '@angular/core';
import { CordovaInstance, Plugin, CordovaCheck, IonicNativePlugin } from '@ionic-native/core';
/**
 * @hidden
 */
var SecureStorageObject = (function () {
    function SecureStorageObject(_objectInstance) {
        this._objectInstance = _objectInstance;
    }
    /**
     * Gets a stored item
     * @param key {string}
     * @returns {Promise<string>}
     */
    SecureStorageObject.prototype.get = function (key) { return; };
    /**
     * Stores a value
     * @param key {string}
     * @param value {string}
     * @returns {Promise<any>}
     */
    SecureStorageObject.prototype.set = function (key, value) { return; };
    /**
     * Removes a single stored item
     * @param key {string}
     * @returns {Promise<string>} returns a promise that resolves with the key that was removed
     */
    SecureStorageObject.prototype.remove = function (key) { return; };
    /**
     * Get all references from the storage.
     * @returns {Promise<string[]>} returns a promise that resolves with array of keys storage
     */
    SecureStorageObject.prototype.keys = function () { return; };
    /**
     * Clear all references from the storage.
     * @returns {Promise<any>}
     */
    SecureStorageObject.prototype.clear = function () { return; };
    return SecureStorageObject;
}());
/**
 * @hidden
 */
var SecureDeviceObject = (function () {
    function SecureDeviceObject(_objectInstance) {
        this._objectInstance = _objectInstance;
    }

    /**
        * Brings up the screen-lock settings
        * @returns {Promise<any>}
        */
    SecureStorageObject.prototype.secureDevice = function () { return; };
    return SecureDeviceObject;
}());
export { SecureStorageObject, SecureDeviceObject };
__decorate([
    CordovaInstance({
        callbackOrder: 'reverse'
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "get", null);
__decorate([
    CordovaInstance({
        callbackOrder: 'reverse'
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "set", null);
__decorate([
    CordovaInstance({
        callbackOrder: 'reverse'
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "remove", null);
__decorate([
    CordovaInstance({
        callbackOrder: 'reverse'
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "keys", null);
__decorate([
    CordovaInstance({
        callbackOrder: 'reverse'
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "clear", null);
__decorate([
    CordovaInstance(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureDeviceObject.prototype, "secureDevice", null);
/**
 * @name Secure Storage
 * @description
 * This plugin gets, sets and removes key,value pairs from a device's secure storage.
 *
 * Requires Cordova plugin: `cordova-plugin-secure-storage`. For more info, please see the [Cordova Secure Storage docs](https://github./Crypho/cordova-plugin-secure-storage).
 *
 * The browser platform is supported as a mock only. Key/values are stored unencrypted in localStorage.
 *
 * @usage
 *
 * ```typescript
 * import { SecureStorage, SecureStorageObject } from '@ionic-native/secure-storage';
 *
 * constructor(private secureStorage: SecureStorage) { }
 *
 * ...
 *
 * this.secureStorage.create('my_store_name')
 *   .then((storage: SecureStorageObject) => {
 *
 *      storage.get('key')
 *        .then(
 *          data => console.log(data),
 *          error => console.log(error)
 *      );
 *
 *      storage.set('key', 'value')
 *        .then(
 *         data => console.log(data),
 *          error => console.log(error)
 *      );
 *
 *      storage.remove('key')
 *      .then(
 *          data => console.log(data),
 *          error => console.log(error)
 *      );
 *
 *   });
 *
 *
 * ```
 * @classes
 * SecureStorageObject
 */
var SecureStorage = SecureStorage_1 = (function (_super) {
    __extends(SecureStorage, _super);
    function SecureStorage() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * Creates a namespaced storage.
     * @param store {string}
     * @returns {Promise<SecureStorageObject>}
     */
    SecureStorage.prototype.create = function (store) {
        return new Promise(function (res, rej) {
            var instance = new (SecureStorage_1.getPlugin())(
                function () { 
                    res(new SecureStorageObject(instance)); 
                }, 
                function () {
                    rej(new SecureDeviceObject(instance));
                }, 
                store);
        });
    };
    return SecureStorage;
}(IonicNativePlugin));
SecureStorage.decorators = [
    { type: Injectable },
];
/** @nocollapse */
SecureStorage.ctorParameters = function () { return []; };
__decorate([
    CordovaCheck(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecureStorage.prototype, "create", null);
SecureStorage = SecureStorage_1 = __decorate([
    Plugin({
        pluginName: 'SecureStorage',
        plugin: 'cordova-plugin-secure-storage',
        pluginRef: 'cordova.plugins.SecureStorage',
        repo: 'https://github./Crypho/cordova-plugin-secure-storage',
        platforms: ['Android', 'Browser', 'iOS', 'Windows']
    })
], SecureStorage);
export { SecureStorage };
var SecureStorage_1;
//# sourceMappingURL=index.js.map

Then you'll be able to use:

 private createSecureStorage() {
        this.secureStorageAPI.create(this.storeName).then( 
            (storage: SecureStorageObject) => {
                console.log("secure");
                this.secureStorage = storage;
        }).catch( 
            (secureDeviceObject) => {
                this.dialogs.alert( 'Please enable the screen lock on your device. This app cannot operate securely without it.').then( 
                    () => {
                        // Alert Dismissed, should open the secure lockscreen settings here
                        secureDeviceObject.secureDevice().then( 
                        () => {
                            // Try again
                            console.log("Success");
                            this.createSecureStorage();
                        } ).catch( () => { 
                            // Try again
                            console.log(" Error ")
                            this.createSecureStorage();
                        })
                    } ); 
            } );
    }

What has changed?

What i've done is moving the secureDevice function to a new object called SecureDeviceObject and changed the decorators. By doing this you cannot use this object to try to call the get and set functions etc.

This is the new object:

var SecureDeviceObject = (function () {
    function SecureDeviceObject(_objectInstance) {
        this._objectInstance = _objectInstance;
    }

    /**
        * Brings up the screen-lock settings
        * @returns {Promise<any>}
        */
    SecureStorageObject.prototype.secureDevice = function () { return; };
    return SecureDeviceObject;
}());

Then i've changed the decorater:

__decorate([
    CordovaInstance(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureDeviceObject.prototype, "secureDevice", null);

The last change is making the reject promise return the secureDeviceObject:

SecureStorage.prototype.create = function (store) {
        return new Promise(function (res, rej) {
            var instance = new (SecureStorage_1.getPlugin())(
                function () { 
                    res(new SecureStorageObject(instance)); 
                }, 
                function () {
                    rej(new SecureDeviceObject(instance));
                }, 
                store);
        });
    };

I suppose this is not the best possible fix, but it was the best i can do :D Tested on android 4 till 8. Working on all these!

Hope it helps someone :)

Thanks @JudgeFudge for pointing me in the right direction

This problem is already tracked as an issue, see: https://github./ionic-team/ionic-native/issues/1944.

If you need a quick solution for this you can try one of the following steps:

1) Downgrade the Ionic SecureStorage plugin, maybe this issue does not occur in a previous version.

2) Try to fix the problem yourself. You can find the sources in your node_modules folder right here (if you need help with that, I can try to have to look at this later):

node_modules\cordova-plugin-secure-storage\src\android\SecureStorage.java node_modules\cordova-plugin-secure-storage\src\ios\SecureStorage.m

.

Here i sent a pull request that fix this bug.

Here:

create(store: string): Promise<SecureStorageObject> {
    return getPromise<SecureStorageObject>((res: Function, rej: Function) => {
        const instance = new (SecureStorage.getPlugin())(
            () => res(new SecureStorageObject(instance)),
            rej,
            store
        );
    });
}

Simple change the reject callback:

() => rej(new SecureStorageObject(instance)),

Inside ionic-native/src/@ionic-native/plugins/secure-storage/index.ts

then:

npm install npm run build

and at the end copy the plugin piled on you npm_modules folder:

cp -r ionic-native/dist/@ionic-native/plugins/secure-storage/ /your_project/node_modules/@ionic-native/ UPDATE:

They merge the PR.

Here how to use it:

{ this.storage = await this.secureStorage.create('my_storage'); } catch (e) { await e.secureDevice(); }

发布评论

评论列表(0)

  1. 暂无评论