react-native-authsignal 2.5.0 → 2.8.0-alpha.1

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.
Files changed (188) hide show
  1. package/android/build.gradle +3 -19
  2. package/android/gradle.properties +1 -1
  3. package/android/src/main/java/com/authsignal/react/AuthsignalEmailModule.kt +11 -18
  4. package/android/src/main/java/com/authsignal/react/AuthsignalInAppModule.kt +66 -45
  5. package/android/src/main/java/com/authsignal/react/AuthsignalModule.kt +25 -39
  6. package/android/src/main/java/com/authsignal/react/AuthsignalPackage.kt +70 -17
  7. package/android/src/main/java/com/authsignal/react/AuthsignalPasskeyModule.kt +23 -17
  8. package/android/src/main/java/com/authsignal/react/AuthsignalPushModule.kt +16 -21
  9. package/android/src/main/java/com/authsignal/react/AuthsignalQRCodeModule.kt +16 -22
  10. package/android/src/main/java/com/authsignal/react/AuthsignalSMSModule.kt +11 -25
  11. package/android/src/main/java/com/authsignal/react/AuthsignalTOTPModule.kt +10 -17
  12. package/android/src/main/java/com/authsignal/react/AuthsignalWhatsappModule.kt +10 -23
  13. package/ios/AuthsignalEmailModule.m +7 -7
  14. package/ios/AuthsignalEmailModule.swift +10 -9
  15. package/ios/AuthsignalInAppModule.m +18 -17
  16. package/ios/AuthsignalInAppModule.swift +42 -27
  17. package/ios/AuthsignalModule.m +4 -4
  18. package/ios/AuthsignalModule.swift +14 -10
  19. package/ios/AuthsignalPasskeyModule.m +10 -10
  20. package/ios/AuthsignalPasskeyModule.swift +22 -21
  21. package/ios/AuthsignalPushModule.m +9 -9
  22. package/ios/AuthsignalPushModule.swift +14 -13
  23. package/ios/AuthsignalQRModule.m +10 -10
  24. package/ios/AuthsignalQRModule.swift +15 -14
  25. package/ios/AuthsignalSMSModule.m +7 -7
  26. package/ios/AuthsignalSMSModule.swift +10 -9
  27. package/ios/AuthsignalTOTPModule.m +5 -5
  28. package/ios/AuthsignalTOTPModule.swift +8 -7
  29. package/ios/AuthsignalTurboModules.mm +26 -0
  30. package/ios/AuthsignalWhatsappModule.m +5 -5
  31. package/ios/AuthsignalWhatsappModule.swift +8 -7
  32. package/lib/commonjs/NativeAuthsignalEmailModule.js +9 -0
  33. package/lib/commonjs/NativeAuthsignalEmailModule.js.map +1 -0
  34. package/lib/commonjs/NativeAuthsignalInAppModule.js +9 -0
  35. package/lib/commonjs/NativeAuthsignalInAppModule.js.map +1 -0
  36. package/lib/commonjs/NativeAuthsignalModule.js +9 -0
  37. package/lib/commonjs/NativeAuthsignalModule.js.map +1 -0
  38. package/lib/commonjs/NativeAuthsignalPasskeyModule.js +9 -0
  39. package/lib/commonjs/NativeAuthsignalPasskeyModule.js.map +1 -0
  40. package/lib/commonjs/NativeAuthsignalPushModule.js +9 -0
  41. package/lib/commonjs/NativeAuthsignalPushModule.js.map +1 -0
  42. package/lib/commonjs/NativeAuthsignalQRCodeModule.js +9 -0
  43. package/lib/commonjs/NativeAuthsignalQRCodeModule.js.map +1 -0
  44. package/lib/commonjs/NativeAuthsignalSMSModule.js +9 -0
  45. package/lib/commonjs/NativeAuthsignalSMSModule.js.map +1 -0
  46. package/lib/commonjs/NativeAuthsignalTOTPModule.js +9 -0
  47. package/lib/commonjs/NativeAuthsignalTOTPModule.js.map +1 -0
  48. package/lib/commonjs/NativeAuthsignalWhatsappModule.js +9 -0
  49. package/lib/commonjs/NativeAuthsignalWhatsappModule.js.map +1 -0
  50. package/lib/commonjs/email.js +7 -9
  51. package/lib/commonjs/email.js.map +1 -1
  52. package/lib/commonjs/getNativeModule.js +23 -0
  53. package/lib/commonjs/getNativeModule.js.map +1 -0
  54. package/lib/commonjs/inapp.js +15 -16
  55. package/lib/commonjs/inapp.js.map +1 -1
  56. package/lib/commonjs/index.js +8 -29
  57. package/lib/commonjs/index.js.map +1 -1
  58. package/lib/commonjs/index.web.js +9 -3
  59. package/lib/commonjs/index.web.js.map +1 -1
  60. package/lib/commonjs/passkey.js +21 -31
  61. package/lib/commonjs/passkey.js.map +1 -1
  62. package/lib/commonjs/push.js +8 -10
  63. package/lib/commonjs/push.js.map +1 -1
  64. package/lib/commonjs/qr.js +8 -10
  65. package/lib/commonjs/qr.js.map +1 -1
  66. package/lib/commonjs/sms.js +7 -9
  67. package/lib/commonjs/sms.js.map +1 -1
  68. package/lib/commonjs/totp.js +7 -9
  69. package/lib/commonjs/totp.js.map +1 -1
  70. package/lib/commonjs/types.js +6 -1
  71. package/lib/commonjs/types.js.map +1 -1
  72. package/lib/commonjs/whatsapp.js +7 -9
  73. package/lib/commonjs/whatsapp.js.map +1 -1
  74. package/lib/module/NativeAuthsignalEmailModule.js +3 -0
  75. package/lib/module/NativeAuthsignalEmailModule.js.map +1 -0
  76. package/lib/module/NativeAuthsignalInAppModule.js +3 -0
  77. package/lib/module/NativeAuthsignalInAppModule.js.map +1 -0
  78. package/lib/module/NativeAuthsignalModule.js +3 -0
  79. package/lib/module/NativeAuthsignalModule.js.map +1 -0
  80. package/lib/module/NativeAuthsignalPasskeyModule.js +3 -0
  81. package/lib/module/NativeAuthsignalPasskeyModule.js.map +1 -0
  82. package/lib/module/NativeAuthsignalPushModule.js +3 -0
  83. package/lib/module/NativeAuthsignalPushModule.js.map +1 -0
  84. package/lib/module/NativeAuthsignalQRCodeModule.js +3 -0
  85. package/lib/module/NativeAuthsignalQRCodeModule.js.map +1 -0
  86. package/lib/module/NativeAuthsignalSMSModule.js +3 -0
  87. package/lib/module/NativeAuthsignalSMSModule.js.map +1 -0
  88. package/lib/module/NativeAuthsignalTOTPModule.js +3 -0
  89. package/lib/module/NativeAuthsignalTOTPModule.js.map +1 -0
  90. package/lib/module/NativeAuthsignalWhatsappModule.js +3 -0
  91. package/lib/module/NativeAuthsignalWhatsappModule.js.map +1 -0
  92. package/lib/module/email.js +7 -10
  93. package/lib/module/email.js.map +1 -1
  94. package/lib/module/getNativeModule.js +17 -0
  95. package/lib/module/getNativeModule.js.map +1 -0
  96. package/lib/module/inapp.js +15 -17
  97. package/lib/module/inapp.js.map +1 -1
  98. package/lib/module/index.js +6 -29
  99. package/lib/module/index.js.map +1 -1
  100. package/lib/module/index.web.js +9 -3
  101. package/lib/module/index.web.js.map +1 -1
  102. package/lib/module/passkey.js +22 -33
  103. package/lib/module/passkey.js.map +1 -1
  104. package/lib/module/push.js +8 -11
  105. package/lib/module/push.js.map +1 -1
  106. package/lib/module/qr.js +8 -11
  107. package/lib/module/qr.js.map +1 -1
  108. package/lib/module/sms.js +7 -10
  109. package/lib/module/sms.js.map +1 -1
  110. package/lib/module/totp.js +7 -10
  111. package/lib/module/totp.js.map +1 -1
  112. package/lib/module/types.js +5 -0
  113. package/lib/module/types.js.map +1 -1
  114. package/lib/module/whatsapp.js +7 -10
  115. package/lib/module/whatsapp.js.map +1 -1
  116. package/lib/typescript/NativeAuthsignalEmailModule.d.ts +10 -0
  117. package/lib/typescript/NativeAuthsignalEmailModule.d.ts.map +1 -0
  118. package/lib/typescript/NativeAuthsignalInAppModule.d.ts +15 -0
  119. package/lib/typescript/NativeAuthsignalInAppModule.d.ts.map +1 -0
  120. package/lib/typescript/NativeAuthsignalModule.d.ts +8 -0
  121. package/lib/typescript/NativeAuthsignalModule.d.ts.map +1 -0
  122. package/lib/typescript/NativeAuthsignalPasskeyModule.d.ts +12 -0
  123. package/lib/typescript/NativeAuthsignalPasskeyModule.d.ts.map +1 -0
  124. package/lib/typescript/NativeAuthsignalPushModule.d.ts +12 -0
  125. package/lib/typescript/NativeAuthsignalPushModule.d.ts.map +1 -0
  126. package/lib/typescript/NativeAuthsignalQRCodeModule.d.ts +12 -0
  127. package/lib/typescript/NativeAuthsignalQRCodeModule.d.ts.map +1 -0
  128. package/lib/typescript/NativeAuthsignalSMSModule.d.ts +10 -0
  129. package/lib/typescript/NativeAuthsignalSMSModule.d.ts.map +1 -0
  130. package/lib/typescript/NativeAuthsignalTOTPModule.d.ts +9 -0
  131. package/lib/typescript/NativeAuthsignalTOTPModule.d.ts.map +1 -0
  132. package/lib/typescript/NativeAuthsignalWhatsappModule.d.ts +9 -0
  133. package/lib/typescript/NativeAuthsignalWhatsappModule.d.ts.map +1 -0
  134. package/lib/typescript/email.d.ts +1 -0
  135. package/lib/typescript/email.d.ts.map +1 -1
  136. package/lib/typescript/getNativeModule.d.ts +2 -0
  137. package/lib/typescript/getNativeModule.d.ts.map +1 -0
  138. package/lib/typescript/inapp.d.ts +2 -1
  139. package/lib/typescript/inapp.d.ts.map +1 -1
  140. package/lib/typescript/index.d.ts +3 -2
  141. package/lib/typescript/index.d.ts.map +1 -1
  142. package/lib/typescript/index.web.d.ts +3 -2
  143. package/lib/typescript/index.web.d.ts.map +1 -1
  144. package/lib/typescript/passkey.d.ts +2 -0
  145. package/lib/typescript/passkey.d.ts.map +1 -1
  146. package/lib/typescript/push.d.ts +1 -0
  147. package/lib/typescript/push.d.ts.map +1 -1
  148. package/lib/typescript/qr.d.ts +1 -0
  149. package/lib/typescript/qr.d.ts.map +1 -1
  150. package/lib/typescript/sms.d.ts +1 -0
  151. package/lib/typescript/sms.d.ts.map +1 -1
  152. package/lib/typescript/totp.d.ts +1 -0
  153. package/lib/typescript/totp.d.ts.map +1 -1
  154. package/lib/typescript/types.d.ts +13 -0
  155. package/lib/typescript/types.d.ts.map +1 -1
  156. package/lib/typescript/whatsapp.d.ts +1 -0
  157. package/lib/typescript/whatsapp.d.ts.map +1 -1
  158. package/package.json +10 -1
  159. package/react-native-authsignal.podspec +3 -2
  160. package/src/NativeAuthsignalEmailModule.ts +10 -0
  161. package/src/NativeAuthsignalInAppModule.ts +32 -0
  162. package/src/NativeAuthsignalModule.ts +8 -0
  163. package/src/NativeAuthsignalPasskeyModule.ts +26 -0
  164. package/src/NativeAuthsignalPushModule.ts +20 -0
  165. package/src/NativeAuthsignalQRCodeModule.ts +20 -0
  166. package/src/NativeAuthsignalSMSModule.ts +10 -0
  167. package/src/NativeAuthsignalTOTPModule.ts +9 -0
  168. package/src/NativeAuthsignalWhatsappModule.ts +9 -0
  169. package/src/email.ts +90 -0
  170. package/src/email.web.ts +105 -0
  171. package/src/error.ts +28 -0
  172. package/src/error.web.ts +21 -0
  173. package/src/getNativeModule.ts +28 -0
  174. package/src/inapp.ts +220 -0
  175. package/src/index.tsx +80 -0
  176. package/src/index.web.tsx +99 -0
  177. package/src/passkey.ts +165 -0
  178. package/src/passkey.web.ts +153 -0
  179. package/src/push.ts +147 -0
  180. package/src/qr.ts +150 -0
  181. package/src/sms.ts +92 -0
  182. package/src/sms.web.ts +107 -0
  183. package/src/totp.ts +79 -0
  184. package/src/totp.web.ts +95 -0
  185. package/src/types.ts +167 -0
  186. package/src/web-client.ts +29 -0
  187. package/src/whatsapp.ts +76 -0
  188. package/src/whatsapp.web.ts +83 -0
