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
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @help Adds CONDSTORE [RFC7162] capability
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = condstorePlugin;
|
|
7
|
+
const fetch_js_1 = require("../commands/fetch.js");
|
|
8
|
+
const search_js_1 = require("../commands/handlers/search.js");
|
|
9
|
+
const flags_js_1 = require("../commands/handlers/flags.js");
|
|
10
|
+
const numbers_js_1 = require("../numbers.js");
|
|
11
|
+
const enable_js_1 = require("./enable.js");
|
|
12
|
+
function condstorePlugin(server) {
|
|
13
|
+
// Register capability, always usable
|
|
14
|
+
server.registerCapability('CONDSTORE');
|
|
15
|
+
(0, enable_js_1.registerEnable)(server, 'CONDSTORE');
|
|
16
|
+
// HIGHESTMODSEQ must be a positive number, even for an empty mailbox
|
|
17
|
+
const getHighestModseq = (mailbox) => Math.max(Number(mailbox.HIGHESTMODSEQ) || 0, 1);
|
|
18
|
+
const bumpModseq = (mailbox) => {
|
|
19
|
+
mailbox.HIGHESTMODSEQ = getHighestModseq(mailbox) + 1;
|
|
20
|
+
return mailbox.HIGHESTMODSEQ;
|
|
21
|
+
};
|
|
22
|
+
// RFC 8437 section 4.1: after UNAUTHENTICATE the session behaves as if no CONDSTORE enabling command was issued
|
|
23
|
+
server.resetHandlers.push((connection) => {
|
|
24
|
+
connection.condstoreEnabled = false;
|
|
25
|
+
});
|
|
26
|
+
// ENABLE QRESYNC is a CONDSTORE enabling command as well (RFC 7162 section 3.2.3)
|
|
27
|
+
const isEnabled = (connection) => !!connection.condstoreEnabled || (0, enable_js_1.isEnabled)(connection, 'CONDSTORE') || (0, enable_js_1.isEnabled)(connection, 'QRESYNC');
|
|
28
|
+
// shared with QRESYNC, which builds on CONDSTORE
|
|
29
|
+
server.condstore = { isEnabled, getHighestModseq };
|
|
30
|
+
const sendHighestModseq = (connection, mailbox, parsed, data) => {
|
|
31
|
+
connection.send({
|
|
32
|
+
tag: '*',
|
|
33
|
+
command: 'OK',
|
|
34
|
+
attributes: [
|
|
35
|
+
{
|
|
36
|
+
type: 'SECTION',
|
|
37
|
+
section: [
|
|
38
|
+
{
|
|
39
|
+
type: 'ATOM',
|
|
40
|
+
value: 'HIGHESTMODSEQ'
|
|
41
|
+
},
|
|
42
|
+
getHighestModseq(mailbox)
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'TEXT',
|
|
47
|
+
value: 'Highest'
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}, 'CONDSTORE INFO', parsed, data);
|
|
51
|
+
};
|
|
52
|
+
// Marks the session as CONDSTORE aware. The first CONDSTORE enabling command
|
|
53
|
+
// issued with a mailbox selected reports HIGHESTMODSEQ for that mailbox
|
|
54
|
+
const enableCondstore = (connection, parsed, data) => {
|
|
55
|
+
if (isEnabled(connection)) {
|
|
56
|
+
connection.condstoreEnabled = true;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
connection.condstoreEnabled = true;
|
|
60
|
+
if (connection.state === 'Selected' && connection.selectedMailbox) {
|
|
61
|
+
sendHighestModseq(connection, connection.selectedMailbox, parsed, data);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
// Set modseq values when a message is created or initialized
|
|
65
|
+
server.messageHandlers.push((server, message, mailbox) => {
|
|
66
|
+
const modseq = Number(message.MODSEQ);
|
|
67
|
+
if (modseq > 0 && Number.isSafeInteger(modseq)) {
|
|
68
|
+
// keep the value from storage
|
|
69
|
+
message.MODSEQ = modseq;
|
|
70
|
+
mailbox.HIGHESTMODSEQ = Math.max(getHighestModseq(mailbox), modseq);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
message.MODSEQ = bumpModseq(mailbox);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
// Expunging messages (EXPUNGE, UID EXPUNGE, CLOSE, MOVE) changes the mailbox, all messages removed
|
|
77
|
+
// at once share the incremented mod-sequence (RFC 7162 section 3.2)
|
|
78
|
+
server.on('expunge', mailbox => {
|
|
79
|
+
bumpModseq(mailbox);
|
|
80
|
+
});
|
|
81
|
+
// RFC 7162 section 3.2.11: SELECT or EXAMINE closes the selected mailbox, a CONDSTORE server marks
|
|
82
|
+
// where the responses for the new mailbox start
|
|
83
|
+
server.closedChecks.push(() => true);
|
|
84
|
+
server.allowedStatus.push('HIGHESTMODSEQ');
|
|
85
|
+
server.statusHandlers.HIGHESTMODSEQ = (connection, mailbox) => getHighestModseq(mailbox);
|
|
86
|
+
// Wraps an existing command handler. Commands that are not available are left alone
|
|
87
|
+
const wrapHandler = (command, wrapper) => {
|
|
88
|
+
const prevHandler = server.getCommandHandler(command);
|
|
89
|
+
if (!prevHandler) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
server.setCommandHandler(command, (connection, parsed, data, callback) => wrapper(prevHandler, connection, parsed, data, callback));
|
|
93
|
+
};
|
|
94
|
+
const sendBad = (connection, parsed, data, callback, message) => {
|
|
95
|
+
connection.sendStatus(parsed, data, 'BAD', message, false, 'CONDSTORE FAILED');
|
|
96
|
+
return callback();
|
|
97
|
+
};
|
|
98
|
+
// RFC 7162 section 7: chgsince-fetch-mod = "CHANGEDSINCE" SP mod-sequence-value (1 or more), store-modifier =/
|
|
99
|
+
// "UNCHANGEDSINCE" SP mod-sequence-valzer (0 or more). Both are 1*DIGIT, so not a quoted string, up to 63 bits
|
|
100
|
+
const isValidModseq = (value, allowZero) => !!value && value.type === 'ATOM' && (0, numbers_js_1.isNumber)(value.value, numbers_js_1.MAX_NUMBER64) && (allowZero || BigInt(value.value) > 0n);
|
|
101
|
+
const selectWrapper = (prevHandler, connection, parsed, data, callback) => {
|
|
102
|
+
if (hasCondstoreOption(parsed.attributes && parsed.attributes[1], parsed.attributes, 1)) {
|
|
103
|
+
// SELECT and EXAMINE always report HIGHESTMODSEQ, so no need to send it here
|
|
104
|
+
connection.condstoreEnabled = true;
|
|
105
|
+
parsed.condstoreOption = true;
|
|
106
|
+
}
|
|
107
|
+
prevHandler(connection, parsed, data, callback);
|
|
108
|
+
};
|
|
109
|
+
wrapHandler('SELECT', selectWrapper);
|
|
110
|
+
wrapHandler('EXAMINE', selectWrapper);
|
|
111
|
+
wrapHandler('STATUS', (prevHandler, connection, parsed, data, callback) => {
|
|
112
|
+
const items = parsed.attributes && parsed.attributes[1];
|
|
113
|
+
if (Array.isArray(items) && items.some(item => item && item.type === 'ATOM' && String(item.value).toUpperCase() === 'HIGHESTMODSEQ')) {
|
|
114
|
+
enableCondstore(connection, parsed, data);
|
|
115
|
+
}
|
|
116
|
+
prevHandler(connection, parsed, data, callback);
|
|
117
|
+
});
|
|
118
|
+
const fetchWrapper = (prevHandler, connection, parsed, data, callback) => {
|
|
119
|
+
// RFC 4466 2.4: fetch-modifiers are the last argument, a single fetch-att may take arguments of its own
|
|
120
|
+
const attributes = parsed.attributes || [];
|
|
121
|
+
const index = Math.max(attributes.length - 1, 2);
|
|
122
|
+
const changedsince = getCondstoreValue(attributes[index], 'CHANGEDSINCE', attributes, index);
|
|
123
|
+
if (changedsince) {
|
|
124
|
+
if (!isValidModseq(changedsince)) {
|
|
125
|
+
return sendBad(connection, parsed, data, callback, 'Invalid syntax for CHANGEDSINCE, number expected');
|
|
126
|
+
}
|
|
127
|
+
parsed.changedsince = Number(changedsince.value);
|
|
128
|
+
// CHANGEDSINCE implicitly adds the MODSEQ data item
|
|
129
|
+
addModseqItem(parsed);
|
|
130
|
+
}
|
|
131
|
+
if (changedsince || hasModseqItem(parsed)) {
|
|
132
|
+
enableCondstore(connection, parsed, data);
|
|
133
|
+
}
|
|
134
|
+
prevHandler(connection, parsed, data, callback);
|
|
135
|
+
};
|
|
136
|
+
wrapHandler('FETCH', fetchWrapper);
|
|
137
|
+
wrapHandler('UID FETCH', fetchWrapper);
|
|
138
|
+
const storeWrapper = (prevHandler, connection, parsed, data, callback) => {
|
|
139
|
+
const unchangedsince = getCondstoreValue(parsed.attributes && parsed.attributes[1], 'UNCHANGEDSINCE', parsed.attributes, 1);
|
|
140
|
+
if (unchangedsince) {
|
|
141
|
+
if (!isValidModseq(unchangedsince, true)) {
|
|
142
|
+
return sendBad(connection, parsed, data, callback, 'Invalid syntax for UNCHANGEDSINCE, number expected');
|
|
143
|
+
}
|
|
144
|
+
parsed.unchangedsince = Number(unchangedsince.value);
|
|
145
|
+
enableCondstore(connection, parsed, data);
|
|
146
|
+
}
|
|
147
|
+
// Per command state for tracking changed messages
|
|
148
|
+
parsed.condstoreStore = {
|
|
149
|
+
isUid: (parsed.command || '').toUpperCase() === 'UID STORE',
|
|
150
|
+
messages: new Map(),
|
|
151
|
+
modified: [],
|
|
152
|
+
done: false
|
|
153
|
+
};
|
|
154
|
+
prevHandler(connection, parsed, data, callback);
|
|
155
|
+
};
|
|
156
|
+
wrapHandler('STORE', storeWrapper);
|
|
157
|
+
wrapHandler('UID STORE', storeWrapper);
|
|
158
|
+
// RFC 7162 section 3.1.5: MODSEQ [<entry-name> <entry-type-req>] <mod-sequence-valzer>. Mod-sequences
|
|
159
|
+
// are not stored per flag, so the entry name and type are checked but otherwise ignored
|
|
160
|
+
const searchModseq = (connection, message, index, ...args) => message.MODSEQ >= args[args.length - 1];
|
|
161
|
+
searchModseq.argumentTypes = (list) => typeof list[0] === 'string' && /^\d+$/.test(list[0]) ? [parseModseqValzer] : [parseEntryName, parseEntryType, parseModseqValzer];
|
|
162
|
+
server.searchHandlers.MODSEQ = searchModseq;
|
|
163
|
+
// highest mod-sequence of a list of messages
|
|
164
|
+
const highestModseq = (messages) => messages.reduce((highest, message) => Math.max(highest, message.MODSEQ), 0);
|
|
165
|
+
server.fetchHandlers.MODSEQ = function (connection, message) {
|
|
166
|
+
return [message.MODSEQ]; // Must be a list
|
|
167
|
+
};
|
|
168
|
+
server.fetchFilters.push((connection, message, parsed, index) => {
|
|
169
|
+
if ('changedsince' in parsed && !(parsed.changedsince < message.MODSEQ)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
// remember \Seen state, FETCH might set it implicitly
|
|
173
|
+
if (!parsed.condstoreFetch) {
|
|
174
|
+
parsed.condstoreFetch = new Map();
|
|
175
|
+
}
|
|
176
|
+
parsed.condstoreFetch.set(index, {
|
|
177
|
+
message,
|
|
178
|
+
seen: message.flags.indexOf('\\Seen') >= 0
|
|
179
|
+
});
|
|
180
|
+
return true;
|
|
181
|
+
});
|
|
182
|
+
server.storeFilters.push((connection, message, parsed, index) => {
|
|
183
|
+
const state = parsed.condstoreStore;
|
|
184
|
+
if (!state) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
if ('unchangedsince' in parsed && message.MODSEQ > parsed.unchangedsince) {
|
|
188
|
+
// failed the UNCHANGEDSINCE test, reported with the MODIFIED response code
|
|
189
|
+
state.modified.push(state.isUid ? message.uid : index);
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
state.messages.set(message, {
|
|
193
|
+
index,
|
|
194
|
+
before: snapshot(message),
|
|
195
|
+
bumped: false,
|
|
196
|
+
reported: false
|
|
197
|
+
});
|
|
198
|
+
return true;
|
|
199
|
+
});
|
|
200
|
+
// Bumps MODSEQ if the message metadata was changed by the current STORE
|
|
201
|
+
const checkStored = (connection, message, entry) => {
|
|
202
|
+
if (!entry.bumped && snapshot(message) !== entry.before) {
|
|
203
|
+
entry.bumped = true;
|
|
204
|
+
// STORE runs in the Selected state
|
|
205
|
+
message.MODSEQ = bumpModseq(connection.selectedMailbox);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
server.outputHandlers.push((connection, response, description, parsed, data, extra) => {
|
|
209
|
+
// Flag changes made by another session (RFC 7162 section 3.1), these are not responses to a command
|
|
210
|
+
if (description === 'FLAG NOTIFICATION' && response && extra && isEnabled(connection)) {
|
|
211
|
+
setModseqValue(response.attributes[2], extra.MODSEQ);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (!parsed || !response) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// Untagged FETCH responses caused by STORE
|
|
218
|
+
if (description === 'FLAG UPDATE' && parsed.condstoreStore && extra && parsed.condstoreStore.messages.has(extra)) {
|
|
219
|
+
const entry = parsed.condstoreStore.messages.get(extra);
|
|
220
|
+
checkStored(connection, extra, entry);
|
|
221
|
+
entry.reported = true;
|
|
222
|
+
if (isEnabled(connection)) {
|
|
223
|
+
setModseqValue(response.attributes[2], extra.MODSEQ);
|
|
224
|
+
setUidValue(response.attributes[2], extra.uid);
|
|
225
|
+
}
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// SEARCH, ESEARCH, SORT or THREAD with the MODSEQ search key, a CONDSTORE enabling command (RFC 7162 section 3.1).
|
|
229
|
+
// `extra.list` holds the messages the response is about
|
|
230
|
+
const isSearch = ['SEARCH', 'SORT', 'THREAD'].includes(response.command) &&
|
|
231
|
+
[response.command, 'UID ' + response.command].includes(description);
|
|
232
|
+
if ((isSearch || description === 'ESEARCH') && response.tag === '*' && extra && extra.keys && extra.keys.has('MODSEQ')) {
|
|
233
|
+
enableCondstore(connection, parsed, data);
|
|
234
|
+
// RFC 7162 section 3.1.9: THREAD responses are unchanged
|
|
235
|
+
if (extra.list.length && response.command !== 'THREAD') {
|
|
236
|
+
const modseq = [{ type: 'ATOM', value: 'MODSEQ' }, highestModseq(extra.list)];
|
|
237
|
+
// RFC 7162 sections 3.1.6 and 3.1.9 append "(MODSEQ n)" to SEARCH and SORT, RFC 4731 section 3.2 (and RFC 7162 section 3.1.10)
|
|
238
|
+
// adds "MODSEQ n" to ESEARCH
|
|
239
|
+
response.attributes.push(...(isSearch ? [modseq] : modseq));
|
|
240
|
+
}
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// Untagged FETCH responses of FETCH, check for implicitly set \Seen
|
|
244
|
+
if (response.tag === '*' &&
|
|
245
|
+
parsed.condstoreFetch &&
|
|
246
|
+
response.attributes &&
|
|
247
|
+
response.attributes[1] &&
|
|
248
|
+
response.attributes[1].value === 'FETCH' &&
|
|
249
|
+
parsed.condstoreFetch.has(response.attributes[0])) {
|
|
250
|
+
const entry = parsed.condstoreFetch.get(response.attributes[0]);
|
|
251
|
+
const message = entry.message;
|
|
252
|
+
let changed = false;
|
|
253
|
+
if (!entry.seen && message.flags.indexOf('\\Seen') >= 0 && connection.selectedMailbox) {
|
|
254
|
+
entry.seen = true;
|
|
255
|
+
message.MODSEQ = bumpModseq(connection.selectedMailbox);
|
|
256
|
+
changed = true;
|
|
257
|
+
}
|
|
258
|
+
const list = response.attributes[2];
|
|
259
|
+
if (Array.isArray(list) && (findItem(list, 'MODSEQ') >= 0 || (changed && isEnabled(connection)))) {
|
|
260
|
+
setModseqValue(list, message.MODSEQ);
|
|
261
|
+
}
|
|
262
|
+
// RFC 7162 section 3.1: a FETCH that implicitly set \Seen includes UID and MODSEQ
|
|
263
|
+
if (Array.isArray(list) && changed && isEnabled(connection)) {
|
|
264
|
+
setUidValue(list, message.uid);
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
// Tagged response of STORE
|
|
269
|
+
if (response.tag === parsed.tag && parsed.condstoreStore && !parsed.condstoreStore.done) {
|
|
270
|
+
const state = parsed.condstoreStore;
|
|
271
|
+
state.done = true;
|
|
272
|
+
state.messages.forEach((entry, message) => {
|
|
273
|
+
checkStored(connection, message, entry);
|
|
274
|
+
// .SILENT stores send no FETCH responses, CONDSTORE aware clients still need the new MODSEQ values
|
|
275
|
+
if (!entry.reported && isEnabled(connection) && (entry.bumped || 'unchangedsince' in parsed)) {
|
|
276
|
+
const attributes = [
|
|
277
|
+
{
|
|
278
|
+
type: 'ATOM',
|
|
279
|
+
value: 'MODSEQ'
|
|
280
|
+
},
|
|
281
|
+
[message.MODSEQ]
|
|
282
|
+
];
|
|
283
|
+
// RFC 7162 section 3.1: UID and MODSEQ in every untagged FETCH caused by STORE
|
|
284
|
+
attributes.unshift({ type: 'ATOM', value: 'UID' }, message.uid);
|
|
285
|
+
connection.send({
|
|
286
|
+
tag: '*',
|
|
287
|
+
attributes: [
|
|
288
|
+
entry.index,
|
|
289
|
+
{
|
|
290
|
+
type: 'ATOM',
|
|
291
|
+
value: 'FETCH'
|
|
292
|
+
},
|
|
293
|
+
attributes
|
|
294
|
+
]
|
|
295
|
+
}, 'CONDSTORE MODSEQ UPDATE', parsed, data, message);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
// RFC 7162 section 3.1.3 example 11: MODIFIED can also go with the tagged NO of a STORE on expunged messages
|
|
299
|
+
// (RFC 2180 section 4.2.3), it replaces EXPUNGEISSUED there since a response has only one response code
|
|
300
|
+
if ((response.command === 'OK' || response.command === 'NO') && state.modified.length) {
|
|
301
|
+
response.attributes = [
|
|
302
|
+
{
|
|
303
|
+
type: 'SECTION',
|
|
304
|
+
section: [
|
|
305
|
+
{
|
|
306
|
+
type: 'ATOM',
|
|
307
|
+
value: 'MODIFIED'
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
type: 'SEQUENCE',
|
|
311
|
+
value: state.modified.sort((a, b) => a - b).join(',')
|
|
312
|
+
}
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
].concat((response.attributes || []).filter((attr) => response.command === 'OK' || !attr || attr.type !== 'SECTION'));
|
|
316
|
+
}
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (description === 'ENABLED' && Array.isArray(extra) && extra.indexOf('CONDSTORE') >= 0) {
|
|
320
|
+
// ENABLE CONDSTORE was issued
|
|
321
|
+
if (!connection.condstoreEnabled) {
|
|
322
|
+
connection.condstoreEnabled = true;
|
|
323
|
+
if (connection.state === 'Selected' && connection.selectedMailbox) {
|
|
324
|
+
parsed.condstoreReportHighest = true;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (description === 'ENABLE' && parsed.condstoreReportHighest && connection.selectedMailbox) {
|
|
330
|
+
parsed.condstoreReportHighest = false;
|
|
331
|
+
sendHighestModseq(connection, connection.selectedMailbox, parsed, data);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
// Add CONDSTORE info to SELECT and EXAMINE
|
|
335
|
+
if ((description === 'EXAMINE' || description === 'SELECT') && response.tag === parsed.tag && connection.selectedMailbox) {
|
|
336
|
+
// (CONDSTORE) option was used, show notice
|
|
337
|
+
if (parsed.condstoreOption) {
|
|
338
|
+
const last = response.attributes && response.attributes.slice(-1)[0];
|
|
339
|
+
if (!last || last.type !== 'TEXT') {
|
|
340
|
+
response.attributes = (response.attributes || []).concat({
|
|
341
|
+
type: 'TEXT',
|
|
342
|
+
value: 'CONDSTORE is now enabled'
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
last.value += ', CONDSTORE is now enabled';
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// Send untagged info about highest modseq
|
|
350
|
+
sendHighestModseq(connection, connection.selectedMailbox, parsed, data);
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
// RFC 7162 section 7: mod-sequence-valzer = "0" / mod-sequence-value. Dovecot also accepts values above 63 bits
|
|
355
|
+
function parseModseqValzer(value) {
|
|
356
|
+
if (!(0, numbers_js_1.isNumber)(value, numbers_js_1.MAX_NUMBER64)) {
|
|
357
|
+
throw (0, search_js_1.badError)('MODSEQ expects a mod-sequence value');
|
|
358
|
+
}
|
|
359
|
+
return Number(value);
|
|
360
|
+
}
|
|
361
|
+
// RFC 7162 section 7: entry-flag-name = DQUOTE "/flags/" attr-flag DQUOTE, attr-flag is a flag without "\Recent"
|
|
362
|
+
function parseEntryName(value) {
|
|
363
|
+
const match = value.match(/^\/flags\/(\\?)(.+)$/i);
|
|
364
|
+
if (!match || flags_js_1.INVALID_KEYWORD_CHAR.test(match[2]) || (match[1] && match[2].toUpperCase() === 'RECENT')) {
|
|
365
|
+
throw (0, search_js_1.badError)('MODSEQ expects an entry name like "/flags/\\\\seen"');
|
|
366
|
+
}
|
|
367
|
+
return value;
|
|
368
|
+
}
|
|
369
|
+
// RFC 7162 section 7: entry-type-req = "priv" / "shared" / "all"
|
|
370
|
+
function parseEntryType(value) {
|
|
371
|
+
if (!['PRIV', 'SHARED', 'ALL'].includes(value.toUpperCase())) {
|
|
372
|
+
throw (0, search_js_1.badError)('MODSEQ expects entry type priv, shared or all');
|
|
373
|
+
}
|
|
374
|
+
return value;
|
|
375
|
+
}
|
|
376
|
+
// Serialized message metadata, used to detect changes
|
|
377
|
+
function snapshot(message) {
|
|
378
|
+
return JSON.stringify([message.flags || [], message['X-GM-LABELS'] || []]);
|
|
379
|
+
}
|
|
380
|
+
function findItem(list, name) {
|
|
381
|
+
if (!Array.isArray(list)) {
|
|
382
|
+
return -1;
|
|
383
|
+
}
|
|
384
|
+
for (let i = 0; i < list.length; i += 2) {
|
|
385
|
+
if (list[i] && list[i].type === 'ATOM' && String(list[i].value).toUpperCase() === name) {
|
|
386
|
+
return i;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return -1;
|
|
390
|
+
}
|
|
391
|
+
// Sets or adds the MODSEQ value in a FETCH response attribute list
|
|
392
|
+
function setModseqValue(list, modseq) {
|
|
393
|
+
if (!Array.isArray(list)) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const pos = findItem(list, 'MODSEQ');
|
|
397
|
+
if (pos >= 0) {
|
|
398
|
+
list[pos + 1] = [modseq];
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
list.push({
|
|
402
|
+
type: 'ATOM',
|
|
403
|
+
value: 'MODSEQ'
|
|
404
|
+
}, [modseq]);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// Adds the UID to a FETCH response attribute list unless it is there already
|
|
408
|
+
function setUidValue(list, uid) {
|
|
409
|
+
if (Array.isArray(list) && findItem(list, 'UID') < 0) {
|
|
410
|
+
list.push({
|
|
411
|
+
type: 'ATOM',
|
|
412
|
+
value: 'UID'
|
|
413
|
+
}, uid);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
function isModseqAtom(item) {
|
|
417
|
+
return !!item && item.type === 'ATOM' && String(item.value).toUpperCase() === 'MODSEQ';
|
|
418
|
+
}
|
|
419
|
+
function hasModseqItem(parsed) {
|
|
420
|
+
const items = parsed.attributes && parsed.attributes[1];
|
|
421
|
+
return Array.isArray(items) ? items.some(isModseqAtom) : isModseqAtom(items);
|
|
422
|
+
}
|
|
423
|
+
// Adds MODSEQ to the list of FETCH data items, unless it is already there
|
|
424
|
+
function addModseqItem(parsed) {
|
|
425
|
+
if (!parsed.attributes || !parsed.attributes[1] || hasModseqItem(parsed)) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
let items = parsed.attributes[1];
|
|
429
|
+
if (!Array.isArray(items)) {
|
|
430
|
+
const name = String(items.value).toUpperCase();
|
|
431
|
+
const macro = items.type === 'ATOM' && Object.hasOwn(fetch_js_1.macros, name) && fetch_js_1.macros[name];
|
|
432
|
+
// a single fetch-att keeps the arguments that follow it, eg. RFC 8970 PREVIEW (LAZY)
|
|
433
|
+
items = macro ? macro.map((value) => ({ type: 'ATOM', value })) : [items].concat(parsed.attributes.splice(2));
|
|
434
|
+
}
|
|
435
|
+
parsed.attributes[1] = items.concat({
|
|
436
|
+
type: 'ATOM',
|
|
437
|
+
value: 'MODSEQ'
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
function hasCondstoreOption(attributes, parent, index) {
|
|
441
|
+
if (!attributes) {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
let condstoreOption = false;
|
|
445
|
+
if (Array.isArray(attributes)) {
|
|
446
|
+
for (let i = attributes.length - 1; i >= 0; i--) {
|
|
447
|
+
if (attributes[i] && attributes[i].type === 'ATOM' && attributes[i].value.toUpperCase() === 'CONDSTORE') {
|
|
448
|
+
attributes.splice(i, 1);
|
|
449
|
+
condstoreOption = true;
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// remove parameter if no other memebers were left
|
|
454
|
+
if (!attributes.length) {
|
|
455
|
+
parent.splice(index, 1);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return !!condstoreOption;
|
|
459
|
+
}
|
|
460
|
+
function getCondstoreValue(attributes, name, parent, index) {
|
|
461
|
+
if (!attributes) {
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
let condstoreValue = false;
|
|
465
|
+
if (Array.isArray(attributes)) {
|
|
466
|
+
for (let i = 0; i < attributes.length; i += 2) {
|
|
467
|
+
if (attributes[i] && attributes[i].type === 'ATOM' && attributes[i].value.toUpperCase() === name.toUpperCase()) {
|
|
468
|
+
// a missing value is reported as a syntax error
|
|
469
|
+
condstoreValue = attributes[i + 1] || { type: 'NIL' };
|
|
470
|
+
attributes.splice(i, 2);
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
// remove parameter if no other memebers were left
|
|
475
|
+
if (!attributes.length) {
|
|
476
|
+
parent.splice(index, 1);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return condstoreValue;
|
|
480
|
+
}
|
|
481
|
+
{
|
|
482
|
+
const defaultExport = exports.default;
|
|
483
|
+
if (defaultExport && (typeof defaultExport === 'function' || typeof defaultExport === 'object')) {
|
|
484
|
+
for (const key of Object.keys(exports)) {
|
|
485
|
+
if (key !== 'default' && !(key in defaultExport)) {
|
|
486
|
+
defaultExport[key] = exports[key];
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
Object.defineProperty(defaultExport, 'default', { value: defaultExport, enumerable: false, writable: true, configurable: true });
|
|
490
|
+
module.exports = defaultExport;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @help Adds CONTEXT=SEARCH [RFC5267] capability, loads ESEARCH as well
|
|
3
|
+
* @help SEARCH RETURN (UPDATE) sends ADDTO and REMOVEFROM updates as the result changes, until CANCELUPDATE or the mailbox is closed
|
|
4
|
+
* @help SEARCH RETURN (PARTIAL 1:100) returns a window of the results, the CONTEXT hint is accepted and ignored
|
|
5
|
+
* @help Server option "maxSearchContexts" (default 10) limits the updating contexts of a session, above it NOUPDATE is sent
|
|
6
|
+
*/
|
|
7
|
+
import type { IMAPServer } from '../types.js';
|
|
8
|
+
export default function contextSearchPlugin(server: IMAPServer): void;
|