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,422 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = xGmExt1Plugin;
7
+ const search_js_1 = __importDefault(require("../commands/handlers/search.js"));
8
+ const search_js_2 = require("../commands/handlers/search.js");
9
+ const dates_js_1 = require("../dates.js");
10
+ // X-GM-MSGID is a 64 bit unsigned number, so it is tracked as a BigInt
11
+ // Sample value from Gmail IMAP extensions API page
12
+ // https://developers.google.com/workspace/gmail/imap/imap-extensions
13
+ // Used as default, if server.options["HIGHESTX-GM-MSGID"]
14
+ // is missing
15
+ const SEED = '1278455344230334865';
16
+ const MAX_UINT64 = 2n ** 64n - 1n;
17
+ // X-GM-RAW mailbox shortcuts of in: and is: (Gmail search operators), as ImapKit criteria
18
+ const RAW_SHORTCUTS = {
19
+ 'in:inbox': ['X-GM-LABELS', '\\Inbox'],
20
+ 'in:sent': ['X-GM-LABELS', '\\Sent'],
21
+ 'in:drafts': ['X-GM-LABELS', '\\Drafts'],
22
+ 'in:trash': ['X-GM-LABELS', '\\Trash'],
23
+ 'in:spam': ['X-GM-LABELS', '\\Junk'],
24
+ 'in:anywhere': ['ALL'],
25
+ 'is:unread': ['UNSEEN'],
26
+ 'is:read': ['SEEN'],
27
+ 'is:starred': ['FLAGGED'],
28
+ 'is:important': ['X-GM-LABELS', '\\Important']
29
+ };
30
+ // X-GM-RAW operators that take a value, as the search key the value is given to
31
+ const RAW_OPERATORS = {
32
+ from: 'FROM',
33
+ to: 'TO',
34
+ cc: 'CC',
35
+ bcc: 'BCC',
36
+ subject: 'SUBJECT',
37
+ label: 'X-GM-LABELS',
38
+ larger: 'LARGER',
39
+ smaller: 'SMALLER',
40
+ after: 'SINCE',
41
+ before: 'BEFORE',
42
+ rfc822msgid: 'HEADER'
43
+ };
44
+ // Gmail operators that ImapKit does not implement, answered with NO instead of a wrong result
45
+ const RAW_UNSUPPORTED = ['is', 'has', 'list', 'filename', 'around', 'size', 'older', 'newer', 'older_than', 'newer_than', 'deliveredto', 'category'];
46
+ /**
47
+ * @help Adds Gmail specific X-GM-EXT-1 capability
48
+ * @help (https://developers.google.com/workspace/gmail/imap/imap-extensions)
49
+ * @help X-GM-MSGID and X-GM-THRID: FETCH and SEARCH. X-GM-THRID is the
50
+ * @help X-GM-MSGID of the message unless storage sets an X-GM-THRID
51
+ * @help value, so every message is its own thread unless the
52
+ * @help fixture groups messages. With OBJECTID, the messages of a
53
+ * @help THREADID share the X-GM-THRID of its first message
54
+ * @help X-GM-LABELS: FETCH, STORE (+/-, .SILENT) and SEARCH. System
55
+ * @help labels are atoms that start with "\" (\Inbox for INBOX, the
56
+ * @help special-use attribute for special-use mailboxes), other labels
57
+ * @help are mailbox names, sent like mailbox names (modified UTF-7, or
58
+ * @help UTF-8 after ENABLE UTF8=ACCEPT, quoted when not atoms). Labels
59
+ * @help have no side effects: the message is not copied to or removed
60
+ * @help from other mailboxes. In SEARCH a label that starts with "\"
61
+ * @help is a system label
62
+ * @help X-GM-RAW: a subset of the Gmail search syntax. Words and "quoted
63
+ * @help phrases" (TEXT), -term, OR, (groups), {any of}, from: to: cc:
64
+ * @help bcc: subject: label: in: (inbox sent drafts trash spam
65
+ * @help anywhere, or a label) is: (read unread starred important)
66
+ * @help larger: smaller: (k and m suffixes) after: before:
67
+ * @help (YYYY/MM/DD) and rfc822msgid:. Other Gmail operators are
68
+ * @help answered with NO
69
+ */
70
+ function xGmExt1Plugin(server) {
71
+ server.registerCapability('X-GM-EXT-1');
72
+ server['HIGHESTX-GM-MSGID'] = BigInt(server.options['HIGHESTX-GM-MSGID'] || SEED);
73
+ // set X-GM-MSGID values when message is created / initialized
74
+ server.messageHandlers.push((server, message, mailbox) => {
75
+ let labels;
76
+ if (!message['X-GM-MSGID']) {
77
+ server['HIGHESTX-GM-MSGID'] += 1n;
78
+ message['X-GM-MSGID'] = server['HIGHESTX-GM-MSGID'].toString();
79
+ }
80
+ else if (/^\d+$/.test(message['X-GM-MSGID']) && BigInt(message['X-GM-MSGID']) > server['HIGHESTX-GM-MSGID']) {
81
+ // Storage might be shared with another server instance, do not reuse existing values
82
+ server['HIGHESTX-GM-MSGID'] = BigInt(message['X-GM-MSGID']);
83
+ }
84
+ // Ensure message has an array of labels
85
+ message['X-GM-LABELS'] = [].concat(message['X-GM-LABELS'] || []);
86
+ if (mailbox.path.toUpperCase() === 'INBOX') {
87
+ labels = ['\\Inbox'];
88
+ }
89
+ else if (mailbox['special-use'] && mailbox['special-use'].length) {
90
+ labels = [].concat(mailbox['special-use']);
91
+ }
92
+ else {
93
+ labels = [userLabel(mailbox.path)];
94
+ }
95
+ labels.forEach(label => {
96
+ server.ensureFlag(message['X-GM-LABELS'], label);
97
+ });
98
+ });
99
+ // A message starts its own thread unless storage puts it into one. With OBJECTID loaded, the messages of a THREADID
100
+ // (RFC 8474 section 5.2) share an X-GM-THRID: the one of the first message of that thread, like Gmail uses the
101
+ // X-GM-MSGID of the first message. This runs after every other message handler, so OBJECTID set the THREADID
102
+ // already, whatever the load order is
103
+ const gmThreads = new Map();
104
+ server.once('pluginsLoaded', () => {
105
+ server.messageHandlers.push((server, message) => {
106
+ const known = message.THREADID && gmThreads.get(message.THREADID);
107
+ if (!message['X-GM-THRID']) {
108
+ message['X-GM-THRID'] = known || message['X-GM-MSGID'];
109
+ }
110
+ if (message.THREADID && !known) {
111
+ gmThreads.set(message.THREADID, message['X-GM-THRID']);
112
+ }
113
+ });
114
+ });
115
+ // Retrieve X-GM-MSGID values with FETCH
116
+ server.fetchHandlers['X-GM-MSGID'] = function (connection, message) {
117
+ return {
118
+ type: 'ATOM',
119
+ value: message['X-GM-MSGID']
120
+ };
121
+ };
122
+ // Retrieve X-GM-LABELS values with FETCH
123
+ server.fetchHandlers['X-GM-LABELS'] = function (connection, message) {
124
+ return formatLabels(message);
125
+ };
126
+ // X-GM-MSGID and X-GM-THRID are 64 bit unsigned numbers
127
+ const idArgument = () => [
128
+ (value) => {
129
+ if (!/^\d{1,20}$/.test(value) || BigInt(value) > MAX_UINT64) {
130
+ throw (0, search_js_2.badError)('Expected a 64 bit unsigned number');
131
+ }
132
+ return BigInt(value).toString();
133
+ }
134
+ ];
135
+ server.searchHandlers['X-GM-MSGID'] = function (connection, message, sequence, xGmMsgid) {
136
+ return message['X-GM-MSGID'] === xGmMsgid;
137
+ };
138
+ server.searchHandlers['X-GM-MSGID'].argumentTypes = idArgument;
139
+ // Retrieve X-GM-THRID values with FETCH
140
+ server.fetchHandlers['X-GM-THRID'] = function (connection, message) {
141
+ return {
142
+ type: 'ATOM',
143
+ value: message['X-GM-THRID']
144
+ };
145
+ };
146
+ server.searchHandlers['X-GM-THRID'] = function (connection, message, sequence, xGmThrid) {
147
+ return message['X-GM-THRID'] === xGmThrid;
148
+ };
149
+ server.searchHandlers['X-GM-THRID'].argumentTypes = idArgument;
150
+ // SEARCH X-GM-LABELS label, the label is given in the form the session uses for mailbox names
151
+ server.searchHandlers['X-GM-LABELS'] = function (connection, message, sequence, label) {
152
+ return message['X-GM-LABELS'].some((stored) => {
153
+ if (isSystemLabel(stored)) {
154
+ // system labels are matched without case, like flags
155
+ return stored.toLowerCase() === label.toLowerCase();
156
+ }
157
+ return connection.exportMailboxName(labelName(stored)) === label;
158
+ });
159
+ };
160
+ // SEARCH X-GM-RAW query, a subset of the Gmail search syntax
161
+ // the translated criteria are compiled once per SEARCH, they are the same array for every message
162
+ const rawMatchers = new WeakMap();
163
+ server.searchHandlers['X-GM-RAW'] = function (connection, message, sequence, criteria) {
164
+ if (!rawMatchers.has(criteria)) {
165
+ // without UTF8=ACCEPT the translated criteria take a CHARSET, Gmail queries are UTF-8
166
+ const params = connection.searchCharset ? criteria : ['CHARSET', 'UTF-8'].concat(criteria);
167
+ rawMatchers.set(criteria, (0, search_js_1.default)(connection, [], params, () => []).matches);
168
+ }
169
+ return rawMatchers.get(criteria)(message, sequence);
170
+ };
171
+ server.searchHandlers['X-GM-RAW'].argumentTypes = () => [parseRawQuery];
172
+ const setLabels = (message, labels) => {
173
+ message['X-GM-LABELS'] = [];
174
+ addLabels(message, labels);
175
+ };
176
+ const addLabels = (message, labels) => {
177
+ labels.forEach((label) => server.ensureFlag(message['X-GM-LABELS'], label));
178
+ };
179
+ const removeLabels = (message, labels) => {
180
+ labels.forEach((label) => server.removeFlag(message['X-GM-LABELS'], label));
181
+ };
182
+ [
183
+ ['X-GM-LABELS', setLabels],
184
+ ['+X-GM-LABELS', addLabels],
185
+ ['-X-GM-LABELS', removeLabels]
186
+ ].forEach(([name, update]) => {
187
+ // all labels are parsed before the message changes, an invalid one fails the STORE
188
+ const apply = (connection, message, flags) => update(message, flags.map(flag => parseLabel(connection, flag)));
189
+ server.storeHandlers[name] = function (connection, message, flags, index, parsed, data) {
190
+ apply(connection, message, flags);
191
+ sendLabelUpdate(connection, parsed, data, index, message);
192
+ };
193
+ server.storeHandlers[name + '.SILENT'] = apply;
194
+ // labels are astrings (Gmail IMAP extensions): literals are accepted, NIL is a label name
195
+ server.storeHandlers[name].astringValues = server.storeHandlers[name + '.SILENT'].astringValues = true;
196
+ });
197
+ // Gmail keeps the same X-GM-MSGID for a message in every mailbox, so copies get the value of the source message
198
+ server.copyHandlers.push((server, source, copy) => {
199
+ if (source['X-GM-MSGID']) {
200
+ copy['X-GM-MSGID'] = source['X-GM-MSGID'];
201
+ copy['X-GM-THRID'] = source['X-GM-THRID'];
202
+ }
203
+ });
204
+ }
205
+ /**
206
+ * Labels are kept as strings in message["X-GM-LABELS"]. A system label like \Inbox starts with "\",
207
+ * any other label is a mailbox name in storage form. A mailbox name that itself starts with "\" is
208
+ * kept with one more "\" in front, so it can not be mistaken for a system label
209
+ */
210
+ const isSystemLabel = (label) => label.charAt(0) === '\\' && label.charAt(1) !== '\\';
211
+ const userLabel = (name) => (name.charAt(0) === '\\' ? '\\' + name : name);
212
+ const labelName = (label) => (label.charAt(0) === '\\' ? label.substr(1) : label);
213
+ /**
214
+ * Converts a STORE X-GM-LABELS value to a stored label. An atom that starts with "\" is a system
215
+ * label, anything else is a label name: an astring in the form the session uses for mailbox names
216
+ *
217
+ * @param {Object} connection IMAP connection
218
+ * @param {Object} attr Parsed value
219
+ * @return {String} Stored label
220
+ */
221
+ function parseLabel(connection, attr) {
222
+ const value = String((attr && attr.value) || '');
223
+ if (attr.type === 'ATOM' && value.charAt(0) === '\\') {
224
+ return value;
225
+ }
226
+ return userLabel(connection.importMailboxName(value));
227
+ }
228
+ /**
229
+ * Formats the labels of a message for a FETCH response. Label names are MAILBOX attributes, so the
230
+ * session gets them in its own form and quoted when they are not atoms
231
+ */
232
+ function formatLabels(message) {
233
+ return message['X-GM-LABELS'].map((label) => isSystemLabel(label) ? { type: 'ATOM', value: label } : { type: 'MAILBOX', value: labelName(label) });
234
+ }
235
+ /**
236
+ * Translates an X-GM-RAW query (Gmail search syntax) to ImapKit search criteria. Terms are
237
+ * ANDed, OR binds tighter than that ("a b OR c" is a AND (b OR c)), "-" negates a term, ( ) groups
238
+ * terms and { } matches any of its terms.
239
+ *
240
+ * @param {String} query Query as a binary string, UTF-8
241
+ * @return {Array} Search criteria
242
+ * @throws {Error} BAD for a query that can not be parsed, NO for an unsupported operator
243
+ */
244
+ function parseRawQuery(query) {
245
+ const tokens = [];
246
+ const re = /\s*(?:([(){}])|"([^"]*)"|([^\s(){}"]+?:)"([^"]*)"|([^\s(){}"]+))/gy;
247
+ let match;
248
+ // end of the last token, a failed sticky match resets lastIndex
249
+ let end = 0;
250
+ while (end < query.length && (match = re.exec(query))) {
251
+ end = re.lastIndex;
252
+ if (match[1]) {
253
+ tokens.push({ type: match[1] });
254
+ }
255
+ else if (typeof match[2] === 'string') {
256
+ tokens.push({ type: 'word', value: match[2] });
257
+ }
258
+ else if (match[3]) {
259
+ tokens.push({ type: 'word', value: match[3] + match[4], operator: match[3].slice(0, -1), operand: match[4] });
260
+ }
261
+ else {
262
+ tokens.push({ type: 'word', value: match[5] });
263
+ }
264
+ }
265
+ if (query.slice(end).trim()) {
266
+ throw (0, search_js_2.badError)('X-GM-RAW query has an unterminated quoted string');
267
+ }
268
+ let pos = 0;
269
+ const peek = () => tokens[pos];
270
+ // expression = 1*term, until the end or a closing bracket
271
+ const expression = (end) => {
272
+ const terms = [];
273
+ while (pos < tokens.length && (!peek() || peek().type !== end)) {
274
+ terms.push(term());
275
+ }
276
+ if (end) {
277
+ if (!peek() || peek().type !== end) {
278
+ throw (0, search_js_2.badError)('X-GM-RAW query is missing "' + end + '"');
279
+ }
280
+ pos++;
281
+ }
282
+ if (!terms.length) {
283
+ throw (0, search_js_2.badError)('X-GM-RAW query is empty');
284
+ }
285
+ return terms.length === 1 ? terms[0] : terms;
286
+ };
287
+ // term = unary *("OR" unary)
288
+ const term = () => {
289
+ let result = unary();
290
+ while (peek() && peek().type === 'word' && peek().value === 'OR' && tokens[pos + 1]) {
291
+ pos++;
292
+ result = ['OR', result, unary()];
293
+ }
294
+ return result;
295
+ };
296
+ const unary = () => {
297
+ const token = tokens[pos++];
298
+ if (!token || token.type === ')' || token.type === '}') {
299
+ throw (0, search_js_2.badError)('Unexpected end of X-GM-RAW query');
300
+ }
301
+ if (token.type === '(') {
302
+ return expression(')');
303
+ }
304
+ if (token.type === '{') {
305
+ const options = [];
306
+ while (peek() && peek().type !== '}') {
307
+ options.push(unary());
308
+ }
309
+ if (!peek() || !options.length) {
310
+ throw (0, search_js_2.badError)('X-GM-RAW query has an empty or unterminated { } group');
311
+ }
312
+ pos++;
313
+ return options.reduce((any, option) => ['OR', any, option]);
314
+ }
315
+ // the brackets are handled above, a word always has a value
316
+ const value = token.value;
317
+ if (value === '-' && peek() && (peek().type === '(' || peek().type === '{')) {
318
+ return ['NOT', unary()];
319
+ }
320
+ if (value.charAt(0) === '-' && value.length > 1) {
321
+ return ['NOT', rawTerm(rawWord(value.substr(1)))];
322
+ }
323
+ return rawTerm(token);
324
+ };
325
+ return [expression()];
326
+ }
327
+ // splits "name:value" into an operator and an operand
328
+ function rawWord(value) {
329
+ const match = value.match(/^([a-z_0-9]+):(.+)$/i);
330
+ return match ? { value, operator: match[1], operand: match[2] } : { value, operator: false, operand: false };
331
+ }
332
+ function rawTerm(token) {
333
+ const word = token.operator ? token : rawWord(token.value);
334
+ const operator = word.operator;
335
+ if (!operator) {
336
+ return ['TEXT', token.value];
337
+ }
338
+ // an operator always comes with its operand
339
+ const operand = word.operand;
340
+ const name = operator.toLowerCase();
341
+ // own keys only, names like "constructor:" are plain text
342
+ const shortcutKey = name + ':' + operand.toLowerCase();
343
+ const shortcut = Object.hasOwn(RAW_SHORTCUTS, shortcutKey) && RAW_SHORTCUTS[shortcutKey];
344
+ if (shortcut) {
345
+ return shortcut;
346
+ }
347
+ const key = Object.hasOwn(RAW_OPERATORS, name) && RAW_OPERATORS[name];
348
+ if (key) {
349
+ switch (key) {
350
+ case 'LARGER':
351
+ case 'SMALLER': {
352
+ const size = operand.match(/^(\d+)([km]?)$/i);
353
+ if (!size) {
354
+ throw (0, search_js_2.badError)('X-GM-RAW ' + name + ': expects a size');
355
+ }
356
+ return [key, String(Number(size[1]) * { '': 1, k: 1024, m: 1024 * 1024 }[size[2].toLowerCase()])];
357
+ }
358
+ case 'SINCE':
359
+ case 'BEFORE': {
360
+ const date = operand.match(/^(\d{4})[/-](\d{1,2})[/-](\d{1,2})$/);
361
+ if (!date || !(0, dates_js_1.isRealDate)(Number(date[3]), Number(date[2]) - 1, Number(date[1]))) {
362
+ throw (0, search_js_2.badError)('X-GM-RAW ' + name + ': expects a date as YYYY/MM/DD');
363
+ }
364
+ return [key, Number(date[3]) + '-' + dates_js_1.MONTHS[Number(date[2]) - 1] + '-' + date[1]];
365
+ }
366
+ case 'HEADER':
367
+ return [key, 'Message-ID', operand];
368
+ default:
369
+ return [key, operand];
370
+ }
371
+ }
372
+ if (name === 'in') {
373
+ // any other mailbox is a label
374
+ return ['X-GM-LABELS', operand];
375
+ }
376
+ if (RAW_UNSUPPORTED.indexOf(name) >= 0) {
377
+ const err = new Error('X-GM-RAW operator ' + name + ':' + operand + ' is not supported by imapkit');
378
+ err.imapResponse = 'NO';
379
+ throw err;
380
+ }
381
+ // not an operator, like "http://example.com"
382
+ return ['TEXT', token.value];
383
+ }
384
+ function sendLabelUpdate(connection, parsed, data, index, message) {
385
+ const resp = [
386
+ {
387
+ type: 'ATOM',
388
+ value: 'X-GM-LABELS'
389
+ },
390
+ formatLabels(message)
391
+ ];
392
+ if ((parsed.command || '').toUpperCase() === 'UID STORE') {
393
+ resp.push({
394
+ type: 'ATOM',
395
+ value: 'UID'
396
+ });
397
+ resp.push(message.uid);
398
+ }
399
+ connection.send({
400
+ tag: '*',
401
+ attributes: [
402
+ index,
403
+ {
404
+ type: 'ATOM',
405
+ value: 'FETCH'
406
+ },
407
+ resp
408
+ ]
409
+ }, 'FLAG UPDATE', parsed, data, message);
410
+ }
411
+ {
412
+ const defaultExport = exports.default;
413
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
414
+ for (const key of Object.keys(exports)) {
415
+ if (key !== 'default' && !(key in defaultExport)) {
416
+ defaultExport[key] = exports[key];
417
+ }
418
+ }
419
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
420
+ module.exports = defaultExport;
421
+ }
422
+ }
@@ -0,0 +1,2 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ export default function xoauth2Plugin(server: IMAPServer): void;
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = xoauth2Plugin;
4
+ // https://developers.google.com/gmail/xoauth2_protocol
5
+ /**
6
+ * @help Enables XOAUTH2 capability
7
+ * @help Implementation difference - ImapKit requires
8
+ * @help SASL-IR enabled and used while Gmail does not
9
+ * @help Valid login info:
10
+ * @help Username: testuser
11
+ * @help Access Token: testtoken
12
+ */
13
+ const utf8 = new TextDecoder('utf-8', { fatal: true });
14
+ function xoauth2Plugin(server) {
15
+ // Register capability, usable for non authenticated users
16
+ server.registerCapability('AUTH=XOAUTH2', (connection) => {
17
+ return connection.state === 'Not Authenticated';
18
+ });
19
+ server.setCommandHandler('AUTHENTICATE XOAUTH2', (connection, parsed, data, callback) => {
20
+ if (!server.capabilities['SASL-IR'] || !server.capabilities['SASL-IR'](connection)) {
21
+ connection.send({
22
+ tag: parsed.tag,
23
+ command: 'BAD',
24
+ attributes: [
25
+ {
26
+ type: 'TEXT',
27
+ value: 'SASL-IR must be enabled to support XOAUTH2'
28
+ }
29
+ ]
30
+ }, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
31
+ return callback();
32
+ }
33
+ if (!parsed.attributes || parsed.attributes.length !== 1 || !parsed.attributes[0] || ['STRING', 'ATOM'].indexOf(parsed.attributes[0].type) < 0) {
34
+ connection.send({
35
+ tag: parsed.tag,
36
+ command: 'NO',
37
+ attributes: [
38
+ {
39
+ type: 'TEXT',
40
+ value: 'Invalid SASL argument'
41
+ }
42
+ ]
43
+ }, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
44
+ return callback();
45
+ }
46
+ const decoded = connection.decodeSaslResponse(parsed.attributes[0].value);
47
+ if (!decoded) {
48
+ connection.sendStatus(parsed, data, 'BAD', 'Invalid base64 in SASL response', false, 'AUTHENTICATE XOAUTH2 FAILED');
49
+ return callback();
50
+ }
51
+ let parts = [];
52
+ try {
53
+ // user names are unicode strings, like the keys of `users`
54
+ parts = utf8.decode(decoded).split('\x01');
55
+ }
56
+ catch {
57
+ // invalid UTF-8 is a malformed payload like any other
58
+ }
59
+ const user = (parts[0] || '').substr(5);
60
+ const accessToken = (parts[1] || '').substr(12);
61
+ if (parts.length !== 4 ||
62
+ !parts[0].match(/^user=/) ||
63
+ !parts[1].match(/^auth=Bearer /) ||
64
+ !user || // Must be present
65
+ !accessToken || // Must be present
66
+ parts[2] || // Must be empty
67
+ parts[3] // Must be empty
68
+ ) {
69
+ connection.send({
70
+ tag: parsed.tag,
71
+ command: 'NO',
72
+ attributes: [
73
+ {
74
+ type: 'TEXT',
75
+ value: 'Invalid SASL argument.'
76
+ }
77
+ ]
78
+ }, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
79
+ return callback();
80
+ }
81
+ const userData = connection.server.getUser(user);
82
+ if (!userData) {
83
+ connection.send({
84
+ tag: parsed.tag,
85
+ command: 'NO',
86
+ attributes: [
87
+ // RFC 5530 section 3: unknown user or bad token
88
+ { type: 'SECTION', section: [{ type: 'ATOM', value: 'AUTHENTICATIONFAILED' }] },
89
+ {
90
+ type: 'TEXT',
91
+ value: 'Invalid credentials'
92
+ }
93
+ ]
94
+ }, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
95
+ return callback();
96
+ }
97
+ if (!userData.xoauth2 || userData.xoauth2.accessToken !== accessToken) {
98
+ connection.send({
99
+ tag: '+',
100
+ attributes: [
101
+ {
102
+ type: 'ATOM',
103
+ value: Buffer.from(JSON.stringify({
104
+ status: '400',
105
+ schemes: 'Bearer',
106
+ scope: 'https://mail.google.com/'
107
+ })).toString('base64')
108
+ }
109
+ ]
110
+ }, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
111
+ // wait for response
112
+ connection.inputHandler = function () {
113
+ connection.inputHandler = false;
114
+ connection.send({
115
+ tag: parsed.tag,
116
+ command: 'NO',
117
+ attributes: [
118
+ { type: 'SECTION', section: [{ type: 'ATOM', value: 'AUTHENTICATIONFAILED' }] },
119
+ {
120
+ type: 'TEXT',
121
+ value: 'SASL authentication failed'
122
+ }
123
+ ]
124
+ }, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
125
+ };
126
+ }
127
+ else {
128
+ connection.state = 'Authenticated';
129
+ connection.username = user;
130
+ connection.send({
131
+ tag: parsed.tag,
132
+ command: 'OK',
133
+ attributes: [
134
+ {
135
+ type: 'TEXT',
136
+ value: 'User logged in'
137
+ }
138
+ ]
139
+ }, 'AUTHENTICATE XOAUTH2 SUCCESS', parsed, data);
140
+ }
141
+ return callback();
142
+ });
143
+ }
144
+ {
145
+ const defaultExport = exports.default;
146
+ if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
147
+ for (const key of Object.keys(exports)) {
148
+ if (key !== 'default' && !(key in defaultExport)) {
149
+ defaultExport[key] = exports[key];
150
+ }
151
+ }
152
+ Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
153
+ module.exports = defaultExport;
154
+ }
155
+ }
@@ -0,0 +1,2 @@
1
+ import type { IMAPServer } from '../types.js';
2
+ export default function xtoybirdPlugin(server: IMAPServer): void;