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.
- package/CHANGELOG.md +42 -0
- package/README.md +132 -32
- package/android/build.gradle +4 -4
- package/android/gradle.properties +2 -2
- package/android/src/main/cpp/PlatformAuth+Android.cpp +87 -4
- package/android/src/main/java/com/auth/AuthAdapter.kt +85 -48
- package/android/src/main/java/com/auth/GoogleSignInActivity.kt +12 -2
- package/cpp/HybridAuth.cpp +168 -18
- package/cpp/HybridAuth.hpp +7 -0
- package/cpp/PlatformAuth.hpp +1 -0
- package/ios/AuthAdapter.swift +101 -24
- package/ios/PlatformAuth+iOS.mm +37 -1
- package/lib/commonjs/Auth.web.js +74 -21
- package/lib/commonjs/Auth.web.js.map +1 -1
- package/lib/commonjs/create-auth-service.js +10 -0
- package/lib/commonjs/create-auth-service.js.map +1 -1
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +12 -0
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/provider-options.js +6 -0
- package/lib/commonjs/provider-options.js.map +1 -0
- package/lib/commonjs/service.js.map +1 -1
- package/lib/commonjs/service.web.js.map +1 -1
- package/lib/commonjs/use-auth.js +21 -1
- package/lib/commonjs/use-auth.js.map +1 -1
- package/lib/module/Auth.web.js +74 -21
- package/lib/module/Auth.web.js.map +1 -1
- package/lib/module/create-auth-service.js +10 -0
- package/lib/module/create-auth-service.js.map +1 -1
- package/lib/module/global.d.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/provider-options.js +4 -0
- package/lib/module/provider-options.js.map +1 -0
- package/lib/module/service.js.map +1 -1
- package/lib/module/service.web.js.map +1 -1
- package/lib/module/use-auth.js +21 -1
- package/lib/module/use-auth.js.map +1 -1
- package/lib/typescript/commonjs/Auth.nitro.d.ts +11 -0
- package/lib/typescript/commonjs/Auth.nitro.d.ts.map +1 -1
- package/lib/typescript/commonjs/Auth.web.d.ts +4 -0
- package/lib/typescript/commonjs/Auth.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/create-auth-service.d.ts +2 -1
- package/lib/typescript/commonjs/create-auth-service.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +1 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/provider-options.d.ts +23 -0
- package/lib/typescript/commonjs/provider-options.d.ts.map +1 -0
- package/lib/typescript/commonjs/service.d.ts +2 -2
- package/lib/typescript/commonjs/service.d.ts.map +1 -1
- package/lib/typescript/commonjs/service.web.d.ts +2 -2
- package/lib/typescript/commonjs/service.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/use-auth.d.ts +4 -2
- package/lib/typescript/commonjs/use-auth.d.ts.map +1 -1
- package/lib/typescript/module/Auth.nitro.d.ts +11 -0
- package/lib/typescript/module/Auth.nitro.d.ts.map +1 -1
- package/lib/typescript/module/Auth.web.d.ts +4 -0
- package/lib/typescript/module/Auth.web.d.ts.map +1 -1
- package/lib/typescript/module/create-auth-service.d.ts +2 -1
- package/lib/typescript/module/create-auth-service.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +1 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/provider-options.d.ts +23 -0
- package/lib/typescript/module/provider-options.d.ts.map +1 -0
- package/lib/typescript/module/service.d.ts +2 -2
- package/lib/typescript/module/service.d.ts.map +1 -1
- package/lib/typescript/module/service.web.d.ts +2 -2
- package/lib/typescript/module/service.web.d.ts.map +1 -1
- package/lib/typescript/module/use-auth.d.ts +4 -2
- package/lib/typescript/module/use-auth.d.ts.map +1 -1
- package/nitrogen/generated/shared/c++/AuthUser.hpp +17 -1
- package/nitrogen/generated/shared/c++/HybridAuthSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridAuthSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/LoginOptions.hpp +25 -1
- package/package.json +7 -7
- package/react-native-nitro-auth.podspec +1 -1
- package/src/Auth.nitro.ts +11 -0
- package/src/Auth.web.ts +99 -16
- package/src/create-auth-service.ts +19 -9
- package/src/global.d.ts +2 -1
- package/src/index.ts +1 -0
- package/src/index.web.ts +1 -0
- package/src/provider-options.ts +62 -0
- package/src/service.ts +2 -1
- package/src/service.web.ts +2 -2
- 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
|
-

|
|
5
|
-

|
|
6
|
-

|
|
3
|
+
[](https://www.npmjs.com/package/react-native-nitro-auth)
|
|
4
|
+
[](https://github.com/JoaoPauloCMarra/react-native-nitro-auth/blob/main/LICENSE)
|
|
5
|
+
[](https://reactnative.dev/)
|
|
6
|
+
[](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
|
|
53
|
-
|
|
|
54
|
-
| React Native
|
|
55
|
-
| Nitro Modules
|
|
56
|
-
| iOS
|
|
57
|
-
| Android
|
|
58
|
-
|
|
|
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 {
|
|
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
|
|
249
|
-
|
|
|
250
|
-
| `scopes`
|
|
251
|
-
| `loginHint`
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
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
|
|
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
|
|
540
|
+
bun run release:preflight
|
|
443
541
|
```
|
|
444
542
|
|
|
445
|
-
The
|
|
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
|
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
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.
|
|
102
|
+
implementation "androidx.browser:browser:1.10.0"
|
|
103
103
|
|
|
104
104
|
// Google Credential Manager (One-Tap / Passkeys)
|
|
105
|
-
implementation "androidx.credentials:credentials:1.
|
|
106
|
-
implementation "androidx.credentials:credentials-play-services-auth:1.
|
|
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
|
}
|
|
@@ -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;
|
|
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;
|