Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abandoned Plugin #57

Open
MatthewPringle opened this issue Sep 26, 2018 · 16 comments
Open

Abandoned Plugin #57

MatthewPringle opened this issue Sep 26, 2018 · 16 comments

Comments

@MatthewPringle
Copy link

This plugin no longer seems to be getting updates.

It has numerous issues that can cause build failures and crashes on both iOS and Android.

The docs are incorrect.

I would recommend not using this plugin as it will only cause you issues.

@vvarda
Copy link

vvarda commented Nov 16, 2018

@MatthewPringle some alternatives..?

@jacobweber
Copy link
Contributor

Does anyone know of an alternative plugin? I need one that supports keychain storage like this one, not just fingerprint authentication.

@MatthewPringle
Copy link
Author

MatthewPringle commented Jan 15, 2019

Removed

@danicholls
Copy link

What about using one or more fingerprint/face auth plugins with https://github.com/Crypho/cordova-plugin-secure-storage ? Looking into it myself (raised an issue about its underlying dependency, but the repo itself seems good).

@mzealey
Copy link

mzealey commented Feb 21, 2019

https://github.com/niklasmerz/cordova-plugin-fingerprint-aio looks good am about to try that in an app

@edubskiy
Copy link

@mzealey , did you try?

@mzealey
Copy link

mzealey commented Mar 27, 2019

Yes works great out of the box.

@edubskiy
Copy link

edubskiy commented Mar 27, 2019

How do you save/retrieve user passwords in keychain using this plugin, it seems to have no option to handle this case, am I wrong? If yes, code sample would be great.

@MatthewPringle
Copy link
Author

@edubskiy I can put up an example of this plugin cordova-plugin-keychain-touch-id working.

It is in Ember though and uses computed values / services so wouldn't be so straight forward. But it does work and has been used in a couple of applications I have used.

@MatthewPringle
Copy link
Author

MatthewPringle commented Mar 27, 2019

/* App - Service - Biometrics /
/
---------------------------------------------------------------------------------------------------- */

/* Import */
import EmberService from '@ember/service';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { isPresent } from '@ember/utils';

/* Export /
/
---------------------------------------------------------------------------------------------------- */
export default EmberService.extend({

/* Setup */
/* ------------------------------------------------------------------------------------------------ */
type: false, saved: false,

/* Services */
/* ------------------------------------------------------------------------------------------------ */
authService:    service( 'authentication' ),
dialogService:  service( 'dialog'         ),
storageService: service( 'storage'        ),

/* Active */
/* ------------------------------------------------------------------------------------------------ */
active: computed( 'type' , 'saved' , function() {
    return this.get( 'type' ) && this.get( 'saved' );
}),

/* Label */
/* ------------------------------------------------------------------------------------------------ */
label: computed( 'type' , function() {
    
    /* Touch ID */
    if ( this.get( 'type' ) === 'touch' ) {
        return 'Touch ID';
        
    /* Face ID */
    } else if ( this.get( 'type' ) === 'face' ) {
        return 'Face ID';
        
    /* Biometric ID */
    } else {
        return 'Biometric ID';
    }

}),

/* Status */
/* ------------------------------------------------------------------------------------------------ */
status: function() {
    
    /* Check Plugin */
    if ( window.cordova !== undefined && window.plugins !== undefined && window.plugins.touchid !== undefined ) {
        
        /* Setup */
        var self = this;
        
        /* Available */
        window.plugins.touchid.isAvailable( function( type ) {
        
            /* Set Type */
            self.set( 'type' , type );
            
        /* Unavailable */
        }, function() {
        
            /* Reset Type */
            self.set( 'type' , false );
            
        });
    
    }

},
    
/* Authenticate */
/* ------------------------------------------------------------------------------------------------ */
authenticate: function() {
    
    /* Check Plugin */
    if ( window.cordova !== undefined && window.plugins !== undefined && window.plugins.touchid !== undefined ) {
        
        /* Setup */
        var self = this;
        
        /* Load Password */
        window.plugins.touchid.verify( this.get( 'storageService' ).load( 'username' ) , 'Access your App Name account' , function( password ) {
            
            /* Authenticate */
            self.get( 'authService.authenticate' ).perform( self.get( 'storageService' ).load( 'username' ) , password );
        
        /* Error */
        }, function() {
        
            /* Reset */
            self.set( 'saved' , false );
            
            /* Reset Question */
            self.get( 'storageService' ).save( 'biometrics' , '' );
        
        });
    
    }

},

/* Restore */
/* ------------------------------------------------------------------------------------------------ */
restore: function() {

    /* Update Status */
    this.status();
    
    /* Check Response */
    if ( window.cordova !== undefined && this.get( 'storageService' ).load( 'biometrics' ) !== 'rejected' && isPresent( this.get( 'storageService' ).load( 'username' ) ) ) {
        
        /* Check Plugin */
        if ( window.plugins !== undefined && window.plugins.touchid !== undefined ) {
            
            /* Setup */
            var self = this;
            
            /* Key Exists */
            window.plugins.touchid.has( this.get( 'storageService' ).load( 'username' ) , function() {
            
                /* Set Saved */
                self.set( 'saved' , true );
            
            /* Key Doesnt Exist */
            }, function() {
                
                /* Reset Saved */
                self.set( 'saved' , false );
                
                /* Reset Question */
                self.get( 'storageService' ).save( 'biometrics' , '' );
            
            });
        
        }
    
    }

},

/* Save */
/* ------------------------------------------------------------------------------------------------ */
save: function( username , password ) {
    
    /* Check Response */
    if ( window.cordova !== undefined && this.get( 'storageService' ).load( 'biometrics' ) !== 'rejected' && this.get( 'type' ) ) {
    
        /* Check Plugin */
        if ( window.plugins !== undefined && window.plugins.touchid !== undefined ) {
        
            /* Ask Question */
            if ( !this.get( 'saved' ) ) {
            
                /* Ask Question */
                this.question( username , password );
            
            /* Save */
            } else {
            
                /* Save Password */
                window.plugins.touchid.save( username , password , false , function() {} , function() {} );
            
            }        
        
        }
    
    }

},
    
/* Reset */
/* ------------------------------------------------------------------------------------------------ */
reset: function() {
    
    /* Check Plugin */
    if ( window.cordova !== undefined && window.plugins !== undefined && window.plugins.touchid !== undefined ) {
    
        /* Check Saved */
        if ( this.get( 'saved' ) ) {
            
            /* Delete Password */
            window.plugins.touchid.delete( this.get( 'storageService' ).load( 'username' ) , function() {} , function() {} );
            
            /* Reset */
            this.set( 'saved' , false );
        
        }
        
        /* Reset Question */
        this.get( 'storageService' ).save( 'biometrics' , '' );
    
    }

},

/* Question */
/* ------------------------------------------------------------------------------------------------ */
question: function( username , password ) {
    
    /* Check Plugin */
    if ( window.cordova !== undefined && window.plugins !== undefined && window.plugins.touchid !== undefined ) {
    
        /* Setup */
        var self = this;
             
        /* Show Question */
        this.get( 'dialogService' ).confirm( 'App Name' , 'Do you want to use your ' + this.get( 'label' ) + ' to log in next time?',
        
            /* Answer - Yes */
            /* ------------------------------------------------------------------------------------ */
            function() {
                
                /* Save Password */
                /* -------------------------------------------------------------------------------- */
                window.plugins.touchid.save( username , password , true , function() {
                    
                    /* Set Saved */
                    self.set( 'saved' , true );
                    
                    /* Show Notification */
                    self.get( 'dialogService' ).notification( 'App Name' , 'Continue' , 'Your password has been saved.' );
                    
                /* Error */
                /* -------------------------------------------------------------------------------- */
                }, function() {
                    
                    /* Set Saved */
                    self.set( 'saved' , false );
                    
                    /* Show Notification */
                    self.get( 'dialogService' ).notification( 'App Name' , 'Continue' , 'An error has occurred. Your password has not been saved.' );
                    
                });
            
            /* Answer - No */
            /* ------------------------------------------------------------------------------------ */
            }, function() {
                
                /* Set Saved */
                self.set( 'saved' , false );
                
                /* Save Response */
                self.get( 'storageService' ).save( 'biometrics' , 'rejected' );
                
            }
            
        );
    
    }

}

});

