@qore-id/react-native-qoreid-sdk 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,12 +11,18 @@ Pod::Spec.new do |s|
11
11
  s.authors = package["author"]
12
12
 
13
13
  s.platforms = { :ios => min_ios_version_supported }
14
- s.source = { :git => "https://.git", :tag => "#{s.version}" }
14
+ s.source = { :git => "https://", :tag => "#{s.version}" }
15
15
 
16
16
  s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
17
- s.private_header_files = "ios/**/*.h"
18
- s.dependency 'QoreIDSDK'
19
17
 
18
+ if defined?($RNQoreidAsStaticFramework)
19
+ Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNQoreidAsStaticFramework}'"
20
+ s.static_framework = $RNQoreidAsStaticFramework
21
+ else
22
+ s.static_framework = false
23
+ end
24
+
25
+ s.dependency 'QoreIDSDK'
20
26
 
21
27
  install_modules_dependencies(s)
22
28
  end
@@ -21,6 +21,8 @@ apply plugin: "kotlin-android"
21
21
 
22
22
  apply plugin: "com.facebook.react"
23
23
 
24
+ apply from: file('../scripts/android/setupQoreid.gradle.kts')
25
+
24
26
  def getExtOrIntegerDefault(name) {
25
27
  return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["RNQoreIdSdk_" + name]).toInteger()
26
28
  }
@@ -8,9 +8,7 @@ import com.facebook.react.bridge.Arguments
8
8
  import com.facebook.react.bridge.BaseActivityEventListener
9
9
  import com.facebook.react.bridge.ReactApplicationContext
10
10
  import com.facebook.react.bridge.ReadableMap
11
- import com.facebook.react.bridge.WritableMap
12
11
  import com.facebook.react.module.annotations.ReactModule
13
- import com.facebook.react.modules.core.DeviceEventManagerModule
14
12
  import com.qoreid.sdk.core.OnFlowRequestIdCallback
15
13
  import com.qoreid.sdk.core.QoreIDParams
16
14
  import com.qoreid.sdk.core.QoreIDSdk
@@ -26,8 +24,7 @@ import com.qoreid.sdk.core.models.SuccessResult
26
24
  import com.qoreid.sdk.core.models.VerificationExtraData
27
25
 
28
26
  @ReactModule(name = RNQoreIdSdkModule.NAME)
