react-native-nitro-auth 0.5.12 → 0.6.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 (93) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +132 -32
  3. package/android/build.gradle +4 -4
  4. package/android/gradle.properties +2 -2
  5. package/android/src/main/cpp/PlatformAuth+Android.cpp +87 -4
  6. package/android/src/main/java/com/auth/AuthAdapter.kt +85 -48
  7. package/android/src/main/java/com/auth/GoogleSignInActivity.kt +12 -2
  8. package/cpp/HybridAuth.cpp +168 -18
  9. package/cpp/HybridAuth.hpp +7 -0
  10. package/cpp/PlatformAuth.hpp +1 -0
  11. package/ios/AuthAdapter.swift +101 -24
  12. package/ios/PlatformAuth+iOS.mm +37 -1
  13. package/lib/commonjs/Auth.web.js +74 -21
  14. package/lib/commonjs/Auth.web.js.map +1 -1
  15. package/lib/commonjs/create-auth-service.js +10 -0
  16. package/lib/commonjs/create-auth-service.js.map +1 -1
  17. package/lib/commonjs/index.js +12 -0
  18. package/lib/commonjs/index.js.map +1 -1
  19. package/lib/commonjs/index.web.js +12 -0
  20. package/lib/commonjs/index.web.js.map +1 -1
  21. package/lib/commonjs/provider-options.js +6 -0
  22. package/lib/commonjs/provider-options.js.map +1 -0
  23. package/lib/commonjs/service.js.map +1 -1
  24. package/lib/commonjs/service.web.js.map +1 -1
  25. package/lib/commonjs/use-auth.js +21 -1
  26. package/lib/commonjs/use-auth.js.map +1 -1
  27. package/lib/module/Auth.web.js +74 -21
  28. package/lib/module/Auth.web.js.map +1 -1
  29. package/lib/module/create-auth-service.js +10 -0
  30. package/lib/module/create-auth-service.js.map +1 -1
  31. package/lib/module/global.d.js.map +1 -1
  32. package/lib/module/index.js +1 -0
  33. package/lib/module/index.js.map +1 -1
  34. package/lib/module/index.web.js +1 -0
  35. package/lib/module/index.web.js.map +1 -1
  36. package/lib/module/provider-options.js +4 -0
  37. package/lib/module/provider-options.js.map +1 -0
  38. package/lib/module/service.js.map +1 -1
  39. package/lib/module/service.web.js.map +1 -1
  40. package/lib/module/use-auth.js +21 -1
  41. package/lib/module/use-auth.js.map +1 -1
  42. package/lib/typescript/commonjs/Auth.nitro.d.ts +11 -0
  43. package/lib/typescript/commonjs/Auth.nitro.d.ts.map +1 -1
  44. package/lib/typescript/commonjs/Auth.web.d.ts +4 -0
  45. package/lib/typescript/commonjs/Auth.web.d.ts.map +1 -1
  46. package/lib/typescript/commonjs/create-auth-service.d.ts +2 -1
  47. package/lib/typescript/commonjs/create-auth-service.d.ts.map +1 -1
  48. package/lib/typescript/commonjs/index.d.ts +1 -0
  49. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  50. package/lib/typescript/commonjs/index.web.d.ts +1 -0
  51. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/provider-options.d.ts +23 -0
  53. package/lib/typescript/commonjs/provider-options.d.ts.map +1 -0
  54. package/lib/typescript/commonjs/service.d.ts +2 -2
  55. package/lib/typescript/commonjs/service.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/service.web.d.ts +2 -2
  57. package/lib/typescript/commonjs/service.web.d.ts.map +1 -1
  58. package/lib/typescript/commonjs/use-auth.d.ts +4 -2
  59. package/lib/typescript/commonjs/use-auth.d.ts.map +1 -1
  60. package/lib/typescript/module/Auth.nitro.d.ts +11 -0
  61. package/lib/typescript/module/Auth.nitro.d.ts.map +1 -1
  62. package/lib/typescript/module/Auth.web.d.ts +4 -0
  63. package/lib/typescript/module/Auth.web.d.ts.map +1 -1
  64. package/lib/typescript/module/create-auth-service.d.ts +2 -1
  65. package/lib/typescript/module/create-auth-service.d.ts.map +1 -1
  66. package/lib/typescript/module/index.d.ts +1 -0
  67. package/lib/typescript/module/index.d.ts.map +1 -1
  68. package/lib/typescript/module/index.web.d.ts +1 -0
  69. package/lib/typescript/module/index.web.d.ts.map +1 -1
  70. package/lib/typescript/module/provider-options.d.ts +23 -0
  71. package/lib/typescript/module/provider-options.d.ts.map +1 -0
  72. package/lib/typescript/module/service.d.ts +2 -2
  73. package/lib/typescript/module/service.d.ts.map +1 -1
  74. package/lib/typescript/module/service.web.d.ts +2 -2
  75. package/lib/typescript/module/service.web.d.ts.map +1 -1
  76. package/lib/typescript/module/use-auth.d.ts +4 -2
  77. package/lib/typescript/module/use-auth.d.ts.map +1 -1
  78. package/nitrogen/generated/shared/c++/AuthUser.hpp +17 -1
  79. package/nitrogen/generated/shared/c++/HybridAuthSpec.cpp +1 -0
  80. package/nitrogen/generated/shared/c++/HybridAuthSpec.hpp +1 -0
  81. package/nitrogen/generated/shared/c++/LoginOptions.hpp +25 -1
  82. package/package.json +7 -7
  83. package/react-native-nitro-auth.podspec +1 -1
  84. package/src/Auth.nitro.ts +11 -0
  85. package/src/Auth.web.ts +99 -16
  86. package/src/create-auth-service.ts +19 -9
  87. package/src/global.d.ts +2 -1
  88. package/src/index.ts +1 -0
  89. package/src/index.web.ts +1 -0
  90. package/src/provider-options.ts +62 -0
  91. package/src/service.ts +2 -1
  92. package/src/service.web.ts +2 -2
  93. package/src/use-auth.ts +22 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.1 - 2026-05-21
