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,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { badError } = require('../commands/handlers/search');
|
|
8
|
-
const { isAtom, isAstring } = require('../arguments');
|
|
9
|
-
|
|
1
|
+
import { states } from '../command-states.js';
|
|
2
|
+
import { fetchResponse } from '../commands/fetch.js';
|
|
3
|
+
import builtinFetchHandlers from '../commands/handlers/fetch.js';
|
|
4
|
+
import { statusResponse } from '../commands/handlers/status.js';
|
|
5
|
+
import { badError } from '../commands/handlers/search.js';
|
|
6
|
+
import { isAtom, isAstring } from '../arguments.js';
|
|
10
7
|
/**
|
|
11
8
|
* @help Adds NOTIFY [RFC5465] capability. Events: MessageNew (with
|
|
12
9
|
* @help fetch attributes for the selected mailbox), MessageExpunge,
|
|
@@ -25,23 +22,17 @@ const { isAtom, isAstring } = require('../arguments');
|
|
|
25
22
|
* responses of its own commands are sent as usual. Fetch attributes of MessageNew never set \Seen,
|
|
26
23
|
* clients SHOULD NOT use such attributes anyway (section 5.2).
|
|
27
24
|
*/
|
|
28
|
-
|
|
29
25
|
// RFC 5465 section 8, canonical names by upper case name
|
|
30
26
|
const MESSAGE_EVENTS = ['MessageNew', 'MessageExpunge', 'FlagChange', 'AnnotationChange'];
|
|
31
|
-
const EVENT_NAMES = new Map(
|
|
32
|
-
MESSAGE_EVENTS.concat(['MailboxName', 'SubscriptionChange', 'MailboxMetadataChange', 'ServerMetadataChange']).map(name => [name.toUpperCase(), name])
|
|
33
|
-
);
|
|
27
|
+
const EVENT_NAMES = new Map(MESSAGE_EVENTS.concat(['MailboxName', 'SubscriptionChange', 'MailboxMetadataChange', 'ServerMetadataChange']).map(name => [name.toUpperCase(), name]));
|
|
34
28
|
const SELECTED_FILTERS = ['SELECTED', 'SELECTED-DELAYED'];
|
|
35
29
|
const OTHER_FILTERS = ['INBOXES', 'PERSONAL', 'SUBSCRIBED', 'SUBTREE', 'MAILBOXES'];
|
|
36
30
|
// fetch items whose arguments are checked with a dry run when NOTIFY SET is parsed
|
|
37
31
|
const SECTION_ITEMS = ['BODY', 'BODY.PEEK', 'BINARY', 'BINARY.PEEK', 'BINARY.SIZE'];
|
|
38
|
-
|
|
39
|
-
module.exports = function (server) {
|
|
32
|
+
export default function notifyPlugin(server) {
|
|
40
33
|
server.registerCapability('NOTIFY');
|
|
41
|
-
|
|
42
34
|
// NOTIFY needs the authenticated state, UNAUTHENTICATE clears the settings
|
|
43
|
-
const isActive = connection => !!connection.notifyState;
|
|
44
|
-
|
|
35
|
+
const isActive = (connection) => !!connection.notifyState;
|
|
45
36
|
// RFC 5465 sections 5.6 and 5.7: the metadata events are supported (and REQUIRED) with METADATA or METADATA-SERVER
|
|
46
37
|
const getSupportedEvents = () => {
|
|
47
38
|
const supported = ['MessageNew', 'MessageExpunge', 'FlagChange', 'MailboxName', 'SubscriptionChange'];
|
|
@@ -53,7 +44,6 @@ module.exports = function (server) {
|
|
|
53
44
|
}
|
|
54
45
|
return supported;
|
|
55
46
|
};
|
|
56
|
-
|
|
57
47
|
// Access checks, RFC 5465 section 3.1 and section 5: every event needs the "l" and "r" rights
|
|
58
48
|
const hasRights = (connection, mailbox, letters, acl) => {
|
|
59
49
|
const rights = server.acl && server.acl.getRights(connection, mailbox, acl);
|
|
@@ -61,9 +51,7 @@ module.exports = function (server) {
|
|
|
61
51
|
};
|
|
62
52
|
const canList = (connection, mailbox, acl) => hasRights(connection, mailbox, 'l', acl);
|
|
63
53
|
const canRead = (connection, mailbox, acl) => hasRights(connection, mailbox, 'lr', acl);
|
|
64
|
-
|
|
65
|
-
const normalizePath = path => (path.toUpperCase() === 'INBOX' ? 'INBOX' : path);
|
|
66
|
-
|
|
54
|
+
const normalizePath = (path) => (path.toUpperCase() === 'INBOX' ? 'INBOX' : path);
|
|
67
55
|
/**
|
|
68
56
|
* Checks if an event group of NOTIFY SET covers a mailbox name (RFC 5465 section 6)
|
|
69
57
|
*
|
|
@@ -83,14 +71,13 @@ module.exports = function (server) {
|
|
|
83
71
|
// RFC 5465 section 6.4: the list is reevaluated when subscriptions change
|
|
84
72
|
return !!subscription || !!(mailbox && mailbox.subscribed);
|
|
85
73
|
case 'SUBTREE':
|
|
86
|
-
return group.paths.indexOf(path) >= 0 || group.prefixes.some(prefix => path.substr(0, prefix.length) === prefix);
|
|
74
|
+
return group.paths.indexOf(path) >= 0 || group.prefixes.some((prefix) => path.substr(0, prefix.length) === prefix);
|
|
87
75
|
case 'MAILBOXES':
|
|
88
76
|
// RFC 5465 section 6.6: no wildcard expansion
|
|
89
77
|
return group.paths.indexOf(path) >= 0;
|
|
90
78
|
}
|
|
91
79
|
return false;
|
|
92
80
|
};
|
|
93
|
-
|
|
94
81
|
/**
|
|
95
82
|
* Lists the events a session asked for on a mailbox other than the selected one. Several groups
|
|
96
83
|
* can cover the same mailbox (RFC 5465 section 6), message events for the selected mailbox only
|
|
@@ -110,24 +97,20 @@ module.exports = function (server) {
|
|
|
110
97
|
}
|
|
111
98
|
return events;
|
|
112
99
|
};
|
|
113
|
-
|
|
114
100
|
// RFC 5465 section 6.1.2: with SELECTED-DELAYED an expunge waits for a command that allows it
|
|
115
|
-
const isHeld = connection =>
|
|
116
|
-
!!(connection.notifyState.selected && connection.notifyState.selected.delayed) && !connection.directNotifications && connection.hasPendingExpunge();
|
|
117
|
-
|
|
101
|
+
const isHeld = (connection) => !!(connection.notifyState.selected && connection.notifyState.selected.delayed) && !connection.directNotifications && connection.hasPendingExpunge();
|
|
118
102
|
/**
|
|
119
103
|
* Sends the queued notifications of a session that is between commands (RFC 5465 section 3.1: the
|
|
120
104
|
* client listens all the time). During a command they wait for its tagged response
|
|
121
105
|
*/
|
|
122
|
-
const flush = connection => {
|
|
106
|
+
const flush = (connection) => {
|
|
123
107
|
if (!connection.socket || !connection.notificationQueue.length || connection._runningCommand || !isActive(connection) || isHeld(connection)) {
|
|
124
108
|
return;
|
|
125
109
|
}
|
|
126
110
|
connection.processNotifications();
|
|
127
111
|
};
|
|
128
|
-
|
|
129
112
|
// the events of one command go out together, e.g. several expunges as one VANISHED response (QRESYNC)
|
|
130
|
-
const scheduleFlush = connection => {
|
|
113
|
+
const scheduleFlush = (connection) => {
|
|
131
114
|
if (!connection.notifyFlushPending) {
|
|
132
115
|
connection.notifyFlushPending = true;
|
|
133
116
|
setImmediate(() => {
|
|
@@ -136,14 +119,14 @@ module.exports = function (server) {
|
|
|
136
119
|
});
|
|
137
120
|
}
|
|
138
121
|
};
|
|
139
|
-
|
|
140
122
|
/**
|
|
141
123
|
* Sends an event response about another mailbox or about the server
|
|
142
124
|
*
|
|
143
125
|
* @param {Object} connection IMAP connection
|
|
144
126
|
* @param {Object} response Untagged response
|
|
145
127
|
*/
|
|
146
|
-
const deliver = (connection,
|
|
128
|
+
const deliver = (connection, event) => {
|
|
129
|
+
const response = event;
|
|
147
130
|
response.tag = '*';
|
|
148
131
|
response.notification = true;
|
|
149
132
|
if (!connection._runningCommand && isHeld(connection)) {
|
|
@@ -154,10 +137,8 @@ module.exports = function (server) {
|
|
|
154
137
|
connection.notificationQueue.push(response);
|
|
155
138
|
scheduleFlush(connection);
|
|
156
139
|
};
|
|
157
|
-
|
|
158
140
|
// the sessions that use NOTIFY, other than the one that caused a change (RFC 5465 section 5: SHOULD omit)
|
|
159
|
-
const listeners = origin => [...server.connections].filter(connection => connection !== origin && isActive(connection));
|
|
160
|
-
|
|
141
|
+
const listeners = (origin) => [...server.connections].filter(connection => connection !== origin && isActive(connection));
|
|
161
142
|
/**
|
|
162
143
|
* Builds an unsolicited STATUS response for a mailbox. With FlagChange the UNSEEN count is added
|
|
163
144
|
* when it changed since the session last heard of it (RFC 5465 section 5.1), with CONDSTORE (or
|
|
@@ -168,7 +149,8 @@ module.exports = function (server) {
|
|
|
168
149
|
const eventStatus = (connection, mailbox, items, events) => {
|
|
169
150
|
items = items.slice();
|
|
170
151
|
if (events.has('FlagChange')) {
|
|
171
|
-
const
|
|
152
|
+
const status = server.getStatus(mailbox);
|
|
153
|
+
const unseen = (status && status.unseen) || 0;
|
|
172
154
|
if (connection.notifyState.unseen.get(mailbox) !== unseen) {
|
|
173
155
|
connection.notifyState.unseen.set(mailbox, unseen);
|
|
174
156
|
items.push('UNSEEN');
|
|
@@ -182,7 +164,6 @@ module.exports = function (server) {
|
|
|
182
164
|
}
|
|
183
165
|
return statusResponse(connection, mailbox.path, mailbox, items);
|
|
184
166
|
};
|
|
185
|
-
|
|
186
167
|
// Reports a change of the messages of a mailbox that is not selected (RFC 5465 sections 5.1, 5.2 and 5.3)
|
|
187
168
|
const messageEvent = (mailbox, event, items, origin) => {
|
|
188
169
|
listeners(origin).forEach(connection => {
|
|
@@ -193,22 +174,14 @@ module.exports = function (server) {
|
|
|
193
174
|
if (!events.has(event)) {
|
|
194
175
|
return;
|
|
195
176
|
}
|
|
196
|
-
const response = eventStatus(
|
|
197
|
-
connection,
|
|
198
|
-
mailbox,
|
|
199
|
-
event === 'FlagChange' && server.condstore && server.condstore.isEnabled(connection) ? ['UIDVALIDITY'] : items,
|
|
200
|
-
events
|
|
201
|
-
);
|
|
177
|
+
const response = eventStatus(connection, mailbox, event === 'FlagChange' && server.condstore && server.condstore.isEnabled(connection) ? ['UIDVALIDITY'] : items, events);
|
|
202
178
|
if (response) {
|
|
203
179
|
deliver(connection, response);
|
|
204
180
|
}
|
|
205
181
|
});
|
|
206
182
|
};
|
|
207
|
-
|
|
208
183
|
// Checks if any mailbox below a mailbox is visible to the session (RFC 3348 section 4)
|
|
209
|
-
const hasVisibleChildren = (connection, path) =>
|
|
210
|
-
server.hasDescendant(path, child => canList(connection, child) && child.flags.indexOf('\\NonExistent') < 0);
|
|
211
|
-
|
|
184
|
+
const hasVisibleChildren = (connection, path) => server.hasDescendant(path, (child) => canList(connection, child) && child.flags.indexOf('\\NonExistent') < 0);
|
|
212
185
|
/**
|
|
213
186
|
* Builds an unsolicited LIST response with accurate attributes (RFC 5465 sections 5.4 and 5.5)
|
|
214
187
|
*
|
|
@@ -233,7 +206,6 @@ module.exports = function (server) {
|
|
|
233
206
|
}
|
|
234
207
|
return { tag: '*', command: 'LIST', attributes };
|
|
235
208
|
};
|
|
236
|
-
|
|
237
209
|
// RFC 5465 section 5.4: a created or deleted mailbox and its direct parent are affected
|
|
238
210
|
const nameEvent = (connection, path, mailbox, exists) => {
|
|
239
211
|
[path, server.getParentPath(path)].forEach(name => {
|
|
@@ -246,16 +218,15 @@ module.exports = function (server) {
|
|
|
246
218
|
}
|
|
247
219
|
});
|
|
248
220
|
};
|
|
249
|
-
|
|
250
221
|
// RFC 5465 section 5.1: with FlagChange the server MUST tell about UIDVALIDITY changes, a mailbox that
|
|
251
222
|
// gets a name that is watched has a new UIDVALIDITY
|
|
252
223
|
const uidvalidityEvent = (connection, mailbox) => {
|
|
253
224
|
if (mailbox !== connection.selectedMailbox && canRead(connection, mailbox) && getEvents(connection, mailbox.path, mailbox).has('FlagChange')) {
|
|
225
|
+
// the item list is not empty, so there is always a response
|
|
254
226
|
deliver(connection, eventStatus(connection, mailbox, ['MESSAGES', 'UIDNEXT', 'UIDVALIDITY'], new Set(['FlagChange'])));
|
|
255
227
|
}
|
|
256
228
|
};
|
|
257
|
-
|
|
258
|
-
server.on('mailbox', change => {
|
|
229
|
+
server.on('mailbox', (change) => {
|
|
259
230
|
const mailbox = server.getMailbox(change.path);
|
|
260
231
|
listeners(change.origin).forEach(connection => {
|
|
261
232
|
switch (change.type) {
|
|
@@ -274,6 +245,7 @@ module.exports = function (server) {
|
|
|
274
245
|
// RFC 5465 section 5.4: one LIST response for the new name, none for the children
|
|
275
246
|
if (mailbox && canList(connection, mailbox)) {
|
|
276
247
|
const events = getEvents(connection, change.path, mailbox);
|
|
248
|
+
// a rename always has the old name
|
|
277
249
|
getEvents(connection, change.oldPath).forEach(event => events.add(event));
|
|
278
250
|
if (events.has('MailboxName')) {
|
|
279
251
|
deliver(connection, listResponse(connection, change.path, { oldPath: change.oldPath }));
|
|
@@ -291,7 +263,6 @@ module.exports = function (server) {
|
|
|
291
263
|
}
|
|
292
264
|
});
|
|
293
265
|
});
|
|
294
|
-
|
|
295
266
|
// RFC 5465 section 5.4: granting or revoking the "l" right counts as creating or deleting the mailbox. Section 5.9:
|
|
296
267
|
// monitoring stops without the rights and starts again when they are granted, \NoAccess tells about the "r" right
|
|
297
268
|
server.on('acl', (mailbox, previous) => {
|
|
@@ -300,7 +271,8 @@ module.exports = function (server) {
|
|
|
300
271
|
const after = { list: canList(connection, mailbox), read: canRead(connection, mailbox) };
|
|
301
272
|
if (before.list !== after.list) {
|
|
302
273
|
nameEvent(connection, mailbox.path, mailbox, after.list);
|
|
303
|
-
}
|
|
274
|
+
}
|
|
275
|
+
else if (after.list && before.read !== after.read) {
|
|
304
276
|
const events = getEvents(connection, mailbox.path, mailbox);
|
|
305
277
|
if (MESSAGE_EVENTS.some(event => events.has(event))) {
|
|
306
278
|
deliver(connection, listResponse(connection, mailbox.path, { noAccess: !after.read }));
|
|
@@ -308,18 +280,17 @@ module.exports = function (server) {
|
|
|
308
280
|
}
|
|
309
281
|
});
|
|
310
282
|
});
|
|
311
|
-
|
|
312
283
|
server.on('expunge', (mailbox, messages, origin) => messageEvent(mailbox, 'MessageExpunge', ['MESSAGES', 'UIDNEXT'], origin));
|
|
313
|
-
|
|
314
|
-
server.on('notify', notification => {
|
|
284
|
+
server.on('notify', (notification) => {
|
|
315
285
|
const command = notification.command || {};
|
|
316
286
|
const mailbox = typeof notification.mailbox === 'string' ? server.getMailbox(notification.mailbox) : notification.mailbox;
|
|
317
|
-
|
|
318
287
|
if (mailbox && command.flagUpdate) {
|
|
319
288
|
messageEvent(mailbox, 'FlagChange', [], notification.origin);
|
|
320
|
-
}
|
|
289
|
+
}
|
|
290
|
+
else if (mailbox && command.message && isAtom(command.attributes && command.attributes[1], 'EXISTS')) {
|
|
321
291
|
messageEvent(mailbox, 'MessageNew', ['MESSAGES', 'UIDNEXT'], notification.origin);
|
|
322
|
-
}
|
|
292
|
+
}
|
|
293
|
+
else if (command.command === 'METADATA' && command.attributes && command.attributes[0]) {
|
|
323
294
|
// RFC 5465 sections 5.6 and 5.7: METADATA responses without ENABLE METADATA
|
|
324
295
|
const path = command.attributes[0].value;
|
|
325
296
|
const target = path === '' ? null : server.getMailbox(path);
|
|
@@ -327,7 +298,8 @@ module.exports = function (server) {
|
|
|
327
298
|
let wanted;
|
|
328
299
|
if (path === '') {
|
|
329
300
|
wanted = connection.notifyState.groups.some(group => group.events.has('ServerMetadataChange'));
|
|
330
|
-
}
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
331
303
|
wanted = !!target && canRead(connection, target) && getEvents(connection, path, target).has('MailboxMetadataChange');
|
|
332
304
|
}
|
|
333
305
|
if (wanted) {
|
|
@@ -338,12 +310,10 @@ module.exports = function (server) {
|
|
|
338
310
|
});
|
|
339
311
|
}
|
|
340
312
|
});
|
|
341
|
-
|
|
342
313
|
// a METADATA response that NOTIFY sent already does not go out again for ENABLE METADATA
|
|
343
314
|
server.notifyFilters.push((connection, notification) => !(notification.notifyHandled && notification.notifyHandled.has(connection)));
|
|
344
|
-
|
|
345
315
|
// Which message event a notification for the selected mailbox is
|
|
346
|
-
const selectedEvent = command => {
|
|
316
|
+
const selectedEvent = (command) => {
|
|
347
317
|
if (command.flagUpdate) {
|
|
348
318
|
return 'FlagChange';
|
|
349
319
|
}
|
|
@@ -357,14 +327,14 @@ module.exports = function (server) {
|
|
|
357
327
|
}
|
|
358
328
|
return false;
|
|
359
329
|
};
|
|
360
|
-
|
|
361
330
|
// Builds the FETCH response for a new message in the selected mailbox (RFC 5465 section 5.2)
|
|
362
331
|
const newMessageFetch = (connection, items, sequence, message) => {
|
|
363
332
|
const params = items.map(item => Object.assign({}, item));
|
|
364
333
|
let data;
|
|
365
334
|
try {
|
|
366
335
|
data = fetchResponse(connection, message, params);
|
|
367
|
-
}
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
368
338
|
// the items were checked by NOTIFY SET, a failure here leaves out the FETCH response
|
|
369
339
|
return false;
|
|
370
340
|
}
|
|
@@ -372,10 +342,8 @@ module.exports = function (server) {
|
|
|
372
342
|
// marks an EXPUNGE notification
|
|
373
343
|
return { tag: '*', notification: true, attributes: [sequence, { type: 'ATOM', value: 'FETCH' }, data], fetchedMessage: message };
|
|
374
344
|
};
|
|
375
|
-
|
|
376
|
-
server.connectionHandlers.push(connection => {
|
|
345
|
+
server.connectionHandlers.push((connection) => {
|
|
377
346
|
connection.notifyState = null;
|
|
378
|
-
|
|
379
347
|
const queueNotification = connection.queueNotification;
|
|
380
348
|
connection.queueNotification = function (command, notification) {
|
|
381
349
|
const event = notification && notification.mailbox && selectedEvent(command);
|
|
@@ -384,6 +352,7 @@ module.exports = function (server) {
|
|
|
384
352
|
return queueNotification.call(this, command, notification);
|
|
385
353
|
}
|
|
386
354
|
const selected = this.notifyState.selected;
|
|
355
|
+
// notifications about the selected mailbox
|
|
387
356
|
if (!selected || !selected.events.has(event) || !canRead(this, this.selectedMailbox)) {
|
|
388
357
|
// RFC 5465 section 3.1: without SELECTED or SELECTED-DELAYED (or without the event) the client
|
|
389
358
|
// does not want to hear about it
|
|
@@ -400,40 +369,36 @@ module.exports = function (server) {
|
|
|
400
369
|
scheduleFlush(this);
|
|
401
370
|
};
|
|
402
371
|
});
|
|
403
|
-
|
|
404
372
|
// RFC 8437 section 4.1: UNAUTHENTICATE forgets the NOTIFY settings
|
|
405
|
-
server.resetHandlers.push(connection => {
|
|
373
|
+
server.resetHandlers.push((connection) => {
|
|
406
374
|
connection.notifyState = null;
|
|
407
375
|
});
|
|
408
|
-
|
|
409
376
|
// notifications held back during a command (FETCH, STORE, SEARCH) go out once it completed
|
|
410
377
|
server.outputHandlers.push((connection, response) => {
|
|
411
378
|
if (response.tag !== '*' && !response.notification && isActive(connection) && connection.notificationQueue.length) {
|
|
412
379
|
scheduleFlush(connection);
|
|
413
380
|
}
|
|
414
381
|
});
|
|
415
|
-
|
|
416
382
|
/**
|
|
417
383
|
* RFC 5465 section 5.8: disables notifications for a session (or all sessions that use NOTIFY),
|
|
418
384
|
* which get an untagged OK [NOTIFICATIONOVERFLOW] and behave as after NOTIFY NONE
|
|
419
385
|
*
|
|
420
386
|
* @param {Object} [target] IMAP connection, all sessions if not set
|
|
421
387
|
*/
|
|
422
|
-
server.notifyOverflow = target => {
|
|
388
|
+
server.notifyOverflow = (target) => {
|
|
423
389
|
listeners(null)
|
|
424
390
|
.filter(connection => !target || connection === target)
|
|
425
391
|
.forEach(connection => {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
});
|
|
392
|
+
connection.notifyState = { selected: null, groups: [], unseen: new WeakMap() };
|
|
393
|
+
deliver(connection, {
|
|
394
|
+
command: 'OK',
|
|
395
|
+
attributes: [
|
|
396
|
+
{ type: 'SECTION', section: [{ type: 'ATOM', value: 'NOTIFICATIONOVERFLOW' }] },
|
|
397
|
+
{ type: 'TEXT', value: 'Too many notifications, NOTIFY is turned off' }
|
|
398
|
+
]
|
|
434
399
|
});
|
|
400
|
+
});
|
|
435
401
|
};
|
|
436
|
-
|
|
437
402
|
/**
|
|
438
403
|
* Parses the fetch attributes of MessageNew (RFC 5465 section 8: "(" fetch-att *(SP fetch-att) ")")
|
|
439
404
|
*
|
|
@@ -455,15 +420,16 @@ module.exports = function (server) {
|
|
|
455
420
|
// check the section and the partial range against a message
|
|
456
421
|
const params = [Object.assign({}, item)];
|
|
457
422
|
try {
|
|
423
|
+
// a dry run against a minimal message, the section items only look at its source
|
|
458
424
|
fetchResponse(connection, { raw: 'Subject: test\r\n\r\nTest\r\n', flags: [], uid: 1 }, params);
|
|
459
|
-
}
|
|
425
|
+
}
|
|
426
|
+
catch (err) {
|
|
460
427
|
throw badError(err.message);
|
|
461
428
|
}
|
|
462
429
|
}
|
|
463
430
|
return item;
|
|
464
431
|
});
|
|
465
432
|
};
|
|
466
|
-
|
|
467
433
|
/**
|
|
468
434
|
* Parses the events of an event group (RFC 5465 section 8: events = ( "(" event *(SP event) ")" ) / "NONE")
|
|
469
435
|
*
|
|
@@ -515,7 +481,6 @@ module.exports = function (server) {
|
|
|
515
481
|
}
|
|
516
482
|
return { events, fetch };
|
|
517
483
|
};
|
|
518
|
-
|
|
519
484
|
// one-or-more-mailbox = mailbox / many-mailboxes, the names are converted to storage names
|
|
520
485
|
const parseMailboxes = (connection, value) => {
|
|
521
486
|
const list = Array.isArray(value) ? value : [value];
|
|
@@ -524,7 +489,6 @@ module.exports = function (server) {
|
|
|
524
489
|
}
|
|
525
490
|
return list.map(item => normalizePath(connection.importMailboxName(item.value)));
|
|
526
491
|
};
|
|
527
|
-
|
|
528
492
|
/**
|
|
529
493
|
* Parses the arguments of NOTIFY (RFC 5465 section 8)
|
|
530
494
|
*
|
|
@@ -562,7 +526,8 @@ module.exports = function (server) {
|
|
|
562
526
|
throw badError('Only one of SELECTED and SELECTED-DELAYED can be used');
|
|
563
527
|
}
|
|
564
528
|
state.selected = Object.assign({ delayed: filter === 'SELECTED-DELAYED' }, parseEvents(connection, group[1], true, unknown));
|
|
565
|
-
}
|
|
529
|
+
}
|
|
530
|
+
else if (OTHER_FILTERS.indexOf(filter) >= 0) {
|
|
566
531
|
const withNames = filter === 'SUBTREE' || filter === 'MAILBOXES';
|
|
567
532
|
if (group.length !== (withNames ? 3 : 2)) {
|
|
568
533
|
throw badError('Invalid event group');
|
|
@@ -572,19 +537,19 @@ module.exports = function (server) {
|
|
|
572
537
|
// the names below a SUBTREE root start with these
|
|
573
538
|
const prefixes = filter === 'SUBTREE' ? paths.map(root => root + server.getSeparator(root)) : [];
|
|
574
539
|
state.groups.push({ filter, paths, prefixes, events });
|
|
575
|
-
}
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
576
542
|
throw badError('Unknown mailbox filter ' + group[0].value);
|
|
577
543
|
}
|
|
578
544
|
});
|
|
579
545
|
return { state, status, unknown };
|
|
580
546
|
};
|
|
581
|
-
|
|
582
547
|
// RFC 5465 section 3.1: the initial STATUS responses and the \NoAccess LIST responses of NOTIFY SET
|
|
583
548
|
const sendInitialResponses = (connection, status, parsed, data) => {
|
|
584
549
|
const paths = Object.keys(server.folderCache).sort((a, b) => (a === 'INBOX' ? -1 : b === 'INBOX' ? 1 : a.localeCompare(b)));
|
|
585
550
|
paths.forEach(path => {
|
|
586
551
|
const mailbox = server.folderCache[path];
|
|
587
|
-
if (mailbox === connection.selectedMailbox || mailbox.flags.some(flag => /^\\(Noselect|NonExistent)$/i.test(flag))) {
|
|
552
|
+
if (mailbox === connection.selectedMailbox || mailbox.flags.some((flag) => /^\\(Noselect|NonExistent)$/i.test(flag))) {
|
|
588
553
|
return;
|
|
589
554
|
}
|
|
590
555
|
const events = getEvents(connection, path, mailbox);
|
|
@@ -601,7 +566,8 @@ module.exports = function (server) {
|
|
|
601
566
|
const items = ['MESSAGES', 'UIDNEXT', 'UIDVALIDITY'];
|
|
602
567
|
if (events.has('FlagChange')) {
|
|
603
568
|
items.push('UNSEEN');
|
|
604
|
-
|
|
569
|
+
const mailboxStatus = server.getStatus(mailbox);
|
|
570
|
+
connection.notifyState.unseen.set(mailbox, (mailboxStatus && mailboxStatus.unseen) || 0);
|
|
605
571
|
if (server.condstore) {
|
|
606
572
|
items.push('HIGHESTMODSEQ');
|
|
607
573
|
}
|
|
@@ -609,46 +575,36 @@ module.exports = function (server) {
|
|
|
609
575
|
connection.send(statusResponse(connection, path, mailbox, items), 'NOTIFY STATUS', parsed, data);
|
|
610
576
|
});
|
|
611
577
|
};
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
]
|
|
637
|
-
},
|
|
638
|
-
'NOTIFY FAILED',
|
|
639
|
-
parsed,
|
|
640
|
-
data
|
|
641
|
-
);
|
|
642
|
-
return callback();
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
connection.notifyState = result.state;
|
|
646
|
-
sendInitialResponses(connection, result.status, parsed, data);
|
|
647
|
-
|
|
648
|
-
// the tagged response sends the changes of the selected mailbox, NOTIFY SET implies NOOP (section 3.1)
|
|
649
|
-
connection.sendStatus(parsed, data, 'OK', 'NOTIFY completed');
|
|
578
|
+
server.setCommandHandler('NOTIFY', (connection, parsed, data, callback) => {
|
|
579
|
+
let result;
|
|
580
|
+
try {
|
|
581
|
+
result = parseNotify(connection, parsed.attributes || []);
|
|
582
|
+
}
|
|
583
|
+
catch (err) {
|
|
584
|
+
connection.sendStatus(parsed, data, 'BAD', err.imapResponse === 'BAD' ? err.message : 'Invalid NOTIFY arguments');
|
|
585
|
+
return callback();
|
|
586
|
+
}
|
|
587
|
+
const supported = getSupportedEvents();
|
|
588
|
+
const used = [result.state.selected]
|
|
589
|
+
.concat(result.state.groups)
|
|
590
|
+
.filter((group) => !!group);
|
|
591
|
+
const unsupported = result.unknown.concat(...used.map(group => [...group.events].filter(event => supported.indexOf(event) < 0)));
|
|
592
|
+
if (unsupported.length) {
|
|
593
|
+
// RFC 5465 section 3.1: NO with BADEVENT, which MUST list all supported events
|
|
594
|
+
connection.send({
|
|
595
|
+
tag: parsed.tag,
|
|
596
|
+
command: 'NO',
|
|
597
|
+
attributes: [
|
|
598
|
+
{ type: 'SECTION', section: [{ type: 'ATOM', value: 'BADEVENT' }, supported.map(event => ({ type: 'ATOM', value: event }))] },
|
|
599
|
+
{ type: 'TEXT', value: 'Unsupported NOTIFY events' }
|
|
600
|
+
]
|
|
601
|
+
}, 'NOTIFY FAILED', parsed, data);
|
|
650
602
|
return callback();
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
603
|
+
}
|
|
604
|
+
connection.notifyState = result.state;
|
|
605
|
+
sendInitialResponses(connection, result.status, parsed, data);
|
|
606
|
+
// the tagged response sends the changes of the selected mailbox, NOTIFY SET implies NOOP (section 3.1)
|
|
607
|
+
connection.sendStatus(parsed, data, 'OK', 'NOTIFY completed');
|
|
608
|
+
return callback();
|
|
609
|
+
}, { states: states.AUTHENTICATED });
|
|
610
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { IMAPServer } from '../types.js';
|
|
2
|
+
/** A parsed OAUTHBEARER client response, see parseClientResponse() */
|
|
3
|
+
interface ClientResponse {
|
|
4
|
+
kvsepOnly?: boolean | undefined;
|
|
5
|
+
error?: string | undefined;
|
|
6
|
+
channelBinding?: boolean | undefined;
|
|
7
|
+
authzid?: string | false | undefined;
|
|
8
|
+
pairs?: Record<string, string> | undefined;
|
|
9
|
+
/** the user that the credentials log in, set by checkCredentials() */
|
|
10
|
+
username?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Parses an OAUTHBEARER client response (RFC 7628 section 3.1)
|
|
14
|
+
*
|
|
15
|
+
* client-resp = (gs2-header kvsep *kvpair kvsep) / kvsep
|
|
16
|
+
* kvpair = key "=" value kvsep
|
|
17
|
+
* key = 1*(ALPHA)
|
|
18
|
+
* value = *(VCHAR / SP / HTAB / CR / LF)
|
|
19
|
+
*
|
|
20
|
+
* and its GS2 header (RFC 5801 section 4)
|
|
21
|
+
*
|
|
22
|
+
* gs2-header = [gs2-nonstd-flag ","] gs2-cb-flag "," [gs2-authzid] ","
|
|
23
|
+
* gs2-cb-flag = ("p=" cb-name) / "n" / "y"
|
|
24
|
+
* gs2-authzid = "a=" saslname
|
|
25
|
+
*
|
|
26
|
+
* @param {Buffer} input Decoded client response
|
|
27
|
+
* @return {Object} `{ kvsepOnly }`, `{ error }` when the response breaks the grammar, or
|
|
28
|
+
* `{ channelBinding, authzid, pairs }` where pairs maps keys to values
|
|
29
|
+
*/
|
|
30
|
+
declare function parseClientResponse(input: Buffer): ClientResponse;
|
|
31
|
+
export default function oauthbearerPlugin(server: IMAPServer): void;
|
|
32
|
+
export { parseClientResponse };
|