imapkit 4.0.3 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -19
- package/bin/imapkit.js +12 -16
- package/dist/cjs/addressparser.d.ts +21 -0
- package/dist/cjs/addressparser.js +277 -0
- package/dist/cjs/arguments.d.ts +31 -0
- package/{lib → dist/cjs}/arguments.js +9 -21
- package/dist/cjs/bodystructure.d.ts +25 -0
- package/dist/cjs/bodystructure.js +150 -0
- package/dist/cjs/cert.d.ts +2 -0
- package/dist/cjs/cert.js +7 -0
- package/dist/cjs/command-states.d.ts +36 -0
- package/dist/cjs/command-states.js +102 -0
- package/dist/cjs/commands/append.d.ts +88 -0
- package/dist/cjs/commands/append.js +299 -0
- package/dist/cjs/commands/capability.d.ts +2 -0
- package/dist/cjs/commands/capability.js +44 -0
- package/dist/cjs/commands/check.d.ts +2 -0
- package/dist/cjs/commands/check.js +28 -0
- package/dist/cjs/commands/close.d.ts +2 -0
- package/dist/cjs/commands/close.js +35 -0
- package/dist/cjs/commands/copy.d.ts +30 -0
- package/dist/cjs/commands/copy.js +107 -0
- package/dist/cjs/commands/create.d.ts +2 -0
- package/dist/cjs/commands/create.js +53 -0
- package/dist/cjs/commands/delete.d.ts +2 -0
- package/dist/cjs/commands/delete.js +63 -0
- package/dist/cjs/commands/examine.d.ts +2 -0
- package/dist/cjs/commands/examine.js +19 -0
- package/dist/cjs/commands/expunge.d.ts +2 -0
- package/dist/cjs/commands/expunge.js +32 -0
- package/dist/cjs/commands/fetch.d.ts +23 -0
- package/dist/cjs/commands/fetch.js +208 -0
- package/dist/cjs/commands/handlers/fetch.d.ts +12 -0
- package/dist/cjs/commands/handlers/fetch.js +195 -0
- package/dist/cjs/commands/handlers/flags.d.ts +17 -0
- package/dist/cjs/commands/handlers/flags.js +39 -0
- package/dist/cjs/commands/handlers/search.d.ts +85 -0
- package/dist/cjs/commands/handlers/search.js +504 -0
- package/dist/cjs/commands/handlers/status.d.ts +34 -0
- package/dist/cjs/commands/handlers/status.js +81 -0
- package/dist/cjs/commands/handlers/store.d.ts +3 -0
- package/dist/cjs/commands/handlers/store.js +117 -0
- package/dist/cjs/commands/index.d.ts +2 -0
- package/dist/cjs/commands/index.js +61 -0
- package/dist/cjs/commands/list.d.ts +2 -0
- package/dist/cjs/commands/list.js +86 -0
- package/dist/cjs/commands/login.d.ts +2 -0
- package/dist/cjs/commands/login.js +62 -0
- package/dist/cjs/commands/logout.d.ts +2 -0
- package/dist/cjs/commands/logout.js +40 -0
- package/dist/cjs/commands/lsub.d.ts +2 -0
- package/dist/cjs/commands/lsub.js +79 -0
- package/dist/cjs/commands/noop.d.ts +2 -0
- package/dist/cjs/commands/noop.js +28 -0
- package/dist/cjs/commands/rename.d.ts +2 -0
- package/dist/cjs/commands/rename.js +98 -0
- package/dist/cjs/commands/search.d.ts +10 -0
- package/dist/cjs/commands/search.js +71 -0
- package/dist/cjs/commands/select.d.ts +19 -0
- package/dist/cjs/commands/select.js +230 -0
- package/dist/cjs/commands/status.d.ts +2 -0
- package/dist/cjs/commands/status.js +57 -0
- package/dist/cjs/commands/store.d.ts +10 -0
- package/dist/cjs/commands/store.js +134 -0
- package/dist/cjs/commands/subscribe.d.ts +2 -0
- package/dist/cjs/commands/subscribe.js +51 -0
- package/dist/cjs/commands/uid-copy.d.ts +2 -0
- package/dist/cjs/commands/uid-copy.js +19 -0
- package/dist/cjs/commands/uid-fetch.d.ts +3 -0
- package/dist/cjs/commands/uid-fetch.js +17 -0
- package/dist/cjs/commands/uid-search.d.ts +3 -0
- package/dist/cjs/commands/uid-search.js +17 -0
- package/dist/cjs/commands/uid-store.d.ts +3 -0
- package/dist/cjs/commands/uid-store.js +17 -0
- package/dist/cjs/commands/unsubscribe.d.ts +2 -0
- package/dist/cjs/commands/unsubscribe.js +50 -0
- package/dist/cjs/dates.d.ts +64 -0
- package/dist/cjs/dates.js +124 -0
- package/dist/cjs/deflate-layer.d.ts +83 -0
- package/dist/cjs/deflate-layer.js +232 -0
- package/dist/cjs/encoded-words.d.ts +15 -0
- package/dist/cjs/encoded-words.js +85 -0
- package/dist/cjs/envelope.d.ts +33 -0
- package/dist/cjs/envelope.js +86 -0
- package/dist/cjs/esearch.d.ts +96 -0
- package/dist/cjs/esearch.js +190 -0
- package/dist/cjs/framing.d.ts +66 -0
- package/{lib → dist/cjs}/framing.js +9 -26
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.js +56 -0
- package/dist/cjs/list-extensions.d.ts +50 -0
- package/dist/cjs/list-extensions.js +35 -0
- package/dist/cjs/load-plugins.d.ts +21 -0
- package/dist/cjs/load-plugins.js +89 -0
- package/dist/cjs/mailbox-name.d.ts +26 -0
- package/dist/cjs/mailbox-name.js +127 -0
- package/dist/cjs/mimeparser.d.ts +137 -0
- package/dist/cjs/mimeparser.js +727 -0
- package/dist/cjs/mock-client.d.ts +39 -0
- package/dist/cjs/mock-client.js +236 -0
- package/dist/cjs/numbers.d.ts +28 -0
- package/dist/cjs/numbers.js +52 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/plugins/acl.d.ts +2 -0
- package/dist/cjs/plugins/acl.js +888 -0
- package/dist/cjs/plugins/appendlimit.d.ts +16 -0
- package/dist/cjs/plugins/appendlimit.js +87 -0
- package/dist/cjs/plugins/auth-plain.d.ts +2 -0
- package/dist/cjs/plugins/auth-plain.js +89 -0
- package/dist/cjs/plugins/binary.d.ts +30 -0
- package/dist/cjs/plugins/binary.js +247 -0
- package/dist/cjs/plugins/catenate.d.ts +14 -0
- package/dist/cjs/plugins/catenate.js +250 -0
- package/dist/cjs/plugins/compress.d.ts +7 -0
- package/dist/cjs/plugins/compress.js +79 -0
- package/dist/cjs/plugins/condstore.d.ts +5 -0
- package/dist/cjs/plugins/condstore.js +492 -0
- package/dist/cjs/plugins/context-search.d.ts +8 -0
- package/dist/cjs/plugins/context-search.js +304 -0
- package/dist/cjs/plugins/context-sort.d.ts +6 -0
- package/dist/cjs/plugins/context-sort.js +32 -0
- package/dist/cjs/plugins/create-special-use.d.ts +7 -0
- package/dist/cjs/plugins/create-special-use.js +101 -0
- package/dist/cjs/plugins/enable.d.ts +23 -0
- package/dist/cjs/plugins/enable.js +127 -0
- package/dist/cjs/plugins/esearch.d.ts +6 -0
- package/dist/cjs/plugins/esearch.js +142 -0
- package/dist/cjs/plugins/esort.d.ts +6 -0
- package/dist/cjs/plugins/esort.js +60 -0
- package/dist/cjs/plugins/id.d.ts +5 -0
- package/dist/cjs/plugins/id.js +123 -0
- package/dist/cjs/plugins/idle.d.ts +5 -0
- package/dist/cjs/plugins/idle.js +85 -0
- package/dist/cjs/plugins/imap4rev2.d.ts +6 -0
- package/dist/cjs/plugins/imap4rev2.js +184 -0
- package/dist/cjs/plugins/index.d.ts +2 -0
- package/dist/cjs/plugins/index.js +119 -0
- package/dist/cjs/plugins/list-extended.d.ts +2 -0
- package/dist/cjs/plugins/list-extended.js +235 -0
- package/dist/cjs/plugins/list-status.d.ts +6 -0
- package/dist/cjs/plugins/list-status.js +42 -0
- package/dist/cjs/plugins/literalminus.d.ts +8 -0
- package/dist/cjs/plugins/literalminus.js +32 -0
- package/dist/cjs/plugins/literalplus.d.ts +6 -0
- package/dist/cjs/plugins/literalplus.js +30 -0
- package/dist/cjs/plugins/logindisabled.d.ts +5 -0
- package/dist/cjs/plugins/logindisabled.js +54 -0
- package/dist/cjs/plugins/messagelimit.d.ts +19 -0
- package/dist/cjs/plugins/messagelimit.js +227 -0
- package/dist/cjs/plugins/metadata-server.d.ts +7 -0
- package/dist/cjs/plugins/metadata-server.js +24 -0
- package/dist/cjs/plugins/metadata.d.ts +11 -0
- package/dist/cjs/plugins/metadata.js +436 -0
- package/dist/cjs/plugins/move.d.ts +11 -0
- package/dist/cjs/plugins/move.js +96 -0
- package/dist/cjs/plugins/multiappend.d.ts +12 -0
- package/dist/cjs/plugins/multiappend.js +38 -0
- package/dist/cjs/plugins/multisearch.d.ts +6 -0
- package/dist/cjs/plugins/multisearch.js +263 -0
- package/dist/cjs/plugins/namespace.d.ts +5 -0
- package/dist/cjs/plugins/namespace.js +57 -0
- package/dist/cjs/plugins/notify.d.ts +2 -0
- package/dist/cjs/plugins/notify.js +628 -0
- package/dist/cjs/plugins/oauthbearer.d.ts +32 -0
- package/dist/cjs/plugins/oauthbearer.js +202 -0
- package/dist/cjs/plugins/objectid.d.ts +23 -0
- package/dist/cjs/plugins/objectid.js +221 -0
- package/dist/cjs/plugins/partial.d.ts +6 -0
- package/dist/cjs/plugins/partial.js +78 -0
- package/dist/cjs/plugins/preview.d.ts +31 -0
- package/dist/cjs/plugins/preview.js +378 -0
- package/dist/cjs/plugins/qresync.d.ts +11 -0
- package/dist/cjs/plugins/qresync.js +473 -0
- package/dist/cjs/plugins/quota.d.ts +18 -0
- package/dist/cjs/plugins/quota.js +254 -0
- package/dist/cjs/plugins/replace.d.ts +14 -0
- package/dist/cjs/plugins/replace.js +130 -0
- package/dist/cjs/plugins/sasl-ir.d.ts +5 -0
- package/dist/cjs/plugins/sasl-ir.js +24 -0
- package/dist/cjs/plugins/savedate.d.ts +17 -0
- package/dist/cjs/plugins/savedate.js +64 -0
- package/dist/cjs/plugins/savelimit.d.ts +10 -0
- package/dist/cjs/plugins/savelimit.js +30 -0
- package/dist/cjs/plugins/searchres.d.ts +6 -0
- package/dist/cjs/plugins/searchres.js +91 -0
- package/dist/cjs/plugins/sort-display.d.ts +11 -0
- package/dist/cjs/plugins/sort-display.js +37 -0
- package/dist/cjs/plugins/sort.d.ts +11 -0
- package/dist/cjs/plugins/sort.js +125 -0
- package/dist/cjs/plugins/special-use.d.ts +10 -0
- package/dist/cjs/plugins/special-use.js +95 -0
- package/dist/cjs/plugins/starttls.d.ts +5 -0
- package/dist/cjs/plugins/starttls.js +55 -0
- package/dist/cjs/plugins/status-size.d.ts +7 -0
- package/dist/cjs/plugins/status-size.js +30 -0
- package/dist/cjs/plugins/thread-orderedsubject.d.ts +11 -0
- package/dist/cjs/plugins/thread-orderedsubject.js +28 -0
- package/dist/cjs/plugins/thread-references.d.ts +11 -0
- package/dist/cjs/plugins/thread-references.js +28 -0
- package/dist/cjs/plugins/uidonly.d.ts +15 -0
- package/dist/cjs/plugins/uidonly.js +126 -0
- package/dist/cjs/plugins/uidplus.d.ts +15 -0
- package/dist/cjs/plugins/uidplus.js +119 -0
- package/dist/cjs/plugins/unauthenticate.d.ts +7 -0
- package/dist/cjs/plugins/unauthenticate.js +32 -0
- package/dist/cjs/plugins/unselect.d.ts +5 -0
- package/dist/cjs/plugins/unselect.js +36 -0
- package/dist/cjs/plugins/utf8-accept.d.ts +6 -0
- package/dist/cjs/plugins/utf8-accept.js +72 -0
- package/dist/cjs/plugins/x-gm-ext-1.d.ts +26 -0
- package/dist/cjs/plugins/x-gm-ext-1.js +422 -0
- package/dist/cjs/plugins/xoauth2.d.ts +2 -0
- package/dist/cjs/plugins/xoauth2.js +155 -0
- package/dist/cjs/plugins/xtoybird.d.ts +2 -0
- package/dist/cjs/plugins/xtoybird.js +236 -0
- package/dist/cjs/server.d.ts +876 -0
- package/dist/cjs/server.js +2597 -0
- package/dist/cjs/smtp-listener.d.ts +13 -0
- package/dist/cjs/smtp-listener.js +47 -0
- package/dist/cjs/sorting.d.ts +77 -0
- package/dist/cjs/sorting.js +290 -0
- package/dist/cjs/threading.d.ts +30 -0
- package/dist/cjs/threading.js +318 -0
- package/dist/cjs/types.d.ts +327 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/utf8-session.d.ts +17 -0
- package/dist/cjs/utf8-session.js +148 -0
- package/dist/cjs/vanished.d.ts +21 -0
- package/dist/cjs/vanished.js +55 -0
- package/dist/esm/addressparser.d.ts +21 -0
- package/{lib → dist/esm}/addressparser.js +102 -123
- package/dist/esm/arguments.d.ts +31 -0
- package/dist/esm/arguments.js +96 -0
- package/dist/esm/bodystructure.d.ts +25 -0
- package/{lib → dist/esm}/bodystructure.js +17 -33
- package/dist/esm/cert.d.ts +2 -0
- package/dist/esm/cert.js +4 -0
- package/dist/esm/command-states.d.ts +36 -0
- package/{lib → dist/esm}/command-states.js +4 -16
- package/dist/esm/commands/append.d.ts +88 -0
- package/{lib → dist/esm}/commands/append.js +47 -85
- package/dist/esm/commands/capability.d.ts +2 -0
- package/dist/esm/commands/capability.js +29 -0
- package/dist/esm/commands/check.d.ts +2 -0
- package/dist/esm/commands/check.js +13 -0
- package/dist/esm/commands/close.d.ts +2 -0
- package/dist/esm/commands/close.js +20 -0
- package/dist/esm/commands/copy.d.ts +30 -0
- package/{lib → dist/esm}/commands/copy.js +31 -55
- package/dist/esm/commands/create.d.ts +2 -0
- package/{lib → dist/esm}/commands/create.js +25 -39
- package/dist/esm/commands/delete.d.ts +2 -0
- package/{lib → dist/esm}/commands/delete.js +25 -41
- package/dist/esm/commands/examine.d.ts +2 -0
- package/dist/esm/commands/examine.js +4 -0
- package/dist/esm/commands/expunge.d.ts +2 -0
- package/dist/esm/commands/expunge.js +17 -0
- package/dist/esm/commands/fetch.d.ts +23 -0
- package/{lib → dist/esm}/commands/fetch.js +33 -74
- package/dist/esm/commands/handlers/fetch.d.ts +12 -0
- package/{lib → dist/esm}/commands/handlers/fetch.js +11 -42
- package/dist/esm/commands/handlers/flags.d.ts +17 -0
- package/{lib → dist/esm}/commands/handlers/flags.js +3 -11
- package/dist/esm/commands/handlers/search.d.ts +85 -0
- package/{lib → dist/esm}/commands/handlers/search.js +33 -71
- package/dist/esm/commands/handlers/status.d.ts +34 -0
- package/{lib → dist/esm}/commands/handlers/status.js +1 -9
- package/dist/esm/commands/handlers/store.d.ts +3 -0
- package/{lib → dist/esm}/commands/handlers/store.js +20 -44
- package/dist/esm/commands/index.d.ts +2 -0
- package/dist/esm/commands/index.js +55 -0
- package/dist/esm/commands/list.d.ts +2 -0
- package/dist/esm/commands/list.js +71 -0
- package/dist/esm/commands/login.d.ts +2 -0
- package/{lib → dist/esm}/commands/login.js +24 -44
- package/dist/esm/commands/logout.d.ts +2 -0
- package/dist/esm/commands/logout.js +25 -0
- package/dist/esm/commands/lsub.d.ts +2 -0
- package/dist/esm/commands/lsub.js +64 -0
- package/dist/esm/commands/noop.d.ts +2 -0
- package/dist/esm/commands/noop.js +13 -0
- package/dist/esm/commands/rename.d.ts +2 -0
- package/{lib → dist/esm}/commands/rename.js +32 -51
- package/dist/esm/commands/search.d.ts +10 -0
- package/dist/esm/commands/search.js +54 -0
- package/dist/esm/commands/select.d.ts +19 -0
- package/dist/esm/commands/select.js +214 -0
- package/dist/esm/commands/status.d.ts +2 -0
- package/{lib → dist/esm}/commands/status.js +18 -39
- package/dist/esm/commands/store.d.ts +10 -0
- package/{lib → dist/esm}/commands/store.js +39 -73
- package/dist/esm/commands/subscribe.d.ts +2 -0
- package/{lib → dist/esm}/commands/subscribe.js +22 -39
- package/dist/esm/commands/uid-copy.d.ts +2 -0
- package/dist/esm/commands/uid-copy.js +4 -0
- package/dist/esm/commands/uid-fetch.d.ts +3 -0
- package/dist/esm/commands/uid-fetch.js +3 -0
- package/dist/esm/commands/uid-search.d.ts +3 -0
- package/dist/esm/commands/uid-search.js +3 -0
- package/dist/esm/commands/uid-store.d.ts +3 -0
- package/dist/esm/commands/uid-store.js +3 -0
- package/dist/esm/commands/unsubscribe.d.ts +2 -0
- package/{lib → dist/esm}/commands/unsubscribe.js +22 -37
- package/dist/esm/dates.d.ts +64 -0
- package/{lib → dist/esm}/dates.js +6 -14
- package/dist/esm/deflate-layer.d.ts +83 -0
- package/{lib → dist/esm}/deflate-layer.js +9 -26
- package/dist/esm/encoded-words.d.ts +15 -0
- package/{lib → dist/esm}/encoded-words.js +9 -25
- package/dist/esm/envelope.d.ts +33 -0
- package/{lib → dist/esm}/envelope.js +8 -19
- package/dist/esm/esearch.d.ts +96 -0
- package/{lib → dist/esm}/esearch.js +12 -39
- package/dist/esm/framing.d.ts +66 -0
- package/dist/esm/framing.js +82 -0
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/list-extensions.d.ts +50 -0
- package/{lib → dist/esm}/list-extensions.js +1 -4
- package/dist/esm/load-plugins.d.ts +21 -0
- package/{lib → dist/esm}/load-plugins.js +9 -43
- package/dist/esm/mailbox-name.d.ts +26 -0
- package/{lib → dist/esm}/mailbox-name.js +5 -26
- package/dist/esm/mimeparser.d.ts +137 -0
- package/{lib → dist/esm}/mimeparser.js +74 -152
- package/dist/esm/mock-client.d.ts +39 -0
- package/{lib → dist/esm}/mock-client.js +26 -40
- package/dist/esm/numbers.d.ts +28 -0
- package/{lib → dist/esm}/numbers.js +1 -8
- package/dist/esm/package.json +3 -0
- package/dist/esm/plugins/acl.d.ts +2 -0
- package/{lib → dist/esm}/plugins/acl.js +146 -240
- package/dist/esm/plugins/appendlimit.d.ts +16 -0
- package/{lib → dist/esm}/plugins/appendlimit.js +5 -16
- package/dist/esm/plugins/auth-plain.d.ts +2 -0
- package/{lib → dist/esm}/plugins/auth-plain.js +11 -31
- package/dist/esm/plugins/binary.d.ts +30 -0
- package/{lib → dist/esm}/plugins/binary.js +17 -43
- package/dist/esm/plugins/catenate.d.ts +14 -0
- package/{lib → dist/esm}/plugins/catenate.js +19 -40
- package/dist/esm/plugins/compress.d.ts +7 -0
- package/dist/esm/plugins/compress.js +61 -0
- package/dist/esm/plugins/condstore.d.ts +5 -0
- package/{lib → dist/esm}/plugins/condstore.js +66 -152
- package/dist/esm/plugins/context-search.d.ts +8 -0
- package/{lib → dist/esm}/plugins/context-search.js +53 -88
- package/dist/esm/plugins/context-sort.d.ts +6 -0
- package/{lib → dist/esm}/plugins/context-sort.js +4 -9
- package/dist/esm/plugins/create-special-use.d.ts +7 -0
- package/{lib → dist/esm}/plugins/create-special-use.js +33 -55
- package/dist/esm/plugins/enable.d.ts +23 -0
- package/dist/esm/plugins/enable.js +111 -0
- package/dist/esm/plugins/esearch.d.ts +6 -0
- package/{lib → dist/esm}/plugins/esearch.js +13 -42
- package/dist/esm/plugins/esort.d.ts +6 -0
- package/{lib → dist/esm}/plugins/esort.js +7 -25
- package/dist/esm/plugins/id.d.ts +5 -0
- package/dist/esm/plugins/id.js +108 -0
- package/dist/esm/plugins/idle.d.ts +5 -0
- package/dist/esm/plugins/idle.js +70 -0
- package/dist/esm/plugins/imap4rev2.d.ts +6 -0
- package/{lib → dist/esm}/plugins/imap4rev2.js +24 -60
- package/dist/esm/plugins/index.d.ts +2 -0
- package/dist/esm/plugins/index.js +113 -0
- package/dist/esm/plugins/list-extended.d.ts +2 -0
- package/{lib → dist/esm}/plugins/list-extended.js +28 -66
- package/dist/esm/plugins/list-status.d.ts +6 -0
- package/{lib → dist/esm}/plugins/list-status.js +5 -12
- package/dist/esm/plugins/literalminus.d.ts +8 -0
- package/{lib → dist/esm}/plugins/literalminus.js +2 -5
- package/dist/esm/plugins/literalplus.d.ts +6 -0
- package/{lib → dist/esm}/plugins/literalplus.js +2 -5
- package/dist/esm/plugins/logindisabled.d.ts +5 -0
- package/dist/esm/plugins/logindisabled.js +39 -0
- package/dist/esm/plugins/messagelimit.d.ts +19 -0
- package/{lib → dist/esm}/plugins/messagelimit.js +18 -41
- package/dist/esm/plugins/metadata-server.d.ts +7 -0
- package/{lib → dist/esm}/plugins/metadata-server.js +3 -7
- package/dist/esm/plugins/metadata.d.ts +11 -0
- package/dist/esm/plugins/metadata.js +421 -0
- package/dist/esm/plugins/move.d.ts +11 -0
- package/{lib → dist/esm}/plugins/move.js +37 -66
- package/dist/esm/plugins/multiappend.d.ts +12 -0
- package/{lib → dist/esm}/plugins/multiappend.js +2 -5
- package/dist/esm/plugins/multisearch.d.ts +6 -0
- package/{lib → dist/esm}/plugins/multisearch.js +24 -48
- package/dist/esm/plugins/namespace.d.ts +5 -0
- package/dist/esm/plugins/namespace.js +42 -0
- package/dist/esm/plugins/notify.d.ts +2 -0
- package/{lib → dist/esm}/plugins/notify.js +90 -134
- package/dist/esm/plugins/oauthbearer.d.ts +32 -0
- package/{lib → dist/esm}/plugins/oauthbearer.js +18 -48
- package/dist/esm/plugins/objectid.d.ts +23 -0
- package/{lib → dist/esm}/plugins/objectid.js +21 -58
- package/dist/esm/plugins/partial.d.ts +6 -0
- package/{lib → dist/esm}/plugins/partial.js +7 -15
- package/dist/esm/plugins/preview.d.ts +31 -0
- package/{lib → dist/esm}/plugins/preview.js +28 -66
- package/dist/esm/plugins/qresync.d.ts +11 -0
- package/{lib → dist/esm}/plugins/qresync.js +64 -134
- package/dist/esm/plugins/quota.d.ts +18 -0
- package/{lib → dist/esm}/plugins/quota.js +89 -135
- package/dist/esm/plugins/replace.d.ts +14 -0
- package/{lib → dist/esm}/plugins/replace.js +21 -51
- package/dist/esm/plugins/sasl-ir.d.ts +5 -0
- package/{lib → dist/esm}/plugins/sasl-ir.js +3 -6
- package/dist/esm/plugins/savedate.d.ts +17 -0
- package/{lib → dist/esm}/plugins/savedate.js +5 -15
- package/dist/esm/plugins/savelimit.d.ts +10 -0
- package/{lib → dist/esm}/plugins/savelimit.js +3 -6
- package/dist/esm/plugins/searchres.d.ts +6 -0
- package/{lib → dist/esm}/plugins/searchres.js +13 -22
- package/dist/esm/plugins/sort-display.d.ts +11 -0
- package/{lib → dist/esm}/plugins/sort-display.js +6 -10
- package/dist/esm/plugins/sort.d.ts +11 -0
- package/{lib → dist/esm}/plugins/sort.js +24 -46
- package/dist/esm/plugins/special-use.d.ts +10 -0
- package/{lib → dist/esm}/plugins/special-use.js +9 -24
- package/dist/esm/plugins/starttls.d.ts +5 -0
- package/{lib → dist/esm}/plugins/starttls.js +20 -37
- package/dist/esm/plugins/status-size.d.ts +7 -0
- package/{lib → dist/esm}/plugins/status-size.js +4 -11
- package/dist/esm/plugins/thread-orderedsubject.d.ts +11 -0
- package/{lib → dist/esm}/plugins/thread-orderedsubject.js +3 -6
- package/dist/esm/plugins/thread-references.d.ts +11 -0
- package/{lib → dist/esm}/plugins/thread-references.js +3 -6
- package/dist/esm/plugins/uidonly.d.ts +15 -0
- package/{lib → dist/esm}/plugins/uidonly.js +11 -35
- package/dist/esm/plugins/uidplus.d.ts +15 -0
- package/{lib → dist/esm}/plugins/uidplus.js +25 -45
- package/dist/esm/plugins/unauthenticate.d.ts +7 -0
- package/dist/esm/plugins/unauthenticate.js +17 -0
- package/dist/esm/plugins/unselect.d.ts +5 -0
- package/dist/esm/plugins/unselect.js +21 -0
- package/dist/esm/plugins/utf8-accept.d.ts +6 -0
- package/{lib → dist/esm}/plugins/utf8-accept.js +10 -21
- package/dist/esm/plugins/x-gm-ext-1.d.ts +26 -0
- package/{lib → dist/esm}/plugins/x-gm-ext-1.js +48 -100
- package/dist/esm/plugins/xoauth2.d.ts +2 -0
- package/dist/esm/plugins/xoauth2.js +140 -0
- package/dist/esm/plugins/xtoybird.d.ts +2 -0
- package/dist/esm/plugins/xtoybird.js +218 -0
- package/dist/esm/server.d.ts +876 -0
- package/dist/esm/server.js +2543 -0
- package/dist/esm/smtp-listener.d.ts +13 -0
- package/{lib → dist/esm}/smtp-listener.js +5 -12
- package/dist/esm/sorting.d.ts +77 -0
- package/{lib → dist/esm}/sorting.js +40 -53
- package/dist/esm/threading.d.ts +30 -0
- package/{lib → dist/esm}/threading.js +29 -70
- package/dist/esm/types.d.ts +327 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/utf8-session.d.ts +17 -0
- package/{lib → dist/esm}/utf8-session.js +15 -25
- package/dist/esm/vanished.d.ts +21 -0
- package/{lib → dist/esm}/vanished.js +16 -21
- package/dist/plugin-help.json +298 -0
- package/package.json +54 -11
- package/lib/commands/capability.js +0 -47
- package/lib/commands/check.js +0 -21
- package/lib/commands/close.js +0 -30
- package/lib/commands/examine.js +0 -7
- package/lib/commands/expunge.js +0 -27
- package/lib/commands/list.js +0 -100
- package/lib/commands/logout.js +0 -41
- package/lib/commands/lsub.js +0 -87
- package/lib/commands/noop.js +0 -21
- package/lib/commands/search.js +0 -76
- package/lib/commands/select.js +0 -289
- package/lib/commands/uid copy.js +0 -7
- package/lib/commands/uid fetch.js +0 -5
- package/lib/commands/uid search.js +0 -5
- package/lib/commands/uid store.js +0 -5
- package/lib/plugins/compress.js +0 -76
- package/lib/plugins/enable.js +0 -155
- package/lib/plugins/id.js +0 -138
- package/lib/plugins/idle.js +0 -105
- package/lib/plugins/logindisabled.js +0 -50
- package/lib/plugins/metadata.js +0 -475
- package/lib/plugins/namespace.js +0 -67
- package/lib/plugins/unauthenticate.js +0 -28
- package/lib/plugins/unselect.js +0 -36
- package/lib/plugins/xoauth2.js +0 -188
- package/lib/plugins/xtoybird.js +0 -282
- package/lib/server.js +0 -2880
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @help Adds AUTH=OAUTHBEARER [RFC7628] capability
|
|
5
3
|
* @help Works with and without SASL-IR [RFC4959]
|
|
@@ -7,10 +5,8 @@
|
|
|
7
5
|
* @help Username (authzid, optional): testuser
|
|
8
6
|
* @help Access Token: testtoken
|
|
9
7
|
*/
|
|
10
|
-
|
|
11
8
|
const KVSEP = '\x01';
|
|
12
9
|
const utf8 = new TextDecoder('utf-8', { fatal: true });
|
|
13
|
-
|
|
14
10
|
/**
|
|
15
11
|
* Parses an OAUTHBEARER client response (RFC 7628 section 3.1)
|
|
16
12
|
*
|
|
@@ -34,12 +30,10 @@ function parseClientResponse(input) {
|
|
|
34
30
|
if (str === KVSEP) {
|
|
35
31
|
return { kvsepOnly: true };
|
|
36
32
|
}
|
|
37
|
-
|
|
38
33
|
const header = str.match(/^(?:F,)?(n|y|p=[A-Za-z0-9.-]+),(?:a=([^,]+))?,/);
|
|
39
34
|
if (!header || str.charAt(header[0].length) !== KVSEP) {
|
|
40
35
|
return { error: 'Invalid GS2 header' };
|
|
41
36
|
}
|
|
42
|
-
|
|
43
37
|
let authzid = false;
|
|
44
38
|
if (header[2]) {
|
|
45
39
|
// saslname: "," and "=" are only allowed as "=2C" and "=3D", NUL is not allowed
|
|
@@ -48,17 +42,16 @@ function parseClientResponse(input) {
|
|
|
48
42
|
}
|
|
49
43
|
try {
|
|
50
44
|
authzid = utf8.decode(Buffer.from(header[2].replace(/=2C/g, ',').replace(/=3D/g, '='), 'binary'));
|
|
51
|
-
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
52
47
|
return { error: 'Invalid UTF-8 in the authorization identity' };
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
|
-
|
|
56
50
|
// *kvpair kvsep: every pair ends with a kvsep of its own, so the split ends with two empty parts
|
|
57
51
|
const parts = str.substr(header[0].length + 1).split(KVSEP);
|
|
58
52
|
if (parts.pop() !== '' || parts.pop() !== '') {
|
|
59
53
|
return { error: 'The client response must end with %x01' };
|
|
60
54
|
}
|
|
61
|
-
|
|
62
55
|
const pairs = Object.create(null);
|
|
63
56
|
for (const pair of parts) {
|
|
64
57
|
const match = pair.match(/^([A-Za-z]+)=([\x20-\x7e\t\r\n]*)$/);
|
|
@@ -67,34 +60,28 @@ function parseClientResponse(input) {
|
|
|
67
60
|
}
|
|
68
61
|
pairs[match[1]] = match[2];
|
|
69
62
|
}
|
|
70
|
-
|
|
71
63
|
return { channelBinding: header[1].charAt(0) === 'p', authzid, pairs };
|
|
72
64
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
server.registerCapability('AUTH=OAUTHBEARER', connection => connection.state === 'Not Authenticated');
|
|
76
|
-
|
|
65
|
+
export default function oauthbearerPlugin(server) {
|
|
66
|
+
server.registerCapability('AUTH=OAUTHBEARER', (connection) => connection.state === 'Not Authenticated');
|
|
77
67
|
const fail = (connection, parsed, data, command, text) => {
|
|
78
68
|
// RFC 5530 section 3: a rejected login is AUTHENTICATIONFAILED
|
|
79
69
|
connection.sendStatus(parsed, data, command, text, command === 'NO' && 'AUTHENTICATIONFAILED', 'AUTHENTICATE OAUTHBEARER FAILED');
|
|
80
70
|
};
|
|
81
|
-
|
|
82
71
|
/**
|
|
83
72
|
* Checks the client response. Returns the OAuth error status (RFC 6750 section 3.1) if the
|
|
84
73
|
* credentials are not accepted, or false if the user is logged in
|
|
85
74
|
*/
|
|
86
|
-
const checkCredentials = request => {
|
|
75
|
+
const checkCredentials = (request) => {
|
|
87
76
|
if (request.channelBinding) {
|
|
88
77
|
// RFC 5801 section 5: "p" asks for channel binding, which this mechanism does not support
|
|
89
78
|
return 'invalid_request';
|
|
90
79
|
}
|
|
91
|
-
|
|
92
80
|
const { auth, port } = request.pairs;
|
|
93
81
|
// port: a decimal positive integer string without leading zeros (RFC 7628 section 3.1)
|
|
94
82
|
if (typeof port === 'string' && !/^[1-9][0-9]*$/.test(port)) {
|
|
95
83
|
return 'invalid_request';
|
|
96
84
|
}
|
|
97
|
-
|
|
98
85
|
// RFC 6750 section 2.1: "Bearer" 1*SP b64token, the scheme name is case insensitive
|
|
99
86
|
const bearer = typeof auth === 'string' && auth.match(/^Bearer +([A-Za-z0-9\-._~+/]+=*)$/i);
|
|
100
87
|
if (!bearer) {
|
|
@@ -102,7 +89,6 @@ module.exports = function (server) {
|
|
|
102
89
|
return auth === '' ? 'invalid_token' : 'invalid_request';
|
|
103
90
|
}
|
|
104
91
|
const token = bearer[1];
|
|
105
|
-
|
|
106
92
|
let username = request.authzid;
|
|
107
93
|
if (username === false) {
|
|
108
94
|
// without an authzid the token tells who the user is
|
|
@@ -118,7 +104,6 @@ module.exports = function (server) {
|
|
|
118
104
|
request.username = username;
|
|
119
105
|
return false;
|
|
120
106
|
};
|
|
121
|
-
|
|
122
107
|
// Decodes a base64 client response, sends BAD and returns false if it is not valid base64
|
|
123
108
|
const decode = (connection, parsed, data, input) => {
|
|
124
109
|
const decoded = connection.decodeSaslResponse(input);
|
|
@@ -127,11 +112,10 @@ module.exports = function (server) {
|
|
|
127
112
|
}
|
|
128
113
|
return decoded;
|
|
129
114
|
};
|
|
130
|
-
|
|
131
115
|
// Waits for the next client response line. "*" cancels the exchange, which RFC 3501 section 6.2.2
|
|
132
116
|
// answers with BAD
|
|
133
117
|
const readResponse = (connection, parsed, data, onResponse) => {
|
|
134
|
-
connection.inputHandler = line => {
|
|
118
|
+
connection.inputHandler = (line) => {
|
|
135
119
|
connection.inputHandler = false;
|
|
136
120
|
if (line === '*') {
|
|
137
121
|
return fail(connection, parsed, data, 'BAD', 'Authentication cancelled');
|
|
@@ -142,7 +126,6 @@ module.exports = function (server) {
|
|
|
142
126
|
}
|
|
143
127
|
};
|
|
144
128
|
};
|
|
145
|
-
|
|
146
129
|
// Handles the decoded client response, sent with SASL-IR or after the empty continuation request
|
|
147
130
|
const authenticate = (connection, parsed, data, decoded) => {
|
|
148
131
|
const request = parseClientResponse(decoded);
|
|
@@ -153,65 +136,52 @@ module.exports = function (server) {
|
|
|
153
136
|
// RFC 7628 section 3.1: as the first message the server may fail without discovery information
|
|
154
137
|
return fail(connection, parsed, data, 'NO', 'SASL authentication failed');
|
|
155
138
|
}
|
|
156
|
-
|
|
157
139
|
const status = checkCredentials(request);
|
|
158
140
|
if (!status) {
|
|
159
141
|
connection.state = 'Authenticated';
|
|
160
142
|
connection.username = request.username;
|
|
161
143
|
return connection.sendStatus(parsed, data, 'OK', 'SASL authentication succeeded', false, 'AUTHENTICATE OAUTHBEARER SUCCESS');
|
|
162
144
|
}
|
|
163
|
-
|
|
164
145
|
// RFC 7628 section 3.2.2: the error result is a JSON document in a continuation request, the
|
|
165
146
|
// client MUST answer with a single %x01 or cancel, and the server then fails the exchange
|
|
166
|
-
readResponse(connection, parsed, data, response => {
|
|
147
|
+
readResponse(connection, parsed, data, (response) => {
|
|
167
148
|
if (response.toString('binary') !== KVSEP) {
|
|
168
149
|
return fail(connection, parsed, data, 'BAD', 'The client must answer the error result with a single %x01 (RFC 7628 section 3.2.3)');
|
|
169
150
|
}
|
|
170
151
|
fail(connection, parsed, data, 'NO', 'SASL authentication failed');
|
|
171
152
|
});
|
|
172
|
-
connection.send(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
},
|
|
182
|
-
'AUTHENTICATE OAUTHBEARER CHALLENGE',
|
|
183
|
-
parsed,
|
|
184
|
-
data
|
|
185
|
-
);
|
|
153
|
+
connection.send({
|
|
154
|
+
tag: '+',
|
|
155
|
+
attributes: [
|
|
156
|
+
{
|
|
157
|
+
type: 'ATOM',
|
|
158
|
+
value: Buffer.from(JSON.stringify({ status })).toString('base64')
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
}, 'AUTHENTICATE OAUTHBEARER CHALLENGE', parsed, data);
|
|
186
162
|
};
|
|
187
|
-
|
|
188
163
|
server.setCommandHandler('AUTHENTICATE OAUTHBEARER', (connection, parsed, data, callback) => {
|
|
189
164
|
const args = parsed.attributes || [];
|
|
190
|
-
|
|
191
165
|
if (!args.length) {
|
|
192
166
|
// without an initial response the client sends its response after an empty challenge
|
|
193
167
|
readResponse(connection, parsed, data, decoded => authenticate(connection, parsed, data, decoded));
|
|
194
168
|
connection.write('+ \r\n');
|
|
195
169
|
return callback();
|
|
196
170
|
}
|
|
197
|
-
|
|
198
171
|
if (args.length !== 1 || !args[0] || args[0].type !== 'ATOM') {
|
|
199
172
|
fail(connection, parsed, data, 'BAD', 'Invalid arguments for AUTHENTICATE OAUTHBEARER');
|
|
200
173
|
return callback();
|
|
201
174
|
}
|
|
202
|
-
|
|
203
175
|
// RFC 4959 section 3: an initial response is only allowed when SASL-IR is advertised
|
|
204
176
|
if (!server.capabilities['SASL-IR'] || !server.capabilities['SASL-IR'](connection)) {
|
|
205
177
|
fail(connection, parsed, data, 'BAD', 'SASL-IR must be enabled to send Initial Response with the request');
|
|
206
178
|
return callback();
|
|
207
179
|
}
|
|
208
|
-
|
|
209
180
|
const decoded = decode(connection, parsed, data, args[0].value);
|
|
210
181
|
if (decoded) {
|
|
211
182
|
authenticate(connection, parsed, data, decoded);
|
|
212
183
|
}
|
|
213
184
|
return callback();
|
|
214
185
|
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
module.exports.parseClientResponse = parseClientResponse;
|
|
186
|
+
}
|
|
187
|
+
export { parseClientResponse };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IMAPServer } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @help Adds OBJECTID [RFC8474] capability
|
|
4
|
+
* @help MAILBOXID, EMAILID and THREADID values are generated (F1, M1, T1, ...)
|
|
5
|
+
* @help unless storage sets them for a mailbox ("MAILBOXID") or a message
|
|
6
|
+
* @help ("EMAILID", "THREADID"). Messages are threaded by their Message-ID,
|
|
7
|
+
* @help In-Reply-To and References headers across all mailboxes
|
|
8
|
+
*
|
|
9
|
+
* OBJECTID: https://www.rfc-editor.org/rfc/rfc8474.txt
|
|
10
|
+
*
|
|
11
|
+
* Additional response codes:
|
|
12
|
+
* - MAILBOXID for CREATE, SELECT and EXAMINE
|
|
13
|
+
*
|
|
14
|
+
* Additional STATUS items:
|
|
15
|
+
* - MAILBOXID
|
|
16
|
+
*
|
|
17
|
+
* Additional FETCH items:
|
|
18
|
+
* - EMAILID, THREADID
|
|
19
|
+
*
|
|
20
|
+
* Additional SEARCH keys:
|
|
21
|
+
* - EMAILID, THREADID
|
|
22
|
+
*/
|
|
23
|
+
export default function objectidPlugin(server: IMAPServer): void;
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { badError } = require('../commands/handlers/search');
|
|
4
|
-
|
|
1
|
+
import { badError } from '../commands/handlers/search.js';
|
|
5
2
|
// RFC 8474 section 7: objectid = 1*255(ALPHA / DIGIT / "_" / "-"), case sensitive
|
|
6
3
|
const OBJECTID = /^[A-Za-z0-9_-]{1,255}$/;
|
|
7
|
-
|
|
8
4
|
// header fields that threading uses, in an unfolded header
|
|
9
5
|
const MESSAGE_ID_HEADER = /^Message-ID[ \t]*:(.*)$/im;
|
|
10
6
|
const REFERENCES_HEADER = /^References[ \t]*:(.*)$/im;
|
|
11
7
|
const IN_REPLY_TO_HEADER = /^In-Reply-To[ \t]*:(.*)$/im;
|
|
12
|
-
|
|
13
8
|
// uidvalidity a MAILBOXID was assigned for
|
|
14
9
|
const ASSIGNED_FOR = Symbol('mailboxid-uidvalidity');
|
|
15
|
-
|
|
16
10
|
/**
|
|
17
11
|
* @help Adds OBJECTID [RFC8474] capability
|
|
18
12
|
* @help MAILBOXID, EMAILID and THREADID values are generated (F1, M1, T1, ...)
|
|
@@ -34,9 +28,8 @@ const ASSIGNED_FOR = Symbol('mailboxid-uidvalidity');
|
|
|
34
28
|
* Additional SEARCH keys:
|
|
35
29
|
* - EMAILID, THREADID
|
|
36
30
|
*/
|
|
37
|
-
|
|
31
|
+
export default function objectidPlugin(server) {
|
|
38
32
|
server.registerCapability('OBJECTID');
|
|
39
|
-
|
|
40
33
|
// kind (F, M or T) of every value ever used, generated values must not collide with them
|
|
41
34
|
const used = new Map();
|
|
42
35
|
const counters = { F: 0, M: 0, T: 0 };
|
|
@@ -46,9 +39,8 @@ module.exports = function (server) {
|
|
|
46
39
|
const emailThreads = new Map();
|
|
47
40
|
// THREADID by Message-ID, for threading
|
|
48
41
|
const messageIdThreads = new Map();
|
|
49
|
-
|
|
50
42
|
// RFC 8474 section 8.1: the prefix keeps generated ids from starting with a digit or a dash
|
|
51
|
-
const generate = prefix => {
|
|
43
|
+
const generate = (prefix) => {
|
|
52
44
|
let id;
|
|
53
45
|
do {
|
|
54
46
|
id = prefix + ++counters[prefix];
|
|
@@ -56,13 +48,11 @@ module.exports = function (server) {
|
|
|
56
48
|
used.set(id, prefix);
|
|
57
49
|
return id;
|
|
58
50
|
};
|
|
59
|
-
|
|
60
51
|
const checkValue = (value, what, owner) => {
|
|
61
52
|
if (typeof value !== 'string' || !OBJECTID.test(value)) {
|
|
62
53
|
throw new Error('Invalid ' + what + ' value ' + JSON.stringify(value) + ' in ' + owner);
|
|
63
54
|
}
|
|
64
55
|
};
|
|
65
|
-
|
|
66
56
|
// RFC 8474 section 5.2: an id is used for one kind of object only
|
|
67
57
|
const checkUnique = (value, prefix) => {
|
|
68
58
|
if (used.has(value) && used.get(value) !== prefix) {
|
|
@@ -70,33 +60,30 @@ module.exports = function (server) {
|
|
|
70
60
|
}
|
|
71
61
|
used.set(value, prefix);
|
|
72
62
|
};
|
|
73
|
-
|
|
74
63
|
/**
|
|
75
64
|
* Returns the MAILBOXID of a mailbox. A mailbox that got a new UIDVALIDITY (re-created after
|
|
76
65
|
* DELETE) is a new mailbox and gets a new id (RFC 8474 section 4)
|
|
77
66
|
*/
|
|
78
|
-
const getMailboxId = mailbox => {
|
|
67
|
+
const getMailboxId = (mailbox) => {
|
|
79
68
|
if (mailbox[ASSIGNED_FOR] === mailbox.uidvalidity && mailboxOwners.get(mailbox.MAILBOXID) === mailbox) {
|
|
80
69
|
return mailbox.MAILBOXID;
|
|
81
70
|
}
|
|
82
|
-
|
|
83
71
|
let id;
|
|
84
72
|
if (mailbox.MAILBOXID && mailbox[ASSIGNED_FOR] === undefined && !mailboxOwners.has(mailbox.MAILBOXID)) {
|
|
85
73
|
// value from storage
|
|
86
74
|
id = mailbox.MAILBOXID;
|
|
87
75
|
checkValue(id, 'MAILBOXID', 'mailbox ' + mailbox.path);
|
|
88
76
|
checkUnique(id, 'F');
|
|
89
|
-
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
90
79
|
// a new mailbox, or a copy of a deleted one (a \Noselect placeholder that is created again)
|
|
91
80
|
id = generate('F');
|
|
92
81
|
}
|
|
93
|
-
|
|
94
82
|
mailbox.MAILBOXID = id;
|
|
95
83
|
mailbox[ASSIGNED_FOR] = mailbox.uidvalidity;
|
|
96
84
|
mailboxOwners.set(id, mailbox);
|
|
97
85
|
return id;
|
|
98
86
|
};
|
|
99
|
-
|
|
100
87
|
// Assign ids when mailboxes are loaded or created. A \Noselect placeholder is not a mailbox
|
|
101
88
|
server.mailboxHandlers.push((server, mailbox) => {
|
|
102
89
|
if (mailbox.flags.indexOf('\\Noselect') >= 0) {
|
|
@@ -108,31 +95,26 @@ module.exports = function (server) {
|
|
|
108
95
|
}
|
|
109
96
|
getMailboxId(mailbox);
|
|
110
97
|
});
|
|
111
|
-
|
|
112
98
|
server.messageHandlers.push((server, message, mailbox) => {
|
|
113
99
|
const owner = 'a message of mailbox ' + mailbox.path;
|
|
114
|
-
|
|
115
100
|
if (message.EMAILID) {
|
|
116
101
|
checkValue(message.EMAILID, 'EMAILID', owner);
|
|
117
102
|
checkUnique(message.EMAILID, 'M');
|
|
118
|
-
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
119
105
|
message.EMAILID = generate('M');
|
|
120
106
|
}
|
|
121
|
-
|
|
122
107
|
if (message.THREADID) {
|
|
123
108
|
checkValue(message.THREADID, 'THREADID', owner);
|
|
124
109
|
checkUnique(message.THREADID, 'T');
|
|
125
110
|
}
|
|
126
|
-
|
|
127
111
|
const threadOfEmail = emailThreads.get(message.EMAILID);
|
|
128
112
|
if (threadOfEmail && message.THREADID && message.THREADID !== threadOfEmail) {
|
|
129
113
|
throw new Error('Messages with EMAILID ' + JSON.stringify(message.EMAILID) + ' must have the same THREADID');
|
|
130
114
|
}
|
|
131
|
-
|
|
132
115
|
const ids = getThreadingIds(message.raw);
|
|
133
116
|
message.THREADID = message.THREADID || threadOfEmail || findThread(ids.references) || generate('T');
|
|
134
117
|
emailThreads.set(message.EMAILID, message.THREADID);
|
|
135
|
-
|
|
136
118
|
// later replies, and later messages with a common parent, join this thread
|
|
137
119
|
[ids.messageId].concat(ids.references).forEach(id => {
|
|
138
120
|
if (id && !messageIdThreads.has(id)) {
|
|
@@ -140,9 +122,8 @@ module.exports = function (server) {
|
|
|
140
122
|
}
|
|
141
123
|
});
|
|
142
124
|
});
|
|
143
|
-
|
|
144
125
|
// the nearest known parent decides the thread
|
|
145
|
-
const findThread = references => {
|
|
126
|
+
const findThread = (references) => {
|
|
146
127
|
for (let i = references.length - 1; i >= 0; i--) {
|
|
147
128
|
if (messageIdThreads.has(references[i])) {
|
|
148
129
|
return messageIdThreads.get(references[i]);
|
|
@@ -150,7 +131,6 @@ module.exports = function (server) {
|
|
|
150
131
|
}
|
|
151
132
|
return false;
|
|
152
133
|
};
|
|
153
|
-
|
|
154
134
|
// RFC 8474 section 5.1: the copy in the COPYUID pairing has the EMAILID of the source, after COPY as well as after MOVE
|
|
155
135
|
server.copyHandlers.push((server, source, copy) => {
|
|
156
136
|
if (source.EMAILID) {
|
|
@@ -158,66 +138,51 @@ module.exports = function (server) {
|
|
|
158
138
|
copy.THREADID = source.THREADID;
|
|
159
139
|
}
|
|
160
140
|
});
|
|
161
|
-
|
|
162
141
|
// RFC 8474 section 4.3
|
|
163
142
|
server.allowedStatus.push('MAILBOXID');
|
|
164
143
|
server.statusHandlers.MAILBOXID = (connection, mailbox) => [{ type: 'ATOM', value: getMailboxId(mailbox) }];
|
|
165
|
-
|
|
166
144
|
// RFC 8474 section 5.3
|
|
167
145
|
server.fetchHandlers.EMAILID = (connection, message) => [{ type: 'ATOM', value: message.EMAILID }];
|
|
168
146
|
server.fetchHandlers.THREADID = (connection, message) => [{ type: 'ATOM', value: message.THREADID }];
|
|
169
|
-
|
|
170
147
|
// RFC 8474 section 6: search-key =/ "EMAILID" SP objectid / "THREADID" SP objectid
|
|
171
|
-
const objectIdArgument = value => {
|
|
148
|
+
const objectIdArgument = (value) => {
|
|
172
149
|
if (!OBJECTID.test(value)) {
|
|
173
150
|
throw badError('Invalid object identifier');
|
|
174
151
|
}
|
|
175
152
|
return value;
|
|
176
153
|
};
|
|
177
|
-
|
|
178
|
-
const searchHandler = name => {
|
|
154
|
+
const searchHandler = (name) => {
|
|
179
155
|
const handler = (connection, message, index, value) => message[name] === value;
|
|
180
156
|
handler.argumentTypes = () => [objectIdArgument];
|
|
181
157
|
server.searchHandlers[name] = handler;
|
|
182
158
|
};
|
|
183
159
|
searchHandler('EMAILID');
|
|
184
160
|
searchHandler('THREADID');
|
|
185
|
-
|
|
186
161
|
// resp-text-code =/ "MAILBOXID" SP "(" objectid ")"
|
|
187
|
-
const mailboxIdCode = mailbox => ({
|
|
162
|
+
const mailboxIdCode = (mailbox) => ({
|
|
188
163
|
type: 'SECTION',
|
|
189
164
|
section: [{ type: 'ATOM', value: 'MAILBOXID' }, [{ type: 'ATOM', value: getMailboxId(mailbox) }]]
|
|
190
165
|
});
|
|
191
|
-
|
|
192
166
|
server.outputHandlers.push((connection, response, description, parsed, data, extra) => {
|
|
193
167
|
// RFC 8474 section 4.1: MAILBOXID response code in the tagged OK of CREATE
|
|
194
168
|
if (description === 'CREATE' && response.command === 'OK' && extra) {
|
|
195
169
|
response.attributes = [mailboxIdCode(extra)].concat(response.attributes || []);
|
|
196
170
|
return;
|
|
197
171
|
}
|
|
198
|
-
|
|
199
172
|
// RFC 8474 section 4.2: untagged OK with MAILBOXID on every successful SELECT and EXAMINE
|
|
200
|
-
if (
|
|
201
|
-
(description === 'SELECT' || description === 'EXAMINE') &&
|
|
173
|
+
if ((description === 'SELECT' || description === 'EXAMINE') &&
|
|
202
174
|
parsed &&
|
|
203
175
|
response.tag === parsed.tag &&
|
|
204
176
|
response.command === 'OK' &&
|
|
205
|
-
connection.selectedMailbox
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
attributes: [mailboxIdCode(connection.selectedMailbox), { type: 'TEXT', value: 'Ok' }]
|
|
212
|
-
},
|
|
213
|
-
description + ' MAILBOXID',
|
|
214
|
-
parsed,
|
|
215
|
-
data
|
|
216
|
-
);
|
|
177
|
+
connection.selectedMailbox) {
|
|
178
|
+
connection.send({
|
|
179
|
+
tag: '*',
|
|
180
|
+
command: 'OK',
|
|
181
|
+
attributes: [mailboxIdCode(connection.selectedMailbox), { type: 'TEXT', value: 'Ok' }]
|
|
182
|
+
}, description + ' MAILBOXID', parsed, data);
|
|
217
183
|
}
|
|
218
184
|
});
|
|
219
|
-
}
|
|
220
|
-
|
|
185
|
+
}
|
|
221
186
|
/**
|
|
222
187
|
* Reads the message ids that threading uses from the header of a message
|
|
223
188
|
*
|
|
@@ -229,12 +194,10 @@ function getThreadingIds(raw) {
|
|
|
229
194
|
const end = raw.search(/\r?\n\r?\n/);
|
|
230
195
|
// unfolded header lines
|
|
231
196
|
const header = (end >= 0 ? raw.substr(0, end) : raw).replace(/\r?\n(?=[ \t])/g, '');
|
|
232
|
-
|
|
233
|
-
const getIds = regex => {
|
|
197
|
+
const getIds = (regex) => {
|
|
234
198
|
const match = header.match(regex);
|
|
235
199
|
return match ? match[1].match(/<[^<>\s]+>/g) || [] : [];
|
|
236
200
|
};
|
|
237
|
-
|
|
238
201
|
return {
|
|
239
202
|
messageId: getIds(MESSAGE_ID_HEADER)[0] || false,
|
|
240
203
|
// In-Reply-To names the parent, which is also the last entry of References
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @help Adds PARTIAL [RFC9394] capability, loads ESEARCH as well
|
|
3
|
+
* @help SEARCH RETURN (PARTIAL 1:100) or (PARTIAL -1:-100) returns a window of the results, FETCH and UID FETCH take a PARTIAL modifier
|
|
4
|
+
*/
|
|
5
|
+
import type { IMAPServer } from '../types.js';
|
|
6
|
+
export default function partialPlugin(server: IMAPServer): void;
|
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @help Adds PARTIAL [RFC9394] capability, loads ESEARCH as well
|
|
5
3
|
* @help SEARCH RETURN (PARTIAL 1:100) or (PARTIAL -1:-100) returns a window of the results, FETCH and UID FETCH take a PARTIAL modifier
|
|
6
4
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const isPartial = item => !!item && item.type === 'ATOM' && String(item.value).toUpperCase() === 'PARTIAL';
|
|
12
|
-
|
|
13
|
-
module.exports = function (server) {
|
|
5
|
+
import esearch from './esearch.js';
|
|
6
|
+
import { parsePartialRange, selectPartial, registerPartialOption } from '../esearch.js';
|
|
7
|
+
const isPartial = (item) => !!item && item.type === 'ATOM' && String(item.value).toUpperCase() === 'PARTIAL';
|
|
8
|
+
export default function partialPlugin(server) {
|
|
14
9
|
// the PARTIAL search return option is returned in an ESEARCH response (RFC 9394 section 3.1)
|
|
15
10
|
esearch(server);
|
|
16
|
-
|
|
17
11
|
server.registerCapability('PARTIAL');
|
|
18
12
|
server.partialRangeLast = true;
|
|
19
13
|
registerPartialOption(server);
|
|
20
|
-
|
|
21
14
|
// RFC 9394 section 3.3: fetch-modifier =/ modifier-partial. The grammar (RFC 4466 section 2.4) allows
|
|
22
15
|
// the modifier for FETCH as well as for UID FETCH. The modifier is taken off the list, CHANGEDSINCE of
|
|
23
16
|
// CONDSTORE then filters the messages in the range (RFC 9394 section 3.4)
|
|
@@ -33,7 +26,8 @@ module.exports = function (server) {
|
|
|
33
26
|
throw new Error('PARTIAL can be used only once');
|
|
34
27
|
}
|
|
35
28
|
parsed.partialFetch = parsePartialRange(modifiers[i + 1], true);
|
|
36
|
-
}
|
|
29
|
+
}
|
|
30
|
+
catch (E) {
|
|
37
31
|
connection.sendStatus(parsed, data, 'BAD', E.message, false, (parsed.command || '').toUpperCase() + ' FAILED');
|
|
38
32
|
return callback();
|
|
39
33
|
}
|
|
@@ -46,12 +40,10 @@ module.exports = function (server) {
|
|
|
46
40
|
}
|
|
47
41
|
prevHandler(connection, parsed, data, callback);
|
|
48
42
|
};
|
|
49
|
-
|
|
50
43
|
['FETCH', 'UID FETCH'].forEach(command => {
|
|
51
44
|
const prevHandler = server.getCommandHandler(command);
|
|
52
45
|
server.setCommandHandler(command, (connection, parsed, data, callback) => fetchWrapper(prevHandler, connection, parsed, data, callback));
|
|
53
46
|
});
|
|
54
|
-
|
|
55
47
|
// only the messages in the PARTIAL range of the messages that the sequence set matched are returned,
|
|
56
48
|
// checked before the other filters
|
|
57
49
|
server.fetchFilters.unshift((connection, message, parsed) => {
|
|
@@ -65,4 +57,4 @@ module.exports = function (server) {
|
|
|
65
57
|
}
|
|
66
58
|
return parsed.partialFetchSet.has(message);
|
|
67
59
|
});
|
|
68
|
-
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { MimeNode } from '../mimeparser.js';
|
|
2
|
+
import type { IMAPServer } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* @help Adds PREVIEW [RFC8970] capability
|
|
5
|
+
* @help Previews come from the first text/plain or text/html body part,
|
|
6
|
+
* @help or from the "preview" property of a message in storage.
|
|
7
|
+
* @help PREVIEW (LAZY) returns NIL until a preview has been generated
|
|
8
|
+
*
|
|
9
|
+
* PREVIEW: https://www.rfc-editor.org/rfc/rfc8970
|
|
10
|
+
*
|
|
11
|
+
* Message storage property:
|
|
12
|
+
* - preview: preview text to return instead of a generated one
|
|
13
|
+
*/
|
|
14
|
+
export default function previewPlugin(server: IMAPServer): void;
|
|
15
|
+
/**
|
|
16
|
+
* Generates the preview text of a message (RFC 8970 3.3) from the first text/plain or text/html part
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} tree Root node of the MIME tree
|
|
19
|
+
* @return {String} Preview, an empty string if there is no text to show
|
|
20
|
+
*/
|
|
21
|
+
declare function generatePreview(tree: MimeNode): string;
|
|
22
|
+
/**
|
|
23
|
+
* Normalizes preview text: control characters are removed, whitespace runs become a single space (so there are no
|
|
24
|
+
* CR or LF characters) and the text is cut to at most `length` characters (code points, RFC 8970 3.3)
|
|
25
|
+
*
|
|
26
|
+
* @param {String} text Text
|
|
27
|
+
* @param {Number} length Maximum number of characters
|
|
28
|
+
* @return {String} Preview
|
|
29
|
+
*/
|
|
30
|
+
declare function finishPreview(text: string, length: number): string;
|
|
31
|
+
export { generatePreview, finishPreview };
|