4
+
5
+ ### Changed
6
+
7
+ - Updated the package and Expo example baseline to Expo SDK 56, React Native 0.85.3, React 19.2.3, TypeScript 6.0.3, Nitro Modules 0.35.7, and nitrogen 0.35.7.
8
+ - Raised the iOS deployment target to 16.4 for SDK 56 compatibility.
9
+ - Added release preflight checks for Expo dependency validation, Expo Doctor, config introspection, package build, tests, C++ tests, and publish dry run.
10
+ - Simplified the example app by keeping provider-specific advanced options collapsed by default.
11
+ - Updated README badges, setup commands, release checks, and typed API examples to match the 0.6.1 package state.
12
+ - Added compile-time coverage for provider-specific login option types.
13
+ - Added CI setup and versioned tool detection for LLVM C++ coverage tools.
14
+ - Added a CI-safe release preflight mode that skips unauthenticated npm publish dry runs while keeping local publish dry runs intact.
15
+
16
+ ### Fixed
17
+
18
+ - Retained the active iOS Apple Sign-In controller until completion to avoid premature native lifecycle cleanup.
19
+ - Removed the example app's import-time native logging side effect.
20
+ - Removed Turbo cache-output warnings from lint and typecheck tasks.
21
+
22
+ ## 0.6.0 - 2026-05-14
23
+
24
+ ### Added
25
+
26
+ - Added provider option support for Google nonce, hosted domain, OpenID realm, authorized-account filtering, verified phone number requests, refresh-code forcing, and Android legacy Google sign-in.
27
+ - Added Apple nonce and authorization-code/user-id result support.
28
+ - Added Microsoft tenant and prompt option coverage across native and web flows.
29
+ - Added `revokeAccess()` to the native/web auth API and `useAuth()` hook.
30
+ - Added native logging hooks and platform-gated example controls for supported provider options only.
31
+ - Added provider-specific TypeScript option types for `AuthService.login()` and `useAuth().login()`.
32
+
33
+ ### Changed
34
+
35
+ - Updated Nitro Modules and native SDK dependencies, including Android Credential Manager, Activity, Browser, and API 36 targets.
36
+ - Hardened native and web promise handling so stale sign-in, scope, restore, revoke, and token operations settle consistently.
37
+ - Updated Android Google sign-out to avoid noisy Credential Manager cleanup during normal logout while preserving deep cleanup through revoke access.
38
+
39
+ ### Fixed
40
+
41
+ - Fixed Android Metro watcher noise from transient Bun `node_modules/.old-*` directories in the example app.
42
+ - Fixed Android Google cancellation handling so cancellations are not reported as unknown failures.
43
+ - Fixed native session cleanup paths to reject pending work before clearing provider state.
44
+
3
45
  ## 0.5.12 - 2026-05-13
