-
-
- {__('Integration Name:', 'bit-integrations')}
- handleInput(e, tab, crmConf, setCrmConf)}
- name="name"
- value={crmConf.name}
- type="text"
- placeholder={__('Integration Name...', 'bit-integrations')}
- />
-
-
-
-
-
-
handleInput(e, tab, crmConf, setCrmConf, setIsLoading, setSnackbar)}
+ if (step == 1) {
+ return (
+
+ )
+ }
+
+ if (step == 2) {
+ return (
+
+
+
+
+ {__('Integration Name:', 'bit-integrations')}
+ handleInput(e, tab, crmConf, setCrmConf)}
+ name="name"
+ value={crmConf.name}
+ type="text"
+ placeholder={__('Integration Name...', 'bit-integrations')}
+ />
+
+
+
+
+
+
handleInput(e, tab, crmConf, setCrmConf, setIsLoading, setSnackbar)}
+ crmConf={crmConf}
+ setCrmConf={setCrmConf}
+ isLoading={isLoading}
+ setIsLoading={setIsLoading}
+ setSnackbar={setSnackbar}
+ />
+
+
+
+
+ )
+ }
-
-
-
- )
}
export default EditZohoCRM
diff --git a/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRM.jsx b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRM.jsx
index d244b907a..4a4bca741 100644
--- a/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRM.jsx
+++ b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRM.jsx
@@ -10,6 +10,7 @@ import IntegrationStepThree from '../IntegrationHelpers/IntegrationStepThree'
import ZohoCRMAuthorization from './ZohoCRMAuthorization'
import { checkMappedFields, handleInput } from './ZohoCRMCommonFunc'
import ZohoCRMIntegLayout from './ZohoCRMIntegLayout'
+import bitsFetch from '../../../Utils/bitsFetch'
function ZohoCRM({ formFields, setFlow, flow, allIntegURL }) {
const navigate = useNavigate()
@@ -32,9 +33,28 @@ function ZohoCRM({ formFields, setFlow, flow, allIntegURL }) {
actions: {}
})
+
useEffect(() => {
- window.opener && setGrantTokenResponse('zohoCRM')
- }, [])
+ const fetchCredentials = async () => {
+ if (crmConf.oneClickAuthCredentials === undefined) {
+ const actionName = "zohoCrm";
+
+ try {
+ const userInfoResponse = await fetch('https://auth-apps.bitapps.pro/apps/' + actionName);
+ const userInfo = await userInfoResponse.json();
+ setCrmConf((prevConf) => {
+ return { ...prevConf, oneClickAuthCredentials: userInfo };
+ });
+ } catch (error) {
+ console.error('Error fetching Credentials:', error);
+ }
+ }
+ };
+
+ fetchCredentials();
+ }, []);
+
+
const saveConfig = () => {
saveActionConf({
diff --git a/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMAuthorization.jsx b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMAuthorization.jsx
index bbde46bfe..ac924b943 100644
--- a/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMAuthorization.jsx
+++ b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMAuthorization.jsx
@@ -1,13 +1,17 @@
-import { useState } from 'react'
-import { useRecoilValue } from 'recoil'
+import { useEffect, useState } from 'react'
+import { useRecoilState, useRecoilValue } from 'recoil'
import { __ } from '../../../Utils/i18nwrap'
import CopyText from '../../Utilities/CopyText'
import LoaderSm from '../../Loaders/LoaderSm'
-import { refreshModules } from './ZohoCRMCommonFunc'
-import { handleAuthorize } from '../IntegrationHelpers/IntegrationHelpers'
-import { $btcbi } from '../../../GlobalStates'
+import { handleAuthorize, refreshModules, tokenHelper } from './ZohoCRMCommonFunc'
+import { $btcbi, authInfoAtom } from '../../../GlobalStates'
import tutorialLinks from '../../../Utils/StaticData/tutorialLinks'
import TutorialLink from '../../Utilities/TutorialLink'
+import SelectAuthorizationType from '../../OneClickRadioComponents/SelectAuthorizationType'
+import Loader from '../../Loaders/Loader'
+import BackIcn from '../../../Icons/BackIcn'
+import AuthorizationAccountList from '../../OneClickRadioComponents/AuthorizationAccountList'
+import bitsFetch from '../../../Utils/bitsFetch'
export default function ZohoCRMAuthorization({
formID,
@@ -19,21 +23,38 @@ export default function ZohoCRMAuthorization({
setIsLoading,
setSnackbar,
redirectLocation,
- isInfo
+ isEdit
}) {
+
const [isAuthorized, setisAuthorized] = useState(false)
const [error, setError] = useState({ dataCenter: '', clientId: '', clientSecret: '' })
const btcbi = useRecoilValue($btcbi)
const { zohoCRM } = tutorialLinks
+ const [authData, setAuthData] = useState([])
+ const [authInfo, setAuthInfo] = useRecoilState(authInfoAtom);
+ const [selectedAuthType, setSelectedAuthType] = useState('')
+ const [selectedUserId, setSelectedUserId] = useState(null)
const scopes = 'ZohoCRM.modules.ALL,ZohoCRM.settings.ALL,ZohoCRM.users.Read,zohocrm.files.CREATE'
const nextPage = () => {
+ console.log('crmConf', crmConf)
+ const selectedAuth = authData.find((item) => item.id === selectedUserId)
+ setCrmConf((prevConf) => ({
+ ...prevConf,
+ tokenDetails: selectedAuth ? selectedAuth.tokenDetails : '',
+ authId: selectedAuth ? selectedAuth.id : '',
+ dataCenter: (selectedAuth?.tokenDetails?.selectedAuthType ?? crmConf?.tokenDetails) === 'One Click Authorization' ? 'com' : '',
+ }))
+
setTimeout(() => {
document.getElementById('btcd-settings-wrp').scrollTop = 0
}, 300)
setstep(2)
- !crmConf.module && refreshModules(formID, crmConf, setCrmConf, setIsLoading, setSnackbar)
+ !crmConf.module && refreshModules(formID, {
+ ...crmConf, tokenDetails: selectedAuth ? selectedAuth.tokenDetails : '', authId: selectedAuth ? selectedAuth.id : '',
+ dataCenter: selectedAuth.tokenDetails.selectedAuthType === 'One Click Authorization' ? 'com' : ''
+ }, setCrmConf, setIsLoading, setSnackbar)
}
const handleInput = (e) => {
const newConf = { ...crmConf }
@@ -44,6 +65,94 @@ export default function ZohoCRMAuthorization({
setCrmConf(newConf)
}
+ //Commented for one click authorization
+
+ const handleChange = (option) => {
+ setSelectedAuthType(option)
+ setisAuthorized(false)
+
+ setCrmConf((prevConf) => ({
+ ...prevConf,
+ selectedAuthType: option,
+ ...(option === "One Click Authorization" && process.env.NODE_ENV !== 'development'
+ ? {
+ clientId: '',
+ clientSecret: '',
+ }
+ : {}),
+ }))
+
+ if (option === "One Click Authorization") {
+ processAuth(option);
+ }
+ setIsLoading(false);
+ };
+
+
+ const processAuth = (option) => {
+ handleAuthorize('zohoCRM',
+ 'zcrm',
+ option,
+ scopes,
+ crmConf,
+ setCrmConf,
+ setError,
+ setisAuthorized,
+ setIsLoading,
+ setSnackbar,
+ btcbi);
+ }
+
+ const getAuthData = () => {
+ setIsLoading(true)
+ const queryParams = {
+ actionName: crmConf.type
+ }
+
+ bitsFetch(null, 'auth/get', queryParams, 'GET').then((res) => {
+ if (res.success && res.data.data.length > 0) {
+ setAuthData(res.data.data);
+ }
+ setIsLoading(false)
+ })
+ }
+
+ useEffect(() => {
+ if (step === 1) {
+ getAuthData()
+ }
+ }, [])
+
+
+
+ const handleVerificationCode = async (authInfo) => {
+ await tokenHelper(authInfo, crmConf, setCrmConf, selectedAuthType, setAuthData, setIsLoading, setSnackbar);
+ setAuthInfo(undefined)
+ getAuthData()
+ }
+
+ useEffect(() => {
+ if (!authInfo || Object.keys(authInfo).length === 0) return;
+ handleVerificationCode(authInfo);
+ }, [authInfo]);
+
+
+
+ useEffect(() => {
+
+ if (step === 1 && isEdit) {
+
+ const authIdExists = authData.find(auth => auth.id === crmConf.authId);
+
+ if (authIdExists) {
+ setSelectedUserId(crmConf.authId)
+ } else {
+ setSelectedUserId(null)
+ }
+ }
+ }, [authData])
+
+ console.log('authData.length === 0 && !isEdit && (crmConf.tokenDetails == null)', authData.length === 0 && !isEdit && !(crmConf.tokenDetails))
return (
-
{__('Integration Name:', 'bit-integrations')}
+
+
Choose channel
+
-
-
-
- {__('Data Center:', 'bit-integrations')}
-
-
-
{error.dataCenter}
-
-
- {__('Homepage URL:', 'bit-integrations')}
-
-
-
-
- {__('Authorized Redirect URIs:', 'bit-integrations')}
-
-
-
-
- {__('To get Client ID and SECRET , Please Visit', 'bit-integrations')}{' '}
-
- {__('Zoho API Console', 'bit-integrations')}
-
-
-
-
- {__('Client id:', 'bit-integrations')}
-
-
-
{error.clientId}
-
-
- {__('Client secret:', 'bit-integrations')}
-
-
-
{error.clientSecret}
-
- {!isInfo && (
- <>
-
)
}
diff --git a/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMCommonFunc.js b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMCommonFunc.js
index b7f9b6287..c7b0a9ab3 100644
--- a/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMCommonFunc.js
+++ b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMCommonFunc.js
@@ -1,5 +1,6 @@
import { __, sprintf } from '../../../Utils/i18nwrap'
import bitsFetch from '../../../Utils/bitsFetch'
+import { handleAuthData } from '../GlobalIntegrationHelper'
export const handleInput = (
e,
@@ -108,7 +109,7 @@ export const layoutChange = (recordTab, formID, crmConf, setCrmConf, setIsLoadin
newConf.upload_field_map =
newConf?.default?.layouts?.[module]?.[layout]?.requiredFileUploadFields &&
- Object.keys(newConf.default.layouts[module][layout].requiredFileUploadFields).length > 0
+ Object.keys(newConf.default.layouts[module][layout].requiredFileUploadFields).length > 0
? generateMappedField(recordTab, newConf, true)
: [{ formField: '', zohoFormField: '' }]
} else {
@@ -121,7 +122,7 @@ export const layoutChange = (recordTab, formID, crmConf, setCrmConf, setIsLoadin
newConf.relatedlists[recordTab - 1].upload_field_map =
newConf?.default?.layouts?.[module]?.[layout]?.requiredFileUploadFields &&
- Object.keys(newConf.default.layouts[module][layout].requiredFileUploadFields).length > 0
+ Object.keys(newConf.default.layouts[module][layout].requiredFileUploadFields).length > 0
? generateMappedField(recordTab, newConf, true)
: [{ formField: '', zohoFormField: '' }]
}
@@ -134,12 +135,14 @@ export const layoutChange = (recordTab, formID, crmConf, setCrmConf, setIsLoadin
export const refreshModules = (formID, crmConf, setCrmConf, setIsLoading, setSnackbar) => {
setIsLoading(true)
+
+ const isCustomAuth = !crmConf.tokenDetails?.selectedAuthType || crmConf.tokenDetails.selectedAuthType === 'Custom Authorization'
const refreshModulesRequestParams = {
formID,
id: crmConf.id,
- dataCenter: crmConf.dataCenter,
- clientId: crmConf.clientId,
- clientSecret: crmConf.clientSecret,
+ dataCenter: isCustomAuth ? crmConf.tokenDetails.dataCenter : 'com',
+ clientId: isCustomAuth ? crmConf.clientId : crmConf.oneClickAuthCredentials.clientId,
+ clientSecret: isCustomAuth ? crmConf.clientSecret : crmConf.oneClickAuthCredentials.clientSecret,
tokenDetails: crmConf.tokenDetails
}
bitsFetch(refreshModulesRequestParams, 'zcrm_refresh_modules')
@@ -190,13 +193,15 @@ export const refreshLayouts = (
if (!module) {
return
}
+
+ const isCustomAuth = !crmConf.tokenDetails?.selectedAuthType || crmConf.tokenDetails.selectedAuthType === 'Custom Authorization'
setIsLoading(true)
const refreshLayoutsRequestParams = {
formID,
module,
- dataCenter: newConf.dataCenter,
- clientId: newConf.clientId,
- clientSecret: newConf.clientSecret,
+ dataCenter: isCustomAuth ? crmConf.tokenDetails.dataCenter : 'com',
+ clientId: isCustomAuth ? crmConf.clientId : crmConf.oneClickAuthCredentials.clientId,
+ clientSecret: isCustomAuth ? crmConf.clientSecret : crmConf.oneClickAuthCredentials.clientSecret,
tokenDetails: newConf.tokenDetails
}
bitsFetch(refreshLayoutsRequestParams, 'zcrm_refresh_layouts')
@@ -261,13 +266,15 @@ export const refreshRelatedList = (formID, crmConf, setCrmConf, setIsLoading, se
if (!crmConf.module) {
return
}
+
+ const isCustomAuth = !crmConf.tokenDetails?.selectedAuthType || crmConf.tokenDetails.selectedAuthType === 'Custom Authorization'
setIsLoading(true)
const relatedListRequestParams = {
formID,
module: crmConf.module,
- dataCenter: crmConf.dataCenter,
- clientId: crmConf.clientId,
- clientSecret: crmConf.clientSecret,
+ dataCenter: isCustomAuth ? crmConf.tokenDetails.dataCenter : 'com',
+ clientId: isCustomAuth ? crmConf.clientId : crmConf.oneClickAuthCredentials.clientId,
+ clientSecret: isCustomAuth ? crmConf.clientSecret : crmConf.oneClickAuthCredentials.clientSecret,
tokenDetails: crmConf.tokenDetails
}
bitsFetch(relatedListRequestParams, 'zcrm_get_related_lists')
@@ -304,13 +311,15 @@ export const refreshRelatedList = (formID, crmConf, setCrmConf, setIsLoading, se
export const refreshTags = (recordTab, formID, crmConf, setCrmConf, setIsLoading, setSnackbar) => {
const module = recordTab === 0 ? crmConf.module : crmConf.relatedlists[recordTab - 1].module
if (!module) return
+
+ const isCustomAuth = !crmConf.tokenDetails?.selectedAuthType || crmConf.tokenDetails.selectedAuthType === 'Custom Authorization'
setIsLoading(true)
const refreshTagsParams = {
formID,
module,
- dataCenter: crmConf.dataCenter,
- clientId: crmConf.clientId,
- clientSecret: crmConf.clientSecret,
+ dataCenter: isCustomAuth ? crmConf.tokenDetails.dataCenter : 'com',
+ clientId: isCustomAuth ? crmConf.clientId : crmConf.oneClickAuthCredentials.clientId,
+ clientSecret: isCustomAuth ? crmConf.clientSecret : crmConf.oneClickAuthCredentials.clientSecret,
tokenDetails: crmConf.tokenDetails
}
bitsFetch(refreshTagsParams, 'zcrm_get_tags')
@@ -346,11 +355,13 @@ export const refreshTags = (recordTab, formID, crmConf, setCrmConf, setIsLoading
export const refreshOwners = (formID, crmConf, setCrmConf, setIsLoading, setSnackbar) => {
setIsLoading(true)
+
+ const isCustomAuth = !crmConf.tokenDetails?.selectedAuthType || crmConf.tokenDetails.selectedAuthType === 'Custom Authorization'
const getOwnersParams = {
formID,
- dataCenter: crmConf.dataCenter,
- clientId: crmConf.clientId,
- clientSecret: crmConf.clientSecret,
+ dataCenter: isCustomAuth ? crmConf.tokenDetails.dataCenter : 'com',
+ clientId: isCustomAuth ? crmConf.clientId : crmConf.oneClickAuthCredentials.clientId,
+ clientSecret: isCustomAuth ? crmConf.clientSecret : crmConf.oneClickAuthCredentials.clientSecret,
tokenDetails: crmConf.tokenDetails
}
bitsFetch(getOwnersParams, 'zcrm_get_users')
@@ -383,12 +394,14 @@ export const refreshAssigmentRules = (
) => {
const module = recordTab === 0 ? crmConf.module : crmConf.relatedlists[recordTab - 1].module
if (!module) return
+
+ const isCustomAuth = !crmConf.tokenDetails?.selectedAuthType || crmConf.tokenDetails.selectedAuthType === 'Custom Authorization'
setIsLoading(true)
const getAssigmentRulesParams = {
module,
- dataCenter: crmConf.dataCenter,
- clientId: crmConf.clientId,
- clientSecret: crmConf.clientSecret,
+ dataCenter: isCustomAuth ? crmConf.tokenDetails.dataCenter : 'com',
+ clientId: isCustomAuth ? crmConf.clientId : crmConf.oneClickAuthCredentials.clientId,
+ clientSecret: isCustomAuth ? crmConf.clientSecret : crmConf.oneClickAuthCredentials.clientSecret,
tokenDetails: crmConf.tokenDetails
}
bitsFetch(getAssigmentRulesParams, 'zcrm_get_assignment_rules')
@@ -422,39 +435,39 @@ export const generateMappedField = (recordTab, crmConf, uploadFields) => {
if (uploadFields) {
return crmConf.default.layouts[module][layout].requiredFileUploadFields.length > 0
? crmConf.default.layouts[module][layout].requiredFileUploadFields.map((field) => ({
- formField: '',
- zohoFormField: field
- }))
+ formField: '',
+ zohoFormField: field
+ }))
: [{ formField: '', zohoFormField: '' }]
}
return crmConf.default.layouts[module][layout].required.length > 0
? crmConf.default.layouts[module][layout].required.map((field) => ({
- formField: '',
- zohoFormField: field
- }))
+ formField: '',
+ zohoFormField: field
+ }))
: [{ formField: '', zohoFormField: '' }]
}
export const checkMappedFields = (crmConf) => {
const mappedFields = crmConf?.field_map
? crmConf.field_map.filter(
- (mappedField) =>
- !mappedField.formField &&
- mappedField.zohoFormField &&
- crmConf?.default?.layouts?.[crmConf.module]?.[crmConf.layout]?.required.indexOf(
- mappedField.zohoFormField
- ) !== -1
- )
+ (mappedField) =>
+ !mappedField.formField &&
+ mappedField.zohoFormField &&
+ crmConf?.default?.layouts?.[crmConf.module]?.[crmConf.layout]?.required.indexOf(
+ mappedField.zohoFormField
+ ) !== -1
+ )
: []
const mappedUploadFields = crmConf?.upload_field_map
? crmConf.upload_field_map.filter(
- (mappedField) =>
- !mappedField.formField &&
- mappedField.zohoFormField &&
- crmConf.default.layouts[crmConf.module][crmConf.layout].requiredFileUploadFields.indexOf(
- mappedField.zohoFormField
- ) !== -1
- )
+ (mappedField) =>
+ !mappedField.formField &&
+ mappedField.zohoFormField &&
+ crmConf.default.layouts[crmConf.module][crmConf.layout].requiredFileUploadFields.indexOf(
+ mappedField.zohoFormField
+ ) !== -1
+ )
: []
const mappedRelatedFields = crmConf.relatedlists.map((relatedlist) =>
relatedlist.field_map.filter(
@@ -478,3 +491,145 @@ export const checkMappedFields = (crmConf) => {
return true
}
+
+export const handleAuthorize = (
+ integ,
+ ajaxInteg,
+ selectedAuthType,
+ scopes,
+ confTmp,
+ setConf,
+ setError,
+ setisAuthorized,
+ setIsLoading,
+ setSnackbar,
+ btcbi
+) => {
+
+ let clientId = '';
+ let dataCenter = '';
+ if (selectedAuthType === 'One Click Authorization') {
+ clientId = confTmp.oneClickAuthCredentials.clientId
+ dataCenter = 'com'
+ } else if (selectedAuthType === 'Custom Authorization') {
+ if (!confTmp.clientId || !confTmp.clientSecret || !confTmp.dataCenter) {
+ setError({
+ dataCenter: !confTmp.dataCenter ? __("Data center can't be empty", 'bit-integrations') : '',
+ clientId: !confTmp.clientId ? __("Client Id can't be empty", 'bit-integrations') : '',
+ clientSecret: !confTmp.clientSecret ? __("Secret key can't be empty", 'bit-integrations') : ''
+ })
+ return
+ }
+ clientId = confTmp.clientId
+ dataCenter = confTmp.dataCenter
+ }
+
+ const redirectURI = 'https://auth-apps.bitapps.pro/redirect/v2';
+ const finalRedirectUri = selectedAuthType === 'One Click Authorization' ? redirectURI : `${btcbi.api.base}/redirect`
+
+ setIsLoading(true)
+
+
+ const { href, hash } = window.location
+ const stateUrl = hash ? href.replace(hash, '#/auth-response/') : `${href}#/auth-response/`
+ const apiEndpoint = `https://accounts.zoho.${dataCenter
+ }/oauth/v2/auth?scope=${scopes}&response_type=code&client_id=${clientId
+ }&prompt=Consent&access_type=offline&state=${encodeURIComponent(stateUrl)}/redirect&redirect_uri=${encodeURIComponent(finalRedirectUri)}`
+
+ const authWindow = window.open(apiEndpoint, integ, 'width=400,height=609,toolbar=off')
+ if (selectedAuthType === 'Custom Authorization') {
+ const popupURLCheckTimer = setInterval(() => {
+ if (authWindow.closed) {
+ clearInterval(popupURLCheckTimer)
+ setIsLoading(false)
+ }
+ }, 500)
+ }
+}
+
+
+export const tokenHelper = async (authInfo, confTmp, setConf, selectedAuthType, setAuthData, setIsLoading, setSnackbar) => {
+ if (!selectedAuthType) {
+ return;
+ }
+
+ const tokenRequestParams = {};
+ tokenRequestParams.code = authInfo.code || '';
+ const redirectURI = 'https://auth-apps.bitapps.pro/redirect/v2';
+
+ if (selectedAuthType === 'One Click Authorization') {
+ tokenRequestParams.clientId = confTmp.oneClickAuthCredentials.clientId;
+ tokenRequestParams.clientSecret = confTmp.oneClickAuthCredentials.clientSecret;
+ tokenRequestParams.dataCenter = 'com';
+ tokenRequestParams.redirectURI = redirectURI;
+ tokenRequestParams['accounts-server'] = 'https://accounts.zoho.com';
+ } else {
+ tokenRequestParams.clientId = confTmp.clientId;
+ tokenRequestParams.clientSecret = confTmp.clientSecret;
+ tokenRequestParams.dataCenter = confTmp.dataCenter;
+ tokenRequestParams.redirectURI = `${btcbi.api.base}/redirect`;
+ tokenRequestParams['accounts-server'] = authInfo['accounts-server'];
+ }
+
+ setIsLoading(true);
+ try {
+ const result = await bitsFetch(tokenRequestParams, 'zcrm_generate_token');
+
+ if (result && result.success) {
+ const userInfo = await fetchUserInfo(result.data);
+
+ if (userInfo) {
+ const newConf = { ...confTmp };
+ result.data.selectedAuthType = selectedAuthType;
+ result.data.dataCenter = selectedAuthType === 'One Click Authorization' ? 'com' : confTmp.dataCenter;
+ try {
+ await handleAuthData(newConf.type, result.data, userInfo, setAuthData);
+ newConf.setisAuthorized = true;
+ setConf(newConf);
+ setSnackbar({ show: true, msg: __('Authorized Successfully', 'bit-integrations') });
+ } catch (error) {
+ console.error('Authorization failed:', error.message);
+ setSnackbar({ show: true, msg: error.message }); // Display backend error
+ }
+ }
+ } else {
+ const errorMessage = result?.data?.error || __('Authorization failed. Please try again.', 'bit-integrations');
+ setSnackbar({ show: true, msg: `${__('Authorization failed Cause:', 'bit-integrations')} ${errorMessage}` });
+ }
+ } catch (error) {
+ console.error('Error during token generation:', error.message);
+ setSnackbar({ show: true, msg: __('An unexpected error occurred. Please try again.', 'bit-integrations') });
+ } finally {
+ setIsLoading(false);
+ }
+}
+
+
+
+async function fetchUserInfo(tokenResponse) {
+ const requestParams = {
+ code: tokenResponse.access_token
+ }
+ try {
+ const result = await bitsFetch(requestParams, 'zcrm_get_user_details');
+ if (result.data && result.success) {
+ return result.data;
+ } else if ((result && result.data && result.data.data) || (!result.success && typeof result.data === 'string')) {
+ setSnackbar({
+ show: true,
+ msg: `${__('Authorization failed Cause:', 'bit-integrations')} ${result.data.data || result.data}. ${__('Please try again', 'bit-integrations')}`
+ });
+ } else {
+ setSnackbar({
+ show: true,
+ msg: __('User Fetch Failed. Please try again', 'bit-integrations')
+ });
+ }
+ } catch (error) {
+ console.error('Error fetching user info:', error.message);
+ setSnackbar({
+ show: true,
+ msg: __('An unexpected error occurred. Please try again.', 'bit-integrations')
+ });
+ }
+}
\ No newline at end of file
diff --git a/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMInfo.jsx b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMInfo.jsx
new file mode 100644
index 000000000..8579432b7
--- /dev/null
+++ b/frontend-dev/src/components/AllIntegrations/ZohoCRM/ZohoCRMInfo.jsx
@@ -0,0 +1,53 @@
+import { useEffect, useState } from "react"
+import bitsFetch from "../../../Utils/bitsFetch";
+import { __ } from "../../../Utils/i18nwrap";
+import AuthorizationAccountList from "../../OneClickRadioComponents/AuthorizationAccountList";
+
+
+export default function ZohoCRMInfo({ crmConf, isInfo }) {
+
+ const [authData, setAuthData] = useState([])
+
+ useEffect(() => {
+ const queryParams = {
+ id: crmConf.authId
+ }
+ bitsFetch(null, 'auth/getbyId', queryParams, 'GET').then((res) => {
+ if (res.success) {
+ if (res.data.data.length > 0) {
+ setAuthData(res.data.data);
+ }
+ }
+ })
+ }, []);
+ return (
+
+ {crmConf.tokenDetails.selectedAuthType == 'Custom Authorization' && (
+
+
Account Details (Custom Authorization)
+
{__('Client id:', 'bit-integrations')}
+
+
+
{__('Client secret:', 'bit-integrations')}
+
+
+
+ )}
+ {(crmConf.tokenDetails.selectedAuthType == 'One Click Authorization' && authData.length !== 0) && (
+
+
Account Details (One Click Authorization)
+
+
+ )}
+ {(crmConf.tokenDetails.selectedAuthType == 'One Click Authorization' && authData.length === 0) && (
+
+
The Authorized Account Has been Deleted. (One Click Authorization)
+
+ )}
+
+
+ )
+}
\ No newline at end of file
diff --git a/frontend-dev/src/components/OneClickRadioComponents/AuthorizationAccountList.jsx b/frontend-dev/src/components/OneClickRadioComponents/AuthorizationAccountList.jsx
index d6e23c796..bcaba4da9 100644
--- a/frontend-dev/src/components/OneClickRadioComponents/AuthorizationAccountList.jsx
+++ b/frontend-dev/src/components/OneClickRadioComponents/AuthorizationAccountList.jsx
@@ -1,6 +1,7 @@
import React, { useState, useEffect, useRef } from 'react';
import bitsFetch from '../../Utils/bitsFetch';
import TrashIcn from '../../Icons/TrashIcn';
+import Avatar from '../../resource/img/avatar.webp'
const AuthorizationAccountList = ({ authData, setAuthData, selectedUserId, setSelectedUserId, setIsLoading, isEdit, isInfo }) => {
const [showConfirm, setShowConfirm] = useState(null);
@@ -71,7 +72,7 @@ const AuthorizationAccountList = ({ authData, setAuthData, selectedUserId, setSe
className="radio-input"
/>
-

+
{user?.userInfo?.user?.displayName}
{user?.userInfo?.user?.emailAddress}
diff --git a/frontend-dev/src/components/OneClickRadioComponents/SelectAuthorizationType.jsx b/frontend-dev/src/components/OneClickRadioComponents/SelectAuthorizationType.jsx
index f2ddc1d20..ea438a3f8 100644
--- a/frontend-dev/src/components/OneClickRadioComponents/SelectAuthorizationType.jsx
+++ b/frontend-dev/src/components/OneClickRadioComponents/SelectAuthorizationType.jsx
@@ -13,7 +13,7 @@ const SelectAuthorizationType = ({ name, options, selectedAuthType, handleChange
onClick={() => handleChange(option)}
className="radio-input"
/>
- {option}
+ {option}{option === 'One Click Authorization' ? ' (Beta )' : ' (Recomended )'}
))}
diff --git a/frontend-dev/src/pages/AuthResponse.jsx b/frontend-dev/src/pages/AuthResponse.jsx
index 89eb13d05..36f346080 100644
--- a/frontend-dev/src/pages/AuthResponse.jsx
+++ b/frontend-dev/src/pages/AuthResponse.jsx
@@ -1,23 +1,29 @@
-import { useEffect } from 'react'
-import { useSetRecoilState } from 'recoil'
-import { authInfoAtom } from '../GlobalStates'
+import { useEffect } from 'react';
+import { useSetRecoilState } from 'recoil';
+import { authInfoAtom } from '../GlobalStates';
// popup window: render when redirected from oauth to bit-integration with code
export default function AuthResponse() {
- const setAuthInfo = useSetRecoilState(authInfoAtom)
+ const setAuthInfo = useSetRecoilState(authInfoAtom);
useEffect(() => {
- const urlParams = new URLSearchParams(window.location.hash)
- const code = urlParams.get('code')
+ const searchParams = new URLSearchParams(window.location.hash.slice(1));
+ const authResponse = {};
- if (code) {
- setAuthInfo({ code: code });
+ for (const [key, value] of searchParams) {
+ if (value !== null && value.trim() !== '') {
+ authResponse[key] = value;
+ }
+ }
- setTimeout(() => {
- window.close()
- }, 100)
+ if (Object.keys(authResponse).length > 0) {
+ setAuthInfo(authResponse);
}
- }, [])
- return
Auth Response Captured
+ setTimeout(() => {
+ window.close();
+ }, 100);
+ }, []);
+
+ return
Auth Response Captured
;
}
diff --git a/frontend-dev/src/resource/img/avatar.webp b/frontend-dev/src/resource/img/avatar.webp
new file mode 100644
index 0000000000000000000000000000000000000000..6f4e2adb7be318f167c6196aa30dd95262d9896e
GIT binary patch
literal 1270
zcmWIYbaQ*h!oU#j>J$(bU=hK^z`$St#QI?5>FgYEf)U7NU_1dLS%6Zxc_l?b?oJ93
zkx>fl4;UDM5DXHNiwhtutRzs?w`&l!mvynKz%R&|l3JV$RPq6cRf>R?1KlJ7WQ(Lj
z*cu>q5`=97VwaZ`lmOKPfY?PLLC!#S3XrXlj>JwvVkZ|Afz
Z
zZ((5Ab{-*y2$O=uqC~K9z}R45N=sv4__UmXfj5$YLHGg#16MRy4oKi|n*vZu2I#JQ
zAWUb-VMt|AVDMzfV@PJu1G0>Ok!r|b28>}J24-N?>L1`1uzzeZDL2&e`MvLU@7CPu
zZ2u4&_U_#s6N&A)(jBk%zkF-|=4hje=d#e|@AtO9{T+X58*g)t^7CIT_RZlx7)tin
znc5mRXH^}#VEk{HS?j`=T$e+VC0gg*EH(MV&+@_8LgMe`+)SyNSFb3rAFdDcWTwelT&e
z_AUJ9YwhpzDE)eWVB(!^mNL#=T6sE^%^gs1rJUDyO7^O#d6KU(gapChV+Gr@kWes~
zF63^gT`d>-Oya9_<>}Nfzt=2t4K3aLq_Aw+J*73
z2w(mBM(F&+DGzOr-JT$@+UGL=AIZnb9w$T8kFp+%JmGOg=xBD&&+iTEZO(WH&CLtVvbgP*R#n}
z21H+=lUlvciFV{J*vmi>F@c5Ccd!QiZ?JmbQ#n^DD=-eoZN
zO3H*SI`S~fKY6vz&g(j#E!=r#hED%i{84%?chBTwTF)eA>8@=Jh?JDhDX(Aw0ODuF
AU;qFB
literal 0
HcmV?d00001
diff --git a/includes/Actions/Mailup/MailupController.php b/includes/Actions/Mailup/MailupController.php
index cb99aed06..39fc14045 100644
--- a/includes/Actions/Mailup/MailupController.php
+++ b/includes/Actions/Mailup/MailupController.php
@@ -62,7 +62,6 @@ public static function getAllField($requestParams)
'required' => true
]
];
- error_log(print_r($apiResponse, true));
if (!property_exists($apiResponse, 'Items')) {
wp_send_json_error('List fetching failed', 400);
diff --git a/includes/Actions/ZohoCRM/RecordApiHelper.php b/includes/Actions/ZohoCRM/RecordApiHelper.php
index 61abc42a7..b9d8eb577 100644
--- a/includes/Actions/ZohoCRM/RecordApiHelper.php
+++ b/includes/Actions/ZohoCRM/RecordApiHelper.php
@@ -6,12 +6,12 @@
namespace BitCode\FI\Actions\ZohoCRM;
-use stdClass;
-use WP_Error;
-use BitCode\FI\Log\LogHandler;
use BitCode\FI\Core\Util\Common;
-use BitCode\FI\Core\Util\HttpHelper;
use BitCode\FI\Core\Util\DateTimeHelper;
+use BitCode\FI\Core\Util\HttpHelper;
+use BitCode\FI\Log\LogHandler;
+use stdClass;
+use WP_Error;
/**
* Provide functionality for Record insert,upsert
diff --git a/includes/Actions/ZohoCRM/Routes.php b/includes/Actions/ZohoCRM/Routes.php
index 8ca7ad92b..17798bc72 100644
--- a/includes/Actions/ZohoCRM/Routes.php
+++ b/includes/Actions/ZohoCRM/Routes.php
@@ -14,6 +14,7 @@
Route::post('zcrm_generate_token', [ZohoCRMController::class, 'generateTokens']);
Route::post('zcrm_refresh_modules', [ZohoCRMController::class, 'refreshModulesAjaxHelper']);
Route::post('zcrm_refresh_layouts', [ZohoCRMController::class, 'refreshLayoutsAjaxHelper']);
+Route::post('zcrm_get_user_details', [ZohoCRMController::class, 'getUserDetails']);
// Rapidmail
// Route::post('rapidmail_authorization', [RapidmailController::class, 'checkAuthorization']);
diff --git a/includes/Actions/ZohoCRM/ZohoCRMController.php b/includes/Actions/ZohoCRM/ZohoCRMController.php
index 19f0792da..829e710c9 100644
--- a/includes/Actions/ZohoCRM/ZohoCRMController.php
+++ b/includes/Actions/ZohoCRM/ZohoCRMController.php
@@ -6,11 +6,11 @@
namespace BitCode\FI\Actions\ZohoCRM;
+use BitCode\FI\Core\Util\HttpHelper;
+use BitCode\FI\Flow\FlowController;
+use BitCode\FI\Log\LogHandler;
use stdClass;
use WP_Error;
-use BitCode\FI\Log\LogHandler;
-use BitCode\FI\Flow\FlowController;
-use BitCode\FI\Core\Util\HttpHelper;
/**
* Provide functionality for ZohoCrm integration
@@ -58,6 +58,7 @@ public static function generateTokens($requestsParams)
'code' => $requestsParams->code
];
$apiResponse = HttpHelper::post($apiEndpoint, $requestParams);
+
if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
wp_send_json_error(
empty($apiResponse->error) ? 'Unknown' : $apiResponse->error,
@@ -178,7 +179,6 @@ public static function refreshLayoutsAjaxHelper($queryParams)
$authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
$requiredParams['module'] = $queryParams->module;
$layoutsMetaResponse = HttpHelper::get($layoutsMetaApiEndpoint, $requiredParams, $authorizationHeader);
- error_log(print_r($layoutsMetaResponse, true));
if (!is_wp_error($layoutsMetaResponse) && (empty($layoutsMetaResponse->status) || (!empty($layoutsMetaResponse->status) && $layoutsMetaResponse->status !== 'error'))) {
$retriveLayoutsData = $layoutsMetaResponse->layouts;
$layouts = [];
@@ -640,6 +640,25 @@ public function execute($integrationData, $fieldValues)
return $zcrmApiResponse;
}
+ public static function getUserDetails($requestParams)
+ {
+ if (empty($requestParams->code) || $requestParams->code === null) {
+ return;
+ }
+ $apiEndpoint = 'https://www.zohoapis.com/crm/v2/users?type=AllUsers';
+ $authorizationHeader['Authorization'] = 'Bearer ' . $requestParams->code;
+ $authorizationHeader['Content-Type'] = 'application/json';
+
+ $response = HttpHelper::get($apiEndpoint, null, $authorizationHeader);
+
+ $user['user'] = [
+ 'displayName' => $response->users[0]->full_name,
+ 'emailAddress' => $response->users[0]->email,
+ ];
+
+ wp_send_json_success($user, 200);
+ }
+
/**
* Helps to refresh zoho crm access_token
*
diff --git a/includes/Flow/Flow.php b/includes/Flow/Flow.php
index 197f2a706..36b283bb6 100644
--- a/includes/Flow/Flow.php
+++ b/includes/Flow/Flow.php
@@ -2,15 +2,15 @@
namespace BitCode\FI\Flow;
-use WP_Error;
-use BitCode\FI\Log\LogHandler;
+use BitCode\FI\Core\Util\Capabilities;
use BitCode\FI\Core\Util\Common;
+use BitCode\FI\Core\Util\CustomFuncValidator;
use BitCode\FI\Core\Util\IpTool;
use BitCode\FI\Core\Util\SmartTags;
-use BitCode\FI\Core\Util\Capabilities;
use BitCode\FI\Core\Util\StoreInCache;
+use BitCode\FI\Log\LogHandler;
use BitCode\FI\Triggers\TriggerController;
-use BitCode\FI\Core\Util\CustomFuncValidator;
+use WP_Error;
/**
* Provides details of available integration and helps to
diff --git a/includes/controller/AuthDataController.php b/includes/controller/AuthDataController.php
index 107a8a460..702b781ce 100644
--- a/includes/controller/AuthDataController.php
+++ b/includes/controller/AuthDataController.php
@@ -39,7 +39,7 @@ public function saveAuthData($requestParams)
return $this->getAuthData($sanitizedActionName);
}
- wp_send_json_success(['error' => 'Email address exists.']);
+ wp_send_json_error(['error' => 'Email address already exists in the list.']);
}
public function getAuthData($request)
@@ -62,7 +62,7 @@ public function getAuthData($request)
);
if (is_wp_error($result)) {
- wp_send_json_success(['data' => []]);
+ wp_send_json_error(['data' => []]);
exit;
}