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,20 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const { MONTHS, isRealDate } = require('../dates');
|
|
5
|
-
|
|
6
|
-
const { badError } = search;
|
|
7
|
-
|
|
1
|
+
import search from '../commands/handlers/search.js';
|
|
2
|
+
import { badError } from '../commands/handlers/search.js';
|
|
3
|
+
import { MONTHS, isRealDate } from '../dates.js';
|
|
8
4
|
// X-GM-MSGID is a 64 bit unsigned number, so it is tracked as a BigInt
|
|
9
|
-
|
|
10
5
|
// Sample value from Gmail IMAP extensions API page
|
|
11
6
|
// https://developers.google.com/workspace/gmail/imap/imap-extensions
|
|
12
7
|
// Used as default, if server.options["HIGHESTX-GM-MSGID"]
|
|
13
8
|
// is missing
|
|
14
9
|
const SEED = '1278455344230334865';
|
|
15
|
-
|
|
16
10
|
const MAX_UINT64 = 2n ** 64n - 1n;
|
|
17
|
-
|
|
18
11
|
// X-GM-RAW mailbox shortcuts of in: and is: (Gmail search operators), as ImapKit criteria
|
|
19
12
|
const RAW_SHORTCUTS = {
|
|
20
13
|
'in:inbox': ['X-GM-LABELS', '\\Inbox'],
|
|
@@ -28,7 +21,6 @@ const RAW_SHORTCUTS = {
|
|
|
28
21
|
'is:starred': ['FLAGGED'],
|
|
29
22
|
'is:important': ['X-GM-LABELS', '\\Important']
|
|
30
23
|
};
|
|
31
|
-
|
|
32
24
|
// X-GM-RAW operators that take a value, as the search key the value is given to
|
|
33
25
|
const RAW_OPERATORS = {
|
|
34
26
|
from: 'FROM',
|
|
@@ -43,10 +35,8 @@ const RAW_OPERATORS = {
|
|
|
43
35
|
before: 'BEFORE',
|
|
44
36
|
rfc822msgid: 'HEADER'
|
|
45
37
|
};
|
|
46
|
-
|
|
47
38
|
// Gmail operators that ImapKit does not implement, answered with NO instead of a wrong result
|
|
48
39
|
const RAW_UNSUPPORTED = ['is', 'has', 'list', 'filename', 'around', 'size', 'older', 'newer', 'older_than', 'newer_than', 'deliveredto', 'category'];
|
|
49
|
-
|
|
50
40
|
/**
|
|
51
41
|
* @help Adds Gmail specific X-GM-EXT-1 capability
|
|
52
42
|
* @help (https://developers.google.com/workspace/gmail/imap/imap-extensions)
|
|
@@ -71,40 +61,35 @@ const RAW_UNSUPPORTED = ['is', 'has', 'list', 'filename', 'around', 'size', 'old
|
|
|
71
61
|
* @help (YYYY/MM/DD) and rfc822msgid:. Other Gmail operators are
|
|
72
62
|
* @help answered with NO
|
|
73
63
|
*/
|
|
74
|
-
|
|
75
|
-
module.exports = function (server) {
|
|
64
|
+
export default function xGmExt1Plugin(server) {
|
|
76
65
|
server.registerCapability('X-GM-EXT-1');
|
|
77
|
-
|
|
78
66
|
server['HIGHESTX-GM-MSGID'] = BigInt(server.options['HIGHESTX-GM-MSGID'] || SEED);
|
|
79
|
-
|
|
80
67
|
// set X-GM-MSGID values when message is created / initialized
|
|
81
|
-
server.messageHandlers.push((
|
|
68
|
+
server.messageHandlers.push((server, message, mailbox) => {
|
|
82
69
|
let labels;
|
|
83
|
-
|
|
84
70
|
if (!message['X-GM-MSGID']) {
|
|
85
71
|
server['HIGHESTX-GM-MSGID'] += 1n;
|
|
86
72
|
message['X-GM-MSGID'] = server['HIGHESTX-GM-MSGID'].toString();
|
|
87
|
-
}
|
|
73
|
+
}
|
|
74
|
+
else if (/^\d+$/.test(message['X-GM-MSGID']) && BigInt(message['X-GM-MSGID']) > server['HIGHESTX-GM-MSGID']) {
|
|
88
75
|
// Storage might be shared with another server instance, do not reuse existing values
|
|
89
76
|
server['HIGHESTX-GM-MSGID'] = BigInt(message['X-GM-MSGID']);
|
|
90
77
|
}
|
|
91
|
-
|
|
92
78
|
// Ensure message has an array of labels
|
|
93
79
|
message['X-GM-LABELS'] = [].concat(message['X-GM-LABELS'] || []);
|
|
94
|
-
|
|
95
80
|
if (mailbox.path.toUpperCase() === 'INBOX') {
|
|
96
81
|
labels = ['\\Inbox'];
|
|
97
|
-
}
|
|
82
|
+
}
|
|
83
|
+
else if (mailbox['special-use'] && mailbox['special-use'].length) {
|
|
98
84
|
labels = [].concat(mailbox['special-use']);
|
|
99
|
-
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
100
87
|
labels = [userLabel(mailbox.path)];
|
|
101
88
|
}
|
|
102
|
-
|
|
103
89
|
labels.forEach(label => {
|
|
104
90
|
server.ensureFlag(message['X-GM-LABELS'], label);
|
|
105
91
|
});
|
|
106
92
|
});
|
|
107
|
-
|
|
108
93
|
// A message starts its own thread unless storage puts it into one. With OBJECTID loaded, the messages of a THREADID
|
|
109
94
|
// (RFC 8474 section 5.2) share an X-GM-THRID: the one of the first message of that thread, like Gmail uses the
|
|
110
95
|
// X-GM-MSGID of the first message. This runs after every other message handler, so OBJECTID set the THREADID
|
|
@@ -121,7 +106,6 @@ module.exports = function (server) {
|
|
|
121
106
|
}
|
|
122
107
|
});
|
|
123
108
|
});
|
|
124
|
-
|
|
125
109
|
// Retrieve X-GM-MSGID values with FETCH
|
|
126
110
|
server.fetchHandlers['X-GM-MSGID'] = function (connection, message) {
|
|
127
111
|
return {
|
|
@@ -129,27 +113,23 @@ module.exports = function (server) {
|
|
|
129
113
|
value: message['X-GM-MSGID']
|
|
130
114
|
};
|
|
131
115
|
};
|
|
132
|
-
|
|
133
116
|
// Retrieve X-GM-LABELS values with FETCH
|
|
134
117
|
server.fetchHandlers['X-GM-LABELS'] = function (connection, message) {
|
|
135
118
|
return formatLabels(message);
|
|
136
119
|
};
|
|
137
|
-
|
|
138
120
|
// X-GM-MSGID and X-GM-THRID are 64 bit unsigned numbers
|
|
139
121
|
const idArgument = () => [
|
|
140
|
-
value => {
|
|
122
|
+
(value) => {
|
|
141
123
|
if (!/^\d{1,20}$/.test(value) || BigInt(value) > MAX_UINT64) {
|
|
142
124
|
throw badError('Expected a 64 bit unsigned number');
|
|
143
125
|
}
|
|
144
126
|
return BigInt(value).toString();
|
|
145
127
|
}
|
|
146
128
|
];
|
|
147
|
-
|
|
148
129
|
server.searchHandlers['X-GM-MSGID'] = function (connection, message, sequence, xGmMsgid) {
|
|
149
130
|
return message['X-GM-MSGID'] === xGmMsgid;
|
|
150
131
|
};
|
|
151
132
|
server.searchHandlers['X-GM-MSGID'].argumentTypes = idArgument;
|
|
152
|
-
|
|
153
133
|
// Retrieve X-GM-THRID values with FETCH
|
|
154
134
|
server.fetchHandlers['X-GM-THRID'] = function (connection, message) {
|
|
155
135
|
return {
|
|
@@ -157,15 +137,13 @@ module.exports = function (server) {
|
|
|
157
137
|
value: message['X-GM-THRID']
|
|
158
138
|
};
|
|
159
139
|
};
|
|
160
|
-
|
|
161
140
|
server.searchHandlers['X-GM-THRID'] = function (connection, message, sequence, xGmThrid) {
|
|
162
141
|
return message['X-GM-THRID'] === xGmThrid;
|
|
163
142
|
};
|
|
164
143
|
server.searchHandlers['X-GM-THRID'].argumentTypes = idArgument;
|
|
165
|
-
|
|
166
144
|
// SEARCH X-GM-LABELS label, the label is given in the form the session uses for mailbox names
|
|
167
145
|
server.searchHandlers['X-GM-LABELS'] = function (connection, message, sequence, label) {
|
|
168
|
-
return message['X-GM-LABELS'].some(stored => {
|
|
146
|
+
return message['X-GM-LABELS'].some((stored) => {
|
|
169
147
|
if (isSystemLabel(stored)) {
|
|
170
148
|
// system labels are matched without case, like flags
|
|
171
149
|
return stored.toLowerCase() === label.toLowerCase();
|
|
@@ -173,7 +151,6 @@ module.exports = function (server) {
|
|
|
173
151
|
return connection.exportMailboxName(labelName(stored)) === label;
|
|
174
152
|
});
|
|
175
153
|
};
|
|
176
|
-
|
|
177
154
|
// SEARCH X-GM-RAW query, a subset of the Gmail search syntax
|
|
178
155
|
// the translated criteria are compiled once per SEARCH, they are the same array for every message
|
|
179
156
|
const rawMatchers = new WeakMap();
|
|
@@ -186,43 +163,31 @@ module.exports = function (server) {
|
|
|
186
163
|
return rawMatchers.get(criteria)(message, sequence);
|
|
187
164
|
};
|
|
188
165
|
server.searchHandlers['X-GM-RAW'].argumentTypes = () => [parseRawQuery];
|
|
189
|
-
|
|
190
166
|
const setLabels = (message, labels) => {
|
|
191
167
|
message['X-GM-LABELS'] = [];
|
|
192
168
|
addLabels(message, labels);
|
|
193
169
|
};
|
|
194
|
-
|
|
195
170
|
const addLabels = (message, labels) => {
|
|
196
|
-
labels.forEach(label => server.ensureFlag(message['X-GM-LABELS'], label));
|
|
171
|
+
labels.forEach((label) => server.ensureFlag(message['X-GM-LABELS'], label));
|
|
197
172
|
};
|
|
198
|
-
|
|
199
173
|
const removeLabels = (message, labels) => {
|
|
200
|
-
labels.forEach(label => server.removeFlag(message['X-GM-LABELS'], label));
|
|
174
|
+
labels.forEach((label) => server.removeFlag(message['X-GM-LABELS'], label));
|
|
201
175
|
};
|
|
202
|
-
|
|
203
176
|
[
|
|
204
177
|
['X-GM-LABELS', setLabels],
|
|
205
178
|
['+X-GM-LABELS', addLabels],
|
|
206
179
|
['-X-GM-LABELS', removeLabels]
|
|
207
180
|
].forEach(([name, update]) => {
|
|
208
181
|
// all labels are parsed before the message changes, an invalid one fails the STORE
|
|
209
|
-
const apply = (connection, message, flags) =>
|
|
210
|
-
update(
|
|
211
|
-
message,
|
|
212
|
-
flags.map(flag => parseLabel(connection, flag))
|
|
213
|
-
);
|
|
214
|
-
|
|
182
|
+
const apply = (connection, message, flags) => update(message, flags.map(flag => parseLabel(connection, flag)));
|
|
215
183
|
server.storeHandlers[name] = function (connection, message, flags, index, parsed, data) {
|
|
216
184
|
apply(connection, message, flags);
|
|
217
185
|
sendLabelUpdate(connection, parsed, data, index, message);
|
|
218
186
|
};
|
|
219
|
-
|
|
220
187
|
server.storeHandlers[name + '.SILENT'] = apply;
|
|
221
|
-
|
|
222
188
|
// labels are astrings (Gmail IMAP extensions): literals are accepted, NIL is a label name
|
|
223
189
|
server.storeHandlers[name].astringValues = server.storeHandlers[name + '.SILENT'].astringValues = true;
|
|
224
190
|
});
|
|
225
|
-
|
|
226
191
|
// Gmail keeps the same X-GM-MSGID for a message in every mailbox, so copies get the value of the source message
|
|
227
192
|
server.copyHandlers.push((server, source, copy) => {
|
|
228
193
|
if (source['X-GM-MSGID']) {
|
|
@@ -230,17 +195,15 @@ module.exports = function (server) {
|
|
|
230
195
|
copy['X-GM-THRID'] = source['X-GM-THRID'];
|
|
231
196
|
}
|
|
232
197
|
});
|
|
233
|
-
}
|
|
234
|
-
|
|
198
|
+
}
|
|
235
199
|
/**
|
|
236
200
|
* Labels are kept as strings in message["X-GM-LABELS"]. A system label like \Inbox starts with "\",
|
|
237
201
|
* any other label is a mailbox name in storage form. A mailbox name that itself starts with "\" is
|
|
238
202
|
* kept with one more "\" in front, so it can not be mistaken for a system label
|
|
239
203
|
*/
|
|
240
|
-
const isSystemLabel = label => label.charAt(0) === '\\' && label.charAt(1) !== '\\';
|
|
241
|
-
const userLabel = name => (name.charAt(0) === '\\' ? '\\' + name : name);
|
|
242
|
-
const labelName = label => (label.charAt(0) === '\\' ? label.substr(1) : label);
|
|
243
|
-
|
|
204
|
+
const isSystemLabel = (label) => label.charAt(0) === '\\' && label.charAt(1) !== '\\';
|
|
205
|
+
const userLabel = (name) => (name.charAt(0) === '\\' ? '\\' + name : name);
|
|
206
|
+
const labelName = (label) => (label.charAt(0) === '\\' ? label.substr(1) : label);
|
|
244
207
|
/**
|
|
245
208
|
* Converts a STORE X-GM-LABELS value to a stored label. An atom that starts with "\" is a system
|
|
246
209
|
* label, anything else is a label name: an astring in the form the session uses for mailbox names
|
|
@@ -256,15 +219,13 @@ function parseLabel(connection, attr) {
|
|
|
256
219
|
}
|
|
257
220
|
return userLabel(connection.importMailboxName(value));
|
|
258
221
|
}
|
|
259
|
-
|
|
260
222
|
/**
|
|
261
223
|
* Formats the labels of a message for a FETCH response. Label names are MAILBOX attributes, so the
|
|
262
224
|
* session gets them in its own form and quoted when they are not atoms
|
|
263
225
|
*/
|
|
264
226
|
function formatLabels(message) {
|
|
265
|
-
return message['X-GM-LABELS'].map(label =>
|
|
227
|
+
return message['X-GM-LABELS'].map((label) => isSystemLabel(label) ? { type: 'ATOM', value: label } : { type: 'MAILBOX', value: labelName(label) });
|
|
266
228
|
}
|
|
267
|
-
|
|
268
229
|
/**
|
|
269
230
|
* Translates an X-GM-RAW query (Gmail search syntax) to ImapKit search criteria. Terms are
|
|
270
231
|
* ANDed, OR binds tighter than that ("a b OR c" is a AND (b OR c)), "-" negates a term, ( ) groups
|
|
@@ -284,23 +245,24 @@ function parseRawQuery(query) {
|
|
|
284
245
|
end = re.lastIndex;
|
|
285
246
|
if (match[1]) {
|
|
286
247
|
tokens.push({ type: match[1] });
|
|
287
|
-
}
|
|
248
|
+
}
|
|
249
|
+
else if (typeof match[2] === 'string') {
|
|
288
250
|
tokens.push({ type: 'word', value: match[2] });
|
|
289
|
-
}
|
|
251
|
+
}
|
|
252
|
+
else if (match[3]) {
|
|
290
253
|
tokens.push({ type: 'word', value: match[3] + match[4], operator: match[3].slice(0, -1), operand: match[4] });
|
|
291
|
-
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
292
256
|
tokens.push({ type: 'word', value: match[5] });
|
|
293
257
|
}
|
|
294
258
|
}
|
|
295
259
|
if (query.slice(end).trim()) {
|
|
296
260
|
throw badError('X-GM-RAW query has an unterminated quoted string');
|
|
297
261
|
}
|
|
298
|
-
|
|
299
262
|
let pos = 0;
|
|
300
263
|
const peek = () => tokens[pos];
|
|
301
|
-
|
|
302
264
|
// expression = 1*term, until the end or a closing bracket
|
|
303
|
-
const expression = end => {
|
|
265
|
+
const expression = (end) => {
|
|
304
266
|
const terms = [];
|
|
305
267
|
while (pos < tokens.length && (!peek() || peek().type !== end)) {
|
|
306
268
|
terms.push(term());
|
|
@@ -316,7 +278,6 @@ function parseRawQuery(query) {
|
|
|
316
278
|
}
|
|
317
279
|
return terms.length === 1 ? terms[0] : terms;
|
|
318
280
|
};
|
|
319
|
-
|
|
320
281
|
// term = unary *("OR" unary)
|
|
321
282
|
const term = () => {
|
|
322
283
|
let result = unary();
|
|
@@ -326,7 +287,6 @@ function parseRawQuery(query) {
|
|
|
326
287
|
}
|
|
327
288
|
return result;
|
|
328
289
|
};
|
|
329
|
-
|
|
330
290
|
const unary = () => {
|
|
331
291
|
const token = tokens[pos++];
|
|
332
292
|
if (!token || token.type === ')' || token.type === '}') {
|
|
@@ -346,30 +306,31 @@ function parseRawQuery(query) {
|
|
|
346
306
|
pos++;
|
|
347
307
|
return options.reduce((any, option) => ['OR', any, option]);
|
|
348
308
|
}
|
|
349
|
-
|
|
309
|
+
// the brackets are handled above, a word always has a value
|
|
310
|
+
const value = token.value;
|
|
311
|
+
if (value === '-' && peek() && (peek().type === '(' || peek().type === '{')) {
|
|
350
312
|
return ['NOT', unary()];
|
|
351
313
|
}
|
|
352
|
-
if (
|
|
353
|
-
return ['NOT', rawTerm(rawWord(
|
|
314
|
+
if (value.charAt(0) === '-' && value.length > 1) {
|
|
315
|
+
return ['NOT', rawTerm(rawWord(value.substr(1)))];
|
|
354
316
|
}
|
|
355
317
|
return rawTerm(token);
|
|
356
318
|
};
|
|
357
|
-
|
|
358
319
|
return [expression()];
|
|
359
320
|
}
|
|
360
|
-
|
|
361
321
|
// splits "name:value" into an operator and an operand
|
|
362
322
|
function rawWord(value) {
|
|
363
323
|
const match = value.match(/^([a-z_0-9]+):(.+)$/i);
|
|
364
324
|
return match ? { value, operator: match[1], operand: match[2] } : { value, operator: false, operand: false };
|
|
365
325
|
}
|
|
366
|
-
|
|
367
326
|
function rawTerm(token) {
|
|
368
|
-
const
|
|
327
|
+
const word = token.operator ? token : rawWord(token.value);
|
|
328
|
+
const operator = word.operator;
|
|
369
329
|
if (!operator) {
|
|
370
330
|
return ['TEXT', token.value];
|
|
371
331
|
}
|
|
372
|
-
|
|
332
|
+
// an operator always comes with its operand
|
|
333
|
+
const operand = word.operand;
|
|
373
334
|
const name = operator.toLowerCase();
|
|
374
335
|
// own keys only, names like "constructor:" are plain text
|
|
375
336
|
const shortcutKey = name + ':' + operand.toLowerCase();
|
|
@@ -377,7 +338,6 @@ function rawTerm(token) {
|
|
|
377
338
|
if (shortcut) {
|
|
378
339
|
return shortcut;
|
|
379
340
|
}
|
|
380
|
-
|
|
381
341
|
const key = Object.hasOwn(RAW_OPERATORS, name) && RAW_OPERATORS[name];
|
|
382
342
|
if (key) {
|
|
383
343
|
switch (key) {
|
|
@@ -403,22 +363,18 @@ function rawTerm(token) {
|
|
|
403
363
|
return [key, operand];
|
|
404
364
|
}
|
|
405
365
|
}
|
|
406
|
-
|
|
407
366
|
if (name === 'in') {
|
|
408
367
|
// any other mailbox is a label
|
|
409
368
|
return ['X-GM-LABELS', operand];
|
|
410
369
|
}
|
|
411
|
-
|
|
412
370
|
if (RAW_UNSUPPORTED.indexOf(name) >= 0) {
|
|
413
371
|
const err = new Error('X-GM-RAW operator ' + name + ':' + operand + ' is not supported by imapkit');
|
|
414
372
|
err.imapResponse = 'NO';
|
|
415
373
|
throw err;
|
|
416
374
|
}
|
|
417
|
-
|
|
418
375
|
// not an operator, like "http://example.com"
|
|
419
376
|
return ['TEXT', token.value];
|
|
420
377
|
}
|
|
421
|
-
|
|
422
378
|
function sendLabelUpdate(connection, parsed, data, index, message) {
|
|
423
379
|
const resp = [
|
|
424
380
|
{
|
|
@@ -427,7 +383,6 @@ function sendLabelUpdate(connection, parsed, data, index, message) {
|
|
|
427
383
|
},
|
|
428
384
|
formatLabels(message)
|
|
429
385
|
];
|
|
430
|
-
|
|
431
386
|
if ((parsed.command || '').toUpperCase() === 'UID STORE') {
|
|
432
387
|
resp.push({
|
|
433
388
|
type: 'ATOM',
|
|
@@ -435,22 +390,15 @@ function sendLabelUpdate(connection, parsed, data, index, message) {
|
|
|
435
390
|
});
|
|
436
391
|
resp.push(message.uid);
|
|
437
392
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
]
|
|
450
|
-
},
|
|
451
|
-
'FLAG UPDATE',
|
|
452
|
-
parsed,
|
|
453
|
-
data,
|
|
454
|
-
message
|
|
455
|
-
);
|
|
393
|
+
connection.send({
|
|
394
|
+
tag: '*',
|
|
395
|
+
attributes: [
|
|
396
|
+
index,
|
|
397
|
+
{
|
|
398
|
+
type: 'ATOM',
|
|
399
|
+
value: 'FETCH'
|
|
400
|
+
},
|
|
401
|
+
resp
|
|
402
|
+
]
|
|
403
|
+
}, 'FLAG UPDATE', parsed, data, message);
|
|
456
404
|
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// https://developers.google.com/gmail/xoauth2_protocol
|
|
2
|
+
/**
|
|
3
|
+
* @help Enables XOAUTH2 capability
|
|
4
|
+
* @help Implementation difference - ImapKit requires
|
|
5
|
+
* @help SASL-IR enabled and used while Gmail does not
|
|
6
|
+
* @help Valid login info:
|
|
7
|
+
* @help Username: testuser
|
|
8
|
+
* @help Access Token: testtoken
|
|
9
|
+
*/
|
|
10
|
+
const utf8 = new TextDecoder('utf-8', { fatal: true });
|
|
11
|
+
export default function xoauth2Plugin(server) {
|
|
12
|
+
// Register capability, usable for non authenticated users
|
|
13
|
+
server.registerCapability('AUTH=XOAUTH2', (connection) => {
|
|
14
|
+
return connection.state === 'Not Authenticated';
|
|
15
|
+
});
|
|
16
|
+
server.setCommandHandler('AUTHENTICATE XOAUTH2', (connection, parsed, data, callback) => {
|
|
17
|
+
if (!server.capabilities['SASL-IR'] || !server.capabilities['SASL-IR'](connection)) {
|
|
18
|
+
connection.send({
|
|
19
|
+
tag: parsed.tag,
|
|
20
|
+
command: 'BAD',
|
|
21
|
+
attributes: [
|
|
22
|
+
{
|
|
23
|
+
type: 'TEXT',
|
|
24
|
+
value: 'SASL-IR must be enabled to support XOAUTH2'
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
|
|
28
|
+
return callback();
|
|
29
|
+
}
|
|
30
|
+
if (!parsed.attributes || parsed.attributes.length !== 1 || !parsed.attributes[0] || ['STRING', 'ATOM'].indexOf(parsed.attributes[0].type) < 0) {
|
|
31
|
+
connection.send({
|
|
32
|
+
tag: parsed.tag,
|
|
33
|
+
command: 'NO',
|
|
34
|
+
attributes: [
|
|
35
|
+
{
|
|
36
|
+
type: 'TEXT',
|
|
37
|
+
value: 'Invalid SASL argument'
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
|
|
41
|
+
return callback();
|
|
42
|
+
}
|
|
43
|
+
const decoded = connection.decodeSaslResponse(parsed.attributes[0].value);
|
|
44
|
+
if (!decoded) {
|
|
45
|
+
connection.sendStatus(parsed, data, 'BAD', 'Invalid base64 in SASL response', false, 'AUTHENTICATE XOAUTH2 FAILED');
|
|
46
|
+
return callback();
|
|
47
|
+
}
|
|
48
|
+
let parts = [];
|
|
49
|
+
try {
|
|
50
|
+
// user names are unicode strings, like the keys of `users`
|
|
51
|
+
parts = utf8.decode(decoded).split('\x01');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// invalid UTF-8 is a malformed payload like any other
|
|
55
|
+
}
|
|
56
|
+
const user = (parts[0] || '').substr(5);
|
|
57
|
+
const accessToken = (parts[1] || '').substr(12);
|
|
58
|
+
if (parts.length !== 4 ||
|
|
59
|
+
!parts[0].match(/^user=/) ||
|
|
60
|
+
!parts[1].match(/^auth=Bearer /) ||
|
|
61
|
+
!user || // Must be present
|
|
62
|
+
!accessToken || // Must be present
|
|
63
|
+
parts[2] || // Must be empty
|
|
64
|
+
parts[3] // Must be empty
|
|
65
|
+
) {
|
|
66
|
+
connection.send({
|
|
67
|
+
tag: parsed.tag,
|
|
68
|
+
command: 'NO',
|
|
69
|
+
attributes: [
|
|
70
|
+
{
|
|
71
|
+
type: 'TEXT',
|
|
72
|
+
value: 'Invalid SASL argument.'
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
|
|
76
|
+
return callback();
|
|
77
|
+
}
|
|
78
|
+
const userData = connection.server.getUser(user);
|
|
79
|
+
if (!userData) {
|
|
80
|
+
connection.send({
|
|
81
|
+
tag: parsed.tag,
|
|
82
|
+
command: 'NO',
|
|
83
|
+
attributes: [
|
|
84
|
+
// RFC 5530 section 3: unknown user or bad token
|
|
85
|
+
{ type: 'SECTION', section: [{ type: 'ATOM', value: 'AUTHENTICATIONFAILED' }] },
|
|
86
|
+
{
|
|
87
|
+
type: 'TEXT',
|
|
88
|
+
value: 'Invalid credentials'
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
|
|
92
|
+
return callback();
|
|
93
|
+
}
|
|
94
|
+
if (!userData.xoauth2 || userData.xoauth2.accessToken !== accessToken) {
|
|
95
|
+
connection.send({
|
|
96
|
+
tag: '+',
|
|
97
|
+
attributes: [
|
|
98
|
+
{
|
|
99
|
+
type: 'ATOM',
|
|
100
|
+
value: Buffer.from(JSON.stringify({
|
|
101
|
+
status: '400',
|
|
102
|
+
schemes: 'Bearer',
|
|
103
|
+
scope: 'https://mail.google.com/'
|
|
104
|
+
})).toString('base64')
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
|
|
108
|
+
// wait for response
|
|
109
|
+
connection.inputHandler = function () {
|
|
110
|
+
connection.inputHandler = false;
|
|
111
|
+
connection.send({
|
|
112
|
+
tag: parsed.tag,
|
|
113
|
+
command: 'NO',
|
|
114
|
+
attributes: [
|
|
115
|
+
{ type: 'SECTION', section: [{ type: 'ATOM', value: 'AUTHENTICATIONFAILED' }] },
|
|
116
|
+
{
|
|
117
|
+
type: 'TEXT',
|
|
118
|
+
value: 'SASL authentication failed'
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}, 'AUTHENTICATE XOAUTH2 FAILED', parsed, data);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
connection.state = 'Authenticated';
|
|
126
|
+
connection.username = user;
|
|
127
|
+
connection.send({
|
|
128
|
+
tag: parsed.tag,
|
|
129
|
+
command: 'OK',
|
|
130
|
+
attributes: [
|
|
131
|
+
{
|
|
132
|
+
type: 'TEXT',
|
|
133
|
+
value: 'User logged in'
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}, 'AUTHENTICATE XOAUTH2 SUCCESS', parsed, data);
|
|
137
|
+
}
|
|
138
|
+
return callback();
|
|
139
|
+
});
|
|
140
|
+
}
|