4
46
 
5
47
  ### Changed
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # react-native-nitro-auth
2
2
 
3
- ![npm](https://img.shields.io/badge/npm-v0.5.12-f97316?style=flat-square)
4
- ![license](https://img.shields.io/badge/license-MIT-007ec6?style=flat-square)
5
- ![react-native](https://img.shields.io/badge/react--native-%3E%3D0.75-61dafb?style=flat-square)
6
- ![nitro-modules](https://img.shields.io/badge/nitro--modules-%3E%3D0.35.0-black?style=flat-square)
3
+ [![npm](https://img.shields.io/badge/npm-v0.6.1-f97316?style=flat-square)](https://www.npmjs.com/package/react-native-nitro-auth)
4
+ [![license](https://img.shields.io/badge/license-MIT-007ec6?style=flat-square)](https://github.com/JoaoPauloCMarra/react-native-nitro-auth/blob/main/LICENSE)
5
+ [![react-native](https://img.shields.io/badge/react--native-%3E%3D0.75-61dafb?style=flat-square)](https://reactnative.dev/)
6
+ [![nitro-modules](https://img.shields.io/badge/nitro--modules-%3E%3D0.35.0-black?style=flat-square)](https://nitro.margelo.com/)
7
7
 
8
8
  Fast React Native authentication for Google Sign-In, Apple Sign-In, and Microsoft Entra ID, built on Nitro Modules and JSI.
9
9
 
@@ -41,6 +41,8 @@ For Expo projects, prebuild after adding the config plugin:
41
41
  bunx expo prebuild --clean
42
42
  ```
43
43
 
44
+ The example app uses Expo Continuous Native Generation. Its `apps/example/android` and `apps/example/ios` folders are generated local artifacts and intentionally ignored by git.
45
+
44
46
  For bare React Native projects, install pods after installing the package:
45
47
 
46
48
  ```sh
@@ -49,13 +51,15 @@ cd ios && pod install
49
51
 
50
52
  ## Requirements
51
53
 
52
- | Runtime | Requirement |
53
- | --------------------- | ---------------------------------------- |
54
- | React Native | `>=0.75` |
55
- | Nitro Modules | `>=0.35` |
56
- | iOS | 15.1+ recommended |
57
- | Android | min SDK 24+ recommended |
58
- | Expo example baseline | Expo SDK 55, React Native 0.83, React 19 |
54
+ | Runtime | Requirement |
55
+ | ------------------ | ---------------------------------------- |
56
+ | React Native | `>=0.75` peer range |
57
+ | Nitro Modules | `>=0.35` peer range |
58
+ | iOS | 16.4+ for Expo SDK 56 |
59
+ | Android | min SDK 24+ recommended |
60
+ | Validated baseline | Expo SDK 56, React Native 0.85, React 19 |
61
+
62
+ The package keeps a wide React Native peer range for existing consumers, but this release is validated against Expo SDK 56, React Native 0.85.3, React 19.2.3, and Nitro Modules 0.35.7.
59
63
 
60
64
  ## Expo Setup
61
65
 
@@ -154,16 +158,23 @@ Use `microsoftTenant` for `common`, `organizations`, `consumers`, a tenant ID, o
154
158
 
155
159
  ```tsx
156
160
  import { Button, Text, View } from "react-native";
157
- import { AuthError, useAuth } from "react-native-nitro-auth";
161
+ import {
162
+ AuthError,
163
+ type GoogleLoginOptions,
164
+ useAuth,
165
+ } from "react-native-nitro-auth";
166
+
167
+ const googleOptions = {
168
+ scopes: ["email", "profile"],
169
+ forceAccountPicker: true,
170
+ } satisfies GoogleLoginOptions;
158
171
 
159
172
  export function SignInScreen() {
160
173
  const { user, loading, login, logout, getAccessToken } = useAuth();
161
174
 
162
175
  async function signInWithGoogle() {
163
176
  try {
164
- await login("google", {
165
- scopes: ["email", "profile"],
166
- });
177
+ await login("google", googleOptions);
167
178
  } catch (e) {
168
179
  const error = AuthError.from(e);
169
180
  console.warn(error.code, error.underlyingMessage);
@@ -232,29 +243,45 @@ tokensUnsubscribe();
232
243
  await login("google", {
233
244
  scopes: ["email", "profile"],
234
245
  loginHint: "user@example.com",
246
+ nonce: "opaque-nonce",
235
247
  useOneTap: true,
236
- useSheet: true,
237
248
  forceAccountPicker: true,
249
+ filterByAuthorizedAccounts: true,
238
250
  useLegacyGoogleSignIn: true,
251
+ forceCodeForRefreshToken: true,
252
+ hostedDomain: "company.com",
253
+ requestVerifiedPhoneNumber: true,
254
+ });
255
+
256
+ await login("apple", {
257
+ scopes: ["email", "name"],
258
+ nonce: "opaque-nonce",
239
259
  });
240
260
 
241
261
  await login("microsoft", {
242
262
  scopes: ["openid", "profile", "email", "offline_access", "User.Read"],
263
+ loginHint: "user@example.com",
243
264
  tenant: "organizations",
244
265
  prompt: "select_account",
245
266
  });
246
267
  ```
247
268
 
248
- | Option | Applies to | Notes |
249
- | ----------------------- | ----------------- | ---------------------------------------------------- |
250
- | `scopes` | Google, Microsoft | Requested OAuth scopes |
251
- | `loginHint` | Google, Microsoft | Prefills account selection when supported |
252
- | `useOneTap` | Android Google | Enables Credential Manager auto-select |
253
- | `useSheet` | iOS Google | Uses native sign-in sheet behavior |
254
- | `forceAccountPicker` | Google | Forces account picker |
255
- | `useLegacyGoogleSignIn` | Android Google | Uses legacy Google Sign-In path for server auth code |
256
- | `tenant` | Microsoft | Overrides configured tenant |
257
- | `prompt` | Microsoft | `login`, `consent`, `select_account`, or `none` |
269
+ | Option | Provider | Platform | Notes |
270
+ | ---------------------------- | ------------ | ---------------- | ----------------------------------------------------------- |
271
+ | `scopes` | All | iOS, Android, web | Requested OAuth scopes. Apple is unavailable on Android. |
272
+ | `loginHint` | Google, Microsoft | iOS, Android, web | Prefills account selection when supported by the provider. |
273
+ | `nonce` | Google, Apple | iOS, Android, web | Passed to provider ID-token flows when the SDK supports it. |
274
+ | `useOneTap` | Google | Android | Enables Credential Manager auto-select. |
275
+ | `useSheet` | Google | iOS | Compatibility alias; prefer `forceAccountPicker`. |
276
+ | `forceAccountPicker` | Google | iOS, Android, web | Forces an account picker. Android uses the legacy chooser. |
277
+ | `filterByAuthorizedAccounts` | Google | Android | Limits Credential Manager to authorized accounts. |
278
+ | `useLegacyGoogleSignIn` | Google | Android | Uses legacy Google Sign-In for server auth code flows. |
279
+ | `forceCodeForRefreshToken` | Google | Android | Forces a new server auth code on the legacy Google path. |
280
+ | `hostedDomain` | Google | iOS, Android, web | Hints or filters Google Workspace hosted-domain accounts. |
281
+ | `openIDRealm` | Google | iOS, web | Adds OpenID realm support where the SDK exposes it. |
282
+ | `requestVerifiedPhoneNumber` | Google | Android | Requests verified phone number through Credential Manager. |
283
+ | `tenant` | Microsoft | iOS, Android, web | Overrides configured tenant. |
284
+ | `prompt` | Microsoft | iOS, Android, web | `login`, `consent`, `select_account`, or `none`. |
258
285
 
259
286
  ## Incremental Scopes
260
287
 
@@ -357,6 +384,18 @@ Main exports:
357
384
  - `AuthUser`
358
385
  - `AuthTokens`
359
386
  - `LoginOptions`
387
+ - `ProviderLoginOptions`
388
+ - `LoginOptionsByProvider`
389
+ - `GoogleLoginOptions`
390
+ - `GoogleIOSLoginOptions`
391
+ - `GoogleAndroidLoginOptions`
392
+ - `GoogleWebLoginOptions`
393
+ - `AppleLoginOptions`
394
+ - `AppleIOSLoginOptions`
395
+ - `AppleWebLoginOptions`
396
+ - `MicrosoftLoginOptions`
397
+ - `AuthLogin`
398
+ - `TypedAuth`
360
399
 
361
400
  ### useAuth()
362
401
 
@@ -371,12 +410,66 @@ type UseAuthReturn = {
371
410
  logout(): void;
372
411
  requestScopes(scopes: string[]): Promise<void>;
373
412
  revokeScopes(scopes: string[]): Promise<void>;
413
+ revokeAccess(): Promise<void>;
374
414
  getAccessToken(): Promise<string | undefined>;
375
415
  refreshToken(): Promise<AuthTokens>;
376
416
  silentRestore(): Promise<void>;
377
417
  };
378
418
  ```
379
419
 
420
+ ### Strong Login Types
421
+
422
+ `AuthService.login()` and `useAuth().login()` infer the allowed option object from the provider argument. Provider-specific option types intentionally reject unsupported keys, so TypeScript can catch mistakes before they become native configuration bugs.
423
+
424
+ ```ts
425
+ await AuthService.login("apple", {
426
+ nonce: "opaque-nonce",
427
+ });
428
+
429
+ await AuthService.login("microsoft", {
430
+ tenant: "organizations",
431
+ prompt: "select_account",
432
+ });
433
+ ```
434
+
435
+ Provider/platform option helpers are exported for config builders and AI-generated integrations:
436
+
437
+ ```ts
438
+ import type {
439
+ GoogleAndroidLoginOptions,
440
+ GoogleIOSLoginOptions,
441
+ MicrosoftLoginOptions,
442
+ } from "react-native-nitro-auth";
443
+
444
+ const androidGoogleOptions = {
445
+ useOneTap: true,
446
+ filterByAuthorizedAccounts: true,
447
+ requestVerifiedPhoneNumber: true,
448
+ } satisfies GoogleAndroidLoginOptions;
449
+
450
+ const iosGoogleOptions = {
451
+ hostedDomain: "company.com",
452
+ openIDRealm: "https://example.com",
453
+ } satisfies GoogleIOSLoginOptions;
454
+
455
+ const microsoftOptions = {
456
+ tenant: "organizations",
457
+ prompt: "select_account",
458
+ } satisfies MicrosoftLoginOptions;
459
+ ```
460
+
461
+ Examples of mistakes that TypeScript rejects:
462
+
463
+ ```ts
464
+ await AuthService.login("apple", {
465
+ tenant: "organizations",
466
+ });
467
+
468
+ await AuthService.login("microsoft", {
469
+ nonce: "opaque-nonce",
470
+ });
471
+ ```
472
+
380
473
  ### AuthUser
381
474
 
382
475
  ```ts
@@ -389,6 +482,10 @@ type AuthUser = {
389
482
  accessToken?: string;
390
483
  refreshToken?: string;
391
484
  serverAuthCode?: string;
485
+ authorizationCode?: string;
486
+ userId?: string;
487
+ phoneNumber?: string;
488
+ hostedDomain?: string;
392
489
  scopes?: string[];
393
490
  expirationTime?: number;
394
491
  underlyingError?: string;
@@ -402,16 +499,17 @@ The example app is the fastest way to verify setup and read a complete integrati
402
499
  ```sh
403
500
  cp apps/example/.env.example apps/example/.env.local
404
501
  bun install
405
- bun example:prebuild:clean
406
- bun example:ios
407
- bun example:android
502
+ bun run example:prebuild:clean
503
+ bun run example:ios
504
+ bun run example:android
408
505
  ```
409
506
 
410
507
  The demo includes:
411
508
 
412
509
  - Provider cards for Google, Apple, and Microsoft.
413
510
  - Token and scope operations.
414
- - Silent restore and account picker actions.
511
+ - Silent restore, account picker, revoke access, and native logging actions.
512
+ - Platform-gated controls for each supported Google, Apple, and Microsoft option.
415
513
  - App-owned disk snapshot example with `react-native-nitro-storage`.
416
514
  - Runtime smoke tests for the public API.
417
515
 
@@ -439,10 +537,12 @@ The demo includes:
439
537
  ## Release Checks
440
538
 
441
539
  ```sh
442
- bun run publish-package:dry-run
540
+ bun run release:preflight
443
541
  ```
444
542
 
445
- The publish script runs frozen install, core-version verification, codegen, build, lint, typecheck, Jest, JS coverage, C++ tests, C++ coverage, Expo Doctor, package docs sync, pack dry run, and `bun publish --dry-run --ignore-scripts`.
543
+ The release preflight runs core-version verification, codegen, build, lint, typecheck, Jest, C++ tests, Expo dependency validation, Expo Doctor, Expo config introspection, package docs sync, pack dry run, and `bun publish --dry-run --ignore-scripts`.
544
+
545
+ CI runs the same preflight with registry publish dry-run disabled because GitHub pull-request jobs do not have npm publish credentials.
446
546
 
447
547
  For faster local iteration before the full release dry run:
448
548
 
@@ -96,13 +96,13 @@ dependencies {
96
96
  implementation "com.google.android.gms:play-services-auth:21.5.1"
97
97
 
98
98
  // Activity result APIs
99
- implementation "androidx.activity:activity-ktx:1.9.3"
99
+ implementation "androidx.activity:activity-ktx:1.13.0"
100
100
 
101
101
  // Custom Tabs (Microsoft OAuth in-app browser)
102
- implementation "androidx.browser:browser:1.8.0"
102
+ implementation "androidx.browser:browser:1.10.0"
103
103
 
104
104
  // Google Credential Manager (One-Tap / Passkeys)
105
- implementation "androidx.credentials:credentials:1.5.0"
106
- implementation "androidx.credentials:credentials-play-services-auth:1.5.0"
105
+ implementation "androidx.credentials:credentials:1.6.0"
106
+ implementation "androidx.credentials:credentials-play-services-auth:1.6.0"
107
107
  implementation "com.google.android.libraries.identity.googleid:googleid:1.2.0"
108
108
  }
@@ -1,4 +1,4 @@
1
1
  NitroAuth_ndkVersion=27.1.12297006
2
- NitroAuth_compileSdkVersion=35
3
- NitroAuth_targetSdkVersion=35
2
+ NitroAuth_compileSdkVersion=36
3
+ NitroAuth_targetSdkVersion=36
4
4
  NitroAuth_minSdkVersion=24
@@ -25,6 +25,7 @@ static jmethodID gRefreshMethod = nullptr;
25
25
  static jmethodID gRestoreMethod = nullptr;
26
26
  static jmethodID gHasPlayMethod = nullptr;
27
27
  static jmethodID gLogoutMethod = nullptr;
28
+ static jmethodID gRevokeAccessMethod = nullptr;
28
29
 
29
30
  // Call from JNI_OnUnload or dispose to prevent stale refs after a module reload.
30
31
  static void clearCachedJniRefs(JNIEnv* env) {
@@ -38,13 +39,14 @@ static void clearCachedJniRefs(JNIEnv* env) {
38
39
  gRestoreMethod = nullptr;
39
40
  gHasPlayMethod = nullptr;
40
41
  gLogoutMethod = nullptr;
42
+ gRevokeAccessMethod = nullptr;
41
43
  }
42
44
 
43
45
  static void ensureAuthAdapterMethods(JNIEnv* env) {
44
46
  if (gAuthAdapterClass != nullptr && gLoginMethod != nullptr
45
47
  && gRequestScopesMethod != nullptr && gRefreshMethod != nullptr
46
48
  && gRestoreMethod != nullptr && gHasPlayMethod != nullptr
47
- && gLogoutMethod != nullptr) {
49
+ && gLogoutMethod != nullptr && gRevokeAccessMethod != nullptr) {
48
50
  return;
49
51
  }
50
52
 
@@ -61,7 +63,7 @@ static void ensureAuthAdapterMethods(JNIEnv* env) {
61
63
  gLoginMethod = env->GetStaticMethodID(
62
64
  gAuthAdapterClass,
63
65
  "loginSync",
64
- "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;ZZZLjava/lang/String;Ljava/lang/String;)V"
66
+ "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZZZZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"
65
67
  );
66
68
  }
67
69
  if (gRequestScopesMethod == nullptr) {
@@ -99,6 +101,13 @@ static void ensureAuthAdapterMethods(JNIEnv* env) {
99
101
  "(Landroid/content/Context;)V"
100
102
  );
101
103
  }
104
+ if (gRevokeAccessMethod == nullptr) {
105
+ gRevokeAccessMethod = env->GetStaticMethodID(
106
+ gAuthAdapterClass,
107
+ "revokeAccessSync",
108
+ "(Landroid/content/Context;)V"
109
+ );
110
+ }
102
111
  }
103
112
 
104
113
  std::shared_ptr<Promise<AuthUser>> PlatformAuth::login(AuthProvider provider, const std::optional<LoginOptions>& options) {
@@ -127,16 +136,25 @@ std::shared_ptr<Promise<AuthUser>> PlatformAuth::login(AuthProvider provider, co
127
136
 
128
137
  std::vector<std::string> scopes = {"email", "profile"};
129
138
  std::optional<std::string> loginHint;
139
+ std::optional<std::string> nonce;
130
140
  std::optional<std::string> tenant;
131
141
  std::optional<std::string> prompt;
142
+ std::optional<std::string> hostedDomain;
143
+ std::optional<std::string> openIDRealm;
132
144
  bool useOneTap = false;
133
145
  bool forceAccountPicker = false;
134
146
  bool useLegacyGoogleSignIn = false;
147
+ bool filterByAuthorizedAccounts = false;
148
+ bool forceCodeForRefreshToken = false;
149
+ bool requestVerifiedPhoneNumber = false;
135
150
 
136
151
  if (options) {
137
152
  if (options->scopes) scopes = *options->scopes;
138
153
  loginHint = options->loginHint;
154
+ nonce = options->nonce;
139
155
  tenant = options->tenant;
156
+ hostedDomain = options->hostedDomain;
157
+ openIDRealm = options->openIDRealm;
140
158
  if (options->prompt.has_value()) {
141
159
  switch (options->prompt.value()) {
142
160
  case MicrosoftPrompt::LOGIN: prompt = "login"; break;
@@ -148,6 +166,9 @@ std::shared_ptr<Promise<AuthUser>> PlatformAuth::login(AuthProvider provider, co
148
166
  useOneTap = options->useOneTap.value_or(false);
149
167
  forceAccountPicker = options->forceAccountPicker.value_or(false);
150
168
  useLegacyGoogleSignIn = options->useLegacyGoogleSignIn.value_or(false);
169
+ filterByAuthorizedAccounts = options->filterByAuthorizedAccounts.value_or(false);
170
+ forceCodeForRefreshToken = options->forceCodeForRefreshToken.value_or(false);
171
+ requestVerifiedPhoneNumber = options->requestVerifiedPhoneNumber.value_or(false);
151
172
  }
152
173
 
153
174
  JNIEnv* env = Environment::current();
@@ -170,18 +191,30 @@ std::shared_ptr<Promise<AuthUser>> PlatformAuth::login(AuthProvider provider, co
170
191
 
171
192
  local_ref<JString> providerRef = make_jstring(providerStr);
172
193
  local_ref<JString> loginHintRef;
194
+ local_ref<JString> nonceRef;
173
195
  local_ref<JString> tenantRef;
174
196
  local_ref<JString> promptRef;
197
+ local_ref<JString> hostedDomainRef;
198
+ local_ref<JString> openIDRealmRef;
175
199
 
176
200
  if (loginHint.has_value()) {
177
201
  loginHintRef = make_jstring(loginHint.value());
178
202
  }
203
+ if (nonce.has_value()) {
204
+ nonceRef = make_jstring(nonce.value());
205
+ }
179
206
  if (tenant.has_value()) {
180
207
  tenantRef = make_jstring(tenant.value());
181
208
  }
182
209
  if (prompt.has_value()) {
183
210
  promptRef = make_jstring(prompt.value());
184
211
  }
212
+ if (hostedDomain.has_value()) {
213
+ hostedDomainRef = make_jstring(hostedDomain.value());
214
+ }
215
+ if (openIDRealm.has_value()) {
216
+ openIDRealmRef = make_jstring(openIDRealm.value());
217
+ }
185
218
 
186
219
  env->CallStaticVoidMethod(gAuthAdapterClass, gLoginMethod,
187
220
  contextPtr,
@@ -189,11 +222,17 @@ std::shared_ptr<Promise<AuthUser>> PlatformAuth::login(AuthProvider provider, co
189
222
  nullptr,
190
223
  jScopes,
191
224
  loginHintRef.get(),
225
+ nonceRef.get(),
192
226
  (jboolean)useOneTap,
193
227
  (jboolean)forceAccountPicker,
194
228
  (jboolean)useLegacyGoogleSignIn,
229
+ (jboolean)filterByAuthorizedAccounts,
230
+ (jboolean)forceCodeForRefreshToken,
231
+ (jboolean)requestVerifiedPhoneNumber,
195
232
  tenantRef.get(),
196
- promptRef.get());
233
+ promptRef.get(),
234
+ hostedDomainRef.get(),
235
+ openIDRealmRef.get());
197
236
 
198
237
  env->DeleteLocalRef(jScopes);
199
238
  env->DeleteLocalRef(stringClass);
@@ -396,13 +435,42 @@ void PlatformAuth::logout() {
396
435
  }
397
436
  }
398
437
 
438
+ std::shared_ptr<Promise<void>> PlatformAuth::revokeAccess() {
439
+ auto promise = Promise<void>::create();
440
+ auto contextPtr = static_cast<jobject>(AuthCache::getAndroidContext());
441
+ if (!contextPtr) {
442
+ promise->resolve();
443
+ return promise;
444
+ }
445
+
446
+ JNIEnv* env = Environment::current();
447
+ try {
448
+ ensureAuthAdapterMethods(env);
449
+ } catch (...) {
450
+ promise->reject(std::current_exception());
451
+ return promise;
452
+ }
453
+
454
+ env->CallStaticVoidMethod(gAuthAdapterClass, gRevokeAccessMethod, contextPtr);
455
+
456
+ if (env->ExceptionCheck()) {
457
+ env->ExceptionDescribe();
458
+ env->ExceptionClear();
459
+ promise->reject(std::make_exception_ptr(std::runtime_error("JNI call failed")));
460
+ return promise;
461
+ }
462
+
463
+ promise->resolve();
464
+ return promise;
465
+ }
466
+
399
467
  extern "C" JNIEXPORT void JNICALL Java_com_auth_AuthAdapter_nativeInitialize(JNIEnv*, jclass, jobject context) {
400
468
  AuthCache::setAndroidContext(context);
401
469
  }
402
470
 
403
471
  extern "C" JNIEXPORT void JNICALL Java_com_auth_AuthAdapter_nativeOnLoginSuccess(
404
472
  JNIEnv* env, jclass,
405
- jstring origin, jstring provider, jstring email, jstring name, jstring photo, jstring idToken, jstring accessToken, jstring serverAuthCode, jobjectArray scopes, jobject expirationTime) {
473
+ jstring origin, jstring provider, jstring email, jstring name, jstring photo, jstring idToken, jstring accessToken, jstring serverAuthCode, jstring userId, jstring phoneNumber, jstring hostedDomain, jobjectArray scopes, jobject expirationTime) {
406
474
 
407
475
  const char* originCStr = env->GetStringUTFChars(origin, nullptr);
408
476
  std::string originStr(originCStr);
@@ -467,6 +535,21 @@ extern "C" JNIEXPORT void JNICALL Java_com_auth_AuthAdapter_nativeOnLoginSuccess
467
535
  user.serverAuthCode = std::string(s);
468
536
  env->ReleaseStringUTFChars(serverAuthCode, s);
469
537
  }
538
+ if (userId) {
539
+ const char* s = env->GetStringUTFChars(userId, nullptr);
540
+ user.userId = std::string(s);
541
+ env->ReleaseStringUTFChars(userId, s);
542
+ }
543
+ if (phoneNumber) {
544
+ const char* s = env->GetStringUTFChars(phoneNumber, nullptr);
545
+ user.phoneNumber = std::string(s);
546
+ env->ReleaseStringUTFChars(phoneNumber, s);
547
+ }
548
+ if (hostedDomain) {
549
+ const char* s = env->GetStringUTFChars(hostedDomain, nullptr);
550
+ user.hostedDomain = std::string(s);
551
+ env->ReleaseStringUTFChars(hostedDomain, s);
552
+ }
470
553
  if (scopes) {
471
554
  int len = env->GetArrayLength(scopes);
472
555
  std::vector<std::string> scopeVec;