imapkit 4.0.2 → 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 +34 -75
  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,254 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = quotaPlugin;
4
+ const command_states_js_1 = require("../command-states.js");
5
+ const mimeparser_js_1 = require("../mimeparser.js");
6
+ const numbers_js_1 = require("../numbers.js");
7
+ const arguments_js_1 = require("../arguments.js");
8
+ // Resource types of RFC 9208 section 5 that can be counted. ANNOTATION-STORAGE is left out,
9
+ // as there is no ANNOTATE support
10
+ const RESOURCES = ['STORAGE', 'MESSAGE', 'MAILBOX'];
11
+ const DEFAULT_ROOT = 'User quota';
12
+ /**
13
+ * @help Adds QUOTA [RFC9208] capability with the STORAGE, MESSAGE and MAILBOX
14
+ * @help resources and SETQUOTA. All personal mailboxes share one quota root, set
15
+ * @help with the "quota" server option, eg. {"root": "User quota",
16
+ * @help "STORAGE": 10240, "MESSAGE": 1000, "MAILBOX": 100, "soft": false}.
17
+ * @help STORAGE is in units of 1024 octets. Hard limits make APPEND, COPY, MOVE
18
+ * @help and CREATE fail with NO [OVERQUOTA], soft limits only send a warning
19
+ *
20
+ * QUOTA: https://www.rfc-editor.org/rfc/rfc9208.txt
21
+ *
22
+ * Additional commands:
23
+ * - GETQUOTA, GETQUOTAROOT, SETQUOTA
24
+ *
25
+ * Additional STATUS items:
26
+ * - DELETED, DELETED-STORAGE
27
+ */
28
+ function quotaPlugin(server) {
29
+ const config = server.options.quota || {};
30
+ const root = {
31
+ name: typeof config.root === 'string' ? config.root : DEFAULT_ROOT,
32
+ soft: !!config.soft,
33
+ limits: {}
34
+ };
35
+ RESOURCES.forEach(resource => {
36
+ if (config[resource] === undefined || config[resource] === null) {
37
+ return;
38
+ }
39
+ const limit = Number(config[resource]);
40
+ if (!Number.isSafeInteger(limit) || limit < 0) {
41
+ throw new Error('Invalid quota limit for ' + resource + ': ' + JSON.stringify(config[resource]));
42
+ }
43
+ root.limits[resource] = limit;
44
+ });
45
+ // RFC 9208 sections 3.1.1 and 5: every supported resource is advertised, SETQUOTA needs QUOTASET
46
+ server.registerCapability('QUOTA');
47
+ RESOURCES.forEach(resource => server.registerCapability('QUOTA=RES-' + resource));
48
+ server.registerCapability('QUOTASET');
49
+ // Personal mailboxes, INBOX included, belong to the quota root. Other namespaces have no quota root. A mailbox
50
+ // that does not exist yet belongs to the namespace of its prefix
51
+ const inRoot = (path) => server.isPersonal(path);
52
+ const isSelectable = (mailbox) => mailbox.flags.indexOf('\\Noselect') < 0;
53
+ // RFC822.SIZE, the message with CRLF line breaks
54
+ const totalSize = (messages) => messages.reduce((total, message) => total + (0, mimeparser_js_1.normalizeLineBreaks)(message.raw).length, 0);
55
+ const getUsage = () => {
56
+ const usage = { MESSAGE: 0, MAILBOX: 0, bytes: 0 };
57
+ Object.keys(server.folderCache).forEach(path => {
58
+ const mailbox = server.folderCache[path];
59
+ if (!isSelectable(mailbox) || !inRoot(mailbox)) {
60
+ return;
61
+ }
62
+ usage.MAILBOX++;
63
+ usage.MESSAGE += mailbox.messages.length;
64
+ usage.bytes += totalSize(mailbox.messages);
65
+ });
66
+ return usage;
67
+ };
68
+ // RFC 9208 section 4.2.1: quota-list, resources that are not listed are not limited
69
+ const sendQuota = (connection, parsed, data) => {
70
+ const usage = getUsage();
71
+ // RFC 9208 section 5.1: units of 1024 octets
72
+ usage.STORAGE = Math.ceil(usage.bytes / 1024);
73
+ const list = [];
74
+ RESOURCES.forEach(resource => {
75
+ if (resource in root.limits) {
76
+ list.push({ type: 'ATOM', value: resource }, usage[resource], root.limits[resource]);
77
+ }
78
+ });
79
+ connection.send({
80
+ tag: '*',
81
+ command: 'QUOTA',
82
+ attributes: [{ type: 'STRING', value: root.name }, list]
83
+ }, 'QUOTA', parsed, data);
84
+ };
85
+ /**
86
+ * Checks if adding to the quota root goes over a limit
87
+ *
88
+ * @param {Object} added Added amounts, `{ MESSAGE, MAILBOX, bytes }`
89
+ * @return {Object|undefined} `{ code, text, soft }` for IMAPConnection#checkAppend, or nothing if within limits
90
+ */
91
+ const checkLimits = (added) => {
92
+ const limited = (added.MESSAGE && 'MESSAGE' in root.limits) || (added.bytes && 'STORAGE' in root.limits) || (added.MAILBOX && 'MAILBOX' in root.limits);
93
+ if (!limited) {
94
+ return;
95
+ }
96
+ const usage = getUsage();
97
+ const over = (added.MESSAGE && 'MESSAGE' in root.limits && usage.MESSAGE + added.MESSAGE > root.limits.MESSAGE) ||
98
+ (added.bytes && 'STORAGE' in root.limits && usage.bytes + added.bytes > root.limits.STORAGE * 1024) ||
99
+ (added.MAILBOX && 'MAILBOX' in root.limits && usage.MAILBOX + added.MAILBOX > root.limits.MAILBOX);
100
+ if (!over) {
101
+ return;
102
+ }
103
+ // RFC 9208 section 4.3.1 and RFC 5530 section 3
104
+ return root.soft ? { code: 'OVERQUOTA', text: 'Soft quota has been exceeded', soft: true } : { code: 'OVERQUOTA', text: 'Quota exceeded' };
105
+ };
106
+ // APPEND, COPY, MOVE and REPLACE
107
+ server.appendChecks.push((connection, mailbox, messages, options) => {
108
+ if (!messages.length || !inRoot(mailbox)) {
109
+ return;
110
+ }
111
+ if (options.move && options.source && inRoot(options.source)) {
112
+ // moving within the quota root does not change the usage
113
+ return;
114
+ }
115
+ const added = { MESSAGE: messages.length, bytes: totalSize(messages) };
116
+ // RFC 8508 section 3.4: REPLACE counts only the net usage, the replaced message is removed
117
+ if (options.replaced && connection.selectedMailbox && inRoot(connection.selectedMailbox)) {
118
+ added.MESSAGE--;
119
+ added.bytes -= totalSize([options.replaced]);
120
+ }
121
+ return checkLimits(added);
122
+ });
123
+ // Number of mailboxes that CREATE adds, missing parent mailboxes are created as well
124
+ const countNewMailboxes = (path) => {
125
+ const target = server.getMailbox(server.stripSeparator(path, server.getSeparator(path)));
126
+ let count = !target || !isSelectable(target) ? 1 : 0;
127
+ for (let parent = server.getParentPath(path); parent; parent = server.getParentPath(parent)) {
128
+ if (!server.getMailbox(parent)) {
129
+ count++;
130
+ }
131
+ }
132
+ return count;
133
+ };
134
+ // The MAILBOX resource limits CREATE and RENAME INBOX (which creates a mailbox)
135
+ const wrapCreate = (command, getPath) => {
136
+ // CREATE and RENAME are core commands, so the handler exists
137
+ const prevHandler = server.getCommandHandler(command);
138
+ server.setCommandHandler(command, (connection, parsed, data, callback) => {
139
+ const path = getPath(parsed.attributes);
140
+ if (typeof path === 'string' &&
141
+ path.toUpperCase() !== 'INBOX' &&
142
+ inRoot(path) &&
143
+ !connection.applyChecks([checkLimits({ MAILBOX: countNewMailboxes(path) })], parsed, data, command + ' FAILED')) {
144
+ return callback();
145
+ }
146
+ prevHandler(connection, parsed, data, callback);
147
+ });
148
+ };
149
+ const argValue = (attributes, i) => (0, arguments_js_1.isAstring)((attributes || [])[i]) && attributes[i].value;
150
+ wrapCreate('CREATE', (attributes) => (attributes && attributes.length === 1 ? argValue(attributes, 0) : false));
151
+ wrapCreate('RENAME', (attributes) => {
152
+ const source = argValue(attributes, 0);
153
+ // only RENAME INBOX adds a mailbox, other renames keep the count (RFC 3501 section 6.3.5)
154
+ return attributes && attributes.length === 2 && typeof source === 'string' && source.toUpperCase() === 'INBOX' ? argValue(attributes, 1) : false;
155
+ });
156
+ // RFC 9208 section 4.1.1: GETQUOTA quota-root-name
157
+ server.setCommandHandler('GETQUOTA', (connection, parsed, data, callback) => {
158
+ if (!parsed.attributes || parsed.attributes.length !== 1 || !(0, arguments_js_1.isAstring)(parsed.attributes[0])) {
159
+ connection.sendStatus(parsed, data, 'BAD', 'GETQUOTA expects a quota root name');
160
+ return callback();
161
+ }
162
+ if (parsed.attributes[0].value !== root.name) {
163
+ connection.sendStatus(parsed, data, 'NO', 'Quota root does not exist', 'NONEXISTENT');
164
+ return callback();
165
+ }
166
+ sendQuota(connection, parsed, data);
167
+ connection.sendStatus(parsed, data, 'OK', 'GETQUOTA completed');
168
+ return callback();
169
+ },
170
+ // quota-root = astring (RFC 9208 section 9)
171
+ { states: command_states_js_1.states.AUTHENTICATED, astringArguments: [0] });
172
+ // RFC 9208 section 4.1.2: GETQUOTAROOT mailbox, the mailbox does not have to exist
173
+ server.setCommandHandler('GETQUOTAROOT', (connection, parsed, data, callback) => {
174
+ if (!parsed.attributes || parsed.attributes.length !== 1 || !(0, arguments_js_1.isAstring)(parsed.attributes[0])) {
175
+ connection.sendStatus(parsed, data, 'BAD', 'GETQUOTAROOT expects a mailbox name');
176
+ return callback();
177
+ }
178
+ let path = parsed.attributes[0].value;
179
+ if (path.toUpperCase() === 'INBOX') {
180
+ path = 'INBOX';
181
+ }
182
+ const hasRoot = inRoot(path);
183
+ connection.send({
184
+ tag: '*',
185
+ command: 'QUOTAROOT',
186
+ attributes: [{ type: 'MAILBOX', value: path }].concat(hasRoot ? { type: 'STRING', value: root.name } : [])
187
+ }, 'QUOTAROOT', parsed, data);
188
+ if (hasRoot) {
189
+ sendQuota(connection, parsed, data);
190
+ }
191
+ connection.sendStatus(parsed, data, 'OK', 'GETQUOTAROOT completed');
192
+ return callback();
193
+ }, { states: command_states_js_1.states.AUTHENTICATED, mailboxArguments: [0] });
194
+ // RFC 9208 section 4.1.3: SETQUOTA quota-root-name setquota-list, the new limits replace all earlier ones
195
+ server.setCommandHandler('SETQUOTA', (connection, parsed, data, callback) => {
196
+ const list = parsed.attributes && parsed.attributes[1];
197
+ if (!parsed.attributes || parsed.attributes.length !== 2 || !(0, arguments_js_1.isAstring)(parsed.attributes[0]) || !Array.isArray(list) || list.length % 2) {
198
+ connection.sendStatus(parsed, data, 'BAD', 'SETQUOTA expects a quota root name and a list of resource limits');
199
+ return callback();
200
+ }
201
+ const limits = {};
202
+ for (let i = 0; i < list.length; i += 2) {
203
+ const name = list[i];
204
+ const limit = list[i + 1];
205
+ // setquota-resource = resource-name SP resource-limit, resource-limit = number64
206
+ if (!name || name.type !== 'ATOM' || !limit || limit.type !== 'ATOM' || !(0, numbers_js_1.isNumber)(limit.value, numbers_js_1.MAX_NUMBER64)) {
207
+ connection.sendStatus(parsed, data, 'BAD', 'Invalid resource limit');
208
+ return callback();
209
+ }
210
+ const resource = name.value.toUpperCase();
211
+ if (RESOURCES.indexOf(resource) < 0 || resource in limits) {
212
+ connection.sendStatus(parsed, data, 'NO', 'Can not set a limit for ' + resource, 'CANNOT');
213
+ return callback();
214
+ }
215
+ const value = Number(limit.value);
216
+ if (!Number.isSafeInteger(value)) {
217
+ connection.sendStatus(parsed, data, 'NO', 'Limit is too large for ' + resource, 'LIMIT');
218
+ return callback();
219
+ }
220
+ limits[resource] = value;
221
+ }
222
+ // new quota roots can not be created
223
+ if (parsed.attributes[0].value !== root.name) {
224
+ connection.sendStatus(parsed, data, 'NO', 'Quota root does not exist', 'NONEXISTENT');
225
+ return callback();
226
+ }
227
+ root.limits = limits;
228
+ sendQuota(connection, parsed, data);
229
+ connection.sendStatus(parsed, data, 'OK', 'SETQUOTA completed');
230
+ return callback();
231
+ },
232
+ // quota-root = astring (RFC 9208 section 9)
233
+ { states: command_states_js_1.states.AUTHENTICATED, astringArguments: [0] });
234
+ // RFC 9208 section 4.1.4: DELETED (the built-in item, required with QUOTA=RES-MESSAGE) and DELETED-STORAGE
235
+ // (required with QUOTA=RES-STORAGE), the storage EXPUNGE would free as the sum of RFC822.SIZE
236
+ ['DELETED', 'DELETED-STORAGE'].forEach(item => {
237
+ if (server.allowedStatus.indexOf(item) < 0) {
238
+ server.allowedStatus.push(item);
239
+ }
240
+ });
241
+ server.statusHandlers['DELETED-STORAGE'] = (connection, mailbox) => totalSize(mailbox.messages.filter(message => message.flags.indexOf('\\Deleted') >= 0));
242
+ }
243
+ {
244
+ const defaultExport = exports.default;
245
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
246
+ for (const key of Object.keys(exports)) {
247
+ if (key !== 'default' && !(key in defaultExport)) {
248
+ defaultExport[key] = exports[key];
249
+ }
250
+ }
251
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
252
+ module.exports = defaultExport;
253
+ }
254
+ }
@@ -0,0 +1,14 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ /**
3
+ * @help Adds REPLACE [RFC8508] capability (REPLACE and UID REPLACE commands)
4
+ *
5
+ * REPLACE: https://www.rfc-editor.org/rfc/rfc8508
6
+ *
7
+ * Additional commands:
8
+ * - REPLACE
9
+ * - UID REPLACE
10
+ *
11
+ * The new message is appended and the old one expunged as a single action. With UIDPLUS the
12
+ * APPENDUID response code is sent in an untagged OK before the EXPUNGE. Works with CATENATE.
13
+ */
14
+ export default function replacePlugin(server: IMAPServer): void;
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = replacePlugin;
4
+ const append_js_1 = require("../commands/append.js");
5
+ const command_states_js_1 = require("../command-states.js");
6
+ const numbers_js_1 = require("../numbers.js");
7
+ // RFC 8508 section 5 and RFC 3501 section 9: seq-number = nz-number / "*"
8
+ const isSeqNumber = (value) => value === '*' || (0, numbers_js_1.isNzNumber)(value);
9
+ /**
10
+ * @help Adds REPLACE [RFC8508] capability (REPLACE and UID REPLACE commands)
11
+ *
12
+ * REPLACE: https://www.rfc-editor.org/rfc/rfc8508
13
+ *
14
+ * Additional commands:
15
+ * - REPLACE
16
+ * - UID REPLACE
17
+ *
18
+ * The new message is appended and the old one expunged as a single action. With UIDPLUS the
19
+ * APPENDUID response code is sent in an untagged OK before the EXPUNGE. Works with CATENATE.
20
+ */
21
+ function replacePlugin(server) {
22
+ server.registerCapability('REPLACE');
23
+ const replaceHandler = function (uidMode, connection, parsed, data, callback) {
24
+ const command = uidMode ? 'UID REPLACE' : 'REPLACE';
25
+ const args = [].concat(parsed.attributes || []);
26
+ const id = args.shift();
27
+ const pathArg = args.shift();
28
+ // RFC 8508 section 5: replace = "REPLACE" SP seq-number SP mailbox append-message
29
+ if (!id || ['ATOM', 'SEQUENCE'].indexOf(id.type) < 0 || !isSeqNumber(String(id.value))) {
30
+ connection.sendStatus(parsed, data, 'BAD', command + ' expects a message number, a mailbox name and a message', false, 'INVALID COMMAND');
31
+ return callback();
32
+ }
33
+ const found = findMessage(connection, uidMode, id.value);
34
+ if (found.error) {
35
+ connection.sendStatus(parsed, data, found.error.command, found.error.text, found.error.code || false, found.error.command === 'BAD' ? 'INVALID COMMAND' : command + ' FAILED');
36
+ return callback();
37
+ }
38
+ const message = found.message;
39
+ // RFC 8508 section 4.7: REPLACE takes a single message even with MULTIAPPEND. Nothing is
40
+ // changed if the new message can not be appended (section 3.4)
41
+ const prepared = (0, append_js_1.prepareAppend)(connection, parsed, data, pathArg, args, { command, maxMessages: 1, replaced: message });
42
+ if (!prepared) {
43
+ return callback();
44
+ }
45
+ const result = (0, append_js_1.storeMessages)(connection, prepared);
46
+ // Hook for UIDPLUS to send APPENDUID in an untagged OK before the EXPUNGE
47
+ // (RFC 8508 section 4.3). If UIDPLUS is not loaded, this is not sent
48
+ connection.send({
49
+ tag: '*',
50
+ command: 'OK',
51
+ attributes: [
52
+ {
53
+ type: 'TEXT',
54
+ value: 'Replacement message saved'
55
+ }
56
+ ],
57
+ skipResponse: true
58
+ }, 'REPLACE APPENDUID', parsed, data, result);
59
+ // only the replaced message is expunged, not every \Deleted message (RFC 8508 section 3.4).
60
+ // When the new message went to the selected mailbox, it was already announced with EXISTS
61
+ connection.expungeSpecificMessages(connection.selectedMailbox, [message], false, true);
62
+ connection.sendStatus(parsed, data, 'OK', command + ' completed', false, command);
63
+ callback();
64
+ };
65
+ // Refuse the literal of the new message when the message to replace is already known to be
66
+ // invalid, unless earlier commands are still running and could change the selected mailbox
67
+ server.literalFilters.push((connection, command, line) => {
68
+ if ((command !== 'REPLACE' && command !== 'UID REPLACE') || connection.isBusy()) {
69
+ return false;
70
+ }
71
+ const match = line.match(/^\S+ (?:UID )?REPLACE ([^ ]+) /i);
72
+ return (match && isSeqNumber(match[1]) && findMessage(connection, command === 'UID REPLACE', match[1]).error) || false;
73
+ });
74
+ // RFC 8508 section 3.5: valid only in the selected state, the second argument is the target mailbox
75
+ // the message can be a literal8 with BINARY: RFC 8508 section 6 uses append-message, whose append-data
76
+ // is a literal8 too (RFC 4466 section 2.7)
77
+ // REPLACE takes a message sequence number, UID REPLACE a UID
78
+ const options = { states: command_states_js_1.states.SELECTED, mailboxArguments: [1], literal8: 'BINARY', appendMessage: true };
79
+ server.setCommandHandler('REPLACE', replaceHandler.bind(null, false), Object.assign({ sequenceSet: 0 }, options));
80
+ server.setCommandHandler('UID REPLACE', replaceHandler.bind(null, true), options);
81
+ }
82
+ /**
83
+ * Finds the message to replace in the selected mailbox
84
+ *
85
+ * @param {Object} connection IMAPConnection
86
+ * @param {Boolean} uidMode If true, the value is a UID, otherwise a sequence number
87
+ * @param {String} value seq-number, a number or "*"
88
+ * @return {Object} `{ message }`, or `{ error: { command, text } }` if there is no such message
89
+ */
90
+ function findMessage(connection, uidMode, value) {
91
+ // sequence numbers refer to the message list this session knows about
92
+ const messages = connection.getSessionMessages();
93
+ let message;
94
+ if (uidMode) {
95
+ // "*" is the UID of the last message (RFC 3501 section 9, seq-number)
96
+ const uid = value === '*' ? (messages.length ? messages[messages.length - 1].uid : 0) : Number(value);
97
+ message = messages.find((item) => item.uid === uid);
98
+ }
99
+ else {
100
+ const seq = value === '*' ? messages.length : Number(value);
101
+ // RFC 3501 section 9, seq-number: a sequence number greater than the number of messages
102
+ // (or "*" in an empty mailbox) gets a tagged BAD
103
+ if (!seq || seq > messages.length) {
104
+ return { error: { command: 'BAD', text: 'Invalid message sequence number' } };
105
+ }
106
+ message = messages[seq - 1];
107
+ }
108
+ // RFC 8508 section 3.2: NO - can't remove specified message
109
+ if (!message || message.ghost) {
110
+ return { error: { command: 'NO', text: 'No such message' } };
111
+ }
112
+ // the old message is expunged, which is not allowed after EXAMINE
113
+ const readOnly = connection.readOnlyRefusal();
114
+ if (readOnly) {
115
+ return { error: readOnly };
116
+ }
117
+ return { message };
118
+ }
119
+ {
120
+ const defaultExport = exports.default;
121
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
122
+ for (const key of Object.keys(exports)) {
123
+ if (key !== 'default' && !(key in defaultExport)) {
124
+ defaultExport[key] = exports[key];
125
+ }
126
+ }
127
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
128
+ module.exports = defaultExport;
129
+ }
130
+ }
@@ -0,0 +1,5 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ /**
3
+ * @help Enables SASL-IR [RFC4959] capability
4
+ */
5
+ export default function saslIrPlugin(server: IMAPServer): void;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = saslIrPlugin;
4
+ /**
5
+ * @help Enables SASL-IR [RFC4959] capability
6
+ */
7
+ function saslIrPlugin(server) {
8
+ // Register capability, usable for non authenticated users
9
+ server.registerCapability('SASL-IR', (connection) => {
10
+ return connection.state === 'Not Authenticated';
11
+ });
12
+ }
13
+ {
14
+ const defaultExport = exports.default;
15
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
16
+ for (const key of Object.keys(exports)) {
17
+ if (key !== 'default' && !(key in defaultExport)) {
18
+ defaultExport[key] = exports[key];
19
+ }
20
+ }
21
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
22
+ module.exports = defaultExport;
23
+ }
24
+ }
@@ -0,0 +1,17 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ /**
3
+ * @help Adds SAVEDATE [RFC8514] capability
4
+ * @help Every message gets a save date when it is added to a mailbox (APPEND,
5
+ * @help COPY, MOVE, and when the storage is loaded), messages in storage can
6
+ * @help set it with a "SAVEDATE" value. A mailbox with "SAVEDATE": false in
7
+ * @help storage does not support save dates, FETCH returns NIL for its messages
8
+ *
9
+ * SAVEDATE: https://www.rfc-editor.org/rfc/rfc8514.txt
10
+ *
11
+ * Additional FETCH items:
12
+ * - SAVEDATE
13
+ *
14
+ * Additional SEARCH keys:
15
+ * - SAVEDBEFORE, SAVEDON, SAVEDSINCE, SAVEDATESUPPORTED
16
+ */
17
+ export default function savedatePlugin(server: IMAPServer): void;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = savedatePlugin;
4
+ const search_js_1 = require("../commands/handlers/search.js");
5
+ /**
6
+ * @help Adds SAVEDATE [RFC8514] capability
7
+ * @help Every message gets a save date when it is added to a mailbox (APPEND,
8
+ * @help COPY, MOVE, and when the storage is loaded), messages in storage can
9
+ * @help set it with a "SAVEDATE" value. A mailbox with "SAVEDATE": false in
10
+ * @help storage does not support save dates, FETCH returns NIL for its messages
11
+ *
12
+ * SAVEDATE: https://www.rfc-editor.org/rfc/rfc8514.txt
13
+ *
14
+ * Additional FETCH items:
15
+ * - SAVEDATE
16
+ *
17
+ * Additional SEARCH keys:
18
+ * - SAVEDBEFORE, SAVEDON, SAVEDSINCE, SAVEDATESUPPORTED
19
+ */
20
+ function savedatePlugin(server) {
21
+ server.registerCapability('SAVEDATE');
22
+ // RFC 8514 section 3: storage may lack save dates for some mailboxes
23
+ const isSupported = (mailbox) => !!mailbox && mailbox.SAVEDATE !== false;
24
+ // RFC 8514 section 3: the save date is the current time when the message is saved in a mailbox, it is
25
+ // never copied from the source message. Messages from storage may bring their own value.
26
+ server.messageHandlers.push((server, message, mailbox) => {
27
+ if (!isSupported(mailbox)) {
28
+ delete message.SAVEDATE;
29
+ return;
30
+ }
31
+ const savedate = server.normalizeDateTime(message.SAVEDATE || new Date());
32
+ if (!server.validateInternalDate(savedate)) {
33
+ throw new Error('Invalid SAVEDATE value ' + JSON.stringify(savedate) + ' in mailbox ' + mailbox.path);
34
+ }
35
+ message.SAVEDATE = savedate;
36
+ });
37
+ // RFC 8514 section 4.2: date-time, or NIL if the mailbox does not support save dates
38
+ server.fetchHandlers.SAVEDATE = (connection, message) => message.SAVEDATE || null;
39
+ const dateKey = (name, compare) => {
40
+ const handler = (connection, message, index, date) => {
41
+ // RFC 8514 section 4.3: without save dates the internal date is used instead
42
+ const saved = (0, search_js_1.getDateKey)(message.SAVEDATE || message.internaldate);
43
+ return !!saved && compare(saved, date);
44
+ };
45
+ handler.argumentTypes = () => ['date'];
46
+ server.searchHandlers[name] = handler;
47
+ };
48
+ dateKey('SAVEDBEFORE', (saved, date) => saved < date);
49
+ dateKey('SAVEDON', (saved, date) => saved === date);
50
+ dateKey('SAVEDSINCE', (saved, date) => saved >= date);
51
+ server.searchHandlers.SAVEDATESUPPORTED = (connection) => isSupported(connection.selectedMailbox);
52
+ }
53
+ {
54
+ const defaultExport = exports.default;
55
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
56
+ for (const key of Object.keys(exports)) {
57
+ if (key !== 'default' && !(key in defaultExport)) {
58
+ defaultExport[key] = exports[key];
59
+ }
60
+ }
61
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
62
+ module.exports = defaultExport;
63
+ }
64
+ }
@@ -0,0 +1,10 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ /**
3
+ * @help Adds SAVELIMIT [RFC9738] capability, advertised as SAVELIMIT=<n>
4
+ * @help Server option "messageLimit" sets n (default 1000). COPY and APPEND (MULTIAPPEND)
5
+ * @help of more messages fail with NO [MESSAGELIMIT ...], other commands are not limited.
6
+ * @help Can not be loaded with MESSAGELIMIT
7
+ *
8
+ * SAVELIMIT: https://www.rfc-editor.org/rfc/rfc9738
9
+ */
10
+ export default function savelimitPlugin(server: IMAPServer): void;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = savelimitPlugin;
4
+ const messagelimit_js_1 = require("./messagelimit.js");
5
+ /**
6
+ * @help Adds SAVELIMIT [RFC9738] capability, advertised as SAVELIMIT=<n>
7
+ * @help Server option "messageLimit" sets n (default 1000). COPY and APPEND (MULTIAPPEND)
8
+ * @help of more messages fail with NO [MESSAGELIMIT ...], other commands are not limited.
9
+ * @help Can not be loaded with MESSAGELIMIT
10
+ *
11
+ * SAVELIMIT: https://www.rfc-editor.org/rfc/rfc9738
12
+ */
13
+ function savelimitPlugin(server) {
14
+ // RFC 9738 section 3: a server that only limits COPY and APPEND (and their UID variants) advertises SAVELIMIT
15
+ const limit = (0, messagelimit_js_1.getLimit)(server, 'SAVELIMIT');
16
+ server.registerCapability('SAVELIMIT=' + limit);
17
+ (0, messagelimit_js_1.addSaveLimit)(server, limit);
18
+ }
19
+ {
20
+ const defaultExport = exports.default;
21
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
22
+ for (const key of Object.keys(exports)) {
23
+ if (key !== 'default' && !(key in defaultExport)) {
24
+ defaultExport[key] = exports[key];
25
+ }
26
+ }
27
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
28
+ module.exports = defaultExport;
29
+ }
30
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @help Adds SEARCHRES [RFC5182] capability, loads ESEARCH as well
3
+ * @help SEARCH RETURN (SAVE) stores the result, "$" refers to it in place of a sequence set
4
+ */
5
+ import type { IMAPServer } from '../types.js';
6
+ export default function searchresPlugin(server: IMAPServer): void;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * @help Adds SEARCHRES [RFC5182] capability, loads ESEARCH as well
4
+ * @help SEARCH RETURN (SAVE) stores the result, "$" refers to it in place of a sequence set
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 = searchresPlugin;
11
+ const esearch_js_1 = __importDefault(require("./esearch.js"));
12
+ const esearch_js_2 = require("../esearch.js");
13
+ // Commands after which the search result variable is empty (RFC 5182 section 2.1). After CLOSE and
14
+ // UNSELECT no mailbox is selected, so "$" can not be used until the next SELECT or EXAMINE anyway
15
+ const RESET_COMMANDS = new Set(['SELECT', 'EXAMINE', 'CLOSE', 'UNSELECT']);
16
+ // SAVE also applies to commands based on SEARCH, like SORT (RFC 5182 section 1) with ESORT
17
+ // and to the ESEARCH command of MULTISEARCH, which leaves the messages to save in `parsed.searchresFound`
18
+ const isSearch = (command) => ['SEARCH', 'UID SEARCH', 'SORT', 'UID SORT', 'ESEARCH'].includes(command);
19
+ function searchresPlugin(server) {
20
+ // a SEARCHRES server MUST also implement ESEARCH (RFC 5182 section 2.1)
21
+ (0, esearch_js_1.default)(server);
22
+ server.registerCapability('SEARCHRES');
23
+ // SAVE adds no data to the ESEARCH response
24
+ server.searchReturnOptions.set('SAVE', { data: false });
25
+ server.connectionHandlers.push((connection) => {
26
+ // RFC 5182 section 3: sequence-set =/ seq-last-command, seq-last-command = "$". Dovecot only accepts
27
+ // "$" as the whole sequence set, not combined with numbers like "1,$", and neither does ImapKit
28
+ const getMessageRange = connection.getMessageRange;
29
+ connection.getMessageRange = function (range, isUid) {
30
+ if (range !== '$') {
31
+ return getMessageRange.call(this, range, isUid);
32
+ }
33
+ // The search result variable holds message objects, so expunged messages drop out of it without
34
+ // renumbering, and it is the same set for UID and sequence number commands (RFC 5182 section 2.1).
35
+ // As "$" holds no sequence numbers, core lets it be pipelined (RFC 5182 section 2.3)
36
+ const saved = this.searchResult || new Set();
37
+ const result = [];
38
+ this.getSessionMessages().forEach((message, i) => {
39
+ if (saved.has(message)) {
40
+ result.push([i + 1, message]);
41
+ }
42
+ });
43
+ return result;
44
+ };
45
+ });
46
+ // RFC 8437 section 4.1: after UNAUTHENTICATE "$" represents the empty set
47
+ server.resetHandlers.push((connection) => {
48
+ connection.searchResult = null;
49
+ });
50
+ server.outputHandlers.push((connection, response, description, parsed, data, extra) => {
51
+ if (!parsed || !response || (response.tag !== parsed.tag && response.command !== 'SEARCH' && response.command !== 'SORT')) {
52
+ return;
53
+ }
54
+ const command = (parsed.command || '').toUpperCase();
55
+ const save = isSearch(command) && parsed.searchReturn && parsed.searchReturn.has('SAVE');
56
+ // the result of SEARCH, with MIN and/or MAX only these messages are saved (RFC 5182 section 2.4).
57
+ // It is stored once the tagged response tells if the command succeeded
58
+ if (save &&
59
+ response.tag === '*' &&
60
+ (response.command === 'SEARCH' || response.command === 'SORT') &&
61
+ description === command &&
62
+ extra &&
63
+ Array.isArray(extra.list)) {
64
+ parsed.searchresFound = (0, esearch_js_2.selectReturned)(extra.sorted || extra.list, parsed.searchReturn);
65
+ return;
66
+ }
67
+ if (response.tag !== parsed.tag) {
68
+ return;
69
+ }
70
+ if (RESET_COMMANDS.has(command)) {
71
+ connection.searchResult = null;
72
+ return;
73
+ }
74
+ // RFC 5182 section 2.1: an OK sets the variable, a NO empties it and a BAD leaves it as it was
75
+ if (save && response.command !== 'BAD') {
76
+ connection.searchResult = new Set(response.command === 'OK' ? parsed.searchresFound : []);
77
+ }
78
+ });
79
+ }
80
+ {
81
+ const defaultExport = exports.default;
82
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
83
+ for (const key of Object.keys(exports)) {
84
+ if (key !== 'default' && !(key in defaultExport)) {
85
+ defaultExport[key] = exports[key];
86
+ }
87
+ }
88
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
89
+ module.exports = defaultExport;
90
+ }
91
+ }