Coder Social home page Coder Social logo

aparajita / capacitor-biometric-auth Goto Github PK

View Code? Open in Web Editor NEW
109.0 5.0 17.0 550 KB

Easy access to native biometric auth APIs on iOS and Android

License: MIT License

Ruby 1.48% Java 25.70% Objective-C 0.91% Swift 7.08% JavaScript 2.74% TypeScript 34.94% Shell 0.31% CSS 26.83%
capacitor capacitor-plugin capacitorjs biometry biometric-authentication capacitor-plugins capacitor-android capacitor-ios

capacitor-biometric-auth's People

Contributors

a1jan avatar aparajita avatar sunagaga avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

capacitor-biometric-auth's Issues

Cannot access 'registerPlugin' before initialization

When try to build with android studio I received in logcat this error so app is broken.
I think is related to rollup (with vite) but the rollup.config.mjs seems ok.

My configuration is (vite.config.ts):

import legacy from '@vitejs/plugin-legacy'
import react from '@vitejs/plugin-react'
import inject from '@rollup/plugin-inject'
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
import rollupNodePolyFill from 'rollup-plugin-polyfill-node'
import { defineConfig } from 'vite'

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: {
      mqtt: 'mqtt/dist/mqtt.js',
    },
  },
  plugins: [
    react(),
    legacy()
  ],
  optimizeDeps: {
    esbuildOptions: {
      define: {
        global: 'globalThis'
      },
      plugins: [
        NodeGlobalsPolyfillPlugin({
          buffer: true
        })
      ]
    }
  },
  build: {
    minify: false,
    rollupOptions: {
      plugins: [
        inject({ Buffer: ['buffer', 'Buffer'] }),
        rollupNodePolyFill(),
      ],
      output:{
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString();
          }
        }
      }
    }
  },
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/setupTests.ts',
  }
})

My ionic info:

$ ionic info

Ionic:

   Ionic CLI       : 7.1.1 (C:\Users\LAG\AppData\Roaming\nvm\v16.20.0\node_modules\@ionic\cli)
   Ionic Framework : @ionic/react 7.3.1

Capacitor:

   Capacitor CLI      : 5.3.0
   @capacitor/android : 5.3.0
   @capacitor/core    : 5.3.0
   @capacitor/ios     : 5.3.0

Utility:

   cordova-res : 0.15.4
   native-run  : 1.7.2

System:

   NodeJS : v16.20.0 (C:\Program Files\nodejs\node.exe)
   npm    : 8.19.4
   OS     : Windows 10

My package.json relevant is:

  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "test.e2e": "cypress run",
    "test.unit": "vitest",
    "lint": "eslint",
    "ionic:build": "npm run build",
    "ionic:serve": "vite dev --host",
    "ionic:buildDEV": "tsc && vite build --mode development"
  },
  "dependencies": {
    "@aparajita/capacitor-biometric-auth": "^5.0.2",
    "@capacitor/android": "5.3.0",
    "@capacitor/app": "5.0.6",
    "@capacitor/core": "5.3.0",
    "@capacitor/device": "^5.0.6",
    "@capacitor/haptics": "5.0.6",
    "@capacitor/ios": "5.3.0",
    "@capacitor/keyboard": "5.0.6",
    "@capacitor/status-bar": "5.0.6",
    "@emotion/core": "^11.0.0",
    "@emotion/styled": "^11.11.0",
    "@ionic/react": "^7.3.1",
    "@ionic/react-router": "^7.3.1",
    "@tarragon/swipeable-tabs": "^0.1.11",
    "@types/react-router": "^5.1.20",
    "@types/react-router-dom": "^5.3.3",
    "antd": "^5.8.4",
    "axios": "^1.4.0",
    "flag-icons": "^6.10.0",
    "ionicons": "^7.1.2",
    "lodash": "^4.17.21",
    "mqtt": "^5.0.3",
    "onesignal-cordova-plugin": "^3.3.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-intl-universal": "^2.6.21",
    "react-router": "^5.3.4",
    "react-router-dom": "^5.3.4",
    "styled-components": "^6.0.7",
    "swiper": "^10.2.0",
    "use-force-update": "^1.0.11",
    "zustand": "^4.4.1"
  },
  "devDependencies": {
    "@capacitor/cli": "5.3.0",
    "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
    "@testing-library/jest-dom": "^6.0.1",
    "@testing-library/react": "^14.0.0",
    "@testing-library/user-event": "^14.4.3",
    "@types/jest": "^29.5.4",
    "@types/lodash": "^4.14.197",
    "@types/react": "^18.2.21",
    "@types/react-dom": "^18.2.7",
    "@vitejs/plugin-legacy": "^4.1.1",
    "@vitejs/plugin-react": "^4.0.4",
    "cypress": "^12.17.4",
    "eslint": "^8.47.0",
    "eslint-plugin-react": "^7.33.2",
    "jsdom": "^22.1.0",
    "rollup-plugin-polyfill-node": "^0.12.0",
    "typescript": "^5.1.6",
    "vite": "^4.4.9",
    "vitest": "^0.34.2"
  },

