react-native-nitro-auth 0.5.1 → 0.5.3

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 (121) hide show
  1. package/README.md +362 -190
  2. package/android/src/main/java/com/auth/AuthAdapter.kt +55 -169
  3. package/android/src/main/java/com/auth/NitroAuthPackage.kt +1 -1
  4. package/app.plugin.js +2 -9
  5. package/cpp/AuthCache.cpp +12 -102
  6. package/cpp/HybridAuth.cpp +37 -61
  7. package/cpp/HybridAuth.hpp +2 -4
  8. package/ios/AuthAdapter.swift +21 -25
  9. package/lib/commonjs/Auth.web.js +433 -164
  10. package/lib/commonjs/Auth.web.js.map +1 -1
  11. package/lib/commonjs/index.js +0 -12
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/commonjs/index.web.js +0 -12
  14. package/lib/commonjs/index.web.js.map +1 -1
  15. package/lib/commonjs/js-storage-adapter.js +2 -0
  16. package/lib/commonjs/js-storage-adapter.js.map +1 -0
  17. package/lib/commonjs/service.js +7 -84
  18. package/lib/commonjs/service.js.map +1 -1
  19. package/lib/commonjs/service.web.js +1 -5
  20. package/lib/commonjs/service.web.js.map +1 -1
  21. package/lib/commonjs/ui/social-button.js +44 -29
  22. package/lib/commonjs/ui/social-button.js.map +1 -1
  23. package/lib/commonjs/ui/social-button.web.js +44 -29
  24. package/lib/commonjs/ui/social-button.web.js.map +1 -1
  25. package/lib/commonjs/use-auth.js +8 -2
  26. package/lib/commonjs/use-auth.js.map +1 -1
  27. package/lib/commonjs/utils/logger.js +12 -4
  28. package/lib/commonjs/utils/logger.js.map +1 -1
  29. package/lib/module/Auth.web.js +433 -164
  30. package/lib/module/Auth.web.js.map +1 -1
  31. package/lib/module/index.js +0 -1
  32. package/lib/module/index.js.map +1 -1
  33. package/lib/module/index.web.js +0 -1
  34. package/lib/module/index.web.js.map +1 -1
  35. package/lib/module/js-storage-adapter.js +2 -0
  36. package/lib/module/js-storage-adapter.js.map +1 -0
  37. package/lib/module/service.js +7 -84
  38. package/lib/module/service.js.map +1 -1
  39. package/lib/module/service.web.js +1 -5
  40. package/lib/module/service.web.js.map +1 -1
  41. package/lib/module/ui/social-button.js +44 -29
  42. package/lib/module/ui/social-button.js.map +1 -1
  43. package/lib/module/ui/social-button.web.js +44 -29
  44. package/lib/module/ui/social-button.web.js.map +1 -1
  45. package/lib/module/use-auth.js +8 -2
  46. package/lib/module/use-auth.js.map +1 -1
  47. package/lib/module/utils/logger.js +12 -4
  48. package/lib/module/utils/logger.js.map +1 -1
  49. package/lib/typescript/commonjs/Auth.nitro.d.ts +3 -3
  50. package/lib/typescript/commonjs/Auth.nitro.d.ts.map +1 -1
  51. package/lib/typescript/commonjs/Auth.web.d.ts +18 -6
  52. package/lib/typescript/commonjs/Auth.web.d.ts.map +1 -1
  53. package/lib/typescript/commonjs/index.d.ts +1 -2
  54. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  55. package/lib/typescript/commonjs/index.web.d.ts +0 -1
  56. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  57. package/lib/typescript/commonjs/js-storage-adapter.d.ts +6 -0
  58. package/lib/typescript/commonjs/js-storage-adapter.d.ts.map +1 -0
  59. package/lib/typescript/commonjs/service.d.ts +1 -8
  60. package/lib/typescript/commonjs/service.d.ts.map +1 -1
  61. package/lib/typescript/commonjs/service.web.d.ts +1 -8
  62. package/lib/typescript/commonjs/service.web.d.ts.map +1 -1
  63. package/lib/typescript/commonjs/ui/social-button.d.ts +6 -6
  64. package/lib/typescript/commonjs/ui/social-button.d.ts.map +1 -1
  65. package/lib/typescript/commonjs/ui/social-button.web.d.ts +6 -6
  66. package/lib/typescript/commonjs/ui/social-button.web.d.ts.map +1 -1
  67. package/lib/typescript/commonjs/use-auth.d.ts +4 -4
  68. package/lib/typescript/commonjs/use-auth.d.ts.map +1 -1
  69. package/lib/typescript/commonjs/utils/logger.d.ts +4 -4
  70. package/lib/typescript/commonjs/utils/logger.d.ts.map +1 -1
  71. package/lib/typescript/module/Auth.nitro.d.ts +3 -3
  72. package/lib/typescript/module/Auth.nitro.d.ts.map +1 -1
  73. package/lib/typescript/module/Auth.web.d.ts +18 -6
  74. package/lib/typescript/module/Auth.web.d.ts.map +1 -1
  75. package/lib/typescript/module/index.d.ts +1 -2
  76. package/lib/typescript/module/index.d.ts.map +1 -1
  77. package/lib/typescript/module/index.web.d.ts +0 -1
  78. package/lib/typescript/module/index.web.d.ts.map +1 -1
  79. package/lib/typescript/module/js-storage-adapter.d.ts +6 -0
  80. package/lib/typescript/module/js-storage-adapter.d.ts.map +1 -0
  81. package/lib/typescript/module/service.d.ts +1 -8
  82. package/lib/typescript/module/service.d.ts.map +1 -1
  83. package/lib/typescript/module/service.web.d.ts +1 -8
  84. package/lib/typescript/module/service.web.d.ts.map +1 -1
  85. package/lib/typescript/module/ui/social-button.d.ts +6 -6
  86. package/lib/typescript/module/ui/social-button.d.ts.map +1 -1
  87. package/lib/typescript/module/ui/social-button.web.d.ts +6 -6
  88. package/lib/typescript/module/ui/social-button.web.d.ts.map +1 -1
  89. package/lib/typescript/module/use-auth.d.ts +4 -4
  90. package/lib/typescript/module/use-auth.d.ts.map +1 -1
  91. package/lib/typescript/module/utils/logger.d.ts +4 -4
  92. package/lib/typescript/module/utils/logger.d.ts.map +1 -1
  93. package/nitrogen/generated/android/NitroAuth+autolinking.cmake +0 -1
  94. package/nitrogen/generated/shared/c++/AuthTokens.hpp +5 -1
  95. package/nitrogen/generated/shared/c++/AuthUser.hpp +5 -1
  96. package/nitrogen/generated/shared/c++/HybridAuthSpec.cpp +0 -1
  97. package/nitrogen/generated/shared/c++/HybridAuthSpec.hpp +0 -5
  98. package/package.json +11 -8
  99. package/src/Auth.nitro.ts +4 -3
  100. package/src/Auth.web.ts +582 -202
  101. package/src/global.d.ts +0 -1
  102. package/src/index.ts +1 -2
  103. package/src/index.web.ts +0 -1
  104. package/src/js-storage-adapter.ts +5 -0
  105. package/src/service.ts +11 -104
  106. package/src/service.web.ts +0 -7
  107. package/src/ui/social-button.tsx +66 -43
  108. package/src/ui/social-button.web.tsx +67 -44
  109. package/src/use-auth.ts +18 -6
  110. package/src/utils/logger.ts +12 -4
  111. package/lib/commonjs/AuthStorage.nitro.js +0 -6
  112. package/lib/commonjs/AuthStorage.nitro.js.map +0 -1
  113. package/lib/module/AuthStorage.nitro.js +0 -4
  114. package/lib/module/AuthStorage.nitro.js.map +0 -1
  115. package/lib/typescript/commonjs/AuthStorage.nitro.d.ts +0 -26
  116. package/lib/typescript/commonjs/AuthStorage.nitro.d.ts.map +0 -1
  117. package/lib/typescript/module/AuthStorage.nitro.d.ts +0 -26
  118. package/lib/typescript/module/AuthStorage.nitro.d.ts.map +0 -1
  119. package/nitrogen/generated/shared/c++/HybridAuthStorageAdapterSpec.cpp +0 -23
  120. package/nitrogen/generated/shared/c++/HybridAuthStorageAdapterSpec.hpp +0 -65
  121. package/src/AuthStorage.nitro.ts +0 -26
