react-native-nitro-auth 0.5.7 → 0.5.8

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.
@@ -142,6 +142,7 @@ object AuthAdapter {
142
142
  }
143
143
 
144
144
  fun dispose() {
145
+ clearPkceState()
145
146
  moduleScope.cancel()
146
147
  moduleScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
147
148
  runCatching { nativeDispose() }
@@ -309,7 +310,8 @@ object AuthAdapter {
309
310
  val origin = pendingOrigin
310
311
  if (error != null) {
311
312
  clearPkceState()
312
- nativeOnLoginError(origin, error, errorDescription)
313
+ val mappedError = mapMicrosoftOAuthError(error)
314
+ nativeOnLoginError(origin, mappedError, errorDescription ?: error)
313
315
  return
314
316
  }
315
317
  if (state != pendingState) {
@@ -391,7 +393,7 @@ object AuthAdapter {
391
393
  val error = json.optString("error", "token_error")
392
394
  val desc = json.optString("error_description", "Failed to exchange code for tokens")
393
395
  clearPkceState()
394
- nativeOnLoginError(origin, error, desc)
396
+ nativeOnLoginError(origin, mapMicrosoftOAuthError(error), desc)
395
397
  } catch (e: Exception) {
396
398
  clearPkceState()
397
399
  nativeOnLoginError(origin, "token_error", "Failed to exchange code for tokens")
@@ -438,6 +440,7 @@ object AuthAdapter {
438
440
  }
439
441
  }
440
442
 
443
+ @Synchronized
441
444
  private fun clearPkceState() {
442
445
  pendingOrigin = "login"
443
446
  pendingPkceVerifier = null
@@ -450,6 +453,16 @@ object AuthAdapter {
450
453
  microsoftAuthInProgress = false
451
454
  }
452
455
 
456
+ private fun mapMicrosoftOAuthError(error: String): String {
457
+ return when (error) {
458
+ "access_denied", "interaction_required" -> "cancelled"
459
+ "invalid_client", "unauthorized_client" -> "configuration_error"
460
+ "invalid_grant", "invalid_request", "invalid_scope" -> "token_error"
461
+ "temporarily_unavailable", "server_error" -> "network_error"
462
+ else -> "token_error"
463
+ }
464
+ }
465
+
453
466
  private fun decodeJwt(token: String): Map<String, String> {
454
467
  return try {
455
468
  val parts = token.split(".")
@@ -594,8 +607,10 @@ object AuthAdapter {
594
607
  val account = GoogleSignIn.getLastSignedInAccount(ctx)
595
608
  if (account != null) {
596
609
  val newScopes = scopes.map { Scope(it) }
610
+ val grantedScopes = account.grantedScopes?.map { it.scopeUri }.orEmpty()
611
+ val allScopes = (grantedScopes + scopes.toList()).distinct()
597
612
  if (GoogleSignIn.hasPermissions(account, *newScopes.toTypedArray())) {
598
- onSignInSuccess(account, (pendingScopes + scopes.toList()).distinct(), "scopes")
613
+ onSignInSuccess(account, allScopes, "scopes")
599
614
  return
600
615
  }
601
616
  val clientId = getClientIdFromResources(ctx)
@@ -603,7 +618,6 @@ object AuthAdapter {
603
618
  nativeOnLoginError("scopes", "configuration_error", "Google Client ID not configured")
604
619
  return
605
620
  }
606
- val allScopes = (pendingScopes + scopes.toList()).distinct()
607
621
  val intent = GoogleSignInActivity.createIntent(ctx, clientId, allScopes.toTypedArray(), account.email, origin = "scopes")
608
622
  ctx.startActivity(intent)
609
623
  return
@@ -667,6 +681,7 @@ object AuthAdapter {
667
681
  @JvmStatic
668
682
  fun logoutSync(context: Context) {
669
683
  val ctx = appContext ?: context.applicationContext
684
+ clearPkceState()
670
685
  // Clear Credential Manager state (covers One-Tap / passkey credentials).
671
686
  moduleScope.launch {
672
687
  try {
@@ -689,6 +704,7 @@ object AuthAdapter {
689
704
  @JvmStatic
690
705
  fun revokeAccessSync(context: Context) {
691
706
  val ctx = appContext ?: context.applicationContext
707
+ clearPkceState()
692
708
  val clientId = getClientIdFromResources(ctx)
693
709
  if (clientId != null) {
694
710
  val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
@@ -788,7 +804,7 @@ object AuthAdapter {
788
804
  val json = org.json.JSONObject(responseBody)
789
805
  val errorCode = json.optString("error", "token_error")
790
806
  val errorDesc = json.optString("error_description", "Token refresh failed")
791
- Pair(errorCode, errorDesc)
807
+ Pair(mapMicrosoftOAuthError(errorCode), errorDesc)
792
808
  } catch (e: Exception) {
793
809
  Pair("token_error", "Token refresh failed")
794
810
  }
@@ -871,7 +887,7 @@ object AuthAdapter {
871
887
  val json = org.json.JSONObject(errorBody)
872
888
  val errorCode = json.optString("error", "token_error")
873
889
  val errorDesc = json.optString("error_description", "Token refresh failed")
874
- Pair(errorCode, errorDesc)
890
+ Pair(mapMicrosoftOAuthError(errorCode), errorDesc)
875
891
  } catch (e: Exception) {
876
892
  Pair("token_error", "Token refresh failed")
877
893
  }
@@ -2,6 +2,7 @@
2
2
  #include "PlatformAuth.hpp"
3
3
  #include <algorithm>
4
4
  #include <chrono>
5
+ #include <stdexcept>
5
6
 
6
7
  namespace margelo::nitro::NitroAuth {
7
8
 
@@ -69,10 +70,19 @@ std::function<void()> HybridAuth::onTokensRefreshed(const std::function<void(con
69
70
  }
70
71
 
71
72
  void HybridAuth::logout() {
73
+ std::shared_ptr<Promise<AuthTokens>> refreshInFlight;
72
74
  {
73
75
  std::lock_guard<std::recursive_mutex> lock(_mutex);
76
+ _sessionGeneration++;
74
77
  _currentUser = std::nullopt;
75
78
  _grantedScopes.clear();
79
+ refreshInFlight = _refreshInFlight;
80
+ _refreshInFlight = nullptr;
81
+ }
82
+ if (refreshInFlight) {
83
+ refreshInFlight->reject(
84
+ std::make_exception_ptr(std::runtime_error("not_signed_in"))
85
+ );
76
86
  }
77
87
  PlatformAuth::logout();
78
88
  notifyAuthStateChanged();
@@ -80,12 +90,21 @@ void HybridAuth::logout() {
80
90
 
81
91
  std::shared_ptr<Promise<void>> HybridAuth::silentRestore() {
82
92
  auto promise = Promise<void>::create();
93
+ uint64_t generation;
94
+ {
95
+ std::lock_guard<std::recursive_mutex> lock(_mutex);
96
+ generation = _sessionGeneration;
97
+ }
83
98
  auto silentPromise = PlatformAuth::silentRestore();
84
99
  auto self = shared_from_this();
85
- silentPromise->addOnResolvedListener([self, promise](const std::optional<AuthUser>& user) {
100
+ silentPromise->addOnResolvedListener([self, promise, generation](const std::optional<AuthUser>& user) {
86
101
  auto* auth = dynamic_cast<HybridAuth*>(self.get());
87
102
  {
88
103
  std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
104
+ if (auth->_sessionGeneration != generation) {
105
+ promise->resolve();
106
+ return;
107
+ }
89
108
  auth->_currentUser = user;
90
109
  if (user) {
91
110
  if (user->scopes) {
@@ -111,13 +130,24 @@ std::shared_ptr<Promise<void>> HybridAuth::silentRestore() {
111
130
 
112
131
  std::shared_ptr<Promise<void>> HybridAuth::login(AuthProvider provider, const std::optional<LoginOptions>& options) {
113
132
  auto promise = Promise<void>::create();
133
+ uint64_t generation;
134
+ {
135
+ std::lock_guard<std::recursive_mutex> lock(_mutex);
136
+ generation = _sessionGeneration;
137
+ }
114
138
 
115
139
  auto self = shared_from_this();
116
140
  auto loginPromise = PlatformAuth::login(provider, options);
117
- loginPromise->addOnResolvedListener([self, promise, options](const AuthUser& user) {
141
+ loginPromise->addOnResolvedListener([self, promise, options, generation](const AuthUser& user) {
118
142
  auto* auth = dynamic_cast<HybridAuth*>(self.get());
119
143
  {
120
144
  std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
145
+ if (auth->_sessionGeneration != generation) {
146
+ promise->reject(
147
+ std::make_exception_ptr(std::runtime_error("cancelled"))
148
+ );
149
+ return;
150
+ }
121
151
  auth->_currentUser = user;
122
152
  if (user.scopes && !user.scopes->empty()) {
123
153
  auth->_grantedScopes = *user.scopes;
@@ -144,12 +174,23 @@ std::shared_ptr<Promise<void>> HybridAuth::login(AuthProvider provider, const st
144
174
 
145
175
  std::shared_ptr<Promise<void>> HybridAuth::requestScopes(const std::vector<std::string>& scopes) {
146
176
  auto promise = Promise<void>::create();
177
+ uint64_t generation;
178
+ {
179
+ std::lock_guard<std::recursive_mutex> lock(_mutex);
180
+ generation = _sessionGeneration;
181
+ }
147
182
  auto self = shared_from_this();
148
183
  auto requestPromise = PlatformAuth::requestScopes(scopes);
149
- requestPromise->addOnResolvedListener([self, promise, scopes](const AuthUser& user) {
184
+ requestPromise->addOnResolvedListener([self, promise, scopes, generation](const AuthUser& user) {
150
185
  auto* auth = dynamic_cast<HybridAuth*>(self.get());
151
186
  {
152
187
  std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
188
+ if (auth->_sessionGeneration != generation) {
189
+ promise->reject(
190
+ std::make_exception_ptr(std::runtime_error("cancelled"))
191
+ );
192
+ return;
193
+ }
153
194
  auth->_currentUser = user;
154
195
  for (const auto& scope : scopes) {
155
196
  if (std::find(auth->_grantedScopes.begin(), auth->_grantedScopes.end(), scope) == auth->_grantedScopes.end()) {
@@ -191,9 +232,11 @@ std::shared_ptr<Promise<void>> HybridAuth::revokeScopes(const std::vector<std::s
191
232
  std::shared_ptr<Promise<std::optional<std::string>>> HybridAuth::getAccessToken() {
192
233
  auto promise = Promise<std::optional<std::string>>::create();
193
234
  bool needsRefresh = false;
235
+ std::optional<std::string> cachedAccessToken;
194
236
  {
195
237
  std::lock_guard<std::recursive_mutex> lock(_mutex);
196
238
  if (_currentUser && _currentUser->accessToken) {
239
+ cachedAccessToken = _currentUser->accessToken;
197
240
  if (_currentUser->expirationTime) {
198
241
  auto now = std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
199
242
  if (now + 300000 > *_currentUser->expirationTime) needsRefresh = true;
@@ -210,8 +253,8 @@ std::shared_ptr<Promise<std::optional<std::string>>> HybridAuth::getAccessToken(
210
253
 
211
254
  if (needsRefresh) {
212
255
  auto refreshPromise = refreshToken();
213
- refreshPromise->addOnResolvedListener([promise](const AuthTokens& tokens) {
214
- promise->resolve(tokens.accessToken);
256
+ refreshPromise->addOnResolvedListener([promise, cachedAccessToken](const AuthTokens& tokens) {
257
+ promise->resolve(tokens.accessToken.has_value() ? tokens.accessToken : cachedAccessToken);
215
258
  });
216
259
  refreshPromise->addOnRejectedListener([promise](const std::exception_ptr& error) {
217
260
  promise->reject(error);
@@ -222,21 +265,26 @@ std::shared_ptr<Promise<std::optional<std::string>>> HybridAuth::getAccessToken(
222
265
 
223
266
  std::shared_ptr<Promise<AuthTokens>> HybridAuth::refreshToken() {
224
267
  std::shared_ptr<Promise<AuthTokens>> promise;
268
+ uint64_t generation;
225
269
  {
226
270
  std::lock_guard<std::recursive_mutex> lock(_mutex);
227
271
  if (_refreshInFlight) {
228
272
  return _refreshInFlight;
229
273
  }
274
+ generation = _sessionGeneration;
230
275
  promise = Promise<AuthTokens>::create();
231
276
  _refreshInFlight = promise;
232
277
  }
233
278
 
234
279
  auto self = shared_from_this();
235
280
  auto refreshPromise = PlatformAuth::refreshToken();
236
- refreshPromise->addOnResolvedListener([self, promise](const AuthTokens& tokens) {
281
+ refreshPromise->addOnResolvedListener([self, promise, generation](const AuthTokens& tokens) {
237
282
  auto* auth = dynamic_cast<HybridAuth*>(self.get());
238
283
  {
239
284
  std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
285
+ if (auth->_sessionGeneration != generation) {
286
+ return;
287
+ }
240
288
  if (auth->_currentUser) {
241
289
  if (tokens.accessToken.has_value()) {
242
290
  auth->_currentUser->accessToken = tokens.accessToken;
@@ -260,10 +308,13 @@ std::shared_ptr<Promise<AuthTokens>> HybridAuth::refreshToken() {
260
308
  promise->resolve(tokens);
261
309
  });
262
310
 
263
- refreshPromise->addOnRejectedListener([self, promise](const std::exception_ptr& error) {
311
+ refreshPromise->addOnRejectedListener([self, promise, generation](const std::exception_ptr& error) {
264
312
  auto* auth = dynamic_cast<HybridAuth*>(self.get());
265
313
  {
266
314
  std::lock_guard<std::recursive_mutex> lock(auth->_mutex);
315
+ if (auth->_sessionGeneration != generation) {
316
+ return;
317
+ }
267
318
  if (auth->_refreshInFlight == promise) {
268
319
  auth->_refreshInFlight = nullptr;
269
320
  }
@@ -48,6 +48,7 @@ private:
48
48
  std::map<uint64_t, std::function<void(const AuthTokens&)>> _tokenListeners;
49
49
  uint64_t _nextTokenListenerId = 0;
50
50
  std::shared_ptr<Promise<AuthTokens>> _refreshInFlight;
51
+ uint64_t _sessionGeneration = 0;
51
52
 
52
53
  // recursive_mutex: listeners resolved inside a lock scope may re-enter Auth methods
53
54
  // that also acquire _mutex, causing deadlock with a non-recursive mutex.
@@ -261,7 +261,7 @@ public class AuthAdapter: NSObject {
261
261
 
262
262
  URLSession.shared.dataTask(with: request) { data, response, error in
263
263
  DispatchQueue.main.async {
264
- if let error = error {
264
+ if error != nil {
265
265
  completion(nil, "network_error")
266
266
  return
267
267
  }
@@ -626,7 +626,7 @@ public class AuthAdapter: NSObject {
626
626
  .data(using: .utf8)
627
627
  URLSession.shared.dataTask(with: request) { data, response, error in
628
628
  DispatchQueue.main.async {
629
- if let error = error {
629
+ if error != nil {
630
630
  completion(nil, "network_error")
631
631
  return
632
632
  }
@@ -11,7 +11,14 @@ function isAuthErrorCode(value) {
11
11
  return AUTH_ERROR_CODES.has(value);
12
12
  }
13
13
  function toAuthErrorCode(raw) {
14
- return isAuthErrorCode(raw) ? raw : "unknown";
14
+ if (isAuthErrorCode(raw)) {
15
+ return raw;
16
+ }
17
+ const prefix = raw.split(":", 1)[0]?.trim();
18
+ if (prefix && isAuthErrorCode(prefix)) {
19
+ return prefix;
20
+ }
21
+ return "unknown";
15
22
  }
16
23
 
17
24
  /**
@@ -1 +1 @@
1
- {"version":3,"names":["AUTH_ERROR_CODES","Set","isAuthErrorCode","value","has","toAuthErrorCode","raw","AuthError","Error","constructor","message","String","code","name","underlyingMessage","undefined","from","e","exports"],"sourceRoot":"../../../src","sources":["utils/auth-error.ts"],"mappings":";;;;;;;;AAEA,MAAMA,gBAAqC,GAAG,IAAIC,GAAG,CAAgB,CACnE,WAAW,EACX,SAAS,EACT,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,CACV,CAAC;AAEK,SAASC,eAAeA,CAACC,KAAa,EAA0B;EACrE,OAAOH,gBAAgB,CAACI,GAAG,CAACD,KAAK,CAAC;AACpC;AAEO,SAASE,eAAeA,CAACC,GAAW,EAAiB;EAC1D,OAAOJ,eAAe,CAACI,GAAG,CAAC,GAAGA,GAAG,GAAG,SAAS;AAC/C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,SAAS,SAASC,KAAK,CAAC;EAInCC,WAAWA,CAACH,GAAY,EAAE;IACxB,MAAMI,OAAO,GAAGJ,GAAG,YAAYE,KAAK,GAAGF,GAAG,CAACI,OAAO,GAAGC,MAAM,CAACL,GAAG,CAAC;IAChE,MAAMM,IAAI,GAAGP,eAAe,CAACK,OAAO,CAAC;IACrC,KAAK,CAACE,IAAI,CAAC;IACX,IAAI,CAACC,IAAI,GAAG,WAAW;IACvB,IAAI,CAACD,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACE,iBAAiB,GAAGF,IAAI,KAAKF,OAAO,GAAGA,OAAO,GAAGK,SAAS;EACjE;EAEA,OAAOC,IAAIA,CAACC,CAAU,EAAa;IACjC,OAAOA,CAAC,YAAYV,SAAS,GAAGU,CAAC,GAAG,IAAIV,SAAS,CAACU,CAAC,CAAC;EACtD;AACF;AAACC,OAAA,CAAAX,SAAA,GAAAA,SAAA","ignoreList":[]}
1
+ {"version":3,"names":["AUTH_ERROR_CODES","Set","isAuthErrorCode","value","has","toAuthErrorCode","raw","prefix","split","trim","AuthError","Error","constructor","message","String","code","name","underlyingMessage","undefined","from","e","exports"],"sourceRoot":"../../../src","sources":["utils/auth-error.ts"],"mappings":";;;;;;;;AAEA,MAAMA,gBAAqC,GAAG,IAAIC,GAAG,CAAgB,CACnE,WAAW,EACX,SAAS,EACT,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,CACV,CAAC;AAEK,SAASC,eAAeA,CAACC,KAAa,EAA0B;EACrE,OAAOH,gBAAgB,CAACI,GAAG,CAACD,KAAK,CAAC;AACpC;AAEO,SAASE,eAAeA,CAACC,GAAW,EAAiB;EAC1D,IAAIJ,eAAe,CAACI,GAAG,CAAC,EAAE;IACxB,OAAOA,GAAG;EACZ;EAEA,MAAMC,MAAM,GAAGD,GAAG,CAACE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAEC,IAAI,CAAC,CAAC;EAC3C,IAAIF,MAAM,IAAIL,eAAe,CAACK,MAAM,CAAC,EAAE;IACrC,OAAOA,MAAM;EACf;EAEA,OAAO,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMG,SAAS,SAASC,KAAK,CAAC;EAInCC,WAAWA,CAACN,GAAY,EAAE;IACxB,MAAMO,OAAO,GAAGP,GAAG,YAAYK,KAAK,GAAGL,GAAG,CAACO,OAAO,GAAGC,MAAM,CAACR,GAAG,CAAC;IAChE,MAAMS,IAAI,GAAGV,eAAe,CAACQ,OAAO,CAAC;IACrC,KAAK,CAACE,IAAI,CAAC;IACX,IAAI,CAACC,IAAI,GAAG,WAAW;IACvB,IAAI,CAACD,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACE,iBAAiB,GAAGF,IAAI,KAAKF,OAAO,GAAGA,OAAO,GAAGK,SAAS;EACjE;EAEA,OAAOC,IAAIA,CAACC,CAAU,EAAa;IACjC,OAAOA,CAAC,YAAYV,SAAS,GAAGU,CAAC,GAAG,IAAIV,SAAS,CAACU,CAAC,CAAC;EACtD;AACF;AAACC,OAAA,CAAAX,SAAA,GAAAA,SAAA","ignoreList":[]}
@@ -5,7 +5,14 @@ export function isAuthErrorCode(value) {
5
5
  return AUTH_ERROR_CODES.has(value);
6
6
  }
7
7
  export function toAuthErrorCode(raw) {
8
- return isAuthErrorCode(raw) ? raw : "unknown";
8
+ if (isAuthErrorCode(raw)) {
9
+ return raw;
10
+ }
11
+ const prefix = raw.split(":", 1)[0]?.trim();
12
+ if (prefix && isAuthErrorCode(prefix)) {
13
+ return prefix;
14
+ }
15
+ return "unknown";
9
16
  }
10
17
 
11
18
  /**
@@ -1 +1 @@
1
- {"version":3,"names":["AUTH_ERROR_CODES","Set","isAuthErrorCode","value","has","toAuthErrorCode","raw","AuthError","Error","constructor","message","String","code","name","underlyingMessage","undefined","from","e"],"sourceRoot":"../../../src","sources":["utils/auth-error.ts"],"mappings":";;AAEA,MAAMA,gBAAqC,GAAG,IAAIC,GAAG,CAAgB,CACnE,WAAW,EACX,SAAS,EACT,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,CACV,CAAC;AAEF,OAAO,SAASC,eAAeA,CAACC,KAAa,EAA0B;EACrE,OAAOH,gBAAgB,CAACI,GAAG,CAACD,KAAK,CAAC;AACpC;AAEA,OAAO,SAASE,eAAeA,CAACC,GAAW,EAAiB;EAC1D,OAAOJ,eAAe,CAACI,GAAG,CAAC,GAAGA,GAAG,GAAG,SAAS;AAC/C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,SAAS,SAASC,KAAK,CAAC;EAInCC,WAAWA,CAACH,GAAY,EAAE;IACxB,MAAMI,OAAO,GAAGJ,GAAG,YAAYE,KAAK,GAAGF,GAAG,CAACI,OAAO,GAAGC,MAAM,CAACL,GAAG,CAAC;IAChE,MAAMM,IAAI,GAAGP,eAAe,CAACK,OAAO,CAAC;IACrC,KAAK,CAACE,IAAI,CAAC;IACX,IAAI,CAACC,IAAI,GAAG,WAAW;IACvB,IAAI,CAACD,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACE,iBAAiB,GAAGF,IAAI,KAAKF,OAAO,GAAGA,OAAO,GAAGK,SAAS;EACjE;EAEA,OAAOC,IAAIA,CAACC,CAAU,EAAa;IACjC,OAAOA,CAAC,YAAYV,SAAS,GAAGU,CAAC,GAAG,IAAIV,SAAS,CAACU,CAAC,CAAC;EACtD;AACF","ignoreList":[]}
1
+ {"version":3,"names":["AUTH_ERROR_CODES","Set","isAuthErrorCode","value","has","toAuthErrorCode","raw","prefix","split","trim","AuthError","Error","constructor","message","String","code","name","underlyingMessage","undefined","from","e"],"sourceRoot":"../../../src","sources":["utils/auth-error.ts"],"mappings":";;AAEA,MAAMA,gBAAqC,GAAG,IAAIC,GAAG,CAAgB,CACnE,WAAW,EACX,SAAS,EACT,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,CACV,CAAC;AAEF,OAAO,SAASC,eAAeA,CAACC,KAAa,EAA0B;EACrE,OAAOH,gBAAgB,CAACI,GAAG,CAACD,KAAK,CAAC;AACpC;AAEA,OAAO,SAASE,eAAeA,CAACC,GAAW,EAAiB;EAC1D,IAAIJ,eAAe,CAACI,GAAG,CAAC,EAAE;IACxB,OAAOA,GAAG;EACZ;EAEA,MAAMC,MAAM,GAAGD,GAAG,CAACE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAEC,IAAI,CAAC,CAAC;EAC3C,IAAIF,MAAM,IAAIL,eAAe,CAACK,MAAM,CAAC,EAAE;IACrC,OAAOA,MAAM;EACf;EAEA,OAAO,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,SAAS,SAASC,KAAK,CAAC;EAInCC,WAAWA,CAACN,GAAY,EAAE;IACxB,MAAMO,OAAO,GAAGP,GAAG,YAAYK,KAAK,GAAGL,GAAG,CAACO,OAAO,GAAGC,MAAM,CAACR,GAAG,CAAC;IAChE,MAAMS,IAAI,GAAGV,eAAe,CAACQ,OAAO,CAAC;IACrC,KAAK,CAACE,IAAI,CAAC;IACX,IAAI,CAACC,IAAI,GAAG,WAAW;IACvB,IAAI,CAACD,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACE,iBAAiB,GAAGF,IAAI,KAAKF,OAAO,GAAGA,OAAO,GAAGK,SAAS;EACjE;EAEA,OAAOC,IAAIA,CAACC,CAAU,EAAa;IACjC,OAAOA,CAAC,YAAYV,SAAS,GAAGU,CAAC,GAAG,IAAIV,SAAS,CAACU,CAAC,CAAC;EACtD;AACF","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-error.d.ts","sourceRoot":"","sources":["../../../../src/utils/auth-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAoBnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAErE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAE1D;AAED;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEnC,GAAG,EAAE,OAAO;IASxB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS;CAGnC"}
1
+ {"version":3,"file":"auth-error.d.ts","sourceRoot":"","sources":["../../../../src/utils/auth-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAoBnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAErE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAW1D;AAED;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEnC,GAAG,EAAE,OAAO;IASxB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS;CAGnC"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-error.d.ts","sourceRoot":"","sources":["../../../../src/utils/auth-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAoBnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAErE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAE1D;AAED;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEnC,GAAG,EAAE,OAAO;IASxB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS;CAGnC"}
1
+ {"version":3,"file":"auth-error.d.ts","sourceRoot":"","sources":["../../../../src/utils/auth-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAoBnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAErE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAW1D;AAED;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEnC,GAAG,EAAE,OAAO;IASxB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS;CAGnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-auth",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "High-performance authentication library for React Native with Google Sign-In, Apple Sign-In, and Microsoft Sign-In support, powered by Nitro Modules (JSI)",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -39,9 +39,10 @@
39
39
  "test": "jest",
40
40
  "test:coverage": "jest --coverage",
41
41
  "test:cpp": "node scripts/test-cpp.js",
42
- "prepublishOnly": "bun run clean && bun run build",
43
- "prepack": "node -e \"const fs=require('fs'); fs.copyFileSync('../../README.md','./README.md'); try{fs.copyFileSync('../../LICENSE','./LICENSE')}catch(e){}\"",
44
- "postpack": "node -e \"const fs=require('fs'); ['./README.md','./LICENSE'].forEach(f=>fs.existsSync(f)&&fs.unlinkSync(f))\""
42
+ "prepublishOnly": "bun run clean && bun run codegen && bun run build && bun run typecheck && bun run lint && bun run test && bun run test:cpp",
43
+ "prepack": "bun ../../scripts/sync-package-docs.ts",
44
+ "pack:dry-run": "bun pm pack --dry-run",
45
+ "publish:dry-run": "bun publish --dry-run --access public"
45
46
  },
46
47
  "keywords": [
47
48
  "react-native",
@@ -80,13 +81,13 @@
80
81
  "access": "public"
81
82
  },
82
83
  "devDependencies": {
83
- "@expo/config-plugins": "^55.0.6",
84
+ "@expo/config-plugins": "^55.0.8",
84
85
  "@react-native/babel-preset": "^0.83.0",
85
86
  "@testing-library/react": "^16.3.2",
86
87
  "@types/node": "^22.19.11",
87
88
  "jest-environment-jsdom": "^29.7.0",
88
89
  "react": "19.2.0",
89
- "react-native": "0.83.2",
90
+ "react-native": "0.83.4",
90
91
  "react-native-nitro-modules": "^0.35.4",
91
92
  "react-native-web": "^0.21.2",
92
93
  "typescript": "^5.9.3"
@@ -23,7 +23,16 @@ export function isAuthErrorCode(value: string): value is AuthErrorCode {
23
23
  }
24
24
 
25
25
  export function toAuthErrorCode(raw: string): AuthErrorCode {
26
- return isAuthErrorCode(raw) ? raw : "unknown";
26
+ if (isAuthErrorCode(raw)) {
27
+ return raw;
28
+ }
29
+
30
+ const prefix = raw.split(":", 1)[0]?.trim();
31
+ if (prefix && isAuthErrorCode(prefix)) {
32
+ return prefix;
33
+ }
34
+
35
+ return "unknown";
27
36
  }
28
37
 
29
38
  /**