@moeindana/google-oauth
Version:
Google OAuth2 using Google Identity Services for React
237 lines (223 loc) • 10.2 kB
JavaScript
;
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 { 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.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);
};
}, []);
return scriptLoadedSuccessfully;
}
const GoogleOAuthContext = React.createContext(null);
function GoogleOAuthProvider({ clientId, onScriptLoadSuccess, onScriptLoadError, children, }) {
const scriptLoadedSuccessfully = useLoadGsiScript({
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;
}
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, ...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;
if (!scriptLoadedSuccessfully)
return;
(_a = window.google) === null || _a === void 0 ? void 0 : _a.accounts.id.initialize({
client_id: clientId,
callback: (credentialResponse) => {
var _a;
if (!credentialResponse.clientId || !credentialResponse.credential) {
return (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef);
}
fetch(`https://oauth2.googleapis.com/tokeninfo?id_token=${credentialResponse.credential}`)
.then(res => res.json())
.then(response => {
onSuccessRef.current({ ...response, ...credentialResponse });
})
.catch(error => {
onSuccessRef.current(credentialResponse);
});
},
...props,
});
(_b = window.google) === null || _b === void 0 ? void 0 : _b.accounts.id.renderButton(btnContainerRef.current, {
type,
theme,
size,
text,
shape,
logo_alignment,
width,
locale,
});
if (useOneTap)
(_c = window.google) === null || _c === void 0 ? void 0 : _c.accounts.id.prompt(promptMomentNotificationRef.current);
return () => {
var _a;
if (useOneTap)
(_a = window.google) === null || _a === void 0 ? void 0 : _a.accounts.id.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", { ref: btnContainerRef, style: { height: containerHeightMap[size] } }));
}
function googleLogout() {
var _a;
(_a = window.google) === null || _a === void 0 ? void 0 : _a.accounts.id.disableAutoSelect();
}
/* eslint-disable import/export */
function useGoogleLogin({ flow = 'implicit', scope = '', onSuccess, onError, ...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;
React.useEffect(() => {
var _a;
if (!scriptLoadedSuccessfully)
return;
// const clientMethod = 'initTokenClient';
const clientMethod = flow === 'implicit' ? 'initTokenClient' : 'initCodeClient';
const client = (_a = window.google) === null || _a === void 0 ? void 0 : _a.accounts.oauth2[clientMethod]({
client_id: clientId,
scope: `openid profile email https://www.googleapis.com/auth/userinfo.profile ${scope}`,
callback: (response) => {
var _a;
if (response.error)
return (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef, response);
fetch(`https://www.googleapis.com/oauth2/v1/userinfo?access_token=${response.access_token}`)
.then(res => res.json())
.then(res => {
var _a;
(_a = onSuccessRef.current) === null || _a === void 0 ? void 0 : _a.call(onSuccessRef, {
...res,
...response,
});
});
},
...props,
});
clientRef.current = client;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [clientId, scriptLoadedSuccessfully, flow, scope]);
const loginImplicitFlow = React.useCallback((overrideConfig) => { var _a; return (_a = clientRef.current) === null || _a === void 0 ? void 0 : _a.requestAccessToken(overrideConfig); }, []);
const loginAuthCodeFlow = React.useCallback(() => clientRef.current.requestCode(), []);
return flow === 'implicit' ? loginImplicitFlow : loginAuthCodeFlow;
}
function useGoogleOneTapLogin({ onSuccess, onError, promptMomentNotification, cancel_on_tap_outside, hosted_domain, }) {
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;
if (!scriptLoadedSuccessfully)
return;
(_a = window.google) === null || _a === void 0 ? void 0 : _a.accounts.id.initialize({
client_id: clientId,
callback: (credentialResponse) => {
var _a;
if (!credentialResponse.clientId || !credentialResponse.credential) {
return (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef);
}
onSuccessRef.current(credentialResponse);
},
hosted_domain,
cancel_on_tap_outside,
});
(_b = window.google) === null || _b === void 0 ? void 0 : _b.accounts.id.prompt(promptMomentNotificationRef.current);
return () => {
var _a;
(_a = window.google) === null || _a === void 0 ? void 0 : _a.accounts.id.cancel();
};
}, [
clientId,
scriptLoadedSuccessfully,
cancel_on_tap_outside,
hosted_domain,
]);
}
/**
* Checks if the user granted all the specified scope or scopes
* @returns True if all the scopes are granted
*/
function hasGrantedAllScopesGoogle(tokenResponse, firstScope, ...restScopes) {
if (!window.google)
return false;
return window.google.accounts.oauth2.hasGrantedAllScopes(tokenResponse, firstScope, ...restScopes);
}
/**
* 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) {
if (!window.google)
return false;
return window.google.accounts.oauth2.hasGrantedAnyScope(tokenResponse, firstScope, ...restScopes);
}
exports.GoogleLogin = GoogleLogin;
exports.GoogleOAuthProvider = GoogleOAuthProvider;
exports.googleLogout = googleLogout;
exports.hasGrantedAllScopesGoogle = hasGrantedAllScopesGoogle;
exports.hasGrantedAnyScopeGoogle = hasGrantedAnyScopeGoogle;
exports.useGoogleLogin = useGoogleLogin;
exports.useGoogleOneTapLogin = useGoogleOneTapLogin;