29
- class RNQoreIdSdkModule(context: ReactApplicationContext) :
30
- NativeRNQoreIdSdkSpec(context) {
27
+ class RNQoreIdSdkModule(context: ReactApplicationContext) : NativeRNQoreIdSdkSpec(context) {
31
28
 
32
29
  override fun getName(): String {
33
30
  return NAME
@@ -36,40 +33,42 @@ class RNQoreIdSdkModule(context: ReactApplicationContext) :
36
33
  private var qoreIdResult: QoreIDResult? = null
37
34
 
38
35
  init {
39
- context.addActivityEventListener(object : BaseActivityEventListener () {
40
- override fun onActivityResult(
41
- activity: Activity,
42
- requestCode: Int,
43
- resultCode: Int,
44
- data: Intent?
45
- ) {
46
- if (resultCode == QORE_ID_RESULT_CODE && data!= null) {
47
- qoreIdResult =
48
- if (Build.VERSION.SDK_INT < 33) {
49
- data.extras?.getSerializable(QORE_ID_RESULT_EXTRA_KEY) as QoreIDResult
50
- } else {
51
- data.extras?.getSerializable(
52
- QORE_ID_RESULT_EXTRA_KEY,
53
- QoreIDResult::class.java
54
- )
36
+ context.addActivityEventListener(
37
+ object : BaseActivityEventListener() {
38
+ override fun onActivityResult(
39
+ activity: Activity,
40
+ requestCode: Int,
41
+ resultCode: Int,
42
+ data: Intent?
43
+ ) {
44
+ if (resultCode == QORE_ID_RESULT_CODE && data != null) {
45
+ qoreIdResult =
46
+ if (Build.VERSION.SDK_INT < 33) {
47
+ data.extras?.getSerializable(QORE_ID_RESULT_EXTRA_KEY) as QoreIDResult
48
+ } else {
49
+ data.extras?.getSerializable(
50
+ QORE_ID_RESULT_EXTRA_KEY,
51
+ QoreIDResult::class.java
52
+ )
53
+ }
54
+ processQoreIDResult(context, qoreIdResult!!)
55
+ }
56
+ }
55
57
  }
56
- processQoreIDResult(context, qoreIdResult!!)
57
- }
58
- }
59
- })
58
+ )
60
59
 
61
60
  QoreIDSdk.Callbacks.onFlowRequestId(
62
61
  object : OnFlowRequestIdCallback {
63
62
  override fun onValue(flowRequestId: Long) {
64
63
  Log.i("QORE_ID", flowRequestId.toString())
65
64
  val event =
66
- Arguments.createMap().apply {
65
+ Arguments.createMap().apply {
67
66
  putString("data", flowRequestId.toString())
68
67
  putString("message", "QOREID SDK INITIALIZED")
69
68
  putString("event", "SESSION_RESULT")
70
69
  }
71
70
 
72
- emitOnResult( event)
71
+ emitOnResult(event)
73
72
  }
74
73
  }
75
74
  )
@@ -157,7 +156,7 @@ class RNQoreIdSdkModule(context: ReactApplicationContext) :
157
156
 
158
157
  QoreIDSdk.s(BuildConfig.s)
159
158
  QoreIDSdk.params(qoreIDParams)
160
- QoreIDSdk.launch(requireNotNull(reactApplicationContext.currentActivity ))
159
+ QoreIDSdk.launch(requireNotNull(reactApplicationContext.currentActivity))
161
160
  }
162
161
 
163
162
  fun processQoreIDResult(context: ReactApplicationContext, qoreIdResult: QoreIDResult) {
package/app.plugin.js ADDED
@@ -0,0 +1,30 @@
1
+ const {
2
+ createRunOncePlugin,
3
+ withDangerousMod,
4
+ } = require('expo/config-plugins');
5
+
6
+ const { execSync } = require('child_process');
7
+
8
+ const pkg = require('@qore-id/react-native-qoreid-sdk/package.json');
9
+
10
+ const withQoreIdExpo = (config) => {
11
+ config = withDangerousMod(config, [
12
+ 'android',
13
+ (cfg) => {
14
+ execSync('npx qoreid-android-setup', { stdio: 'inherit' });
15
+ return cfg;
16
+ },
17
+ ]);
18
+
19
+ config = withDangerousMod(config, [
20
+ 'ios',
21
+ (cfg) => {
22
+ execSync('npx qoreid-ios-setup', { stdio: 'inherit' });
23
+ return cfg;
24
+ },
25
+ ]);
26
+
27
+ return config;
28
+ };
29
+
30
+ module.exports = createRunOncePlugin(withQoreIdExpo, pkg.name, pkg.version);
package/ios/RNQoreIdSdk.h CHANGED
@@ -1,14 +1 @@
1
- #import <RNQoreIdSdkSpec/RNQoreIdSdkSpec.h>
2
1
  #import <Foundation/Foundation.h>
3
-
4
- // When `use_frameworks!` is used, the generated Swift header is inside ExpoModulesCore module.
5
- // Otherwise, it's available only locally with double-quoted imports.
6
- #if __has_include(<RNQoreIdSdk/RNQoreIdSdk-Swift.h>)
7
- #import <RNQoreIdSdk/RNQoreIdSdk-Swift.h>
8
- #else
9
- #import "RNQoreIdSdk-Swift.h"
10
- #endif
11
-
12
- @interface RNQoreIdSdk : NativeRNQoreIdSdkSpecBase <NativeRNQoreIdSdkSpec>
13
-
14
- @end
@@ -1,33 +1,42 @@
1
1
  #import "RNQoreIdSdk.h"
2
+ #import <RNQoreIdSdkSpec/RNQoreIdSdkSpec.h>
2
3
  #import <UIKit/UIKit.h>
3
4
 
5
+ #if __has_include(<RNQoreIdSdk/RNQoreIdSdk-Swift.h>)
6
+ #import <RNQoreIdSdk/RNQoreIdSdk-Swift.h>
7
+ #else
8
+ #import "RNQoreIdSdk-Swift.h"
9
+ #endif
10
+
11
+ @interface RNQoreIdSdk : NativeRNQoreIdSdkSpecBase <NativeRNQoreIdSdkSpec>
12
+
13
+ @end
14
+
4
15
  @implementation RNQoreIdSdk {
5
16
  RCTRNQoreIdSdk *qoreIdSdk;
6
17
  }
7
18
 
8
- - (id) init {
19
+ - (id)init {
9
20
 
10
- if(self = [super init]) {
21
+ if (self = [super init]) {
11
22
 
12
23
  qoreIdSdk = [RCTRNQoreIdSdk shared];
13
24
 
14
- [qoreIdSdk setOnEmitResult:^(NSDictionary<NSString *,id> * _Nonnull result) {
15
- [self emitOnResult:result];
16
- }];
25
+ [qoreIdSdk
26
+ setOnEmitResult:^(NSDictionary<NSString *, id> *_Nonnull result) {
27
+ [self emitOnResult:result];
28
+ }];
17
29
  }
18
30
 
19
31
  return self;
20
32
  }
21
33
 
22
-
23
34
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
24
- (const facebook::react::ObjCTurboModule::InitParams &)params
25
- {
35
+ (const facebook::react::ObjCTurboModule::InitParams &)params {
26
36
  return std::make_shared<facebook::react::NativeRNQoreIdSdkSpecJSI>(params);
27
37
  }
28
38
 
29
- + (NSString *)moduleName
30
- {
39
+ + (NSString *)moduleName {
31
40
  return @"RNQoreIdSdk";
32
41
  }
33
42
 
@@ -5,18 +5,18 @@
5
5
  // Created by Guru King on 03/10/2023.
6
6
  //
7
7
 
8
- import UIKit
9
8
  import QoreIDSDK
9
+ import UIKit
10
10
 
11
11
  class ViewController: UIViewController {
12
- var param:QoreIDParam?
13
- var onQoreIdResult:((QoreIDResult) -> ())?
14
-
15
-
16
- override func viewDidLoad() {
17
- super.viewDidLoad()
18
- QoreIdSdk.shared.launch(param: param ?? QoreIDParam(), vc: self, "react_native_ios_sdk") { [weak self] result in
19
- self?.onQoreIdResult!(result)
20
- }
12
+ var param: QoreIDParam?
13
+ var onQoreIdResult: ((QoreIDResult) -> Void)?
14
+
15
+ override func viewDidLoad() {
16
+ super.viewDidLoad()
17
+ QoreIdSdk.shared.launch(param: param ?? QoreIDParam(), vc: self, "react_native_ios_sdk") {
18
+ [weak self] result in
19
+ self?.onQoreIdResult!(result)
21
20
  }
21
+ }
22
22
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qore-id/react-native-qoreid-sdk",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "QoreId React Native SDK",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -10,16 +10,20 @@
10
10
  "types": "./lib/typescript/src/index.d.ts",
11
11
  "default": "./lib/module/index.js"
12
12
  },
13
- "./package.json": "./package.json"
13
+ "./package.json": "./package.json",
14
+ "./plugin": "./app.plugin.js"
14
15
  },
15
16
  "files": [
16
17
  "src",
17
18
  "lib",
19
+ "scripts",
18
20
  "android",
19
21
  "ios",
20
22
  "cpp",
21
23
  "*.podspec",
24
+ "*.rb",
22
25
  "react-native.config.js",
26
+ "app.plugin.js",
23
27
  "!ios/build",
24
28
  "!android/build",
25
29
  "!android/gradle",
@@ -31,6 +35,12 @@
31
35
  "!**/__mocks__",
32
36
  "!**/.*"
33
37
  ],
38
+ "bin": {
39
+ "qoreid-android-setup": "./scripts/js/android-setup.js",
40
+ "qoreid-ios-setup": "./scripts/js/ios-setup.js",
41
+ "qoreid-setup": "./scripts/js/setup.js",
42
+ "qoreid-uninstall": "./scripts/js/uninstall.js"
43
+ },
34
44
  "scripts": {
35
45
  "example": "yarn workspace @qore-id/react-native-qoreid-sdk-example",
36
46
  "test": "jest",
@@ -38,12 +48,14 @@
38
48
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
39
49
  "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
40
50
  "prepare": "bob build",
41
- "release": "release-it --only-version"
51
+ "release": "release-it --only-version",
52
+ "preuninstall": "node ./scripts/js/uninstall.js"
42
53
  },
43
54
  "keywords": [
44
55
  "react-native",
45
56
  "ios",
46
- "android"
57
+ "android",
58
+ "expo"
47
59
  ],
48
60
  "repository": {
49
61
  "type": "git",
@@ -75,7 +87,10 @@
75
87
  "del-cli": "^6.0.0",
76
88
  "eslint": "^9.35.0",
77
89
  "eslint-config-prettier": "^10.1.8",
90
+ "eslint-plugin-jest": "^29.2.1",
78
91
  "eslint-plugin-prettier": "^5.5.4",
92
+ "expo": "^54.0.25",
93
+ "expo-module-scripts": "^5.0.7",
79
94
  "jest": "^29.7.0",
80
95
  "prettier": "^3.6.2",
81
96
  "react": "19.1.0",
@@ -87,9 +102,15 @@
87
102
  "typescript": "^5.9.2"
88
103
  },
89
104
  "peerDependencies": {
105
+ "expo": "*",
90
106
  "react": "*",
91
107
  "react-native": "*"
92
108
  },
109
+ "peerDependenciesMeta": {
110
+ "expo": {
111
+ "optional": true
112
+ }
113
+ },
93
114
  "workspaces": [
94
115
  "example"
95
116
  ],
@@ -0,0 +1,225 @@
1
+ import java.io.File
2
+
3
+ val rootGradleFile =
4
+ rootProject.file("build.gradle.kts").takeIf { it.exists() }
5
+ ?: rootProject.file("build.gradle")
6
+
7
+ val appBuildGradle = rootProject.file("app/build.gradle.kts").takeIf { it.exists() }
8
+ ?: rootProject.file("app/build.gradle")
9
+
10
+
11
+ // === Register setup task ===
12
+ rootProject.tasks.register("setupQoreid") {
13
+ group = "qoreid"
14
+ description = "One-click Qoreid SDK setup for React Native"
15
+ doLast {
16
+ // === 1. Add Maven repo to root build.gradle(.kts) ===
17
+ if (rootGradleFile.exists()) {
18
+ var content = rootGradleFile.readText()
19
+ if (!content.contains("repo.qoreid.com")) {
20
+
21
+ val mavenBlock = """
22
+ maven {
23
+ url = uri("https://repo.qoreid.com/repository/maven-releases/")
24
+ }
25
+ """.trimIndent()
26
+
27
+ if (content.contains("allprojects")) {
28
+ content = content.replace(
29
+ Regex("""allprojects\s\{\s*repositories\s*\{"""),
30
+ """allprojects {
31
+ repositories {
32
+ $mavenBlock"""
33
+ )
34
+ } else {
35
+ content += """
36
+
37
+ allprojects {
38
+ repositories {
39
+ google()
40
+ mavenCentral()
41
+ $mavenBlock
42
+ maven { url 'https://jitpack.io' }
43
+ }
44
+ }
45
+ """.trimIndent()
46
+ }
47
+
48
+ rootGradleFile.writeText(content)
49
+ println("Added Qoreid to repository")
50
+ } else {
51
+ println("Qoreid repo already added")
52
+ }
53
+ }
54
+
55
+ // === 2. Extract namespace ===
56
+ // Helpful to allow overriding via env var for CI/CD scenarios and CNG expo projects
57
+ val fullNamespace = System.getenv("FULL_ANDROID_NAMESPACE")
58
+
59
+ val namespace = fullNamespace ?: appBuildGradle.readText()
60
+ .let {
61
+ // Attempt 1: Standard assignment with quotes (e.g., namespace = "com.full.path")
62
+ Regex("""namespace\s*=\s*["']([^"']+)["']""").find(it)
63
+
64
+ // Attempt 2: Method call with quotes (e.g., namespace 'com.full.path')
65
+ // We use \s+ to ensure there is space after 'namespace'
66
+ ?: Regex("""namespace\s+["']([^"']+)["']""").find(it)
67
+
68
+ // Attempt 3: Assignment or method call without quotes (e.g., namespace com.full.path)
69
+ // This is less common but necessary if quotes are the issue.
70
+ // It captures any sequence of non-whitespace, non-quote characters after 'namespace'.
71
+ ?: Regex("""namespace\s*=?\s*([^\s"']+)""").find(it)
72
+ }
73
+ ?.groupValues?.get(1)
74
+ ?: "com.example.app"
75
+
76
+ val packagePath = namespace.replace('.', '/')
77
+ val possibleActivityFiles = listOf(
78
+ "app/src/main/java/$packagePath/MainActivity.kt",
79
+ "app/src/main/java/$packagePath/MainActivity.java",
80
+ "app/src/main/kotlin/$packagePath/MainActivity.kt",
81
+ "app/src/main/kotlin/$packagePath/MainActivity.java",
82
+ )
83
+
84
+ val activityFile = possibleActivityFiles
85
+ .map { rootProject.file(it) }
86
+ .firstOrNull { it.exists() }
87
+
88
+ if (activityFile == null) {
89
+ println("MainActivity not found! Searched for namespace: $namespace")
90
+ println("Please manually add RNQoreIdSdkModule.initialize(this) inside onCreate().")
91
+ } else {
92
+ var content = activityFile.readText()
93
+ val importLine = "import com.qoreid.reactnativeqoreidsdk.RNQoreIdSdkModule"
94
+ val initCall = "RNQoreIdSdkModule.initialize(this)"
95
+
96
+ var changed = false
97
+
98
+ // === (1) Insert import right after last import ===
99
+ if (!content.contains(importLine)) {
100
+ val importRegex = Regex("""import .+""")
101
+ val imports = importRegex.findAll(content).toList()
102
+
103
+ content = if (imports.isNotEmpty()) {
104
+ // Insert after last import
105
+ val lastImport = imports.last()
106
+ content.replaceRange(
107
+ lastImport.range.last + 1,
108
+ lastImport.range.last + 1,
109
+ "\n$importLine"
110
+ )
111
+ } else {
112
+ // No imports → insert after package
113
+ content.replace(
114
+ Regex("""(package .*)"""),
115
+ "$1\n$importLine"
116
+ )
117
+ }
118
+ changed = true
119
+ }
120
+
121
+ // === (2) Insert init call before the final '}' of onCreate ===
122
+ val onCreateRegex = Regex("""onCreate\s*\([^)]*\)\s*\{([\s\S]*?)\}""")
123
+ val match = onCreateRegex.find(content)
124
+
125
+ if (match != null && !content.contains(initCall)) {
126
+ val insertionPoint = match.range.last // just before the closing }
127
+
128
+ // rewrite: insert call before closing }
129
+ content = content.substring(0, insertionPoint) +
130
+ " \n$initCall\n " +
131
+ content.substring(insertionPoint)
132
+
133
+ changed = true
134
+ }
135
+
136
+ if (changed) {
137
+ activityFile.writeText(content)
138
+ println("Injected Qoreid init into ${activityFile.name}")
139
+ } else {
140
+ println("MainActivity already configured")
141
+ }
142
+ }
143
+
144
+ }
145
+ }
146
+
147
+
148
+ // =================================================================
149
+ // === Register removal task (CLEANUP) ===
150
+ // =================================================================
151
+ rootProject.tasks.register("removeQoreidSetup") {
152
+ group = "qoreid"
153
+ description = "Removes Qoreid SDK configuration from Android project files"
154
+ doLast {
155
+ // 1. Remove Maven repo from root build.gradle(.kts)
156
+ if (rootGradleFile.exists()) {
157
+ var content = rootGradleFile.readText()
158
+
159
+ val mavenBlock = """
160
+ maven {
161
+ url = uri("https://repo.qoreid.com/repository/maven-releases/")
162
+ }
163
+ """.trimIndent()
164
+
165
+ if (content.contains(mavenBlock)) {
166
+ // Replace the maven block with an empty string
167
+ content = content.replace(mavenBlock, "")
168
+
169
+ rootGradleFile.writeText(content)
170
+ println("Removed Qoreid Maven repository from ${rootGradleFile.name}")
171
+ } else {
172
+ println("Qoreid repo not found in root build.gradle - skipping removal.")
173
+ }
174
+ }
175
+
176
+ // 2. Remove configuration from MainActivity
177
+ val namespace = appBuildGradle.readText()
178
+ .let { text ->
179
+ Regex("""namespace\s*=\s*["']([^"']+)["']""").find(text)
180
+ ?: Regex("""namespace ["']([^"']+)["']""").find(text)
181
+ }?.groupValues?.get(1)
182
+ ?: "com.example.app"
183
+
184
+ val packagePath = namespace.replace('.', '/')
185
+ val possibleActivityFiles = listOf(
186
+ "app/src/main/java/$packagePath/MainActivity.kt",
187
+ "app/src/main/java/$packagePath/MainActivity.java",
188
+ "app/src/main/kotlin/$packagePath/MainActivity.kt",
189
+ "app/src/main/kotlin/$packagePath/MainActivity.java",
190
+ )
191
+
192
+ val activityFile = possibleActivityFiles
193
+ .map { rootProject.file(it) }
194
+ .firstOrNull { it.exists() }
195
+ if (activityFile != null && activityFile.exists()) {
196
+ var content = activityFile.readText()
197
+ val importLine = "import com.qoreid.reactnativeqoreidsdk.RNQoreIdSdkModule"
198
+ val initCall = "RNQoreIdSdkModule.initialize(this)"
199
+ var changed = false
200
+
201
+ // Remove import line (must handle leading newline)
202
+ if (content.contains(importLine)) {
203
+ // Remove the import line, including the preceding newline
204
+ content = content.replace("\n$importLine", "")
205
+ changed = true
206
+ }
207
+
208
+ // Remove init call (must handle surrounding formatting added by setup script)
209
+ if (content.contains(initCall)) {
210
+ // Safely remove the call along with its preceding whitespace and the newline
211
+ // inserted by the setup script (which used " $initCall\n ")
212
+ // Escaping the initCall string is crucial for safe regex use.
213
+ content = content.replace(Regex("""\s*${Regex.escape(initCall)}\s*\n?"""), "")
214
+ changed = true
215
+ }
216
+
217
+ if (changed) {
218
+ activityFile.writeText(content)
219
+ println("Removed Qoreid init and import from ${activityFile.name}")
220
+ } else {
221
+ println("MainActivity was not configured for Qoreid - skipping removal.")
222
+ }
223
+ }
224
+ }
225
+ }