import React, { useEffect, useState } from 'react'; import useRouter from '@/_hooks/use-router'; import { aiOnboardingService, appService, authenticationService } from '@/_services'; import { Navigate } from 'react-router-dom'; import Configs from './Configs/Config.json'; import { getCookie } from '@/_helpers'; import { TJLoader } from '@/_ui/TJLoader/TJLoader'; import { onInvitedUserSignUpSuccess, onLoginSuccess } from '@/_helpers/platform/utils/auth.utils'; import { updateCurrentSession } from '@/_helpers/authorizeWorkspace'; import posthogHelper from '@/modules/common/helpers/posthogHelper'; import { fetchEdition } from '@/modules/common/helpers/utils'; export function Authorize({ navigate }) { const [error, setError] = useState(''); const [inviteeEmail, setInviteeEmail] = useState(); const router = useRouter(); const organizationId = authenticationService.getLoginOrganizationId(); const organizationSlug = authenticationService.getLoginOrganizationSlug(); const redirectUrl = getCookie('redirectPath'); const signupOrganizationSlug = authenticationService.getSignupOrganizationSlug(); const inviteFlowIdentifier = authenticationService.getInviteFlowIndetifier(); useEffect(() => { const errorMessage = router.query.error_description || router.query.error; if (errorMessage) { return setError(errorMessage); } if (!(router.query.origin && Configs[router.query.origin])) { return setError('Login failed'); } const configs = Configs[router.query.origin]; const authParams = {}; if (configs.responseType === 'hash') { if (!window.location.hash) { return setError('Login failed'); } const params = new Proxy(new URLSearchParams(window.location.hash.substr(1)), { get: (searchParams, prop) => searchParams.get(prop), }); authParams.token = params[configs.params.token]; authParams.state = params[configs.params.state]; } else { authParams.token = router.query[configs.params.token]; authParams.state = router.query[configs.params.state]; authParams.iss = router.query[configs.params.iss]; } /* If the params has SAMLResponse the SAML auth is success */ if (router.query.saml_response_id) { authParams.samlResponseId = router.query.saml_response_id; } let subsciption; if (organizationId) { subsciption = authenticationService.currentSession.subscribe((session) => { //logged users should send tj-workspace-id when login to unauthorized workspace if (session.authentication_status === false || session.current_organization_id) { signIn(authParams, configs); subsciption.unsubscribe(); } }); } else { signIn(authParams, configs); } // Disabled for useEffect not being called for updation // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const signIn = (authParams, configs) => { const handleAuthResponse = ({ redirect_url, ...restResponse }) => { const { organization_id, current_organization_id, email } = restResponse; const event = `${redirect_url ? 'signup' : 'signin'}_${ router.query.origin === 'google' ? 'google' : router.query.origin === 'openid' ? 'openid' : 'github' }`; posthogHelper.initPosthog(restResponse); posthogHelper.captureEvent(event, { email, workspace_id: organization_id || current_organization_id, }); /* Precaution code to not take any previous values since there are two entry point to the app now (site and tooljet-app) */ authenticationService.deleteAllSSOCookies(); if (redirect_url) { localStorage.setItem('ph-sso-type', router.query.origin); //for posthog event window.location.href = redirect_url; return; } if (restResponse?.organizationInviteUrl) onInvitedUserSignUpSuccess(restResponse, navigate); else { updateCurrentSession({ isUserLoggingIn: true, }); onLoginSuccess(restResponse, navigate); } posthogHelper.initPosthog({ redirect_url, ...restResponse }); posthogHelper.captureEvent(event, { email, workspace_id: organization_id || current_organization_id, }); }; const handleAuthError = (err) => { console.log('SSO login error', err); const details = err?.data?.message; const inviteeEmail = details?.inviteeEmail; if (inviteeEmail) setInviteeEmail(inviteeEmail); let errorMessage = ''; if (details?.error && details?.data) { errorMessage = `${details.error} ${details.data.join(', ')}`; } const errMessage = errorMessage || details?.error || details?.message || err?.error || 'something went wrong'; if (!inviteeEmail && inviteFlowIdentifier) { /* Some unexpected error happened from the provider side. Need to retreive email to continue */ appService .getInviteeDetails(inviteFlowIdentifier) .then((response) => { setInviteeEmail(response.email); }) .catch(() => { console.error('Error while fetching invitee details'); }) .finally(() => { setError(`${configs.name} login failed - ${errMessage}`); }); } else { setError(`${configs.name} login failed - ${errMessage}`); } }; const hashParams = new URLSearchParams(window.location.hash.substring(1)); // FIXME: later create different component/login for cloud and ce/ee const edition = fetchEdition(); if (edition === 'cloud') { const isAiOnboarding = hashParams.get('state')?.includes('tj_api_source=ai_onboarding') || router.query.state?.includes('tj_api_source=ai_onboarding'); const isNormalFlow = (organizationId || signupOrganizationSlug || inviteFlowIdentifier) && !isAiOnboarding; if (isNormalFlow) { /* For workspace signup and signin */ authenticationService .signInViaOAuth(router.query.configId, router.query.origin, authParams) .then(handleAuthResponse) .catch(handleAuthError); } else { /* For ai onboarding */ aiOnboardingService .signInViaOAuth(router.query.origin, authParams) .then(handleAuthResponse) .catch(handleAuthError); } return; } else { authenticationService .signInViaOAuth(router.query.configId, router.query.origin, authParams) .then(handleAuthResponse) .catch(handleAuthError); } }; const baseRoute = signupOrganizationSlug ? '/signup' : '/login'; const slug = signupOrganizationSlug ? signupOrganizationSlug : organizationSlug; const errorURL = `${baseRoute}${error && slug ? `/${slug}` : '/'}${ !signupOrganizationSlug && redirectUrl ? `?redirectTo=${redirectUrl}` : '' }`; return (
{error && ( )}
); }