react-native-nitro-auth 0.5.4 → 0.5.6

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 (100) hide show
  1. package/README.md +82 -47
  2. package/android/proguard-rules.pro +7 -1
  3. package/android/src/main/AndroidManifest.xml +12 -0
  4. package/android/src/main/cpp/JniOnLoad.cpp +3 -1
  5. package/android/src/main/cpp/PlatformAuth+Android.cpp +271 -78
  6. package/android/src/main/java/com/auth/AuthAdapter.kt +293 -238
  7. package/android/src/main/java/com/auth/GoogleSignInActivity.kt +9 -5
  8. package/android/src/main/java/com/auth/NitroAuthModule.kt +8 -1
  9. package/cpp/HybridAuth.cpp +79 -64
  10. package/cpp/HybridAuth.hpp +9 -7
  11. package/cpp/JSONSerializer.hpp +3 -0
  12. package/ios/AuthAdapter.swift +226 -79
  13. package/ios/PlatformAuth+iOS.mm +10 -3
  14. package/lib/commonjs/Auth.web.js +50 -10
  15. package/lib/commonjs/Auth.web.js.map +1 -1
  16. package/lib/commonjs/index.js +23 -1
  17. package/lib/commonjs/index.js.map +1 -1
  18. package/lib/commonjs/index.web.js +30 -12
  19. package/lib/commonjs/index.web.js.map +1 -1
  20. package/lib/commonjs/service.js +36 -9
  21. package/lib/commonjs/service.js.map +1 -1
  22. package/lib/commonjs/service.web.js +65 -13
  23. package/lib/commonjs/service.web.js.map +1 -1
  24. package/lib/commonjs/ui/social-button.js +19 -14
  25. package/lib/commonjs/ui/social-button.js.map +1 -1
  26. package/lib/commonjs/ui/social-button.web.js +16 -10
  27. package/lib/commonjs/ui/social-button.web.js.map +1 -1
  28. package/lib/commonjs/use-auth.js +22 -25
  29. package/lib/commonjs/use-auth.js.map +1 -1
  30. package/lib/commonjs/utils/auth-error.js +37 -0
  31. package/lib/commonjs/utils/auth-error.js.map +1 -0
  32. package/lib/commonjs/utils/logger.js +1 -0
  33. package/lib/commonjs/utils/logger.js.map +1 -1
  34. package/lib/module/Auth.web.js +50 -10
  35. package/lib/module/Auth.web.js.map +1 -1
  36. package/lib/module/global.d.js.map +1 -1
  37. package/lib/module/index.js +1 -0
  38. package/lib/module/index.js.map +1 -1
  39. package/lib/module/index.web.js +2 -1
  40. package/lib/module/index.web.js.map +1 -1
  41. package/lib/module/service.js +36 -9
  42. package/lib/module/service.js.map +1 -1
  43. package/lib/module/service.web.js +65 -13
  44. package/lib/module/service.web.js.map +1 -1
  45. package/lib/module/ui/social-button.js +19 -14
  46. package/lib/module/ui/social-button.js.map +1 -1
  47. package/lib/module/ui/social-button.web.js +16 -10
  48. package/lib/module/ui/social-button.web.js.map +1 -1
  49. package/lib/module/use-auth.js +22 -25
  50. package/lib/module/use-auth.js.map +1 -1
  51. package/lib/module/utils/auth-error.js +30 -0
  52. package/lib/module/utils/auth-error.js.map +1 -0
  53. package/lib/module/utils/logger.js +1 -0
  54. package/lib/module/utils/logger.js.map +1 -1
  55. package/lib/typescript/commonjs/Auth.web.d.ts +5 -1
  56. package/lib/typescript/commonjs/Auth.web.d.ts.map +1 -1
  57. package/lib/typescript/commonjs/index.d.ts +1 -0
  58. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  59. package/lib/typescript/commonjs/index.web.d.ts +2 -1
  60. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  61. package/lib/typescript/commonjs/service.d.ts.map +1 -1
  62. package/lib/typescript/commonjs/service.web.d.ts +2 -18
  63. package/lib/typescript/commonjs/service.web.d.ts.map +1 -1
  64. package/lib/typescript/commonjs/ui/social-button.d.ts.map +1 -1
  65. package/lib/typescript/commonjs/ui/social-button.web.d.ts.map +1 -1
  66. package/lib/typescript/commonjs/use-auth.d.ts +2 -1
  67. package/lib/typescript/commonjs/use-auth.d.ts.map +1 -1
  68. package/lib/typescript/commonjs/utils/auth-error.d.ts +16 -0
  69. package/lib/typescript/commonjs/utils/auth-error.d.ts.map +1 -0
  70. package/lib/typescript/commonjs/utils/logger.d.ts.map +1 -1
  71. package/lib/typescript/module/Auth.web.d.ts +5 -1
  72. package/lib/typescript/module/Auth.web.d.ts.map +1 -1
  73. package/lib/typescript/module/index.d.ts +1 -0
  74. package/lib/typescript/module/index.d.ts.map +1 -1
  75. package/lib/typescript/module/index.web.d.ts +2 -1
  76. package/lib/typescript/module/index.web.d.ts.map +1 -1
  77. package/lib/typescript/module/service.d.ts.map +1 -1
  78. package/lib/typescript/module/service.web.d.ts +2 -18
  79. package/lib/typescript/module/service.web.d.ts.map +1 -1
  80. package/lib/typescript/module/ui/social-button.d.ts.map +1 -1
  81. package/lib/typescript/module/ui/social-button.web.d.ts.map +1 -1
  82. package/lib/typescript/module/use-auth.d.ts +2 -1
  83. package/lib/typescript/module/use-auth.d.ts.map +1 -1
  84. package/lib/typescript/module/utils/auth-error.d.ts +16 -0
  85. package/lib/typescript/module/utils/auth-error.d.ts.map +1 -0
  86. package/lib/typescript/module/utils/logger.d.ts.map +1 -1
  87. package/nitrogen/generated/android/NitroAuthOnLoad.cpp +22 -17
  88. package/nitrogen/generated/android/NitroAuthOnLoad.hpp +13 -4
  89. package/package.json +8 -10
  90. package/src/Auth.web.ts +77 -11
  91. package/src/global.d.ts +0 -11
  92. package/src/index.ts +5 -0
  93. package/src/index.web.ts +6 -1
  94. package/src/service.ts +37 -9
  95. package/src/service.web.ts +84 -15
  96. package/src/ui/social-button.tsx +21 -9
  97. package/src/ui/social-button.web.tsx +17 -4
  98. package/src/use-auth.ts +29 -67
  99. package/src/utils/auth-error.ts +49 -0
  100. package/src/utils/logger.ts +1 -0
