react-native-oauth-essentials 1.0.11 → 1.1.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 (51) hide show
  1. package/README.md +384 -362
  2. package/android/src/main/java/com/oauthessentials/CredentialError.kt +4 -1
  3. package/android/src/main/java/com/oauthessentials/CredentialFactory.kt +24 -2
  4. package/android/src/main/java/com/oauthessentials/CustomTabsActivity.kt +14 -1
  5. package/android/src/main/java/com/oauthessentials/OauthEssentialsModule.kt +448 -192
  6. package/app.plugin.js +1 -0
  7. package/ios/AppleIdRetriever.swift +25 -26
  8. package/ios/CredentialError.swift +3 -0
  9. package/ios/CredentialFactory.swift +38 -20
  10. package/ios/CredentialsType.swift +1 -0
  11. package/ios/GoogleIdRetriever.swift +132 -56
  12. package/ios/HybridRetriever.swift +12 -18
  13. package/ios/OauthEssentials.h +0 -3
  14. package/ios/OauthEssentials.mm +45 -2
  15. package/ios/OauthEssentialsModule.swift +266 -57
  16. package/ios/PasskeyRetriever.swift +31 -49
  17. package/ios/PasswordRetriever.swift +10 -30
  18. package/ios/RCTPromiseSettler.swift +125 -0
  19. package/jest/index.js +149 -0
  20. package/lib/module/NativeOauthEssentials.js +10 -1
  21. package/lib/module/NativeOauthEssentials.js.map +1 -1
  22. package/lib/module/errors.js +38 -0
  23. package/lib/module/errors.js.map +1 -0
  24. package/lib/module/index.js +432 -58
  25. package/lib/module/index.js.map +1 -1
  26. package/lib/module/oauth.js +97 -0
  27. package/lib/module/oauth.js.map +1 -0
  28. package/lib/module/platform.js +108 -0
  29. package/lib/module/platform.js.map +1 -0
  30. package/lib/module/types.js +46 -1
  31. package/lib/module/types.js.map +1 -1
  32. package/lib/typescript/src/NativeOauthEssentials.d.ts +70 -16
  33. package/lib/typescript/src/NativeOauthEssentials.d.ts.map +1 -1
  34. package/lib/typescript/src/errors.d.ts +18 -0
  35. package/lib/typescript/src/errors.d.ts.map +1 -0
  36. package/lib/typescript/src/index.d.ts +235 -40
  37. package/lib/typescript/src/index.d.ts.map +1 -1
  38. package/lib/typescript/src/oauth.d.ts +32 -0
  39. package/lib/typescript/src/oauth.d.ts.map +1 -0
  40. package/lib/typescript/src/platform.d.ts +39 -0
  41. package/lib/typescript/src/platform.d.ts.map +1 -0
  42. package/lib/typescript/src/types.d.ts +190 -3
  43. package/lib/typescript/src/types.d.ts.map +1 -1
  44. package/package.json +8 -4
  45. package/plugin/withOauthEssentials.js +291 -0
  46. package/src/NativeOauthEssentials.ts +91 -17
  47. package/src/errors.ts +49 -0
  48. package/src/index.tsx +587 -80
  49. package/src/oauth.ts +140 -0
  50. package/src/platform.ts +121 -0
  51. package/src/types.ts +200 -2
@@ -2,63 +2,165 @@
2
2
 
3
3
  import OauthEssentials from "./NativeOauthEssentials.js";
4
4
  import { Platform } from 'react-native';
5
- import { CredentialsType } from "./types.js";
5
+ import { CredentialError, CredentialsType } from "./types.js";
6
+ import { buildAuthorizationUrl, buildTokenRequestBody, getUrlScheme, parseRedirectParams } from "./oauth.js";
7
+ import { createCredentialError } from "./errors.js";
8
+ import { resolveGoogleClientId, splitGoogleArgs, warnIgnored, warnOnce } from "./platform.js";
6
9
  export * from "./types.js";
10
+ export { isCredentialError } from "./errors.js";
7
11
  const APPLE_ID_CACHED_RESULTS = new Map();
8
12
 
