imapkit 4.0.3 → 4.1.1
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 +271 -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 +106 -133
- 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 +55 -12
- 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
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = metadataPlugin;
|
|
4
|
+
exports.setup = setup;
|
|
5
|
+
const command_states_js_1 = require("../command-states.js");
|
|
6
|
+
const numbers_js_1 = require("../numbers.js");
|
|
7
|
+
const arguments_js_1 = require("../arguments.js");
|
|
8
|
+
const enable_js_1 = require("./enable.js");
|
|
9
|
+
/**
|
|
10
|
+
* @help Adds METADATA [RFC5464] capability (GETMETADATA and SETMETADATA)
|
|
11
|
+
* @help for server and mailbox annotations. Mailboxes take initial entries
|
|
12
|
+
* @help from a "metadata" object in storage, server entries come from the
|
|
13
|
+
* @help "metadata" option. Limits: "metadataMaxSize" (octets per value,
|
|
14
|
+
* @help default 65536), "metadataMaxEntries" (per mailbox and for the
|
|
15
|
+
* @help server, default 100). "metadataPrivate": false turns /private
|
|
16
|
+
* @help entries off. ENABLE METADATA turns on unsolicited METADATA responses
|
|
17
|
+
*/
|
|
18
|
+
// Default limits, RFC 5464 section 4.1 requires at least 1024 octets and 10 entries
|
|
19
|
+
const DEFAULT_MAX_SIZE = 64 * 1024;
|
|
20
|
+
const DEFAULT_MAX_ENTRIES = 100;
|
|
21
|
+
// RFC 5464 section 3.2.1.1: /shared/admin is always read-only
|
|
22
|
+
const READ_ONLY_SERVER_ENTRIES = new Set(['/shared/admin']);
|
|
23
|
+
// RFC 6154 section 4: special-use attributes are tied to this mailbox entry
|
|
24
|
+
const SPECIAL_USE_ENTRY = '/private/specialuse';
|
|
25
|
+
/**
|
|
26
|
+
* Checks an entry name against RFC 5464 section 3.2
|
|
27
|
+
*
|
|
28
|
+
* @param {String} name Entry name as a binary string
|
|
29
|
+
* @param {Boolean} [isSet] If true, the name must be one that can hold a value (at least 2 components,
|
|
30
|
+
* at least 4 under /shared/vendor and /private/vendor). GETMETADATA also accepts the bare "/shared"
|
|
31
|
+
* and "/private" scopes, so a client can ask for everything with DEPTH infinity
|
|
32
|
+
* @return {String|Boolean} Description of the problem, or false if the name is valid
|
|
33
|
+
*/
|
|
34
|
+
function checkEntryName(name, isSet) {
|
|
35
|
+
if (typeof name !== 'string' || name.charAt(0) !== '/') {
|
|
36
|
+
return 'Entry name must begin with "/"';
|
|
37
|
+
}
|
|
38
|
+
// "MUST NOT contain non-ASCII characters or characters with octet values in the range 0x00 to 0x19"
|
|
39
|
+
if (/[^\x20-\x7f]/.test(name)) {
|
|
40
|
+
return 'Entry name must not contain non-ASCII or control characters';
|
|
41
|
+
}
|
|
42
|
+
if (/[*%]/.test(name)) {
|
|
43
|
+
return 'Entry name must not contain "*" or "%"';
|
|
44
|
+
}
|
|
45
|
+
if (name.indexOf('//') >= 0) {
|
|
46
|
+
return 'Entry name must not contain consecutive "/" characters';
|
|
47
|
+
}
|
|
48
|
+
if (name.charAt(name.length - 1) === '/') {
|
|
49
|
+
return 'Entry name must not end with "/"';
|
|
50
|
+
}
|
|
51
|
+
const components = name.toLowerCase().substr(1).split('/');
|
|
52
|
+
if (components[0] !== 'private' && components[0] !== 'shared') {
|
|
53
|
+
return 'Entry name must begin with /private or /shared';
|
|
54
|
+
}
|
|
55
|
+
if (isSet && components.length < 2) {
|
|
56
|
+
return 'Entry name must have at least 2 components';
|
|
57
|
+
}
|
|
58
|
+
if (isSet && components[1] === 'vendor' && components.length < 4) {
|
|
59
|
+
return 'Vendor entry names must have at least 4 components';
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Converts a value from storage or options to a binary string. A value with NUL is sent as a literal8
|
|
65
|
+
*
|
|
66
|
+
* @param {String} name Entry name, for error messages
|
|
67
|
+
* @param {*} value Entry value
|
|
68
|
+
* @return {String|null} Binary string, or null for no value
|
|
69
|
+
*/
|
|
70
|
+
function normalizeValue(name, value) {
|
|
71
|
+
if (value === null || value === undefined) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
if (value instanceof Uint8Array) {
|
|
75
|
+
value = Buffer.from(value).toString('binary');
|
|
76
|
+
}
|
|
77
|
+
else if (typeof value === 'string') {
|
|
78
|
+
if (/[Ā-]/.test(value)) {
|
|
79
|
+
// characters outside Latin-1 can only come from a unicode string, so encode it as UTF-8
|
|
80
|
+
value = Buffer.from(value, 'utf-8').toString('binary');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
throw new Error('Invalid value for metadata entry ' + name + ', expecting a string');
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Formats a mailbox name for a METADATA response. IMAPConnection#send converts the storage name for
|
|
90
|
+
* each session (UTF-8 with UTF8=ACCEPT) and quotes it when it is not an atom
|
|
91
|
+
*
|
|
92
|
+
* @param {String} name Mailbox name, "" for the server
|
|
93
|
+
* @return {Object} Response attribute
|
|
94
|
+
*/
|
|
95
|
+
function mailboxAttribute(name) {
|
|
96
|
+
return { type: 'MAILBOX', value: name };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Sets up METADATA or METADATA-SERVER. With both plugins loaded, METADATA wins (RFC 5464 section 1:
|
|
100
|
+
* a server with mailbox annotations advertises METADATA)
|
|
101
|
+
*
|
|
102
|
+
* @param {Object} server IMAPServer instance
|
|
103
|
+
* @param {Boolean} mailboxes If true, mailbox annotations are supported, otherwise only server annotations
|
|
104
|
+
*/
|
|
105
|
+
function setup(server, mailboxes) {
|
|
106
|
+
if (server.metadataState) {
|
|
107
|
+
// the other variant is already loaded, upgrade it if needed
|
|
108
|
+
if (mailboxes && !server.metadataState.mailboxes) {
|
|
109
|
+
server.metadataState.mailboxes = true;
|
|
110
|
+
delete server.capabilities['METADATA-SERVER'];
|
|
111
|
+
server.registerCapability('METADATA');
|
|
112
|
+
server.enableAvailable.splice(server.enableAvailable.indexOf('METADATA-SERVER'), 1, 'METADATA');
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// RFC 5464 section 5: SETMETADATA values can be literal8
|
|
117
|
+
server.parserOptions.literal8 = true;
|
|
118
|
+
const capability = mailboxes ? 'METADATA' : 'METADATA-SERVER';
|
|
119
|
+
server.registerCapability(capability);
|
|
120
|
+
// RFC 5464 section 4.1: unsolicited METADATA responses are only sent after ENABLE
|
|
121
|
+
(0, enable_js_1.registerEnable)(server, capability);
|
|
122
|
+
const options = server.options;
|
|
123
|
+
const state = (server.metadataState = {
|
|
124
|
+
mailboxes,
|
|
125
|
+
maxSize: Number(options.metadataMaxSize) || DEFAULT_MAX_SIZE,
|
|
126
|
+
maxEntries: Number(options.metadataMaxEntries) || DEFAULT_MAX_ENTRIES,
|
|
127
|
+
allowPrivate: options.metadataPrivate !== false,
|
|
128
|
+
// server annotations, normalized on first use like mailbox annotations
|
|
129
|
+
server: { path: '', metadata: options.metadata }
|
|
130
|
+
});
|
|
131
|
+
// metadata objects that are already normalized
|
|
132
|
+
const normalized = new WeakSet();
|
|
133
|
+
/**
|
|
134
|
+
* Returns the stored entries of a mailbox or the server, as an object of lower case entry
|
|
135
|
+
* names (entry names are case-insensitive, RFC 5464 section 3.2) and binary string values
|
|
136
|
+
*
|
|
137
|
+
* @param {Object} holder Mailbox object or state.server
|
|
138
|
+
* @return {Object} Entries, replace them with setEntries instead of changing them
|
|
139
|
+
*/
|
|
140
|
+
const getEntries = (holder) => {
|
|
141
|
+
if (!holder.metadata) {
|
|
142
|
+
return Object.create(null);
|
|
143
|
+
}
|
|
144
|
+
if (normalized.has(holder.metadata)) {
|
|
145
|
+
return holder.metadata;
|
|
146
|
+
}
|
|
147
|
+
// initial values from storage or options, never modify the caller's objects
|
|
148
|
+
const entries = Object.create(null);
|
|
149
|
+
const metadata = holder.metadata;
|
|
150
|
+
Object.keys(metadata).forEach(name => {
|
|
151
|
+
const error = checkEntryName(name, true);
|
|
152
|
+
if (error) {
|
|
153
|
+
throw new Error('Invalid metadata entry name ' + JSON.stringify(name) + ': ' + error);
|
|
154
|
+
}
|
|
155
|
+
const value = normalizeValue(name, metadata[name]);
|
|
156
|
+
if (value !== null) {
|
|
157
|
+
entries[name.toLowerCase()] = value;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
return setEntries(holder, entries);
|
|
161
|
+
};
|
|
162
|
+
const setEntries = (holder, entries) => {
|
|
163
|
+
normalized.add(entries);
|
|
164
|
+
holder.metadata = entries;
|
|
165
|
+
return entries;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Returns entries that the server computes instead of storing them
|
|
169
|
+
*
|
|
170
|
+
* @param {Object} holder Mailbox object or state.server
|
|
171
|
+
* @return {Object} Entries, a null value means no value
|
|
172
|
+
*/
|
|
173
|
+
const getComputedEntries = (holder) => {
|
|
174
|
+
const computed = Object.create(null);
|
|
175
|
+
if (holder.path && server.capabilities['SPECIAL-USE']) {
|
|
176
|
+
// RFC 6154 section 4: NIL or the special-use attributes separated by spaces, as in LIST responses
|
|
177
|
+
const specialUse = [].concat(holder['special-use'] || []);
|
|
178
|
+
computed[SPECIAL_USE_ENTRY] = specialUse.length ? specialUse.join(' ') : null;
|
|
179
|
+
}
|
|
180
|
+
return computed;
|
|
181
|
+
};
|
|
182
|
+
const isMetadataEnabled = (connection) => (0, enable_js_1.isEnabled)(connection, state.mailboxes ? 'METADATA' : 'METADATA-SERVER');
|
|
183
|
+
/**
|
|
184
|
+
* Finds the annotation holder for a mailbox name argument, sends a NO if there is none
|
|
185
|
+
*
|
|
186
|
+
* @return {Object|Boolean} Mailbox object, state.server or false
|
|
187
|
+
*/
|
|
188
|
+
const getHolder = (connection, parsed, data, name) => {
|
|
189
|
+
if (name === '') {
|
|
190
|
+
return state.server;
|
|
191
|
+
}
|
|
192
|
+
if (!state.mailboxes) {
|
|
193
|
+
connection.sendStatus(parsed, data, 'NO', 'Mailbox annotations are not supported, only server annotations');
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
// RFC 5464 section 3.3: only mailboxes that exist and are returned by LIST. Annotations
|
|
197
|
+
// on \Noselect mailboxes are allowed (section 4.1)
|
|
198
|
+
const mailbox = connection.server.getMailbox(name);
|
|
199
|
+
if (!mailbox || mailbox.flags.indexOf('\\NonExistent') >= 0) {
|
|
200
|
+
connection.sendStatus(parsed, data, 'NO', 'Mailbox does not exist', 'NONEXISTENT');
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return mailbox;
|
|
204
|
+
};
|
|
205
|
+
const bad = (connection, parsed, data, text, callback) => {
|
|
206
|
+
connection.sendStatus(parsed, data, 'BAD', text);
|
|
207
|
+
return callback();
|
|
208
|
+
};
|
|
209
|
+
// RFC 5464 section 4.2, options before the mailbox name as corrected by errata 2785 and 2786:
|
|
210
|
+
// getmetadata = "GETMETADATA" [SP getmetadata-options] SP mailbox SP entries
|
|
211
|
+
server.setCommandHandler('GETMETADATA', (connection, parsed, data, callback) => {
|
|
212
|
+
const attrs = parsed.attributes || [];
|
|
213
|
+
const offset = Array.isArray(attrs[0]) ? 1 : 0;
|
|
214
|
+
let maxSize = false;
|
|
215
|
+
let depth = 0;
|
|
216
|
+
if (attrs.length !== offset + 2 || !(0, arguments_js_1.isAstring)(attrs[offset])) {
|
|
217
|
+
return bad(connection, parsed, data, 'GETMETADATA expects options, a mailbox name and entries', callback);
|
|
218
|
+
}
|
|
219
|
+
if (offset) {
|
|
220
|
+
// getmetadata-options = "(" getmetadata-option *(SP getmetadata-option) ")"
|
|
221
|
+
const list = attrs[0];
|
|
222
|
+
if (!list.length) {
|
|
223
|
+
return bad(connection, parsed, data, 'Empty option list', callback);
|
|
224
|
+
}
|
|
225
|
+
for (let i = 0; i < list.length; i += 2) {
|
|
226
|
+
const label = list[i] && list[i].type === 'ATOM' ? list[i].value.toUpperCase() : false;
|
|
227
|
+
const value = list[i + 1] && list[i + 1].type === 'ATOM' ? list[i + 1].value : false;
|
|
228
|
+
if (label === 'MAXSIZE') {
|
|
229
|
+
// maxsize-opt = "MAXSIZE" SP number
|
|
230
|
+
if (!(0, numbers_js_1.isNumber)(value)) {
|
|
231
|
+
return bad(connection, parsed, data, 'Invalid value for MAXSIZE', callback);
|
|
232
|
+
}
|
|
233
|
+
maxSize = Number(value);
|
|
234
|
+
}
|
|
235
|
+
else if (label === 'DEPTH') {
|
|
236
|
+
// scope-opt = "DEPTH" SP ("0" / "1" / "infinity")
|
|
237
|
+
if (!value || !/^(0|1|infinity)$/i.test(value)) {
|
|
238
|
+
return bad(connection, parsed, data, 'Invalid value for DEPTH', callback);
|
|
239
|
+
}
|
|
240
|
+
depth = value.toLowerCase() === 'infinity' ? Infinity : Number(value);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
return bad(connection, parsed, data, 'Unknown GETMETADATA option', callback);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// the mailbox position depends on the options, so the name is converted here, not by mailboxArguments
|
|
248
|
+
let mailboxName;
|
|
249
|
+
try {
|
|
250
|
+
mailboxName = connection.importMailboxName(attrs[offset].value);
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
return bad(connection, parsed, data, err.message, callback);
|
|
254
|
+
}
|
|
255
|
+
// entries = entry / "(" entry *(SP entry) ")"
|
|
256
|
+
const entryAttrs = [].concat(attrs[offset + 1]);
|
|
257
|
+
if (!entryAttrs.length || !entryAttrs.every(arguments_js_1.isAstring)) {
|
|
258
|
+
return bad(connection, parsed, data, 'GETMETADATA expects an entry name or a list of entry names', callback);
|
|
259
|
+
}
|
|
260
|
+
for (const attr of entryAttrs) {
|
|
261
|
+
const error = checkEntryName(attr.value);
|
|
262
|
+
if (error) {
|
|
263
|
+
// RFC 5464 section 3.2: "Invalid entry names result in a BAD response"
|
|
264
|
+
return bad(connection, parsed, data, error, callback);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const holder = getHolder(connection, parsed, data, mailboxName);
|
|
268
|
+
if (!holder) {
|
|
269
|
+
return callback();
|
|
270
|
+
}
|
|
271
|
+
const all = Object.assign(Object.create(null), getEntries(holder), getComputedEntries(holder));
|
|
272
|
+
const names = depth
|
|
273
|
+
? Object.keys(all)
|
|
274
|
+
.filter(name => all[name] !== null)
|
|
275
|
+
.sort()
|
|
276
|
+
: [];
|
|
277
|
+
// RFC 5464 section 4.2.2: the entry itself and the entries below it up to DEPTH
|
|
278
|
+
const found = new Map();
|
|
279
|
+
for (const attr of entryAttrs) {
|
|
280
|
+
const entry = attr.value.toLowerCase();
|
|
281
|
+
const value = all[entry] ?? null;
|
|
282
|
+
if (!depth || value !== null) {
|
|
283
|
+
// a requested entry without a value is returned as NIL
|
|
284
|
+
found.set(entry, value);
|
|
285
|
+
}
|
|
286
|
+
const prefix = entry + '/';
|
|
287
|
+
names.forEach(name => {
|
|
288
|
+
if (name.startsWith(prefix) && (depth === Infinity || name.indexOf('/', prefix.length) < 0)) {
|
|
289
|
+
found.set(name, all[name]);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
// RFC 5464 section 4.2.1: larger values are left out, LONGENTRIES reports the biggest one
|
|
294
|
+
let longest = -1;
|
|
295
|
+
const pairs = [];
|
|
296
|
+
found.forEach((value, name) => {
|
|
297
|
+
if (maxSize !== false && value !== null && value.length > maxSize) {
|
|
298
|
+
longest = Math.max(longest, value.length);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
// RFC 5464 section 5: value = nstring / literal8, only binary data with NUL needs a literal8
|
|
302
|
+
pairs.push({ type: 'ATOM', value: name }, value === null ? null : { type: value.indexOf('\x00') >= 0 ? 'LITERAL8' : 'STRING', value });
|
|
303
|
+
});
|
|
304
|
+
if (pairs.length) {
|
|
305
|
+
connection.send({
|
|
306
|
+
tag: '*',
|
|
307
|
+
command: 'METADATA',
|
|
308
|
+
attributes: [mailboxAttribute(holder.path), pairs]
|
|
309
|
+
}, 'METADATA', parsed, data, holder);
|
|
310
|
+
}
|
|
311
|
+
connection.sendStatus(parsed, data, 'OK', 'GETMETADATA completed', longest >= 0 && ['METADATA', 'LONGENTRIES', longest]);
|
|
312
|
+
return callback();
|
|
313
|
+
}, { states: command_states_js_1.states.AUTHENTICATED });
|
|
314
|
+
// RFC 5464 section 4.3: setmetadata = "SETMETADATA" SP mailbox SP entry-values
|
|
315
|
+
server.setCommandHandler('SETMETADATA', (connection, parsed, data, callback) => {
|
|
316
|
+
const attrs = parsed.attributes || [];
|
|
317
|
+
if (attrs.length !== 2 || !(0, arguments_js_1.isAstring)(attrs[0]) || !Array.isArray(attrs[1])) {
|
|
318
|
+
return bad(connection, parsed, data, 'SETMETADATA expects a mailbox name and a list of entries and values', callback);
|
|
319
|
+
}
|
|
320
|
+
// entry-values = "(" entry-value *(SP entry-value) ")", entry-value = entry SP value
|
|
321
|
+
const list = attrs[1];
|
|
322
|
+
if (!list.length || list.length % 2) {
|
|
323
|
+
return bad(connection, parsed, data, 'SETMETADATA expects entry and value pairs', callback);
|
|
324
|
+
}
|
|
325
|
+
const changes = new Map();
|
|
326
|
+
for (let i = 0; i < list.length; i += 2) {
|
|
327
|
+
if (!(0, arguments_js_1.isAstring)(list[i])) {
|
|
328
|
+
return bad(connection, parsed, data, 'Entry name must be a string', callback);
|
|
329
|
+
}
|
|
330
|
+
const error = checkEntryName(list[i].value, true);
|
|
331
|
+
if (error) {
|
|
332
|
+
return bad(connection, parsed, data, error, callback);
|
|
333
|
+
}
|
|
334
|
+
// value = nstring / literal8, an atom is not a value
|
|
335
|
+
const value = list[i + 1];
|
|
336
|
+
if (value !== null && (!value || ['STRING', 'LITERAL', 'LITERAL8'].indexOf(value.type) < 0)) {
|
|
337
|
+
return bad(connection, parsed, data, 'Entry value must be a string, a literal, a literal8 or NIL', callback);
|
|
338
|
+
}
|
|
339
|
+
// RFC 5464 section 3.2: "Clients MUST use the CRLF (0x0D 0x0A) character octet sequence
|
|
340
|
+
// to represent line ends in a multi-line string value", binary data in a literal8 is not a string
|
|
341
|
+
if (value && value.type !== 'LITERAL8' && /\r(?!\n)|(?:^|[^\r])\n/.test(value.value)) {
|
|
342
|
+
return bad(connection, parsed, data, 'Line ends in a value must be CRLF', callback);
|
|
343
|
+
}
|
|
344
|
+
changes.set(list[i].value.toLowerCase(), value ? value.value : null);
|
|
345
|
+
}
|
|
346
|
+
const holder = getHolder(connection, parsed, data, attrs[0].value);
|
|
347
|
+
if (!holder) {
|
|
348
|
+
return callback();
|
|
349
|
+
}
|
|
350
|
+
const entries = getEntries(holder);
|
|
351
|
+
const computed = getComputedEntries(holder);
|
|
352
|
+
const fail = (text, code) => {
|
|
353
|
+
// RFC 5464 section 4.3: when one entry fails, no entry is changed
|
|
354
|
+
connection.sendStatus(parsed, data, 'NO', text, code);
|
|
355
|
+
return callback();
|
|
356
|
+
};
|
|
357
|
+
// changes go to a copy that replaces the entries once every check passed
|
|
358
|
+
const next = Object.assign(Object.create(null), entries);
|
|
359
|
+
const changed = [];
|
|
360
|
+
for (const [name, value] of changes) {
|
|
361
|
+
if ((!holder.path && READ_ONLY_SERVER_ENTRIES.has(name)) || name in computed) {
|
|
362
|
+
return fail('The ' + name + ' entry is read-only', 'CANNOT');
|
|
363
|
+
}
|
|
364
|
+
if (!state.allowPrivate && name.startsWith('/private/')) {
|
|
365
|
+
return fail('Private annotations are not supported', ['METADATA', 'NOPRIVATE']);
|
|
366
|
+
}
|
|
367
|
+
if (value !== null && value.length > state.maxSize) {
|
|
368
|
+
return fail('Value of ' + name + ' is too large', ['METADATA', 'MAXSIZE', state.maxSize]);
|
|
369
|
+
}
|
|
370
|
+
if ((entries[name] ?? null) !== value) {
|
|
371
|
+
changed.push(name);
|
|
372
|
+
}
|
|
373
|
+
if (value === null) {
|
|
374
|
+
delete next[name];
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
next[name] = value;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// only adding entries can fail, even when the storage already holds more than the limit
|
|
381
|
+
const count = Object.keys(next).length;
|
|
382
|
+
if (count > state.maxEntries && count > Object.keys(entries).length) {
|
|
383
|
+
return fail('Too many annotations', ['METADATA', 'TOOMANY']);
|
|
384
|
+
}
|
|
385
|
+
setEntries(holder, next);
|
|
386
|
+
if (changed.length) {
|
|
387
|
+
// RFC 5464 section 4.4.2: unsolicited responses only list the entry names. Section 4.1:
|
|
388
|
+
// only sessions that used ENABLE METADATA (or METADATA-SERVER) get them
|
|
389
|
+
server.notify({
|
|
390
|
+
tag: '*',
|
|
391
|
+
command: 'METADATA',
|
|
392
|
+
attributes: [mailboxAttribute(holder.path)].concat(changed.map(name => ({ type: 'ATOM', value: name })))
|
|
393
|
+
}, false, connection, isMetadataEnabled);
|
|
394
|
+
}
|
|
395
|
+
connection.sendStatus(parsed, data, 'OK', 'SETMETADATA completed');
|
|
396
|
+
return callback();
|
|
397
|
+
},
|
|
398
|
+
// RFC 5464 section 5: values can be literal8, with or without BINARY
|
|
399
|
+
{ states: command_states_js_1.states.AUTHENTICATED, mailboxArguments: [0], literal8: true });
|
|
400
|
+
server.outputHandlers.push((connection, response, description, parsed, data, extra) => {
|
|
401
|
+
if (response.command !== 'OK' || !parsed || !parsed.attributes) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (description === 'RENAME' && extra && extra.path === 'INBOX') {
|
|
405
|
+
// RFC 5464 section 4.1: renaming INBOX copies its annotations, INBOX keeps them. Other
|
|
406
|
+
// mailboxes are moved as objects, so their annotations follow without any help
|
|
407
|
+
const target = connection.server.getMailbox(parsed.attributes[1].value);
|
|
408
|
+
if (target && target !== extra && extra.metadata) {
|
|
409
|
+
setEntries(target, Object.assign(Object.create(null), getEntries(extra)));
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
else if (description === 'DELETE') {
|
|
413
|
+
// RFC 5464 section 4.1: a mailbox created later with the same name must not inherit the
|
|
414
|
+
// annotations. A mailbox with children stays as a \Noselect placeholder
|
|
415
|
+
const placeholder = connection.server.getMailbox(parsed.attributes[0].value);
|
|
416
|
+
if (placeholder) {
|
|
417
|
+
delete placeholder.metadata;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
function metadataPlugin(server) {
|
|
423
|
+
setup(server, true);
|
|
424
|
+
}
|
|
425
|
+
{
|
|
426
|
+
const defaultExport = exports.default;
|
|
427
|
+
if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
|
|
428
|
+
for (const key of Object.keys(exports)) {
|
|
429
|
+
if (key !== 'default' && !(key in defaultExport)) {
|
|
430
|
+
defaultExport[key] = exports[key];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
|
|
434
|
+
module.exports = defaultExport;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IMAPServer } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @help Adds MOVE [RFC6851] capability
|
|
4
|
+
*
|
|
5
|
+
* MOVE: http://tools.ietf.org/html/rfc6851
|
|
6
|
+
*
|
|
7
|
+
* Additional commands:
|
|
8
|
+
* - MOVE
|
|
9
|
+
* - UID MOVE
|
|
10
|
+
*/
|
|
11
|
+
export default function movePlugin(server: IMAPServer): void;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = movePlugin;
|
|
4
|
+
const copy_js_1 = require("../commands/copy.js");
|
|
5
|
+
const command_states_js_1 = require("../command-states.js");
|
|
6
|
+
/**
|
|
7
|
+
* @help Adds MOVE [RFC6851] capability
|
|
8
|
+
*
|
|
9
|
+
* MOVE: http://tools.ietf.org/html/rfc6851
|
|
10
|
+
*
|
|
11
|
+
* Additional commands:
|
|
12
|
+
* - MOVE
|
|
13
|
+
* - UID MOVE
|
|
14
|
+
*/
|
|
15
|
+
function movePlugin(server) {
|
|
16
|
+
server.registerCapability('MOVE');
|
|
17
|
+
const moveHandler = function (uidMode, connection, parsed, data, callback) {
|
|
18
|
+
function uidify(str) {
|
|
19
|
+
if (uidMode) {
|
|
20
|
+
return 'UID ' + str;
|
|
21
|
+
}
|
|
22
|
+
return str;
|
|
23
|
+
}
|
|
24
|
+
if (!parsed.attributes ||
|
|
25
|
+
parsed.attributes.length !== 2 ||
|
|
26
|
+
!parsed.attributes[0] ||
|
|
27
|
+
['ATOM', 'SEQUENCE'].indexOf(parsed.attributes[0].type) < 0 ||
|
|
28
|
+
!parsed.attributes[1] ||
|
|
29
|
+
['ATOM', 'STRING', 'LITERAL'].indexOf(parsed.attributes[1].type) < 0) {
|
|
30
|
+
connection.send({
|
|
31
|
+
tag: parsed.tag,
|
|
32
|
+
command: 'BAD',
|
|
33
|
+
attributes: [
|
|
34
|
+
{
|
|
35
|
+
type: 'TEXT',
|
|
36
|
+
value: uidify('MOVE expects sequence set and a mailbox name')
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}, 'INVALID COMMAND', parsed, data);
|
|
40
|
+
return callback();
|
|
41
|
+
}
|
|
42
|
+
// MOVE expunges messages from the source mailbox, which is not allowed after EXAMINE
|
|
43
|
+
if (connection.refuseReadOnly(parsed, data, uidify('MOVE FAIL'))) {
|
|
44
|
+
return callback();
|
|
45
|
+
}
|
|
46
|
+
const result = (0, copy_js_1.copyToMailbox)(connection, parsed, data, uidMode, uidify('MOVE FAIL'), true);
|
|
47
|
+
if (!result) {
|
|
48
|
+
return callback();
|
|
49
|
+
}
|
|
50
|
+
// Hook for UIDPLUS to generate the untagged COPYUID response (that wants
|
|
51
|
+
// to happen prior to the EXPUNGEs). If the UIDPLUS extension is not
|
|
52
|
+
// active, this will not happen.
|
|
53
|
+
connection.send({
|
|
54
|
+
tag: '*',
|
|
55
|
+
command: 'OK',
|
|
56
|
+
attributes: [
|
|
57
|
+
{
|
|
58
|
+
type: 'TEXT',
|
|
59
|
+
value: 'Copied'
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
skipResponse: true
|
|
63
|
+
}, uidify('MOVE COPYUID'), parsed, data, result);
|
|
64
|
+
// Expunge the messages from the source folder. When moving into the selected mailbox,
|
|
65
|
+
// the copies were already announced with EXISTS responses
|
|
66
|
+
connection.expungeSpecificMessages(connection.selectedMailbox, result.messages, false, true, !!parsed.highestFirst);
|
|
67
|
+
connection.send({
|
|
68
|
+
tag: parsed.tag,
|
|
69
|
+
command: 'OK',
|
|
70
|
+
attributes: [
|
|
71
|
+
{
|
|
72
|
+
type: 'TEXT',
|
|
73
|
+
value: 'Done'
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}, uidify('MOVE OK'), parsed, data);
|
|
77
|
+
callback();
|
|
78
|
+
};
|
|
79
|
+
// RFC 6851 section 3.1: valid only in the selected state, the second argument is the target mailbox
|
|
80
|
+
// MOVE takes a sequence set of message numbers, UID MOVE of UIDs
|
|
81
|
+
const options = { states: command_states_js_1.states.SELECTED, mailboxArguments: [1] };
|
|
82
|
+
server.setCommandHandler('MOVE', moveHandler.bind(null, false), Object.assign({ sequenceSet: 0 }, options));
|
|
83
|
+
server.setCommandHandler('UID MOVE', moveHandler.bind(null, true), options);
|
|
84
|
+
}
|
|
85
|
+
{
|
|
86
|
+
const defaultExport = exports.default;
|
|
87
|
+
if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
|
|
88
|
+
for (const key of Object.keys(exports)) {
|
|
89
|
+
if (key !== 'default' && !(key in defaultExport)) {
|
|
90
|
+
defaultExport[key] = exports[key];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
|
|
94
|
+
module.exports = defaultExport;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IMAPServer } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @help Adds MULTIAPPEND [RFC3502] capability
|
|
4
|
+
* @help With UIDPLUS, APPENDUID lists the UIDs of all messages
|
|
5
|
+
*
|
|
6
|
+
* MULTIAPPEND: https://www.rfc-editor.org/rfc/rfc3502
|
|
7
|
+
*
|
|
8
|
+
* APPEND takes several messages, which are appended all or nothing. A zero-length
|
|
9
|
+
* message literal cancels the whole APPEND with NO. With UIDPLUS, APPENDUID lists the
|
|
10
|
+
* UIDs of all appended messages as a UID set.
|
|
11
|
+
*/
|
|
12
|
+
export default function multiappendPlugin(server: IMAPServer): void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = multiappendPlugin;
|
|
4
|
+
/**
|
|
5
|
+
* @help Adds MULTIAPPEND [RFC3502] capability
|
|
6
|
+
* @help With UIDPLUS, APPENDUID lists the UIDs of all messages
|
|
7
|
+
*
|
|
8
|
+
* MULTIAPPEND: https://www.rfc-editor.org/rfc/rfc3502
|
|
9
|
+
*
|
|
10
|
+
* APPEND takes several messages, which are appended all or nothing. A zero-length
|
|
11
|
+
* message literal cancels the whole APPEND with NO. With UIDPLUS, APPENDUID lists the
|
|
12
|
+
* UIDs of all appended messages as a UID set.
|
|
13
|
+
*/
|
|
14
|
+
function multiappendPlugin(server) {
|
|
15
|
+
server.registerCapability('MULTIAPPEND');
|
|
16
|
+
server.multiAppend = true;
|
|
17
|
+
// RFC 3502 section 6.3.11: "A zero-length message literal argument is an error, and MUST return a NO.
|
|
18
|
+
// This can be used to cancel the append." Nothing is stored when any message fails
|
|
19
|
+
server.appendChecks.push((connection, mailbox, messages, options) => {
|
|
20
|
+
// only APPEND like commands, not COPY or MOVE
|
|
21
|
+
if (options.command && messages.some(message => !message.resolve && !message.raw.length)) {
|
|
22
|
+
return { text: 'Zero-length message literal, APPEND cancelled' };
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
{
|
|
28
|
+
const defaultExport = exports.default;
|
|
29
|
+
if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
|
|
30
|
+
for (const key of Object.keys(exports)) {
|
|
31
|
+
if (key !== 'default' && !(key in defaultExport)) {
|
|
32
|
+
defaultExport[key] = exports[key];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
|
|
36
|
+
module.exports = defaultExport;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @help Adds MULTISEARCH [RFC7377] capability, loads ESEARCH as well
|
|
3
|
+
* @help ESEARCH IN (mailboxes "a" subtree "b" personal ...) RETURN (...) searches several mailboxes, also in the authenticated state
|
|
4
|
+
*/
|
|
5
|
+
import type { IMAPServer } from '../types.js';
|
|
6
|
+
export default function multisearchPlugin(server: IMAPServer): void;
|