package/README.md CHANGED
@@ -71,11 +71,11 @@ bun add react-native-nitro-auth react-native-nitro-modules
71
71
 
72
72
  ### Requirements
73
73
 
74
- | Dependency | Version |
75
- | ---------------------------- | ----------- |
76
- | `react-native` | `>= 0.75.0` |
77
- | `react-native-nitro-modules` | `>= 0.33.9` |
78
- | `react` | `*` |
74
+ | Dependency | Version |
75
+ | ---------------------------- | ------------ |
76
+ | `react-native` | `>= 0.75.0` |
77
+ | `react-native-nitro-modules` | `>= 0.35.0` |
78
+ | `react` | `*` |
79
79
 
80
80
  For Expo projects, rebuild native code after installation:
81
81
 
@@ -308,12 +308,13 @@ To enable Microsoft Sign-In, you need to register an application in the Azure Po
308
308
  - `nitro_auth_microsoft_client_id`
309
309
  - `nitro_auth_microsoft_tenant` (optional)
310
310
  - `nitro_auth_microsoft_b2c_domain` (optional)
311
- - Add the Microsoft redirect activity to `AndroidManifest.xml`:
311
+ - `MicrosoftAuthActivity` is **automatically declared** by the library manifest — no manual `AndroidManifest.xml` entry is required for basic Microsoft OAuth redirect handling. If you need to customize the intent-filter (e.g., restrict the host/path to your specific package and client ID), you can override it in your app manifest:
312
312
 