I set minified: false because instead error was fuorviant (Cannot access 'registerPlugin' before initialization)

Any suggest for solve or workaround this?

Crashes on iOS 16.4

My code is pretty much the same as the demo code. Crashes on iOS 16.4 simulator.

Trouble running pnpm build -- Unexpected token ! in JSON at position 0

Hello again! At your suggestion here, I'm taking a crack at making the modifications discussed in #21. I admit to not having much experience with pnpm or npm. After getting pnpm installed, cloning my unmodified fork, then running pnpm install, finally running pnpm build, I receive the following output, ending with what looks like a syntax exception thrown.


> @aparajita/[email protected] prebuild /Users/me/Desktop/capacitor-biometric-auth
> pnpm lint


> @aparajita/[email protected] lint /Users/me/Desktop/capacitor-biometric-auth
> pnpm lint.eslint . && pnpm lint.prettier '**/*.{js,mjs,ts,json,md,java}' && pnpm lint.tsc && swiftly ios


> @aparajita/[email protected] lint.eslint /Users/me/Desktop/capacitor-biometric-auth
> eslint --fix --cache --ext .js,.cjs,.mjs,.ts --max-warnings 0 "."


> @aparajita/[email protected] lint.prettier /Users/me/Desktop/capacitor-biometric-auth
> prettier --write --cache --list-different "**/*.{js,mjs,ts,json,md,java}"


> @aparajita/[email protected] lint.tsc /Users/me/Desktop/capacitor-biometric-auth
> tsc --noEmit

Unexpected token ! in JSON at position 0
 ELIFECYCLE  Command failed with exit code 1.
 ELIFECYCLE  Command failed with exit code 1.

I wish I knew what JSON it was referring to. Does this seem like an issue on my side? If so, any suggestions to resolve it?

NOTE: Your Android app must use a base theme named "AppTheme"

At the following location https://github.com/aparajita/capacitor-biometric-auth?tab=readme-ov-file#usage it is saying:

👉 NOTE: Your Android app must use a base theme named "AppTheme".

...but for me it works fine even though my app is not using "a base theme named "AppTheme"".

I found the following related issue #4 and it seems it has been fixed.

The question is whether it has really been fixed but the docs have not been updated accordingly or does the requirement related to AppTheme name still applies (which would imply the issue at the link from above is not related to this issue).

As I reported above for me it is working fine when I am using a theme that has name different then AppTheme.

Thanks!

Background Issue

Hi there,

I'm not sure if it's related to this plugin but I got this gray background each time the biometric is fired.

issue

Have you already encounter this kind of issue ?
Regards

AAPT: error: resource style/AppTheme not found

When I run the command ./gradlew assembleRelease in the Android Studio terminal, I get the following error:

Execution failed for task ':aparajita-capacitor-biometric-auth:verifyReleaseResources'.
> A failure occurred while executing com.android.build.gradle.tasks.VerifyLibraryResourcesTask$Action
   > Android resource linking failed
     ERROR:AAPT: error: resource style/AppTheme (aka com.aparajita.capacitor.biometricauth:style/AppTheme) not found.
     error: failed linking references.

Can you confirm this, or is this an issue on my side?

  • when I do a debug build, everything works fine
  • my apps styles.xml contains a theme named 'AppTheme'

Add namespace in build.gradle to fix android compilation issue on Capacitor 5.x.x

Hi! 👋

Firstly, thanks for your work on this project! 🙂

The aim of this PR is to patch @aparajita/[email protected] for the project I'm working on by adding the namespace to the android build.gradle file for the plugin to be compiled for android using capacitor 5.x.x

Here is the diff that solved my problem:

diff --git a/node_modules/@aparajita/capacitor-biometric-auth/android/build.gradle b/node_modules/@aparajita/capacitor-biometric-auth/android/build.gradle
index 4d3a551..282211d 100644
--- a/node_modules/@aparajita/capacitor-biometric-auth/android/build.gradle
+++ b/node_modules/@aparajita/capacitor-biometric-auth/android/build.gradle
@@ -17,6 +17,7 @@ buildscript {
 apply plugin: 'com.android.library'
 
 android {
+    namespace 'com.aparajita.capacitor.biometricauth'
     compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 32
     defaultConfig {
         minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22

Question: Does `biometryType` really indicate the primary (most secure) type of biometry supported?

Hello @aparajita 👋

Thanks for creating and maintaining this plugin!

Currently I'm checking what's the best option to implement biometric auth for my Capacitor app and if for iOS everything is clear, then for Android it's not that obvious. Meaning, there could be more than one type availbale and how to handle that properly is the question...

In the doc mentioned that CheckBiometryResult biometryType returns the primary (most secure) type of biometry supported by the device, however in the code I see that first element from the collection is taken:

biometryTypes = getDeviceBiometryTypes();
result.put("biometryType", biometryTypes.get(0).getType());

And if both FEATURE_FINGERPRINT and FEATURE_FACE are supported, then FEATURE_FINGERPRINT will be returned. @aparajita, is that intentional? 🤔

implementing in capacitor with angular

hi, is there a tutorial on how i can implemented this plugin in angular? from the demo version that you provided, it's using vue.

somehow i try to implemented it in my apps and build it to iOS, but it got this error :
⚡️ WebView loaded
⚡️ [log] - begin init biometric..
⚡️ [error] - Error during biometric auth: {"code":"UNIMPLEMENTED"}

here's my code snippet :

import { registerPlugin } from '@capacitor/core';
import { BiometricAuthPlugin } from '@aparajita/capacitor-biometric-auth';
const BiometricAuth = registerPlugin<BiometricAuthPlugin>('BiometricAuth');

  initBiometric() {
    console.log('begin init biometric..');
    BiometricAuth.checkBiometry()
      .then((result: any) => {
        console.log('auth biometry', result);
      })
      .catch((error: any) => {
        // Handle any errors
        console.error('Error during biometric check:', error);
      });
  }

  ngOnInit() {
    this.initBiometric();
  }

Thanks!

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference

Hi

First of all, thank you for developing this plugin!

We have issues on Android and IOS when we call the authenticate-method. Getting a NullPointerException.
FATAL EXCEPTION: CapacitorPlugins Process: ***.***.app, PID: 17832 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at com.getcapacitor.Bridge.lambda$callPluginMethod$0(Bridge.java:789) at com.getcapacitor.Bridge.$r8$lambda$ehFTi5f4HhVNFKTbCKAYDkpQYRA(Unknown Source:0) at com.getcapacitor.Bridge$$ExternalSyntheticLambda3.run(Unknown Source:8) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.os.HandlerThread.run(HandlerThread.java:67) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138) at com.getcapacitor.Bridge.lambda$callPluginMethod$0(Bridge.java:780) at com.getcapacitor.Bridge.$r8$lambda$ehFTi5f4HhVNFKTbCKAYDkpQYRA(Unknown Source:0)  at com.getcapacitor.Bridge$$ExternalSyntheticLambda3.run(Unknown Source:8)  at android.os.Handler.handleCallback(Handler.java:942)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loopOnce(Looper.java:201)  at android.os.Looper.loop(Looper.java:288)  at android.os.HandlerThread.run(HandlerThread.java:67)  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference at com.aparajita.capacitor.biometricauth.BiometricAuthNative.authenticate(BiometricAuthNative.java:198) at java.lang.reflect.Method.invoke(Native Method)  at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138)  at com.getcapacitor.Bridge.lambda$callPluginMethod$0(Bridge.java:780)  at com.getcapacitor.Bridge.$r8$lambda$ehFTi5f4HhVNFKTbCKAYDkpQYRA(Unknown Source:0)  at com.getcapacitor.Bridge$$ExternalSyntheticLambda3.run(Unknown Source:8)  at android.os.Handler.handleCallback(Handler.java:942)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loopOnce(Looper.java:201)  at android.os.Looper.loop(Looper.java:288)  at android.os.HandlerThread.run(HandlerThread.java:67) 

Any ideas?

Thanks!

error instanceof BiometryError, error.code typing

For developer experience with typescript, I want to do error instanceof BiometryError like the following:

    try {
      await BiometricAuth.authenticate({
        allowDeviceCredential: true,
      });
    } catch (error) {
      if (error instanceof BiometryError && error.code === 'biometryNotEnrolled') {
         // do thing with error.code
      }

      throw error;
    }

Because error instanceof BiometryError evaluates to false, I have to do the following:

    try {
      await BiometricAuth.authenticate({
        allowDeviceCredential: true,
      });
    } catch (error) {
      if (error && typeof error === 'object' &&'code' in error && error.code === 'biometryNotEnrolled') {
        
      }
      throw error;
    }

or I have to unsafely cast.

Also, BiometryError.code is typed as string, it would be nice if it was BiometryErrorType.

Thank you!

OAuth linking?

Forgive me if this is a dumb question but how do I link biometric authentication with OAuth? For example, I am using firebase and allow users to sign in via username/password, google, etc. If a user has never logged in via username/password (which is the credential I would expect biometric auth to give me from the keychain?), how do I link their biometric auth data to their OAuth provider to show them as logged in? Any info here would be appreciated!

Fallback to PIN on Android

I'm trying to implement this plugin for Android, and it works great when I do have any biometric types on device. But I'd like it to fallback to the PIN input if not. Is this possible?
This is are the options I'm passing to the authenticate method right now:

{
   "reason":"Please authenticate",
   "cancelTitle":"Cancel",
   "allowDeviceCredential":true,
   "iosFallbackTitle":"Use passcode",
   "androidTitle":"Biometric login",
   "androidSubtitle":"Log in using biometric authentication",
   "androidConfirmationRequired":true
}

And it's returning this error:

{
   "save":false,
   "callbackId":"51279928",
   "pluginId":"BiometricAuthNative",
   "methodName":"internalAuthenticate",
   "success":false,
   "error": {
      "message":"There is no biometric hardware on this device.",
      "code":"biometryNotAvailable"
   }
}

Ask for permission without calling 'authenticate'

Hi, I believe there is no way to do this currently, so this is a feature request. We have a settings page in our app where we ask users whether they want to use biometrics or not. If they enable, we call authenticate on app login and FaceId permission is asked here. It would be good to have a way to ask for FaceId permission in settings rather than the login page when they actually attempt to use it for the first time. I believe this would improve the UX. Thanks in advance 🙏

iOS Touch ID dialog displays when calling checkBiometry()

iOS Touch ID dialog displays when checkBiometry() is called.
This doesn't seem like the expected behaviour - was just expecting the metadata to return.
I thought we called authenticate() to actually perform a touch ID or face ID on the device?

Capacitor 5 Support

hello - Thanks for plugin, any approximate time line when it will be updated to Capacitor 5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.