@@ -1,19 +1,6 @@
1
- buildscript {
2
- def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["Authsignal_kotlinVersion"]
3
-
4
- repositories {
5
- google()
6
- mavenCentral()
7
- }
8
-
9
- dependencies {
10
- classpath 'com.android.tools.build:gradle:8.1.4'
11
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
12
- }
13
- }
14
-
15
1
  apply plugin: 'com.android.library'
16
2
  apply plugin: 'org.jetbrains.kotlin.android'
3
+ apply plugin: 'com.facebook.react'
17
4
 
18
5
  def getExtOrDefault(name) {
19
6
  return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['Authsignal_' + name]
@@ -45,7 +32,7 @@ android {
45
32
  }
46
33
  }
47
34
 
48
- lintOptions {
35
+ lint {
49
36
  disable 'GradleCompatible'
50
37
  }
51
38
 
@@ -68,14 +55,11 @@ repositories {
68
55
  google()
69
56
  }
70
57
 
71
- def kotlin_version = getExtOrDefault("kotlinVersion")
72
-
73
58
  dependencies {
74
59
  //noinspection GradleDynamicVersion
75
60
  implementation "com.facebook.react:react-native:+"
76
- implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
77
61
 
78
62
  implementation "androidx.browser:browser:1.2.0"
79
63
 
80
- implementation("com.authsignal:authsignal-android:3.4.0")
64
+ implementation("com.authsignal:authsignal-android:3.4.1-alpha.1")
81
65
  }
@@ -1,4 +1,4 @@
1
- Authsignal_kotlinVersion=1.9.24
1
+ Authsignal_kotlinVersion=2.1.0
2
2
  Authsignal_minSdkVersion=24
3
3
  Authsignal_targetSdkVersion=34
4
4
  Authsignal_compileSdkVersion=34
@@ -5,35 +5,24 @@ import com.authsignal.email.AuthsignalEmail
5
5
  import com.facebook.react.bridge.Arguments
6
6
  import com.facebook.react.bridge.Promise
7
7
  import com.facebook.react.bridge.ReactApplicationContext
8
- import com.facebook.react.bridge.ReactContextBaseJavaModule
9
8
  import com.facebook.react.bridge.ReactMethod
9
+ import com.facebook.react.module.annotations.ReactModule
10
10
  import kotlinx.coroutines.CoroutineScope
11
11
  import kotlinx.coroutines.Dispatchers
12
12
  import kotlinx.coroutines.SupervisorJob
13
13
  import kotlinx.coroutines.launch
14
14
 
15
+ @ReactModule(name = AuthsignalEmailModule.NAME)
15
16
  class AuthsignalEmailModule(private val reactContext: ReactApplicationContext) :
16
- ReactContextBaseJavaModule(
17
- reactContext
18
- ) {
17
+ NativeAuthsignalEmailModuleSpec(reactContext) {
19
18
  private var authsignal: AuthsignalEmail? = null
20
19
 
21
20
  private val defaultError = "unexpected_error"
22
21
 
23
22
  private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
24
23
 
25
- override fun getConstants(): Map<String, Any>? {
26
- val constants: MutableMap<String, Any> = HashMap()
27
- constants["bundleIdentifier"] = reactContext.applicationInfo.packageName
28
- return constants
29
- }
30
-
31
- override fun getName(): String {
32
- return "AuthsignalEmailModule"
33
- }
34
-
35
24
  @ReactMethod
36
- fun initialize(tenantID: String, baseURL: String, promise: Promise) {
25
+ override fun initialize(tenantID: String, baseURL: String, promise: Promise) {
37
26
  val currentActivity = reactContext.currentActivity
38
27
 
39
28
  if (currentActivity != null) {
@@ -44,7 +33,7 @@ class AuthsignalEmailModule(private val reactContext: ReactApplicationContext) :
44
33
  }
45
34
 
46
35
  @ReactMethod
47
- fun enroll(email: String, promise: Promise) {
36
+ override fun enroll(email: String, promise: Promise) {
48
37
  launch(promise) {
49
38
  val response = it.enroll(email)
50
39
 
@@ -62,7 +51,7 @@ class AuthsignalEmailModule(private val reactContext: ReactApplicationContext) :
62
51
  }
63
52
 
64
53
  @ReactMethod
65
- fun challenge(promise: Promise) {
54
+ override fun challenge(promise: Promise) {
66
55
  launch(promise) {
67
56
  val response = it.challenge()
68
57
 
@@ -80,7 +69,7 @@ class AuthsignalEmailModule(private val reactContext: ReactApplicationContext) :
80
69
  }
81
70
 
82
71
  @ReactMethod
83
- fun verify(code: String, promise: Promise) {
72
+ override fun verify(code: String, promise: Promise) {
84
73
  launch(promise) {
85
74
  val response = it.verify(code)
86
75
 
@@ -110,4 +99,8 @@ class AuthsignalEmailModule(private val reactContext: ReactApplicationContext) :
110
99
  }
111
100
  }
112
101
  }
102
+
103
+ companion object {
104
+ const val NAME = "AuthsignalEmailModule"
105
+ }
113
106
  }
@@ -2,44 +2,35 @@ package com.authsignal.react
2
2
 
3
3
  import android.util.Log
4
4
  import com.authsignal.inapp.AuthsignalInApp
5
+ import com.authsignal.models.api.AppAttestation
6
+ import com.authsignal.models.api.AppAttestationProvider
5
7
  import com.facebook.react.bridge.Arguments
6
8
  import com.facebook.react.bridge.Promise
7
9
  import com.facebook.react.bridge.ReactApplicationContext
8
- import com.facebook.react.bridge.ReactContextBaseJavaModule
9
10
  import com.facebook.react.bridge.ReactMethod
11
+ import com.facebook.react.bridge.ReadableMap
12
+ import com.facebook.react.module.annotations.ReactModule
10
13
  import kotlinx.coroutines.CoroutineScope
11
14
  import kotlinx.coroutines.Dispatchers
12
15
  import kotlinx.coroutines.SupervisorJob
13
16
  import kotlinx.coroutines.launch
14
17
 
18
+ @ReactModule(name = AuthsignalInAppModule.NAME)
15
19
  class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
16
- ReactContextBaseJavaModule(
17
- reactContext
18
- ) {
20
+ NativeAuthsignalInAppModuleSpec(reactContext) {
19
21
  private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
20
22
  private var authsignal: AuthsignalInApp? = null
21
23
  private var defaultError = "unexpected_error"
22
24
 
23
- override fun getConstants(): Map<String, Any>? {
24
- val constants: MutableMap<String, Any> = HashMap()
25
- constants["bundleIdentifier"] = reactContext.applicationInfo.packageName
26
- return constants
27
- }
28
-
29
- override fun getName(): String {
30
- return "AuthsignalInAppModule"
31
- }
32
-
33
25
  @ReactMethod
34
- fun initialize(tenantID: String?, baseURL: String?, promise: Promise) {
35
- Log.d("AuthsignalInAppModule", "initialize: $tenantID, $baseURL")
36
- authsignal = AuthsignalInApp(tenantID!!, baseURL!!, context = reactContext)
26
+ override fun initialize(tenantID: String, baseURL: String, promise: Promise) {
27
+ authsignal = AuthsignalInApp(tenantID, baseURL, context = reactContext)
37
28
 
38
29
  promise.resolve(null)
39
30
  }
40
31
 
41
32
  @ReactMethod
42
- fun getCredential(username: String?, promise: Promise) {
33
+ override fun getCredential(username: String?, promise: Promise) {
43
34
  launch(promise) {
44
35
  val response = it.getCredential(username = username)
45
36
 
@@ -62,11 +53,24 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
62
53
  }
63
54
 
64
55
  @ReactMethod
65
- fun addCredential(
56
+ override fun addCredential(
66
57
  token: String?,
58
+ _requireUserAuthentication: Boolean,
59
+ _keychainAccess: String?,
67
60
  username: String?,
61
+ appAttestationMap: ReadableMap?,
68
62
  promise: Promise
69
63
  ) {
64
+ val appAttestation = appAttestationMap?.let { map ->
65
+ val attestationToken = map.getString("token") ?: return@let null
66
+ val provider = when (map.getString("provider")) {
67
+ "playIntegrity" -> AppAttestationProvider.PLAY_INTEGRITY
68
+ else -> AppAttestationProvider.PLAY_INTEGRITY
69
+ }
70
+ val keyId = if (map.hasKey("keyId")) map.getString("keyId") else null
71
+ AppAttestation(provider = provider, token = attestationToken, keyId = keyId)
72
+ }
73
+
70
74
  launch(promise) {
71
75
  val response = it.addCredential(
72
76
  token = token,
@@ -75,6 +79,7 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
75
79
  timeout = 0,
76
80
  authorizationType = 0,
77
81
  username = username,
82
+ appAttestation = appAttestation,
78
83
  )
79
84
 
80
85
  if (response.error != null) {
@@ -94,7 +99,7 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
94
99
  }
95
100
 
96
101
  @ReactMethod
97
- fun removeCredential(username: String?, promise: Promise) {
102
+ override fun removeCredential(username: String?, promise: Promise) {
98
103
  launch(promise) {
99
104
  val response = it.removeCredential(username = username)
100
105
 
@@ -109,7 +114,7 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
109
114
  }
110
115
 
111
116
  @ReactMethod
112
- fun verify(
117
+ override fun verify(
113
118
  action: String?,
114
119
  username: String?,
115
120
  promise: Promise
@@ -122,19 +127,23 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
122
127
 
123
128
  promise.reject(errorCode, response.error)
124
129
  } else {
125
- val data = response.data!!
126
- val map = Arguments.createMap()
127
- map.putString("token", data.token)
128
- map.putString("userId", data.userId)
129
- map.putString("userAuthenticatorId", data.userAuthenticatorId)
130
- map.putString("username", data.username)
131
- promise.resolve(map)
130
+ val data = response.data
131
+ if (data != null) {
132
+ val map = Arguments.createMap()
133
+ map.putString("token", data.token)
134
+ map.putString("userId", data.userId)
135
+ map.putString("userAuthenticatorId", data.userAuthenticatorId)
136
+ map.putString("username", data.username)
137
+ promise.resolve(map)
138
+ } else {
139
+ promise.reject(defaultError, "No data returned")
140
+ }
132
141
  }
133
142
  }
134
143
  }
135
144
 
136
145
  @ReactMethod
137
- fun createPin(pin: String, username: String, token: String?, promise: Promise) {
146
+ override fun createPin(pin: String, username: String, token: String?, promise: Promise) {
138
147
  launch(promise) {
139
148
  val response = it.createPin(
140
149
  pin = pin,
@@ -147,19 +156,23 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
147
156
 
148
157
  promise.reject(errorCode, response.error)
149
158
  } else {
150
- val data = response.data!!
151
- val map = Arguments.createMap()
152
- map.putString("credentialId", data.credentialId)
153
- map.putString("createdAt", data.createdAt)
154
- map.putString("userId", data.userId)
155
- map.putString("lastAuthenticatedAt", data.lastAuthenticatedAt)
156
- promise.resolve(map)
159
+ val data = response.data
160
+ if (data != null) {
161
+ val map = Arguments.createMap()
162
+ map.putString("credentialId", data.credentialId)
163
+ map.putString("createdAt", data.createdAt)
164
+ map.putString("userId", data.userId)
165
+ map.putString("lastAuthenticatedAt", data.lastAuthenticatedAt)
166
+ promise.resolve(map)
167
+ } else {
168
+ promise.reject(defaultError, "No data returned")
169
+ }
157
170
  }
158
171
  }
159
172
  }
160
173
 
161
174
  @ReactMethod
162
- fun verifyPin(pin: String, username: String, action: String?, promise: Promise) {
175
+ override fun verifyPin(pin: String, username: String, action: String?, promise: Promise) {
163
176
  launch(promise) {
164
177
  val response = it.verifyPin(
165
178
  pin = pin,
@@ -172,18 +185,22 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
172
185
 
173
186
  promise.reject(errorCode, response.error)
174
187
  } else {
175
- val data = response.data!!
176
- val map = Arguments.createMap()
177
- map.putBoolean("isVerified", data.isVerified)
178
- map.putString("token", data.token)
179
- map.putString("userId", data.userId)
180
- promise.resolve(map)
188
+ val data = response.data
189
+ if (data != null) {
190
+ val map = Arguments.createMap()
191
+ map.putBoolean("isVerified", data.isVerified)
192
+ map.putString("token", data.token)
193
+ map.putString("userId", data.userId)
194
+ promise.resolve(map)
195
+ } else {
196
+ promise.reject(defaultError, "No data returned")
197
+ }
181
198
  }
182
199
  }
183
200
  }
184
201
 
185
202
  @ReactMethod
186
- fun deletePin(username: String, promise: Promise) {
203
+ override fun deletePin(username: String, promise: Promise) {
187
204
  launch(promise) {
188
205
  val response = it.deletePin(username = username)
189
206
 
@@ -198,7 +215,7 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
198
215
  }
199
216
 
200
217
  @ReactMethod
201
- fun getAllPinUsernames(promise: Promise) {
218
+ override fun getAllPinUsernames(promise: Promise) {
202
219
  launch(promise) {
203
220
  val response = it.getAllPinUsernames()
204
221
 
@@ -225,4 +242,8 @@ class AuthsignalInAppModule(private val reactContext: ReactApplicationContext) :
225
242
  }
226
243
  }
227
244
  }
245
+
246
+ companion object {
247
+ const val NAME = "AuthsignalInAppModule"
248
+ }
228
249
  }
@@ -7,61 +7,49 @@ import android.net.Uri
7
7
  import com.authsignal.TokenCache.Companion.shared
8
8
  import com.authsignal.react.AuthenticationActivity.Companion.authenticateUsingBrowser
9
9
  import com.facebook.react.bridge.ActivityEventListener
10
- import com.facebook.react.bridge.Arguments
11
- import com.facebook.react.bridge.Callback
12
10
  import com.facebook.react.bridge.Promise
13
11
  import com.facebook.react.bridge.ReactApplicationContext
14
- import com.facebook.react.bridge.ReactContextBaseJavaModule
15
12
  import com.facebook.react.bridge.ReactMethod
13
+ import com.facebook.react.module.annotations.ReactModule
16
14
  import java.net.URLDecoder
17
15
 
16
+ @ReactModule(name = AuthsignalModule.NAME)
18
17
  class AuthsignalModule(private val reactContext: ReactApplicationContext) :
19
- ReactContextBaseJavaModule(
20
- reactContext
21
- ), ActivityEventListener {
22
- private var callback: Callback? = null
18
+ NativeAuthsignalModuleSpec(reactContext), ActivityEventListener {
19
+ private var launchPromise: Promise? = null
23
20
 
24
21
  init {
25
22
  reactContext.addActivityEventListener(this)
26
23
  }
27
24
 
28
- override fun getConstants(): Map<String, Any>? {
29
- val constants: MutableMap<String, Any> = HashMap()
30
- constants["bundleIdentifier"] = reactContext.applicationInfo.packageName
31
- return constants
32
- }
33
-
34
- override fun getName(): String {
35
- return "AuthsignalModule"
36
- }
37
-
38
25
  @ReactMethod
39
- fun setToken(token: String?, promise: Promise) {
26
+ override fun setToken(token: String?, promise: Promise) {
40
27
  shared.token = token
41
28
 
42
29
  promise.resolve("token_set")
43
30
  }
44
31
 
45
32
  @ReactMethod
46
- fun launch(url: String?, callback: Callback) {
33
+ override fun launch(url: String?, promise: Promise) {
34
+ if (url == null) {
35
+ promise.reject("invalid_url", "Launch URL must not be null.")
36
+ return
37
+ }
38
+
47
39
  val activity = reactContext.currentActivity
48
40
  val parsedUrl = Uri.parse(url)
49
- this.callback = callback
41
+ this.launchPromise = promise
50
42
 
51
43
  try {
52
44
  if (activity != null) {
53
45
  authenticateUsingBrowser(activity, parsedUrl)
54
46
  } else {
55
- val error = Arguments.createMap()
56
- error.putString("error", "activity_not_available")
57
- error.putString("error_description", "Android Activity is null.")
58
- callback.invoke(error)
47
+ promise.reject("activity_not_available", "Android Activity is null.")
48
+ this.launchPromise = null
59
49
  }
60
50
  } catch (e: ActivityNotFoundException) {
61
- val error = Arguments.createMap()
62
- error.putString("error", "browser_not_available")
63
- error.putString("error_description", "No browser app is installed")
64
- callback.invoke(error)
51
+ promise.reject("browser_not_available", "No browser app is installed")
52
+ this.launchPromise = null
65
53
  }
66
54
  }
67
55
 
@@ -71,7 +59,7 @@ class AuthsignalModule(private val reactContext: ReactApplicationContext) :
71
59
  resultCode: Int,
72
60
  data: Intent?
73
61
  ) {
74
- val cb = this@AuthsignalModule.callback ?: return
62
+ val pendingPromise = this@AuthsignalModule.launchPromise ?: return
75
63
 
76
64
  val hasResult =
77
65
  resultCode == Activity.RESULT_OK && requestCode == AuthenticationActivity.AUTHENTICATION_REQUEST && data!!.data != null
@@ -93,23 +81,21 @@ class AuthsignalModule(private val reactContext: ReactApplicationContext) :
93
81
  shared.token = value
94
82
  }
95
83
  }
96
- cb.invoke(null, token)
84
+ pendingPromise.resolve(token)
97
85
  } catch (ex: Exception) {
98
- val error = Arguments.createMap()
99
- error.putString("error", "malformed_url")
100
- error.putString("error_description", "Malformed redirect url")
101
- cb.invoke(error)
86
+ pendingPromise.reject("malformed_url", "Malformed redirect url")
102
87
  }
103
88
  } else {
104
- val error = Arguments.createMap()
105
- error.putString("error", "user_cancelled")
106
- error.putString("error_description", "User cancelled")
107
- cb.invoke(error)
89
+ pendingPromise.resolve(null)
108
90
  }
109
91
 
110
- this@AuthsignalModule.callback = null
92
+ this@AuthsignalModule.launchPromise = null
111
93
  }
112
94
 
113
95
  override fun onNewIntent(intent: Intent) {
114
96
  }
97
+
98
+ companion object {
99
+ const val NAME = "AuthsignalModule"
100
+ }
115
101
  }
@@ -1,26 +1,79 @@
1
1
  package com.authsignal.react
2
2
 
3
- import com.facebook.react.ReactPackage
3
+ import com.facebook.react.TurboReactPackage
4
4
  import com.facebook.react.bridge.NativeModule
5
5
  import com.facebook.react.bridge.ReactApplicationContext
6
- import com.facebook.react.uimanager.ViewManager
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
7
8
 
8
- class AuthsignalPackage : ReactPackage {
9
- override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
10
- return listOf<NativeModule>(
11
- AuthsignalModule(reactContext),
12
- AuthsignalEmailModule(reactContext),
13
- AuthsignalPasskeyModule(reactContext),
14
- AuthsignalPushModule(reactContext),
15
- AuthsignalInAppModule(reactContext),
16
- AuthsignalQRCodeModule(reactContext),
17
- AuthsignalSMSModule(reactContext),
18
- AuthsignalTOTPModule(reactContext),
19
- AuthsignalWhatsappModule(reactContext)
20
- )
9
+ class AuthsignalPackage : TurboReactPackage() {
10
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
11
+ return when (name) {
12
+ AuthsignalModule.NAME -> AuthsignalModule(reactContext)
13
+ AuthsignalEmailModule.NAME -> AuthsignalEmailModule(reactContext)
14
+ AuthsignalPasskeyModule.NAME -> AuthsignalPasskeyModule(reactContext)
15
+ AuthsignalPushModule.NAME -> AuthsignalPushModule(reactContext)
16
+ AuthsignalInAppModule.NAME -> AuthsignalInAppModule(reactContext)
17
+ AuthsignalQRCodeModule.NAME -> AuthsignalQRCodeModule(reactContext)
18
+ AuthsignalSMSModule.NAME -> AuthsignalSMSModule(reactContext)
19
+ AuthsignalTOTPModule.NAME -> AuthsignalTOTPModule(reactContext)
20
+ AuthsignalWhatsappModule.NAME -> AuthsignalWhatsappModule(reactContext)
21
+ else -> null
22
+ }
23
+ }
24
+
25
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
26
+ return ReactModuleInfoProvider {
27
+ mapOf(
28
+ AuthsignalModule.NAME to createModuleInfo(
29
+ AuthsignalModule.NAME,
30
+ AuthsignalModule::class.java.name
31
+ ),
32
+ AuthsignalEmailModule.NAME to createModuleInfo(
33
+ AuthsignalEmailModule.NAME,
34
+ AuthsignalEmailModule::class.java.name
35
+ ),
36
+ AuthsignalPasskeyModule.NAME to createModuleInfo(
37
+ AuthsignalPasskeyModule.NAME,
38
+ AuthsignalPasskeyModule::class.java.name
39
+ ),
40
+ AuthsignalPushModule.NAME to createModuleInfo(
41
+ AuthsignalPushModule.NAME,
42
+ AuthsignalPushModule::class.java.name
43
+ ),
44
+ AuthsignalInAppModule.NAME to createModuleInfo(
45
+ AuthsignalInAppModule.NAME,
46
+ AuthsignalInAppModule::class.java.name
47
+ ),
48
+ AuthsignalQRCodeModule.NAME to createModuleInfo(
49
+ AuthsignalQRCodeModule.NAME,
50
+ AuthsignalQRCodeModule::class.java.name
51
+ ),
52
+ AuthsignalSMSModule.NAME to createModuleInfo(
53
+ AuthsignalSMSModule.NAME,
54
+ AuthsignalSMSModule::class.java.name
55
+ ),
56
+ AuthsignalTOTPModule.NAME to createModuleInfo(
57
+ AuthsignalTOTPModule.NAME,
58
+ AuthsignalTOTPModule::class.java.name
59
+ ),
60
+ AuthsignalWhatsappModule.NAME to createModuleInfo(
61
+ AuthsignalWhatsappModule.NAME,
62
+ AuthsignalWhatsappModule::class.java.name
63
+ ),
64
+ )
65
+ }
21
66
  }
22
67
 
23
- override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
24
- return emptyList()
68
+ private fun createModuleInfo(name: String, className: String): ReactModuleInfo {
69
+ return ReactModuleInfo(
70
+ name,
71
+ className,
72
+ false,
73
+ false,
74
+ false,
75
+ false,
76
+ true,
77
+ )
25
78
  }
26
79
  }
@@ -5,31 +5,22 @@ import com.authsignal.passkey.AuthsignalPasskey
5
5
  import com.facebook.react.bridge.Arguments
6
6
  import com.facebook.react.bridge.Promise
7
7
  import com.facebook.react.bridge.ReactApplicationContext
8
- import com.facebook.react.bridge.ReactContextBaseJavaModule
9
8
  import com.facebook.react.bridge.ReactMethod
9
+ import com.facebook.react.module.annotations.ReactModule
10
10
  import kotlinx.coroutines.CoroutineScope
11
11
  import kotlinx.coroutines.Dispatchers
12
12
  import kotlinx.coroutines.SupervisorJob
13
13
  import kotlinx.coroutines.launch
14
14
 
15
+ @ReactModule(name = AuthsignalPasskeyModule.NAME)
15
16
  class AuthsignalPasskeyModule(private val reactContext: ReactApplicationContext) :
16
- ReactContextBaseJavaModule(reactContext) {
17
+ NativeAuthsignalPasskeyModuleSpec(reactContext) {
17
18
  private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
18
19
  private var authsignal: AuthsignalPasskey? = null
19
20
  private var defaultError = "unexpected_error"
20
21
 
21
- override fun getConstants(): Map<String, Any>? {
22
- val constants: MutableMap<String, Any> = HashMap()
23
- constants["bundleIdentifier"] = reactContext.applicationInfo.packageName
24
- return constants
25
- }
26
-
27
- override fun getName(): String {
28
- return "AuthsignalPasskeyModule"
29
- }
30
-
31
22
  @ReactMethod
32
- fun initialize(tenantID: String, baseURL: String, deviceID: String?, promise: Promise) {
23
+ override fun initialize(tenantID: String, baseURL: String, deviceID: String?, promise: Promise) {
33
24
  val activity = reactContext.currentActivity
34
25
 
35
26
  if (activity != null) {
@@ -40,7 +31,7 @@ class AuthsignalPasskeyModule(private val reactContext: ReactApplicationContext)
40
31
  }
41
32
 
42
33
  @ReactMethod
43
- fun signUp(token: String?, username: String?, displayName: String?, ignorePasskeyAlreadyExistsError: Boolean, promise: Promise) {
34
+ override fun signUp(token: String?, username: String?, displayName: String?, ignorePasskeyAlreadyExistsError: Boolean, promise: Promise) {
44
35
  launch(promise) {
45
36
  val response = it.signUp(token, username, displayName, false, ignorePasskeyAlreadyExistsError)
46
37
 
@@ -61,7 +52,13 @@ class AuthsignalPasskeyModule(private val reactContext: ReactApplicationContext)
61
52
  }
62
53
 
63
54
  @ReactMethod
64
- fun signIn(action: String?, token: String?, preferImmediatelyAvailableCredentials: Boolean, promise: Promise) {
55
+ override fun signIn(
56
+ action: String?,
57
+ token: String?,
58
+ _autofill: Boolean,
59
+ preferImmediatelyAvailableCredentials: Boolean,
60
+ promise: Promise
61
+ ) {
65
62
  launch(promise) {
66
63
  val response = it.signIn(action, token, preferImmediatelyAvailableCredentials)
67
64
 
@@ -84,7 +81,12 @@ class AuthsignalPasskeyModule(private val reactContext: ReactApplicationContext)
84
81
  }
85
82
 
86
83
  @ReactMethod
87
- fun shouldPromptToCreatePasskey(username: String?, promise: Promise) {
84
+ override fun cancel() {
85
+ // No-op on Android; cancel is only applicable for iOS autofill
86
+ }
87
+
88
+ @ReactMethod
89
+ override fun shouldPromptToCreatePasskey(username: String?, promise: Promise) {
88
90
  launch(promise) {
89
91
  val response = it.shouldPromptToCreatePasskey(username)
90
92
 
@@ -93,7 +95,7 @@ class AuthsignalPasskeyModule(private val reactContext: ReactApplicationContext)
93
95
  }
94
96
 
95
97
  @ReactMethod
96
- fun isAvailableOnDevice(promise: Promise) {
98
+ override fun isAvailableOnDevice(promise: Promise) {
97
99
  launch(promise) {
98
100
  val response = it.isAvailableOnDevice()
99
101
 
@@ -112,4 +114,8 @@ class AuthsignalPasskeyModule(private val reactContext: ReactApplicationContext)
112
114
  }
113
115
  }
114
116
  }
117
+
118
+ companion object {
119
+ const val NAME = "AuthsignalPasskeyModule"
120
+ }
115
121
  }