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

@ -30,6 +30,10 @@ export type Scalars = {
Upload: { input: any; output: any; }
};
export type AccountType = {
type: Scalars['String']['input'];
};
export type ActivateWorkspaceInput = {
displayName?: InputMaybe<Scalars['String']['input']>;
};
@ -412,6 +416,32 @@ export type ConfigVariablesOutput = {
groups: Array<ConfigVariablesGroupData>;
};
export type ConnectedImapSmtpCaldavAccount = {
__typename?: 'ConnectedImapSmtpCaldavAccount';
accountOwnerId: Scalars['String']['output'];
connectionParameters?: Maybe<ImapSmtpCaldavConnectionParameters>;
handle: Scalars['String']['output'];
id: Scalars['String']['output'];
provider: Scalars['String']['output'];
};
export type ConnectionParameters = {
host: Scalars['String']['input'];
password: Scalars['String']['input'];
port: Scalars['Float']['input'];
secure?: InputMaybe<Scalars['Boolean']['input']>;
username: Scalars['String']['input'];
};
export type ConnectionParametersOutput = {
__typename?: 'ConnectionParametersOutput';
host: Scalars['String']['output'];
password: Scalars['String']['output'];
port: Scalars['Float']['output'];
secure?: Maybe<Scalars['Boolean']['output']>;
username: Scalars['String']['output'];
};
export type CreateAgentInput = {
description?: InputMaybe<Scalars['String']['input']>;
modelId: Scalars['String']['input'];
@ -662,6 +692,7 @@ export type FeatureFlagDto = {
export enum FeatureFlagKey {
IS_AIRTABLE_INTEGRATION_ENABLED = 'IS_AIRTABLE_INTEGRATION_ENABLED',
IS_AI_ENABLED = 'IS_AI_ENABLED',
IS_IMAP_ENABLED = 'IS_IMAP_ENABLED',
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
@ -819,6 +850,18 @@ export enum IdentityProviderType {
SAML = 'SAML'
}
export type ImapSmtpCaldavConnectionParameters = {
__typename?: 'ImapSmtpCaldavConnectionParameters';
CALDAV?: Maybe<ConnectionParametersOutput>;
IMAP?: Maybe<ConnectionParametersOutput>;
SMTP?: Maybe<ConnectionParametersOutput>;
};
export type ImapSmtpCaldavConnectionSuccess = {
__typename?: 'ImapSmtpCaldavConnectionSuccess';
success: Scalars['Boolean']['output'];
};
export type ImpersonateOutput = {
__typename?: 'ImpersonateOutput';
loginToken: AuthToken;
@ -1010,6 +1053,7 @@ export type Mutation = {
resendEmailVerificationToken: ResendEmailVerificationTokenOutput;
resendWorkspaceInvitation: SendInvitationsOutput;
runWorkflowVersion: WorkflowRun;
saveImapSmtpCaldav: ImapSmtpCaldavConnectionSuccess;
sendInvitations: SendInvitationsOutput;
signIn: AvailableWorkspacesAndAccessTokensOutput;
signUp: AvailableWorkspacesAndAccessTokensOutput;
@ -1294,6 +1338,15 @@ export type MutationRunWorkflowVersionArgs = {
};
export type MutationSaveImapSmtpCaldavArgs = {
accountOwnerId: Scalars['String']['input'];
accountType: AccountType;
connectionParameters: ConnectionParameters;
handle: Scalars['String']['input'];
id?: InputMaybe<Scalars['String']['input']>;
};
export type MutationSendInvitationsArgs = {
emails: Array<Scalars['String']['input']>;
};
@ -1696,6 +1749,7 @@ export type Query = {
getApprovedAccessDomains: Array<ApprovedAccessDomain>;
getAvailablePackages: Scalars['JSON']['output'];
getConfigVariablesGrouped: ConfigVariablesOutput;
getConnectedImapSmtpCaldavAccount: ConnectedImapSmtpCaldavAccount;
getDatabaseConfigVariable: ConfigVariable;
getIndicatorHealthStatus: AdminPanelHealthServiceData;
getMeteredProductsUsage: Array<BillingMeteredProductUsageOutput>;
@ -1783,6 +1837,11 @@ export type QueryGetAvailablePackagesArgs = {
};
export type QueryGetConnectedImapSmtpCaldavAccountArgs = {
id: Scalars['String']['input'];
};
export type QueryGetDatabaseConfigVariableArgs = {
key: Scalars['String']['input'];
};