Ensure the privacy of your app with Ionic secure storage by prompting the user to establish a personalized lock

I'm running into an issue while trying to set up the secure storage plugin. If initialization fails, it typically indicates that the user hasn't configured a secure lock screen. Following guidelines from the project's GitHub page, I am attempting to replicate the provided sample code:

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();

Here is my implementation:

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 challenge I am facing is that if the secureStorageApi.create call fails, the secureStorage object will be undefined, making it impossible to execute secureDevice().

I would greatly appreciate any assistance with this matter.

Answer №1

If you're looking to make this work immediately, make the following modification:

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

Functional Code

This is how it should appear after modification:

 // Code block goes here
// More code
// Even more code

Once modified, you can implement the following code snippet:

 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();
                        })
                    } ); 
            } );
    }

Updated Features

The modification involved moving the secureDevice function to a new object named SecureDeviceObject and adjusting the decorators accordingly. This ensures that the object cannot be utilized for get and set functions.

Here is the updated 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;
}());

Furthermore, the decorator was changed as follows:

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

Finally, the reject promise now returns 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);
        });
    };

This may not be the optimal solution but it has shown success on Android versions 4 through 8. Give it a try!

Hopefully, this information proves helpful! Special thanks to @JudgeFudge for guidance in solving the issue.

Answer №2

This particular issue has already been identified and is being tracked, please refer to the following link for more information: https://github.com/ionic-team/ionic-native/issues/1944.

If you are seeking a swift resolution to this problem, consider attempting one of these methods:

1) Consider reverting back to an earlier version of the Ionic SecureStorage plugin as this may resolve the issue.

2) Take on the challenge of troubleshooting the problem yourself by examining the source files located in your node_modules directory at the following paths (I can offer assistance with this if needed later):

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

.

Answer №3

I have submitted a pull request to address this issue.

Below is the code snippet that fixes the bug:

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

To resolve the issue, simply update the reject callback as follows:

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

This change needs to be made within

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

After making the change, run the following commands:

npm install npm run build

Finally, copy the compiled plugin to your project's node_modules folder:

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

The pull request has been merged successfully.

Here is how you can use it:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The electron program is unable to locate the package.json module

I am new to electron and attempting to run an express app for the first time. However, I encountered this error: Need assistance updating code Error: Cannot find module 'C:\package.json' at Module._resolveFilename (module.js:440:15) ...

Error: Attempting to access the `isPaused` property of a null object is not possible

For my Vue front-end app, I'm attempting to integrate wavesurfer.js. However, upon receiving the audio file link from the backend, I encounter the following error: wavesurfer.js?8896:5179 Uncaught (in promise) TypeError: Cannot read property 'isP ...

In the file index.js on line 1, a SyntaxError was encountered due to an unexpected token &

We are currently facing an issue while trying to run the production version of our web application on our IIS server. This app utilizes the minified (production) version of React. While we can successfully run the developer version, we encounter an error w ...

Trouble with VueJS: @change event not triggered when <input> value changes

In my VueJS project, I am working with two separate components: One is a modal and the other is a form. Within the modal component, the user inputs a PIN which is then confirmed. This value is then set to an input tag in the form component to save it. T ...

retrieving identifiers from a separate table for an array of values

As a newcomer to node and noSQL databases, I am facing challenges in grasping the concept of passing an array of IDs and retrieving the corresponding values from another table. I have 'users' and 'products' tables in my database. The st ...

What could be causing the failure of the update for this computed property in my Vue 3 application?

Currently, I am in the process of creating an audio player using Vue 3 and the Napster API. About the Project I have managed to make the vinyl rotate by utilizing a CSS keyframes-based animation paired with the computed property isSpinning. I intend for ...

Mapping nested array of references in Angular Firestore

I am working with a collection called A, which contains documents that reference other documents in collection B. https://i.sstatic.net/C1HtT.png When fetching my A documents from the service, I receive an array of objects that are not usable. However, I ...

Establish the state as the result of a function

I need to update the state of timeToCountdown with the value stored in allTimeInSeconds. Next, I intend to pass this data as a prop to a component. class Timer extends Component { constructor(props){ super(props); this.state = { ...

Error in Typo3 Rendering FieldControl due to insufficient arguments

A plugin has been created for a Typo3 retailer/store database that requires latitude and longitude data for each store. To streamline the process, a button has been added to automatically enter this data through field control in TCA. While this works well ...

Is there a way to connect either of two distinct values in Angular?

Looking to assign the data with two possible values, depending on its existence. For instance, if I have a collection of TVs and I want to save the "name" value of myTVs[0] and myTVs[1]. For example: var myTVs = [ { "JapaneseTV": { ...

How can the Flickr API be utilized with JavaScript functions?

In preparation for a project, we are required to utilize the Flickr API in order to display a collection of photos when a specific category is selected. I have successfully set up my categories on the left side of a flexbox container. However, I am struggl ...

Unable to send State from parent Component to Child (state counter for pomodoro clock)

Hi everyone, I am relatively new to React and currently working on building a Pomodoro Clock. However, I have hit a roadblock while trying to get the buttons + and - to update the numbers set in my State. Here is what I have in my Main App Component: clas ...

Is there a way to update the background image of a div element through a JavaScript file within a react component?

After spending hours on this issue, I am still stuck and have exhausted all my ideas and research. In my project, I have three buttons that are supposed to change the background image of my site. The background image is linked to the default "App" div elem ...

two adjacent elements filling the entire height of the window at 100% dimensions

Is there a way to place two elements side by side, with one of them (the textarea) always being 100% height of the window? I've looked at similar questions here but can't figure out how to make it work. Can you help me with this? html: <div ...

Please define a unique "redirect_uri" in the FB.ui() function for posting purposes

I'm currently utilizing the "Facebook Javascript Sdk" to publish messages on a user's wall. However, I am facing an issue with dynamic redirect URLs. Even though I am explicitly passing the "redirect_uri" as a link with query string in the FB.ui ...

Utilize a bot to scan through an array for specific elements

I'm currently working on a project to create a bot that can extract information from an info.json file and display it in the form of a rich embed within a Discord Channel. One challenge I've encountered is that my JSON file contains multiple arr ...

Tips for stopping variables from leaking in JavaScript

I'm currently working on a JavaScript code for my task manager website. Each page has its own JS file, but I've noticed that the data saved in one file seems to leak over to the others. How can I contain these variables so that tasks don't s ...

Unexpected Typescript error when React component receives props

I encountered an unexpected error saying ": expected." Could it be related to how I'm setting up props for the onChange event? Here is my code for the component: import React from "react"; interface TextFieldProps { label?: string; ...

Attempting to utilize JSON.Stringify on Scripting.Dictionary objects will result in failure

In my current ASP classic project, I have integrated the JScript JSON class available at this link. This class can interact with both VBScript and JScript, closely resembling the code provided on json.org. However, due to team manager's requirement, I ...

Concealing the nearest object

I am currently working on using jquery to hide certain content on a website's index page. Within the fiddle, there is commented out code which I have been experimenting with - however, it hides all content divs if any toggle link is clicked. HTML & ...