9
13
  /**
10
- * Performs the google sign in.
11
- * @param webClientId
12
- * @param options
14
+ * Shows the Google sign in UI and resolves with the signed in account.
13
15
  *
14
- * You should rely on GOOGLE_ID_SUPPORTED constant to check if you can use this method.
15
- * [Available on Android and IOS].
16
+ * iOS: configures GoogleSignIn with the iOS client id (+ `serverClientId`, `hostedDomain`) and
17
+ * presents it from the top most view controller, passing `hint`, `scopes` and `nonce`. If the app is
18
+ * not active it waits up to 2 seconds for it to become active. The client id falls back to
19
+ * `GIDClientID` and `serverClientId` to `webClientId`, then to `GIDServerClientID` (Info.plist).
20
+ * Android: shows the Credential Manager bottom sheet (`mode: 'bottomSheet'`, falls back to the
21
+ * "Sign in with Google" flow when there is no credential and `authorizedAccounts` is not set) or
22
+ * the "Sign in with Google" flow (`mode: 'button'`). When `scopes` or `offlineAccess` are set it
23
+ * then asks for authorization, which may show a consent screen.
24
+ *
25
+ * Resolves `GOOGLE_ID`, or `CANCELLED` when the user dismisses the UI (or declines the consent
26
+ * screen on Android).
27
+ * Rejects with `CONFIGURATION_ERROR` (no client id; iOS: the reversed client id URL scheme is not in
28
+ * Info.plist, the message has the exact scheme), `NOT_SUPPORTED_ERROR` (Android, no Play Services),
29
+ * `NO_ACTIVITY_ERROR`,
30
+ * `NO_SIGN_IN_AVAILABLE` (Android), `BROWSER_UNAVAILABLE` (iOS: app not active, its window not in
31
+ * the foreground, Guided Access or Safari could not be opened), `SIMULTANEOUS_CALL_ERROR` (iOS: a Google sign in is pending) or
32
+ * `INVALID_RESULT_ERROR`.
33
+ * Emits `onCredentialSuccess` / `onCredentialFailure`.
34
+ *
35
+ * @param clientId - `{ iosClientId, webClientId }` (see {@link GoogleClientIds}), or one client id
36
+ * string used as is (the iOS client id on iOS, the web client id on Android). Optional: without it
37
+ * the ids are read from the app config (`googleSignIn()` or `googleSignIn(options)`), see
38
+ * {@link GoogleClientIds}.
39
+ * @param options - See {@link GoogleSignInOptions}.
40
+ */
41
+
42
+ export async function googleSignIn(clientIdOrOptions, maybeOptions) {
43
+ const {
44
+ clientId,
45
+ options
46
+ } = splitGoogleArgs(clientIdOrOptions, maybeOptions);
47
+ warnIgnored('googleSignIn', Platform.OS, options, Platform.OS === 'ios' ? GOOGLE_IOS_IGNORED : ['hint']);
48
+ const resolved = resolveGoogleClientId(Platform.OS, clientId, {
49
+ ...options
50
+ });
51
+ return await OauthEssentials.googleSignIn(resolved.clientId, parseGoogleIdOptions(resolved.options));
52
+ }
53
+ const GOOGLE_IOS_IGNORED = ['authorizedAccounts', 'autoSelectEnabled', 'mode', 'offlineAccess'];
54
+
55
+ /**
56
+ * Restores a previous Google sign in.
57
+ *
58
+ * iOS: calls GoogleSignIn `restorePreviousSignIn`, which never shows UI and refreshes the tokens.
59
+ * `hint`, `scopes`, `nonce` and `offlineAccess` are ignored and `serverAuthCode` is always null.
60
+ * Android: shows the Credential Manager bottom sheet filtered to accounts that already signed in to
61
+ * the app with auto select on, so it signs in without UI when there is a single one. `mode` and
62
+ * `hint` are ignored. When `scopes`/`offlineAccess` are set, authorization is only requested without UI:
63
+ * if consent is needed the result has `accessToken: null`.
64
+ *
65
+ * Resolves `GOOGLE_ID`, or `CANCELLED` when the user dismisses the Android sheet.
66
+ * Rejects with `NO_SIGN_IN_AVAILABLE` when there is nothing to restore, plus the same errors as
67
+ * {@link googleSignIn} (it shares the iOS simultaneous call lock with it). Takes the same
68
+ * `clientId` as {@link googleSignIn} (also optional).
69
+ * Emits `onCredentialSuccess` / `onCredentialFailure`.
70
+ */
71
+
72
+ export async function googleSilentSignIn(clientIdOrOptions, maybeOptions) {
73
+ const {
74
+ clientId,
75
+ options
76
+ } = splitGoogleArgs(clientIdOrOptions, maybeOptions);
77
+ warnIgnored('googleSilentSignIn', Platform.OS, options, Platform.OS === 'ios' ? [...GOOGLE_IOS_IGNORED, 'hint', 'scopes', 'nonce'] : ['hint', 'mode']);
78
+ const resolved = resolveGoogleClientId(Platform.OS, clientId, {
79
+ ...options
80
+ });
81
+ return await OauthEssentials.googleSilentSignIn(resolved.clientId, parseGoogleIdOptions(resolved.options));
82
+ }
83
+
84
+ /**
85
+ * Clears the stored sign in state.
86
+ *
87
+ * iOS: calls GoogleSignIn `signOut` (removes the Google session from the keychain, so
88
+ * {@link googleSilentSignIn} rejects afterwards). It does not affect Apple ID or passwords.
89
+ * Android: calls Credential Manager `clearCredentialState`, which turns off auto select for every
90
+ * provider until the user picks an account again.
91
+ *
92
+ * Resolves `true`. Rejects with `INVALID_RESULT_ERROR` (Android only) when clearing fails.
93
+ * Does not emit events.
16
94
  */
17
- export async function googleSignIn(webClientId, options) {
18
- return await OauthEssentials.googleSignIn(webClientId, parseGoogleIdOptions(options));
95
+ export async function signOut() {
96
+ return await OauthEssentials.signOut();
19
97
  }
20
98
 
21
99
  /**
22
- * Gets the stored password.
23
- * If does not have an stored password, returns false.
100
+ * Shows the saved passwords of the app and resolves with the one the user picks.
101
+ *
102
+ * iOS: `ASAuthorizationPasswordProvider` request (iOS 16+ only offers credentials already saved on
103
+ * the device). Resolves `PASSWORD`, or the `CANCELLED` result when the user dismisses it or there
104
+ * is no saved password. Rejects with `INVALID_RESULT_ERROR` on other errors and
105
+ * `SIMULTANEOUS_CALL_ERROR` while a previous call is pending.
106
+ * Android: Credential Manager `GetPasswordOption`. Resolves `PASSWORD`, or `CANCELLED` when the user
107
+ * dismisses it or there is no saved password. Rejects with `NOT_SUPPORTED_ERROR` without Play
108
+ * Services, `NO_ACTIVITY_ERROR` and `INVALID_RESULT_ERROR` on other errors.
24
109
  *
25
- * You should rely on PASSWORD_SUPPORTED constant to check if you can use this method.
26
- * [Available on Android and IOS].
110
+ * Emits `onCredentialSuccess` / `onCredentialFailure`.
27
111
  */
28
112
  export async function getPassword() {
29
- const result = await OauthEssentials.getPassword();
30
- return result || false;
113
+ return await OauthEssentials.getPassword();
31
114
  }
32
115
 
33
116
  /**
34
- * Performs the password sign in.
35
- * Cannot be a already stored password.
36
- * @param {string} username
37
- * @param {string} password
117
+ * Saves a username and password in the platform password manager. It does not authenticate the
118
+ * user against anything.
119
+ *
120
+ * iOS: does nothing and resolves `false` (iOS has no API to save a password without an associated
121
+ * domain; use the `textContentType` props of your inputs so iOS offers to save it).
122
+ * Android: Credential Manager `createCredential(CreatePasswordRequest)`, which shows the save
123
+ * prompt. Resolves `true` when saved, `false` on any error (including the user declining).
124
+ * Rejects with `NOT_SUPPORTED_ERROR` without Play Services and `NO_ACTIVITY_ERROR`.
38
125
  *
39
- * You should rely on PASSWORD_SUPPORTED constant to check if you can use this method.
40
- * [Available on Android and IOS].
126
+ * Does not emit events, except `onCredentialFailure` for the Android rejections.
41
127
  */
42
128
  export async function passwordSignIn(username, password) {
129
+ if (Platform.OS === 'ios') {
130
+ warnOnce('passwordSignIn', 'ios', 'does nothing on iOS: set textContentType on your inputs so iOS offers to save the password.');
131
+ }
43
132
  return await OauthEssentials.passwordSignIn(username, password);
44
133
  }
45
134
 
46
135
  /**
47
- * Initiates the Apple Sign-In process.
48
- * On IOS devices it handles it smoothly using the latest UI workflow.
49
- * On Android it dispatches the androidWebUrl to device default browser for handling it.
50
- * you need to implement on your backend the redirect logic and validation accordingly to the link below
51
- * @see [Apple Sign In REST API Documentation](https://developer.apple.com/documentation/signinwithapplerestapi)
136
+ * Signs in with Apple.
137
+ *
138
+ * iOS: native Sign in with Apple sheet requesting `fullName` and `email`, with `options.nonce` and
139
+ * `options.state`. Resolves `APPLE_ID`, or `CANCELLED` when the user dismisses it. Rejects with
140
+ * `INVALID_RESULT_ERROR` on other errors and `SIMULTANEOUS_CALL_ERROR` while a previous call is
141
+ * pending. Apple only sends `email`/`fullName` on the first authorization: this function keeps the
142
+ * first result of each `user` in memory (until the app is killed) and fills empty `email`/`fullName`
143
+ * with it.
144
+ * Android: opens `androidWebUrl` in a Custom Tab; `options` is ignored (put the nonce in your url).
145
+ * Your backend must run the Apple web flow and redirect to `<applicationId>://oauth/callback`.
146
+ * Resolves `WEB_APPLE_ID` with the redirect url, or `CANCELLED` when the user closes the tab or
147
+ * another browser session (`appleSignIn`/`oauthSignIn`) starts. Rejects with `INVALID_RESULT_ERROR`
148
+ * (invalid url), `NO_ACTIVITY_ERROR` or `BROWSER_UNAVAILABLE` (no browser installed).
52
149
  *
53
- * @param {string} androidWebUrl - The web URL on Android where the user will complete the OAuth flow. **[Android only]**
150
+ * Emits `onCredentialSuccess` / `onCredentialFailure`.
151
+ * @see [Sign in with Apple REST API](https://developer.apple.com/documentation/signinwithapplerestapi)
54
152
  *
55
- * @returns {AppleIdCredentialResult|WebAppleIdCredentialResult} Returns AppleIdCredentialResult on IOS devices and WebAppleIdCredentialResult on android.
153
+ * @param androidWebUrl - Web url that starts the Apple flow. Required on Android, ignored on iOS.
154
+ * @param options - See {@link AppleSignInOptions}. iOS only.
56
155
  */
57
- export async function appleSignIn(androidWebUrl) {
156
+ export async function appleSignIn(androidWebUrl, options) {
157
+ if (Platform.OS !== 'ios') {
158
+ warnIgnored('appleSignIn', Platform.OS, options, ['nonce', 'state']);
159
+ }
58
160
  const result = await OauthEssentials.appleSignIn(Platform.select({
59
- ios: undefined,
60
- android: androidWebUrl
61
- }));
161
+ ios: null,
162
+ default: androidWebUrl ?? null
163
+ }), options ?? {});
62
164
  if (result.type === CredentialsType.APPLE_ID) {
63
165
  if (APPLE_ID_CACHED_RESULTS.has(result.data.user)) {
64
166
  // Reuse the fullName and email provided
@@ -73,41 +175,305 @@ export async function appleSignIn(androidWebUrl) {
73
175
  } else {
74
176
  APPLE_ID_CACHED_RESULTS.set(result.data.user, result.data);
75
177
  }
76
- return result;
77
- } else {
78
- return result;
79
178
  }
179
+ return result;
180
+ }
181
+
182
+ /**
183
+ * Asks Apple whether the user is still signed in to the app with Apple ID, without UI
184
+ * (`ASAuthorizationAppleIDProvider.getCredentialState`).
185
+ * Call it on app start and sign the user out when it is not `AUTHORIZED`.
186
+ *
187
+ * Resolves `AUTHORIZED`, `REVOKED`, `TRANSFERRED` or `NOT_FOUND`. Rejects with
188
+ * `INVALID_RESULT_ERROR` when the check fails, and always with `NOT_SUPPORTED_ERROR` on Android.
189
+ * Does not emit events.
190
+ *
191
+ * @param userId - The `user` field of the AppleIdCredentialResult.
192
+ */
193
+ export async function getAppleIdCredentialState(userId) {
194
+ return await OauthEssentials.getAppleIdCredentialState(userId);
80
195
  }
81
196
 
82
197
  /**
83
- * Performs all sign in methods available on the platform at once.
84
- * This is supposed to be used on app start to get any existing sign in.
198
+ * Shows a single picker with the credentials the user already has, meant for app start.
199
+ *
200
+ * iOS: Apple ID + saved passwords (`clientId` is ignored, Google is not included; only
201
+ * `options.nonce` is used, for Apple ID). On iOS 16+ only credentials already on the device are
202
+ * offered. Resolves `APPLE_ID` or `PASSWORD`, or `CANCELLED` when the user dismisses it or nothing
203
+ * is available. Rejects with `INVALID_RESULT_ERROR` or `SIMULTANEOUS_CALL_ERROR`.
204
+ * Android: Credential Manager with Google ID (bottom sheet option with the web client id,
205
+ * `authorizedAccounts`, `autoSelectEnabled` and `nonce`) + saved passwords. Apple is not included
206
+ * and `mode`, `hint`, `scopes`, `offlineAccess`, `hostedDomain` and `serverClientId` are ignored.
207
+ * Resolves `GOOGLE_ID` or `PASSWORD`, or `CANCELLED`. Rejects with `CONFIGURATION_ERROR` (no web
208
+ * client id), `NOT_SUPPORTED_ERROR` (no Play Services), `NO_ACTIVITY_ERROR`,
209
+ * `NO_SIGN_IN_AVAILABLE` or `INVALID_RESULT_ERROR`.
210
+ *
211
+ * Ignored options produce a warning in development.
212
+ * `clientId` is optional like in {@link googleSignIn}: without it the web client id is read from
213
+ * the app config.
214
+ *
215
+ * Emits `onCredentialSuccess` / `onCredentialFailure`.
85
216
  */
