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,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const { MAX_NUMBER64, isNumber } = require('../numbers');
|
|
6
|
-
const { isAstring } = require('../arguments');
|
|
7
|
-
|
|
1
|
+
import { states } from '../command-states.js';
|
|
2
|
+
import { normalizeLineBreaks } from '../mimeparser.js';
|
|
3
|
+
import { MAX_NUMBER64, isNumber } from '../numbers.js';
|
|
4
|
+
import { isAstring } from '../arguments.js';
|
|
8
5
|
// Resource types of RFC 9208 section 5 that can be counted. ANNOTATION-STORAGE is left out,
|
|
9
6
|
// as there is no ANNOTATE support
|
|
10
7
|
const RESOURCES = ['STORAGE', 'MESSAGE', 'MAILBOX'];
|
|
11
8
|
const DEFAULT_ROOT = 'User quota';
|
|
12
|
-
|
|
13
9
|
/**
|
|
14
10
|
* @help Adds QUOTA [RFC9208] capability with the STORAGE, MESSAGE and MAILBOX
|
|
15
11
|
* @help resources and SETQUOTA. All personal mailboxes share one quota root, set
|
|
@@ -26,14 +22,13 @@ const DEFAULT_ROOT = 'User quota';
|
|
|
26
22
|
* Additional STATUS items:
|
|
27
23
|
* - DELETED, DELETED-STORAGE
|
|
28
24
|
*/
|
|
29
|
-
|
|
25
|
+
export default function quotaPlugin(server) {
|
|
30
26
|
const config = server.options.quota || {};
|
|
31
27
|
const root = {
|
|
32
28
|
name: typeof config.root === 'string' ? config.root : DEFAULT_ROOT,
|
|
33
29
|
soft: !!config.soft,
|
|
34
30
|
limits: {}
|
|
35
31
|
};
|
|
36
|
-
|
|
37
32
|
RESOURCES.forEach(resource => {
|
|
38
33
|
if (config[resource] === undefined || config[resource] === null) {
|
|
39
34
|
return;
|
|
@@ -44,21 +39,16 @@ module.exports = function (server) {
|
|
|
44
39
|
}
|
|
45
40
|
root.limits[resource] = limit;
|
|
46
41
|
});
|
|
47
|
-
|
|
48
42
|
// RFC 9208 sections 3.1.1 and 5: every supported resource is advertised, SETQUOTA needs QUOTASET
|
|
49
43
|
server.registerCapability('QUOTA');
|
|
50
44
|
RESOURCES.forEach(resource => server.registerCapability('QUOTA=RES-' + resource));
|
|
51
45
|
server.registerCapability('QUOTASET');
|
|
52
|
-
|
|
53
46
|
// Personal mailboxes, INBOX included, belong to the quota root. Other namespaces have no quota root. A mailbox
|
|
54
47
|
// that does not exist yet belongs to the namespace of its prefix
|
|
55
|
-
const inRoot = path => server.isPersonal(path);
|
|
56
|
-
|
|
57
|
-
const isSelectable = mailbox => mailbox.flags.indexOf('\\Noselect') < 0;
|
|
58
|
-
|
|
48
|
+
const inRoot = (path) => server.isPersonal(path);
|
|
49
|
+
const isSelectable = (mailbox) => mailbox.flags.indexOf('\\Noselect') < 0;
|
|
59
50
|
// RFC822.SIZE, the message with CRLF line breaks
|
|
60
|
-
const totalSize = messages => messages.reduce((total, message) => total + normalizeLineBreaks(message.raw).length, 0);
|
|
61
|
-
|
|
51
|
+
const totalSize = (messages) => messages.reduce((total, message) => total + normalizeLineBreaks(message.raw).length, 0);
|
|
62
52
|
const getUsage = () => {
|
|
63
53
|
const usage = { MESSAGE: 0, MAILBOX: 0, bytes: 0 };
|
|
64
54
|
Object.keys(server.folderCache).forEach(path => {
|
|
@@ -72,7 +62,6 @@ module.exports = function (server) {
|
|
|
72
62
|
});
|
|
73
63
|
return usage;
|
|
74
64
|
};
|
|
75
|
-
|
|
76
65
|
// RFC 9208 section 4.2.1: quota-list, resources that are not listed are not limited
|
|
77
66
|
const sendQuota = (connection, parsed, data) => {
|
|
78
67
|
const usage = getUsage();
|
|
@@ -84,32 +73,25 @@ module.exports = function (server) {
|
|
|
84
73
|
list.push({ type: 'ATOM', value: resource }, usage[resource], root.limits[resource]);
|
|
85
74
|
}
|
|
86
75
|
});
|
|
87
|
-
connection.send(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
},
|
|
93
|
-
'QUOTA',
|
|
94
|
-
parsed,
|
|
95
|
-
data
|
|
96
|
-
);
|
|
76
|
+
connection.send({
|
|
77
|
+
tag: '*',
|
|
78
|
+
command: 'QUOTA',
|
|
79
|
+
attributes: [{ type: 'STRING', value: root.name }, list]
|
|
80
|
+
}, 'QUOTA', parsed, data);
|
|
97
81
|
};
|
|
98
|
-
|
|
99
82
|
/**
|
|
100
83
|
* Checks if adding to the quota root goes over a limit
|
|
101
84
|
*
|
|
102
85
|
* @param {Object} added Added amounts, `{ MESSAGE, MAILBOX, bytes }`
|
|
103
86
|
* @return {Object|undefined} `{ code, text, soft }` for IMAPConnection#checkAppend, or nothing if within limits
|
|
104
87
|
*/
|
|
105
|
-
const checkLimits = added => {
|
|
88
|
+
const checkLimits = (added) => {
|
|
106
89
|
const limited = (added.MESSAGE && 'MESSAGE' in root.limits) || (added.bytes && 'STORAGE' in root.limits) || (added.MAILBOX && 'MAILBOX' in root.limits);
|
|
107
90
|
if (!limited) {
|
|
108
91
|
return;
|
|
109
92
|
}
|
|
110
93
|
const usage = getUsage();
|
|
111
|
-
const over =
|
|
112
|
-
(added.MESSAGE && 'MESSAGE' in root.limits && usage.MESSAGE + added.MESSAGE > root.limits.MESSAGE) ||
|
|
94
|
+
const over = (added.MESSAGE && 'MESSAGE' in root.limits && usage.MESSAGE + added.MESSAGE > root.limits.MESSAGE) ||
|
|
113
95
|
(added.bytes && 'STORAGE' in root.limits && usage.bytes + added.bytes > root.limits.STORAGE * 1024) ||
|
|
114
96
|
(added.MAILBOX && 'MAILBOX' in root.limits && usage.MAILBOX + added.MAILBOX > root.limits.MAILBOX);
|
|
115
97
|
if (!over) {
|
|
@@ -118,7 +100,6 @@ module.exports = function (server) {
|
|
|
118
100
|
// RFC 9208 section 4.3.1 and RFC 5530 section 3
|
|
119
101
|
return root.soft ? { code: 'OVERQUOTA', text: 'Soft quota has been exceeded', soft: true } : { code: 'OVERQUOTA', text: 'Quota exceeded' };
|
|
120
102
|
};
|
|
121
|
-
|
|
122
103
|
// APPEND, COPY, MOVE and REPLACE
|
|
123
104
|
server.appendChecks.push((connection, mailbox, messages, options) => {
|
|
124
105
|
if (!messages.length || !inRoot(mailbox)) {
|
|
@@ -136,9 +117,8 @@ module.exports = function (server) {
|
|
|
136
117
|
}
|
|
137
118
|
return checkLimits(added);
|
|
138
119
|
});
|
|
139
|
-
|
|
140
120
|
// Number of mailboxes that CREATE adds, missing parent mailboxes are created as well
|
|
141
|
-
const countNewMailboxes = path => {
|
|
121
|
+
const countNewMailboxes = (path) => {
|
|
142
122
|
const target = server.getMailbox(server.stripSeparator(path, server.getSeparator(path)));
|
|
143
123
|
let count = !target || !isSelectable(target) ? 1 : 0;
|
|
144
124
|
for (let parent = server.getParentPath(path); parent; parent = server.getParentPath(parent)) {
|
|
@@ -148,132 +128,106 @@ module.exports = function (server) {
|
|
|
148
128
|
}
|
|
149
129
|
return count;
|
|
150
130
|
};
|
|
151
|
-
|
|
152
131
|
// The MAILBOX resource limits CREATE and RENAME INBOX (which creates a mailbox)
|
|
153
132
|
const wrapCreate = (command, getPath) => {
|
|
133
|
+
// CREATE and RENAME are core commands, so the handler exists
|
|
154
134
|
const prevHandler = server.getCommandHandler(command);
|
|
155
135
|
server.setCommandHandler(command, (connection, parsed, data, callback) => {
|
|
156
136
|
const path = getPath(parsed.attributes);
|
|
157
|
-
if (
|
|
158
|
-
typeof path === 'string' &&
|
|
137
|
+
if (typeof path === 'string' &&
|
|
159
138
|
path.toUpperCase() !== 'INBOX' &&
|
|
160
139
|
inRoot(path) &&
|
|
161
|
-
!connection.applyChecks([checkLimits({ MAILBOX: countNewMailboxes(path) })], parsed, data, command + ' FAILED')
|
|
162
|
-
) {
|
|
140
|
+
!connection.applyChecks([checkLimits({ MAILBOX: countNewMailboxes(path) })], parsed, data, command + ' FAILED')) {
|
|
163
141
|
return callback();
|
|
164
142
|
}
|
|
165
143
|
prevHandler(connection, parsed, data, callback);
|
|
166
144
|
});
|
|
167
145
|
};
|
|
168
|
-
|
|
169
146
|
const argValue = (attributes, i) => isAstring((attributes || [])[i]) && attributes[i].value;
|
|
170
|
-
|
|
171
|
-
wrapCreate('
|
|
172
|
-
wrapCreate('RENAME', attributes => {
|
|
147
|
+
wrapCreate('CREATE', (attributes) => (attributes && attributes.length === 1 ? argValue(attributes, 0) : false));
|
|
148
|
+
wrapCreate('RENAME', (attributes) => {
|
|
173
149
|
const source = argValue(attributes, 0);
|
|
174
150
|
// only RENAME INBOX adds a mailbox, other renames keep the count (RFC 3501 section 6.3.5)
|
|
175
151
|
return attributes && attributes.length === 2 && typeof source === 'string' && source.toUpperCase() === 'INBOX' ? argValue(attributes, 1) : false;
|
|
176
152
|
});
|
|
177
|
-
|
|
178
153
|
// RFC 9208 section 4.1.1: GETQUOTA quota-root-name
|
|
179
|
-
server.setCommandHandler(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (!parsed.attributes || parsed.attributes.length !== 1 || !isAstring(parsed.attributes[0])) {
|
|
183
|
-
connection.sendStatus(parsed, data, 'BAD', 'GETQUOTA expects a quota root name');
|
|
184
|
-
return callback();
|
|
185
|
-
}
|
|
186
|
-
if (parsed.attributes[0].value !== root.name) {
|
|
187
|
-
connection.sendStatus(parsed, data, 'NO', 'Quota root does not exist', 'NONEXISTENT');
|
|
188
|
-
return callback();
|
|
189
|
-
}
|
|
190
|
-
sendQuota(connection, parsed, data);
|
|
191
|
-
connection.sendStatus(parsed, data, 'OK', 'GETQUOTA completed');
|
|
154
|
+
server.setCommandHandler('GETQUOTA', (connection, parsed, data, callback) => {
|
|
155
|
+
if (!parsed.attributes || parsed.attributes.length !== 1 || !isAstring(parsed.attributes[0])) {
|
|
156
|
+
connection.sendStatus(parsed, data, 'BAD', 'GETQUOTA expects a quota root name');
|
|
192
157
|
return callback();
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
158
|
+
}
|
|
159
|
+
if (parsed.attributes[0].value !== root.name) {
|
|
160
|
+
connection.sendStatus(parsed, data, 'NO', 'Quota root does not exist', 'NONEXISTENT');
|
|
161
|
+
return callback();
|
|
162
|
+
}
|
|
163
|
+
sendQuota(connection, parsed, data);
|
|
164
|
+
connection.sendStatus(parsed, data, 'OK', 'GETQUOTA completed');
|
|
165
|
+
return callback();
|
|
166
|
+
},
|
|
167
|
+
// quota-root = astring (RFC 9208 section 9)
|
|
168
|
+
{ states: states.AUTHENTICATED, astringArguments: [0] });
|
|
198
169
|
// RFC 9208 section 4.1.2: GETQUOTAROOT mailbox, the mailbox does not have to exist
|
|
199
|
-
server.setCommandHandler(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (!parsed.attributes || parsed.attributes.length !== 1 || !isAstring(parsed.attributes[0])) {
|
|
203
|
-
connection.sendStatus(parsed, data, 'BAD', 'GETQUOTAROOT expects a mailbox name');
|
|
204
|
-
return callback();
|
|
205
|
-
}
|
|
206
|
-
let path = parsed.attributes[0].value;
|
|
207
|
-
if (path.toUpperCase() === 'INBOX') {
|
|
208
|
-
path = 'INBOX';
|
|
209
|
-
}
|
|
210
|
-
const hasRoot = inRoot(path);
|
|
211
|
-
connection.send(
|
|
212
|
-
{
|
|
213
|
-
tag: '*',
|
|
214
|
-
command: 'QUOTAROOT',
|
|
215
|
-
attributes: [{ type: 'MAILBOX', value: path }].concat(hasRoot ? { type: 'STRING', value: root.name } : [])
|
|
216
|
-
},
|
|
217
|
-
'QUOTAROOT',
|
|
218
|
-
parsed,
|
|
219
|
-
data
|
|
220
|
-
);
|
|
221
|
-
if (hasRoot) {
|
|
222
|
-
sendQuota(connection, parsed, data);
|
|
223
|
-
}
|
|
224
|
-
connection.sendStatus(parsed, data, 'OK', 'GETQUOTAROOT completed');
|
|
170
|
+
server.setCommandHandler('GETQUOTAROOT', (connection, parsed, data, callback) => {
|
|
171
|
+
if (!parsed.attributes || parsed.attributes.length !== 1 || !isAstring(parsed.attributes[0])) {
|
|
172
|
+
connection.sendStatus(parsed, data, 'BAD', 'GETQUOTAROOT expects a mailbox name');
|
|
225
173
|
return callback();
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
174
|
+
}
|
|
175
|
+
let path = parsed.attributes[0].value;
|
|
176
|
+
if (path.toUpperCase() === 'INBOX') {
|
|
177
|
+
path = 'INBOX';
|
|
178
|
+
}
|
|
179
|
+
const hasRoot = inRoot(path);
|
|
180
|
+
connection.send({
|
|
181
|
+
tag: '*',
|
|
182
|
+
command: 'QUOTAROOT',
|
|
183
|
+
attributes: [{ type: 'MAILBOX', value: path }].concat(hasRoot ? { type: 'STRING', value: root.name } : [])
|
|
184
|
+
}, 'QUOTAROOT', parsed, data);
|
|
185
|
+
if (hasRoot) {
|
|
186
|
+
sendQuota(connection, parsed, data);
|
|
187
|
+
}
|
|
188
|
+
connection.sendStatus(parsed, data, 'OK', 'GETQUOTAROOT completed');
|
|
189
|
+
return callback();
|
|
190
|
+
}, { states: states.AUTHENTICATED, mailboxArguments: [0] });
|
|
230
191
|
// RFC 9208 section 4.1.3: SETQUOTA quota-root-name setquota-list, the new limits replace all earlier ones
|
|
231
|
-
server.setCommandHandler(
|
|
232
|
-
|
|
233
|
-
(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
192
|
+
server.setCommandHandler('SETQUOTA', (connection, parsed, data, callback) => {
|
|
193
|
+
const list = parsed.attributes && parsed.attributes[1];
|
|
194
|
+
if (!parsed.attributes || parsed.attributes.length !== 2 || !isAstring(parsed.attributes[0]) || !Array.isArray(list) || list.length % 2) {
|
|
195
|
+
connection.sendStatus(parsed, data, 'BAD', 'SETQUOTA expects a quota root name and a list of resource limits');
|
|
196
|
+
return callback();
|
|
197
|
+
}
|
|
198
|
+
const limits = {};
|
|
199
|
+
for (let i = 0; i < list.length; i += 2) {
|
|
200
|
+
const name = list[i];
|
|
201
|
+
const limit = list[i + 1];
|
|
202
|
+
// setquota-resource = resource-name SP resource-limit, resource-limit = number64
|
|
203
|
+
if (!name || name.type !== 'ATOM' || !limit || limit.type !== 'ATOM' || !isNumber(limit.value, MAX_NUMBER64)) {
|
|
204
|
+
connection.sendStatus(parsed, data, 'BAD', 'Invalid resource limit');
|
|
237
205
|
return callback();
|
|
238
206
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const limit = list[i + 1];
|
|
244
|
-
// setquota-resource = resource-name SP resource-limit, resource-limit = number64
|
|
245
|
-
if (!name || name.type !== 'ATOM' || !limit || limit.type !== 'ATOM' || !isNumber(limit.value, MAX_NUMBER64)) {
|
|
246
|
-
connection.sendStatus(parsed, data, 'BAD', 'Invalid resource limit');
|
|
247
|
-
return callback();
|
|
248
|
-
}
|
|
249
|
-
const resource = name.value.toUpperCase();
|
|
250
|
-
if (RESOURCES.indexOf(resource) < 0 || resource in limits) {
|
|
251
|
-
connection.sendStatus(parsed, data, 'NO', 'Can not set a limit for ' + resource, 'CANNOT');
|
|
252
|
-
return callback();
|
|
253
|
-
}
|
|
254
|
-
const value = Number(limit.value);
|
|
255
|
-
if (!Number.isSafeInteger(value)) {
|
|
256
|
-
connection.sendStatus(parsed, data, 'NO', 'Limit is too large for ' + resource, 'LIMIT');
|
|
257
|
-
return callback();
|
|
258
|
-
}
|
|
259
|
-
limits[resource] = value;
|
|
207
|
+
const resource = name.value.toUpperCase();
|
|
208
|
+
if (RESOURCES.indexOf(resource) < 0 || resource in limits) {
|
|
209
|
+
connection.sendStatus(parsed, data, 'NO', 'Can not set a limit for ' + resource, 'CANNOT');
|
|
210
|
+
return callback();
|
|
260
211
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
connection.sendStatus(parsed, data, 'NO', 'Quota root does not exist', 'NONEXISTENT');
|
|
212
|
+
const value = Number(limit.value);
|
|
213
|
+
if (!Number.isSafeInteger(value)) {
|
|
214
|
+
connection.sendStatus(parsed, data, 'NO', 'Limit is too large for ' + resource, 'LIMIT');
|
|
265
215
|
return callback();
|
|
266
216
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
217
|
+
limits[resource] = value;
|
|
218
|
+
}
|
|
219
|
+
// new quota roots can not be created
|
|
220
|
+
if (parsed.attributes[0].value !== root.name) {
|
|
221
|
+
connection.sendStatus(parsed, data, 'NO', 'Quota root does not exist', 'NONEXISTENT');
|
|
271
222
|
return callback();
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
223
|
+
}
|
|
224
|
+
root.limits = limits;
|
|
225
|
+
sendQuota(connection, parsed, data);
|
|
226
|
+
connection.sendStatus(parsed, data, 'OK', 'SETQUOTA completed');
|
|
227
|
+
return callback();
|
|
228
|
+
},
|
|
229
|
+
// quota-root = astring (RFC 9208 section 9)
|
|
230
|
+
{ states: states.AUTHENTICATED, astringArguments: [0] });
|
|
277
231
|
// RFC 9208 section 4.1.4: DELETED (the built-in item, required with QUOTA=RES-MESSAGE) and DELETED-STORAGE
|
|
278
232
|
// (required with QUOTA=RES-STORAGE), the storage EXPUNGE would free as the sum of RFC822.SIZE
|
|
279
233
|
['DELETED', 'DELETED-STORAGE'].forEach(item => {
|
|
@@ -282,4 +236,4 @@ module.exports = function (server) {
|
|
|
282
236
|
}
|
|
283
237
|
});
|
|
284
238
|
server.statusHandlers['DELETED-STORAGE'] = (connection, mailbox) => totalSize(mailbox.messages.filter(message => message.flags.indexOf('\\Deleted') >= 0));
|
|
285
|
-
}
|
|
239
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IMAPServer } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @help Adds REPLACE [RFC8508] capability (REPLACE and UID REPLACE commands)
|
|
4
|
+
*
|
|
5
|
+
* REPLACE: https://www.rfc-editor.org/rfc/rfc8508
|
|
6
|
+
*
|
|
7
|
+
* Additional commands:
|
|
8
|
+
* - REPLACE
|
|
9
|
+
* - UID REPLACE
|
|
10
|
+
*
|
|
11
|
+
* The new message is appended and the old one expunged as a single action. With UIDPLUS the
|
|
12
|
+
* APPENDUID response code is sent in an untagged OK before the EXPUNGE. Works with CATENATE.
|
|
13
|
+
*/
|
|
14
|
+
export default function replacePlugin(server: IMAPServer): void;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const { states } = require('../command-states');
|
|
5
|
-
const { isNzNumber } = require('../numbers');
|
|
6
|
-
|
|
1
|
+
import { prepareAppend, storeMessages } from '../commands/append.js';
|
|
2
|
+
import { states } from '../command-states.js';
|
|
3
|
+
import { isNzNumber } from '../numbers.js';
|
|
7
4
|
// RFC 8508 section 5 and RFC 3501 section 9: seq-number = nz-number / "*"
|
|
8
|
-
const isSeqNumber = value => value === '*' || isNzNumber(value);
|
|
9
|
-
|
|
5
|
+
const isSeqNumber = (value) => value === '*' || isNzNumber(value);
|
|
10
6
|
/**
|
|
11
7
|
* @help Adds REPLACE [RFC8508] capability (REPLACE and UID REPLACE commands)
|
|
12
8
|
*
|
|
@@ -19,72 +15,50 @@ const isSeqNumber = value => value === '*' || isNzNumber(value);
|
|
|
19
15
|
* The new message is appended and the old one expunged as a single action. With UIDPLUS the
|
|
20
16
|
* APPENDUID response code is sent in an untagged OK before the EXPUNGE. Works with CATENATE.
|
|
21
17
|
*/
|
|
22
|
-
|
|
18
|
+
export default function replacePlugin(server) {
|
|
23
19
|
server.registerCapability('REPLACE');
|
|
24
|
-
|
|
25
20
|
const replaceHandler = function (uidMode, connection, parsed, data, callback) {
|
|
26
21
|
const command = uidMode ? 'UID REPLACE' : 'REPLACE';
|
|
27
22
|
const args = [].concat(parsed.attributes || []);
|
|
28
23
|
const id = args.shift();
|
|
29
24
|
const pathArg = args.shift();
|
|
30
|
-
|
|
31
25
|
// RFC 8508 section 5: replace = "REPLACE" SP seq-number SP mailbox append-message
|
|
32
26
|
if (!id || ['ATOM', 'SEQUENCE'].indexOf(id.type) < 0 || !isSeqNumber(String(id.value))) {
|
|
33
27
|
connection.sendStatus(parsed, data, 'BAD', command + ' expects a message number, a mailbox name and a message', false, 'INVALID COMMAND');
|
|
34
28
|
return callback();
|
|
35
29
|
}
|
|
36
|
-
|
|
37
30
|
const found = findMessage(connection, uidMode, id.value);
|
|
38
31
|
if (found.error) {
|
|
39
|
-
connection.sendStatus(
|
|
40
|
-
parsed,
|
|
41
|
-
data,
|
|
42
|
-
found.error.command,
|
|
43
|
-
found.error.text,
|
|
44
|
-
found.error.code || false,
|
|
45
|
-
found.error.command === 'BAD' ? 'INVALID COMMAND' : command + ' FAILED'
|
|
46
|
-
);
|
|
32
|
+
connection.sendStatus(parsed, data, found.error.command, found.error.text, found.error.code || false, found.error.command === 'BAD' ? 'INVALID COMMAND' : command + ' FAILED');
|
|
47
33
|
return callback();
|
|
48
34
|
}
|
|
49
35
|
const message = found.message;
|
|
50
|
-
|
|
51
36
|
// RFC 8508 section 4.7: REPLACE takes a single message even with MULTIAPPEND. Nothing is
|
|
52
37
|
// changed if the new message can not be appended (section 3.4)
|
|
53
38
|
const prepared = prepareAppend(connection, parsed, data, pathArg, args, { command, maxMessages: 1, replaced: message });
|
|
54
39
|
if (!prepared) {
|
|
55
40
|
return callback();
|
|
56
41
|
}
|
|
57
|
-
|
|
58
42
|
const result = storeMessages(connection, prepared);
|
|
59
|
-
|
|
60
43
|
// Hook for UIDPLUS to send APPENDUID in an untagged OK before the EXPUNGE
|
|
61
44
|
// (RFC 8508 section 4.3). If UIDPLUS is not loaded, this is not sent
|
|
62
|
-
connection.send(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
'REPLACE APPENDUID',
|
|
75
|
-
parsed,
|
|
76
|
-
data,
|
|
77
|
-
result
|
|
78
|
-
);
|
|
79
|
-
|
|
45
|
+
connection.send({
|
|
46
|
+
tag: '*',
|
|
47
|
+
command: 'OK',
|
|
48
|
+
attributes: [
|
|
49
|
+
{
|
|
50
|
+
type: 'TEXT',
|
|
51
|
+
value: 'Replacement message saved'
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
skipResponse: true
|
|
55
|
+
}, 'REPLACE APPENDUID', parsed, data, result);
|
|
80
56
|
// only the replaced message is expunged, not every \Deleted message (RFC 8508 section 3.4).
|
|
81
57
|
// When the new message went to the selected mailbox, it was already announced with EXISTS
|
|
82
58
|
connection.expungeSpecificMessages(connection.selectedMailbox, [message], false, true);
|
|
83
|
-
|
|
84
59
|
connection.sendStatus(parsed, data, 'OK', command + ' completed', false, command);
|
|
85
60
|
callback();
|
|
86
61
|
};
|
|
87
|
-
|
|
88
62
|
// Refuse the literal of the new message when the message to replace is already known to be
|
|
89
63
|
// invalid, unless earlier commands are still running and could change the selected mailbox
|
|
90
64
|
server.literalFilters.push((connection, command, line) => {
|
|
@@ -94,7 +68,6 @@ module.exports = function (server) {
|
|
|
94
68
|
const match = line.match(/^\S+ (?:UID )?REPLACE ([^ ]+) /i);
|
|
95
69
|
return (match && isSeqNumber(match[1]) && findMessage(connection, command === 'UID REPLACE', match[1]).error) || false;
|
|
96
70
|
});
|
|
97
|
-
|
|
98
71
|
// RFC 8508 section 3.5: valid only in the selected state, the second argument is the target mailbox
|
|
99
72
|
// the message can be a literal8 with BINARY: RFC 8508 section 6 uses append-message, whose append-data
|
|
100
73
|
// is a literal8 too (RFC 4466 section 2.7)
|
|
@@ -102,8 +75,7 @@ module.exports = function (server) {
|
|
|
102
75
|
const options = { states: states.SELECTED, mailboxArguments: [1], literal8: 'BINARY', appendMessage: true };
|
|
103
76
|
server.setCommandHandler('REPLACE', replaceHandler.bind(null, false), Object.assign({ sequenceSet: 0 }, options));
|
|
104
77
|
server.setCommandHandler('UID REPLACE', replaceHandler.bind(null, true), options);
|
|
105
|
-
}
|
|
106
|
-
|
|
78
|
+
}
|
|
107
79
|
/**
|
|
108
80
|
* Finds the message to replace in the selected mailbox
|
|
109
81
|
*
|
|
@@ -119,8 +91,9 @@ function findMessage(connection, uidMode, value) {
|
|
|
119
91
|
if (uidMode) {
|
|
120
92
|
// "*" is the UID of the last message (RFC 3501 section 9, seq-number)
|
|
121
93
|
const uid = value === '*' ? (messages.length ? messages[messages.length - 1].uid : 0) : Number(value);
|
|
122
|
-
message = messages.find(item => item.uid === uid);
|
|
123
|
-
}
|
|
94
|
+
message = messages.find((item) => item.uid === uid);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
124
97
|
const seq = value === '*' ? messages.length : Number(value);
|
|
125
98
|
// RFC 3501 section 9, seq-number: a sequence number greater than the number of messages
|
|
126
99
|
// (or "*" in an empty mailbox) gets a tagged BAD
|
|
@@ -129,17 +102,14 @@ function findMessage(connection, uidMode, value) {
|
|
|
129
102
|
}
|
|
130
103
|
message = messages[seq - 1];
|
|
131
104
|
}
|
|
132
|
-
|
|
133
105
|
// RFC 8508 section 3.2: NO - can't remove specified message
|
|
134
106
|
if (!message || message.ghost) {
|
|
135
107
|
return { error: { command: 'NO', text: 'No such message' } };
|
|
136
108
|
}
|
|
137
|
-
|
|
138
109
|
// the old message is expunged, which is not allowed after EXAMINE
|
|
139
110
|
const readOnly = connection.readOnlyRefusal();
|
|
140
111
|
if (readOnly) {
|
|
141
112
|
return { error: readOnly };
|
|
142
113
|
}
|
|
143
|
-
|
|
144
114
|
return { message };
|
|
145
115
|
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @help Enables SASL-IR [RFC4959] capability
|
|
5
3
|
*/
|
|
6
|
-
|
|
7
|
-
module.exports = function (server) {
|
|
4
|
+
export default function saslIrPlugin(server) {
|
|
8
5
|
// Register capability, usable for non authenticated users
|
|
9
|
-
server.registerCapability('SASL-IR', connection => {
|
|
6
|
+
server.registerCapability('SASL-IR', (connection) => {
|
|
10
7
|
return connection.state === 'Not Authenticated';
|
|
11
8
|
});
|
|
12
|
-
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IMAPServer } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @help Adds SAVEDATE [RFC8514] capability
|
|
4
|
+
* @help Every message gets a save date when it is added to a mailbox (APPEND,
|
|
5
|
+
* @help COPY, MOVE, and when the storage is loaded), messages in storage can
|
|
6
|
+
* @help set it with a "SAVEDATE" value. A mailbox with "SAVEDATE": false in
|
|
7
|
+
* @help storage does not support save dates, FETCH returns NIL for its messages
|
|
8
|
+
*
|
|
9
|
+
* SAVEDATE: https://www.rfc-editor.org/rfc/rfc8514.txt
|
|
10
|
+
*
|
|
11
|
+
* Additional FETCH items:
|
|
12
|
+
* - SAVEDATE
|
|
13
|
+
*
|
|
14
|
+
* Additional SEARCH keys:
|
|
15
|
+
* - SAVEDBEFORE, SAVEDON, SAVEDSINCE, SAVEDATESUPPORTED
|
|
16
|
+
*/
|
|
17
|
+
export default function savedatePlugin(server: IMAPServer): void;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { getDateKey } = require('../commands/handlers/search');
|
|
4
|
-
|
|
1
|
+
import { getDateKey } from '../commands/handlers/search.js';
|
|
5
2
|
/**
|
|
6
3
|
* @help Adds SAVEDATE [RFC8514] capability
|
|
7
4
|
* @help Every message gets a save date when it is added to a mailbox (APPEND,
|
|
@@ -17,12 +14,10 @@ const { getDateKey } = require('../commands/handlers/search');
|
|
|
17
14
|
* Additional SEARCH keys:
|
|
18
15
|
* - SAVEDBEFORE, SAVEDON, SAVEDSINCE, SAVEDATESUPPORTED
|
|
19
16
|
*/
|
|
20
|
-
|
|
17
|
+
export default function savedatePlugin(server) {
|
|
21
18
|
server.registerCapability('SAVEDATE');
|
|
22
|
-
|
|
23
19
|
// RFC 8514 section 3: storage may lack save dates for some mailboxes
|
|
24
|
-
const isSupported = mailbox => !!mailbox && mailbox.SAVEDATE !== false;
|
|
25
|
-
|
|
20
|
+
const isSupported = (mailbox) => !!mailbox && mailbox.SAVEDATE !== false;
|
|
26
21
|
// RFC 8514 section 3: the save date is the current time when the message is saved in a mailbox, it is
|
|
27
22
|
// never copied from the source message. Messages from storage may bring their own value.
|
|
28
23
|
server.messageHandlers.push((server, message, mailbox) => {
|
|
@@ -30,17 +25,14 @@ module.exports = function (server) {
|
|
|
30
25
|
delete message.SAVEDATE;
|
|
31
26
|
return;
|
|
32
27
|
}
|
|
33
|
-
|
|
34
28
|
const savedate = server.normalizeDateTime(message.SAVEDATE || new Date());
|
|
35
29
|
if (!server.validateInternalDate(savedate)) {
|
|
36
30
|
throw new Error('Invalid SAVEDATE value ' + JSON.stringify(savedate) + ' in mailbox ' + mailbox.path);
|
|
37
31
|
}
|
|
38
32
|
message.SAVEDATE = savedate;
|
|
39
33
|
});
|
|
40
|
-
|
|
41
34
|
// RFC 8514 section 4.2: date-time, or NIL if the mailbox does not support save dates
|
|
42
35
|
server.fetchHandlers.SAVEDATE = (connection, message) => message.SAVEDATE || null;
|
|
43
|
-
|
|
44
36
|
const dateKey = (name, compare) => {
|
|
45
37
|
const handler = (connection, message, index, date) => {
|
|
46
38
|
// RFC 8514 section 4.3: without save dates the internal date is used instead
|
|
@@ -50,10 +42,8 @@ module.exports = function (server) {
|
|
|
50
42
|
handler.argumentTypes = () => ['date'];
|
|
51
43
|
server.searchHandlers[name] = handler;
|
|
52
44
|
};
|
|
53
|
-
|
|
54
45
|
dateKey('SAVEDBEFORE', (saved, date) => saved < date);
|
|
55
46
|
dateKey('SAVEDON', (saved, date) => saved === date);
|
|
56
47
|
dateKey('SAVEDSINCE', (saved, date) => saved >= date);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
};
|
|
48
|
+
server.searchHandlers.SAVEDATESUPPORTED = (connection) => isSupported(connection.selectedMailbox);
|
|
49
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IMAPServer } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* @help Adds SAVELIMIT [RFC9738] capability, advertised as SAVELIMIT=<n>
|
|
4
|
+
* @help Server option "messageLimit" sets n (default 1000). COPY and APPEND (MULTIAPPEND)
|
|
5
|
+
* @help of more messages fail with NO [MESSAGELIMIT ...], other commands are not limited.
|
|
6
|
+
* @help Can not be loaded with MESSAGELIMIT
|
|
7
|
+
*
|
|
8
|
+
* SAVELIMIT: https://www.rfc-editor.org/rfc/rfc9738
|
|
9
|
+
*/
|
|
10
|
+
export default function savelimitPlugin(server: IMAPServer): void;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { getLimit, addSaveLimit } = require('./messagelimit');
|
|
4
|
-
|
|
1
|
+
import { getLimit, addSaveLimit } from './messagelimit.js';
|
|
5
2
|
/**
|
|
6
3
|
* @help Adds SAVELIMIT [RFC9738] capability, advertised as SAVELIMIT=<n>
|
|
7
4
|
* @help Server option "messageLimit" sets n (default 1000). COPY and APPEND (MULTIAPPEND)
|
|
@@ -10,9 +7,9 @@ const { getLimit, addSaveLimit } = require('./messagelimit');
|
|
|
10
7
|
*
|
|
11
8
|
* SAVELIMIT: https://www.rfc-editor.org/rfc/rfc9738
|
|
12
9
|
*/
|
|
13
|
-
|
|
10
|
+
export default function savelimitPlugin(server) {
|
|
14
11
|
// RFC 9738 section 3: a server that only limits COPY and APPEND (and their UID variants) advertises SAVELIMIT
|
|
15
12
|
const limit = getLimit(server, 'SAVELIMIT');
|
|
16
13
|
server.registerCapability('SAVELIMIT=' + limit);
|
|
17
14
|
addSaveLimit(server, limit);
|
|
18
|
-
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @help Adds SEARCHRES [RFC5182] capability, loads ESEARCH as well
|
|
3
|
+
* @help SEARCH RETURN (SAVE) stores the result, "$" refers to it in place of a sequence set
|
|
4
|
+
*/
|
|
5
|
+
import type { IMAPServer } from '../types.js';
|
|
6
|
+
export default function searchresPlugin(server: IMAPServer): void;
|