313
313
  ```xml
314
314
  <activity
315
315
  android:name="com.auth.MicrosoftAuthActivity"
316
- android:exported="true">
316
+ android:exported="true"
317
+ android:launchMode="singleTask">
317
318
  <intent-filter>
318
319
  <action android:name="android.intent.action.VIEW" />
319
320
  <category android:name="android.intent.category.DEFAULT" />
@@ -670,61 +671,73 @@ const freshToken = await AuthService.getAccessToken();
670
671
 
671
672
  ### Standardized Error Codes
672
673
 
673
- Handle failures reliably with predictable error strings. Some flows can surface provider-specific codes (listed below):
674
+ All errors thrown by `AuthService` and `useAuth` are `AuthError` instances with a type-safe `code` field (always a valid `AuthErrorCode`) and an optional `underlyingMessage` with the raw provider string when it differs from the code.
674
675
 
675
676
  ```ts
677
+ import { AuthError } from "react-native-nitro-auth";
678
+
676
679
  try {
677
680
  await login("google");
678
681
  } catch (e) {
679
- const error = e as Error;
680
- if (error.message === "cancelled") {
681
- // User closed the popup/picker
682
- } else if (error.message === "network_error") {
683
- // Connection issues
682
+ if (e instanceof AuthError) {
683
+ switch (e.code) {
684
+ case "cancelled":
685
+ // User closed the popup/picker
686
+ break;
687
+ case "network_error":
688
+ // Connection issues
689
+ break;
690
+ default:
691
+ console.error(e.code, e.underlyingMessage);
692
+ }
684
693
  }
685
694
  }
686
695
  ```
687
696
 
688
- | Error Code | Description |
689
- | ---------------------- | ---------------------------------------------- |
690
- | `cancelled` | The user cancelled the sign-in flow |
691
- | `network_error` | A network error occurred |
692
- | `configuration_error` | Missing client IDs or invalid setup |
693
- | `unsupported_provider` | The provider is not supported on this platform |
694
- | `invalid_state` | PKCE state mismatch (possible CSRF) |
695
- | `invalid_nonce` | Nonce mismatch in token response |
696
- | `token_error` | Token exchange failed |
697
- | `no_id_token` | No `id_token` in token response |
698
- | `parse_error` | Failed to parse token response |
699
- | `refresh_failed` | Refresh token flow failed |
700
- | `unknown` | An unknown error occurred |
697
+ | Error Code | Description |
698
+ | ---------------------- | --------------------------------------------------------------- |
699
+ | `cancelled` | The user cancelled the sign-in flow or dismissed the popup |
700
+ | `timeout` | The login popup/flow timed out |
701
+ | `popup_blocked` | The browser blocked the popup window |
702
+ | `network_error` | A network or connectivity error occurred |
703
+ | `configuration_error` | Missing client IDs, invalid tenant, or misconfigured setup |
704
+ | `unsupported_provider` | The provider is not supported on this platform |
705
+ | `invalid_state` | PKCE state mismatch — possible CSRF attack |
706
+ | `invalid_nonce` | Nonce mismatch in token response — possible replay attack |
707
+ | `token_error` | Token exchange or storage failed |
708
+ | `no_id_token` | No `id_token` in token response |
709
+ | `parse_error` | Failed to parse token response |
710
+ | `refresh_failed` | Refresh token flow failed (token may be expired or revoked) |
711
+ | `unknown` | An unknown or unmapped error occurred |
701
712
 
702
713
  ### Native Error Metadata
703
714
 
704
- For more detailed debugging, Nitro Auth captures raw provider/native details in `underlyingError` where available:
715
+ `AuthError` carries the raw provider/native message in `underlyingMessage` when the platform error didn't map to a known code:
705
716
 
706
717
  ```ts
707
- // From authenticated user (on success)
708
- const { user } = useAuth();
709
- if (user?.underlyingError) {
710
- console.warn("Auth warning:", user.underlyingError);
711
- }
718
+ import { AuthError } from "react-native-nitro-auth";
712
719
 
713
- // From error (on failure)
714
720
  try {
715
721
  await login("google");
716
722
  } catch (e) {
717
- const error = e as Error & { underlyingError?: string };
718
- console.log("Native error:", error.underlyingError);
723
+ if (e instanceof AuthError) {
724
+ // e.code is always a valid AuthErrorCode
725
+ // e.underlyingMessage is the original native string (or undefined if it equalled the code)
726
+ console.log(e.code, e.underlyingMessage);
727
+ }
719
728
  }
720
729
  ```
721
730
 
731
+ The `AuthUser.underlyingError` field carries a raw warning string when the provider returns one alongside a successful result.
732
+
722
733
  ### Troubleshooting
723
734
 
724
- - `configuration_error`: verify client IDs, URL schemes, and redirect URIs are set for the current platform.
725
- - `invalid_state` or `invalid_nonce`: ensure the redirect URI in your provider console matches your app config exactly.
735
+ - `configuration_error`: verify client IDs, URL schemes, and redirect URIs are set for the current platform. On Android, check that the `microsoftTenant` is a non-empty valid value.
736
+ - `invalid_state` or `invalid_nonce`: ensure the redirect URI in your provider console matches your app config exactly. These indicate a potential CSRF or replay attack — do not retry silently.
737
+ - `refresh_failed`: the refresh token is likely expired or revoked. Clear the session and prompt the user to sign in again. On Android and web, structured error details from the provider (e.g. `invalid_grant`) are surfaced via `error.underlyingMessage`.
726
738
  - `hasPlayServices` is false: prompt the user to install/update Google Play Services or disable One-Tap.
727
739
  - Apple web login fails: confirm `appleWebClientId` is set and your domain is registered with Apple.
740
+ - Microsoft Android redirect hangs: confirm the `msauth://` redirect URI in your Azure app matches your package name and client ID.
728
741
 
729
742
  ### Automatic Token Refresh
730
743
 
@@ -797,6 +810,9 @@ This is useful for scenarios where:
797
810
  ```ts
798
811
  import {
799
812
  AuthService,
813
+ AuthError,
814
+ isAuthErrorCode,
815
+ toAuthErrorCode,
800
816
  SocialButton,
801
817
  useAuth,
802
818
  type UseAuthReturn,
@@ -869,7 +885,7 @@ declare function useAuth(): UseAuthReturn;
869
885
  | `user` | `AuthUser \| undefined` | Current in-memory user |
870
886
  | `scopes` | `string[]` | Current granted scopes |
871
887
  | `loading` | `boolean` | `true` while an auth operation is in-flight |
872
- | `error` | `Error \| undefined` | Last operation error |
888
+ | `error` | `AuthError \| undefined` | Last operation error (typed, safe to switch on `.code`) |
873
889
  | `hasPlayServices` | `boolean` | Android Play Services availability |
874
890
  | `login` | `(provider: AuthProvider, options?: LoginOptions) => Promise<void>` | Starts provider login |
875
891
  | `logout` | `() => void` | Clears current session |
@@ -965,17 +981,36 @@ There is no public `setStorageAdapter`/`setJSStorageAdapter` API in this package
965
981
  | `nitroAuthWebStorage` | `"session" \| "local" \| "memory"` | `"session"` | Storage for non-sensitive web cache |
966
982
  | `nitroAuthPersistTokensOnWeb` | `boolean` | `false` | Persist sensitive tokens on web storage instead of memory |
967
983
 
968
- ### Error semantics
984
+ ### `AuthError`
969
985
 
970
- Errors are surfaced as `Error` with `message` as a normalized code when possible, and `underlyingError` with provider/native details.
986
+ All thrown errors from `AuthService` and `useAuth` are `AuthError` instances.
971
987
 
972
- | Normalized message | Meaning |
973
- | --------------------- | ---------------------------------------------- |
974
- | `cancelled` | User cancelled popup/login flow |
975
- | `timeout` | Provider popup did not complete before timeout |
976
- | `popup_blocked` | Browser blocked popup opening |
977
- | `network_error` | Network failure |
978
- | `configuration_error` | Missing/invalid provider configuration |
988
+ ```ts
989
+ class AuthError extends Error {
990
+ readonly code: AuthErrorCode; // Always a valid AuthErrorCode — safe to switch on
991
+ readonly underlyingMessage?: string; // Raw native/platform string when it differs from code
992
+ static from(e: unknown): AuthError; // Wraps any value; passes AuthError instances through
993
+ }
994
+
995
+ function isAuthErrorCode(value: string): value is AuthErrorCode;
996
+ function toAuthErrorCode(raw: string): AuthErrorCode; // Returns "unknown" for unrecognized strings
997
+ ```
998
+
999
+ | `code` | Meaning |
1000
+ | ---------------------- | ---------------------------------------------- |
1001
+ | `cancelled` | User cancelled the login flow |
1002
+ | `timeout` | Provider popup did not complete before timeout |
1003
+ | `popup_blocked` | Browser blocked popup opening |
1004
+ | `network_error` | Network failure |
1005
+ | `configuration_error` | Missing/invalid provider configuration |
1006
+ | `unsupported_provider` | Provider not supported on this platform |
1007
+ | `invalid_state` | PKCE state mismatch (possible CSRF) |
1008
+ | `invalid_nonce` | Nonce mismatch in token response |
1009
+ | `token_error` | Token exchange failed |
1010
+ | `no_id_token` | No `id_token` in token response |
1011
+ | `parse_error` | Failed to parse token response |
1012
+ | `refresh_failed` | Refresh token flow failed |
1013
+ | `unknown` | Unrecognized error |
979
1014
 
980
1015
  ## Quality Gates
981
1016
 
@@ -1,4 +1,10 @@
1
1
  # Nitro Auth Proguard Rules
2
- -keep class com.auth.** { *; }
2
+ -keep class com.auth.AuthAdapter {
3
+ public static <methods>;
4
+ }
5
+ -keep class com.auth.MicrosoftAuthActivity { *; }
6
+ -keep class com.auth.GoogleSignInActivity { *; }
7
+ -keep class com.auth.NitroAuthModule { *; }
8
+ -keep class com.auth.NitroAuthPackage { *; }
3
9
  -keep class com.margelo.nitro.com.auth.** { *; }
4
10
  -keep class com.google.android.gms.auth.api.signin.** { *; }
@@ -8,5 +8,17 @@
8
8
  android:name="com.auth.GoogleSignInActivity"
9
9
  android:theme="@android:style/Theme.Translucent.NoTitleBar"
10
10
  android:exported="false" />
11
+ <activity
12
+ android:name="com.auth.MicrosoftAuthActivity"
13
+ android:exported="true"
14
+ android:theme="@android:style/Theme.Translucent.NoTitleBar"
15
+ android:launchMode="singleTask">
16
+ <intent-filter>
17
+ <action android:name="android.intent.action.VIEW" />
18
+ <category android:name="android.intent.category.DEFAULT" />
19
+ <category android:name="android.intent.category.BROWSABLE" />
20
+ <data android:scheme="msauth" />
21
+ </intent-filter>
22
+ </activity>
11
23
  </application>
12
24
  </manifest>
@@ -4,5 +4,7 @@
4
4
 
5
5
  extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
6
6
  (void)reserved;
7
- return margelo::nitro::NitroAuth::initialize(vm);
7
+ return facebook::jni::initialize(vm, []() {
8
+ margelo::nitro::NitroAuth::registerAllNatives();
9
+ });
8
10
  }