86
- export async function hybridSignIn(googleClientId, options) {
87
- return await OauthEssentials.hybridSignIn(googleClientId, parseGoogleIdOptions(options));
217
+
218
+ export async function hybridSignIn(clientIdOrOptions, maybeOptions) {
219
+ const {
220
+ clientId,
221
+ options
222
+ } = splitGoogleArgs(clientIdOrOptions, maybeOptions);
223
+ if (Platform.OS === 'ios') {
224
+ if (clientId) {
225
+ warnOnce('hybridSignIn', 'clientId', 'the Google client id is ignored on iOS (Google is not offered there, only Apple ID and passwords).');
226
+ }
227
+ warnIgnored('hybridSignIn', 'ios', options, [...GOOGLE_IOS_IGNORED, 'hint', 'scopes', 'hostedDomain', 'serverClientId']);
228
+ } else {
229
+ warnIgnored('hybridSignIn', Platform.OS, options, ['hint', 'mode', 'scopes', 'offlineAccess', 'hostedDomain', 'serverClientId']);
230
+ }
231
+ const resolved = resolveGoogleClientId(Platform.OS, clientId, {
232
+ ...options
233
+ });
234
+ return await OauthEssentials.hybridSignIn(resolved.clientId, parseGoogleIdOptions(resolved.options));
88
235
  }
89
236
 
237
+ /** Result of {@link hybridSignIn}: Apple ID only on iOS, Google ID only on Android. */
238
+
90
239
  /**
91
- * Creates a passkey.
92
- * @param options
240
+ * Creates a passkey from a WebAuthn `PublicKeyCredentialCreationOptions` JSON (`requestJson`).
241
+ *
242
+ * iOS 16+: platform passkey registration. Reads `challenge`, `rp.id`, `user.id`, `user.name`,
243
+ * `authenticatorSelection.userVerification`, `attestation` and, on iOS 17.4+,
244
+ * `excludeCredentials`; other fields are ignored. `data` is a JSON string with `id`, `rawId`,
245
+ * `type` and `response.clientDataJSON`/`attestationObject` (base64url). Rejects with
246
+ * `NOT_SUPPORTED_ERROR` below iOS 16 and `SIMULTANEOUS_CALL_ERROR` while a passkey call is pending.
247
+ * Android 9+: Credential Manager `CreatePublicKeyCredentialRequest` with the whole JSON and
248
+ * `preferImmediatelyAvailableCredentials`. `data` is the registration response JSON returned by
249
+ * Credential Manager. Rejects with `NOT_SUPPORTED_ERROR` below Android 9 and `NO_ACTIVITY_ERROR`.
250
+ *
251
+ * Resolves `PASSKEY`, or `CANCELLED` when the user dismisses it. Rejects with
252
+ * `INVALID_RESULT_ERROR` for an invalid/missing `requestJson` and other errors.
253
+ * Emits `onCredentialSuccess` / `onCredentialFailure`. Send `data` to your server to verify it.
93
254
  */
94
255
  export async function createPassKey(options) {
256
+ warnPasskeyOptions('createPassKey', options);
95
257
  return await OauthEssentials.createPassKey(options);
96
258
  }
259
+
260
+ /**
261
+ * Signs in with a passkey from a WebAuthn `PublicKeyCredentialRequestOptions` JSON (`requestJson`).
262
+ *
263
+ * iOS 16+: platform passkey assertion. Reads `challenge`, `rpId`, `allowCredentials` and
264
+ * `userVerification`. With `mediation: 'autofill'` it does not show a sheet: it waits until the user
265
+ * picks a passkey in the QuickType bar of a `textContentType="username"` field, and any other
266
+ * passkey call (or {@link cancelPassKeyAutoFill}) resolves it as `CANCELLED`. Otherwise it shows a
267
+ * sheet that only offers passkeys available on the device (no "other device" QR option), so it
268
+ * resolves `CANCELLED` when there is none. `data` is a JSON string with `id`, `rawId`, `type` and
269
+ * `response.clientDataJSON`/`authenticatorData`/`signature`/`userHandle` (base64url).
270
+ * Rejects with `NOT_SUPPORTED_ERROR` below iOS 16 and `SIMULTANEOUS_CALL_ERROR` while a modal
271
+ * passkey call is pending.
272
+ * Android 9+: Credential Manager `GetPublicKeyCredentialOption` with the whole JSON and
273
+ * `preferImmediatelyAvailableCredentials`; `mediation` is ignored. `data` is the authentication
274
+ * response JSON returned by Credential Manager. Rejects with `NOT_SUPPORTED_ERROR` below Android 9,
275
+ * `NO_ACTIVITY_ERROR` and `NO_SIGN_IN_AVAILABLE` (no passkey).
276
+ *
277
+ * Resolves `PASSKEY`, or `CANCELLED` when the user dismisses it. Rejects with
278
+ * `INVALID_RESULT_ERROR` for an invalid/missing `requestJson` and other errors.
279
+ * Emits `onCredentialSuccess` / `onCredentialFailure`. Send `data` to your server to verify it.
280
+ */
281
+ export async function getPassKey(options) {
282
+ warnPasskeyOptions('getPassKey', options);
283
+ return await OauthEssentials.getPassKey(options);
284
+ }
285
+ function warnPasskeyOptions(method, options) {
286
+ if (Platform.OS === 'ios') {
287
+ if (options?.preferImmediatelyAvailableCredentials === false) {
288
+ warnOnce(method, 'preferImmediatelyAvailableCredentials', '"preferImmediatelyAvailableCredentials: false" is ignored on iOS (modal requests only offer passkeys on the device).');
289
+ }
290
+ } else if (options?.mediation === 'autofill') {
291
+ warnOnce(method, 'mediation', '"mediation: \'autofill\'" is ignored on Android.');
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Cancels a pending `getPassKey({ mediation: 'autofill' })` request, for example when the sign in
297
+ * screen unmounts. The cancelled `getPassKey` resolves `CANCELLED` (and emits it).
298
+ *
299
+ * Resolves `true` when a pending AutoFill request was cancelled, `false` when there was none.
300
+ * Always resolves `false` on Android and below iOS 16.
301
+ */
302
+ export async function cancelPassKeyAutoFill() {
303
+ return await OauthEssentials.cancelPassKeyAutoFill();
304
+ }
305
+
306
+ /**
307
+ * Signs in with any OAuth 2.0 / OpenID Connect provider using the authorization code flow.
308
+ *
309
+ * 1. Generates a random `state` and a PKCE S256 verifier/challenge on the native side.
310
+ * 2. Builds `authorizationEndpoint?response_type=code&client_id&redirect_uri&state[&scope]
311
+ * [&code_challenge&code_challenge_method=S256]` + `additionalParameters` (which may override
312
+ * `scope`; the other parameters above are reserved and ignored there, with a dev warning).
313
+ * 3. Opens it in `ASWebAuthenticationSession` (iOS, `prefersEphemeralSession`, waits up to 2 seconds
314
+ * for the app to be active) or a Custom Tab (Android) and waits for the redirect to `redirectUri`.
315
+ * On Android the redirect must reach `CustomTabsActivity`: use `OAUTH_REDIRECT_URI` or add an
316
+ * intent filter for your uri.
317
+ * 4. Checks that the returned `state` matches, then reads `code` (query or fragment).
318
+ * 5. When `tokenEndpoint` is set, POSTs `grant_type=authorization_code`, `code`, `client_id`,
319
+ * `redirect_uri` and `code_verifier` as a form and returns the JSON response in `tokens`
320
+ * (no client secret is sent, the id_token is not validated).
321
+ *
322
+ * Resolves `OAUTH`, or `CANCELLED` when the user closes the browser, the provider returns
323
+ * `error=access_denied` or (Android) another browser session starts.
324
+ * Rejects with `INVALID_RESULT_ERROR` (state mismatch, provider error, no code, token endpoint
325
+ * returned non 2xx or non JSON), `NETWORK_ERROR` (token request failed), `CONFIGURATION_ERROR`
326
+ * (invalid `redirectUri`), `BROWSER_UNAVAILABLE` (iOS: Guided Access, app not active or its window
327
+ * not in the foreground; Android: no browser), `NO_ACTIVITY_ERROR` or `SIMULTANEOUS_CALL_ERROR` (iOS).
328
+ * Does not emit events.
329
+ */
330
+ export async function oauthSignIn(options) {
331
+ if (Platform.OS !== 'ios') {
332
+ warnIgnored('oauthSignIn', Platform.OS, options, ['prefersEphemeralSession']);
333
+ }
334
+ const redirectUri = options.redirectUri ?? OAUTH_REDIRECT_URI;
335
+ const usePKCE = options.usePKCE !== false;
336
+ const pkce = await OauthEssentials.generatePkce();
337
+ const url = buildAuthorizationUrl({
338
+ authorizationEndpoint: options.authorizationEndpoint,
339
+ clientId: options.clientId,
340
+ redirectUri,
341
+ scopes: options.scopes,
342
+ additionalParameters: options.additionalParameters,
343
+ state: pkce.state,
344
+ codeChallenge: usePKCE ? pkce.codeChallenge : undefined
345
+ });
346
+ const session = await OauthEssentials.openAuthSession(url, {
347
+ callbackScheme: getUrlScheme(redirectUri),
348
+ prefersEphemeralSession: options.prefersEphemeralSession === true
349
+ });
350
+ if (session.type === CredentialsType.CANCELLED || !session.data) {
351
+ return {
352
+ type: CredentialsType.CANCELLED,
353
+ data: null
354
+ };
355
+ }
356
+ const params = parseRedirectParams(session.data.url);
357
+ if (params.state !== pkce.state) {
358
+ throw oauthError('State mismatch in authorization response');
359
+ }
360
+ if (params.error) {
361
+ if (params.error === 'access_denied') {
362
+ return {
363
+ type: CredentialsType.CANCELLED,
364
+ data: null
365
+ };
366
+ }
367
+ throw oauthError(params.error_description ?? params.error);
368
+ }
369
+ if (!params.code) {
370
+ throw oauthError('Authorization response has no code');
371
+ }
372
+ const codeVerifier = usePKCE ? pkce.codeVerifier : null;
373
+ let tokens = null;
374
+ if (options.tokenEndpoint) {
375
+ let response;
376
+ try {
377
+ response = await fetch(options.tokenEndpoint, {
378
+ method: 'POST',
379
+ headers: {
380
+ 'Content-Type': 'application/x-www-form-urlencoded',
381
+ 'Accept': 'application/json'
382
+ },
383
+ body: buildTokenRequestBody({
384
+ code: params.code,
385
+ clientId: options.clientId,
386
+ redirectUri,
387
+ codeVerifier
388
+ })
389
+ });
390
+ } catch (e) {
391
+ throw createCredentialError(CredentialError.NETWORK_ERROR, `Token request failed: ${e instanceof Error ? e.message : String(e)}`, e);
392
+ }
393
+ try {
394
+ tokens = await response.json();
395
+ } catch (e) {
396
+ throw createCredentialError(CredentialError.INVALID_RESULT_ERROR, `Token endpoint returned a non JSON response (status ${response.status})`, e);
397
+ }
398
+ if (!response.ok) {
399
+ throw oauthError(String(tokens.error_description ?? tokens.error ?? response.status));
400
+ }
401
+ }
402
+ return {
403
+ type: CredentialsType.OAUTH,
404
+ data: {
405
+ code: params.code,
406
+ state: params.state,
407
+ redirectUri,
408
+ codeVerifier,
409
+ params,
410
+ tokens
411
+ }
412
+ };
413
+ }
414
+ function oauthError(message) {
415
+ return createCredentialError(CredentialError.INVALID_RESULT_ERROR, message);
416
+ }
417
+
418
+ /**
419
+ * Called with the same `{ type, data }` the promise resolves with (including `CANCELLED`), for
420
+ * `googleSignIn`, `googleSilentSignIn`, `getPassword`, `appleSignIn`, `hybridSignIn`,
421
+ * `createPassKey` and `getPassKey`. Not called by `signOut`, `passwordSignIn`,
422
+ * `getAppleIdCredentialState`, `cancelPassKeyAutoFill` and `oauthSignIn`.
423
+ */
424
+ export function addCredentialSuccessListener(listener) {
425
+ return OauthEssentials.onCredentialSuccess(listener);
426
+ }
427
+
428
+ /**
429
+ * Called with `{ code, message }` when one of the methods listed in
430
+ * {@link addCredentialSuccessListener} rejects. `SIMULTANEOUS_CALL_ERROR`, the iOS
431
+ * `NOT_SUPPORTED_ERROR` below iOS 16 and the iOS missing `requestJson` error are not emitted.
432
+ */
433
+ export function addCredentialFailureListener(listener) {
434
+ return OauthEssentials.onCredentialFailure(event => listener(event));
435
+ }
436
+
437
+ /**
438
+ * Called when iOS posts `credentialRevokedNotification`, i.e. the user stopped using Apple ID with
439
+ * the app while it is running. Sign the user out when it fires. Never called on Android.
440
+ */
441
+ export function addAppleIdCredentialRevokedListener(listener) {
442
+ return OauthEssentials.onAppleIdCredentialRevoked(() => listener());
443
+ }
97
444
  function parseGoogleIdOptions(options) {
98
445
  const bridgeOptions = {
99
446
  authorizedAccounts: false,
100
- autoSelectEnabled: false
447
+ autoSelectEnabled: false,
448
+ mode: 'bottomSheet'
101
449
  };
102
- const hasOptions = options && typeof options === 'object' && Object.keys(options).length > 0;
103
- if (hasOptions) {
104
- if (Platform.OS === 'android') {
105
- if (options.hasOwnProperty('authorizedAccounts')) {
106
- bridgeOptions.authorizedAccounts = options.authorizedAccounts === true;
107
- }
108
- if (options.hasOwnProperty('autoSelectEnabled')) {
109
- bridgeOptions.autoSelectEnabled = options.autoSelectEnabled === true;
110
- }
450
+ if (options && typeof options === 'object') {
451
+ if (options.authorizedAccounts !== undefined) {
452
+ bridgeOptions.authorizedAccounts = options.authorizedAccounts === true;
453
+ }
454
+ if (options.autoSelectEnabled !== undefined) {
455
+ bridgeOptions.autoSelectEnabled = options.autoSelectEnabled === true;
456
+ }
457
+ if (options.mode === 'button') {
458
+ bridgeOptions.mode = 'button';
459
+ }
460
+ if (options.offlineAccess !== undefined) {
461
+ bridgeOptions.offlineAccess = options.offlineAccess === true;
462
+ }
463
+ if (typeof options.nonce === 'string') {
464
+ bridgeOptions.nonce = options.nonce;
465
+ }
466
+ if (typeof options.hint === 'string') {
467
+ bridgeOptions.hint = options.hint;
468
+ }
469
+ if (typeof options.hostedDomain === 'string') {
470
+ bridgeOptions.hostedDomain = options.hostedDomain;
471
+ }
472
+ if (typeof options.serverClientId === 'string') {
473
+ bridgeOptions.serverClientId = options.serverClientId;
474
+ }
475
+ if (Array.isArray(options.scopes)) {
476
+ bridgeOptions.scopes = options.scopes.filter(s => typeof s === 'string');
111
477
  }
112
478
  }
113
479
  return bridgeOptions;
@@ -115,34 +481,42 @@ function parseGoogleIdOptions(options) {
115
481
  const CONSTANTS = OauthEssentials.getConstants();
116
482
 
117
483
  /**
118
- * Google Play are supported.
119
- * It always false on IOS, cause IOS does not use Google Play Services.
484
+ * Android: Google Play Services are installed and up to date (read once, when the module loads).
485
+ * iOS: always false.
120
486
  */
121
487
  export const GOOGLE_PLAY_SERVICES_SUPPORTED = CONSTANTS.GOOGLE_PLAY_SERVICES_SUPPORTED;
122
488
 
123
489
  /**
124
- * The password method is supported.
490
+ * iOS: always true. Android: same as `GOOGLE_PLAY_SERVICES_SUPPORTED` (`getPassword` and
491
+ * `passwordSignIn` reject with `NOT_SUPPORTED_ERROR` without Play Services).
125
492
  */
126
493
  export const PASSWORD_SUPPORTED = CONSTANTS.PASSWORD_SUPPORTED;
127
494
 
128
495
  /**
129
- * Google Play id sign in is supported.
130
- * You should mainly rely on this constant to check if you can use google sign in.
496
+ * iOS: always true. Android: same as `GOOGLE_PLAY_SERVICES_SUPPORTED`.
131
497
  */
132
498
  export const GOOGLE_ID_SUPPORTED = CONSTANTS.GOOGLE_ID_SUPPORTED;
133
499
 
134
500
  /**
135
- * Gets if Apple id sign in is supported.
501
+ * Always true (native on iOS, web flow in a Custom Tab on Android).
136
502
  */
137
503
  export const APPLE_ID_SUPPORTED = CONSTANTS.APPLE_ID_SUPPORTED;
138
504
 
139
505
  /**
140
- * Gets if "hybrid" is supported in this platform.
506
+ * iOS: always true. Android: same as `GOOGLE_PLAY_SERVICES_SUPPORTED` (`hybridSignIn` rejects with
507
+ * `NOT_SUPPORTED_ERROR` without Play Services).
141
508
  */
142
509
  export const HYBRID_SUPPORTED = CONSTANTS.HYBRID_SUPPORTED;
143
510
 
144
511
  /**
145
- * Gets if passkeys are supported.
512
+ * iOS 16+ / Android 9+ (API 28).
146
513
  */
147
514
  export const PASSKEYS_SUPPORTED = CONSTANTS.PASSKEYS_SUPPORTED;
515
+
516
+ /**
517
+ * Default redirect uri of `oauthSignIn`: `<bundle id, lowercased>://oauth/callback` on iOS and
518
+ * `<applicationId>://oauth/callback` on Android (the uri the library's `CustomTabsActivity`
519
+ * intent filter handles).
520
+ */
521
+ export const OAUTH_REDIRECT_URI = CONSTANTS.OAUTH_REDIRECT_URI;
148
522
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["OauthEssentials","Platform","CredentialsType","APPLE_ID_CACHED_RESULTS","Map","googleSignIn","webClientId","options","parseGoogleIdOptions","getPassword","result","passwordSignIn","username","password","appleSignIn","androidWebUrl","select","ios","undefined","android","type","APPLE_ID","has","data","user","cached","get","fullName","email","set","hybridSignIn","googleClientId","createPassKey","bridgeOptions","authorizedAccounts","autoSelectEnabled","hasOptions","Object","keys","length","OS","hasOwnProperty","CONSTANTS","getConstants","GOOGLE_PLAY_SERVICES_SUPPORTED","PASSWORD_SUPPORTED","GOOGLE_ID_SUPPORTED","APPLE_ID_SUPPORTED","HYBRID_SUPPORTED","PASSKEYS_SUPPORTED"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["OauthEssentials","Platform","CredentialError","CredentialsType","buildAuthorizationUrl","buildTokenRequestBody","getUrlScheme","parseRedirectParams","createCredentialError","resolveGoogleClientId","splitGoogleArgs","warnIgnored","warnOnce","isCredentialError","APPLE_ID_CACHED_RESULTS","Map","googleSignIn","clientIdOrOptions","maybeOptions","clientId","options","OS","GOOGLE_IOS_IGNORED","resolved","parseGoogleIdOptions","googleSilentSignIn","signOut","getPassword","passwordSignIn","username","password","appleSignIn","androidWebUrl","result","select","ios","default","type","APPLE_ID","has","data","user","cached","get","fullName","email","set","getAppleIdCredentialState","userId","hybridSignIn","createPassKey","warnPasskeyOptions","getPassKey","method","preferImmediatelyAvailableCredentials","mediation","cancelPassKeyAutoFill","oauthSignIn","redirectUri","OAUTH_REDIRECT_URI","usePKCE","pkce","generatePkce","url","authorizationEndpoint","scopes","additionalParameters","state","codeChallenge","undefined","session","openAuthSession","callbackScheme","prefersEphemeralSession","CANCELLED","params","oauthError","error","error_description","code","codeVerifier","tokens","tokenEndpoint","response","fetch","headers","body","e","NETWORK_ERROR","Error","message","String","json","INVALID_RESULT_ERROR","status","ok","OAUTH","addCredentialSuccessListener","listener","onCredentialSuccess","addCredentialFailureListener","onCredentialFailure","event","addAppleIdCredentialRevokedListener","onAppleIdCredentialRevoked","bridgeOptions","authorizedAccounts","autoSelectEnabled","mode","offlineAccess","nonce","hint","hostedDomain","serverClientId","Array","isArray","filter","s","CONSTANTS","getConstants","GOOGLE_PLAY_SERVICES_SUPPORTED","PASSWORD_SUPPORTED","GOOGLE_ID_SUPPORTED","APPLE_ID_SUPPORTED","HYBRID_SUPPORTED","PASSKEYS_SUPPORTED"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}