├── testapp
├── .node-version
├── .watchmanconfig
├── .ruby-version
├── app.json
├── .bundle
│ └── config
├── babel.config.js
├── .prettierrc.json
├── android
│ ├── app
│ │ ├── src
│ │ │ ├── main
│ │ │ │ ├── res
│ │ │ │ │ ├── values
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ └── drawable
│ │ │ │ │ │ └── rn_edit_text_material.xml
│ │ │ │ ├── java
│ │ │ │ │ └── com
│ │ │ │ │ │ └── testapp
│ │ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ │ └── MainApplication.kt
│ │ │ │ └── AndroidManifest.xml
│ │ │ └── debug
│ │ │ │ └── AndroidManifest.xml
│ │ ├── debug.keystore
│ │ └── proguard-rules.pro
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── settings.gradle
│ ├── build.gradle
│ └── gradle.properties
├── ios
│ ├── testapp
│ │ ├── Images.xcassets
│ │ │ ├── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── testapp.entitlements
│ │ ├── AppDelegate.swift
│ │ ├── PrivacyInfo.xcprivacy
│ │ └── Info.plist
│ ├── testapp.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── .xcode.env
│ └── Podfile
├── .prettierrc.js
├── index.js
├── tsconfig.json
├── Gemfile
├── react-native.config.js
├── .eslintrc.js
├── _tests
│ ├── testbed
│ │ ├── EmptyTestSuite.ts
│ │ ├── CustomMonitor.ts
│ │ └── CustomInteraction.ts
│ ├── PowerAuth_KDF.test.ts
│ ├── PowerAuth_TimeSync.test.ts
│ ├── helpers
│ │ └── PasswordHelper.ts
│ ├── PowerAuthUtils.test.ts
│ └── PowerAuth_ErrorData.test.ts
├── src
│ └── testbed
│ │ ├── index.ts
│ │ ├── private
│ │ ├── CallStack.ts
│ │ ├── ObjectHelper.ts
│ │ └── ErrorHelper.ts
│ │ └── TestInteraction.ts
├── metro.config.js
├── .env-example
├── .gitignore
└── package.json
├── .npmrc
├── packages
├── cordova-powerauth-mobile-sdk
│ ├── android
│ │ ├── .gitignore
│ │ ├── src
│ │ │ └── main
│ │ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── wultra
│ │ │ │ └── android
│ │ │ │ └── powerauth
│ │ │ │ ├── cdv
│ │ │ │ ├── util
│ │ │ │ │ ├── ReadableType.kt
│ │ │ │ │ ├── ReadableMapKeySetIteratorImpl.kt
│ │ │ │ │ ├── WritableArray.kt
│ │ │ │ │ ├── Dynamic.kt
│ │ │ │ │ ├── WritableMap.kt
│ │ │ │ │ ├── ReadableArray.kt
│ │ │ │ │ ├── ReadableMap.kt
│ │ │ │ │ ├── WritableNativeArray.kt
│ │ │ │ │ ├── NativeDynamic.kt
│ │ │ │ │ ├── WritableNativeMap.kt
│ │ │ │ │ └── ReadableNativeArray.kt
│ │ │ │ ├── PowerAuthPassphraseMeterModule.kt
│ │ │ │ ├── PowerAuthCryptoUtilsModule.kt
│ │ │ │ └── PowerAuthObjectRegister.kt
│ │ │ │ └── bridge
│ │ │ │ └── Aliases.kt
│ │ └── build.gradle
│ ├── ios
│ │ └── PowerAuth
│ │ │ ├── LiftPowerAuthSdk.h
│ │ │ ├── LiftPowerAuthSdk.m
│ │ │ └── PAJSPlatform.h
│ ├── src
│ │ └── internal
│ │ │ ├── NativePowerAuth.ts
│ │ │ ├── Utils.ts
│ │ │ └── NativeCordovaModule.ts
│ └── package.json
└── react-native-powerauth-mobile-sdk
│ ├── ios
│ ├── package.json
│ ├── PowerAuth.xcodeproj
│ │ └── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── PowerAuth.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── .xcode.env
│ ├── Podfile
│ └── PowerAuth
│ │ ├── PAJSPlatform.h
│ │ ├── PowerAuthModule.h
│ │ ├── PowerAuthStorageUtilsModule.h
│ │ ├── Info.plist
│ │ ├── PowerAuthPasswordModule.h
│ │ ├── PowerAuthPassphraseMeterModule.h
│ │ ├── PowerAuthCryptoUtilsModule.h
│ │ ├── pin_tester.h
│ │ ├── LiftPowerAuthSdk.m
│ │ ├── PowerAuthData.h
│ │ ├── PowerAuthData.m
│ │ ├── LiftPowerAuthSdk.h
│ │ ├── Constants.h
│ │ ├── wpm_types.h
│ │ └── PowerAuthEncryptorModule.h
│ ├── android
│ ├── settings.gradle
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── com
│ │ │ └── wultra
│ │ │ └── android
│ │ │ └── powerauth
│ │ │ ├── js
│ │ │ ├── BaseJavaJsModule.kt
│ │ │ ├── Utils.kt
│ │ │ ├── ActivityAwareModule.kt
│ │ │ ├── IManagedObject.kt
│ │ │ ├── WrapperException.java
│ │ │ ├── Constants.java
│ │ │ └── PowerAuthCryptoUtilsJsModule.kt
│ │ │ ├── bridge
│ │ │ └── Aliases.kt
│ │ │ └── reactnative
│ │ │ ├── PowerAuthReactPackage.java
│ │ │ ├── PowerAuthUtils.java
│ │ │ ├── PowerAuthCryptoUtilsModule.java
│ │ │ └── PowerAuthPassphraseMeterModule.java
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── generated
│ │ └── jni
│ │ │ └── CMakeLists.txt
│ ├── gradlew.bat
│ └── build.gradle
│ ├── src
│ ├── internal
│ │ ├── SDKVersion.ts
│ │ ├── NativeCryptoUtils.ts
│ │ ├── NativePowerAuthIfc.ts
│ │ ├── Utils.ts
│ │ ├── NativePowerAuth.ts
│ │ ├── NativeStorageUtils.ts
│ │ ├── NativePassphraseMeter.ts
│ │ ├── NativeModulesProvider.ts
│ │ └── NativeModulesProviderIfc.ts
│ ├── debug
│ │ └── NativeObjectRegister.ts
│ ├── model
│ │ ├── PowerAuthConfirmRecoveryCodeDataResult.ts
│ │ ├── PowerAuthDataFormat.ts
│ │ ├── PowerAuthRecoveryActivationData.ts
│ │ ├── PowerAuthNativeObject.ts
│ │ ├── PowerAuthEncryptionHttpHeader.ts
│ │ ├── PowerAuthAuthorizationHttpHeader.ts
│ │ ├── PowerAuthActivationStatus.ts
│ │ ├── PowerAuthExternalPendingOperation.ts
│ │ ├── PowerAuthActivationState.ts
│ │ ├── PowerAuthCreateActivationResult.ts
│ │ ├── PowerAuthConfiguration.ts
│ │ └── PowerAuthNativeTypes.ts
│ ├── PowerAuthCryptoUtils.ts
│ └── index.ts
│ ├── .prettierrc.json
│ ├── react-native.config.js
│ ├── tsconfig.build-types.json
│ ├── .eslintrc.js
│ ├── tsconfig.json
│ ├── scripts
│ └── generate-sdk-version.cjs
│ ├── .gitignore
│ └── react-native-powerauth-mobile-sdk.podspec
├── .limedeploy
├── .vscode
└── settings.json
├── testapp-cordova
├── www
│ └── img
│ │ └── logo.png
├── .gitignore
├── config.xml
├── package.json
└── src
│ └── App.tsx
├── .yarnrc.yml
├── .github
├── dependabot.yml
├── workflows
│ ├── build-library.yml
│ ├── build-react-native.yml
│ └── build-cordova.yml
└── actions
│ └── prepare
│ └── action.yml
├── docs
├── Version-2.4.md
├── Version-2.5.md
├── Migration-Instructions.md
├── Sample-Integration.md
├── _Sidebar.md
├── Troubleshooting.md
├── Secure-Vault.md
├── Installation.md
├── Crypto-Utilities.md
├── Accessing-Native-PowerAuthSDK.md
├── Additional-Utilities.md
├── Storage-Utilities.md
├── Changelog.md
└── Device-Activation-Removal.md
├── .gitignore
├── .deploy
└── package.json
├── .prepare-release.json
└── scripts
└── prepare-release.sh
/testapp/.node-version:
--------------------------------------------------------------------------------
1 | 18
--------------------------------------------------------------------------------
/testapp/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/testapp/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.7.6
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | //registry.npmjs.org/:_authToken=${NPM_TOKEN}
2 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle/
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/package.json:
--------------------------------------------------------------------------------
1 | ../package.json
--------------------------------------------------------------------------------
/testapp/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "testapp",
3 | "displayName": "Test App"
4 | }
--------------------------------------------------------------------------------
/testapp/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/.limedeploy:
--------------------------------------------------------------------------------
1 | DEPLOY_VERSIONING_FILES=( ".deploy/package.json,package.json" )
2 | DEPLOY_MODE='npm'
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "java.configuration.updateBuildConfiguration": "interactive"
3 | }
--------------------------------------------------------------------------------
/testapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | };
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'PowerAuthReactNative'
2 |
--------------------------------------------------------------------------------
/testapp/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "singleQuote": true,
4 | "trailingComma": "all"
5 | }
6 |
7 |
8 |
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | testapp
3 |
4 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/SDKVersion.ts:
--------------------------------------------------------------------------------
1 | // AUTO-GENERATED
2 | export const SDK_VERSION = '0.0.1-dev';
3 |
--------------------------------------------------------------------------------
/testapp/ios/testapp/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/testapp-cordova/www/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp-cordova/www/img/logo.png
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 | enableImmutableInstalls: false
3 | checksumBehavior: update
4 | nmHoistingLimits: workspaces
5 |
6 |
7 |
--------------------------------------------------------------------------------
/testapp/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/debug.keystore
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "singleQuote": true,
4 | "trailingComma": "all"
5 | }
6 |
7 |
8 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/testapp/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/testapp/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/testapp/index.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native';
2 | import App from './src/App';
3 | import { name as appName } from './app.json';
4 |
5 | AppRegistry.registerComponent(appName, () => App);
6 |
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/testapp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/gradle.properties:
--------------------------------------------------------------------------------
1 | android.useAndroidX=true
2 | android.enableJetifier=true
3 |
4 | # Required due to processing a massive react-android AAR
5 | org.gradle.jvmargs=-Xmx2048M
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/" # Root directory
5 | schedule:
6 | interval: weekly
7 | exclude-paths:
8 | - "testapp/**"
9 | - "testapp-cordova/**"
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wultra/react-native-powerauth-mobile-sdk/HEAD/packages/react-native-powerauth-mobile-sdk/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/js/BaseJavaJsModule.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.js
2 |
3 | /**
4 | * Module base.
5 | */
6 | public interface BaseJavaJsModule {
7 |
8 | fun getName(): String
9 | }
10 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/js/Utils.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.bridge
2 |
3 | @Retention(AnnotationRetention.RUNTIME)
4 | public annotation class JsApiMethod(
5 | public val isBlockingSynchronousMethod: Boolean = false
6 | )
--------------------------------------------------------------------------------
/testapp/ios/testapp.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/testapp/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@react-native/typescript-config/tsconfig.json",
3 | "compilerOptions": {
4 | "types": ["react-native"],
5 | "strict": true,
6 | // "noUncheckedIndexedAccess": true,
7 | // "noImplicitOverride": true,
8 | "noFallthroughCasesInSwitch": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/generated/jni/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.13)
2 | # Forward to the actual codegen output produced by the RN Gradle plugin
3 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../build/generated/source/codegen/jni PowerAuthReactNative_autolinked_build)
4 |
5 |
6 |
--------------------------------------------------------------------------------
/testapp/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Apr 08 16:09:51 CEST 2025
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/react-native.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @type {import('@react-native-community/cli-types').UserDependencyConfig}
3 | */
4 | module.exports = {
5 | dependency: {
6 | platforms: {
7 | android: {
8 | cmakeListsPath: 'generated/jni/CMakeLists.txt',
9 | },
10 | },
11 | },
12 | };
--------------------------------------------------------------------------------
/docs/Version-2.4.md:
--------------------------------------------------------------------------------
1 | # Migration from 2.3.x to 2.4.x
2 |
3 | This guide contains instructions for migration from React Native PowerAuth mobile SDK version `2.3.x` to version `2.4.x`.
4 |
5 | ## Support for React Native 0.71
6 |
7 | There are no special migration instructions except that version 2.4.0 require that your application should support React Native 0.71 and later.
--------------------------------------------------------------------------------
/docs/Version-2.5.md:
--------------------------------------------------------------------------------
1 | # Migration from 2.4.x to 2.5.x
2 |
3 | This guide contains instructions for migration from React Native PowerAuth mobile SDK version `2.4.x` to version `2.5.x`.
4 |
5 | ## Support for React Native 0.73+
6 |
7 | There are no special migration instructions except that version 2.5.0 requires that your application should support React Native 0.73 and later.
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/ReadableType.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | /** Defines the type of an object stored in a [ReadableArray] or [ReadableMap]. */
4 | public enum class ReadableType {
5 | Null,
6 | Boolean,
7 | Number,
8 | String,
9 | Map,
10 | Array,
11 | }
12 |
--------------------------------------------------------------------------------
/testapp/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
2 | plugins { id("com.facebook.react.settings") }
3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
4 | rootProject.name = 'testapp'
5 | include ':app'
6 | includeBuild('../node_modules/@react-native/gradle-plugin')
7 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/tsconfig.build-types.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "declaration": true,
5 | "emitDeclarationOnly": true,
6 | "declarationMap": false,
7 | "outDir": "lib/typescript",
8 | "noEmit": false
9 | },
10 | "include": ["src/**/*"],
11 | "exclude": ["node_modules", "lib"]
12 | }
13 |
--------------------------------------------------------------------------------
/testapp/ios/testapp/testapp.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | group.com.wultra.testGroup
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: '@typescript-eslint/parser',
4 | plugins: ['@typescript-eslint'],
5 | extends: ['@react-native/eslint-config', 'plugin:@typescript-eslint/recommended', 'prettier'],
6 | ignorePatterns: ['lib/', 'node_modules/'],
7 | rules: {
8 | '@typescript-eslint/no-explicit-any': 'off',
9 | },
10 | };
11 |
12 |
13 |
--------------------------------------------------------------------------------
/testapp/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby ">= 2.6.10"
5 |
6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9 | gem 'xcodeproj', '< 1.26.0'
10 | gem 'concurrent-ruby', '< 1.3.4'
11 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/NativeCryptoUtils.ts:
--------------------------------------------------------------------------------
1 | import { NativeModulesProvider } from './NativeModulesProvider';
2 | import { Base64String } from "../PowerAuthCryptoUtils";
3 |
4 | export interface PowerAuthCryptoUtilsIfc {
5 | hashSha256(data: Base64String): Promise
6 | randomBytes(length: number): Promise
7 | }
8 |
9 | export const NativeCryptoUtils = NativeModulesProvider.PowerAuthCryptoUtils;
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/js/ActivityAwareModule.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.js
2 |
3 | import android.app.Activity
4 |
5 | /**
6 | * Module aware of the activity.
7 | */
8 | interface ActivityAwareModule {
9 |
10 | fun getCurrentActivity(): Activity
11 | }
12 |
13 | /**
14 | * Provider of activity.
15 | */
16 | interface ActivityProvider {
17 | fun getActivity(): Activity
18 | }
--------------------------------------------------------------------------------
/testapp/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/ReadableMapKeySetIteratorImpl.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 |
4 | class ReadableMapKeySetIteratorImpl(val iterator: Iterator) : ReadableMapKeySetIterator {
5 |
6 | override fun hasNextKey(): Boolean {
7 | return iterator.hasNext()
8 | }
9 |
10 | override fun nextKey(): String {
11 | return iterator.next()
12 | }
13 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@react-native/typescript-config/tsconfig.json",
3 | "compilerOptions": {
4 | "declaration": false,
5 | "composite": false,
6 | "strict": true,
7 | "noUncheckedIndexedAccess": true,
8 | "noImplicitOverride": true,
9 | "noFallthroughCasesInSwitch": true,
10 | "skipLibCheck": false,
11 | "baseUrl": ".",
12 | "types": []
13 | },
14 | "exclude": ["node_modules", "lib"],
15 | "include": ["src"]
16 | }
--------------------------------------------------------------------------------
/testapp/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | # Run the following command from 'ios' folder to setup the path:
8 | #
9 | # echo "export NODE_BINARY=$(which node)" > .xcode.env.local
10 | #
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/scripts/generate-sdk-version.cjs:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const pkg = require('../package.json');
5 |
6 | const outDir = path.join(__dirname, '..', 'src', 'internal');
7 | const outFile = path.join(outDir, 'SDKVersion.ts');
8 |
9 | fs.mkdirSync(outDir, { recursive: true });
10 | fs.writeFileSync(outFile, `// AUTO-GENERATED\nexport const SDK_VERSION = '${pkg.version}';\n`);
11 | console.log(`Wrote ${outFile}`);
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/testapp/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/.github/workflows/build-library.yml:
--------------------------------------------------------------------------------
1 | name: Build Library
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - release/*
8 | pull_request:
9 |
10 | jobs:
11 | build-library:
12 | name: Build and Pack
13 | runs-on: macos-latest
14 | steps:
15 | - name: Checkout the repo
16 | uses: actions/checkout@v4
17 | - name: Prepare environment
18 | uses: ./.github/actions/prepare
19 | with:
20 | env-file: ${{ secrets.ENV_TEST_FILE }}
21 | - name: Library build
22 | run: yarn build
--------------------------------------------------------------------------------
/testapp/react-native.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | project: {
5 | ios: {
6 | automaticPodsInstallation: true,
7 | },
8 | },
9 | dependencies: {
10 | 'react-native-powerauth-mobile-sdk': {
11 | root: path.join(__dirname, '..', 'packages', 'react-native-powerauth-mobile-sdk'),
12 | platforms: {
13 | // Codegen script incorrectly fails without this
14 | // So we explicitly specify the platforms with empty object
15 | ios: {},
16 | android: {},
17 | },
18 | },
19 | },
20 | };
--------------------------------------------------------------------------------
/docs/Migration-Instructions.md:
--------------------------------------------------------------------------------
1 | # Migration Instructions
2 |
3 | This page contains PowerAuth Mobile JS SDK migration instructions.
4 |
5 |
6 | When updating across multiple versions, you need to perform all migration steps additively.
7 |
8 |
9 | - [Migration from version `2.4.x` to `2.5.x`](Version-2.5.md)
10 | - [Migration from version `2.3.x` to `2.4.x`](Version-2.4.md)
11 | - [Migration from version `2.2.x` to `2.3.x`](Version-2.3.md)
12 | - [Migration from version `3.x.x` to `4.0.0`](Version-4.0.md)
13 |
14 | ## Read Next
15 |
16 | - [Sample Integration](Sample-Integration.md)
--------------------------------------------------------------------------------
/testapp/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext {
3 | buildToolsVersion = "35.0.0"
4 | minSdkVersion = 24
5 | compileSdkVersion = 35
6 | targetSdkVersion = 35
7 | ndkVersion = "27.1.12297006"
8 | kotlinVersion = "2.0.21"
9 | }
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | dependencies {
15 | classpath("com.android.tools.build:gradle")
16 | classpath("com.facebook.react:react-native-gradle-plugin")
17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
18 | }
19 | }
20 |
21 | apply plugin: "com.facebook.react.rootproject"
22 |
--------------------------------------------------------------------------------
/testapp/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: '@typescript-eslint/parser',
4 | plugins: ['@typescript-eslint'],
5 | extends: ['@react-native/eslint-config', 'plugin:@typescript-eslint/recommended', 'prettier'],
6 | ignorePatterns: ['node_modules/'],
7 | rules: {
8 | '@typescript-eslint/no-explicit-any': 'off'
9 | },
10 | overrides: [
11 | {
12 | files: ['metro.config.js', 'react-native.config.js', 'babel.config.js'],
13 | env: { node: true },
14 | parserOptions: { sourceType: 'script' },
15 | rules: {
16 | '@typescript-eslint/no-var-requires': 'off'
17 | }
18 | }
19 | ]
20 | };
21 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/WritableArray.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | /** Interface for a mutable array. Used to pass arguments from Kotlin to JS. */
4 | public interface WritableArray : ReadableArray {
5 | public fun pushArray(array: ReadableArray?)
6 |
7 | public fun pushBoolean(value: Boolean)
8 |
9 | public fun pushDouble(value: Double)
10 |
11 | public fun pushInt(value: Int)
12 |
13 | public fun pushLong(value: Long)
14 |
15 | public fun pushMap(map: ReadableMap?)
16 |
17 | public fun pushNull()
18 |
19 | public fun pushString(value: String?)
20 | }
21 |
--------------------------------------------------------------------------------
/.github/actions/prepare/action.yml:
--------------------------------------------------------------------------------
1 | name: Prepare PowerAuth JS environment
2 |
3 | inputs:
4 | env-file:
5 | description: Contents of the testapp/.env file
6 | required: false
7 | default: "empty"
8 |
9 | runs:
10 | using: composite
11 | steps:
12 | - name: Use Node.js 22
13 | uses: actions/setup-node@v4
14 | with:
15 | node-version: 22
16 | - name: Enable Yarn
17 | shell: bash
18 | run: corepack enable
19 | - name: Install dependencies (Yarn)
20 | shell: bash
21 | run: yarn install --immutable
22 | - name: Set .env file
23 | shell: bash
24 | run: |
25 | echo -e "${{ inputs.env-file }}" > testapp/.env
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/Dynamic.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | /**
4 | * Type representing a piece of data with unknown runtime type. Useful for allowing javascript to
5 | * pass one of multiple types down to the native layer.
6 | */
7 | public interface Dynamic {
8 | public val type: ReadableType
9 |
10 | public val isNull: Boolean
11 |
12 | public fun asArray(): ReadableArray
13 |
14 | public fun asBoolean(): Boolean
15 |
16 | public fun asDouble(): Double
17 |
18 | public fun asInt(): Int
19 |
20 | public fun asMap(): ReadableMap
21 |
22 | public fun asString(): String
23 |
24 | public fun recycle(): Unit
25 | }
26 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | google()
5 | }
6 |
7 | dependencies {
8 | classpath("com.android.tools.build:gradle:8.7.2")
9 | }
10 | }
11 |
12 | apply plugin: "org.jetbrains.kotlin.android"
13 |
14 |
15 | android {
16 | namespace = "com.wultra.android.powerauth.cdv"
17 |
18 | compileOptions {
19 | sourceCompatibility JavaVersion.VERSION_1_8
20 | targetCompatibility JavaVersion.VERSION_1_8
21 | }
22 | }
23 |
24 | repositories {
25 | mavenCentral()
26 | google()
27 | }
28 |
29 | dependencies {
30 | implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.9.22"))
31 | api "com.wultra.android.powerauth:powerauth-sdk:1.9.5"
32 | }
33 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/Podfile:
--------------------------------------------------------------------------------
1 | #require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
2 | require_relative '../node_modules/react-native/scripts/react_native_pods'
3 |
4 | platform :ios, '18.0'
5 |
6 | project 'PowerAuth'
7 |
8 | target 'PowerAuth' do
9 | config = use_native_modules!
10 | use_react_native!(
11 | :path => config[:reactNativePath],
12 | :hermes_enabled => false
13 | )
14 | pod 'PowerAuth2', '~> 1.9.5'
15 | # Uncomment to use not-published SDK in project. This is effective only if you manually open 'ios/PowerAuth.xcworkspace'
16 | #pod 'PowerAuth2', :git => 'https://github.com/wultra/powerauth-mobile-sdk.git', :branch => 'develop', :submodules => true
17 | end
18 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/ios/PowerAuth/LiftPowerAuthSdk.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // This feature is not available for Cordova
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/ios/PowerAuth/LiftPowerAuthSdk.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // This feature is not available for Cordova
18 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/ios/PowerAuth/PAJSPlatform.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef PAJS_CORDOVA
18 | #define PAJS_CORDOVA
19 | #endif
20 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PAJSPlatform.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef PAJS_REACT
18 | #define PAJS_REACT
19 | #endif
20 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthModule.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "PAJS.h"
18 |
19 | PAJS_MODULE(PowerAuthModule)
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/testapp/_tests/testbed/EmptyTestSuite.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { TestSuite } from "../../src/testbed";
18 |
19 | export class EmptyTestSuite extends TestSuite {
20 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/NativePowerAuthIfc.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export interface NativePowerAuthIfc {
18 | callNative(...args: any[]): Promise;
19 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthStorageUtilsModule.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "PAJS.h"
18 |
19 | PAJS_MODULE_BASIC(PowerAuthStorageUtilsModule)
20 |
21 | @end
22 |
23 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/Utils.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Platform } from 'react-native';
18 |
19 | export class Utils {
20 | static platformOs = Platform.OS;
21 | }
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/WritableMap.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | /** Interface for a mutable map. Used to pass arguments from Kotlin to JS. */
4 | public interface WritableMap : ReadableMap {
5 | public fun copy(): WritableMap
6 |
7 | public fun merge(source: ReadableMap)
8 |
9 | public fun putArray(key: String, value: ReadableArray?)
10 |
11 | public fun putBoolean(key: String, value: Boolean)
12 |
13 | public fun putDouble(key: String, value: Double)
14 |
15 | public fun putInt(key: String, value: Int)
16 |
17 | public fun putLong(key: String, value: Long)
18 |
19 | public fun putMap(key: String, value: ReadableMap?)
20 |
21 | public fun putNull(key: String)
22 |
23 | public fun putString(key: String, value: String?)
24 | }
25 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthPasswordModule.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "PAJS.h"
18 |
19 | /**
20 | Bridge module implementing PowerAuthPassword JavaScript class.
21 | */
22 | PAJS_MODULE(PowerAuthPasswordModule)
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthPassphraseMeterModule.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "PAJS.h"
18 |
19 | /**
20 | Bridge implementing PowerAuthPassphraseMeter interface.
21 | */
22 | PAJS_MODULE(PowerAuthPassphraseMeterModule)
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/testapp/src/testbed/index.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | export * from './expect';
18 | export * from './TestInteraction';
19 | export * from './TestLog';
20 | export * from './TestMonitor';
21 | export * from './TestProgress';
22 | export * from './TestRunner';
23 | export * from './TestSuite';
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthCryptoUtilsModule.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "PAJS.h"
18 |
19 | /**
20 | Bridge module implementing PowerAuthCryptoUtils JavaScript class for iOS.
21 | */
22 | PAJS_MODULE_BASIC(PowerAuthCryptoUtilsModule)
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/src/internal/NativePowerAuth.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | //@ts-nocheck
18 |
19 | import { NativeCordovaModule } from "./NativeCordovaModule";
20 |
21 | export class NativePowerAuth extends NativeCordovaModule {
22 |
23 | readonly pluginName = "PowerAuthModule";
24 | }
25 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/src/internal/Utils.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export class Utils {
18 |
19 | static platformOs = this.detectPlatform()
20 |
21 | private static detectPlatform(): string {
22 |
23 | // @ts-expect-error
24 | return cordova.platformId
25 | }
26 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/debug/NativeObjectRegister.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { NativeModulesProvider } from "../internal/NativeModulesProvider";
18 |
19 | /**
20 | * Instance of native object register.
21 | */
22 | export const NativeObjectRegister = NativeModulesProvider.PowerAuthObjectRegister;
23 |
--------------------------------------------------------------------------------
/testapp/android/app/src/main/java/com/testapp/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.testapp
2 |
3 | import com.facebook.react.ReactActivity
4 | import com.facebook.react.ReactActivityDelegate
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate
7 |
8 | class MainActivity : ReactActivity() {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | override fun getMainComponentName(): String = "testapp"
15 |
16 | /**
17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
19 | */
20 | override fun createReactActivityDelegate(): ReactActivityDelegate =
21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
22 | }
23 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | .DS_Store
3 |
4 | # vscode
5 | .vscode
6 | !.vscode/launch.json
7 |
8 | # library
9 | node_modules
10 | lib
11 |
12 | # demoapp
13 | demoapp/node_modules
14 |
15 | # Android
16 | android/.gradle/
17 | android/.project
18 | android/.settings
19 | android/.idea
20 | android/local.properties
21 | /android/.classpath
22 | demoapp/android/local.properties
23 | demoapp/android/.gradle/
24 | demoapp/android/.project
25 | demoapp/android/.idea
26 | demoapp/android/.settings
27 | demoapp/android/app/.gradle/
28 | demoapp/android/app/.project
29 | demoapp/android/app/.settings
30 | demoapp/.expo
31 | *build/
32 | .idea
33 | *.iml
34 | *.ipr
35 | *.iws
36 | out
37 | gen-external-apklibs
38 |
39 | # iOS
40 | xcuserdata
41 | *.xcuserstate
42 | ios/Pods/*
43 | demoapp/ios/Pods/*
44 | .xcode.env.local
45 |
46 | # artifacts
47 | *.tgz
48 |
49 | # Yarn and monorepo
50 | .yarn
51 | .yarn/*
52 | !.yarn/releases
53 | !.yarn/plugins
54 | .pnp.*
55 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/ReadableArray.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | import java.util.ArrayList
4 |
5 | /**
6 | * Interface for an array that allows typed access to its members. Used to pass parameters from JS
7 | * to Kotlin.
8 | */
9 | public interface ReadableArray {
10 | public fun getArray(index: Int): ReadableArray
11 |
12 | public fun getBoolean(index: Int): Boolean
13 |
14 | public fun getDouble(index: Int): Double
15 |
16 | public fun getDynamic(index: Int): Dynamic
17 |
18 | public fun getInt(index: Int): Int
19 |
20 | public fun getLong(index: Int): Long
21 |
22 | public fun getMap(index: Int): ReadableMap
23 |
24 | public fun getString(index: Int): String
25 |
26 | public fun getType(index: Int): ReadableType
27 |
28 | public fun isNull(index: Int): Boolean
29 |
30 | public fun size(): Int
31 |
32 | public fun toArrayList(): ArrayList
33 | }
34 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthConfirmRecoveryCodeDataResult.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * Result of the confirmRecoveryCode PowerAuth method.
19 | */
20 | export interface PowerAuthConfirmRecoveryCodeDataResult {
21 | /**
22 | * Indicates that the code was already confirmed in the past
23 | */
24 | alreadyConfirmed: boolean
25 | }
--------------------------------------------------------------------------------
/testapp/src/testbed/private/CallStack.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | export function parseRnCallStack(stack: string, padding: string = ""): string {
18 | const lines = stack.split('\n');
19 | if (lines.length == 0) {
20 | return '';
21 | }
22 | return lines
23 | .filter(line => line.length > 0 && line.startsWith(' at'))
24 | .map(line => `${padding} ${line}`).join('\n')
25 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | .DS_Store
3 |
4 | # vscode
5 | .vscode
6 | !.vscode/launch.json
7 |
8 | # library
9 | node_modules
10 | lib
11 |
12 | # demoapp
13 | demoapp/node_modules
14 |
15 | # Android
16 | android/.gradle/
17 | android/.project
18 | android/.settings
19 | android/.idea
20 | android/local.properties
21 | /android/.classpath
22 | demoapp/android/local.properties
23 | demoapp/android/.gradle/
24 | demoapp/android/.project
25 | demoapp/android/.idea
26 | demoapp/android/.settings
27 | demoapp/android/app/.gradle/
28 | demoapp/android/app/.project
29 | demoapp/android/app/.settings
30 | demoapp/.expo
31 | *build/
32 | .idea
33 | *.iml
34 | *.ipr
35 | *.iws
36 | out
37 | gen-external-apklibs
38 |
39 | # iOS
40 | xcuserdata
41 | *.xcuserstate
42 | ios/Pods/*
43 | demoapp/ios/Pods/*
44 | .xcode.env.local
45 |
46 | # artifacts
47 | *.tgz
48 | package-lock.json
49 | npm-shrinkwrap.json
50 |
51 | # Yarn and monorepo
52 | .yarn
53 | yarn/*
54 | !.yarn/releases
55 | !.yarn/plugins
56 | !.yarn/patches
57 | !.yarn/sdks
58 | !.yarn/versions
59 | .pnp.*
60 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/pin_tester.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef wultra_pin_tester_h
18 | #define wultra_pin_tester_h
19 |
20 | #include
21 | #include "wpm_types.h"
22 |
23 | #ifdef __cplusplus
24 | extern "C" {
25 | #endif
26 |
27 | WPM_PasscodeResult PinTester_testPasscode(const char * pin);
28 |
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 |
33 | #endif /* wultra_pin_tester_h */
34 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthDataFormat.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * Input or output data format specification for the cryptographic operation:
19 | * - `UTF8` - data is formatted as a plain string that will be converted into UTF-8 encoded sequence of bytes before the operation.
20 | * - `BASE64` - binary data encoded into Base64 string.
21 | */
22 | export type PowerAuthDataFormat = 'UTF8' | 'BASE64'
23 |
--------------------------------------------------------------------------------
/testapp-cordova/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one
3 | # or more contributor license agreements. See the NOTICE file
4 | # distributed with this work for additional information
5 | # regarding copyright ownership. The ASF licenses this file
6 | # to you under the Apache License, Version 2.0 (the
7 | # "License"); you may not use this file except in compliance
8 | # with the License. You may obtain a copy of the License at
9 | #
10 | # http://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing,
13 | # software distributed under the License is distributed on an
14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | # KIND, either express or implied. See the License for the
16 | # specific language governing permissions and limitations
17 | # under the License.
18 |
19 | .DS_Store
20 |
21 | # Generated by package manager
22 | node_modules/
23 |
24 | # Generated by Cordova
25 | /plugins/
26 | /platforms/
27 |
28 | # compiled file
29 | www/js/index.js
30 |
31 | .temp/
--------------------------------------------------------------------------------
/testapp/ios/testapp/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import React
3 | import React_RCTAppDelegate
4 | import ReactAppDependencyProvider
5 |
6 | @main
7 | class AppDelegate: RCTAppDelegate {
8 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
9 | self.moduleName = "testapp"
10 | self.dependencyProvider = RCTAppDependencyProvider()
11 |
12 | // You can add your custom initial props in the dictionary below.
13 | // They will be passed down to the ViewController used by React Native.
14 | self.initialProps = [:]
15 |
16 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
17 | }
18 |
19 | override func sourceURL(for bridge: RCTBridge) -> URL? {
20 | self.bundleURL()
21 | }
22 |
23 | override func bundleURL() -> URL? {
24 | #if DEBUG
25 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
26 | #else
27 | Bundle.main.url(forResource: "main", withExtension: "jsbundle")
28 | #endif
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/docs/Sample-Integration.md:
--------------------------------------------------------------------------------
1 | # Sample Integration
2 |
3 | To better understand the APIs of the PowerAuth Mobile JS SDK, we prepared a sample test application.
4 |
5 | ## Test Application
6 |
7 | The test application with the PowerAuth Mobile JS SDK integration can be found inside the `testapp` folder of the [GitHub repository](https://github.com/wultra/react-native-powerauth-mobile-sdk#docucheck-keep-link). Visit [_tests](https://github.com/wultra/react-native-powerauth-mobile-sdk/blob/develop/testapp/_tests#docucheck-keep-link) folder for example usage of the SDK. The [PowerAuth_Example.ts](https://github.com/wultra/react-native-powerauth-mobile-sdk/blob/develop/testapp/_tests/PowerAuth_Example.ts#docucheck-keep-link) file is perhaps the best start point, because contains a well commented example of the activation flow.
8 |
9 |
10 | The test application is using direct calls to PowerAuth Cloud component to manage activations on the server automatically. You suppose to don't do such thing in the real application.
11 |
12 |
13 | ## Read Next
14 |
15 | - [User Info](User-Info.md)
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/bridge/Aliases.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.bridge
2 |
3 | import android.content.Context
4 |
5 | // point to React bridge
6 | typealias Arguments = com.facebook.react.bridge.Arguments
7 | typealias Dynamic = com.facebook.react.bridge.Dynamic
8 | typealias Promise = com.facebook.react.bridge.Promise
9 | typealias ReactMethod = com.facebook.react.bridge.ReactMethod
10 | typealias ReadableArray = com.facebook.react.bridge.ReadableArray
11 | typealias ReadableMap = com.facebook.react.bridge.ReadableMap
12 | typealias ReadableType = com.facebook.react.bridge.ReadableType
13 | typealias WritableArray = com.facebook.react.bridge.WritableArray
14 | typealias WritableMap = com.facebook.react.bridge.WritableMap
15 |
16 |
17 |
18 | // bridge to concrete platform implementation
19 | typealias BuildConfig = com.wultra.android.powerauth.reactnative.BuildConfig
20 | typealias PwBuildConfig = com.wultra.android.powerauth.bridge.ReactPwBuildConfig
21 |
22 | object ReactPwBuildConfig {
23 | fun isDebuggable(context: Context) = BuildConfig.DEBUG
24 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/NativePowerAuth.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { NativeModules } from "react-native";
18 | import { NativePowerAuthIfc } from "./NativePowerAuthIfc";
19 |
20 | export class NativePowerAuth implements NativePowerAuthIfc {
21 | callNative(name: string, ...args: any[]): Promise {
22 | // eslint-disable-next-line @typescript-eslint/ban-types
23 | return (NativeModules.PowerAuth[name] as Function).apply(null, ...args);
24 | }
25 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthRecoveryActivationData.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * The `PowerAuthRecoveryActivationData` object contains information about recovery code and PUK, created
19 | * during the activation process.
20 | */
21 | export interface PowerAuthRecoveryActivationData {
22 | /**
23 | * Contains recovery code.
24 | */
25 | recoveryCode: string
26 | /**
27 | * Contains PUK, valid with recovery code.
28 | */
29 | puk: string
30 | }
--------------------------------------------------------------------------------
/.github/workflows/build-react-native.yml:
--------------------------------------------------------------------------------
1 | name: Build RN Integration
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - release/*
8 | pull_request:
9 |
10 | jobs:
11 | build-ios:
12 | name: iOS
13 | runs-on: macos-latest
14 | steps:
15 | - name: Checkout the repo
16 | uses: actions/checkout@v4
17 | - name: Prepare environment
18 | uses: ./.github/actions/prepare
19 | with:
20 | env-file: ${{ secrets.ENV_TEST_FILE }}
21 | - name: Build RN iOS
22 | run: yarn buildReactIos
23 | build-android:
24 | name: Android
25 | runs-on: macos-latest
26 | steps:
27 | - name: Checkout the repo
28 | uses: actions/checkout@v4
29 | - name: Prepare environment
30 | uses: ./.github/actions/prepare
31 | with:
32 | env-file: ${{ secrets.ENV_TEST_FILE }}
33 | - name: Setup Java 17
34 | uses: actions/setup-java@v4
35 | with:
36 | distribution: 'temurin'
37 | java-version: '17'
38 | cache: 'gradle'
39 | - name: Build RN Android
40 | run: yarn buildReactAndroid
--------------------------------------------------------------------------------
/testapp/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/testapp/ios/testapp/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/.github/workflows/build-cordova.yml:
--------------------------------------------------------------------------------
1 | name: Build Cordova Integration
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - release/*
8 | pull_request:
9 |
10 | jobs:
11 | build-ios:
12 | name: iOS
13 | runs-on: macos-latest
14 | steps:
15 | - name: Checkout the repo
16 | uses: actions/checkout@v4
17 | - name: Prepare environment
18 | uses: ./.github/actions/prepare
19 | with:
20 | env-file: ${{ secrets.ENV_TEST_FILE }}
21 | - name: Build Cordova iOS
22 | run: yarn buildCordovaIos
23 | build-android:
24 | name: Android
25 | runs-on: macos-latest
26 | steps:
27 | - name: Checkout the repo
28 | uses: actions/checkout@v4
29 | - name: Prepare environment
30 | uses: ./.github/actions/prepare
31 | with:
32 | env-file: ${{ secrets.ENV_TEST_FILE }}
33 | - name: Setup Java 17
34 | uses: actions/setup-java@v4
35 | with:
36 | distribution: 'temurin'
37 | java-version: '17'
38 | cache: 'gradle'
39 | - name: Build Cordova Android
40 | run: yarn buildCordovaAndroid
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/js/IManagedObject.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.wultra.android.powerauth.js
17 |
18 | /**
19 | * Interface for objects stored in the objects register.
20 | */
21 | interface IManagedObject {
22 | /**
23 | * Do cleanup when object is being removed from the register.
24 | */
25 | fun cleanup()
26 |
27 | /**
28 | * Return actual object stored in the register.
29 | */
30 | fun managedInstance(): T
31 | }
32 |
--------------------------------------------------------------------------------
/testapp/ios/testapp/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryFileTimestamp
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | C617.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryUserDefaults
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | CA92.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategorySystemBootTime
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | 35F9.1
29 |
30 |
31 |
32 | NSPrivacyCollectedDataTypes
33 |
34 | NSPrivacyTracking
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/testapp/metro.config.js:
--------------------------------------------------------------------------------
1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2 | const path = require('path');
3 | const exclusionList = require('metro-config/src/defaults/exclusionList');
4 |
5 | /**
6 | * Metro configuration
7 | * https://reactnative.dev/docs/metro
8 | *
9 | * @type {import('@react-native/metro-config').MetroConfig}
10 | */
11 | const root = path.resolve(__dirname, '..');
12 | const sdk = path.resolve(root, 'packages', 'react-native-powerauth-mobile-sdk');
13 | const singletons = ['react', 'react-native'];
14 |
15 | const config = {
16 | watchFolders: [sdk],
17 | resolver: {
18 | unstable_enableSymlinks: true,
19 | enablePackageExports: true,
20 | nodeModulesPaths: [path.resolve(__dirname, 'node_modules')],
21 | blacklistRE: exclusionList(
22 | singletons.map(m => new RegExp(`^${path.join(root, 'node_modules', m).replace(/[\\/]/g, '[\\/]')}\/.*$`))
23 | ),
24 | extraNodeModules: singletons.reduce((acc, name) => {
25 | acc[name] = path.join(__dirname, 'node_modules', name);
26 | return acc;
27 | }, {}),
28 | },
29 | };
30 |
31 | module.exports = mergeConfig(getDefaultConfig(__dirname), config);
32 |
--------------------------------------------------------------------------------
/testapp/.env-example:
--------------------------------------------------------------------------------
1 | # ------------------------------------------------------------- #
2 | # If you need to provide credentials for PowerAuth Server #
3 | # then copy this file to `.env` and put your credentials there. #
4 | # #
5 | # The `.env` file is ignored by git, so it will not leak your #
6 | # credentials by accident. #
7 | # #
8 | # If you change some variable, then: #
9 | # run "npm run android" - to apply change on Android #
10 | # run "npm run ios" - to apply changes on iOS #
11 | # ------------------------------------------------------------- #
12 |
13 | # PowerAuth Cloud API
14 | POWERAUTH_CLOUD_URL=https://my-url.com/powerauth-cloud
15 | POWERAUTH_CLOUD_USERNAME=my-login
16 | POWERAUTH_CLOUD_PASSWORD=my-password
17 | POWERAUTH_CLOUD_APP_ID=my-app-id
18 |
19 | # User Data Store API
20 | UDS_SERVER_URL=
21 | UDS_SERVER_USERNAME=
22 | UDS_SERVER_PASSWORD=
23 |
24 | # PowerAuth Enrollment API
25 | ENROLLMENT_SERVER_URL=https://my-url.com/enrollment-server
26 | SDK_CONFIG=BASE64_ENCODED_CONFIG
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/NativeStorageUtils.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { NativeModulesProvider } from './NativeModulesProvider';
18 |
19 | export interface PowerAuthStorageUtilsIfc {
20 | setString(key: string, value: string, storageType: string): Promise
21 | getString(key: string, storageType: string): Promise
22 | exists(key: string, storageType: string): Promise
23 | remove(key: string, storageType: string): Promise
24 | }
25 |
26 | export const NativeStorageUtils = NativeModulesProvider.PowerAuthStorageUtils;
27 |
28 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/LiftPowerAuthSdk.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 | #import "PowerAuthObjectRegister.h"
19 | #import
20 | #import
21 |
22 | PowerAuthSDK * LiftPowerAuthSdk(NSString * instanceId, RCTBridge * bridge)
23 | {
24 | PowerAuthSDK * sdk;
25 | PowerAuthObjectRegister * paor = [bridge moduleForName:@"PowerAuthObjectRegister"];
26 | if (paor)
27 | {
28 | sdk = [paor findObjectWithId:instanceId expectedClass:[PowerAuthSDK class]];
29 | }
30 | return sdk;
31 | }
32 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthData.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "Utilities.h"
18 |
19 | /**
20 | Object that wrap NSData to JavaScript.
21 | */
22 | @interface PowerAuthData : NSObject
23 |
24 | /// Initialize object with NSData object.
25 | /// - Parameters:
26 | /// - data: Data object to manage from JavaScript
27 | /// - cleanup: Do data cleanup if possible.
28 | - (nonnull instancetype) initWithData:(nonnull NSData*)data cleanup:(BOOL)cleanup;
29 |
30 | /// Contains managed data object.
31 | @property (nonatomic, readonly, strong, nonnull) NSData * data;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/docs/_Sidebar.md:
--------------------------------------------------------------------------------
1 | **Integration Tutorials**
2 |
3 | - [Installation](Installation.md)
4 | - [Configuration](Configuration.md)
5 | - [Device Activation](Device-Activation.md)
6 | - [Requesting Device Activation Status](Requesting-Device-Activation-Status.md)
7 | - [Data Signing](Data-Signing.md)
8 | - [Password Management](Password-Management.md)
9 | - [Working with passwords securely](Secure-Password.md)
10 | - [Biometry Setup](Biometry-Setup.md)
11 | - [Device Activation Removal](Device-Activation-Removal.md)
12 | - [End-To-End Encryption](End-To-End-Encryption.md)
13 | - [Secure Vault](Secure-Vault.md)
14 | - [Recovery Codes](Recovery-Codes.md)
15 | - [Token Based Authentication](Token-Based-Authentication.md)
16 |
17 | **Additional Topics**
18 |
19 | - [Troubleshooting](Troubleshooting.md)
20 | - [Migration Instructions](Migration-Instructions.md)
21 | - [Sample Integration](Sample-Integration.md)
22 | - [User Info](User-Info.md)
23 | - [Time Synchronization](Time-Synchronization.md)
24 | - [Crypto Utilities](Crypto-Utilities.md)
25 | - [Storage Utilities](Storage-Utilities.md)
26 | - [Accessing the Native PowerAuthSDK](Accessing-Native-PowerAuthSDK.md)
27 | - [Additional Utilities](Additional-Utilities.md)
28 |
29 | **Other**
30 | - [Changelog](Changelog.md)
--------------------------------------------------------------------------------
/testapp/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 |
37 | # node.js
38 | #
39 | node_modules/
40 | npm-debug.log
41 | yarn-error.log
42 |
43 | # fastlane
44 | #
45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
46 | # screenshots whenever they are needed.
47 | # For more information about the recommended setup visit:
48 | # https://docs.fastlane.tools/best-practices/source-control/
49 |
50 | **/fastlane/report.xml
51 | **/fastlane/Preview.html
52 | **/fastlane/screenshots
53 | **/fastlane/test_output
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # Ruby / CocoaPods
59 | /ios/Pods/
60 | /vendor/bundle/
61 |
62 | # Temporary files created by Metro to check the health of the file watcher
63 | .metro-health-check*
64 |
65 | # Config
66 | .env
67 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthNativeObject.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { NativeModulesProvider } from "../internal/NativeModulesProvider"
18 |
19 | /**
20 | * Low level interface provided by native PowerAuthObjectRegister.
21 | */
22 | export interface PowerAuthNativeObject {
23 | /**
24 | * Test whether underlying native object register still contains object with given ID.
25 | * @param objectId Object identifier to test.
26 | */
27 | isValidNativeObject(objectId: string): Promise
28 | }
29 |
30 | export const PowerAuthNativeObject = NativeModulesProvider.PowerAuthObjectRegister as PowerAuthNativeObject
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthEncryptionHttpHeader.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * Object representing encryption HTTP header with data required for PowerAuth End-To-End encrypted request.
19 | */
20 | export interface PowerAuthEncryptionHttpHeader {
21 | /**
22 | * Property representing PowerAuth HTTP Authorization Header. The current implementation
23 | * contains value "X-PowerAuth-Encryption" for standard encryption.
24 | */
25 | readonly key: string
26 | /**
27 | * Computed value of the PowerAuth HTTP Encryption Header, to be used in HTTP request "as is".
28 | */
29 | readonly value: string
30 | }
--------------------------------------------------------------------------------
/testapp/_tests/testbed/CustomMonitor.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { TestEvent, TestMonitor } from "../../src/testbed/TestMonitor"
18 | import { TestProgress } from "../../src/testbed/TestProgress"
19 |
20 | export class CustomMonitor implements TestMonitor {
21 |
22 | eventList: TestEvent[] = []
23 | suiteProgress: TestProgress | undefined
24 | testsProgress: TestProgress | undefined
25 |
26 | reportEvent(event: TestEvent): void {
27 | this.eventList.push(event)
28 | }
29 | reportTestSuitesProgress(progress: TestProgress): void {
30 | this.suiteProgress = progress
31 | }
32 | reportAllTestsProgress(progress: TestProgress): void {
33 | this.testsProgress = progress
34 | }
35 | }
--------------------------------------------------------------------------------
/docs/Troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | ## Upgrading SDK
4 |
5 | If you upgraded SDK to a newer major or minor version and encounter some problems, then please follow the [Migration Instructions](Migration-Instructions.md) first.
6 |
7 | ## Enable debug log
8 |
9 | In case you encounter a problem with this library, then try to turn-on a detailed debug log to provide a more information for the library developers:
10 |
11 | ```javascript
12 | // Enable debug log with failed call to native function.
13 | PowerAuthDebug.traceNativeCodeCalls(true);
14 | // Trace all calls to native library
15 | PowerAuthDebug.traceNativeCodeCalls(true, true);
16 | ```
17 |
18 |
19 | The `PowerAuthDebug` class is effective only when `isEnabled` is `true`. We don't want to log the sensitive information to the console in the production application.
20 |
21 |
22 | ## Dumping native objects
23 |
24 | If `PowerAuthDebug.isEnabled` is turned on, then you can dump information about all native objects allocated and used by PowerAuth Mobile JS SDK:
25 |
26 | ```javascript
27 | // Dump all objects
28 | await PowerAuthDebug.dumpNativeObjects();
29 | // Dump objects related to PowerAuth instance
30 | await PowerAuthDebug.dumpNativeObjects(powerAuth.instanceId);
31 | ```
32 |
33 | ## Read Next
34 |
35 | - [Migration Instructions](Migration-Instructions.md)
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthAuthorizationHttpHeader.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * Object representing authorization HTTP header with the PowerAuth-Authorization or PowerAuth-Token signature.
19 | */
20 | export interface PowerAuthAuthorizationHttpHeader {
21 | /**
22 | * Property representing PowerAuth HTTP Authorization Header. The current implementation
23 | * contains value "X-PowerAuth-Authorization" for standard authorization and "X-PowerAuth-Token" for
24 | * token-based authorization.
25 | */
26 | key: string
27 | /**
28 | * Computed value of the PowerAuth HTTP Authorization Header, to be used in HTTP requests "as is".
29 | */
30 | value: string
31 | }
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/ReadableMap.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | import java.util.HashMap
4 | import kotlin.collections.Iterator
5 | import kotlin.collections.Map
6 |
7 | /**
8 | * Interface for a map that allows typed access to its members. Used to pass parameters from JS to
9 | * Kotlin.
10 | */
11 | public interface ReadableMap {
12 | public val entryIterator: Iterator>
13 |
14 | public fun getArray(name: String): ReadableArray?
15 |
16 | public fun getBoolean(name: String): Boolean
17 |
18 | public fun getDouble(name: String): Double
19 |
20 | public fun getDynamic(name: String): Dynamic
21 |
22 | public fun getInt(name: String): Int
23 |
24 | public fun getLong(name: String): Long
25 |
26 | public fun getMap(name: String): ReadableMap?
27 |
28 | public fun getString(name: String): String?
29 |
30 | public fun getType(name: String): ReadableType
31 |
32 | public fun hasKey(name: String): Boolean
33 |
34 | public fun isNull(name: String): Boolean
35 |
36 | public fun keySetIterator(): ReadableMapKeySetIterator
37 |
38 | public fun toHashMap(): HashMap
39 | }
40 |
41 | public interface ReadableMapKeySetIterator {
42 | public fun hasNextKey(): Boolean
43 |
44 | public fun nextKey(): String
45 | }
46 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthData.m:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "PowerAuthData.h"
18 | #import "Utilities.h"
19 |
20 | @implementation PowerAuthData
21 | {
22 | BOOL _cleanup;
23 | }
24 |
25 | - (instancetype) initWithData:(nonnull NSData*)data
26 | cleanup:(BOOL)cleanup
27 | {
28 | self = [super init];
29 | if (self) {
30 | _data = data;
31 | _cleanup = cleanup;
32 | }
33 | return self;
34 | }
35 |
36 | - (void) dealloc
37 | {
38 | if (_cleanup) {
39 | NSMutableData * mutable = CAST_TO(_data, NSMutableData);
40 | if (mutable) {
41 | memset(mutable.mutableBytes, 0, mutable.length);
42 | }
43 | }
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/testapp/src/testbed/TestInteraction.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { TestContext } from "./TestSuite"
18 |
19 | export enum UserPromptDuration {
20 | QUICK,
21 | SHORT,
22 | LONG
23 | }
24 |
25 | export interface UserInteraction {
26 | showPrompt(context: TestContext, message: string, duration: UserPromptDuration): Promise
27 | sleepWithProgress(context: TestContext, durationMs: number): Promise
28 | }
29 |
30 | export interface TestInteraction extends UserInteraction {
31 | reportWarning(context: TestContext, message: string): void
32 | reportInfo(context: TestContext, message: string): void
33 | reportSkip(context: TestContext, reason: string): void
34 | reportFailure(context: TestContext, reason: string): void
35 | }
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/bridge/Aliases.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.bridge
2 |
3 | import android.content.Context
4 | import android.content.pm.ApplicationInfo
5 |
6 |
7 |
8 | // point to React bridge
9 | typealias Arguments = com.wultra.android.powerauth.cdv.util.Arguments
10 | typealias Dynamic = com.wultra.android.powerauth.cdv.util.Dynamic
11 | typealias Promise = com.wultra.android.powerauth.cdv.util.Promise
12 | typealias ReadableArray = com.wultra.android.powerauth.cdv.util.ReadableArray
13 | typealias ReadableMap = com.wultra.android.powerauth.cdv.util.ReadableMap
14 | typealias ReadableType = com.wultra.android.powerauth.cdv.util.ReadableType
15 | typealias WritableArray = com.wultra.android.powerauth.cdv.util.WritableArray
16 | typealias WritableMap = com.wultra.android.powerauth.cdv.util.WritableMap
17 |
18 |
19 | // bridge to concrete platform implementation
20 | typealias BuildConfig = com.wultra.android.powerauth.bridge.DummyBuildConfig
21 | typealias PwBuildConfig = com.wultra.android.powerauth.bridge.CordovaPwBuildConfig
22 |
23 | object DummyBuildConfig {
24 | val DEBUG = false // unused in the lib
25 | }
26 |
27 | object CordovaPwBuildConfig {
28 | fun isDebuggable(context: Context): Boolean {
29 | return 0 != context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
30 | }
31 | }
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/WritableNativeArray.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 |
4 | /**
5 | * Cordova implementation of writable array.
6 | *
7 | * It's not in fact native, it's based on Kotlin collections.
8 | */
9 | class WritableNativeArray(list: List = emptyList()) : ReadableNativeArray(list), WritableArray {
10 |
11 | override fun pushArray(array: ReadableArray?) {
12 | if (!(array == null || array is ReadableNativeArray)) {
13 | throw IllegalArgumentException("Illegal type provided")
14 | }
15 | _mutableList.add(array as ReadableNativeArray?)
16 | }
17 |
18 | override fun pushBoolean(value: Boolean) {
19 | _mutableList.add(value)
20 | }
21 |
22 | override fun pushDouble(value: Double) {
23 | _mutableList.add(value)
24 | }
25 |
26 | override fun pushInt(value: Int) {
27 | _mutableList.add(value)
28 | }
29 |
30 | override fun pushLong(value: Long) {
31 | _mutableList.add(value)
32 | }
33 |
34 | override fun pushMap(map: ReadableMap?) {
35 | _mutableList.add(map as ReadableNativeMap?)
36 | }
37 |
38 | override fun pushNull() {
39 | _mutableList.add(null)
40 | }
41 |
42 | override fun pushString(value: String?) {
43 | _mutableList.add(value)
44 | }
45 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/PowerAuthCryptoUtils.ts:
--------------------------------------------------------------------------------
1 | import {NativeWrapper} from "./internal/NativeWrapper";
2 | import {NativeCryptoUtils} from "./internal/NativeCryptoUtils";
3 |
4 | /**
5 | * Typealias for Base64 encoded string.
6 | * This type emphasizes the fact that we expect Base64 encoded string.
7 | */
8 | export type Base64String = string;
9 |
10 | export class PowerAuthCryptoUtils {
11 |
12 | /**
13 | * Hashes given data using SHA-256 algorithm.
14 | * @param data String data encoded in Base64 format.
15 | * @returns Hashed data in Base64 format
16 | * @throws `PowerAuthErrorCode.WRONG_PARAMETER` if data is not Base64 encoded.
17 | */
18 | static async hashSha256(data: Base64String): Promise {
19 | try {
20 | return await NativeCryptoUtils.hashSha256(data);
21 | } catch (error) {
22 | throw NativeWrapper.processException(error)
23 | }
24 | }
25 |
26 | /**
27 | * Generates random bytes.
28 | * @param length Number of bytes to generate.
29 | * @returns Random bytes in Base64 format.
30 | */
31 | static async randomBytes(length: number): Promise {
32 | try {
33 | return await NativeCryptoUtils.randomBytes(length);
34 | } catch (error) {
35 | throw NativeWrapper.processException(error)
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/NativePassphraseMeter.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { PinTestResult } from '../index'
18 | import { NativeModulesProvider } from './NativeModulesProvider';
19 | import { PowerAuthRawPasswordType } from '../model/PowerAuthNativeTypes';
20 | /**
21 | * Password interface implemented in the native code.
22 | */
23 | export interface PowerAuthPassphraseMeterIfc {
24 | /**
25 | * Test strength of PIN.
26 | * @param pin PIN to test.
27 | * @returns `PinTestResult` object.
28 | * @throws `PowerAuthErrorCode.WRONG_PARAM` if PIN contains other characters than digits or length is less than 4.
29 | */
30 | testPin(pin: PowerAuthRawPasswordType): Promise
31 | }
32 |
33 | export const NativePassphraseMeter = NativeModulesProvider.PowerAuthPassphraseMeter;
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/NativeModulesProvider.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { NativeModules } from "react-native";
18 | import { NativeModulesProviderIfc } from "./NativeModulesProviderIfc";
19 | import { NativePowerAuth } from "./NativePowerAuth";
20 |
21 | class Provider implements NativeModulesProviderIfc {
22 | PowerAuthObjectRegister = NativeModules.PowerAuthObjectRegister;
23 | PowerAuthEncryptor = NativeModules.PowerAuthEncryptor
24 | PowerAuthPassphraseMeter = NativeModules.PowerAuthPassphraseMeter
25 | PowerAuthPassword = NativeModules.PowerAuthPassword
26 | PowerAuthCryptoUtils = NativeModules.PowerAuthCryptoUtils
27 | PowerAuthStorageUtils = NativeModules.PowerAuthStorageUtils
28 | PowerAuth = new NativePowerAuth()
29 | }
30 |
31 | export const NativeModulesProvider = new Provider() as NativeModulesProviderIfc
--------------------------------------------------------------------------------
/testapp/_tests/PowerAuth_KDF.test.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { expect } from "../src/testbed";
18 | import { TestWithActivation } from "./helpers/TestWithActivation";
19 |
20 | export class PowerAuth_KDFTests extends TestWithActivation {
21 | async testFetchEncryptionKey() {
22 | const key1a = await this.sdk.fetchEncryptionKey(this.credentials.knowledge, 1000)
23 | expect(key1a).toBeDefined()
24 | const key1b = await this.sdk.fetchEncryptionKey(this.credentials.knowledge, 1000)
25 | expect(key1b).toBe(key1a)
26 |
27 | const key2a = await this.sdk.fetchEncryptionKey(this.credentials.knowledge, 1001)
28 | expect(key2a).toBeDefined()
29 | const key2b = await this.sdk.fetchEncryptionKey(this.credentials.knowledge, 1001)
30 | expect(key2a).toBe(key2b)
31 |
32 | expect(key1a).toNotBe(key2a)
33 | }
34 | }
--------------------------------------------------------------------------------
/testapp/_tests/testbed/CustomInteraction.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { TestContext, UserInteraction, UserPromptDuration } from "../../src/testbed";
18 |
19 | export interface PromptWithDuration {
20 | prompt: string
21 | duration: UserPromptDuration | "CUSTOM"
22 | }
23 |
24 | export class CustomInteraction implements UserInteraction {
25 | promptList: PromptWithDuration[] = []
26 |
27 | reset() {
28 | this.promptList = []
29 | }
30 |
31 | showPrompt(context: TestContext, message: string, duration: UserPromptDuration): Promise {
32 | this.promptList.push({prompt: message, duration: duration})
33 | return Promise.resolve()
34 | }
35 |
36 | sleepWithProgress(context: TestContext, durationMs: number): Promise {
37 | this.promptList.push({prompt: `Sleep for ${durationMs} ms`, duration: "CUSTOM" })
38 | return Promise.resolve()
39 | }
40 | }
--------------------------------------------------------------------------------
/docs/Secure-Vault.md:
--------------------------------------------------------------------------------
1 | # Secure Vault
2 |
3 | PowerAuth SDK has basic support for an encrypted secure vault. At this moment, the only supported method allows your application to establish an encryption / decryption key with a given index. The index represents a "key number" - your identifier for a given key. Different business logic purposes should have encryption keys with a different index value.
4 |
5 | On a server-side, all secure vault-related work is concentrated in a `/pa/v3/vault/unlock` endpoint of PowerAuth Standard RESTful API. In order to receive data from this response, the call must be authenticated with at least 2FA (using password or PIN).
6 |
7 |
8 | The secure vault mechanism does not support biometry by default. Use PIN code or password-based authentication for unlocking the secure vault, or ask your server developers to enable biometry for vault unlock call by configuring PowerAuth Server instance.
9 |
10 |
11 | ## Obtaining Encryption Key
12 |
13 | In order to obtain an encryption key with a given index, use the following code:
14 |
15 | ```javascript
16 | // 2FA signature. It uses device-related key and user PIN code.
17 | const auth = PowerAuthAuthentication.password("1234");
18 |
19 | // Select custom key index
20 | const index = 1000;
21 |
22 | try {
23 | // Fetch encryption key with given index
24 | const r = await powerAuth.fetchEncryptionKey(auth, index);
25 | // ... use encryption key to encrypt or decrypt data
26 | } catch (e) {
27 | // Report error
28 | }
29 | ```
30 |
31 | ## Read Next
32 |
33 | - [Recovery Codes](Recovery-Codes.md)
34 |
--------------------------------------------------------------------------------
/.deploy/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-powerauth-mobile-sdk",
3 | "title": "PowerAuth SDK for React Native Mobile Apps",
4 | "version": "%DEPLOY_VERSION%",
5 | "description": "Wultra PowerAuth Mobile SDK React Native component for iOS and Android",
6 | "main": "lib/index.js",
7 | "types": "lib/index.d.ts",
8 | "source": "src/index",
9 | "files": [
10 | "README.md",
11 | "android/src/main/AndroidManifest.xml",
12 | "android/src/main/java/com/wultra/android/powerauth/reactnative/*.java",
13 | "android/build.gradle",
14 | "lib/*.*",
15 | "lib/internal/*.js",
16 | "lib/model/*.*",
17 | "lib/debug/*.*",
18 | "ios/PowerAuth.xcodeproj/project.pbxproj",
19 | "ios/PowerAuth/*.m",
20 | "ios/PowerAuth/*.c",
21 | "ios/PowerAuth/*.h",
22 | "react-native-powerauth-mobile-sdk.podspec"
23 | ],
24 | "scripts": {
25 | "prepare": "tsc"
26 | },
27 | "homepage": "https://www.wultra.com/mobile-security-suite",
28 | "repository": {
29 | "type": "git",
30 | "url": "https://github.com/wultra/react-native-powerauth-mobile-sdk.git"
31 | },
32 | "keywords": [
33 | "react-native",
34 | "powerauth",
35 | "security"
36 | ],
37 | "author": {
38 | "name": "Wultra s.r.o.",
39 | "email": "support@wultra.com"
40 | },
41 | "license": "Apache 2.0",
42 | "licenseFilename": "LICENSE",
43 | "readmeFilename": "README.md",
44 | "dependencies": {
45 | "node-fetch": ">=2.6.1"
46 | },
47 | "peerDependencies": {
48 | "react-native": "*"
49 | },
50 | "devDependencies": {
51 | "lodash": "^4.17.21",
52 | "react-native": "^0.73.4"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthActivationStatus.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { PowerAuthActivationState } from './PowerAuthActivationState';
18 |
19 | /**
20 | * The `PowerAuthActivationStatus` object represents complete status of the activation.
21 | */
22 | export interface PowerAuthActivationStatus {
23 | /**
24 | * State of the activation.
25 | */
26 | state: PowerAuthActivationState
27 | /**
28 | * Number of failed authentication attempts in a row.
29 | */
30 | failCount: number
31 | /**
32 | * Maximum number of allowed failed authentication attempts in a row.
33 | */
34 | maxFailCount: number
35 | /**
36 | * Contains `(maxFailCount - failCount)` if state is `ACTIVE`, otherwise 0.
37 | */
38 | remainingAttempts: number
39 | /**
40 | * Contains custom object returned from the server. The value is optional and PowerAuth Application Server must support this custom object.
41 | */
42 | customObject?: any
43 | }
44 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/LiftPowerAuthSdk.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import
18 | #import
19 | #import
20 |
21 | #ifdef __cplusplus
22 | // C++
23 | #define PA_EXTERN_C extern "C"
24 | #define PA_EXTERN_C_BEGIN extern "C" {
25 | #define PA_EXTERN_C_END }
26 | #else
27 | // C
28 | #define PA_EXTERN_C extern
29 | #define PA_EXTERN_C_BEGIN
30 | #define PA_EXTERN_C_END
31 | #endif
32 |
33 | /// Function that lifts PowerAuthSDK instance from the React-Native module if present (configured). If the object is not available, returns nil.
34 | /// @param instanceId Id of the instance that was configured from the JS/TS layer.
35 | /// @param bridge React bridge reference obtained from your ReactNative module or app.
36 | /// @return Native PowerAuthSDK or nil if such instance is not configured.
37 | PA_EXTERN_C PowerAuthSDK * LiftPowerAuthSdk(NSString * instanceId, RCTBridge * bridge);
38 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthExternalPendingOperation.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * ### iOS specific
19 | *
20 | * The `PowerAuthExternalPendingOperationType` defines types of operation
21 | * started in another application that share activation data.
22 | */
23 | export type PowerAuthExternalPendingOperationType = "ACTIVATION" | "PROTOCOL_UPGRADE"
24 |
25 | /**
26 | * ### iOS specific
27 | *
28 | * The `PowerAuthExternalPendingOperation` interface contains data that can identify an external
29 | * application that started the critical operation.
30 | */
31 | export interface PowerAuthExternalPendingOperation {
32 | /**
33 | * Type of operation running in another application.
34 | */
35 | externalOperationType: PowerAuthExternalPendingOperationType
36 | /**
37 | * Identifier of external application that started the operation. This is the same identifier
38 | * you provided to `PowerAuthSharingConfiguration` during the PowerAuth initialization.
39 | */
40 | externalApplicationId: string
41 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthActivationState.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * The `PowerAuthActivationState` enum defines all possible states of activation.
19 | * The state is a part of information received together with the rest
20 | * of the `PowerAuthActivationStatus` object.
21 | */
22 | export enum PowerAuthActivationState {
23 | /**
24 | * The activation is just created.
25 | */
26 | CREATED = "CREATED",
27 | /**
28 | * The activation is not completed yet on the server.
29 | */
30 | PENDING_COMMIT = "PENDING_COMMIT",
31 | /**
32 | * The shared secure context is valid and active.
33 | */
34 | ACTIVE = "ACTIVE",
35 | /**
36 | * The activation is blocked.
37 | */
38 | BLOCKED = "BLOCKED",
39 | /**
40 | * The activation doesn't exist anymore.
41 | */
42 | REMOVED = "REMOVED",
43 | /**
44 | * The activation is technically blocked. You cannot use it anymore
45 | * for the signature calculations.
46 | */
47 | DEADLOCK = "DEADLOCK"
48 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/internal/NativeModulesProviderIfc.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { NativeObjectRegisterIfc } from "../debug/NativeObjectRegisterIfc";
18 | import { PowerAuthEncryptorIfc } from "./NativeEncryptor";
19 | import { PowerAuthNativeObject } from "../model/PowerAuthNativeObject";
20 | import { PowerAuthPassphraseMeterIfc } from "./NativePassphraseMeter";
21 | import { PowerAuthPasswordIfc } from "./NativePassword";
22 | import { NativePowerAuthIfc } from "./NativePowerAuthIfc";
23 | import { PowerAuthCryptoUtilsIfc } from "./NativeCryptoUtils";
24 | import { PowerAuthStorageUtilsIfc } from "./NativeStorageUtils";
25 |
26 |
27 | export interface NativeModulesProviderIfc {
28 | PowerAuthObjectRegister: NativeObjectRegisterIfc & PowerAuthNativeObject;
29 | PowerAuthEncryptor: PowerAuthEncryptorIfc;
30 | PowerAuthPassphraseMeter: PowerAuthPassphraseMeterIfc;
31 | PowerAuthPassword: PowerAuthPasswordIfc;
32 | PowerAuthCryptoUtils: PowerAuthCryptoUtilsIfc;
33 | PowerAuthStorageUtils: PowerAuthStorageUtilsIfc;
34 | PowerAuth: NativePowerAuthIfc;
35 | }
--------------------------------------------------------------------------------
/docs/Installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | - [Installation for React-Native](#react-native-installation)
4 | - [Installation for Cordova](#cordova-installation)
5 |
6 | ## React-Native Installation
7 |
8 | ### Supported Platforms
9 |
10 | The library is available for the following __React Native (0.64.1+)__ platforms:
11 |
12 | - __Android 5.0 (API 21)__ and newer
13 | - __iOS 13.4__ and newer
14 |
15 | ### How To Install
16 |
17 | #### 1. Install the package via npm
18 | ```sh
19 | npm i react-native-powerauth-mobile-sdk --save
20 | ```
21 |
22 | #### 2. Install pods for iOS
23 |
24 | To make integration working with iOS, don't forget to install Pods:
25 |
26 | ```sh
27 | cd ios
28 | pod install
29 | ```
30 |
31 | #### 3. Import PowerAuth in your js/ts files
32 |
33 | ```typescript
34 | import { PowerAuth, PowerAuthAuthentication, PowerAuthError } from 'react-native-powerauth-mobile-sdk';
35 | ```
36 |
37 | ## Cordova Installation
38 |
39 | ### Supported Platforms
40 |
41 | The library is available for the following __Apache Cordova (>=12.0.0)__ platforms:
42 |
43 | - __Android 7.0 (API 24)__ and newer (cordova-android version >=12.0.0)
44 | - __iOS 11.0__ and newer (cordova-ios version >=7.0.0)
45 |
46 | ### How To Install
47 |
48 | #### 1. Install the plugin via the cordova plugin installer
49 | ```sh
50 | cordova plugin add cordova-powerauth-mobile-sdk
51 | ```
52 |
53 | #### 2. Install pods for iOS (if needed)
54 |
55 | To make integration working with iOS, you might need to install Pods:
56 |
57 | ```sh
58 | cd platforms/ios
59 | pod install
60 | ```
61 |
62 | #### 3. Start using PowerAuth classes
63 |
64 | ```typescript
65 | const powerAuth = new PowerAuth("my-test-instance");
66 | ```
67 |
68 | ## Read Next
69 |
70 | - [Configuration](./Configuration.md)
71 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/Constants.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "Utilities.h"
18 |
19 | /// Time interval in milliseconds to keep pre-authorized biometric
20 | /// key in memory.
21 | #define BIOMETRY_KEY_KEEP_ALIVE_TIME 10000
22 |
23 | /// Time interval in milliseconds to keep password object valid
24 | /// in memory.
25 | #define PASSWORD_KEY_KEEP_ALIVE_TIME (5 * 60 * 1000)
26 |
27 | /// Time interval in milliseconds to keep encryptor object alive in memory
28 | #define ENCRYPTOR_KEEP_ALIVE_TIME (5 * 60 * 1000)
29 | /// Time interval in milliseconds to keep decryptor object alive in memory
30 | #define DECRYPTOR_KEEP_ALIVE_TIME (5 * 60 * 1000)
31 |
32 | /// Upper limit for Unicode Code Point
33 | #define CODEPOINT_MAX 0x10FFFF
34 |
35 | /// Default period in milliseconds for automatic objects cleanup job.
36 | #define CLEANUP_PERIOD_DEFAULT 10000
37 | /// Minimum allowed period for automatic objects cleanup job.
38 | #define CLEANUP_PERIOD_MIN 100
39 | /// Maximum allowed period for automatic objects cleanup job.
40 | #define CLEANUP_PERIOD_MAX 60000
41 |
--------------------------------------------------------------------------------
/testapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "testapp",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "android": "yarn dlx react-native run-android",
7 | "ios": "yarn dlx react-native run-ios",
8 | "start": "yarn dlx react-native start",
9 | "pods": "(cd ios && yarn dlx pod-install --non-interactive)",
10 | "buildAndroid": "(cd android && ./gradlew assemble)",
11 | "buildIos": "yarn pods && (cd ios && xcodebuild archive -workspace testapp.xcworkspace -scheme testapp -sdk iphoneos CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_ALLOWED=NO)",
12 | "freshAndroid": "yarn android",
13 | "freshIos": "yarn pods && yarn ios",
14 | "lint": "eslint .",
15 | "format": "prettier -w ."
16 | },
17 | "dependencies": {
18 | "react": "19.0.0",
19 | "react-native": "0.78.0",
20 | "react-native-config": "1.5.5",
21 | "react-native-powerauth-mobile-sdk": "workspace:*"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.25.2",
25 | "@babel/preset-env": "^7.25.3",
26 | "@babel/runtime": "^7.25.0",
27 | "@react-native-community/cli": "15.0.1",
28 | "@react-native-community/cli-platform-android": "15.0.1",
29 | "@react-native-community/cli-platform-ios": "15.0.1",
30 | "@react-native/babel-preset": "0.78.0",
31 | "@react-native/eslint-config": "0.78.0",
32 | "@react-native/metro-config": "0.78.0",
33 | "@react-native/typescript-config": "0.78.0",
34 | "@types/react": "^19.0.0",
35 | "@types/react-test-renderer": "^19.0.0",
36 | "@typescript-eslint/eslint-plugin": "^7.0.0",
37 | "@typescript-eslint/parser": "^7.0.0",
38 | "eslint": "^8.57.0",
39 | "prettier": "^3.3.3",
40 | "react-test-renderer": "19.0.0",
41 | "typescript": "5.0.4"
42 | },
43 | "engines": {
44 | "node": ">=18"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-powerauth-mobile-sdk",
3 | "title": "PowerAuth Mobile JS SDK for Cordova Mobile Apps",
4 | "version": "",
5 | "description": "Wultra PowerAuth Mobile JS SDK for Cordova (iOS and Android)",
6 | "types": "typings.d.ts",
7 | "files": [
8 | "README.md",
9 | "android/src/main/AndroidManifest.xml",
10 | "android/src/main/java/com/wultra/android/powerauth/cdv/*",
11 | "android/src/main/java/com/wultra/android/powerauth/bridge/*",
12 | "android/src/main/java/com/wultra/android/powerauth/js/*",
13 | "android/build.gradle",
14 | "lib/*",
15 | "ios/PowerAuth.xcodeproj/project.pbxproj",
16 | "ios/PowerAuth/Info.plist",
17 | "ios/PowerAuth/*.m",
18 | "ios/PowerAuth/*.mm",
19 | "ios/PowerAuth/*.c",
20 | "ios/PowerAuth/*.h",
21 | "plugin.xml",
22 | "typings.d.ts"
23 | ],
24 | "homepage": "https://www.wultra.com/mobile-security-suite",
25 | "repository": {
26 | "type": "git",
27 | "url": "https://github.com/wultra/react-native-powerauth-mobile-sdk.git"
28 | },
29 | "keywords": [
30 | "cordova",
31 | "powerauth",
32 | "security"
33 | ],
34 | "author": {
35 | "name": "Wultra s.r.o.",
36 | "email": "support@wultra.com"
37 | },
38 | "license": "Apache 2.0",
39 | "licenseFilename": "LICENSE",
40 | "readmeFilename": "README.md",
41 | "scripts": {
42 | "cdv": "gulp cdv"
43 | },
44 | "devDependencies": {
45 | "esbuild": "^0.25.12",
46 | "gulp": "^5.0.0",
47 | "gulp-concat": "^2.6.1",
48 | "gulp-filter": "^9.0.1",
49 | "gulp-replace": "^1.1.4",
50 | "gulp-strip-import-export": "^1.0.0",
51 | "gulp-typescript": "^6.0.0-alpha.1",
52 | "rimraf": "^6.0.1",
53 | "typescript": "^5.4.0"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/testapp/src/testbed/private/ObjectHelper.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | /**
18 | * Populate all method names defined in the provided object.
19 | * @param obj Input object.
20 | * @returns List of method names implemented in the object.
21 | */
22 | export function getAllObjectMethods(obj: any) {
23 | let props: string[] = [];
24 | let parent: any;
25 | // Walk over the prototype chain, ignore `Object` methods (e.g. there's no parent prototype)
26 | while (obj && (parent = Object.getPrototypeOf(obj))) {
27 | // get all descriptors at once
28 | const allDescs = Object.getOwnPropertyDescriptors(obj);
29 | for (const prop in allDescs) {
30 | // Functions are writable unlike the getters. If we don't test for `writable`, then the next `obj[prop]`
31 | // statement will access the value of property via the getter function. In other words, it call the
32 | // getter function and that's not we want.
33 | if (allDescs[prop].writable === true && typeof obj[prop] === 'function' && prop !== 'constructor') {
34 | props.push(prop);
35 | }
36 | }
37 | obj = parent;
38 | }
39 | return props;
40 | }
41 |
--------------------------------------------------------------------------------
/testapp-cordova/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PowerAuthTest
4 | PowerAuth tests Cordova App
5 |
6 | Wultra
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/docs/Crypto-Utilities.md:
--------------------------------------------------------------------------------
1 | # Crypto Utilities
2 |
3 | The PowerAuth Mobile JS SDK offers additional crypto functions. These utilities are available through the `PowerAuthCryptoUtils` class.
4 |
5 | ## Available Methods
6 |
7 | ### hashSha256(data: string)
8 |
9 | Calculates SHA256 hash of a parameter encoded as Base64 string.
10 |
11 | **Usage:**
12 |
13 | ```typescript
14 | import { PowerAuthCryptoUtils } from 'react-native-powerauth-mobile-sdk';
15 |
16 | async function hashSha256(data: string) {
17 | try {
18 | const base64 = btoa(unescape(encodeURIComponent(data)));
19 | const hash = await PowerAuthCryptoUtils.hashSha256(base64);
20 | // use hash
21 | } catch (error) {
22 | console.error('Failed to calculate SHA256 hash:', error);
23 | }
24 | }
25 | ```
26 |
27 | **Response:**
28 | The method returns a Base64 encoded string with SHA256 hash of input parameter.
29 |
30 | ### randomBytes(length: number)
31 |
32 | Returns a random byte array of specified length encoded as Base64 string.
33 |
34 | **Usage:**
35 |
36 | ```typescript
37 | import { PowerAuthCryptoUtils } from 'react-native-powerauth-mobile-sdk';
38 |
39 | async function randomBytes(length: number) {
40 | try {
41 | const randomBase64 = await PowerAuthCryptoUtils.randomBytes(length);
42 | const randomBytes = Uint8Array.from(atob(randomBase64), c => c.charCodeAt(0));
43 | // use random bytes
44 | } catch (error) {
45 | console.error('Failed to get random bytes:', error);
46 | }
47 | }
48 | ```
49 |
50 | **Response:**
51 |
52 | The method returns random bytes array encoded as Base64 string. In order to use the bytes, you need to convert the Base64 string to Uint8Array. (see provided sample code)
53 |
54 | ## Read Next
55 |
56 | - [Accessing the Native PowerAuthSDK](Accessing-Native-PowerAuthSDK.md)
57 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/PowerAuthPassphraseMeterModule.kt:
--------------------------------------------------------------------------------
1 |
2 | package com.wultra.android.powerauth.cordova.plugin
3 |
4 | import com.wultra.android.powerauth.bridge.getDynamic
5 | import com.wultra.android.powerauth.js.PowerAuthPassphraseMeterJsModule
6 | import com.wultra.android.powerauth.cdv.util.Promise
7 | import org.apache.cordova.CallbackContext
8 | import org.apache.cordova.CordovaInterface
9 | import org.apache.cordova.CordovaPlugin
10 | import org.apache.cordova.CordovaWebView
11 | import org.json.JSONArray
12 | import org.json.JSONException
13 |
14 | class PowerAuthPassphraseMeterModule : CordovaPlugin() {
15 |
16 | internal lateinit var powerAuthPassphraseMeterJsModule: PowerAuthPassphraseMeterJsModule
17 |
18 | override fun initialize(cordova: CordovaInterface, webView: CordovaWebView) {
19 | super.initialize(cordova, webView);
20 | val powerAuthPasswordModule = webView.pluginManager.getPlugin("PowerAuthPasswordModule") as PowerAuthPasswordModule
21 | powerAuthPassphraseMeterJsModule = PowerAuthPassphraseMeterJsModule(powerAuthPasswordModule.powerAuthPasswordJsModule)
22 | }
23 |
24 | @Throws(JSONException::class)
25 | override fun execute(action: String, args: JSONArray, callbackContext: CallbackContext): Boolean {
26 | val promise = Promise(callbackContext)
27 | when (action) {
28 | "testPin" -> {
29 | testPin(args, promise)
30 | return true
31 | }
32 | }
33 | return false // Returning false results in a "MethodNotFound" error.
34 | }
35 |
36 | private fun testPin(args: JSONArray, promise: Promise) {
37 | val password = args.getDynamic(0)
38 | powerAuthPassphraseMeterJsModule.testPin(password, promise);
39 | }
40 | }
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/NativeDynamic.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | import org.json.JSONArray
4 | import org.json.JSONObject
5 |
6 |
7 | /**
8 | * Implementation of dynamic type.
9 | */
10 | class NativeDynamic(val data: Any?) : Dynamic {
11 |
12 | private val resolvedType: ReadableType = when (data) {
13 | null -> ReadableType.Null
14 | is Boolean -> ReadableType.Boolean
15 | is Int -> ReadableType.Number
16 | is Double -> ReadableType.Number
17 | is String -> ReadableType.String
18 | is JSONArray -> ReadableType.Array
19 | is JSONObject -> ReadableType.Map
20 | is HashMap<*,*> -> ReadableType.Map
21 | else -> throw IllegalArgumentException("Unknown dynamic type ${data::class}")
22 | }
23 |
24 | override val type: ReadableType
25 | get() = resolvedType
26 |
27 | override val isNull: Boolean
28 | get() = false
29 |
30 | override fun asArray(): ReadableArray {
31 | return ReadableNativeArray(data as JSONArray)
32 | }
33 |
34 | override fun asBoolean(): Boolean {
35 | return data as Boolean
36 | }
37 |
38 | override fun asDouble(): Double {
39 | return data as Double
40 | }
41 |
42 | override fun asInt(): Int {
43 | return data as Int
44 | }
45 |
46 | override fun asMap(): ReadableMap {
47 | if (data is JSONObject) {
48 | return ReadableNativeMap(data)
49 | } else {
50 | @Suppress("UNCHECKED_CAST")
51 | return ReadableNativeMap(data as Map)
52 | }
53 | }
54 |
55 | override fun asString(): String {
56 | return data as String
57 | }
58 |
59 | override fun recycle() {
60 | // no op
61 | }
62 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/react-native-powerauth-mobile-sdk.podspec:
--------------------------------------------------------------------------------
1 | require "json"
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4 | folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
5 |
6 | Pod::Spec.new do |s|
7 | s.name = package["name"]
8 | s.version = package["version"]
9 | s.summary = package["description"]
10 | s.homepage = package["homepage"]
11 | s.license = package["license "]
12 | s.authors = { package["author"]["name"] => package["author"]["email"] }
13 | s.platforms = { :ios => "13.4" }
14 | s.source = { :git => "https://github.com/wultra/react-native-powerauth-mobile-sdk.git", :tag => "#{s.version}" }
15 |
16 | s.source_files = "ios/PowerAuth/*.{h,m,c}"
17 | s.requires_arc = true
18 |
19 | s.dependency "PowerAuth2", "~> 1.9.5"
20 |
21 | # For RN > 0.74, this automatically resolves the architecture AND interop layer deps.
22 | if respond_to?(:install_modules_dependencies, true)
23 | install_modules_dependencies(s)
24 | else
25 | s.dependency "React-Core"
26 |
27 | # Don't install the dependencies when we run `pod install` in the old architecture.
28 | if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
29 | s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
30 | s.pod_target_xcconfig = {
31 | "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
32 | "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
33 | "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
34 | }
35 | s.dependency "React-Codegen"
36 | s.dependency "RCT-Folly"
37 | s.dependency "RCTRequired"
38 | s.dependency "RCTTypeSafety"
39 | s.dependency "ReactCommon/turbomodule/core"
40 | end
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/testapp/android/app/src/main/java/com/testapp/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package com.testapp
2 |
3 | import android.app.Application
4 | import com.facebook.react.PackageList
5 | import com.facebook.react.ReactApplication
6 | import com.facebook.react.ReactHost
7 | import com.facebook.react.ReactNativeHost
8 | import com.facebook.react.ReactPackage
9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
11 | import com.facebook.react.defaults.DefaultReactNativeHost
12 | import com.facebook.react.soloader.OpenSourceMergedSoMapping
13 | import com.facebook.soloader.SoLoader
14 |
15 | class MainApplication : Application(), ReactApplication {
16 |
17 | override val reactNativeHost: ReactNativeHost =
18 | object : DefaultReactNativeHost(this) {
19 | override fun getPackages(): List =
20 | PackageList(this).packages.apply {
21 | // Packages that cannot be autolinked yet can be added manually here, for example:
22 | // add(MyReactNativePackage())
23 | }
24 |
25 | override fun getJSMainModuleName(): String = "index"
26 |
27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
28 |
29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
31 | }
32 |
33 | override val reactHost: ReactHost
34 | get() = getDefaultReactHost(applicationContext, reactNativeHost)
35 |
36 | override fun onCreate() {
37 | super.onCreate()
38 | SoLoader.init(this, OpenSourceMergedSoMapping)
39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
40 | // If you opted-in for the New Architecture, we load the native entry point for this app.
41 | load()
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthCreateActivationResult.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import {PowerAuthRecoveryActivationData} from "./PowerAuthRecoveryActivationData";
18 | import {PowerAuthUserInfo} from "./PowerAuthUserInfo";
19 |
20 | /**
21 | * Success object returned by the "createActivation" call.
22 | */
23 | export interface PowerAuthCreateActivationResult {
24 | /**
25 | * Decimalized fingerprint calculated from device's and server's public keys.
26 | */
27 | activationFingerprint: string
28 | /**
29 | * If supported and enabled on the server, then the object contains "Recovery Code" and PUK,
30 | * created for this particular activation. Your application should display that value to the user
31 | * and forget the values immediately. You should NEVER store values from the object persistently
32 | * on the device.
33 | */
34 | activationRecovery?: PowerAuthRecoveryActivationData
35 | /**
36 | * When available, the contents of this object depend on your enrollment server configuration.
37 | */
38 | customAttributes?: any
39 |
40 | /**
41 | * When available, contains user information claims like name, email, address, etc.
42 | */
43 | userInfo?: PowerAuthUserInfo
44 | }
--------------------------------------------------------------------------------
/testapp/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Use this property to specify which architecture you want to build.
26 | # You can also override it from the CLI using
27 | # ./gradlew -PreactNativeArchitectures=x86_64
28 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
29 |
30 | # Use this property to enable support to the new architecture.
31 | # This will allow you to use TurboModules and the Fabric render in
32 | # your application. You should enable this flag either if you want
33 | # to write custom TurboModules/Fabric components OR use libraries that
34 | # are providing them.
35 | newArchEnabled=true
36 |
37 | # Use this property to enable or disable the Hermes JS engine.
38 | # If set to false, you will be using JSC instead.
39 | hermesEnabled=true
40 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/PowerAuthCryptoUtilsModule.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cordova.plugin
2 |
3 | import com.wultra.android.powerauth.cdv.util.Promise
4 | import com.wultra.android.powerauth.js.PowerAuthCryptoUtilsJsModule
5 | import org.apache.cordova.CallbackContext
6 | import org.apache.cordova.CordovaInterface
7 | import org.apache.cordova.CordovaPlugin
8 | import org.apache.cordova.CordovaWebView
9 | import org.json.JSONArray
10 | import org.json.JSONException
11 |
12 | class PowerAuthCryptoUtilsModule : CordovaPlugin() {
13 |
14 | private lateinit var powerAuthCryptoUtilsJsModule: PowerAuthCryptoUtilsJsModule
15 |
16 | override fun initialize(cordova: CordovaInterface, webView: CordovaWebView) {
17 | super.initialize(cordova, webView)
18 | powerAuthCryptoUtilsJsModule = PowerAuthCryptoUtilsJsModule()
19 | }
20 |
21 | @Throws(JSONException::class)
22 | override fun execute(action: String, args: JSONArray, callbackContext: CallbackContext): Boolean {
23 | val promise = Promise(callbackContext)
24 | when (action) {
25 | "hashSha256" -> {
26 | hashSha256(args, promise)
27 | return true
28 | }
29 | "randomBytes" -> {
30 | randomBytes(args, promise)
31 | return true
32 | }
33 | }
34 | return false // Returning false results in a "MethodNotFound" error.
35 | }
36 |
37 | private fun hashSha256(args: JSONArray, promise: Promise) {
38 | val base64Input = args.getString(0)
39 | powerAuthCryptoUtilsJsModule.hashSha256(base64Input, promise)
40 | }
41 |
42 | private fun randomBytes(args: JSONArray, promise: Promise) {
43 | val length = args.getInt(0)
44 | powerAuthCryptoUtilsJsModule.randomBytes(length, promise)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/testapp/ios/testapp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | testapp
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(CURRENT_PROJECT_VERSION)
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSExceptionDomains
30 |
31 | localhost
32 |
33 | NSExceptionAllowsInsecureHTTPLoads
34 |
35 |
36 |
37 | NSFaceIDUsageDescription
38 | Using FaceID for the testing purposes
39 | NSLocationWhenInUseUsageDescription
40 |
41 | UILaunchStoryboardName
42 | LaunchScreen
43 | UIRequiredDeviceCapabilities
44 |
45 | arm64
46 |
47 | UISupportedInterfaceOrientations
48 |
49 | UIInterfaceOrientationPortrait
50 | UIInterfaceOrientationLandscapeLeft
51 | UIInterfaceOrientationLandscapeRight
52 |
53 | UIViewControllerBasedStatusBarAppearance
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/reactnative/PowerAuthReactPackage.java:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.reactnative;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import com.facebook.react.ReactPackage;
6 | import com.facebook.react.bridge.NativeModule;
7 | import com.facebook.react.bridge.ReactApplicationContext;
8 | import com.facebook.react.uimanager.ViewManager;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Collections;
12 | import java.util.List;
13 |
14 | @SuppressWarnings("unused")
15 | public class PowerAuthReactPackage implements ReactPackage {
16 |
17 | @NonNull
18 | @Override
19 | public List createViewManagers(@NonNull ReactApplicationContext reactContext) {
20 | return Collections.emptyList();
21 | }
22 |
23 | @NonNull
24 | @Override
25 | public List createNativeModules(@NonNull ReactApplicationContext reactContext) {
26 | // Object register
27 | final ObjectRegister objectRegister = new ObjectRegister(reactContext);
28 | // Password module
29 | final PowerAuthPasswordModule passwordModule = new PowerAuthPasswordModule(objectRegister);
30 | // Encryptor module
31 | final PowerAuthEncryptorModule encryptorModule = new PowerAuthEncryptorModule(reactContext, objectRegister);
32 | // Create a list of modules
33 | final List modules = new ArrayList<>();
34 | modules.add(objectRegister);
35 | modules.add(passwordModule);
36 | modules.add(encryptorModule);
37 | modules.add(new PowerAuthModule(reactContext, objectRegister, passwordModule));
38 | modules.add(new PowerAuthPassphraseMeterModule(passwordModule));
39 | modules.add(new PowerAuthCryptoUtilsModule());
40 | modules.add(new PowerAuthStorageUtilsModule(reactContext));
41 | return modules;
42 | }
43 | }
--------------------------------------------------------------------------------
/testapp/_tests/PowerAuth_TimeSync.test.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { expect } from "../src/testbed";
18 | import { TestWithActivation } from "./helpers/TestWithActivation";
19 |
20 | export class PowerAuth_TimeSyncTests extends TestWithActivation {
21 |
22 | async testTimeSynchronization() {
23 | // time is synchronized during the activation
24 | expect(await this.sdk.timeSynchronizationService.isTimeSynchronized()).toBe(true)
25 |
26 | // desynchronize time
27 | expect(await this.sdk.timeSynchronizationService.resetTimeSynchronization()).toSucceed()
28 | expect(await this.sdk.timeSynchronizationService.isTimeSynchronized()).toBe(false)
29 |
30 | // sync again
31 | expect(await this.sdk.timeSynchronizationService.synchronizeTime()).toSucceed()
32 | expect(await this.sdk.timeSynchronizationService.isTimeSynchronized()).toBe(true)
33 |
34 | const timestamp = await this.sdk.timeSynchronizationService.currentTime()
35 |
36 | // just check if actual non-zero values are returned
37 | expect(timestamp).toNotBe(0)
38 | expect(await this.sdk.timeSynchronizationService.localTimeAdjustmentPrecision()).toNotBe(0)
39 |
40 | const date = new Date(timestamp)
41 | expect(date.getTime()).toBe(timestamp)
42 | }
43 | }
--------------------------------------------------------------------------------
/testapp/src/testbed/private/ErrorHelper.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { PowerAuthError } from "react-native-powerauth-mobile-sdk";
18 |
19 | /**
20 | * Function translate an error object into string.
21 | * @param error Error to describe.
22 | * @param curlyBrackets If true, then the description is wrapped into curly brackets.
23 | * @returns String description from given error.
24 | */
25 | export function describeError(error: any, curlyBrackets: boolean = false): string {
26 | if (error instanceof PowerAuthError) {
27 | const components: string[] = []
28 | if (error.code) components.push(error.code)
29 | if (error.message) components.push(error.message)
30 | if (error.errorData) components.push(`data=${JSON.stringify(error.errorData)}`)
31 | if (error.originalException) components.push(`reason=${describeError(error.originalException, true)}`)
32 | const msg = components.join(': ')
33 | return curlyBrackets ? `{ PowerAuthError: ${msg} }` : `PowerAuthError: ${msg}`
34 | } else if (error instanceof Error) {
35 | return curlyBrackets ? `{ ${error.name}: ${error.message} }` : `${error.name}: ${error.message}`
36 | } else if (typeof error === 'string') {
37 | return curlyBrackets ? `{ string: '${error}' }` : `'${error}'`
38 | }
39 | return JSON.stringify(error)
40 | }
41 |
--------------------------------------------------------------------------------
/docs/Accessing-Native-PowerAuthSDK.md:
--------------------------------------------------------------------------------
1 | # Accessing the Native PowerAuthSDK
2 |
3 |
4 | __This feature is not available for Cordova.__
5 |
6 |
7 | If you need to access the native PowerAuthSDK object (created in the JS/TS code) from Java/Kotlin or Objective-C/Swift, you can use the following snippets.
8 |
9 |
10 | Consider consultation with our technical support when accessing the native object. This technique should be used rarely and only for limited purposes as it might lead to unexpected behavior.
11 |
12 |
13 | ## iOS
14 |
15 | To access the native `PowerAuthSDK` object on iOS, use the `LiftPowerAuthSdk` helper method.
16 |
17 | ```objc
18 | #import "LiftPowerAuthSdk.h"
19 | #import
20 |
21 | // The `bridge` (of type `RCTBridge`) availability depends on the place, where you're trying to access the PowerAuthSDK object.
22 | // For example, you can access it in the AppDelegate that implements `RCTAppDelegate` or as property of an `RCTBridgeModule`.
23 | PowerAuthSDK * sdk = LiftPowerAuthSdk(@"myPowerauthInstance", bridge);
24 | if (sdk) {
25 | // Do something with the native instance
26 | }
27 | ```
28 |
29 | ## Android
30 |
31 | To access the native `PowerAuthSDK` object on Android, use the `PowerAuthUtils.liftPowerAuthSdk` helper method.
32 |
33 | ```java
34 | import com.wultra.android.powerauth.reactnative.PowerAuthUtils;
35 | import io.getlime.security.powerauth.sdk.PowerAuthSDK;
36 |
37 | // The `reactNativeContext` (of type ReactContext) availability depends on the place, where you're trying to access the PowerAuthSDK object.
38 | // For example, you can pass it when creating our package when implementing `ReactPackage` interface.
39 | PowerAuthSDK sdk = PowerAuthUtils.liftPowerAuthSdk("test", reactNativeContext);
40 | if (sdk != null) {
41 | // Do something with the native instance
42 | }
43 | ```
44 |
45 | ## Read Next
46 |
47 | - [Additional Utilities](Additional-Utilities.md)
48 |
--------------------------------------------------------------------------------
/.prepare-release.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": {
3 | "purpose": "This file is used as a definition file for the prepare-release script.",
4 | "info": "It defines files that contains version number that should be updated during the release preparation.",
5 | "customBuildscript": "If needed, in the library object, set \"buildscript\": \"your-custom-build-command\" command if your build command is different than 'npm i && npm run build'"
6 | },
7 | "library": {
8 | "name": "digital-onboarding-js",
9 | "type": "yarn",
10 | "artifacts": [
11 | "packages/cordova-powerauth-mobile-sdk/build/cdv/cordova-powerauth-mobile-sdk-%VERSION%.tgz",
12 | "packages/react-native-powerauth-mobile-sdk/react-native-powerauth-mobile-sdk-%VERSION%.tgz"
13 | ],
14 | "buildscript": "corepack enable && yarn install && yarn packReactNative && yarn build:cdv"
15 | },
16 | "files": [
17 | {
18 | "description": "React package definition file.",
19 | "path": "packages/react-native-powerauth-mobile-sdk/package.json",
20 | "type": "version_replace",
21 | "match": "\"version\": \"%VERSION%\",\n",
22 | "_comment": "Based on this version, all other versions are derived during the build."
23 | },
24 | {
25 | "description": "Changelog",
26 | "path": "docs/Changelog.md",
27 | "type": "version_verify",
28 | "match": "## %VERSION%"
29 | },
30 | {
31 | "description": "Compatibility in the documentation.",
32 | "path": "docs/Readme.md",
33 | "type": "versionstream_verify",
34 | "match": "| `%VERSION_STREAM%`"
35 | },
36 | {
37 | "description": "Compatibility in the documentation.",
38 | "path": "README.md",
39 | "type": "versionstream_verify",
40 | "match": "| `%VERSION_STREAM%`"
41 | }
42 | ]
43 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/reactnative/PowerAuthUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wultra.android.powerauth.reactnative;
18 |
19 | import androidx.annotation.NonNull;
20 | import androidx.annotation.Nullable;
21 | import com.facebook.react.bridge.ReactContext;
22 | import io.getlime.security.powerauth.sdk.PowerAuthSDK;
23 |
24 | /**
25 | * PowerAuth React-Native Utilities.
26 | * @noinspection unused
27 | */
28 | public class PowerAuthUtils {
29 | /**
30 | * Function that lifts PowerAuthSDK instance from the React-Native module if present (configured). If the object is not available, returns nil.
31 | * Might throw IllegalStateException from the RN layer.
32 | *
33 | * @param instanceId Id of the instance that was configured from the JS/TS layer.
34 | * @param reactContext React context obtained from your ReactNative module or app.
35 | * @return Native PowerAuthSDK or null if such instance is not configured.
36 | */
37 | @Nullable
38 | public static PowerAuthSDK liftPowerAuthSdk(@NonNull String instanceId, @NonNull ReactContext reactContext) {
39 | ObjectRegister module = reactContext.getNativeModule(ObjectRegister.class);
40 | if (module == null) {
41 | return null;
42 | }
43 | return module.findObject(instanceId, PowerAuthSDK.class);
44 | }
45 | }
--------------------------------------------------------------------------------
/testapp/_tests/helpers/PasswordHelper.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { PowerAuth, PowerAuthPassword } from "react-native-powerauth-mobile-sdk";
18 |
19 | /**
20 | * Function creates PowerAuthPassword object and imports provided passphrase from the string.
21 | * In the regular app, you let user to type the password character by character, so don't use such
22 | * function in your application.
23 | * @param password String with password to import.
24 | * @param destroyOnUse Password will be destroyed on use.
25 | * @param owner If provided, then the password will be associated with given PowerAuth instance.
26 | * @param pass If provided, then the string will be imported to this object.
27 | * @returns PowerAuthPassword with imported passphrase.
28 | */
29 | export async function importPassword(password: string, destroyOnUse: boolean = true, owner: PowerAuth | undefined = undefined, pass: PowerAuthPassword | undefined = undefined): Promise {
30 | const p = pass ?? owner?.createPassword(destroyOnUse) ?? new PowerAuthPassword(destroyOnUse)
31 | let pos = 0;
32 | while (pos < password.length) {
33 | const cp = password.codePointAt(pos)
34 | if (cp) {
35 | await p.addCharacter(cp)
36 | pos += String.fromCodePoint(cp).length
37 | } else {
38 | throw new Error('Failed to extract codepoint')
39 | }
40 | }
41 | return p
42 | }
--------------------------------------------------------------------------------
/scripts/prepare-release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e # stop script when error occurs
4 | set -u # stop when undefined variable is used
5 | #set -x # print all execution (good for debugging)
6 |
7 | ######### USAGE #########
8 | #
9 | # To prepare or verify release metadata of the library (settings proper version, updating changelog, etc.)
10 | # - this script runs the JavaScript script from Wultra infrastructure repository
11 | # - it uses data defined in `.prepare-release.json` file in the root of the repository
12 | # - it passes all parameters to the JavaScript script
13 | #
14 | #
15 | # It can be run in 3 modes:
16 | #
17 | # 1. With a version (-v X.Y.Z) argument:
18 | # - it will prepare the release with the current version
19 | # - use it when you're preparing a new release pull-request
20 | # - Example: sh scripts/prepare-release.sh -v 1.0.0
21 | #
22 | # 2. With a version argument and --verify:
23 | # - it will verify that the given release version is prepared.
24 | # - use it to make sure that the release pull-request is properly prepared (also used on CI)
25 | # - Example: sh scripts/prepare-release.sh -v 1.0.0 --verify
26 | #
27 | # 3. Without arguments:
28 | # - it will run the script in the root directory of the repository and verify that all files are prepared.
29 | # - use it to make sure that the current state of the repository is ready for release
30 | # - Example: sh scripts/prepare-release.sh
31 | #
32 | # Note: you can add --ignore-git-clean to ignore "git clean" errors (useful when testing things locally)
33 | #
34 | #########################
35 |
36 | # path to the script folder
37 | SCRIPT_FOLDER=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
38 |
39 | # URL of the JavaScript prepare-release script in Wultra infrastructure repository
40 | URL="https://raw.githubusercontent.com/wultra/wultra-infrastructure/refs/heads/mobile-release/mobile-release/v1/prepare-release.js"
41 |
42 | # execute the remote node and pass all parameters to it + add path parameter to the root of the repository
43 | curl -fsSL "${URL}" | node - -p "${SCRIPT_FOLDER}/.." "${@}"
--------------------------------------------------------------------------------
/docs/Additional-Utilities.md:
--------------------------------------------------------------------------------
1 | # Additional Utilities
2 |
3 | The PowerAuth Mobile JS SDK offers additional utility functions that can help with various tasks in your application. These utilities are available through the `PowerAuthUtils` class.
4 |
5 | ## Available Methods
6 |
7 | ### getEnvironmentInfo()
8 |
9 | Returns information about the current environment, including system details, device information, and SDK version.
10 |
11 | **Usage:**
12 |
13 | ```typescript
14 | import { PowerAuthUtils } from 'react-native-powerauth-mobile-sdk';
15 |
16 | async function getDeviceInfo() {
17 | try {
18 | const environmentInfo = await PowerAuthUtils.getEnvironmentInfo();
19 | console.log('Environment Info:', environmentInfo);
20 |
21 | // Access specific properties
22 | console.log('System:', environmentInfo.systemName);
23 | console.log('Version:', environmentInfo.systemVersion);
24 | console.log('App Version:', environmentInfo.applicationVersion);
25 | console.log('App ID:', environmentInfo.applicationIdentifier);
26 | console.log('Device ID:', environmentInfo.deviceId);
27 | console.log('Device Maker:', environmentInfo.deviceManufacturer);
28 | console.log('SDK Version:', environmentInfo.sdkVersion);
29 | } catch (error) {
30 | console.error('Failed to get environment info:', error);
31 | }
32 | }
33 | ```
34 |
35 | **Response:**
36 |
37 | The method returns a `PowerAuthEnvironmentInfo` object with the following properties:
38 |
39 | - `systemName` (string): System name, for example "iOS", "Android", "iPadOS"
40 | - `systemVersion` (string): Version of the system
41 | - `applicationVersion` (string, optional): Application version, e.g. "1.0.0"
42 | - `applicationIdentifier` (string, optional): Host application identifier, for example "com.wultra.demoapp"
43 | - `deviceManufacturer` (string): Device manufacturer, for example "apple" or "Samsung"
44 | - `deviceId` (string): Device ID, for example "iPhone9,2"
45 | - `sdkVersion` (string): PowerAuth JS SDK version, for example "4.0.0"
46 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/WritableNativeMap.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | /**
4 | * Cordova implementation of writable map.
5 | *
6 | * It's not in fact native, it's based on Kotlin collections.
7 | */
8 | class WritableNativeMap(srcMap: Map = emptyMap()) : ReadableNativeMap(srcMap), WritableMap {
9 |
10 | override fun putMap(key: String, value: ReadableMap?) {
11 | if (!(value == null || value is ReadableNativeMap)) {
12 | throw IllegalArgumentException("Illegal type provided")
13 | }
14 | _mutableMap.put(key, value as ReadableNativeMap?)
15 | }
16 |
17 | override fun putArray(key: String, value: ReadableArray?) {
18 | if (!(value == null || value is ReadableNativeArray)) {
19 | throw IllegalArgumentException("Illegal type provided")
20 | }
21 | _mutableMap.put(key, value as ReadableNativeArray?)
22 | }
23 |
24 | override fun putBoolean(key: String, value: Boolean) {
25 | _mutableMap[key] = value
26 | }
27 |
28 | override fun putDouble(key: String, value: Double) {
29 | _mutableMap[key] = value
30 | }
31 |
32 | override fun putInt(key: String, value: Int) {
33 | _mutableMap[key] = value
34 | }
35 |
36 | override fun putLong(key: String, value: Long) {
37 | _mutableMap[key] = value
38 | }
39 |
40 | override fun putNull(key: String) {
41 | _mutableMap[key] = null
42 | }
43 |
44 | override fun putString(key: String, value: String?) {
45 | _mutableMap[key] = value
46 | }
47 |
48 | override fun merge(source: ReadableMap) {
49 | if (source !is ReadableNativeMap) {
50 | throw IllegalArgumentException("Illegal type provided")
51 | }
52 | val iter = source.entryIterator
53 | while (iter.hasNext()) {
54 | val entry = iter.next()
55 | _mutableMap[entry.key] = entry.value
56 | }
57 | }
58 |
59 | override fun copy(): WritableMap {
60 | val target = WritableNativeMap()
61 | target.merge(this)
62 | return target
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/testapp/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/testapp/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment, if you want to build the app with the old architecture
2 | # ENV['RCT_NEW_ARCH_ENABLED'] = '0'
3 |
4 | # Resolve react_native_pods.rb with node to allow for hoisting
5 | require Pod::Executable.execute_command('node', ['-p',
6 | 'require.resolve(
7 | "react-native/scripts/react_native_pods.rb",
8 | {paths: [process.argv[1]]},
9 | )', __dir__]).strip
10 |
11 | platform :ios, min_ios_version_supported
12 | prepare_react_native_project!
13 |
14 | linkage = ENV['USE_FRAMEWORKS']
15 | if linkage != nil
16 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
17 | use_frameworks! :linkage => linkage.to_sym
18 | end
19 |
20 | target 'testapp' do
21 | config = use_native_modules!
22 |
23 | use_react_native!(
24 | :path => config[:reactNativePath],
25 | # An absolute path to your application root.
26 | :app_path => "#{Pod::Config.instance.installation_root}/.."
27 | )
28 |
29 | post_install do |installer|
30 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
31 | react_native_post_install(
32 | installer,
33 | config[:reactNativePath],
34 | :mac_catalyst_enabled => false,
35 | # :ccache_enabled => true
36 | )
37 |
38 | # Wultra specific
39 | fix_dev_team(installer, 'KTT9G859MR')
40 | end
41 | end
42 |
43 | # Wultra specific. Fix dev team for all configurations and targets
44 | def fix_dev_team(installer, team_id)
45 | # https://github.com/CocoaPods/CocoaPods/issues/8891
46 | def fix_config_dev_team(config, team_id)
47 | if config.build_settings['DEVELOPMENT_TEAM'].nil?
48 | config.build_settings['DEVELOPMENT_TEAM'] = team_id
49 | end
50 | end
51 | installer.generated_projects.each do |project|
52 | project.build_configurations.each do |config|
53 | fix_config_dev_team(config, team_id)
54 | end
55 | project.targets.each do |target|
56 | target.build_configurations.each do |config|
57 | fix_config_dev_team(config, team_id)
58 | end
59 | end
60 | end
61 | end
62 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/reactnative/PowerAuthCryptoUtilsModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wultra.android.powerauth.reactnative;
18 |
19 | import androidx.annotation.NonNull;
20 |
21 | import com.facebook.react.bridge.BaseJavaModule;
22 | import com.facebook.react.bridge.Promise;
23 | import com.facebook.react.bridge.ReactMethod;
24 | import com.facebook.react.module.annotations.ReactModule;
25 | import com.wultra.android.powerauth.js.PowerAuthCryptoUtilsJsModule;
26 |
27 | @SuppressWarnings("unused")
28 | @ReactModule(name = "PowerAuthCryptoUtils")
29 | public class PowerAuthCryptoUtilsModule extends BaseJavaModule {
30 |
31 | private final PowerAuthCryptoUtilsJsModule powerAuthCryptoUtilsJsModule;
32 |
33 | public PowerAuthCryptoUtilsModule() {
34 | super();
35 | this.powerAuthCryptoUtilsJsModule = new PowerAuthCryptoUtilsJsModule();
36 | }
37 |
38 | public PowerAuthCryptoUtilsJsModule getPowerAuthCryptoUtilsJsModule() {
39 | return powerAuthCryptoUtilsJsModule;
40 | }
41 |
42 | @NonNull
43 | @Override
44 | public String getName() {
45 | return powerAuthCryptoUtilsJsModule.getName();
46 | }
47 |
48 | @ReactMethod
49 | void hashSha256(String input, Promise promise) {
50 | powerAuthCryptoUtilsJsModule.hashSha256(input, promise);
51 | }
52 |
53 | @ReactMethod
54 | void randomBytes(int length, Promise promise) {
55 | powerAuthCryptoUtilsJsModule.randomBytes(length, promise);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/testapp/_tests/PowerAuthUtils.test.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2022 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { PowerAuthUtils } from "react-native-powerauth-mobile-sdk";
18 | import { TestSuite, expect } from "../src/testbed";
19 |
20 | export class PowerAuthUtilsTests extends TestSuite {
21 |
22 | async iosTestEnvironmentInfo() {
23 | const deviceInfo = await PowerAuthUtils.getEnvironmentInfo();
24 | console.log(`Device info: ${JSON.stringify(deviceInfo)}`);
25 | expect(deviceInfo).toBeDefined();
26 | expect(deviceInfo.systemName).toBe("iOS");
27 | expect(deviceInfo.systemVersion).toBeDefined();
28 | expect(deviceInfo.deviceManufacturer).toBe("apple");
29 | expect(deviceInfo.deviceId).toBeDefined();
30 | expect(deviceInfo.sdkVersion).toBeDefined();
31 | expect(deviceInfo.applicationVersion).toBe("1.0");
32 | expect(deviceInfo.applicationIdentifier).toBeDefined();
33 | }
34 |
35 | async androidTestEnvironmentInfo() {
36 | const deviceInfo = await PowerAuthUtils.getEnvironmentInfo();
37 | console.log(`Device info: ${JSON.stringify(deviceInfo)}`);
38 | expect(deviceInfo).toBeDefined();
39 | expect(deviceInfo.systemName).toBe("android");
40 | expect(deviceInfo.systemVersion).toBeDefined();
41 | expect(deviceInfo.deviceManufacturer).toBeDefined();
42 | expect(deviceInfo.deviceId).toBeDefined();
43 | expect(deviceInfo.sdkVersion).toBeDefined();
44 | expect(deviceInfo.applicationVersion).toBe("1.0");
45 | expect(deviceInfo.applicationIdentifier).toBeDefined();
46 | }
47 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/wpm_types.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2018 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef wultra_wpm_types_h
18 | #define wultra_wpm_types_h
19 |
20 | #ifdef __cplusplus
21 | extern "C" {
22 | #endif
23 |
24 | /// Result of WPM_testPasscode function that can result in multiple issues.
25 | typedef enum _WPM_PasscodeResult {
26 | /// The passcode is OK, no issues found
27 | WPM_PasscodeResult_Ok = 1 << 0,
28 | /// The passcode doesn't have enough unique digits
29 | WPM_PasscodeResult_NotUnique = 1 << 1,
30 | /// There is a significant amount of repeating characters in the passcode
31 | WPM_PasscodeResult_RepeatingChars = 1 << 2,
32 | /// A repeating pattern was found in the passcode
33 | WPM_PasscodeResult_HasPattern = 1 << 3,
34 | /// This passcode can be a date (and possible birthday of the user)
35 | WPM_PasscodeResult_PossiblyDate = 1 << 4,
36 | /// The passcode is in most used passcodes
37 | WPM_PasscodeResult_FrequentlyUsed = 1 << 5,
38 | /// Wrong input
39 | WPM_PasscodeResult_WrongInput = 1 << 6
40 |
41 | } WPM_PasscodeResult;
42 |
43 | /// Classification of the password strength
44 | typedef enum _WPM_PasswordResult {
45 | WPM_PasswordResult_VeryWeak = 0,
46 | WPM_PasswordResult_Weak = 1,
47 | WPM_PasswordResult_Moderate = 2,
48 | WPM_PasswordResult_Good = 3,
49 | WPM_PasswordResult_Strong = 4,
50 | WPM_PasswordResult_WrongInput = 5,
51 | } WPM_PasswordResult;
52 |
53 | #ifdef __cplusplus
54 | }
55 | #endif
56 |
57 | #endif /* wultra_wpm_types_h */
58 |
--------------------------------------------------------------------------------
/docs/Storage-Utilities.md:
--------------------------------------------------------------------------------
1 | # Storage Utilities
2 |
3 | The PowerAuth Mobile JS SDK provides a simple cache API via `PowerAuthStorageUtils` for string key–value storage.
4 |
5 | ## Storage Types
6 |
7 | - `PowerAuthStorageType.SECURE`
8 | - iOS: PowerAuth Keychain (Keychain service `com.wultra.powerauth.jssdk.storageutils.secure`)
9 | - Android: PowerAuth Keychain (encrypted, backed by Android Keystore)
10 |
11 | - `PowerAuthStorageType.STANDARD`
12 | - iOS: UserDefaults suite `com.wultra.powerauth.jssdk.storageutils.standard`
13 | - Android: SharedPreferences file `com.wultra.powerauth.jssdk.storageutils.standard`
14 |
15 | ## Available Methods
16 |
17 | ### setString(key: string, value: string, storageType: PowerAuthStorageType)
18 | Store a string value under a key.
19 |
20 | ### getString(key: string, storageType: PowerAuthStorageType)
21 | Retrieve a string value. Returns `undefined` when the key is missing.
22 |
23 | ### exists(key: string, storageType: PowerAuthStorageType)
24 | Check whether a key is present.
25 |
26 | ### remove(key: string, storageType: PowerAuthStorageType)
27 | Remove a key. Returns `true` if the key existed.
28 |
29 | ## Usage
30 |
31 | ```typescript
32 | import { PowerAuthStorageUtils, PowerAuthStorageType } from 'react-native-powerauth-mobile-sdk';
33 |
34 | // Secure storage (Keychain / Android Keystore-backed)
35 | await PowerAuthStorageUtils.setString('session', '{"token":"abc"}', PowerAuthStorageType.SECURE);
36 | const secureValue = await PowerAuthStorageUtils.getString('session', PowerAuthStorageType.SECURE);
37 |
38 | // Standard storage (UserDefaults / SharedPreferences)
39 | await PowerAuthStorageUtils.setString('theme', 'dark', PowerAuthStorageType.STANDARD);
40 | const exists = await PowerAuthStorageUtils.exists('theme', PowerAuthStorageType.STANDARD);
41 | const removed = await PowerAuthStorageUtils.remove('theme', PowerAuthStorageType.STANDARD);
42 | ```
43 |
44 | ## Errors
45 |
46 | - `WRONG_PARAMETER`: invalid input (e.g., empty key, invalid storage type)
47 | - `ENCRYPTION_ERROR`: secure storage operation failed
48 |
49 | ## Read Next
50 |
51 | - [Additional Utilities](Additional-Utilities.md)
52 | - [Accessing the Native PowerAuthSDK](Accessing-Native-PowerAuthSDK.md)
53 |
--------------------------------------------------------------------------------
/testapp-cordova/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "com.wultra.pwatest",
3 | "displayName": "PowerAuthTest",
4 | "version": "1.0.0",
5 | "description": "A sample Cordova application that runs PowerAuth tests.",
6 | "main": "index.js",
7 | "scripts": {
8 | "android": "yarn dlx cordova run android",
9 | "ios": "yarn dlx cordova run ios",
10 | "pods": "(cd \"platforms/ios\" && yarn dlx pod-install --non-interactive)",
11 | "rebuildPlugin": "(cd .. && yarn workspace cordova-powerauth-mobile-sdk cdv)",
12 | "installPlugin": "npm_config_workspaces=false yarn dlx cordova plugin add cordova-powerauth-mobile-sdk --noregistry --searchpath ../packages/cordova-powerauth-mobile-sdk/build/cdv --force",
13 | "reinstallPlugin": "(npm_config_workspaces=false yarn dlx cordova plugin remove cordova-powerauth-mobile-sdk --no-save --force || true) && yarn rebuildPlugin && yarn installPlugin",
14 | "prepare": "node node_modules/gulp/bin/gulp.js",
15 | "buildAndroid": "yarn reinstallPlugin && yarn prepare && yarn dlx cordova build android",
16 | "buildIos": "yarn reinstallPlugin && yarn prepare && (cd platforms/ios && yarn dlx pod-install --non-interactive && xcodebuild archive -workspace PowerAuthTest.xcworkspace -scheme PowerAuthTest -sdk iphoneos CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_ALLOWED=NO)",
17 | "freshAndroid": "yarn reinstallPlugin && yarn prepare && yarn android",
18 | "freshIos": "yarn reinstallPlugin && yarn prepare && yarn pods && yarn ios"
19 | },
20 | "keywords": [
21 | "ecosystem:cordova"
22 | ],
23 | "author": "Apache Cordova Team",
24 | "license": "Apache-2.0",
25 | "devDependencies": {
26 | "buffer": "^6.0.3",
27 | "chalk": "^4.1.2",
28 | "cordova-android": "^13.0.0",
29 | "cordova-ios": "^7.1.1",
30 | "dotenv": "^16.4.5",
31 | "esbuild": "^0.23.1",
32 | "gulp": "^5.0.0",
33 | "gulp-replace": "^1.1.4",
34 | "rimraf": "^6.0.1"
35 | },
36 | "cordova": {
37 | "platforms": [
38 | "ios",
39 | "android"
40 | ],
41 | "plugins": {
42 | "cordova-powerauth-mobile-sdk": {}
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/js/WrapperException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wultra.android.powerauth.js;
18 |
19 | import androidx.annotation.NonNull;
20 |
21 | /**
22 | * Exception type used internally in this module to propagate error code and message
23 | * to promise's reject method.
24 | */
25 | class WrapperException extends Exception {
26 |
27 | private final String errorCode;
28 |
29 | /**
30 | * @return Error code that should be reported to promise.
31 | */
32 | @NonNull
33 | String getErrorCode() {
34 | return errorCode;
35 | }
36 |
37 | /**
38 | * Construct WrapperException with required error code and message.
39 | * @param errorCode Error code that should be reported to promise as failure.
40 | * @param message Message that should be reported to promise as failure.
41 | */
42 | WrapperException(@NonNull String errorCode, @NonNull String message) {
43 | super(message, null);
44 | this.errorCode = errorCode;
45 | }
46 |
47 | /**
48 | * Construct WrapperException with required error code, message and optional cause of the failure.
49 | * @param errorCode Error code that should be reported to promise as failure.
50 | * @param message Message that should be reported to promise as failure.
51 | * @param cause Original cause of failure.
52 | */
53 | WrapperException(@NonNull String errorCode, @NonNull String message, Throwable cause) {
54 | super(message, cause);
55 | this.errorCode = errorCode;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/src/internal/NativeCordovaModule.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | //@ts-nocheck
18 |
19 | import { NativePowerAuthIfc } from "./NativePowerAuthIfc";
20 | import { Utils } from "./Utils.ts";
21 |
22 | export abstract class NativeCordovaModule implements NativePowerAuthIfc {
23 |
24 | protected abstract readonly pluginName: string;
25 |
26 | callNative(name: string, args: any[]): Promise {
27 | return new Promise(
28 | (resolve, reject) => {
29 | cordova.exec(
30 | // success callback
31 | (response) => {
32 | if (Utils.detectPlatform() === "android") {
33 | resolve(response);
34 | } else {
35 | const parsed = JSON.parse(response);
36 | resolve(parsed.result);
37 | }
38 | },
39 | // error callback
40 | (error) => {
41 | if (Utils.detectPlatform() === "android") {
42 | reject(error)
43 | } else {
44 | reject(JSON.parse(error))
45 | }
46 | },
47 | // native platform plugin name
48 | this.pluginName,
49 | // function name
50 | name,
51 | // function arguments
52 | args
53 | );
54 | }
55 | );
56 | }
57 | }
--------------------------------------------------------------------------------
/testapp-cordova/src/App.tsx:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2024 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | // @ts-nocheck
18 |
19 | import { TestExecutor } from './TestExecutor'
20 |
21 | document.addEventListener('deviceready', onDeviceReady, false);
22 |
23 | function onDeviceReady() {
24 |
25 | // Cordova is now initialized. Have fun!
26 |
27 | // enable debug
28 | PowerAuthDebug.isEnabled = true;
29 |
30 | const statusEl = document.getElementById('tests-status');
31 | const progressEl = document.getElementById('tests-progress');
32 | const messageEl = document.getElementById("test-message");
33 |
34 | console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
35 | document.getElementById('deviceready').classList.add('ready');
36 |
37 | const executor = new TestExecutor(async (_context, message, duration) => {
38 | messageEl.innerHTML = message;
39 | await new Promise(resolve => setTimeout(resolve, duration))
40 | }, (progress) => {
41 | progressEl.innerHTML = `${progress.succeeded} succeeded
${progress.failed} failed
${progress.skipped} skipped
out of total ${progress.total}`;;
42 | }, (finished) => {
43 | statusEl.innerHTML = finished ? "Tests running" : "Tests finished";
44 | messageEl.innerHTML = "";
45 | })
46 |
47 | document.getElementById('tests-simple').addEventListener('click', (e) => {
48 | executor.runTests(false)
49 | })
50 | document.getElementById('tests-full').addEventListener('click', (e) => {
51 | executor.runTests(true)
52 | })
53 | document.getElementById('tests-stop').addEventListener('click', (e) => {
54 | executor.cancelTests()
55 | })
56 | }
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/util/ReadableNativeArray.kt:
--------------------------------------------------------------------------------
1 | package com.wultra.android.powerauth.cdv.util
2 |
3 | import com.wultra.android.powerauth.bridge.toList
4 | import com.wultra.android.powerauth.bridge.toReadableType
5 | import org.json.JSONArray
6 |
7 |
8 | /**
9 | * Cordova implementation of readable array.
10 | *
11 | * It's not in fact native, it's based on Kotlin collections.
12 | */
13 | open class ReadableNativeArray(srcList: List) : ReadableArray {
14 |
15 | protected val _mutableList = srcList.toMutableList()
16 | protected val list: List = _mutableList
17 |
18 | constructor(jsonArray: JSONArray) : this(jsonArray.toList())
19 |
20 | override fun getArray(index: Int): ReadableArray {
21 | return ReadableNativeArray(list[index] as List)
22 | }
23 |
24 | override fun getBoolean(index: Int): Boolean {
25 | return list[index] as Boolean
26 | }
27 |
28 | override fun getDouble(index: Int): Double {
29 | return list[index] as Double
30 | }
31 |
32 | override fun getDynamic(index: Int): Dynamic {
33 | return list[index] as Dynamic
34 | }
35 |
36 | override fun getInt(index: Int): Int {
37 | return list[index] as Int
38 | }
39 |
40 | override fun getLong(index: Int): Long {
41 | return list[index] as Long
42 | }
43 |
44 | override fun getMap(index: Int): ReadableMap {
45 | @Suppress("UNCHECKED_CAST")
46 | return ReadableNativeMap(list[index] as Map)
47 | }
48 |
49 | override fun getString(index: Int): String {
50 | return list[index] as String
51 | }
52 |
53 | override fun getType(index: Int): ReadableType {
54 | return list[index].toReadableType()
55 | }
56 |
57 | override fun isNull(index: Int): Boolean {
58 | return list[index] == null
59 | }
60 |
61 | override fun size(): Int {
62 | return list.size
63 | }
64 |
65 | override fun toArrayList(): ArrayList {
66 | val l = list.filterNotNull().map {
67 | when (it) {
68 | is ReadableMap -> it.toHashMap()
69 | is ReadableArray -> it.toArrayList()
70 | else -> it
71 | }
72 | }
73 | return ArrayList(l)
74 | }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/reactnative/PowerAuthPassphraseMeterModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wultra.android.powerauth.reactnative;
18 |
19 | import androidx.annotation.NonNull;
20 |
21 | import com.facebook.react.bridge.BaseJavaModule;
22 | import com.facebook.react.bridge.Dynamic;
23 | import com.facebook.react.bridge.Promise;
24 | import com.facebook.react.bridge.ReactMethod;
25 | import com.facebook.react.module.annotations.ReactModule;
26 | import com.wultra.android.powerauth.js.PowerAuthPassphraseMeterJsModule;
27 |
28 | @SuppressWarnings("unused")
29 | @ReactModule(name = "PowerAuthPassphraseMeter")
30 | public class PowerAuthPassphraseMeterModule extends BaseJavaModule {
31 |
32 | private final PowerAuthPasswordModule passwordModule;
33 | private final PowerAuthPassphraseMeterJsModule powerAuthPassphraseMeterJsModule;
34 |
35 | public PowerAuthPassphraseMeterModule(@NonNull PowerAuthPasswordModule passwordModule) {
36 | this.passwordModule = passwordModule;
37 | this.powerAuthPassphraseMeterJsModule = new PowerAuthPassphraseMeterJsModule(passwordModule.getPowerAuthPasswordJsModule());
38 | }
39 |
40 | public PowerAuthPassphraseMeterJsModule getPowerAuthPassphraseMeterJsModule() {
41 | return powerAuthPassphraseMeterJsModule;
42 | }
43 |
44 | @NonNull
45 | @Override
46 | public String getName() {
47 | return powerAuthPassphraseMeterJsModule.getName();
48 | }
49 |
50 | public static final String NAME = "PowerAuthPassphraseMeter";
51 |
52 | @ReactMethod
53 | void testPin(Dynamic password, Promise promise) {
54 | powerAuthPassphraseMeterJsModule.testPin(password, promise);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // Main objects
18 |
19 | export * from './PowerAuth';
20 | export * from './PowerAuthActivationCodeUtil';
21 | export * from './PowerAuthUtils';
22 | export * from './PowerAuthTokenStore';
23 | export * from './PowerAuthPassphraseMeter';
24 | export * from './PowerAuthCryptoUtils';
25 | export * from './PowerAuthStorageUtils';
26 |
27 | // Model objects
28 |
29 | export * from './model/PowerAuthActivation';
30 | export * from './model/PowerAuthActivationState';
31 | export * from './model/PowerAuthActivationStatus';
32 | export * from './model/PowerAuthAuthentication';
33 | export * from './model/PowerAuthAuthorizationHttpHeader';
34 | export * from './model/PowerAuthEncryptionHttpHeader';
35 | export * from './model/PowerAuthBiometryConfiguration';
36 | export * from './model/PowerAuthBiometryInfo';
37 | export * from './model/PowerAuthClientConfiguration';
38 | export * from './model/PowerAuthConfiguration';
39 | export * from './model/PowerAuthConfirmRecoveryCodeDataResult';
40 | export * from './model/PowerAuthCreateActivationResult';
41 | export * from './model/PowerAuthError';
42 | export * from './model/PowerAuthKeychainConfiguration';
43 | export * from './model/PowerAuthSharingConfiguration';
44 | export * from './model/PowerAuthExternalPendingOperation';
45 | export * from './model/PowerAuthRecoveryActivationData';
46 | export * from './model/PowerAuthPassword';
47 | export * from './model/PowerAuthEncryptor';
48 | export * from './model/PowerAuthDataFormat';
49 | export * from './model/PowerAuthUserInfo';
50 | export * from './model/BaseNativeObject';
51 |
52 | // Debug features
53 |
54 | export * from './debug/PowerAuthDebug';
55 | export * from './debug/NativeObjectRegister';
56 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthConfiguration.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * Interface that contains configuration data for a single `PowerAuth` instance.
19 | */
20 | export interface PowerAuthConfigurationType {
21 | /**
22 | * String with the cryptographic configuration.
23 | */
24 | readonly configuration: string
25 | /**
26 | * Base URL to the PowerAuth enrollment server. Usualky ends with `/enrollment-server`.
27 | */
28 | readonly baseEndpointUrl: string
29 | }
30 |
31 | /**
32 | * Class representing a configuration of a single `PowerAuth` instance. The class implements
33 | * `ConfigurationType` interface, so can be used
34 | */
35 | export class PowerAuthConfiguration implements PowerAuthConfigurationType {
36 | configuration: string
37 | baseEndpointUrl: string
38 |
39 | /**
40 | * Construct configuration with required parameters.
41 | *
42 | * @param configuration String with the cryptographic configuration.
43 | * @param baseEndpointUrl Base URL to the PowerAuth enrollment server. Usually ends with `/enrollment-server`.
44 | */
45 | public constructor(configuration: string, baseEndpointUrl: string) {
46 | this.configuration = configuration
47 | this.baseEndpointUrl = baseEndpointUrl
48 | }
49 | }
50 |
51 | /**
52 | * Create frozen configuration from provided configuration object.
53 | * @param input Application provided configuration.
54 | * @returns Frozen configuration object.
55 | */
56 | export function buildConfiguration(input: PowerAuthConfigurationType): PowerAuthConfigurationType {
57 | return Object.freeze({
58 | configuration: input.configuration,
59 | baseEndpointUrl: input.baseEndpointUrl
60 | })
61 | }
62 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/src/model/PowerAuthNativeTypes.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { PasswordType, PowerAuthBiometricPrompt } from '../index'
18 |
19 | /**
20 | * Interface representing a simple native object identified by string identifier.
21 | */
22 | export interface PowerAuthRawNativeObject {
23 | /**
24 | * Object's identifier.
25 | */
26 | objectId?: string
27 | }
28 |
29 | /**
30 | * Type representing a simple native password identifier wrapped in the object.
31 | * We need this auxiliary object due to a problematic call to passphrase meter.
32 | */
33 | export type PowerAuthRawPassword = PowerAuthRawNativeObject;
34 |
35 | /**
36 | * Type representing a raw password object passable to native interface.
37 | */
38 | export type PowerAuthRawPasswordType = PowerAuthRawPassword | string
39 |
40 | /**
41 | * Object representing a data pased to native methods requiring PowerAuthAuthentication
42 | * on imput. The `RawAuthentication` must be be created from `PowerAuthAuthentication`
43 | * instance.
44 | */
45 | export interface PowerAuthRawAuthentication {
46 | readonly password?: string | PowerAuthRawPassword
47 | readonly biometricPrompt?: PowerAuthBiometricPrompt
48 | readonly isPersist?: boolean
49 | readonly isBiometry: boolean
50 | isReusable: boolean
51 | biometryKeyId?: string
52 | }
53 |
54 | /**
55 | * Convert public password type into type passable into native interface.
56 | * @param password Public password object type.
57 | * @returns Raw password object type.
58 | */
59 | export function toPowerAuthRawPassword(password: PasswordType): Promise {
60 | if (typeof password === 'string') {
61 | return Promise.resolve(password)
62 | }
63 | return password.toRawPassword()
64 | }
--------------------------------------------------------------------------------
/docs/Changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## TBA
4 | - Added `PowerAuthCryptoUtils` with functions for hashing and random bytes generation (see [Crypto Utilities](./Crypto-Utilities.md) for more details)
5 | - Added helper method to create `PowerAuthPassword` from string (`PowerAuthPassword.fromString`) (see [Secure Password](./Secure-Password.md) for more details)
6 | - Added `PowerAuthStorageUtils` cache API with secure & standard storage (see [Storage Utilities](./Storage-Utilities.md))
7 | - Fixed bridged native error processing on Cordova (issue[#302](https://github.com/wultra/react-native-powerauth-mobile-sdk/issues/302))
8 |
9 | ## 4.1.3 (9/2025)
10 | - Token-based authentication now automatically synchronizes time if needed (see [Token-Based Authentication](./Token-Based-Authentication.md) for more details)
11 |
12 | ## 4.1.2 (9/2025)
13 | - Fixed Android Encryptor crashing on missing `putLong` JNI bindings (issue [#264](https://github.com/wultra/react-native-powerauth-mobile-sdk/issues/264))
14 | - Added [Time Synchronization service](./Time-Synchronization.md)
15 |
16 | ## 4.1.1 (7/2025)
17 |
18 | - Upgraded the [PowerAuth native SDK to `1.9.5`](https://github.com/wultra/powerauth-mobile-sdk/releases/tag/1.9.5)
19 | - Biometric authentication offloaded to the background thread
20 |
21 | ## 4.1.0 (6/2025)
22 | - Opportunity to sign Base64 encoded data with `signDataWithDevicePrivateKey`
23 | - we added the `dataFormat` parameter with possible `UTF8` and `BASE64` values for the data to be signed
24 | - Added `PowerAuthUtils` that provides `getEnvironmentInfo` with device, system and app info
25 | - Fixed issue on Cordova when iPadOS was recognized as Android in some cases
26 | - Fixed `validatePassword` API on iOS that returned wrong value
27 |
28 | ## 3.2.0 (6/2025)
29 | - Added `PowerAuthUtils` that provides `getEnvironmentInfo` with device, system and app info
30 | - Fixed issue on Cordova when iPadOS was recognized as Android in some cases
31 |
32 | ## 4.0.0 (5/2025)
33 | - Migration to the latest native PowerAuthSDK stack (1.9.x)
34 | - Use [migration guide](Version-4.0.md) for a smooth migration
35 |
36 | ## 3.1.0 (5/2025)
37 | - Support for the new React Architecture
38 |
39 | ## 3.0.1 (4/2025)
40 | - Native PowerAuth SDK version raised to 1.7.12
41 | - Fixed build problems on Xcode 16.3
42 | - OpenSSL upgraded to version `1.1.1w`
43 |
44 | ## 3.0.0 (1/2025)
45 |
46 | - Library renamed to `PowerAuth Mobile JS`
47 | - Added Cordova support
--------------------------------------------------------------------------------
/packages/cordova-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/cdv/PowerAuthObjectRegister.kt:
--------------------------------------------------------------------------------
1 |
2 | package com.wultra.android.powerauth.cordova.plugin
3 |
4 | import com.wultra.android.powerauth.bridge.getOptString
5 | import com.wultra.android.powerauth.bridge.getReadableMap
6 | import com.wultra.android.powerauth.js.ObjectRegisterJs
7 | import com.wultra.android.powerauth.cdv.util.Promise
8 | import org.apache.cordova.CallbackContext
9 | import org.apache.cordova.CordovaInterface
10 | import org.apache.cordova.CordovaPlugin
11 | import org.apache.cordova.CordovaWebView
12 | import org.json.JSONArray
13 | import org.json.JSONException
14 |
15 |
16 | class PowerAuthObjectRegister : CordovaPlugin() {
17 |
18 | internal lateinit var objectRegisterJs: ObjectRegisterJs
19 |
20 | override fun initialize(cordova: CordovaInterface, webView: CordovaWebView) {
21 | super.initialize(cordova, webView);
22 | objectRegisterJs = ObjectRegisterJs(cordova.context.applicationContext)
23 | }
24 |
25 | @Throws(JSONException::class)
26 | override fun execute(action: String, args: JSONArray, callbackContext: CallbackContext): Boolean {
27 | val promise = Promise(callbackContext)
28 | when (action) {
29 | "isValidNativeObject" -> {
30 | isValidNativeObject(args, promise)
31 | return true
32 | }
33 | "debugDump" -> {
34 | debugDump(args, promise)
35 | return true
36 | }
37 | "debugCommand" -> {
38 | debugCommand(args,promise)
39 | return true
40 | }
41 | }
42 | return false // Returning false results in a "MethodNotFound" error.
43 | }
44 |
45 |
46 | private fun isValidNativeObject(args: JSONArray, promise: Promise) {
47 | val objectId = args.getOptString(0)
48 | objectRegisterJs.isValidNativeObject(objectId, promise)
49 | }
50 |
51 | private fun debugDump(args: JSONArray, promise: Promise) {
52 | val instanceId = args.getOptString(0)
53 | objectRegisterJs.debugDump(instanceId, promise);
54 | }
55 |
56 | private fun debugCommand(args: JSONArray, promise: Promise) {
57 | // String command, ReadableMap options
58 | val command = args.getString(0)
59 | val options = args.getReadableMap(1)
60 | objectRegisterJs.debugCommand(command, options, promise);
61 | }
62 | }
--------------------------------------------------------------------------------
/testapp/_tests/PowerAuth_ErrorData.test.ts:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2025 Wultra s.r.o.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | import { PowerAuthError, PowerAuthErrorCode } from "react-native-powerauth-mobile-sdk";
18 | import { expect } from "../src/testbed";
19 | import { TestWithActivation } from "./helpers/TestWithActivation";
20 |
21 | export class PowerAuth_ErrorDataTests extends TestWithActivation {
22 |
23 | async testErrorContainsParsedData() {
24 | let errorThrown = false
25 | try {
26 | await this.sdk.validatePassword(this.credentials.invalidPassword)
27 | } catch (e) {
28 | errorThrown = true
29 | expect(e instanceof PowerAuthError).toBe(true)
30 | const error = e as PowerAuthError
31 |
32 | expect(error.code).toBe(PowerAuthErrorCode.AUTHENTICATION_ERROR)
33 | expect(error.errorData).toBeDefined()
34 | expect(typeof error.errorData.httpStatusCode).toBe('number')
35 | expect(error.errorData.httpStatusCode).toBe(401)
36 | expect(typeof error.errorData.responseBody).toBe('string')
37 | }
38 | expect(errorThrown).toBe(true)
39 | }
40 |
41 | async testResponseErrorContainsParsedData() {
42 | let errorThrown = false
43 | try {
44 | await this.sdk.confirmRecoveryCode('AAAAA-AAAAA-AAAAA-AAAAA', this.credentials.knowledge)
45 | } catch (e) {
46 | errorThrown = true
47 | expect(e instanceof PowerAuthError).toBe(true)
48 | const error = e as PowerAuthError
49 |
50 | expect(error.code === PowerAuthErrorCode.RESPONSE_ERROR || error.code === PowerAuthErrorCode.AUTHENTICATION_ERROR).toBe(true)
51 | expect(error.errorData).toBeDefined()
52 | expect(typeof error.errorData.httpStatusCode).toBe('number')
53 | }
54 | expect(errorThrown).toBe(true)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/ios/PowerAuth/PowerAuthEncryptorModule.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #import "PAJS.h"
18 | #import "Errors.h"
19 |
20 | @class PowerAuthCoreEciesEncryptor;
21 |
22 | /// Object containing all encryptor's data required for the request encryption.
23 | @interface PowerAuthJsEncryptor: NSObject
24 |
25 | - (nonnull instancetype) initWithEncryptor:(nonnull PowerAuthCoreEciesEncryptor*)encryptor
26 | powerAuthInstanceId:(nonnull NSString*)powerAuthInstanceId
27 | activationScoped:(BOOL)activationScoped;
28 |
29 | @property (nonatomic, readonly) BOOL activationScoped;
30 | @property (nonatomic, readonly, strong, nonnull) PowerAuthCoreEciesEncryptor * coreEncryptor;
31 | @property (nonatomic, readonly, strong, nonnull) NSString * powerAuthInstanceId;
32 |
33 | @end
34 |
35 | // "PowerAuthEncryptor" module
36 |
37 | PAJS_MODULE(PowerAuthEncryptorModule)
38 |
39 | /// Use native encryptor object with given identifier.
40 | /// - Parameters:
41 | /// - encryptorId: Encryptor's identifier.
42 | /// - reject: Reject function.
43 | /// - action: Action to execute when encryptor exists and can be used.
44 | - (void) useEncryptor:(nullable NSString*)encryptorId
45 | rejecter:(nonnull RCTPromiseRejectBlock)reject
46 | action:(NS_NOESCAPE void(^_Nonnull)(PowerAuthJsEncryptor * _Nonnull encryptor))action;
47 |
48 | /// Touch native encryptor object with given identifier in the object register.
49 | /// - Parameters:
50 | /// - encryptorId: Encryptor's identifier.
51 | /// - reject: Reject function.
52 | /// - action: Action to execute when encryptor exists and can be used.
53 | - (void) touchEncryptor:(nullable NSString*)encryptorId
54 | rejecter:(nonnull RCTPromiseRejectBlock)reject
55 | action:(NS_NOESCAPE void(^_Nonnull)(PowerAuthJsEncryptor * _Nonnull encryptor))action;
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/js/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wultra.android.powerauth.js;
18 |
19 | class Constants {
20 | /**
21 | * Default period in milliseconds for automatic objects cleanup job.
22 | */
23 | static final int CLEANUP_PERIOD_DEFAULT = 10_000;
24 | /**
25 | * Minimum allowed period for automatic objects cleanup job.
26 | */
27 | static final int CLEANUP_PERIOD_MIN = 100;
28 | /**
29 | * Maximum allowed period for automatic objects cleanup job.
30 | */
31 | static final int CLEANUP_PERIOD_MAX = 60_000;
32 | /**
33 | * Keep object in memory for one more second after the explicit remove.
34 | */
35 | static final int CLEANUP_REMOVE_DELAY = 1_000;
36 | /**
37 | * Time interval in milliseconds to keep pre-authorized biometric key in memory.
38 | */
39 | static final int BIOMETRY_KEY_KEEP_ALIVE_TIME = 10_000;
40 | /**
41 | * Time interval in milliseconds to keep password object valid in memory.
42 | */
43 | static final int PASSWORD_KEY_KEEP_ALIVE_TIME = 5 * 60 * 1_000;
44 | /**
45 | * Time interval in milliseconds to keep encryptor object valid in memory.
46 | */
47 | static final int ENCRYPTOR_KEY_KEEP_ALIVE_TIME = 5 * 60 * 1_000;
48 | /**
49 | * Time interval in milliseconds to keep decryptor object valid in memory.
50 | */
51 | static final int DECRYPTOR_KEY_KEEP_ALIVE_TIME = 5 * 60 * 1_000;
52 | /**
53 | * Upper limit for Unicode Code Point.
54 | */
55 | static final int CODEPOINT_MAX = 0x10FFFF;
56 |
57 | // Fallback strings
58 |
59 | /**
60 | * Fallback string used in biometric authentication when no title is
61 | * provided to authentication dialog.
62 | */
63 | static final String MISSING_REQUIRED_STRING = "< missing >";
64 | }
65 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/build.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 | //
3 | // Defaults for the standalone build
4 |
5 | PowerAuthSdkRN_kotlinVersion = "1.9.22"
6 | PowerAuthSdkRN_minSdkVersion = 21
7 | PowerAuthSdkRN_targetSdkVersion = 33
8 | PowerAuthSdkRN_compileSdkVersion = 33
9 | PowerAuthSdkRN_ndkversion = "21.4.7075529"
10 | PowerAuthSdkRN_reactNativeVersion = "0.78.1"
11 | }
12 |
13 | apply plugin: "com.android.library"
14 | apply plugin: "org.jetbrains.kotlin.android"
15 |
16 | buildscript {
17 | repositories {
18 | mavenCentral()
19 | google()
20 | }
21 |
22 | dependencies {
23 | classpath("com.android.tools.build:gradle")
24 | classpath("com.facebook.react:react-native-gradle-plugin")
25 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
26 | }
27 | }
28 |
29 | def isNewArchitectureEnabled() {
30 | return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
31 | }
32 |
33 | if (isNewArchitectureEnabled()) {
34 | apply plugin: "com.facebook.react"
35 | }
36 |
37 | def getExtOrDefault(name) {
38 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.ext["PowerAuthSdkRN_" + name]
39 | }
40 |
41 | def getExtOrIntegerDefault(name) {
42 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.ext["PowerAuthSdkRN_" + name]).toInteger()
43 | }
44 |
45 | android {
46 |
47 | namespace = "com.wultra.android.powerauth.reactnative"
48 | compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
49 |
50 | buildFeatures {
51 | buildConfig true
52 | }
53 |
54 | defaultConfig {
55 | minSdkVersion getExtOrIntegerDefault("minSdkVersion")
56 | targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
57 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
58 | }
59 | buildTypes {
60 | release {
61 | minifyEnabled false
62 | }
63 | }
64 |
65 | lintOptions {
66 | disable "GradleCompatible"
67 | }
68 |
69 | compileOptions {
70 | sourceCompatibility JavaVersion.VERSION_17
71 | targetCompatibility JavaVersion.VERSION_17
72 | }
73 | }
74 |
75 | repositories {
76 | mavenCentral()
77 | google()
78 | }
79 |
80 | dependencies {
81 | implementation("com.facebook.react:react-android")
82 | implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.22")
83 | api "com.wultra.android.powerauth:powerauth-sdk:1.9.5"
84 | }
85 |
86 | if (isNewArchitectureEnabled()) {
87 | react {
88 | jsRootDir = file("../src")
89 | libraryName = "PowerAuthReactNative"
90 | codegenJavaPackageName = "com.wultra.android.powerauth.reactnative"
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/packages/react-native-powerauth-mobile-sdk/android/src/main/java/com/wultra/android/powerauth/js/PowerAuthCryptoUtilsJsModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Wultra s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.wultra.android.powerauth.js
17 |
18 | import com.wultra.android.powerauth.bridge.JsApiMethod
19 | import com.wultra.android.powerauth.bridge.Promise
20 | import io.getlime.security.powerauth.core.CryptoUtils
21 | import android.util.Base64
22 |
23 | class PowerAuthCryptoUtilsJsModule() : BaseJavaJsModule {
24 | override fun getName(): String {
25 | return "PowerAuthCryptoUtils"
26 | }
27 |
28 | @JsApiMethod
29 | fun hashSha256(input: String, promise: Promise) {
30 | try {
31 | val decodedBytes: ByteArray = Base64.decode(input, Base64.NO_WRAP)
32 | val hash = CryptoUtils.hashSha256(decodedBytes)
33 | val encodedHash = Base64.encodeToString(hash, Base64.NO_WRAP)
34 | promise.resolve(encodedHash)
35 | } catch (e: IllegalArgumentException) {
36 | Errors.rejectPromise(promise, WrapperException(Errors.EC_WRONG_PARAMETER, "Input is not valid Base64.", e))
37 | } catch (t: Throwable) {
38 | Errors.rejectPromise(promise, t)
39 | }
40 | }
41 |
42 | @JsApiMethod
43 | fun randomBytes(length: Int, promise: Promise) {
44 | try {
45 | if (length < 0) {
46 | throw WrapperException(Errors.EC_WRONG_PARAMETER, "Length must be a non-negative integer")
47 | }
48 | // Handle zero-length explicitly to avoid calling underlying generator with 0,
49 | // and to return a valid Base64 for empty data (empty string)
50 | if (length == 0) {
51 | promise.resolve("")
52 | return
53 | }
54 | val randomBytes = CryptoUtils.randomBytes(length)
55 | val encodedBytes = Base64.encodeToString(randomBytes, Base64.NO_WRAP)
56 | promise.resolve(encodedBytes)
57 | } catch (t: Throwable) {
58 | Errors.rejectPromise(promise, t)
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/docs/Device-Activation-Removal.md:
--------------------------------------------------------------------------------
1 | # Device Activation Removal
2 |
3 | You can remove activation using several ways - the choice depends on the desired behavior.
4 |
5 | ## Simple Device-Only Removal
6 |
7 | You can clear activation data anytime from the Keychain. The benefit of this method is that it does not require help from the server, and the user does not have to be logged in. The issue with this removal method is simple: The activation still remains active on the server-side. This, however, does not have to be an issue in your case.
8 |
9 | To remove only data related to PowerAuth, use:
10 |
11 | ```javascript
12 | await powerAuth.removeActivationLocal();
13 | ```
14 |
15 | ## Removal via Authenticated Session
16 |
17 | Suppose your server uses an authenticated session for keeping the users logged in. In that case, you can combine the previous method with calling your proprietary endpoint to remove activation for the currently logged-in user. The advantage of this method is that activation does not remain active on the server. The issue is that the user has to be logged in (the session must be active and must have activation ID stored) and that you have to publish your own method to handle this use case.
18 |
19 | The code for this activation removal method is as follows:
20 |
21 | ```javascript
22 | // Use custom call to proprietary server endpoint to remove activation.
23 | // User must be logged in at this moment, so that session can find
24 | // associated activation ID
25 | httpClient.post(null, "/custom/activation/remove", async (error) => {
26 | if (error == null) {
27 | await powerAuth.removeActivationLocal();
28 | } else {
29 | // Report error
30 | }
31 | });
32 |
33 | ```
34 |
35 | ## Removal via Signed Request
36 |
37 | PowerAuth Standard RESTful API has a default endpoint `/pa/v3/activation/remove` for an activation removal. This endpoint uses a signature verification for looking up the activation to be removed. The benefit of this method is that it is already present in both PowerAuth JS SDK and PowerAuth Standard RESTful API - nothing has to be programmed. Also, the user does not have to be logged in to use it. However, the user has to authenticate using 2FA with either password or biometry.
38 |
39 | Use the following code for an activation removal using signed request:
40 |
41 | ```javascript
42 | // 2FA signature, uses device related key and user PIN code
43 | const auth = PowerAuthAuthentication.password("1234");
44 | try {
45 | await powerAuth.removeActivationWithAuthentication(auth);
46 | // activation removed
47 | } catch (e) {
48 | // failed to remove
49 | }
50 | ```
51 |
52 |
53 | ## Read Next
54 |
55 | - [End-To-End Encryption](End-To-End-Encryption.md)
56 |
57 |
--------------------------------------------------------------------------------