imapkit 4.0.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (485) hide show
  1. package/README.md +32 -19
  2. package/bin/imapkit.js +12 -16
  3. package/dist/cjs/addressparser.d.ts +21 -0
  4. package/dist/cjs/addressparser.js +277 -0
  5. package/dist/cjs/arguments.d.ts +31 -0
  6. package/{lib → dist/cjs}/arguments.js +9 -21
  7. package/dist/cjs/bodystructure.d.ts +25 -0
  8. package/dist/cjs/bodystructure.js +150 -0
  9. package/dist/cjs/cert.d.ts +2 -0
  10. package/dist/cjs/cert.js +7 -0
  11. package/dist/cjs/command-states.d.ts +36 -0
  12. package/dist/cjs/command-states.js +102 -0
  13. package/dist/cjs/commands/append.d.ts +88 -0
  14. package/dist/cjs/commands/append.js +299 -0
  15. package/dist/cjs/commands/capability.d.ts +2 -0
  16. package/dist/cjs/commands/capability.js +44 -0
  17. package/dist/cjs/commands/check.d.ts +2 -0
  18. package/dist/cjs/commands/check.js +28 -0
  19. package/dist/cjs/commands/close.d.ts +2 -0
  20. package/dist/cjs/commands/close.js +35 -0
  21. package/dist/cjs/commands/copy.d.ts +30 -0
  22. package/dist/cjs/commands/copy.js +107 -0
  23. package/dist/cjs/commands/create.d.ts +2 -0
  24. package/dist/cjs/commands/create.js +53 -0
  25. package/dist/cjs/commands/delete.d.ts +2 -0
  26. package/dist/cjs/commands/delete.js +63 -0
  27. package/dist/cjs/commands/examine.d.ts +2 -0
  28. package/dist/cjs/commands/examine.js +19 -0
  29. package/dist/cjs/commands/expunge.d.ts +2 -0
  30. package/dist/cjs/commands/expunge.js +32 -0
  31. package/dist/cjs/commands/fetch.d.ts +23 -0
  32. package/dist/cjs/commands/fetch.js +208 -0
  33. package/dist/cjs/commands/handlers/fetch.d.ts +12 -0
  34. package/dist/cjs/commands/handlers/fetch.js +195 -0
  35. package/dist/cjs/commands/handlers/flags.d.ts +17 -0
  36. package/dist/cjs/commands/handlers/flags.js +39 -0
  37. package/dist/cjs/commands/handlers/search.d.ts +85 -0
  38. package/dist/cjs/commands/handlers/search.js +504 -0
  39. package/dist/cjs/commands/handlers/status.d.ts +34 -0
  40. package/dist/cjs/commands/handlers/status.js +81 -0
  41. package/dist/cjs/commands/handlers/store.d.ts +3 -0
  42. package/dist/cjs/commands/handlers/store.js +117 -0
  43. package/dist/cjs/commands/index.d.ts +2 -0
  44. package/dist/cjs/commands/index.js +61 -0
  45. package/dist/cjs/commands/list.d.ts +2 -0
  46. package/dist/cjs/commands/list.js +86 -0
  47. package/dist/cjs/commands/login.d.ts +2 -0
  48. package/dist/cjs/commands/login.js +62 -0
  49. package/dist/cjs/commands/logout.d.ts +2 -0
  50. package/dist/cjs/commands/logout.js +40 -0
  51. package/dist/cjs/commands/lsub.d.ts +2 -0
  52. package/dist/cjs/commands/lsub.js +79 -0
  53. package/dist/cjs/commands/noop.d.ts +2 -0
  54. package/dist/cjs/commands/noop.js +28 -0
  55. package/dist/cjs/commands/rename.d.ts +2 -0
  56. package/dist/cjs/commands/rename.js +98 -0
  57. package/dist/cjs/commands/search.d.ts +10 -0
  58. package/dist/cjs/commands/search.js +71 -0
  59. package/dist/cjs/commands/select.d.ts +19 -0
  60. package/dist/cjs/commands/select.js +230 -0
  61. package/dist/cjs/commands/status.d.ts +2 -0
  62. package/dist/cjs/commands/status.js +57 -0
  63. package/dist/cjs/commands/store.d.ts +10 -0
  64. package/dist/cjs/commands/store.js +134 -0
  65. package/dist/cjs/commands/subscribe.d.ts +2 -0
  66. package/dist/cjs/commands/subscribe.js +51 -0
  67. package/dist/cjs/commands/uid-copy.d.ts +2 -0
  68. package/dist/cjs/commands/uid-copy.js +19 -0
  69. package/dist/cjs/commands/uid-fetch.d.ts +3 -0
  70. package/dist/cjs/commands/uid-fetch.js +17 -0
  71. package/dist/cjs/commands/uid-search.d.ts +3 -0
  72. package/dist/cjs/commands/uid-search.js +17 -0
  73. package/dist/cjs/commands/uid-store.d.ts +3 -0
  74. package/dist/cjs/commands/uid-store.js +17 -0
  75. package/dist/cjs/commands/unsubscribe.d.ts +2 -0
  76. package/dist/cjs/commands/unsubscribe.js +50 -0
  77. package/dist/cjs/dates.d.ts +64 -0
  78. package/dist/cjs/dates.js +124 -0
  79. package/dist/cjs/deflate-layer.d.ts +83 -0
  80. package/dist/cjs/deflate-layer.js +232 -0
  81. package/dist/cjs/encoded-words.d.ts +15 -0
  82. package/dist/cjs/encoded-words.js +85 -0
  83. package/dist/cjs/envelope.d.ts +33 -0
  84. package/dist/cjs/envelope.js +86 -0
  85. package/dist/cjs/esearch.d.ts +96 -0
  86. package/dist/cjs/esearch.js +190 -0
  87. package/dist/cjs/framing.d.ts +66 -0
  88. package/{lib → dist/cjs}/framing.js +9 -26
  89. package/dist/cjs/index.d.ts +9 -0
  90. package/dist/cjs/index.js +56 -0
  91. package/dist/cjs/list-extensions.d.ts +50 -0
  92. package/dist/cjs/list-extensions.js +35 -0
  93. package/dist/cjs/load-plugins.d.ts +21 -0
  94. package/dist/cjs/load-plugins.js +89 -0
  95. package/dist/cjs/mailbox-name.d.ts +26 -0
  96. package/dist/cjs/mailbox-name.js +127 -0
  97. package/dist/cjs/mimeparser.d.ts +137 -0
  98. package/dist/cjs/mimeparser.js +727 -0
  99. package/dist/cjs/mock-client.d.ts +39 -0
  100. package/dist/cjs/mock-client.js +236 -0
  101. package/dist/cjs/numbers.d.ts +28 -0
  102. package/dist/cjs/numbers.js +52 -0
  103. package/dist/cjs/package.json +3 -0
  104. package/dist/cjs/plugins/acl.d.ts +2 -0
  105. package/dist/cjs/plugins/acl.js +888 -0
  106. package/dist/cjs/plugins/appendlimit.d.ts +16 -0
  107. package/dist/cjs/plugins/appendlimit.js +87 -0
  108. package/dist/cjs/plugins/auth-plain.d.ts +2 -0
  109. package/dist/cjs/plugins/auth-plain.js +89 -0
  110. package/dist/cjs/plugins/binary.d.ts +30 -0
  111. package/dist/cjs/plugins/binary.js +247 -0
  112. package/dist/cjs/plugins/catenate.d.ts +14 -0
  113. package/dist/cjs/plugins/catenate.js +250 -0
  114. package/dist/cjs/plugins/compress.d.ts +7 -0
  115. package/dist/cjs/plugins/compress.js +79 -0
  116. package/dist/cjs/plugins/condstore.d.ts +5 -0
  117. package/dist/cjs/plugins/condstore.js +492 -0
  118. package/dist/cjs/plugins/context-search.d.ts +8 -0
  119. package/dist/cjs/plugins/context-search.js +304 -0
  120. package/dist/cjs/plugins/context-sort.d.ts +6 -0
  121. package/dist/cjs/plugins/context-sort.js +32 -0
  122. package/dist/cjs/plugins/create-special-use.d.ts +7 -0
  123. package/dist/cjs/plugins/create-special-use.js +101 -0
  124. package/dist/cjs/plugins/enable.d.ts +23 -0
  125. package/dist/cjs/plugins/enable.js +127 -0
  126. package/dist/cjs/plugins/esearch.d.ts +6 -0
  127. package/dist/cjs/plugins/esearch.js +142 -0
  128. package/dist/cjs/plugins/esort.d.ts +6 -0
  129. package/dist/cjs/plugins/esort.js +60 -0
  130. package/dist/cjs/plugins/id.d.ts +5 -0
  131. package/dist/cjs/plugins/id.js +123 -0
  132. package/dist/cjs/plugins/idle.d.ts +5 -0
  133. package/dist/cjs/plugins/idle.js +85 -0
  134. package/dist/cjs/plugins/imap4rev2.d.ts +6 -0
  135. package/dist/cjs/plugins/imap4rev2.js +184 -0
  136. package/dist/cjs/plugins/index.d.ts +2 -0
  137. package/dist/cjs/plugins/index.js +119 -0
  138. package/dist/cjs/plugins/list-extended.d.ts +2 -0
  139. package/dist/cjs/plugins/list-extended.js +235 -0
  140. package/dist/cjs/plugins/list-status.d.ts +6 -0
  141. package/dist/cjs/plugins/list-status.js +42 -0
  142. package/dist/cjs/plugins/literalminus.d.ts +8 -0
  143. package/dist/cjs/plugins/literalminus.js +32 -0
  144. package/dist/cjs/plugins/literalplus.d.ts +6 -0
  145. package/dist/cjs/plugins/literalplus.js +30 -0
  146. package/dist/cjs/plugins/logindisabled.d.ts +5 -0
  147. package/dist/cjs/plugins/logindisabled.js +54 -0
  148. package/dist/cjs/plugins/messagelimit.d.ts +19 -0
  149. package/dist/cjs/plugins/messagelimit.js +227 -0
  150. package/dist/cjs/plugins/metadata-server.d.ts +7 -0
  151. package/dist/cjs/plugins/metadata-server.js +24 -0
  152. package/dist/cjs/plugins/metadata.d.ts +11 -0
  153. package/dist/cjs/plugins/metadata.js +436 -0
  154. package/dist/cjs/plugins/move.d.ts +11 -0
  155. package/dist/cjs/plugins/move.js +96 -0
  156. package/dist/cjs/plugins/multiappend.d.ts +12 -0
  157. package/dist/cjs/plugins/multiappend.js +38 -0
  158. package/dist/cjs/plugins/multisearch.d.ts +6 -0
  159. package/dist/cjs/plugins/multisearch.js +263 -0
  160. package/dist/cjs/plugins/namespace.d.ts +5 -0
  161. package/dist/cjs/plugins/namespace.js +57 -0
  162. package/dist/cjs/plugins/notify.d.ts +2 -0
  163. package/dist/cjs/plugins/notify.js +628 -0
  164. package/dist/cjs/plugins/oauthbearer.d.ts +32 -0
  165. package/dist/cjs/plugins/oauthbearer.js +202 -0
  166. package/dist/cjs/plugins/objectid.d.ts +23 -0
  167. package/dist/cjs/plugins/objectid.js +221 -0
  168. package/dist/cjs/plugins/partial.d.ts +6 -0
  169. package/dist/cjs/plugins/partial.js +78 -0
  170. package/dist/cjs/plugins/preview.d.ts +31 -0
  171. package/dist/cjs/plugins/preview.js +378 -0
  172. package/dist/cjs/plugins/qresync.d.ts +11 -0
  173. package/dist/cjs/plugins/qresync.js +473 -0
  174. package/dist/cjs/plugins/quota.d.ts +18 -0
  175. package/dist/cjs/plugins/quota.js +254 -0
  176. package/dist/cjs/plugins/replace.d.ts +14 -0
  177. package/dist/cjs/plugins/replace.js +130 -0
  178. package/dist/cjs/plugins/sasl-ir.d.ts +5 -0
  179. package/dist/cjs/plugins/sasl-ir.js +24 -0
  180. package/dist/cjs/plugins/savedate.d.ts +17 -0
  181. package/dist/cjs/plugins/savedate.js +64 -0
  182. package/dist/cjs/plugins/savelimit.d.ts +10 -0
  183. package/dist/cjs/plugins/savelimit.js +30 -0
  184. package/dist/cjs/plugins/searchres.d.ts +6 -0
  185. package/dist/cjs/plugins/searchres.js +91 -0
  186. package/dist/cjs/plugins/sort-display.d.ts +11 -0
  187. package/dist/cjs/plugins/sort-display.js +37 -0
  188. package/dist/cjs/plugins/sort.d.ts +11 -0
  189. package/dist/cjs/plugins/sort.js +125 -0
  190. package/dist/cjs/plugins/special-use.d.ts +10 -0
  191. package/dist/cjs/plugins/special-use.js +95 -0
  192. package/dist/cjs/plugins/starttls.d.ts +5 -0
  193. package/dist/cjs/plugins/starttls.js +55 -0
  194. package/dist/cjs/plugins/status-size.d.ts +7 -0
  195. package/dist/cjs/plugins/status-size.js +30 -0
  196. package/dist/cjs/plugins/thread-orderedsubject.d.ts +11 -0
  197. package/dist/cjs/plugins/thread-orderedsubject.js +28 -0
  198. package/dist/cjs/plugins/thread-references.d.ts +11 -0
  199. package/dist/cjs/plugins/thread-references.js +28 -0
  200. package/dist/cjs/plugins/uidonly.d.ts +15 -0
  201. package/dist/cjs/plugins/uidonly.js +126 -0
  202. package/dist/cjs/plugins/uidplus.d.ts +15 -0
  203. package/dist/cjs/plugins/uidplus.js +119 -0
  204. package/dist/cjs/plugins/unauthenticate.d.ts +7 -0
  205. package/dist/cjs/plugins/unauthenticate.js +32 -0
  206. package/dist/cjs/plugins/unselect.d.ts +5 -0
  207. package/dist/cjs/plugins/unselect.js +36 -0
  208. package/dist/cjs/plugins/utf8-accept.d.ts +6 -0
  209. package/dist/cjs/plugins/utf8-accept.js +72 -0
  210. package/dist/cjs/plugins/x-gm-ext-1.d.ts +26 -0
  211. package/dist/cjs/plugins/x-gm-ext-1.js +422 -0
  212. package/dist/cjs/plugins/xoauth2.d.ts +2 -0
  213. package/dist/cjs/plugins/xoauth2.js +155 -0
  214. package/dist/cjs/plugins/xtoybird.d.ts +2 -0
  215. package/dist/cjs/plugins/xtoybird.js +236 -0
  216. package/dist/cjs/server.d.ts +876 -0
  217. package/dist/cjs/server.js +2597 -0
  218. package/dist/cjs/smtp-listener.d.ts +13 -0
  219. package/dist/cjs/smtp-listener.js +47 -0
  220. package/dist/cjs/sorting.d.ts +77 -0
  221. package/dist/cjs/sorting.js +290 -0
  222. package/dist/cjs/threading.d.ts +30 -0
  223. package/dist/cjs/threading.js +318 -0
  224. package/dist/cjs/types.d.ts +327 -0
  225. package/dist/cjs/types.js +3 -0
  226. package/dist/cjs/utf8-session.d.ts +17 -0
  227. package/dist/cjs/utf8-session.js +148 -0
  228. package/dist/cjs/vanished.d.ts +21 -0
  229. package/dist/cjs/vanished.js +55 -0
  230. package/dist/esm/addressparser.d.ts +21 -0
  231. package/{lib → dist/esm}/addressparser.js +102 -123
  232. package/dist/esm/arguments.d.ts +31 -0
  233. package/dist/esm/arguments.js +96 -0
  234. package/dist/esm/bodystructure.d.ts +25 -0
  235. package/{lib → dist/esm}/bodystructure.js +17 -33
  236. package/dist/esm/cert.d.ts +2 -0
  237. package/dist/esm/cert.js +4 -0
  238. package/dist/esm/command-states.d.ts +36 -0
  239. package/{lib → dist/esm}/command-states.js +4 -16
  240. package/dist/esm/commands/append.d.ts +88 -0
  241. package/{lib → dist/esm}/commands/append.js +47 -85
  242. package/dist/esm/commands/capability.d.ts +2 -0
  243. package/dist/esm/commands/capability.js +29 -0
  244. package/dist/esm/commands/check.d.ts +2 -0
  245. package/dist/esm/commands/check.js +13 -0
  246. package/dist/esm/commands/close.d.ts +2 -0
  247. package/dist/esm/commands/close.js +20 -0
  248. package/dist/esm/commands/copy.d.ts +30 -0
  249. package/{lib → dist/esm}/commands/copy.js +31 -55
  250. package/dist/esm/commands/create.d.ts +2 -0
  251. package/{lib → dist/esm}/commands/create.js +25 -39
  252. package/dist/esm/commands/delete.d.ts +2 -0
  253. package/{lib → dist/esm}/commands/delete.js +25 -41
  254. package/dist/esm/commands/examine.d.ts +2 -0
  255. package/dist/esm/commands/examine.js +4 -0
  256. package/dist/esm/commands/expunge.d.ts +2 -0
  257. package/dist/esm/commands/expunge.js +17 -0
  258. package/dist/esm/commands/fetch.d.ts +23 -0
  259. package/{lib → dist/esm}/commands/fetch.js +33 -74
  260. package/dist/esm/commands/handlers/fetch.d.ts +12 -0
  261. package/{lib → dist/esm}/commands/handlers/fetch.js +11 -42
  262. package/dist/esm/commands/handlers/flags.d.ts +17 -0
  263. package/{lib → dist/esm}/commands/handlers/flags.js +3 -11
  264. package/dist/esm/commands/handlers/search.d.ts +85 -0
  265. package/{lib → dist/esm}/commands/handlers/search.js +33 -71
  266. package/dist/esm/commands/handlers/status.d.ts +34 -0
  267. package/{lib → dist/esm}/commands/handlers/status.js +1 -9
  268. package/dist/esm/commands/handlers/store.d.ts +3 -0
  269. package/{lib → dist/esm}/commands/handlers/store.js +20 -44
  270. package/dist/esm/commands/index.d.ts +2 -0
  271. package/dist/esm/commands/index.js +55 -0
  272. package/dist/esm/commands/list.d.ts +2 -0
  273. package/dist/esm/commands/list.js +71 -0
  274. package/dist/esm/commands/login.d.ts +2 -0
  275. package/{lib → dist/esm}/commands/login.js +24 -44
  276. package/dist/esm/commands/logout.d.ts +2 -0
  277. package/dist/esm/commands/logout.js +25 -0
  278. package/dist/esm/commands/lsub.d.ts +2 -0
  279. package/dist/esm/commands/lsub.js +64 -0
  280. package/dist/esm/commands/noop.d.ts +2 -0
  281. package/dist/esm/commands/noop.js +13 -0
  282. package/dist/esm/commands/rename.d.ts +2 -0
  283. package/{lib → dist/esm}/commands/rename.js +32 -51
  284. package/dist/esm/commands/search.d.ts +10 -0
  285. package/dist/esm/commands/search.js +54 -0
  286. package/dist/esm/commands/select.d.ts +19 -0
  287. package/dist/esm/commands/select.js +214 -0
  288. package/dist/esm/commands/status.d.ts +2 -0
  289. package/{lib → dist/esm}/commands/status.js +18 -39
  290. package/dist/esm/commands/store.d.ts +10 -0
  291. package/{lib → dist/esm}/commands/store.js +39 -73
  292. package/dist/esm/commands/subscribe.d.ts +2 -0
  293. package/{lib → dist/esm}/commands/subscribe.js +22 -39
  294. package/dist/esm/commands/uid-copy.d.ts +2 -0
  295. package/dist/esm/commands/uid-copy.js +4 -0
  296. package/dist/esm/commands/uid-fetch.d.ts +3 -0
  297. package/dist/esm/commands/uid-fetch.js +3 -0
  298. package/dist/esm/commands/uid-search.d.ts +3 -0
  299. package/dist/esm/commands/uid-search.js +3 -0
  300. package/dist/esm/commands/uid-store.d.ts +3 -0
  301. package/dist/esm/commands/uid-store.js +3 -0
  302. package/dist/esm/commands/unsubscribe.d.ts +2 -0
  303. package/{lib → dist/esm}/commands/unsubscribe.js +22 -37
  304. package/dist/esm/dates.d.ts +64 -0
  305. package/{lib → dist/esm}/dates.js +6 -14
  306. package/dist/esm/deflate-layer.d.ts +83 -0
  307. package/{lib → dist/esm}/deflate-layer.js +9 -26
  308. package/dist/esm/encoded-words.d.ts +15 -0
  309. package/{lib → dist/esm}/encoded-words.js +9 -25
  310. package/dist/esm/envelope.d.ts +33 -0
  311. package/{lib → dist/esm}/envelope.js +8 -19
  312. package/dist/esm/esearch.d.ts +96 -0
  313. package/{lib → dist/esm}/esearch.js +12 -39
  314. package/dist/esm/framing.d.ts +66 -0
  315. package/dist/esm/framing.js +82 -0
  316. package/dist/esm/index.d.ts +9 -0
  317. package/dist/esm/index.js +6 -0
  318. package/dist/esm/list-extensions.d.ts +50 -0
  319. package/{lib → dist/esm}/list-extensions.js +1 -4
  320. package/dist/esm/load-plugins.d.ts +21 -0
  321. package/{lib → dist/esm}/load-plugins.js +9 -43
  322. package/dist/esm/mailbox-name.d.ts +26 -0
  323. package/{lib → dist/esm}/mailbox-name.js +5 -26
  324. package/dist/esm/mimeparser.d.ts +137 -0
  325. package/{lib → dist/esm}/mimeparser.js +74 -152
  326. package/dist/esm/mock-client.d.ts +39 -0
  327. package/{lib → dist/esm}/mock-client.js +26 -40
  328. package/dist/esm/numbers.d.ts +28 -0
  329. package/{lib → dist/esm}/numbers.js +1 -8
  330. package/dist/esm/package.json +3 -0
  331. package/dist/esm/plugins/acl.d.ts +2 -0
  332. package/{lib → dist/esm}/plugins/acl.js +146 -240
  333. package/dist/esm/plugins/appendlimit.d.ts +16 -0
  334. package/{lib → dist/esm}/plugins/appendlimit.js +5 -16
  335. package/dist/esm/plugins/auth-plain.d.ts +2 -0
  336. package/{lib → dist/esm}/plugins/auth-plain.js +11 -31
  337. package/dist/esm/plugins/binary.d.ts +30 -0
  338. package/{lib → dist/esm}/plugins/binary.js +17 -43
  339. package/dist/esm/plugins/catenate.d.ts +14 -0
  340. package/{lib → dist/esm}/plugins/catenate.js +19 -40
  341. package/dist/esm/plugins/compress.d.ts +7 -0
  342. package/dist/esm/plugins/compress.js +61 -0
  343. package/dist/esm/plugins/condstore.d.ts +5 -0
  344. package/{lib → dist/esm}/plugins/condstore.js +66 -152
  345. package/dist/esm/plugins/context-search.d.ts +8 -0
  346. package/{lib → dist/esm}/plugins/context-search.js +53 -88
  347. package/dist/esm/plugins/context-sort.d.ts +6 -0
  348. package/{lib → dist/esm}/plugins/context-sort.js +4 -9
  349. package/dist/esm/plugins/create-special-use.d.ts +7 -0
  350. package/{lib → dist/esm}/plugins/create-special-use.js +33 -55
  351. package/dist/esm/plugins/enable.d.ts +23 -0
  352. package/dist/esm/plugins/enable.js +111 -0
  353. package/dist/esm/plugins/esearch.d.ts +6 -0
  354. package/{lib → dist/esm}/plugins/esearch.js +13 -42
  355. package/dist/esm/plugins/esort.d.ts +6 -0
  356. package/{lib → dist/esm}/plugins/esort.js +7 -25
  357. package/dist/esm/plugins/id.d.ts +5 -0
  358. package/dist/esm/plugins/id.js +108 -0
  359. package/dist/esm/plugins/idle.d.ts +5 -0
  360. package/dist/esm/plugins/idle.js +70 -0
  361. package/dist/esm/plugins/imap4rev2.d.ts +6 -0
  362. package/{lib → dist/esm}/plugins/imap4rev2.js +24 -60
  363. package/dist/esm/plugins/index.d.ts +2 -0
  364. package/dist/esm/plugins/index.js +113 -0
  365. package/dist/esm/plugins/list-extended.d.ts +2 -0
  366. package/{lib → dist/esm}/plugins/list-extended.js +28 -66
  367. package/dist/esm/plugins/list-status.d.ts +6 -0
  368. package/{lib → dist/esm}/plugins/list-status.js +5 -12
  369. package/dist/esm/plugins/literalminus.d.ts +8 -0
  370. package/{lib → dist/esm}/plugins/literalminus.js +2 -5
  371. package/dist/esm/plugins/literalplus.d.ts +6 -0
  372. package/{lib → dist/esm}/plugins/literalplus.js +2 -5
  373. package/dist/esm/plugins/logindisabled.d.ts +5 -0
  374. package/dist/esm/plugins/logindisabled.js +39 -0
  375. package/dist/esm/plugins/messagelimit.d.ts +19 -0
  376. package/{lib → dist/esm}/plugins/messagelimit.js +18 -41
  377. package/dist/esm/plugins/metadata-server.d.ts +7 -0
  378. package/{lib → dist/esm}/plugins/metadata-server.js +3 -7
  379. package/dist/esm/plugins/metadata.d.ts +11 -0
  380. package/dist/esm/plugins/metadata.js +421 -0
  381. package/dist/esm/plugins/move.d.ts +11 -0
  382. package/{lib → dist/esm}/plugins/move.js +37 -66
  383. package/dist/esm/plugins/multiappend.d.ts +12 -0
  384. package/{lib → dist/esm}/plugins/multiappend.js +2 -5
  385. package/dist/esm/plugins/multisearch.d.ts +6 -0
  386. package/{lib → dist/esm}/plugins/multisearch.js +24 -48
  387. package/dist/esm/plugins/namespace.d.ts +5 -0
  388. package/dist/esm/plugins/namespace.js +42 -0
  389. package/dist/esm/plugins/notify.d.ts +2 -0
  390. package/{lib → dist/esm}/plugins/notify.js +90 -134
  391. package/dist/esm/plugins/oauthbearer.d.ts +32 -0
  392. package/{lib → dist/esm}/plugins/oauthbearer.js +18 -48
  393. package/dist/esm/plugins/objectid.d.ts +23 -0
  394. package/{lib → dist/esm}/plugins/objectid.js +21 -58
  395. package/dist/esm/plugins/partial.d.ts +6 -0
  396. package/{lib → dist/esm}/plugins/partial.js +7 -15
  397. package/dist/esm/plugins/preview.d.ts +31 -0
  398. package/{lib → dist/esm}/plugins/preview.js +28 -66
  399. package/dist/esm/plugins/qresync.d.ts +11 -0
  400. package/{lib → dist/esm}/plugins/qresync.js +64 -134
  401. package/dist/esm/plugins/quota.d.ts +18 -0
  402. package/{lib → dist/esm}/plugins/quota.js +89 -135
  403. package/dist/esm/plugins/replace.d.ts +14 -0
  404. package/{lib → dist/esm}/plugins/replace.js +21 -51
  405. package/dist/esm/plugins/sasl-ir.d.ts +5 -0
  406. package/{lib → dist/esm}/plugins/sasl-ir.js +3 -6
  407. package/dist/esm/plugins/savedate.d.ts +17 -0
  408. package/{lib → dist/esm}/plugins/savedate.js +5 -15
  409. package/dist/esm/plugins/savelimit.d.ts +10 -0
  410. package/{lib → dist/esm}/plugins/savelimit.js +3 -6
  411. package/dist/esm/plugins/searchres.d.ts +6 -0
  412. package/{lib → dist/esm}/plugins/searchres.js +13 -22
  413. package/dist/esm/plugins/sort-display.d.ts +11 -0
  414. package/{lib → dist/esm}/plugins/sort-display.js +6 -10
  415. package/dist/esm/plugins/sort.d.ts +11 -0
  416. package/{lib → dist/esm}/plugins/sort.js +24 -46
  417. package/dist/esm/plugins/special-use.d.ts +10 -0
  418. package/{lib → dist/esm}/plugins/special-use.js +9 -24
  419. package/dist/esm/plugins/starttls.d.ts +5 -0
  420. package/{lib → dist/esm}/plugins/starttls.js +20 -37
  421. package/dist/esm/plugins/status-size.d.ts +7 -0
  422. package/{lib → dist/esm}/plugins/status-size.js +4 -11
  423. package/dist/esm/plugins/thread-orderedsubject.d.ts +11 -0
  424. package/{lib → dist/esm}/plugins/thread-orderedsubject.js +3 -6
  425. package/dist/esm/plugins/thread-references.d.ts +11 -0
  426. package/{lib → dist/esm}/plugins/thread-references.js +3 -6
  427. package/dist/esm/plugins/uidonly.d.ts +15 -0
  428. package/{lib → dist/esm}/plugins/uidonly.js +11 -35
  429. package/dist/esm/plugins/uidplus.d.ts +15 -0
  430. package/{lib → dist/esm}/plugins/uidplus.js +25 -45
  431. package/dist/esm/plugins/unauthenticate.d.ts +7 -0
  432. package/dist/esm/plugins/unauthenticate.js +17 -0
  433. package/dist/esm/plugins/unselect.d.ts +5 -0
  434. package/dist/esm/plugins/unselect.js +21 -0
  435. package/dist/esm/plugins/utf8-accept.d.ts +6 -0
  436. package/{lib → dist/esm}/plugins/utf8-accept.js +10 -21
  437. package/dist/esm/plugins/x-gm-ext-1.d.ts +26 -0
  438. package/{lib → dist/esm}/plugins/x-gm-ext-1.js +48 -100
  439. package/dist/esm/plugins/xoauth2.d.ts +2 -0
  440. package/dist/esm/plugins/xoauth2.js +140 -0
  441. package/dist/esm/plugins/xtoybird.d.ts +2 -0
  442. package/dist/esm/plugins/xtoybird.js +218 -0
  443. package/dist/esm/server.d.ts +876 -0
  444. package/dist/esm/server.js +2543 -0
  445. package/dist/esm/smtp-listener.d.ts +13 -0
  446. package/{lib → dist/esm}/smtp-listener.js +5 -12
  447. package/dist/esm/sorting.d.ts +77 -0
  448. package/{lib → dist/esm}/sorting.js +40 -53
  449. package/dist/esm/threading.d.ts +30 -0
  450. package/{lib → dist/esm}/threading.js +29 -70
  451. package/dist/esm/types.d.ts +327 -0
  452. package/dist/esm/types.js +2 -0
  453. package/dist/esm/utf8-session.d.ts +17 -0
  454. package/{lib → dist/esm}/utf8-session.js +15 -25
  455. package/dist/esm/vanished.d.ts +21 -0
  456. package/{lib → dist/esm}/vanished.js +16 -21
  457. package/dist/plugin-help.json +298 -0
  458. package/package.json +54 -11
  459. package/lib/commands/capability.js +0 -47
  460. package/lib/commands/check.js +0 -21
  461. package/lib/commands/close.js +0 -30
  462. package/lib/commands/examine.js +0 -7
  463. package/lib/commands/expunge.js +0 -27
  464. package/lib/commands/list.js +0 -100
  465. package/lib/commands/logout.js +0 -41
  466. package/lib/commands/lsub.js +0 -87
  467. package/lib/commands/noop.js +0 -21
  468. package/lib/commands/search.js +0 -76
  469. package/lib/commands/select.js +0 -289
  470. package/lib/commands/uid copy.js +0 -7
  471. package/lib/commands/uid fetch.js +0 -5
  472. package/lib/commands/uid search.js +0 -5
  473. package/lib/commands/uid store.js +0 -5
  474. package/lib/plugins/compress.js +0 -76
  475. package/lib/plugins/enable.js +0 -155
  476. package/lib/plugins/id.js +0 -138
  477. package/lib/plugins/idle.js +0 -105
  478. package/lib/plugins/logindisabled.js +0 -50
  479. package/lib/plugins/metadata.js +0 -475
  480. package/lib/plugins/namespace.js +0 -67
  481. package/lib/plugins/unauthenticate.js +0 -28
  482. package/lib/plugins/unselect.js +0 -36
  483. package/lib/plugins/xoauth2.js +0 -188
  484. package/lib/plugins/xtoybird.js +0 -282
  485. package/lib/server.js +0 -2880
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = oauthbearerPlugin;
4
+ exports.parseClientResponse = parseClientResponse;
5
+ /**
6
+ * @help Adds AUTH=OAUTHBEARER [RFC7628] capability
7
+ * @help Works with and without SASL-IR [RFC4959]
8
+ * @help Valid login info, same as for XOAUTH2:
9
+ * @help Username (authzid, optional): testuser
10
+ * @help Access Token: testtoken
11
+ */
12
+ const KVSEP = '\x01';
13
+ const utf8 = new TextDecoder('utf-8', { fatal: true });
14
+ /**
15
+ * Parses an OAUTHBEARER client response (RFC 7628 section 3.1)
16
+ *
17
+ * client-resp = (gs2-header kvsep *kvpair kvsep) / kvsep
18
+ * kvpair = key "=" value kvsep
19
+ * key = 1*(ALPHA)
20
+ * value = *(VCHAR / SP / HTAB / CR / LF)
21
+ *
22
+ * and its GS2 header (RFC 5801 section 4)
23
+ *
24
+ * gs2-header = [gs2-nonstd-flag ","] gs2-cb-flag "," [gs2-authzid] ","
25
+ * gs2-cb-flag = ("p=" cb-name) / "n" / "y"
26
+ * gs2-authzid = "a=" saslname
27
+ *
28
+ * @param {Buffer} input Decoded client response
29
+ * @return {Object} `{ kvsepOnly }`, `{ error }` when the response breaks the grammar, or
30
+ * `{ channelBinding, authzid, pairs }` where pairs maps keys to values
31
+ */
32
+ function parseClientResponse(input) {
33
+ const str = input.toString('binary');
34
+ if (str === KVSEP) {
35
+ return { kvsepOnly: true };
36
+ }
37
+ const header = str.match(/^(?:F,)?(n|y|p=[A-Za-z0-9.-]+),(?:a=([^,]+))?,/);
38
+ if (!header || str.charAt(header[0].length) !== KVSEP) {
39
+ return { error: 'Invalid GS2 header' };
40
+ }
41
+ let authzid = false;
42
+ if (header[2]) {
43
+ // saslname: "," and "=" are only allowed as "=2C" and "=3D", NUL is not allowed
44
+ if (/=(?!2C|3D)/.test(header[2]) || header[2].includes('\x00')) {
45
+ return { error: 'Invalid authorization identity' };
46
+ }
47
+ try {
48
+ authzid = utf8.decode(Buffer.from(header[2].replace(/=2C/g, ',').replace(/=3D/g, '='), 'binary'));
49
+ }
50
+ catch {
51
+ return { error: 'Invalid UTF-8 in the authorization identity' };
52
+ }
53
+ }
54
+ // *kvpair kvsep: every pair ends with a kvsep of its own, so the split ends with two empty parts
55
+ const parts = str.substr(header[0].length + 1).split(KVSEP);
56
+ if (parts.pop() !== '' || parts.pop() !== '') {
57
+ return { error: 'The client response must end with %x01' };
58
+ }
59
+ const pairs = Object.create(null);
60
+ for (const pair of parts) {
61
+ const match = pair.match(/^([A-Za-z]+)=([\x20-\x7e\t\r\n]*)$/);
62
+ if (!match) {
63
+ return { error: 'Invalid key/value pair' };
64
+ }
65
+ pairs[match[1]] = match[2];
66
+ }
67
+ return { channelBinding: header[1].charAt(0) === 'p', authzid, pairs };
68
+ }
69
+ function oauthbearerPlugin(server) {
70
+ server.registerCapability('AUTH=OAUTHBEARER', (connection) => connection.state === 'Not Authenticated');
71
+ const fail = (connection, parsed, data, command, text) => {
72
+ // RFC 5530 section 3: a rejected login is AUTHENTICATIONFAILED
73
+ connection.sendStatus(parsed, data, command, text, command === 'NO' && 'AUTHENTICATIONFAILED', 'AUTHENTICATE OAUTHBEARER FAILED');
74
+ };
75
+ /**
76
+ * Checks the client response. Returns the OAuth error status (RFC 6750 section 3.1) if the
77
+ * credentials are not accepted, or false if the user is logged in
78
+ */
79
+ const checkCredentials = (request) => {
80
+ if (request.channelBinding) {
81
+ // RFC 5801 section 5: "p" asks for channel binding, which this mechanism does not support
82
+ return 'invalid_request';
83
+ }
84
+ const { auth, port } = request.pairs;
85
+ // port: a decimal positive integer string without leading zeros (RFC 7628 section 3.1)
86
+ if (typeof port === 'string' && !/^[1-9][0-9]*$/.test(port)) {
87
+ return 'invalid_request';
88
+ }
89
+ // RFC 6750 section 2.1: "Bearer" 1*SP b64token, the scheme name is case insensitive
90
+ const bearer = typeof auth === 'string' && auth.match(/^Bearer +([A-Za-z0-9\-._~+/]+=*)$/i);
91
+ if (!bearer) {
92
+ // an empty auth value is how a client asks for the error details (RFC 7628 section 4.3)
93
+ return auth === '' ? 'invalid_token' : 'invalid_request';
94
+ }
95
+ const token = bearer[1];
96
+ let username = request.authzid;
97
+ if (username === false) {
98
+ // without an authzid the token tells who the user is
99
+ username = Object.keys(server.users).find(name => {
100
+ const user = server.users[name];
101
+ return user && user.xoauth2 && user.xoauth2.accessToken === token;
102
+ });
103
+ }
104
+ const user = server.getUser(username);
105
+ if (!user || !user.xoauth2 || user.xoauth2.accessToken !== token) {
106
+ return 'invalid_token';
107
+ }
108
+ request.username = username;
109
+ return false;
110
+ };
111
+ // Decodes a base64 client response, sends BAD and returns false if it is not valid base64
112
+ const decode = (connection, parsed, data, input) => {
113
+ const decoded = connection.decodeSaslResponse(input);
114
+ if (!decoded) {
115
+ fail(connection, parsed, data, 'BAD', 'Invalid base64 in SASL response');
116
+ }
117
+ return decoded;
118
+ };
119
+ // Waits for the next client response line. "*" cancels the exchange, which RFC 3501 section 6.2.2
120
+ // answers with BAD
121
+ const readResponse = (connection, parsed, data, onResponse) => {
122
+ connection.inputHandler = (line) => {
123
+ connection.inputHandler = false;
124
+ if (line === '*') {
125
+ return fail(connection, parsed, data, 'BAD', 'Authentication cancelled');
126
+ }
127
+ const decoded = decode(connection, parsed, data, line);
128
+ if (decoded) {
129
+ onResponse(decoded);
130
+ }
131
+ };
132
+ };
133
+ // Handles the decoded client response, sent with SASL-IR or after the empty continuation request
134
+ const authenticate = (connection, parsed, data, decoded) => {
135
+ const request = parseClientResponse(decoded);
136
+ if (request.error) {
137
+ return fail(connection, parsed, data, 'BAD', request.error + ' in the OAUTHBEARER client response');
138
+ }
139
+ if (request.kvsepOnly) {
140
+ // RFC 7628 section 3.1: as the first message the server may fail without discovery information
141
+ return fail(connection, parsed, data, 'NO', 'SASL authentication failed');
142
+ }
143
+ const status = checkCredentials(request);
144
+ if (!status) {
145
+ connection.state = 'Authenticated';
146
+ connection.username = request.username;
147
+ return connection.sendStatus(parsed, data, 'OK', 'SASL authentication succeeded', false, 'AUTHENTICATE OAUTHBEARER SUCCESS');
148
+ }
149
+ // RFC 7628 section 3.2.2: the error result is a JSON document in a continuation request, the
150
+ // client MUST answer with a single %x01 or cancel, and the server then fails the exchange
151
+ readResponse(connection, parsed, data, (response) => {
152
+ if (response.toString('binary') !== KVSEP) {
153
+ return fail(connection, parsed, data, 'BAD', 'The client must answer the error result with a single %x01 (RFC 7628 section 3.2.3)');
154
+ }
155
+ fail(connection, parsed, data, 'NO', 'SASL authentication failed');
156
+ });
157
+ connection.send({
158
+ tag: '+',
159
+ attributes: [
160
+ {
161
+ type: 'ATOM',
162
+ value: Buffer.from(JSON.stringify({ status })).toString('base64')
163
+ }
164
+ ]
165
+ }, 'AUTHENTICATE OAUTHBEARER CHALLENGE', parsed, data);
166
+ };
167
+ server.setCommandHandler('AUTHENTICATE OAUTHBEARER', (connection, parsed, data, callback) => {
168
+ const args = parsed.attributes || [];
169
+ if (!args.length) {
170
+ // without an initial response the client sends its response after an empty challenge
171
+ readResponse(connection, parsed, data, decoded => authenticate(connection, parsed, data, decoded));
172
+ connection.write('+ \r\n');
173
+ return callback();
174
+ }
175
+ if (args.length !== 1 || !args[0] || args[0].type !== 'ATOM') {
176
+ fail(connection, parsed, data, 'BAD', 'Invalid arguments for AUTHENTICATE OAUTHBEARER');
177
+ return callback();
178
+ }
179
+ // RFC 4959 section 3: an initial response is only allowed when SASL-IR is advertised
180
+ if (!server.capabilities['SASL-IR'] || !server.capabilities['SASL-IR'](connection)) {
181
+ fail(connection, parsed, data, 'BAD', 'SASL-IR must be enabled to send Initial Response with the request');
182
+ return callback();
183
+ }
184
+ const decoded = decode(connection, parsed, data, args[0].value);
185
+ if (decoded) {
186
+ authenticate(connection, parsed, data, decoded);
187
+ }
188
+ return callback();
189
+ });
190
+ }
191
+ {
192
+ const defaultExport = exports.default;
193
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
194
+ for (const key of Object.keys(exports)) {
195
+ if (key !== 'default' && !(key in defaultExport)) {
196
+ defaultExport[key] = exports[key];
197
+ }
198
+ }
199
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
200
+ module.exports = defaultExport;
201
+ }
202
+ }
@@ -0,0 +1,23 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ /**
3
+ * @help Adds OBJECTID [RFC8474] capability
4
+ * @help MAILBOXID, EMAILID and THREADID values are generated (F1, M1, T1, ...)
5
+ * @help unless storage sets them for a mailbox ("MAILBOXID") or a message
6
+ * @help ("EMAILID", "THREADID"). Messages are threaded by their Message-ID,
7
+ * @help In-Reply-To and References headers across all mailboxes
8
+ *
9
+ * OBJECTID: https://www.rfc-editor.org/rfc/rfc8474.txt
10
+ *
11
+ * Additional response codes:
12
+ * - MAILBOXID for CREATE, SELECT and EXAMINE
13
+ *
14
+ * Additional STATUS items:
15
+ * - MAILBOXID
16
+ *
17
+ * Additional FETCH items:
18
+ * - EMAILID, THREADID
19
+ *
20
+ * Additional SEARCH keys:
21
+ * - EMAILID, THREADID
22
+ */
23
+ export default function objectidPlugin(server: IMAPServer): void;
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = objectidPlugin;
4
+ const search_js_1 = require("../commands/handlers/search.js");
5
+ // RFC 8474 section 7: objectid = 1*255(ALPHA / DIGIT / "_" / "-"), case sensitive
6
+ const OBJECTID = /^[A-Za-z0-9_-]{1,255}$/;
7
+ // header fields that threading uses, in an unfolded header
8
+ const MESSAGE_ID_HEADER = /^Message-ID[ \t]*:(.*)$/im;
9
+ const REFERENCES_HEADER = /^References[ \t]*:(.*)$/im;
10
+ const IN_REPLY_TO_HEADER = /^In-Reply-To[ \t]*:(.*)$/im;
11
+ // uidvalidity a MAILBOXID was assigned for
12
+ const ASSIGNED_FOR = Symbol('mailboxid-uidvalidity');
13
+ /**
14
+ * @help Adds OBJECTID [RFC8474] capability
15
+ * @help MAILBOXID, EMAILID and THREADID values are generated (F1, M1, T1, ...)
16
+ * @help unless storage sets them for a mailbox ("MAILBOXID") or a message
17
+ * @help ("EMAILID", "THREADID"). Messages are threaded by their Message-ID,
18
+ * @help In-Reply-To and References headers across all mailboxes
19
+ *
20
+ * OBJECTID: https://www.rfc-editor.org/rfc/rfc8474.txt
21
+ *
22
+ * Additional response codes:
23
+ * - MAILBOXID for CREATE, SELECT and EXAMINE
24
+ *
25
+ * Additional STATUS items:
26
+ * - MAILBOXID
27
+ *
28
+ * Additional FETCH items:
29
+ * - EMAILID, THREADID
30
+ *
31
+ * Additional SEARCH keys:
32
+ * - EMAILID, THREADID
33
+ */
34
+ function objectidPlugin(server) {
35
+ server.registerCapability('OBJECTID');
36
+ // kind (F, M or T) of every value ever used, generated values must not collide with them
37
+ const used = new Map();
38
+ const counters = { F: 0, M: 0, T: 0 };
39
+ // current owner of each MAILBOXID, RFC 8474 section 4: never two mailboxes at the same time
40
+ const mailboxOwners = new Map();
41
+ // THREADID by EMAILID, RFC 8474 section 5.2: the same EMAILID always has the same THREADID
42
+ const emailThreads = new Map();
43
+ // THREADID by Message-ID, for threading
44
+ const messageIdThreads = new Map();
45
+ // RFC 8474 section 8.1: the prefix keeps generated ids from starting with a digit or a dash
46
+ const generate = (prefix) => {
47
+ let id;
48
+ do {
49
+ id = prefix + ++counters[prefix];
50
+ } while (used.has(id));
51
+ used.set(id, prefix);
52
+ return id;
53
+ };
54
+ const checkValue = (value, what, owner) => {
55
+ if (typeof value !== 'string' || !OBJECTID.test(value)) {
56
+ throw new Error('Invalid ' + what + ' value ' + JSON.stringify(value) + ' in ' + owner);
57
+ }
58
+ };
59
+ // RFC 8474 section 5.2: an id is used for one kind of object only
60
+ const checkUnique = (value, prefix) => {
61
+ if (used.has(value) && used.get(value) !== prefix) {
62
+ throw new Error('Object identifier ' + JSON.stringify(value) + ' is already used for another kind of object');
63
+ }
64
+ used.set(value, prefix);
65
+ };
66
+ /**
67
+ * Returns the MAILBOXID of a mailbox. A mailbox that got a new UIDVALIDITY (re-created after
68
+ * DELETE) is a new mailbox and gets a new id (RFC 8474 section 4)
69
+ */
70
+ const getMailboxId = (mailbox) => {
71
+ if (mailbox[ASSIGNED_FOR] === mailbox.uidvalidity && mailboxOwners.get(mailbox.MAILBOXID) === mailbox) {
72
+ return mailbox.MAILBOXID;
73
+ }
74
+ let id;
75
+ if (mailbox.MAILBOXID && mailbox[ASSIGNED_FOR] === undefined && !mailboxOwners.has(mailbox.MAILBOXID)) {
76
+ // value from storage
77
+ id = mailbox.MAILBOXID;
78
+ checkValue(id, 'MAILBOXID', 'mailbox ' + mailbox.path);
79
+ checkUnique(id, 'F');
80
+ }
81
+ else {
82
+ // a new mailbox, or a copy of a deleted one (a \Noselect placeholder that is created again)
83
+ id = generate('F');
84
+ }
85
+ mailbox.MAILBOXID = id;
86
+ mailbox[ASSIGNED_FOR] = mailbox.uidvalidity;
87
+ mailboxOwners.set(id, mailbox);
88
+ return id;
89
+ };
90
+ // Assign ids when mailboxes are loaded or created. A \Noselect placeholder is not a mailbox
91
+ server.mailboxHandlers.push((server, mailbox) => {
92
+ if (mailbox.flags.indexOf('\\Noselect') >= 0) {
93
+ return;
94
+ }
95
+ if (mailbox.MAILBOXID && mailbox[ASSIGNED_FOR] === undefined && mailboxOwners.has(mailbox.MAILBOXID)) {
96
+ // two mailboxes in storage with the same id
97
+ throw new Error('Duplicate MAILBOXID value ' + JSON.stringify(mailbox.MAILBOXID) + ' in mailbox ' + mailbox.path);
98
+ }
99
+ getMailboxId(mailbox);
100
+ });
101
+ server.messageHandlers.push((server, message, mailbox) => {
102
+ const owner = 'a message of mailbox ' + mailbox.path;
103
+ if (message.EMAILID) {
104
+ checkValue(message.EMAILID, 'EMAILID', owner);
105
+ checkUnique(message.EMAILID, 'M');
106
+ }
107
+ else {
108
+ message.EMAILID = generate('M');
109
+ }
110
+ if (message.THREADID) {
111
+ checkValue(message.THREADID, 'THREADID', owner);
112
+ checkUnique(message.THREADID, 'T');
113
+ }
114
+ const threadOfEmail = emailThreads.get(message.EMAILID);
115
+ if (threadOfEmail && message.THREADID && message.THREADID !== threadOfEmail) {
116
+ throw new Error('Messages with EMAILID ' + JSON.stringify(message.EMAILID) + ' must have the same THREADID');
117
+ }
118
+ const ids = getThreadingIds(message.raw);
119
+ message.THREADID = message.THREADID || threadOfEmail || findThread(ids.references) || generate('T');
120
+ emailThreads.set(message.EMAILID, message.THREADID);
121
+ // later replies, and later messages with a common parent, join this thread
122
+ [ids.messageId].concat(ids.references).forEach(id => {
123
+ if (id && !messageIdThreads.has(id)) {
124
+ messageIdThreads.set(id, message.THREADID);
125
+ }
126
+ });
127
+ });
128
+ // the nearest known parent decides the thread
129
+ const findThread = (references) => {
130
+ for (let i = references.length - 1; i >= 0; i--) {
131
+ if (messageIdThreads.has(references[i])) {
132
+ return messageIdThreads.get(references[i]);
133
+ }
134
+ }
135
+ return false;
136
+ };
137
+ // RFC 8474 section 5.1: the copy in the COPYUID pairing has the EMAILID of the source, after COPY as well as after MOVE
138
+ server.copyHandlers.push((server, source, copy) => {
139
+ if (source.EMAILID) {
140
+ copy.EMAILID = source.EMAILID;
141
+ copy.THREADID = source.THREADID;
142
+ }
143
+ });
144
+ // RFC 8474 section 4.3
145
+ server.allowedStatus.push('MAILBOXID');
146
+ server.statusHandlers.MAILBOXID = (connection, mailbox) => [{ type: 'ATOM', value: getMailboxId(mailbox) }];
147
+ // RFC 8474 section 5.3
148
+ server.fetchHandlers.EMAILID = (connection, message) => [{ type: 'ATOM', value: message.EMAILID }];
149
+ server.fetchHandlers.THREADID = (connection, message) => [{ type: 'ATOM', value: message.THREADID }];
150
+ // RFC 8474 section 6: search-key =/ "EMAILID" SP objectid / "THREADID" SP objectid
151
+ const objectIdArgument = (value) => {
152
+ if (!OBJECTID.test(value)) {
153
+ throw (0, search_js_1.badError)('Invalid object identifier');
154
+ }
155
+ return value;
156
+ };
157
+ const searchHandler = (name) => {
158
+ const handler = (connection, message, index, value) => message[name] === value;
159
+ handler.argumentTypes = () => [objectIdArgument];
160
+ server.searchHandlers[name] = handler;
161
+ };
162
+ searchHandler('EMAILID');
163
+ searchHandler('THREADID');
164
+ // resp-text-code =/ "MAILBOXID" SP "(" objectid ")"
165
+ const mailboxIdCode = (mailbox) => ({
166
+ type: 'SECTION',
167
+ section: [{ type: 'ATOM', value: 'MAILBOXID' }, [{ type: 'ATOM', value: getMailboxId(mailbox) }]]
168
+ });
169
+ server.outputHandlers.push((connection, response, description, parsed, data, extra) => {
170
+ // RFC 8474 section 4.1: MAILBOXID response code in the tagged OK of CREATE
171
+ if (description === 'CREATE' && response.command === 'OK' && extra) {
172
+ response.attributes = [mailboxIdCode(extra)].concat(response.attributes || []);
173
+ return;
174
+ }
175
+ // RFC 8474 section 4.2: untagged OK with MAILBOXID on every successful SELECT and EXAMINE
176
+ if ((description === 'SELECT' || description === 'EXAMINE') &&
177
+ parsed &&
178
+ response.tag === parsed.tag &&
179
+ response.command === 'OK' &&
180
+ connection.selectedMailbox) {
181
+ connection.send({
182
+ tag: '*',
183
+ command: 'OK',
184
+ attributes: [mailboxIdCode(connection.selectedMailbox), { type: 'TEXT', value: 'Ok' }]
185
+ }, description + ' MAILBOXID', parsed, data);
186
+ }
187
+ });
188
+ }
189
+ /**
190
+ * Reads the message ids that threading uses from the header of a message
191
+ *
192
+ * @param {String} raw Message source
193
+ * @return {Object} `{ messageId, references }`, references lists the ids of References and In-Reply-To, the parent last
194
+ */
195
+ function getThreadingIds(raw) {
196
+ raw = raw || '';
197
+ const end = raw.search(/\r?\n\r?\n/);
198
+ // unfolded header lines
199
+ const header = (end >= 0 ? raw.substr(0, end) : raw).replace(/\r?\n(?=[ \t])/g, '');
200
+ const getIds = (regex) => {
201
+ const match = header.match(regex);
202
+ return match ? match[1].match(/<[^<>\s]+>/g) || [] : [];
203
+ };
204
+ return {
205
+ messageId: getIds(MESSAGE_ID_HEADER)[0] || false,
206
+ // In-Reply-To names the parent, which is also the last entry of References
207
+ references: getIds(REFERENCES_HEADER).concat(getIds(IN_REPLY_TO_HEADER))
208
+ };
209
+ }
210
+ {
211
+ const defaultExport = exports.default;
212
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
213
+ for (const key of Object.keys(exports)) {
214
+ if (key !== 'default' && !(key in defaultExport)) {
215
+ defaultExport[key] = exports[key];
216
+ }
217
+ }
218
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
219
+ module.exports = defaultExport;
220
+ }
221
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @help Adds PARTIAL [RFC9394] capability, loads ESEARCH as well
3
+ * @help SEARCH RETURN (PARTIAL 1:100) or (PARTIAL -1:-100) returns a window of the results, FETCH and UID FETCH take a PARTIAL modifier
4
+ */
5
+ import type { IMAPServer } from '../types.js';
6
+ export default function partialPlugin(server: IMAPServer): void;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /**
3
+ * @help Adds PARTIAL [RFC9394] capability, loads ESEARCH as well
4
+ * @help SEARCH RETURN (PARTIAL 1:100) or (PARTIAL -1:-100) returns a window of the results, FETCH and UID FETCH take a PARTIAL modifier
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.default = partialPlugin;
11
+ const esearch_js_1 = __importDefault(require("./esearch.js"));
12
+ const esearch_js_2 = require("../esearch.js");
13
+ const isPartial = (item) => !!item && item.type === 'ATOM' && String(item.value).toUpperCase() === 'PARTIAL';
14
+ function partialPlugin(server) {
15
+ // the PARTIAL search return option is returned in an ESEARCH response (RFC 9394 section 3.1)
16
+ (0, esearch_js_1.default)(server);
17
+ server.registerCapability('PARTIAL');
18
+ server.partialRangeLast = true;
19
+ (0, esearch_js_2.registerPartialOption)(server);
20
+ // RFC 9394 section 3.3: fetch-modifier =/ modifier-partial. The grammar (RFC 4466 section 2.4) allows
21
+ // the modifier for FETCH as well as for UID FETCH. The modifier is taken off the list, CHANGEDSINCE of
22
+ // CONDSTORE then filters the messages in the range (RFC 9394 section 3.4)
23
+ const fetchWrapper = (prevHandler, connection, parsed, data, callback) => {
24
+ const modifiers = parsed.attributes && parsed.attributes[2];
25
+ if (Array.isArray(modifiers)) {
26
+ for (let i = 0; i < modifiers.length; i += 2) {
27
+ if (!isPartial(modifiers[i])) {
28
+ continue;
29
+ }
30
+ try {
31
+ if (parsed.partialFetch) {
32
+ throw new Error('PARTIAL can be used only once');
33
+ }
34
+ parsed.partialFetch = (0, esearch_js_2.parsePartialRange)(modifiers[i + 1], true);
35
+ }
36
+ catch (E) {
37
+ connection.sendStatus(parsed, data, 'BAD', E.message, false, (parsed.command || '').toUpperCase() + ' FAILED');
38
+ return callback();
39
+ }
40
+ modifiers.splice(i, 2);
41
+ i -= 2;
42
+ }
43
+ if (!modifiers.length) {
44
+ parsed.attributes.splice(2, 1);
45
+ }
46
+ }
47
+ prevHandler(connection, parsed, data, callback);
48
+ };
49
+ ['FETCH', 'UID FETCH'].forEach(command => {
50
+ const prevHandler = server.getCommandHandler(command);
51
+ server.setCommandHandler(command, (connection, parsed, data, callback) => fetchWrapper(prevHandler, connection, parsed, data, callback));
52
+ });
53
+ // only the messages in the PARTIAL range of the messages that the sequence set matched are returned,
54
+ // checked before the other filters
55
+ server.fetchFilters.unshift((connection, message, parsed) => {
56
+ if (!parsed.partialFetch) {
57
+ return true;
58
+ }
59
+ if (!parsed.partialFetchSet) {
60
+ const isUid = (parsed.command || '').toUpperCase() === 'UID FETCH';
61
+ const range = connection.getMessageRange(parsed.attributes[0].value, isUid).map(item => item[1]);
62
+ parsed.partialFetchSet = new Set((0, esearch_js_2.selectPartial)(range, parsed.partialFetch));
63
+ }
64
+ return parsed.partialFetchSet.has(message);
65
+ });
66
+ }
67
+ {
68
+ const defaultExport = exports.default;
69
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
70
+ for (const key of Object.keys(exports)) {
71
+ if (key !== 'default' && !(key in defaultExport)) {
72
+ defaultExport[key] = exports[key];
73
+ }
74
+ }
75
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
76
+ module.exports = defaultExport;
77
+ }
78
+ }
@@ -0,0 +1,31 @@
1
+ import type { MimeNode } from '../mimeparser.js';
2
+ import type { IMAPServer } from '../types.js';
3
+ /**
4
+ * @help Adds PREVIEW [RFC8970] capability
5
+ * @help Previews come from the first text/plain or text/html body part,
6
+ * @help or from the "preview" property of a message in storage.
7
+ * @help PREVIEW (LAZY) returns NIL until a preview has been generated
8
+ *
9
+ * PREVIEW: https://www.rfc-editor.org/rfc/rfc8970
10
+ *
11
+ * Message storage property:
12
+ * - preview: preview text to return instead of a generated one
13
+ */
14
+ export default function previewPlugin(server: IMAPServer): void;
15
+ /**
16
+ * Generates the preview text of a message (RFC 8970 3.3) from the first text/plain or text/html part
17
+ *
18
+ * @param {Object} tree Root node of the MIME tree
19
+ * @return {String} Preview, an empty string if there is no text to show
20
+ */
21
+ declare function generatePreview(tree: MimeNode): string;
22
+ /**
23
+ * Normalizes preview text: control characters are removed, whitespace runs become a single space (so there are no
24
+ * CR or LF characters) and the text is cut to at most `length` characters (code points, RFC 8970 3.3)
25
+ *
26
+ * @param {String} text Text
27
+ * @param {Number} length Maximum number of characters
28
+ * @return {String} Preview
29
+ */
30
+ declare function finishPreview(text: string, length: number): string;
31
+ export { generatePreview, finishPreview };