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

240
yarn.lock
View File

@ -23579,6 +23579,15 @@ __metadata:
languageName: node
linkType: hard
"@types/imapflow@npm:^1.0.21":
version: 1.0.21
resolution: "@types/imapflow@npm:1.0.21"
dependencies:
"@types/node": "npm:*"
checksum: 10c0/82b4d370ab9649b358246a85c2fac2daba19202c39defc05e580a5a96f9d4192c5302c438f147ad6ee0b7183e3460adeebfd713bbd6e1aa8e9a29bc675ccf449
languageName: node
linkType: hard
"@types/is-hotkey@npm:^0.1.1":
version: 0.1.10
resolution: "@types/is-hotkey@npm:0.1.10"
@ -23994,6 +24003,16 @@ __metadata:
languageName: node
linkType: hard
"@types/mailparser@npm:^3.4.6":
version: 3.4.6
resolution: "@types/mailparser@npm:3.4.6"
dependencies:
"@types/node": "npm:*"
iconv-lite: "npm:^0.6.3"
checksum: 10c0/5b08f226d6911daf7b8102f88eece0cd6d33a56ea339b85334bd4fdafe6b15e556c22f06a8ede5d54c8990368a93a71f5c599d7f83718f1ae9eea9420ffcd27c
languageName: node
linkType: hard
"@types/markdown-it@npm:12.2.3":
version: 12.2.3
resolution: "@types/markdown-it@npm:12.2.3"
@ -27534,6 +27553,13 @@ __metadata:
languageName: node
linkType: hard
"atomic-sleep@npm:^1.0.0":
version: 1.0.0
resolution: "atomic-sleep@npm:1.0.0"
checksum: 10c0/e329a6665512736a9bbb073e1761b4ec102f7926cce35037753146a9db9c8104f5044c1662e4a863576ce544fb8be27cd2be6bc8c1a40147d03f31eb1cfb6e8a
languageName: node
linkType: hard
"attr-accept@npm:^2.2.2":
version: 2.2.2
resolution: "attr-accept@npm:2.2.2"
@ -33666,6 +33692,13 @@ __metadata:
languageName: node
linkType: hard
"encoding-japanese@npm:2.2.0":
version: 2.2.0
resolution: "encoding-japanese@npm:2.2.0"
checksum: 10c0/9d1f10dde16f59da8a8a1a04499dffa3e9926b0dbd7dfab8054570527b7e6de30c47e828851f42d2727af31586ec8049a84eeae593ad8b22eea10921fd269798
languageName: node
linkType: hard
"encoding@npm:^0.1.12, encoding@npm:^0.1.13":
version: 0.1.13
resolution: "encoding@npm:0.1.13"
@ -35890,6 +35923,13 @@ __metadata:
languageName: node
linkType: hard
"fast-redact@npm:^3.1.1":
version: 3.5.0
resolution: "fast-redact@npm:3.5.0"
checksum: 10c0/7e2ce4aad6e7535e0775bf12bd3e4f2e53d8051d8b630e0fa9e67f68cb0b0e6070d2f7a94b1d0522ef07e32f7c7cda5755e2b677a6538f1e9070ca053c42343a
languageName: node
linkType: hard
"fast-safe-stringify@npm:2.1.1, fast-safe-stringify@npm:^2.0.7, fast-safe-stringify@npm:^2.1.1":
version: 2.1.1
resolution: "fast-safe-stringify@npm:2.1.1"
@ -38636,7 +38676,7 @@ __metadata:
languageName: node
linkType: hard
"he@npm:^1.2.0":
"he@npm:1.2.0, he@npm:^1.2.0":
version: 1.2.0
resolution: "he@npm:1.2.0"
bin:
@ -39315,6 +39355,23 @@ __metadata:
languageName: node
linkType: hard
"imapflow@npm:^1.0.186":
version: 1.0.187
resolution: "imapflow@npm:1.0.187"
dependencies:
encoding-japanese: "npm:2.2.0"
iconv-lite: "npm:0.6.3"
libbase64: "npm:1.3.0"
libmime: "npm:5.3.6"
libqp: "npm:2.1.1"
mailsplit: "npm:5.4.3"
nodemailer: "npm:7.0.3"
pino: "npm:9.7.0"
socks: "npm:2.8.4"
checksum: 10c0/e29aa43eb5bd9623892ecd23cfdf86b8e762a904488ff6af3cff5afaa3ac125c9db5538f8f052865c32c732bfe21901f38a27242f7500eb42567a29fd1ea4542
languageName: node
linkType: hard
"imask@npm:^7.6.1":
version: 7.6.1
resolution: "imask@npm:7.6.1"
@ -42707,6 +42764,25 @@ __metadata:
languageName: node
linkType: hard
"libbase64@npm:1.3.0":
version: 1.3.0
resolution: "libbase64@npm:1.3.0"
checksum: 10c0/4ece76ce09fa389d0c578c83a121c16452916521b177f50c3e8637dd9919170c96c12e1c7de63b1c88da8e5aa7e7ab574c26d18f1f64666f46b358b4b5873c8b
languageName: node
linkType: hard
"libmime@npm:5.3.6":
version: 5.3.6
resolution: "libmime@npm:5.3.6"
dependencies:
encoding-japanese: "npm:2.2.0"
iconv-lite: "npm:0.6.3"
libbase64: "npm:1.3.0"
libqp: "npm:2.1.1"
checksum: 10c0/54afa19f3500fe14b7562fd055518f1d82bf0f1076690a9b097d1a126322de7425d6d29aa9db9b51bc41b2ed16eacff65d7f30cd3622f7010f60993dfc79041e
languageName: node
linkType: hard
"libphonenumber-js@npm:^1.10.14, libphonenumber-js@npm:^1.10.26, libphonenumber-js@npm:^1.11.5":
version: 1.11.5
resolution: "libphonenumber-js@npm:1.11.5"
@ -42714,6 +42790,13 @@ __metadata:
languageName: node
linkType: hard
"libqp@npm:2.1.1":
version: 2.1.1
resolution: "libqp@npm:2.1.1"
checksum: 10c0/6e78f0676cd2424b3ddbf3273ab8539871299310dba433b7e2ec10a41830acecb4d074ea8b78b706dea349996f011ce519d92f81ede712c4824a2dd402aa376c
languageName: node
linkType: hard
"lie@npm:~3.3.0":
version: 3.3.0
resolution: "lie@npm:3.3.0"
@ -42754,7 +42837,7 @@ __metadata:
languageName: node
linkType: hard
"linkify-it@npm:^5.0.0":
"linkify-it@npm:5.0.0, linkify-it@npm:^5.0.0":
version: 5.0.0
resolution: "linkify-it@npm:5.0.0"
dependencies:
@ -43510,6 +43593,35 @@ __metadata:
languageName: node
linkType: hard
"mailparser@npm:^3.7.3":
version: 3.7.3
resolution: "mailparser@npm:3.7.3"
dependencies:
encoding-japanese: "npm:2.2.0"
he: "npm:1.2.0"
html-to-text: "npm:9.0.5"
iconv-lite: "npm:0.6.3"
libmime: "npm:5.3.6"
linkify-it: "npm:5.0.0"
mailsplit: "npm:5.4.3"
nodemailer: "npm:7.0.3"
punycode.js: "npm:2.3.1"
tlds: "npm:1.259.0"
checksum: 10c0/91724c70b87487ca7a2ae9b0a9d095fea07b67215bb1d14dc899cc67442518547b0d57de6b1fe665cee84d2692da991268a4ccf9b603a092544a55545ce9d5aa
languageName: node
linkType: hard
"mailsplit@npm:5.4.3":
version: 5.4.3
resolution: "mailsplit@npm:5.4.3"
dependencies:
libbase64: "npm:1.3.0"
libmime: "npm:5.3.6"
libqp: "npm:2.1.1"
checksum: 10c0/8b95df9f7fa6d810936f8f90163b215eb829a8a3073b9badd134f21cd73365b60c3fe9fda806ec73fd05dd580af3630922a17e2d9b029124f13df6f2a6511e01
languageName: node
linkType: hard
"make-cancellable-promise@npm:^1.3.1":
version: 1.3.2
resolution: "make-cancellable-promise@npm:1.3.2"
@ -47007,6 +47119,13 @@ __metadata:
languageName: node
linkType: hard
"nodemailer@npm:7.0.3":
version: 7.0.3
resolution: "nodemailer@npm:7.0.3"
checksum: 10c0/835492262328471b94a080cea43ea20f4232e19a915400cd71c7f4f4ab93a7d361775154eebe30a8fc40379eecf11a0bbc73e6cf4bbee9dccb6dd1cf7a1dc792
languageName: node
linkType: hard
"nodemailer@npm:^6.9.8":
version: 6.9.14
resolution: "nodemailer@npm:6.9.14"
@ -47714,6 +47833,13 @@ __metadata:
languageName: node
linkType: hard
"on-exit-leak-free@npm:^2.1.0":
version: 2.1.2
resolution: "on-exit-leak-free@npm:2.1.2"
checksum: 10c0/faea2e1c9d696ecee919026c32be8d6a633a7ac1240b3b87e944a380e8a11dc9c95c4a1f8fb0568de7ab8db3823e790f12bda45296b1d111e341aad3922a0570
languageName: node
linkType: hard
"on-finished@npm:2.4.1":
version: 2.4.1
resolution: "on-finished@npm:2.4.1"
@ -49082,6 +49208,43 @@ __metadata:
languageName: node
linkType: hard
"pino-abstract-transport@npm:^2.0.0":
version: 2.0.0
resolution: "pino-abstract-transport@npm:2.0.0"
dependencies:
split2: "npm:^4.0.0"
checksum: 10c0/02c05b8f2ffce0d7c774c8e588f61e8b77de8ccb5f8125afd4a7325c9ea0e6af7fb78168999657712ae843e4462bb70ac550dfd6284f930ee57f17f486f25a9f
languageName: node
linkType: hard
"pino-std-serializers@npm:^7.0.0":
version: 7.0.0
resolution: "pino-std-serializers@npm:7.0.0"
checksum: 10c0/73e694d542e8de94445a03a98396cf383306de41fd75ecc07085d57ed7a57896198508a0dec6eefad8d701044af21eb27253ccc352586a03cf0d4a0bd25b4133
languageName: node
linkType: hard
"pino@npm:9.7.0":
version: 9.7.0
resolution: "pino@npm:9.7.0"
dependencies:
atomic-sleep: "npm:^1.0.0"
fast-redact: "npm:^3.1.1"
on-exit-leak-free: "npm:^2.1.0"
pino-abstract-transport: "npm:^2.0.0"
pino-std-serializers: "npm:^7.0.0"
process-warning: "npm:^5.0.0"
quick-format-unescaped: "npm:^4.0.3"
real-require: "npm:^0.2.0"
safe-stable-stringify: "npm:^2.3.1"
sonic-boom: "npm:^4.0.1"
thread-stream: "npm:^3.0.0"
bin:
pino: bin.js
checksum: 10c0/c7f8a83a9a9d728b4eff6d0f4b9367f031c91bcaa5806fbf0eedcc8e77faba593d59baf11a8fba0dd1c778bb17ca7ed01418ac1df4ec129faeedd4f3ecaff66f
languageName: node
linkType: hard
"pinpoint@npm:^1.1.0":
version: 1.1.0
resolution: "pinpoint@npm:1.1.0"
@ -49780,6 +49943,13 @@ __metadata:
languageName: node
linkType: hard
"process-warning@npm:^5.0.0":
version: 5.0.0
resolution: "process-warning@npm:5.0.0"
checksum: 10c0/941f48863d368ec161e0b5890ba0c6af94170078f3d6b5e915c19b36fb59edb0dc2f8e834d25e0d375a8bf368a49d490f080508842168832b93489d17843ec29
languageName: node
linkType: hard
"process@npm:^0.11.10, process@npm:~0.11.0":
version: 0.11.10
resolution: "process@npm:0.11.10"
@ -50292,7 +50462,7 @@ __metadata:
languageName: node
linkType: hard
"punycode.js@npm:^2.3.1":
"punycode.js@npm:2.3.1, punycode.js@npm:^2.3.1":
version: 2.3.1
resolution: "punycode.js@npm:2.3.1"
checksum: 10c0/1d12c1c0e06127fa5db56bd7fdf698daf9a78104456a6b67326877afc21feaa821257b171539caedd2f0524027fa38e67b13dd094159c8d70b6d26d2bea4dfdb
@ -50444,6 +50614,13 @@ __metadata:
languageName: node
linkType: hard
"quick-format-unescaped@npm:^4.0.3":
version: 4.0.4
resolution: "quick-format-unescaped@npm:4.0.4"
checksum: 10c0/fe5acc6f775b172ca5b4373df26f7e4fd347975578199e7d74b2ae4077f0af05baa27d231de1e80e8f72d88275ccc6028568a7a8c9ee5e7368ace0e18eff93a4
languageName: node
linkType: hard
"quick-lru@npm:^5.1.1":
version: 5.1.1
resolution: "quick-lru@npm:5.1.1"
@ -51460,6 +51637,13 @@ __metadata:
languageName: node
linkType: hard
"real-require@npm:^0.2.0":
version: 0.2.0
resolution: "real-require@npm:0.2.0"
checksum: 10c0/23eea5623642f0477412ef8b91acd3969015a1501ed34992ada0e3af521d3c865bb2fe4cdbfec5fe4b505f6d1ef6a03e5c3652520837a8c3b53decff7e74b6a0
languageName: node
linkType: hard
"recast@npm:^0.23.1, recast@npm:^0.23.3":
version: 0.23.9
resolution: "recast@npm:0.23.9"
@ -53001,6 +53185,13 @@ __metadata:
languageName: node
linkType: hard
"safe-stable-stringify@npm:^2.3.1":
version: 2.5.0
resolution: "safe-stable-stringify@npm:2.5.0"
checksum: 10c0/baea14971858cadd65df23894a40588ed791769db21bafb7fd7608397dbdce9c5aac60748abae9995e0fc37e15f2061980501e012cd48859740796bea2987f49
languageName: node
linkType: hard
"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
@ -53870,6 +54061,16 @@ __metadata:
languageName: node
linkType: hard
"socks@npm:2.8.4":
version: 2.8.4
resolution: "socks@npm:2.8.4"
dependencies:
ip-address: "npm:^9.0.5"
smart-buffer: "npm:^4.2.0"
checksum: 10c0/00c3271e233ccf1fb83a3dd2060b94cc37817e0f797a93c560b9a7a86c4a0ec2961fb31263bdd24a3c28945e24868b5f063cd98744171d9e942c513454b50ae5
languageName: node
linkType: hard
"socks@npm:^2.6.2, socks@npm:^2.8.3":
version: 2.8.3
resolution: "socks@npm:2.8.3"
@ -53880,6 +54081,15 @@ __metadata:
languageName: node
linkType: hard
"sonic-boom@npm:^4.0.1":
version: 4.2.0
resolution: "sonic-boom@npm:4.2.0"
dependencies:
atomic-sleep: "npm:^1.0.0"
checksum: 10c0/ae897e6c2cd6d3cb7cdcf608bc182393b19c61c9413a85ce33ffd25891485589f39bece0db1de24381d0a38fc03d08c9862ded0c60f184f1b852f51f97af9684
languageName: node
linkType: hard
"sort-keys-length@npm:^1.0.0":
version: 1.0.1
resolution: "sort-keys-length@npm:1.0.1"
@ -54121,7 +54331,7 @@ __metadata:
languageName: node
linkType: hard
"split2@npm:^4.1.0":
"split2@npm:^4.0.0, split2@npm:^4.1.0":
version: 4.2.0
resolution: "split2@npm:4.2.0"
checksum: 10c0/b292beb8ce9215f8c642bb68be6249c5a4c7f332fc8ecadae7be5cbdf1ea95addc95f0459ef2e7ad9d45fd1064698a097e4eb211c83e772b49bc0ee423e91534
@ -55515,6 +55725,15 @@ __metadata:
languageName: node
linkType: hard
"thread-stream@npm:^3.0.0":
version: 3.1.0
resolution: "thread-stream@npm:3.1.0"
dependencies:
real-require: "npm:^0.2.0"
checksum: 10c0/c36118379940b77a6ef3e6f4d5dd31e97b8210c3f7b9a54eb8fe6358ab173f6d0acfaf69b9c3db024b948c0c5fd2a7df93e2e49151af02076b35ada3205ec9a6
languageName: node
linkType: hard
"throttle-debounce@npm:^3.0.1":
version: 3.0.1
resolution: "throttle-debounce@npm:3.0.1"
@ -55661,6 +55880,15 @@ __metadata:
languageName: node
linkType: hard
"tlds@npm:1.259.0":
version: 1.259.0
resolution: "tlds@npm:1.259.0"
bin:
tlds: bin.js
checksum: 10c0/1a22109aee9faf826f9da4cc79a7ca2c327955033ab3ad87258665e2bde4011171f536357c9f83d9450b60c87a2261ef9037c0cd8977a39c639909904d051780
languageName: node
linkType: hard
"tldts-core@npm:^6.1.86":
version: 6.1.86
resolution: "tldts-core@npm:6.1.86"
@ -56800,6 +57028,7 @@ __metadata:
"@types/file-saver": "npm:^2.0.7"
"@types/graphql-fields": "npm:^1.3.6"
"@types/graphql-upload": "npm:^8.0.12"
"@types/imapflow": "npm:^1.0.21"
"@types/js-cookie": "npm:^3.0.3"
"@types/js-levenshtein": "npm:^1.1.3"
"@types/lodash.camelcase": "npm:^4.3.7"
@ -56821,6 +57050,7 @@ __metadata:
"@types/lodash.snakecase": "npm:^4.1.7"
"@types/lodash.upperfirst": "npm:^4.3.7"
"@types/luxon": "npm:^3.3.0"
"@types/mailparser": "npm:^3.4.6"
"@types/ms": "npm:^0.7.31"
"@types/node": "npm:^22.0.0"
"@types/nodemailer": "npm:^6.4.14"
@ -56913,6 +57143,7 @@ __metadata:
hex-rgb: "npm:^5.0.0"
http-server: "npm:^14.1.1"
iframe-resizer-react: "npm:^1.1.0"
imapflow: "npm:^1.0.186"
immer: "npm:^10.0.2"
jest: "npm:29.7.0"
jest-environment-jsdom: "npm:30.0.0-beta.3"
@ -56944,6 +57175,7 @@ __metadata:
lodash.snakecase: "npm:^4.1.1"
lodash.upperfirst: "npm:^4.3.1"
luxon: "npm:^3.3.0"
mailparser: "npm:^3.7.3"
microdiff: "npm:^1.3.2"
moize: "npm:^6.1.6"
msw: "npm:^2.0.11"