UNPKG

@krowdy/kds-auth

Version:

React components that implement Google's Material Design.

788 lines (705 loc) 25.3 kB
import _regeneratorRuntime from "@babel/runtime/regenerator"; import _extends from "@babel/runtime/helpers/esm/extends"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import PropTypes from 'prop-types'; import LoginContext from './LoginContext'; import AuthClient from '../Client'; import { initialState, updateStorage, clearStorage, ViewType } from './utils'; import { parseQueryString } from '../utils'; import PasswordNotify from '../LoginSinglePage/PasswordNotify'; import OneTapAuth from '../OnetapAuth'; import OneTapGoogle from '../OnetapGoogle/OnetapGoogle'; import LinkedInPopUp from '../LoginSinglePage/LinkedInPopUp'; var _ref5 = /*#__PURE__*/React.createElement(OneTapGoogle, null); var _ref6 = /*#__PURE__*/React.createElement(LinkedInPopUp, null); var AuthProvider = function AuthProvider(_ref) { var children = _ref.children, _ref$stateContext = _ref.stateContext, stateContext = _ref$stateContext === void 0 ? {} : _ref$stateContext, baseUrl = _ref.baseUrl, _ref$storage = _ref.storage, storage = _ref$storage === void 0 ? 'localStorage' : _ref$storage, urlLogin = _ref.urlLogin, _ref$social = _ref.social; _ref$social = _ref$social === void 0 ? {} : _ref$social; var google = _ref$social.google, linkedin = _ref$social.linkedin, microsoft = _ref$social.microsoft, facebook = _ref$social.facebook, referrer = _ref.referrer, clientSecret = _ref.clientSecret, _ref$loginWith = _ref.loginWith, loginWith = _ref$loginWith === void 0 ? 'only-email' : _ref$loginWith, clientId = _ref.clientId, withGoogle = _ref.withGoogle, isBolsa = _ref.isBolsa, customLegalBase = _ref.customLegalBase, _ref$onError = _ref.onError, onError = _ref$onError === void 0 ? function () {} : _ref$onError; var authClient = useRef(); var iframeRef = useRef(); var _useState = useState(initialState), _useState2 = _slicedToArray(_useState, 2), state = _useState2[0], setState = _useState2[1]; var paramsLinkedIn = typeof window !== 'undefined' ? parseQueryString(window.location.search) : {}; useEffect(function () { if (baseUrl) authClient.current = new AuthClient(baseUrl); }, [baseUrl]); var sendMessageToLoginApp = useCallback(function (eventId, credentials) { var iframe = iframeRef ? iframeRef.current : null; if (iframe) iframe.contentWindow.postMessage({ credentials: credentials, eventId: eventId }, "".concat(urlLogin, "/set-credentials")); }, // eslint-disable-next-line react-hooks/exhaustive-deps [urlLogin, iframeRef, iframeRef.current]); var _handleError = useCallback(function (error) { onError(error, state.typeView); }, [onError, state.typeView]); var _handleVerifySession = useCallback(function (credentials) { return authClient.current.verifySession(credentials).then(function (res) { if (res.success) { setState(function (prev) { return _extends({}, prev, {}, credentials); }); updateStorage(storage, credentials); } return res.success; })["catch"](function () { setState(function (prev) { return _extends({}, prev, { error: true }); }); return false; }); }, // eslint-disable-next-line react-hooks/exhaustive-deps [authClient, authClient.current]); var _handleMessage = useCallback(function _callee(_ref2) { var data, success, eventId, credentials, successLogin; return _regeneratorRuntime.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: data = _ref2.data; success = data.success, eventId = data.eventId, credentials = data.credentials; if (!(success && eventId === 'authStatus')) { _context.next = 9; break; } _context.next = 5; return _regeneratorRuntime.awrap(_handleVerifySession(credentials)); case 5: successLogin = _context.sent; setState(function (prev) { return _extends({}, prev, { flowFinished: successLogin, loadingAuth: false, successLogin: successLogin }); }); _context.next = 10; break; case 9: setState(function (prev) { return _extends({}, prev, { loadingAuth: false }); }); case 10: case "end": return _context.stop(); } } }, null, null, null, Promise); }, []); useEffect(function () { if (urlLogin) { window.addEventListener('message', _handleMessage, false); return function () { return window.removeEventListener('message', _handleMessage); }; } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); var _handleVerifyAccount = useCallback(function _callee2(source) { var _data; var recoveryPass, data, result, _data2, hasPassword, success, value, type, _args2 = arguments; return _regeneratorRuntime.async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: recoveryPass = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : false; setState(function (prev) { return _extends({}, prev, { loading: true }); }); data = {}; if (!(authClient === null || authClient === void 0 ? void 0 : authClient.current)) { _context2.next = 7; break; } _context2.next = 6; return _regeneratorRuntime.awrap(authClient.current.validateAccount({ recoveryPass: recoveryPass, source: source })); case 6: data = _context2.sent; case 7: result = data; if ((_data = data) === null || _data === void 0 ? void 0 : _data.success) { _data2 = data, hasPassword = _data2.hasPassword, success = _data2.success, value = _data2.value, type = _data2.type; setState(function (prev) { return _extends({}, prev, { typeCode: type }); }); result = { hasPassword: hasPassword, success: success, type: type, value: value }; } else { _handleError(data.error); } setState(function (prev) { return _extends({}, prev, { loading: false }); }); return _context2.abrupt("return", result); case 11: case "end": return _context2.stop(); } } }, null, null, null, Promise); }, []); var _handleSendVerifyCode = useCallback(function (source) { if (authClient === null || authClient === void 0 ? void 0 : authClient.current) authClient.current.sendVerifyCode(source); }, [authClient]); var _handleLoginByPassword = useCallback(function (_ref3) { var email = _ref3.email, password = _ref3.password, keepSession = _ref3.keepSession; if (authClient === null || authClient === void 0 ? void 0 : authClient.current) { setState(function (prev) { return _extends({}, prev, { loading: true }); }); return authClient.current.loginByPassword({ allowAds: state.allowAds ? 1 : 0, clientId: clientId, clientSecret: clientSecret, email: email, keepSession: keepSession ? 1 : 0, password: password }).then(function (data) { var result = {}; if (data.success) { var accessToken = data.accessToken, refreshToken = data.refreshToken, userId = data.userId; updateStorage(storage, { accessToken: accessToken, iduser: userId, refreshToken: refreshToken }); setState(function (prev) { return _extends({}, prev, { accessToken: accessToken, flowFinished: true, refreshToken: refreshToken, successLogin: true, userId: userId }); }); sendMessageToLoginApp('logged', { accessToken: accessToken, iduser: userId, refreshToken: refreshToken }); result = { accessToken: accessToken, refreshToken: refreshToken, success: true, userId: userId }; } setState(function (prev) { return _extends({}, prev, { loading: false }); }); return result; })["catch"](function (error) { setState(function (prev) { return _extends({}, prev, { loading: false }); }); _handleError(error); return {}; }); } }, [clientId, clientSecret, _handleError, sendMessageToLoginApp, state.allowAds, storage]); var _handleLoginByCode = useCallback(function _callee3(_ref4) { var code, value, type, keepSession; return _regeneratorRuntime.async(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: code = _ref4.code, value = _ref4.value, type = _ref4.type, keepSession = _ref4.keepSession; if (!(authClient === null || authClient === void 0 ? void 0 : authClient.current)) { _context3.next = 4; break; } setState(function (prev) { return _extends({}, prev, { loading: true }); }); return _context3.abrupt("return", authClient.current.verifyCode({ allowAds: state.allowAds ? 1 : 0, clientId: clientId, clientSecret: clientSecret, code: code, keepSession: keepSession ? 1 : 0, type: type, value: value }).then(function (data) { var result = {}; if (data.success) { var accessToken = data.accessToken, refreshToken = data.refreshToken, userId = data.userId, isNew = data.isNew; if (state.typeView !== ViewType.Recovery) updateStorage(storage, { accessToken: accessToken, iduser: userId, refreshToken: refreshToken }); setState(function (prev) { return _extends({}, prev, { accessToken: accessToken, flowFinished: !isNew, isNew: isNew, refreshToken: refreshToken, userId: userId }); }); sendMessageToLoginApp('logged', { accessToken: accessToken, iduser: userId, refreshToken: refreshToken }); result = { accessToken: accessToken, isNew: isNew, refreshToken: refreshToken, success: true, userId: userId }; } if (data.error) result = { error: data.error, success: false }; setState(function (prev) { return _extends({}, prev, { loading: false }); }); return result; })["catch"](function (error) { setState(function (prev) { return _extends({}, prev, { loading: false }); }); _handleError(error); return {}; })); case 4: case "end": return _context3.stop(); } } }, null, null, null, Promise); }, [state.allowAds, state.typeView, clientId, clientSecret, storage, sendMessageToLoginApp, _handleError]); var _handleSuccessLogin = useCallback(function (successLogin) { setState(function (prev) { return _extends({}, prev, { successLogin: successLogin }); }); }, []); var _handleUpdateAccount = useCallback(function _callee4(body) { var data; return _regeneratorRuntime.async(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: setState(function (prev) { return _extends({}, prev, { loading: true }); }); if (!(authClient === null || authClient === void 0 ? void 0 : authClient.current)) { _context4.next = 5; break; } _context4.next = 4; return _regeneratorRuntime.awrap(authClient.current.updateAccount(state.accessToken, body)); case 4: data = _context4.sent; case 5: setState(function (prev) { var _data3; return _extends({}, prev, { loading: false, successLogin: Boolean((_data3 = data) === null || _data3 === void 0 ? void 0 : _data3.success) }); }); return _context4.abrupt("return", data); case 7: case "end": return _context4.stop(); } } }, null, null, null, Promise); }, // eslint-disable-next-line react-hooks/exhaustive-deps [authClient, authClient.current, state.accessToken]); var _handleValidateSocial = useCallback(function _callee5(network, response) { var tokenId, method, _await$authClient$cur, error, refreshToken, accessToken, userId, isNew; return _regeneratorRuntime.async(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: tokenId = response.tokenId, method = response.method; if (!(authClient === null || authClient === void 0 ? void 0 : authClient.current)) { _context5.next = 12; break; } setState(function (prev) { return _extends({}, prev, { loadingSignIn: true, method: method }); }); _context5.next = 5; return _regeneratorRuntime.awrap(authClient.current.loginSocialNetwork({ allowAds: state.allowAds ? 1 : 0, clientId: clientId, clientSecret: clientSecret, keepSession: state.keepSession ? 1 : 0, network: network, tokenId: tokenId }, referrer)); case 5: _await$authClient$cur = _context5.sent; error = _await$authClient$cur.error; refreshToken = _await$authClient$cur.refreshToken; accessToken = _await$authClient$cur.accessToken; userId = _await$authClient$cur.userId; isNew = _await$authClient$cur.isNew; if (!error) { sendMessageToLoginApp('logged', { accessToken: accessToken, iduser: userId, refreshToken: refreshToken }); updateStorage(storage, { accessToken: accessToken, iduser: userId, refreshToken: refreshToken }); if (network === 'microsoft') window.sessionStorage.clear(); setState(function (prev) { return _extends({}, prev, { accessToken: accessToken, flowFinished: true, isNew: isNew, refreshToken: refreshToken, successLogin: true, userId: userId }); }); } else { _handleError(error); setState(function (prev) { return _extends({}, prev, { loadingSignIn: false }); }); } case 12: case "end": return _context5.stop(); } } }, null, null, null, Promise); }, [clientId, clientSecret, _handleError, referrer, sendMessageToLoginApp, state.allowAds, state.keepSession, storage]); var _handleAllowAds = useCallback(function () { setState(function (prev) { return _extends({}, prev, { allowAds: !prev.allowAds }); }); }, []); var _handleFlowFinished = useCallback(function (flowFinished) { setState(function (prev) { return _extends({}, prev, { flowFinished: flowFinished }); }); }, []); var createPassword = useCallback(function _callee6(password) { var res, accessToken, userId, refreshToken; return _regeneratorRuntime.async(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: if (!(authClient === null || authClient === void 0 ? void 0 : authClient.current)) { _context6.next = 15; break; } setState(function (prev) { return _extends({}, prev, { loading: true }); }); _context6.next = 4; return _regeneratorRuntime.awrap(authClient.current.updatePassword({ accessToken: state.accessToken, password: password })); case 4: res = _context6.sent; if (res === null || res === void 0 ? void 0 : res.success) { _context6.next = 9; break; } setState(function (prev) { return _extends({}, prev, { loading: false }); }); _handleError(res ? res.error : null); return _context6.abrupt("return", { success: false }); case 9: accessToken = state.accessToken, userId = state.userId, refreshToken = state.refreshToken; if (state.keepSession) updateStorage(storage, { accessToken: accessToken, iduser: userId, refreshToken: refreshToken }); setState(function (prev) { return _extends({}, prev, { flowFinished: true, loading: false, successLogin: true }); }); return _context6.abrupt("return", { success: true }); case 15: return _context6.abrupt("return", { success: false }); case 16: case "end": return _context6.stop(); } } }, null, null, null, Promise); }, // eslint-disable-next-line react-hooks/exhaustive-deps [authClient, authClient.current, state.accessToken]); var _handleLogOut = useCallback(function () { var deleteSession = function deleteSession() { if (window.google) window.google.accounts.id.disableAutoSelect(); clearStorage(storage, ['accessToken', 'iduser', 'refreshToken']); sessionStorage.clear(); }; var accessToken = state.accessToken, refreshToken = state.refreshToken; if (accessToken || refreshToken) { authClient.current.logout({ accessToken: accessToken, refreshToken: refreshToken }).then(function (res) { var success = res.success; if (!success) return console.error('Error when user closing session'); deleteSession(); sendMessageToLoginApp('unlogged'); })["catch"](function (error) { _handleError(error); deleteSession(); sendMessageToLoginApp('unlogged'); }); } else { deleteSession(); sendMessageToLoginApp('unlogged'); } }, [_handleError, sendMessageToLoginApp, state, storage]); var _handleUpdateState = useCallback(function (data) { setState(function (prev) { return _extends({}, prev, {}, data); }); }, []); var _handlePasswordNotify = useCallback(function (value) { setState(function (prev) { return _extends({}, prev, { openPasswordNotify: value }); }); }, []); var _handlePasswordCreate = useCallback(function () { setState(function (prev) { return _extends({}, prev, { openBackdrop: true, openPasswordNotify: false, typeView: ViewType.NewPassword }); }); }, []); var _handleClosePasswordNotify = useCallback(function () { setState(function (prev) { return _extends({}, prev, { flowFinished: true, openPasswordNotify: false }); }); }, []); var _handleChangeView = useCallback(function (typeView) { setState(function (prev) { return _extends({}, prev, { typeView: typeView }); }); }, []); var _handleCloseModal = useCallback(function () { setState(function (prev) { return _extends({}, prev, { customMainText: '', openBackdrop: false }); }); }, []); var _handleOpenModal = useCallback(function (customMainText) { setState(function (prev) { return _extends({}, prev, { customMainText: typeof customMainText === 'string' ? customMainText : '', openBackdrop: true }); }); }, []); var _handleSetLoadingSignIn = useCallback(function (value) { setState(function (prev) { return _extends({}, prev, { loadingSignIn: value }); }); }, []); var now = useMemo(function () { return new Date().getTime(); }, []); return /*#__PURE__*/React.createElement(LoginContext.Provider, { value: _extends({}, state, {}, stateContext, { customLegalBase: customLegalBase, facebookCredentials: facebook, googleCredentials: google, isBolsa: isBolsa, linkedinCredentials: linkedin, loginByCode: _handleLoginByCode, loginByPassword: _handleLoginByPassword, loginWith: loginWith, logout: _handleLogOut, microsoftCredentials: microsoft, onAllowAds: _handleAllowAds, onChangeView: _handleChangeView, onClose: _handleCloseModal, onError: _handleError, onFlowFinished: _handleFlowFinished, onOpen: _handleOpenModal, onPasswordNotify: _handlePasswordNotify, onSuccessLogin: _handleSuccessLogin, onUpdatePassword: createPassword, onUpdateState: _handleUpdateState, referrer: referrer, sendVerifyOrCode: _handleSendVerifyCode, setLoadingSignIn: _handleSetLoadingSignIn, updateAccount: _handleUpdateAccount, validateSocialNetwork: _handleValidateSocial, verifyAccount: _handleVerifyAccount }) }, withGoogle && !state.successLogin && !state.loadingAuth ? _ref5 : null, urlLogin && /*#__PURE__*/React.createElement("iframe", { height: "0px", ref: iframeRef, src: "".concat(urlLogin, "/set-credentials?timestamp=").concat(now), style: { display: 'none' }, title: "Alternative login", width: "0px" }), state.openPasswordNotify ? /*#__PURE__*/React.createElement(PasswordNotify, { onClose: _handleClosePasswordNotify, onCreate: _handlePasswordCreate }) : null, children, paramsLinkedIn.code || paramsLinkedIn.error ? _ref6 : null, state.openBackdrop ? /*#__PURE__*/React.createElement(OneTapAuth, { customMainText: state.customMainText }) : null); }; process.env.NODE_ENV !== "production" ? AuthProvider.propTypes = { baseUrl: PropTypes.string.isRequired, children: PropTypes.any, clientId: PropTypes.string, clientSecret: PropTypes.string, customLegalBase: PropTypes.shape({ footerHTML: PropTypes.string, urlPrivacyPolicy: PropTypes.string, urlTermsAndConditions: PropTypes.string }), isBolsa: PropTypes.bool, loginWith: PropTypes.oneOf(['only-email', 'only-phone', 'phone-and-email']), onError: PropTypes.func, referrer: PropTypes.string, social: PropTypes.shape({ facebook: PropTypes.shape({ clientId: PropTypes.string, redirectUri: PropTypes.string }), google: PropTypes.shape({ clientId: PropTypes.string, redirectUri: PropTypes.string }), linkedin: PropTypes.shape({ clientId: PropTypes.string, redirectUri: PropTypes.string }), microsoft: PropTypes.shape({ clientId: PropTypes.string, redirectUri: PropTypes.string }) }), stateContext: PropTypes.any, storage: PropTypes.string, urlLogin: PropTypes.string, withGoogle: PropTypes.bool } : void 0; export default React.memo(AuthProvider);