@MatthewPringle
Copy link
Author

For the above...

Storage Service just saves a cookie with the username and if the user has rejected using biometrics

Dialog Service is just a wrapper for the Cordova notifications plugin ( the code has to work on a website as well and would adapt to use javascript notifications in place of Cordova notifications )

Auth Service is a separate service for authenticating users with the server, you can replace this with your own once you have retrieved the password from the keychain.

@MatthewPringle
Copy link
Author

@edubskiy no I use window.plugins.touchid.save( username , password , false , function() {} , function() {} );

I save the username in a cookie / local storage. I recall the username and then I can pass that to

window.plugins.touchid.has( this.get( 'storageService' ).load( 'username' ) , function() {

To check if the user has a stored username / password protected by biometrics

And then I use

window.plugins.touchid.verify( this.get( 'storageService' ).load( 'username' ) , 'Access your App Name account' , function( password ) {

To retrieve the password using the username + biometrics

@MatthewPringle
Copy link
Author

MatthewPringle commented Mar 27, 2019

The basic idea is that on a login page, you would save a cookie with the username after first login, ask about using Biometrics for future logins etc... ( see question: function( username , password ) { )

When the user sees the login page again, having checked to see if a cookie exists, it autofills the username part of the login form.

I then query the touch id plugin to see if a username exists in the touch id password store.

If so I can present the user with a "Login with Biometrics" button rather than asking them for a password.

They can then provide biometric authentication and the device passes me back the password.

@MatthewPringle
Copy link
Author

You would also want to fire the status: function() on app init so you know about the capabilities of the device.

@edubskiy
Copy link

@MatthewPringle , thank you, but I thought you showed the code for this plugin https://github.com/niklasmerz/cordova-plugin-fingerprint-aio
We also have similar code you showed, and 95% of the time it really works ok, but in some cases we have complains from users when touchid.save is not working correctly and it seems there is no support for plugin any more that is why we have to replace it with alternative.

@MatthewPringle
Copy link
Author

@edubskiy no it is for this plugin, after a lot of testing the code we used seems to work fine across all devices and platforms we tested on. Due to problems with other plugins we decided to use this one for the current releases.

The code we wrote is a little different from their examples, such as

window.plugins.touchid.save( username , password , false , function() {} , function() {} );

Notice the save function has one more param than the one in their example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants