UNPKG

@react-oauth/google

Version:

Google OAuth2 using Google Identity Services for React 🚀

264 lines (249 loc) • 13.5 kB
'use client' 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); function useLoadGsiScript(options = {}) { const { nonce, onScriptLoadSuccess, onScriptLoadError } = options; const [scriptLoadedSuccessfully, setScriptLoadedSuccessfully] = React.useState(false); const onScriptLoadSuccessRef = React.useRef(onScriptLoadSuccess); onScriptLoadSuccessRef.current = onScriptLoadSuccess; const onScriptLoadErrorRef = React.useRef(onScriptLoadError); onScriptLoadErrorRef.current = onScriptLoadError; React.useEffect(() => { const scriptTag = document.createElement('script'); scriptTag.src = 'https://accounts.google.com/gsi/client'; scriptTag.async = true; scriptTag.defer = true; scriptTag.nonce = nonce; scriptTag.onload = () => { var _a; setScriptLoadedSuccessfully(true); (_a = onScriptLoadSuccessRef.current) === null || _a === void 0 ? void 0 : _a.call(onScriptLoadSuccessRef); }; scriptTag.onerror = () => { var _a; setScriptLoadedSuccessfully(false); (_a = onScriptLoadErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onScriptLoadErrorRef); }; document.body.appendChild(scriptTag); return () => { document.body.removeChild(scriptTag); }; }, [nonce]); return scriptLoadedSuccessfully; } const GoogleOAuthContext = React.createContext(null); function GoogleOAuthProvider({ clientId, nonce, onScriptLoadSuccess, onScriptLoadError, children, }) { const scriptLoadedSuccessfully = useLoadGsiScript({ nonce, onScriptLoadSuccess, onScriptLoadError, }); const contextValue = React.useMemo(() => ({ clientId, scriptLoadedSuccessfully, }), [clientId, scriptLoadedSuccessfully]); return (React__default["default"].createElement(GoogleOAuthContext.Provider, { value: contextValue }, children)); } function useGoogleOAuth() { const context = React.useContext(GoogleOAuthContext); if (!context) { throw new Error('Google OAuth components must be used within GoogleOAuthProvider'); } return context; } function extractClientId(credentialResponse) { var _a; const clientId = (_a = credentialResponse === null || credentialResponse === void 0 ? void 0 : credentialResponse.clientId) !== null && _a !== void 0 ? _a : credentialResponse === null || credentialResponse === void 0 ? void 0 : credentialResponse.client_id; return clientId; } const containerHeightMap = { large: 40, medium: 32, small: 20 }; function GoogleLogin({ onSuccess, onError, useOneTap, promptMomentNotification, type = 'standard', theme = 'outline', size = 'large', text, shape, logo_alignment, width, locale, click_listener, containerProps, ...props }) { const btnContainerRef = React.useRef(null); const { clientId, scriptLoadedSuccessfully } = useGoogleOAuth(); const onSuccessRef = React.useRef(onSuccess); onSuccessRef.current = onSuccess; const onErrorRef = React.useRef(onError); onErrorRef.current = onError; const promptMomentNotificationRef = React.useRef(promptMomentNotification); promptMomentNotificationRef.current = promptMomentNotification; React.useEffect(() => { var _a, _b, _c, _d, _e, _f, _g, _h, _j; if (!scriptLoadedSuccessfully) return; (_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.id) === null || _c === void 0 ? void 0 : _c.initialize({ client_id: clientId, callback: (credentialResponse) => { var _a; if (!(credentialResponse === null || credentialResponse === void 0 ? void 0 : credentialResponse.credential)) { return (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef); } const { credential, select_by } = credentialResponse; onSuccessRef.current({ credential, clientId: extractClientId(credentialResponse), select_by, }); }, ...props, }); (_f = (_e = (_d = window === null || window === void 0 ? void 0 : window.google) === null || _d === void 0 ? void 0 : _d.accounts) === null || _e === void 0 ? void 0 : _e.id) === null || _f === void 0 ? void 0 : _f.renderButton(btnContainerRef.current, { type, theme, size, text, shape, logo_alignment, width, locale, click_listener, }); if (useOneTap) (_j = (_h = (_g = window === null || window === void 0 ? void 0 : window.google) === null || _g === void 0 ? void 0 : _g.accounts) === null || _h === void 0 ? void 0 : _h.id) === null || _j === void 0 ? void 0 : _j.prompt(promptMomentNotificationRef.current); return () => { var _a, _b, _c; if (useOneTap) (_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.id) === null || _c === void 0 ? void 0 : _c.cancel(); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [ clientId, scriptLoadedSuccessfully, useOneTap, type, theme, size, text, shape, logo_alignment, width, locale, ]); return (React__default["default"].createElement("div", { ...containerProps, ref: btnContainerRef, style: { height: containerHeightMap[size], ...containerProps === null || containerProps === void 0 ? void 0 : containerProps.style } })); } function googleLogout() { var _a, _b, _c; (_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.id) === null || _c === void 0 ? void 0 : _c.disableAutoSelect(); } /* eslint-disable import/export */ function useGoogleLogin({ flow = 'implicit', scope = '', onSuccess, onError, onNonOAuthError, overrideScope, state, ...props }) { const { clientId, scriptLoadedSuccessfully } = useGoogleOAuth(); const clientRef = React.useRef(); const onSuccessRef = React.useRef(onSuccess); onSuccessRef.current = onSuccess; const onErrorRef = React.useRef(onError); onErrorRef.current = onError; const onNonOAuthErrorRef = React.useRef(onNonOAuthError); onNonOAuthErrorRef.current = onNonOAuthError; React.useEffect(() => { var _a, _b; if (!scriptLoadedSuccessfully) return; const clientMethod = flow === 'implicit' ? 'initTokenClient' : 'initCodeClient'; const client = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.oauth2[clientMethod]({ client_id: clientId, scope: overrideScope ? scope : `openid profile email ${scope}`, callback: (response) => { var _a, _b; if (response.error) return (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef, response); (_b = onSuccessRef.current) === null || _b === void 0 ? void 0 : _b.call(onSuccessRef, response); }, error_callback: (nonOAuthError) => { var _a; (_a = onNonOAuthErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onNonOAuthErrorRef, nonOAuthError); }, state, ...props, }); clientRef.current = client; // eslint-disable-next-line react-hooks/exhaustive-deps }, [clientId, scriptLoadedSuccessfully, flow, scope, state]); const loginImplicitFlow = React.useCallback((overrideConfig) => { var _a; return (_a = clientRef.current) === null || _a === void 0 ? void 0 : _a.requestAccessToken(overrideConfig); }, []); const loginAuthCodeFlow = React.useCallback(() => { var _a; return (_a = clientRef.current) === null || _a === void 0 ? void 0 : _a.requestCode(); }, []); return flow === 'implicit' ? loginImplicitFlow : loginAuthCodeFlow; } function useGoogleOneTapLogin({ onSuccess, onError, promptMomentNotification, cancel_on_tap_outside, prompt_parent_id, state_cookie_domain, hosted_domain, use_fedcm_for_prompt = false, disabled, auto_select, }) { const { clientId, scriptLoadedSuccessfully } = useGoogleOAuth(); const onSuccessRef = React.useRef(onSuccess); onSuccessRef.current = onSuccess; const onErrorRef = React.useRef(onError); onErrorRef.current = onError; const promptMomentNotificationRef = React.useRef(promptMomentNotification); promptMomentNotificationRef.current = promptMomentNotification; React.useEffect(() => { var _a, _b, _c, _d, _e, _f, _g, _h, _j; if (!scriptLoadedSuccessfully) return; if (disabled) { (_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.id) === null || _c === void 0 ? void 0 : _c.cancel(); return; } (_f = (_e = (_d = window === null || window === void 0 ? void 0 : window.google) === null || _d === void 0 ? void 0 : _d.accounts) === null || _e === void 0 ? void 0 : _e.id) === null || _f === void 0 ? void 0 : _f.initialize({ client_id: clientId, callback: (credentialResponse) => { var _a; if (!(credentialResponse === null || credentialResponse === void 0 ? void 0 : credentialResponse.credential)) { return (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef); } const { credential, select_by } = credentialResponse; onSuccessRef.current({ credential, clientId: extractClientId(credentialResponse), select_by, }); }, hosted_domain, cancel_on_tap_outside, prompt_parent_id, state_cookie_domain, use_fedcm_for_prompt, auto_select, }); (_j = (_h = (_g = window === null || window === void 0 ? void 0 : window.google) === null || _g === void 0 ? void 0 : _g.accounts) === null || _h === void 0 ? void 0 : _h.id) === null || _j === void 0 ? void 0 : _j.prompt(promptMomentNotificationRef.current); return () => { var _a, _b, _c; (_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.id) === null || _c === void 0 ? void 0 : _c.cancel(); }; }, [ clientId, scriptLoadedSuccessfully, cancel_on_tap_outside, prompt_parent_id, state_cookie_domain, hosted_domain, use_fedcm_for_prompt, disabled, auto_select, ]); } /** * Checks if the user granted all the specified scope or scopes * @returns True if all the scopes are granted */ function hasGrantedAllScopesGoogle(tokenResponse, firstScope, ...restScopes) { var _a, _b, _c; if (!(window === null || window === void 0 ? void 0 : window.google)) return false; return (((_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.oauth2) === null || _c === void 0 ? void 0 : _c.hasGrantedAllScopes(tokenResponse, firstScope, ...restScopes)) || false); } /** * Checks if the user granted any of the specified scope or scopes. * @returns True if any of the scopes are granted */ function hasGrantedAnyScopeGoogle(tokenResponse, firstScope, ...restScopes) { var _a, _b, _c; if (!(window === null || window === void 0 ? void 0 : window.google)) return false; return (((_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.accounts) === null || _b === void 0 ? void 0 : _b.oauth2) === null || _c === void 0 ? void 0 : _c.hasGrantedAnyScope(tokenResponse, firstScope, ...restScopes)) || false); } exports.GoogleLogin = GoogleLogin; exports.GoogleOAuthProvider = GoogleOAuthProvider; exports.googleLogout = googleLogout; exports.hasGrantedAllScopesGoogle = hasGrantedAllScopesGoogle; exports.hasGrantedAnyScopeGoogle = hasGrantedAnyScopeGoogle; exports.useGoogleLogin = useGoogleLogin; exports.useGoogleOAuth = useGoogleOAuth; exports.useGoogleOneTapLogin = useGoogleOneTapLogin;