Skip to content

Commit 9c23c44

Browse files
authored
feat: add support for use_fedcm_for_prompt for fedcm migration (#316)
1 parent cc7c908 commit 9c23c44

File tree

7 files changed

+46
-17
lines changed

7 files changed

+46
-17
lines changed

.changeset/brown-actors-return.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@react-oauth/google': minor
3+
---
4+
5+
- add support for use_fedcm_for_prompt for fedcm migration
6+
- export `useGoogleOAuth` returns { scriptLoadedSuccessfully: boolean; clientId: string }

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,7 @@ const login = useGoogleLogin({
140140
onSuccess: tokenResponse => console.log(tokenResponse),
141141
});
142142

143-
<MyCustomButton onClick={() => login()}>
144-
Sign in with Google 🚀{' '}
145-
</MyCustomButton>;
143+
<MyCustomButton onClick={() => login()}>Sign in with Google 🚀</MyCustomButton>;
146144
```
147145

148146
#### Authorization code flow
@@ -157,9 +155,7 @@ const login = useGoogleLogin({
157155
flow: 'auth-code',
158156
});
159157

160-
<MyCustomButton onClick={() => login()}>
161-
Sign in with Google 🚀{' '}
162-
</MyCustomButton>;
158+
<MyCustomButton onClick={() => login()}>Sign in with Google 🚀</MyCustomButton>;
163159
```
164160

165161
#### Checks if the user granted all the specified scope or scopes
@@ -186,6 +182,8 @@ const hasAccess = hasGrantedAnyScopeGoogle(
186182
);
187183
```
188184

185+
#### [Content Security Policy (if needed)](https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid#content_security_policy)
186+
189187
## API
190188

191189
### GoogleOAuthProvider
@@ -227,6 +225,7 @@ const hasAccess = hasGrantedAnyScopeGoogle(
227225
| | intermediate_iframe_close_callback | `function` | Overrides the default intermediate iframe behavior when users manually close One Tap |
228226
| | itp_support | `boolean` | Enables upgraded One Tap UX on ITP browsers |
229227
| | hosted_domain | `string` | If your application knows the Workspace domain the user belongs to, use this to provide a hint to Google. For more information, see the [hd](https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters) field in the OpenID Connect docs |
228+
| | use_fedcm_for_prompt | `boolean` | Allow the browser to control user sign-in prompts and mediate the sign-in flow between your website and Google. |
230229

231230
### useGoogleLogin (Both implicit & authorization code flow)
232231

@@ -267,3 +266,4 @@ const hasAccess = hasGrantedAnyScopeGoogle(
267266
| | cancel_on_tap_outside | `boolean` | Controls whether to cancel the prompt if the user clicks outside of the prompt |
268267
| | hosted_domain | `string` | If your application knows the Workspace domain the user belongs to, use this to provide a hint to Google. For more information, see the [hd](https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters) field in the OpenID Connect docs |
269268
| | disabled | `boolean` | Controls whether to cancel the popup in cases such as when the user is already logged in |
269+
| | use_fedcm_for_prompt | `boolean` | Allow the browser to control user sign-in prompts and mediate the sign-in flow between your website and Google. |

packages/@react-oauth/google/README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ $ npm install @react-oauth/google@latest
1212
$ yarn add @react-oauth/google@latest
1313
```
1414

15-
## Demo
15+
## Demo & How to use to fetch user details
1616

1717
https://react-oauth.vercel.app/
1818

@@ -140,9 +140,7 @@ const login = useGoogleLogin({
140140
onSuccess: tokenResponse => console.log(tokenResponse),
141141
});
142142

143-
<MyCustomButton onClick={() => login()}>
144-
Sign in with Google 🚀{' '}
145-
</MyCustomButton>;
143+
<MyCustomButton onClick={() => login()}>Sign in with Google 🚀</MyCustomButton>;
146144
```
147145

148146
#### Authorization code flow
@@ -157,9 +155,7 @@ const login = useGoogleLogin({
157155
flow: 'auth-code',
158156
});
159157

160-
<MyCustomButton onClick={() => login()}>
161-
Sign in with Google 🚀{' '}
162-
</MyCustomButton>;
158+
<MyCustomButton onClick={() => login()}>Sign in with Google 🚀</MyCustomButton>;
163159
```
164160

165161
#### Checks if the user granted all the specified scope or scopes
@@ -186,13 +182,16 @@ const hasAccess = hasGrantedAnyScopeGoogle(
186182
);
187183
```
188184

185+
#### [Content Security Policy (if needed)](https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid#content_security_policy)
186+
189187
## API
190188

191189
### GoogleOAuthProvider
192190

193191
| Required | Prop | Type | Description |
194192
| :------: | ------------------- | ---------- | --------------------------------------------------------------------------- |
195193
|| clientId | `string` | [**Google API client ID**](https://console.cloud.google.com/apis/dashboard) |
194+
| | nonce | `string` | Nonce applied to GSI script tag. Propagates to GSI's inline style tag |
196195
| | onScriptLoadSuccess | `function` | Callback fires on load gsi script success |
197196
| | onScriptLoadError | `function` | Callback fires on load gsi script failure |
198197

@@ -226,6 +225,7 @@ const hasAccess = hasGrantedAnyScopeGoogle(
226225
| | intermediate_iframe_close_callback | `function` | Overrides the default intermediate iframe behavior when users manually close One Tap |
227226
| | itp_support | `boolean` | Enables upgraded One Tap UX on ITP browsers |
228227
| | hosted_domain | `string` | If your application knows the Workspace domain the user belongs to, use this to provide a hint to Google. For more information, see the [hd](https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters) field in the OpenID Connect docs |
228+
| | use_fedcm_for_prompt | `boolean` | Allow the browser to control user sign-in prompts and mediate the sign-in flow between your website and Google. |
229229

230230
### useGoogleLogin (Both implicit & authorization code flow)
231231

@@ -265,3 +265,5 @@ const hasAccess = hasGrantedAnyScopeGoogle(
265265
| | promptMomentNotification | `(notification: PromptMomentNotification) => void` | [PromptMomentNotification](https://developers.google.com/identity/gsi/web/reference/js-reference) methods and description |
266266
| | cancel_on_tap_outside | `boolean` | Controls whether to cancel the prompt if the user clicks outside of the prompt |
267267
| | hosted_domain | `string` | If your application knows the Workspace domain the user belongs to, use this to provide a hint to Google. For more information, see the [hd](https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters) field in the OpenID Connect docs |
268+
| | disabled | `boolean` | Controls whether to cancel the popup in cases such as when the user is already logged in |
269+
| | use_fedcm_for_prompt | `boolean` | Allow the browser to control user sign-in prompts and mediate the sign-in flow between your website and Google. |

packages/@react-oauth/google/src/hooks/useGoogleLogin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export default function useGoogleLogin({
9696
const clientMethod =
9797
flow === 'implicit' ? 'initTokenClient' : 'initCodeClient';
9898

99-
const client = window?.google?.accounts.oauth2[clientMethod]({
99+
const client = window?.google?.accounts?.oauth2[clientMethod]({
100100
client_id: clientId,
101101
scope: overrideScope ? scope : `openid profile email ${scope}`,
102102
callback: (response: TokenResponse | CodeResponse) => {

packages/@react-oauth/google/src/hooks/useGoogleOneTapLogin.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { useEffect, useRef } from 'react';
22

33
import { useGoogleOAuth } from '../GoogleOAuthProvider';
44
import { extractClientId } from '../utils';
5-
import {
5+
import type {
66
CredentialResponse,
77
GoogleCredentialResponse,
8+
IdConfiguration,
89
MomentListener,
910
} from '../types';
1011

@@ -17,6 +18,8 @@ interface UseGoogleOneTapLoginOptions {
1718
state_cookie_domain?: string;
1819
hosted_domain?: string;
1920
disabled?: boolean;
21+
use_fedcm_for_prompt?: IdConfiguration['use_fedcm_for_prompt'];
22+
auto_select?: boolean;
2023
}
2124

2225
export default function useGoogleOneTapLogin({
@@ -27,7 +30,9 @@ export default function useGoogleOneTapLogin({
2730
prompt_parent_id,
2831
state_cookie_domain,
2932
hosted_domain,
33+
use_fedcm_for_prompt = false,
3034
disabled,
35+
auto_select,
3136
}: UseGoogleOneTapLoginOptions): void {
3237
const { clientId, scriptLoadedSuccessfully } = useGoogleOAuth();
3338

@@ -66,6 +71,8 @@ export default function useGoogleOneTapLogin({
6671
cancel_on_tap_outside,
6772
prompt_parent_id,
6873
state_cookie_domain,
74+
use_fedcm_for_prompt,
75+
auto_select,
6976
});
7077

7178
window?.google?.accounts?.id?.prompt(promptMomentNotificationRef.current);
@@ -80,6 +87,8 @@ export default function useGoogleOneTapLogin({
8087
prompt_parent_id,
8188
state_cookie_domain,
8289
hosted_domain,
90+
use_fedcm_for_prompt,
8391
disabled,
92+
auto_select,
8493
]);
8594
}

packages/@react-oauth/google/src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
export { default as GoogleOAuthProvider } from './GoogleOAuthProvider';
1+
export {
2+
default as GoogleOAuthProvider,
3+
useGoogleOAuth,
4+
} from './GoogleOAuthProvider';
25
export { default as GoogleLogin } from './GoogleLogin';
36
export type { GoogleLoginProps } from './GoogleLogin';
47
export { default as googleLogout } from './googleLogout';

packages/@react-oauth/google/src/types/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ export interface IdConfiguration {
4949
* field in the OpenID Connect docs.
5050
*/
5151
hosted_domain?: string;
52+
/**
53+
* Allow the browser to control user sign-in prompts and mediate the sign-in flow between your website and Google.
54+
* @default false
55+
*/
56+
use_fedcm_for_prompt?: boolean;
5257
}
5358

5459
export interface CredentialResponse {
@@ -99,7 +104,11 @@ export interface PromptMomentNotification {
99104
isDisplayed: () => boolean;
100105
/** Is this notification for a display moment, and the UI isn't displayed? */
101106
isNotDisplayed: () => boolean;
102-
/** The detailed reason why the UI isn't displayed */
107+
/**
108+
* The detailed reason why the UI isn't displayed
109+
* Avoid using `opt_out_or_no_session`. When FedCM is enabled,
110+
* this value is not supported. See Migrate to FedCM page for more information.
111+
* */
103112
getNotDisplayedReason: () =>
104113
| 'browser_not_supported'
105114
| 'invalid_client'

0 commit comments

Comments
 (0)