Skip to content
Snippets Groups Projects
useKonnectorAuth.tsx 4.73 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bastien DUMONT's avatar
    Bastien DUMONT committed
    import * as Sentry from '@sentry/react'
    
    import { useClient } from 'cozy-client'
    
    import { useI18n } from 'cozy-ui/transpiled/react/I18n'
    
    import { FluidType } from 'enums'
    import {
      AccountEGLData,
      AccountGRDFData,
      AccountSgeData,
      FluidConnection,
      SgeStore,
    } from 'models'
    
    import { useState } from 'react'
    
    import AccountService from 'services/account.service'
    import ConnectionService from 'services/connection.service'
    
    import { updateFluidConnection } from 'store/global/global.slice'
    
    import { useAppDispatch, useAppSelector } from 'store/hooks'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import logApp from 'utils/logger'
    
    /**
     * Format local state data to a format expected by konnectors
     */
    const formatAuthData = ({
      eglAuthData,
      grdfAuthData,
      sgeAuthData,
    }: {
      eglAuthData?: AccountEGLData
      sgeAuthData?: SgeStore
      grdfAuthData?: AccountGRDFData
    }): AccountEGLData | AccountSgeData | AccountGRDFData => {
      if (eglAuthData) {
        const konnectorFields: AccountEGLData = {
          login: eglAuthData.login,
          password: eglAuthData.password,
        }
        return konnectorFields
        // TODO could be simplified with satisfies but parser error
      } else if (grdfAuthData) {
        const konnectorFields: AccountGRDFData = {
          pce: grdfAuthData.pce,
          email: grdfAuthData.email,
          lastname: grdfAuthData.lastname,
          firstname: grdfAuthData.firstname,
          postalCode: grdfAuthData.postalCode,
        }
        return konnectorFields
      } else if (sgeAuthData) {
        const konnectorFields: AccountSgeData = {
          pointId: sgeAuthData?.pdl?.toString() ?? '',
          firstname: sgeAuthData?.firstName ?? '',
          lastname: sgeAuthData?.lastName ?? '',
          address: sgeAuthData?.address ?? '',
          postalCode: sgeAuthData?.zipCode?.toString() ?? '',
          city: sgeAuthData?.city ?? '',
        }
        return konnectorFields
      } else {
        throw new Error('Expected data but got none')
      }
    }
    
    
    const useKonnectorAuth = (
    
      fluidType: FluidType,
    
      options: {
        eglAuthData?: AccountEGLData
        sgeAuthData?: SgeStore
        grdfAuthData?: AccountGRDFData
      }
    
    ): [() => Promise<null | undefined>, () => Promise<void>, string] => {
    
      const client = useClient()
    
      const { t } = useI18n()
    
      const dispatch = useAppDispatch()
    
      const { fluidStatus } = useAppSelector(state => state.ecolyo.global)
    
      const currentFluidStatus = fluidStatus[fluidType]
    
      const konnectorSlug = currentFluidStatus.connection.konnectorConfig.slug
    
      const [connectError, setConnectError] = useState<string>('')
    
    
      const connect = async () => {
        try {
    
          logApp('info', `useKonnectorAuth connect ${konnectorSlug}`)
          const connectionService = new ConnectionService(client)
          const accountAuthData = formatAuthData({
            eglAuthData: options.eglAuthData,
            grdfAuthData: options.grdfAuthData,
            sgeAuthData: options.sgeAuthData,
          })
          logApp('info', `accountAuthData ${JSON.stringify(accountAuthData)}`)
    
          const { account, trigger } = await connectionService.connectNewUser(
            konnectorSlug,
            accountAuthData
          )
    
          if (!trigger || !account) {
    
            setConnectError(t('konnector_form.error_account_creation'))
    
            return null
          }
          const updatedConnection: FluidConnection = {
    
            ...currentFluidStatus.connection,
    
            account: account,
            trigger: trigger,
    
            shouldLaunchKonnector: true,
    
          dispatch(
            updateFluidConnection({
    
              fluidType: currentFluidStatus.fluidType,
    
              fluidConnection: updatedConnection,
            })
          )
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
        } catch (error) {
          logApp.error(error)
    
          Sentry.captureException(error)
    
        }
      }
    
      const update = async () => {
    
        try {
          logApp('info', `useKonnectorAuth update ${konnectorSlug}`)
          if (currentFluidStatus.connection.account) {
            const accountAuthData = formatAuthData({
              eglAuthData: options.eglAuthData,
              grdfAuthData: options.grdfAuthData,
              sgeAuthData: options.sgeAuthData,
    
            logApp('info', `accountAuthData ${JSON.stringify(accountAuthData)}`)
    
            const newAccount = structuredClone(
              currentFluidStatus.connection.account
            )
            newAccount.auth = accountAuthData
            const accountService = new AccountService(client)
            const updatedAccount = await accountService.updateAccount(newAccount)
            const updatedConnection: FluidConnection = {
              ...currentFluidStatus.connection,
              account: updatedAccount,
              shouldLaunchKonnector: true,
            }
            dispatch(
              updateFluidConnection({
                fluidType: currentFluidStatus.fluidType,
                fluidConnection: updatedConnection,
              })
            )
          }
        } catch (error) {
          logApp.error(error)
          Sentry.captureException(error)
    
      return [connect, update, connectError]
    
    }
    
    export default useKonnectorAuth