@@ -3,9 +3,7 @@
3
3
  package com.auth
4
4
 
5
5
  import android.content.Context
6
- import android.content.SharedPreferences
7
6
  import android.os.Bundle
8
- import android.os.Build
9
7
  import android.util.Log
10
8
  import com.google.android.gms.auth.api.signin.GoogleSignIn
11
9
  import com.google.android.gms.auth.api.signin.GoogleSignInAccount
@@ -27,17 +25,12 @@ import android.app.Application
27
25
  import android.content.Intent
28
26
  import android.net.Uri
29
27
  import androidx.browser.customtabs.CustomTabsIntent
30
- import androidx.security.crypto.EncryptedSharedPreferences
31
- import androidx.security.crypto.MasterKeys
32
28
  import java.util.UUID
33
- import org.json.JSONArray
34
29
  import org.json.JSONObject
35
30
  import android.util.Base64
36
31
 
37
32
  object AuthAdapter {
38
33
  private const val TAG = "AuthAdapter"
39
- private const val PREF_NAME = "nitro_auth"
40
- private const val SECURE_PREF_NAME = "nitro_auth_secure"
41
34
 
42
35
  private var appContext: Context? = null
43
36
  private var currentActivity: Activity? = null
@@ -51,47 +44,10 @@ object AuthAdapter {
51
44
  private var pendingMicrosoftTenant: String? = null
52
45
  private var pendingMicrosoftClientId: String? = null
53
46
  private var pendingMicrosoftB2cDomain: String? = null
54
-
55
- private fun getPrefs(context: Context): SharedPreferences {
56
- return try {
57
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
58
- val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
59
- val securePrefs = EncryptedSharedPreferences.create(
60
- SECURE_PREF_NAME,
61
- masterKeyAlias,
62
- context,
63
- EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
64
- EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
65
- )
66
- migrateLegacyPrefsIfNeeded(context, securePrefs)
67
- securePrefs
68
- } else {
69
- context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
70
- }
71
- } catch (e: Exception) {
72
- Log.w(TAG, "Failed to initialize encrypted storage, falling back to SharedPreferences", e)
73
- context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
74
- }
75
- }
76
-
77
- private fun migrateLegacyPrefsIfNeeded(context: Context, securePrefs: SharedPreferences) {
78
- val legacyPrefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
79
- if (legacyPrefs.all.isEmpty() || securePrefs.all.isNotEmpty()) {
80
- return
81
- }
82
- val editor = securePrefs.edit()
83
- for ((key, value) in legacyPrefs.all) {
84
- when (value) {
85
- is String -> editor.putString(key, value)
86
- is Boolean -> editor.putBoolean(key, value)
87
- is Int -> editor.putInt(key, value)
88
- is Long -> editor.putLong(key, value)
89
- is Float -> editor.putFloat(key, value)
90
- }
91
- }
92
- editor.apply()
93
- legacyPrefs.edit().clear().apply()
94
- }
47
+
48
+ private var inMemoryMicrosoftRefreshToken: String? = null
49
+ private var inMemoryMicrosoftScopes: List<String> =
50
+ listOf("openid", "email", "profile", "offline_access", "User.Read")
95
51
 
96
52
  @JvmStatic
97
53
  private external fun nativeInitialize(context: Context)
@@ -141,11 +97,10 @@ object AuthAdapter {
141
97
  }
142
98
 
143
99
  fun onSignInSuccess(account: GoogleSignInAccount, scopes: List<String>) {
144
- val ctx = appContext ?: return
145
- saveUser(ctx, "google", account.email, account.displayName,
146
- account.photoUrl?.toString(), account.idToken, account.serverAuthCode, scopes)
100
+ appContext ?: return
101
+ val expirationTime = getJwtExpirationTimeMs(account.idToken)
147
102
  nativeOnLoginSuccess("google", account.email, account.displayName,
148
- account.photoUrl?.toString(), account.idToken, null, account.serverAuthCode, scopes.toTypedArray(), null)
103
+ account.photoUrl?.toString(), account.idToken, null, account.serverAuthCode, scopes.toTypedArray(), expirationTime)
149
104
  }
