feat: IMAP Driver Integration (#12576)

### Added IMAP integration 

This PR adds support for connecting email accounts via IMAP protocol,
allowing users to sync their emails without OAuth.

#### DB Changes:
- Added customConnectionParams and connectionType fields to
ConnectedAccountWorkspaceEntity

#### UI:
- Added settings pages for creating and editing IMAP connections with
proper validation and connection testing.
- Implemented reconnection flows for handling permission issues.

#### Backend:
- Built ImapConnectionModule with corresponding resolver and service for
managing IMAP connections.
- Created MessagingIMAPDriverModule to handle IMAP client operations,
message fetching/parsing, and error handling.

#### Dependencies:
Integrated `imapflow` and `mailparser` libraries with their type
definitions to handle the IMAP protocol communication.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
neo773
2025-06-30 01:02:15 +05:30
committed by GitHub
parent 3c5595e4ff
commit 7c8d362772
80 changed files with 3588 additions and 113 deletions

View File

@ -1,7 +1,7 @@
import { InformationBanner } from '@/information-banner/components/InformationBanner';
import { useAccountToReconnect } from '@/information-banner/hooks/useAccountToReconnect';
import { InformationBannerKeys } from '@/information-banner/types/InformationBannerKeys';
import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth';
import { useTriggerProviderReconnect } from '@/settings/accounts/hooks/useTriggerProviderReconnect';
import { IconRefresh } from 'twenty-ui/display';
export const InformationBannerReconnectAccountEmailAliases = () => {
@ -9,7 +9,7 @@ export const InformationBannerReconnectAccountEmailAliases = () => {
InformationBannerKeys.ACCOUNTS_TO_RECONNECT_EMAIL_ALIASES,
);
const { triggerApisOAuth } = useTriggerApisOAuth();
const { triggerProviderReconnect } = useTriggerProviderReconnect();
if (!accountToReconnect) {
return null;
@ -17,10 +17,15 @@ export const InformationBannerReconnectAccountEmailAliases = () => {
return (
<InformationBanner
message={`Please reconnect your mailbox ${accountToReconnect?.handle} to update your email aliases:`}
message={`Please reconnect your mailbox ${accountToReconnect.handle} to update your email aliases:`}
buttonTitle="Reconnect"
buttonIcon={IconRefresh}
buttonOnClick={() => triggerApisOAuth(accountToReconnect.provider)}
buttonOnClick={() =>
triggerProviderReconnect(
accountToReconnect.provider,
accountToReconnect.id,
)
}
/>
);
};

View File

@ -1,7 +1,7 @@
import { InformationBanner } from '@/information-banner/components/InformationBanner';
import { useAccountToReconnect } from '@/information-banner/hooks/useAccountToReconnect';
import { InformationBannerKeys } from '@/information-banner/types/InformationBannerKeys';
import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth';
import { useTriggerProviderReconnect } from '@/settings/accounts/hooks/useTriggerProviderReconnect';
import { IconRefresh } from 'twenty-ui/display';
export const InformationBannerReconnectAccountInsufficientPermissions = () => {
@ -9,7 +9,7 @@ export const InformationBannerReconnectAccountInsufficientPermissions = () => {
InformationBannerKeys.ACCOUNTS_TO_RECONNECT_INSUFFICIENT_PERMISSIONS,
);
const { triggerApisOAuth } = useTriggerApisOAuth();
const { triggerProviderReconnect } = useTriggerProviderReconnect();
if (!accountToReconnect) {
return null;
@ -17,11 +17,16 @@ export const InformationBannerReconnectAccountInsufficientPermissions = () => {
return (
<InformationBanner
message={`Sync lost with mailbox ${accountToReconnect?.handle}. Please
message={`Sync lost with mailbox ${accountToReconnect.handle}. Please
reconnect for updates:`}
buttonTitle="Reconnect"
buttonIcon={IconRefresh}
buttonOnClick={() => triggerApisOAuth(accountToReconnect.provider)}
buttonOnClick={() =>
triggerProviderReconnect(
accountToReconnect.provider,
accountToReconnect.id,
)
}
/>
);
};