150
105
 
151
106
  fun onSignInError(errorCode: Int, message: String?) {
@@ -393,12 +348,11 @@ object AuthAdapter {
393
348
  val email = claims["preferred_username"] ?: claims["email"]
394
349
  val name = claims["name"]
395
350
 
396
- val ctx = appContext
397
- if (ctx != null) {
398
- saveUser(ctx, "microsoft", email, name, null, idToken, refreshToken, pendingMicrosoftScopes)
399
- if (refreshToken.isNotEmpty()) {
400
- saveMicrosoftRefreshToken(ctx, refreshToken)
401
- }
351
+ if (refreshToken.isNotEmpty()) {
352
+ inMemoryMicrosoftRefreshToken = refreshToken
353
+ }
354
+ inMemoryMicrosoftScopes = pendingMicrosoftScopes.ifEmpty {
355
+ listOf("openid", "email", "profile", "offline_access", "User.Read")
402
356
  }
403
357
 
404
358
  clearPkceState()
@@ -419,14 +373,12 @@ object AuthAdapter {
419
373
  }
420
374
  }
421
375
 
422
- private fun saveMicrosoftRefreshToken(context: Context, refreshToken: String) {
423
- val prefs = getPrefs(context)
424
- prefs.edit().putString("microsoft_refresh_token", refreshToken).apply()
376
+ private fun saveMicrosoftRefreshToken(refreshToken: String) {
377
+ inMemoryMicrosoftRefreshToken = refreshToken
425
378
  }
426
379
 
427
- private fun getMicrosoftRefreshToken(context: Context): String? {
428
- val prefs = getPrefs(context)
429
- return prefs.getString("microsoft_refresh_token", null)
380
+ private fun getMicrosoftRefreshToken(): String? {
381
+ return inMemoryMicrosoftRefreshToken
430
382
  }
431
383
 
432
384
  private fun clearPkceState() {
@@ -455,6 +407,15 @@ object AuthAdapter {
455
407
  }
456
408
  }
457
409
 
410
+ private fun getJwtExpirationTimeMs(idToken: String?): Long? {
411
+ if (idToken.isNullOrEmpty()) {
412
+ return null
413
+ }
414
+
415
+ val expSeconds = decodeJwt(idToken)["exp"]?.toLongOrNull() ?: return null
416
+ return expSeconds * 1000
417
+ }
418
+
458
419
  private fun getMicrosoftClientIdFromResources(context: Context): String? {
459
420
  val resId = context.resources.getIdentifier("nitro_auth_microsoft_client_id", "string", context.packageName)
460
421
  return if (resId != 0) context.getString(resId) else null
@@ -553,6 +514,7 @@ object AuthAdapter {
553
514
  }
554
515
 
555
516
  if (googleIdTokenCredential != null) {
517
+ val expirationTime = getJwtExpirationTimeMs(googleIdTokenCredential.idToken)
556
518
  nativeOnLoginSuccess(
557
519
  "google",
558
520
  googleIdTokenCredential.id,
@@ -562,7 +524,7 @@ object AuthAdapter {
562
524
  null,
563
525
  null,
564
526
  scopes.toTypedArray(),
565
- null
527
+ expirationTime
566
528
  )
567
529
  } else {
568
530
  Log.w(TAG, "Unsupported credential type: ${credential.type}")
@@ -590,12 +552,8 @@ object AuthAdapter {
590
552
  ctx.startActivity(intent)
591
553
  return
592
554
  }
593
- val userJson = getUserJson(ctx)
594
- if (userJson != null && userJson.contains("\"provider\":\"microsoft\"")) {
595
- val currentScopes = extractScopesFromUserJson(userJson)
596
- val defaultMicrosoftScopes = listOf("openid", "email", "profile", "offline_access", "User.Read")
597
- val existing = if (currentScopes.isEmpty()) defaultMicrosoftScopes else currentScopes
598
- val mergedScopes = (existing + scopes.toList()).distinct()
555
+ if (inMemoryMicrosoftRefreshToken != null) {
556
+ val mergedScopes = (inMemoryMicrosoftScopes + scopes.toList()).distinct()
599
557
  val tenant = getMicrosoftTenantFromResources(ctx)
600
558
  loginMicrosoft(ctx, mergedScopes.toTypedArray(), null, tenant, null)
601
559
  return
@@ -624,20 +582,21 @@ object AuthAdapter {
624
582
  googleSignInClient!!.silentSignIn().addOnCompleteListener { task ->
625
583
  if (task.isSuccessful) {
626
584
  val acc = task.result
627
- nativeOnRefreshSuccess(acc?.idToken, null, null)
585
+ nativeOnRefreshSuccess(
586
+ acc?.idToken,
587
+ null,
588
+ getJwtExpirationTimeMs(acc?.idToken),
589
+ )
628
590
  } else {
629
591
  nativeOnRefreshError("network_error", task.exception?.message ?: "Silent sign-in failed")
630
592
  }
631
593
  }
632
594
  return
633
595
  }
634
- val userJson = getUserJson(ctx)
635
- if (userJson != null && userJson.contains("\"provider\":\"microsoft\"")) {
636
- val refreshToken = getMicrosoftRefreshToken(ctx)
637
- if (refreshToken != null) {
638
- refreshMicrosoftTokenForRefresh(ctx, refreshToken)
639
- return
640
- }
596
+ val refreshToken = getMicrosoftRefreshToken()
597
+ if (refreshToken != null) {
598
+ refreshMicrosoftTokenForRefresh(ctx, refreshToken)
599
+ return
641
600
  }
642
601
  nativeOnRefreshError("unknown", "No user logged in")
643
602
  }
@@ -662,7 +621,8 @@ object AuthAdapter {
662
621
  .build()
663
622
  GoogleSignIn.getClient(ctx, gso).signOut()
664
623
  }
665
- clearUser(ctx)
624
+ inMemoryMicrosoftRefreshToken = null
625
+ inMemoryMicrosoftScopes = listOf("openid", "email", "profile", "offline_access", "User.Read")
666
626
  }
667
627
 
668
628
  @JvmStatic
@@ -677,7 +637,8 @@ object AuthAdapter {
677
637
  .build()
678
638
  GoogleSignIn.getClient(ctx, gso).revokeAccess()
679
639
  }
680
- clearUser(ctx)
640
+ inMemoryMicrosoftRefreshToken = null
641
+ inMemoryMicrosoftScopes = listOf("openid", "email", "profile", "offline_access", "User.Read")
681
642
  }
682
643
 
683
644
  private fun getClientIdFromResources(context: Context): String? {
@@ -685,66 +646,19 @@ object AuthAdapter {
685
646
  return if (resId != 0) context.getString(resId) else null
686
647
  }
687
648
 
688
- @JvmStatic
689
- fun getUserJson(context: Context): String? {
690
- val pref = getPrefs(context)
691
- return pref.getString("user_json", null)
692
- }
693
-
694
- @JvmStatic
695
- fun setUserJson(context: Context, json: String) {
696
- val pref = getPrefs(context)
697
- pref.edit().putString("user_json", json).apply()
698
- }
699
-
700
- @JvmStatic
701
- fun clearUser(context: Context) {
702
- val pref = getPrefs(context)
703
- pref.edit().clear().apply()
704
- }
705
-
706
649
  @JvmStatic
707
650
  fun restoreSession(context: Context) {
708
651
  val ctx = context.applicationContext ?: appContext ?: context
709
652
  val account = GoogleSignIn.getLastSignedInAccount(ctx)
710
653
  if (account != null) {
654
+ val expirationTime = getJwtExpirationTimeMs(account.idToken)
711
655
  nativeOnLoginSuccess("google", account.email, account.displayName,
712
656
  account.photoUrl?.toString(), account.idToken, null, account.serverAuthCode,
713
- account.grantedScopes?.map { it.scopeUri }?.toTypedArray(), null)
657
+ account.grantedScopes?.map { it.scopeUri }?.toTypedArray(), expirationTime)
714
658
  } else {
715
- val json = getUserJson(ctx)
716
- if (json != null) {
717
- val provider = try {
718
- val parsed = JSONObject(json)
719
- parsed.optString("provider")
720
- } catch (_: Exception) {
721
- ""
722
- }
723
- val effectiveProvider = when (provider) {
724
- "google" -> "google"
725
- "microsoft" -> "microsoft"
726
- "apple" -> "apple"
727
- else -> "apple"
728
- }
729
-
730
- if (effectiveProvider == "microsoft") {
731
- val refreshToken = getMicrosoftRefreshToken(ctx)
732
- if (refreshToken != null) {
733
- refreshMicrosoftToken(ctx, refreshToken)
734
- } else {
735
- val email = extractJsonValue(json, "email")
736
- val name = extractJsonValue(json, "name")
737
- val idToken = extractJsonValue(json, "idToken")
738
- nativeOnLoginSuccess(effectiveProvider, email, name, null, idToken, null, null, null, null)
739
- }
740
- } else {
741
- val email = extractJsonValue(json, "email")
742
- val name = extractJsonValue(json, "name")
743
- val photo = extractJsonValue(json, "photo")
744
- val idToken = extractJsonValue(json, "idToken")
745
- val serverAuthCode = extractJsonValue(json, "serverAuthCode")
746
- nativeOnLoginSuccess(effectiveProvider, email, name, photo, idToken, null, serverAuthCode, null, null)
747
- }
659
+ val refreshToken = getMicrosoftRefreshToken()
660
+ if (refreshToken != null) {
661
+ refreshMicrosoftToken(ctx, refreshToken)
748
662
  } else {
749
663
  nativeOnLoginError("unknown", "No session")
750
664
  }
@@ -801,9 +715,11 @@ object AuthAdapter {
801
715
  val name = claims["name"]
802
716
 
803
717
  if (newRefreshToken.isNotEmpty()) {
804
- saveMicrosoftRefreshToken(context, newRefreshToken)
718
+ saveMicrosoftRefreshToken(newRefreshToken)
719
+ }
720
+ inMemoryMicrosoftScopes = pendingMicrosoftScopes.ifEmpty {
721
+ listOf("openid", "email", "profile", "offline_access", "User.Read")
805
722
  }
806
- saveUser(context, "microsoft", email, name, null, newIdToken, newRefreshToken, null)
807
723
 
808
724
  nativeOnLoginSuccess("microsoft", email, name, null, newIdToken, newAccessToken, null, null, expirationTime)
809
725
  } else {
@@ -859,9 +775,11 @@ object AuthAdapter {
859
775
  val email = claims["preferred_username"] ?: claims["email"]
860
776
  val name = claims["name"]
861
777
  if (newRefreshToken.isNotEmpty()) {
862
- saveMicrosoftRefreshToken(context, newRefreshToken)
778
+ saveMicrosoftRefreshToken(newRefreshToken)
779
+ }
780
+ inMemoryMicrosoftScopes = pendingMicrosoftScopes.ifEmpty {
781
+ listOf("openid", "email", "profile", "offline_access", "User.Read")
863
782
  }
864
- saveUser(context, "microsoft", email, name, null, newIdToken, newRefreshToken, null)
865
783
  nativeOnRefreshSuccess(
866
784
  newIdToken.ifEmpty { null },
867
785
  newAccessToken.ifEmpty { null },
@@ -879,36 +797,4 @@ object AuthAdapter {
879
797
  }
880
798
  }
881
799
 
882
- private fun extractJsonValue(json: String, key: String): String? {
883
- return try {
884
- val value = JSONObject(json).optString(key, "")
885
- if (value.isEmpty()) null else value
886
- } catch (_: Exception) {
887
- null
888
- }
889
- }
890
-
891
- private fun extractScopesFromUserJson(json: String): List<String> {
892
- return try {
893
- val jsonObj = JSONObject(json)
894
- val arr = jsonObj.optJSONArray("scopes") ?: return emptyList()
895
- (0 until arr.length()).mapNotNull { i -> arr.optString(i).takeIf { it.isNotEmpty() } }
896
- } catch (_: Exception) {
897
- emptyList()
898
- }
899
- }
900
-
901
- private fun saveUser(context: Context, provider: String, email: String?, name: String?,
902
- photo: String?, idToken: String?, serverAuthCode: String?, scopes: List<String>?) {
903
- val pref = getPrefs(context)
904
- val json = JSONObject()
905
- json.put("provider", provider)
906
- if (email != null) json.put("email", email)
907
- if (name != null) json.put("name", name)
908
- if (photo != null) json.put("photo", photo)
909
- if (idToken != null) json.put("idToken", idToken)
910
- if (serverAuthCode != null) json.put("serverAuthCode", serverAuthCode)
911
- if (scopes != null) json.put("scopes", JSONArray(scopes))
912
- pref.edit().putString("user_json", json.toString()).apply()
913
- }
914
800
  }
@@ -1,4 +1,4 @@
1
- @file:Suppress("DEPRECATION")
1
+ @file:Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
2
2
 
3
3
  package com.auth
4
4
 
package/app.plugin.js CHANGED
@@ -6,7 +6,6 @@ const {
6
6
  AndroidConfig,
7
7
  createRunOncePlugin,
8
8
  } = require("@expo/config-plugins");
9
-
10
9
  const pkg = require("./package.json");
11
10
 
12
11
  const withNitroAuth = (config, props = {}) => {
@@ -157,9 +156,7 @@ const withNitroAuth = (config, props = {}) => {
157
156
  ],
158
157
  };
159
158
  const existingMsalActivity = application.activity.find(
160
- (a) =>
161
- a.$?.["android:name"] ===
162
- "com.auth.MicrosoftAuthActivity",
159
+ (a) => a.$?.["android:name"] === "com.auth.MicrosoftAuthActivity",
163
160
  );
164
161
  if (!existingMsalActivity) {
165
162
  application.activity.push(msalActivity);
@@ -172,8 +169,4 @@ const withNitroAuth = (config, props = {}) => {
172
169
  return config;
173
170
  };
174
171
 
175
- module.exports = createRunOncePlugin(
176
- withNitroAuth,
177
- pkg.name,
178
- pkg.version,
179
- );
172
+ module.exports = createRunOncePlugin(withNitroAuth, pkg.name, pkg.version);
package/cpp/AuthCache.cpp CHANGED
@@ -13,91 +13,21 @@
13
13
  namespace margelo::nitro::NitroAuth {
14
14
 
15
15
  #ifdef __APPLE__
16
- static CFStringRef kService = CFSTR("react-native-nitro-auth");
17
- static CFStringRef kAccount = CFSTR("nitro_auth_user");
18
- static CFStringRef kLegacyCacheKey = CFSTR("nitro_auth_user");
19
-
20
- static CFMutableDictionaryRef createKeychainQuery() {
21
- CFMutableDictionaryRef query = CFDictionaryCreateMutable(
22
- kCFAllocatorDefault,
23
- 0,
24
- &kCFTypeDictionaryKeyCallBacks,
25
- &kCFTypeDictionaryValueCallBacks
26
- );
27
- CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
28
- CFDictionarySetValue(query, kSecAttrService, kService);
29
- CFDictionarySetValue(query, kSecAttrAccount, kAccount);
30
- return query;
31
- }
32
-
33
- static std::optional<std::string> getLegacyUserJson() {
34
- CFPropertyListRef value = CFPreferencesCopyAppValue(kLegacyCacheKey, kCFPreferencesCurrentApplication);
35
- if (value && CFGetTypeID(value) == CFStringGetTypeID()) {
36
- CFStringRef cfStr = static_cast<CFStringRef>(value);
37
- char buffer[4096];
38
- if (CFStringGetCString(cfStr, buffer, sizeof(buffer), kCFStringEncodingUTF8)) {
39
- CFRelease(value);
40
- return std::string(buffer);
41
- }
42
- }
43
- if (value) CFRelease(value);
44
- return std::nullopt;
45
- }
46
-
47
- static void clearLegacyUserJson() {
48
- CFPreferencesSetAppValue(kLegacyCacheKey, nullptr, kCFPreferencesCurrentApplication);
49
- CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
50
- }
16
+ static std::string sInMemoryUserJson;
51
17
 
52
18
  void AuthCache::setUserJson(const std::string& json) {
53
- CFMutableDictionaryRef query = createKeychainQuery();
54
- SecItemDelete(query);
55
-
56
- CFDataRef data = CFDataCreate(
57
- kCFAllocatorDefault,
58
- reinterpret_cast<const UInt8*>(json.data()),
59
- static_cast<CFIndex>(json.size())
60
- );
61
- CFDictionarySetValue(query, kSecValueData, data);
62
- CFDictionarySetValue(query, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly);
63
-
64
- SecItemAdd(query, nullptr);
65
- CFRelease(data);
66
- CFRelease(query);
19
+ sInMemoryUserJson = json;
67
20
  }
68
21
 
69
22
  std::optional<std::string> AuthCache::getUserJson() {
70
- CFMutableDictionaryRef query = createKeychainQuery();
71
- CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
72
- CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitOne);
73
-
74
- CFTypeRef result = nullptr;
75
- OSStatus status = SecItemCopyMatching(query, &result);
76
- CFRelease(query);
77
-
78
- if (status != errSecSuccess || result == nullptr) {
79
- if (result) CFRelease(result);
80
- auto legacy = getLegacyUserJson();
81
- if (legacy) {
82
- AuthCache::setUserJson(*legacy);
83
- clearLegacyUserJson();
84
- return legacy;
85
- }
23
+ if (sInMemoryUserJson.empty()) {
86
24
  return std::nullopt;
87
25
  }
88
-
89
- CFDataRef data = static_cast<CFDataRef>(result);
90
- const UInt8* bytes = CFDataGetBytePtr(data);
91
- const CFIndex length = CFDataGetLength(data);
92
- std::string value(reinterpret_cast<const char*>(bytes), static_cast<size_t>(length));
93
- CFRelease(result);
94
- return value;
26
+ return sInMemoryUserJson;
95
27
  }
96
28
 
97
29
  void AuthCache::clear() {
98
- CFMutableDictionaryRef query = createKeychainQuery();
99
- SecItemDelete(query);
100
- CFRelease(query);
30
+ sInMemoryUserJson.clear();
101
31
  }
102
32
  #endif
103
33
 
@@ -108,26 +38,8 @@ struct JContext : JavaClass<JContext> {
108
38
  static constexpr auto kJavaDescriptor = "Landroid/content/Context;";
109
39
  };
110
40
 
111
- struct JAuthAdapter : facebook::jni::JavaClass<JAuthAdapter> {
112
- static constexpr auto kJavaDescriptor = "Lcom/auth/AuthAdapter;";
113
-
114
- static void setUserJson(facebook::jni::alias_ref<jobject> context, const std::string& json) {
115
- static auto method = javaClassStatic()->getStaticMethod<void(alias_ref<JContext>, jstring)>("setUserJson");
116
- method(javaClassStatic(), static_ref_cast<JContext>(context), make_jstring(json).get());
117
- }
118
-
119
- static facebook::jni::local_ref<jstring> getUserJson(facebook::jni::alias_ref<jobject> context) {
120
- static auto method = javaClassStatic()->getStaticMethod<jstring(alias_ref<JContext>)>("getUserJson");
121
- return method(javaClassStatic(), static_ref_cast<JContext>(context));
122
- }
123
-
124
- static void clearUser(facebook::jni::alias_ref<jobject> context) {
125
- static auto method = javaClassStatic()->getStaticMethod<void(alias_ref<JContext>)>("clearUser");
126
- method(javaClassStatic(), static_ref_cast<JContext>(context));
127
- }
128
- };
129
-
130
41
  static facebook::jni::global_ref<jobject> gContext;
42
+ static std::string sInMemoryUserJson;
131
43
 
132
44
  void AuthCache::setAndroidContext(void* context) {
133
45
  gContext = facebook::jni::make_global(static_cast<jobject>(context));
@@ -138,20 +50,18 @@ void* AuthCache::getAndroidContext() {
138
50
  }
139
51
 
140
52
  void AuthCache::setUserJson(const std::string& json) {
141
- if (!gContext) return;
142
- JAuthAdapter::setUserJson(gContext, json);
53
+ sInMemoryUserJson = json;
143
54
  }
144
55
 
145
56
  std::optional<std::string> AuthCache::getUserJson() {
146
- if (!gContext) return std::nullopt;
147
- auto result = JAuthAdapter::getUserJson(gContext);
148
- if (!result) return std::nullopt;
149
- return result->toStdString();
57
+ if (sInMemoryUserJson.empty()) {
58
+ return std::nullopt;
59
+ }
60
+ return sInMemoryUserJson;
150
61
  }
151
62
 
152
63
  void AuthCache::clear() {
153
- if (!gContext) return;
154
- JAuthAdapter::clearUser(gContext);
64
+ sInMemoryUserJson.clear();
155
65
  }
156
66
  #endif
157
67