@rapidmx/activesync-plugin 1.0.0-beta.2 → 1.0.0-beta.3

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.
Files changed (201) hide show
  1. package/README.md +4 -4
  2. package/dist/lib/BaseDeviceSyncStateRoute.js +32 -0
  3. package/dist/lib/BaseDeviceSyncStateRoute.js.map +1 -1
  4. package/dist/lib/BaseEasRoute.js +91 -15
  5. package/dist/lib/BaseEasRoute.js.map +1 -1
  6. package/dist/lib/EasAuditLog.js +56 -0
  7. package/dist/lib/EasAuditLog.js.map +1 -0
  8. package/dist/lib/EasCollectionLease.js +199 -0
  9. package/dist/lib/EasCollectionLease.js.map +1 -0
  10. package/dist/lib/EasCollectionStore.js +102 -0
  11. package/dist/lib/EasCollectionStore.js.map +1 -0
  12. package/dist/lib/EasCollectionSync.js +294 -0
  13. package/dist/lib/EasCollectionSync.js.map +1 -0
  14. package/dist/lib/EasSyncKeyUtils.js +125 -62
  15. package/dist/lib/EasSyncKeyUtils.js.map +1 -1
  16. package/dist/lib/MessageMoveRules.js +100 -0
  17. package/dist/lib/MessageMoveRules.js.map +1 -0
  18. package/dist/lib/MimeHeaderUtils.js +395 -0
  19. package/dist/lib/MimeHeaderUtils.js.map +1 -0
  20. package/dist/lib/RegexPatternUtils.js +30 -0
  21. package/dist/lib/RegexPatternUtils.js.map +1 -0
  22. package/dist/lib/RestapiCompat.js +41 -0
  23. package/dist/lib/RestapiCompat.js.map +1 -0
  24. package/dist/lib/adapters/CalendarSyncAdapter.js +142 -33
  25. package/dist/lib/adapters/CalendarSyncAdapter.js.map +1 -1
  26. package/dist/lib/adapters/EmailSyncAdapter.js +114 -27
  27. package/dist/lib/adapters/EmailSyncAdapter.js.map +1 -1
  28. package/dist/lib/adapters/mongo/EmailSyncAdapterMongo.js +2 -1
  29. package/dist/lib/adapters/mongo/EmailSyncAdapterMongo.js.map +1 -1
  30. package/dist/lib/adapters/sql/EmailSyncAdapterSQL.js +2 -1
  31. package/dist/lib/adapters/sql/EmailSyncAdapterSQL.js.map +1 -1
  32. package/dist/lib/codec/WbxmlDecoder.js +86 -34
  33. package/dist/lib/codec/WbxmlDecoder.js.map +1 -1
  34. package/dist/lib/codec/WbxmlEncoder.js +103 -22
  35. package/dist/lib/codec/WbxmlEncoder.js.map +1 -1
  36. package/dist/lib/commands/ComposeMailCommand.js +105 -31
  37. package/dist/lib/commands/ComposeMailCommand.js.map +1 -1
  38. package/dist/lib/commands/FolderSyncCommand.js +67 -27
  39. package/dist/lib/commands/FolderSyncCommand.js.map +1 -1
  40. package/dist/lib/commands/GetItemEstimateCommand.js +80 -59
  41. package/dist/lib/commands/GetItemEstimateCommand.js.map +1 -1
  42. package/dist/lib/commands/ItemOperationsCommand.js +219 -56
  43. package/dist/lib/commands/ItemOperationsCommand.js.map +1 -1
  44. package/dist/lib/commands/MeetingResponseCommand.js +212 -53
  45. package/dist/lib/commands/MeetingResponseCommand.js.map +1 -1
  46. package/dist/lib/commands/MoveItemsCommand.js +54 -21
  47. package/dist/lib/commands/MoveItemsCommand.js.map +1 -1
  48. package/dist/lib/commands/PingCommand.js +288 -56
  49. package/dist/lib/commands/PingCommand.js.map +1 -1
  50. package/dist/lib/commands/ProvisionCommand.js +34 -17
  51. package/dist/lib/commands/ProvisionCommand.js.map +1 -1
  52. package/dist/lib/commands/ResolveRecipientsCommand.js +43 -5
  53. package/dist/lib/commands/ResolveRecipientsCommand.js.map +1 -1
  54. package/dist/lib/commands/SearchCommand.js +92 -17
  55. package/dist/lib/commands/SearchCommand.js.map +1 -1
  56. package/dist/lib/commands/SettingsCommand.js +2 -1
  57. package/dist/lib/commands/SettingsCommand.js.map +1 -1
  58. package/dist/lib/commands/SmartForwardCommand.js +2 -1
  59. package/dist/lib/commands/SmartForwardCommand.js.map +1 -1
  60. package/dist/lib/commands/SmartReplyCommand.js +2 -1
  61. package/dist/lib/commands/SmartReplyCommand.js.map +1 -1
  62. package/dist/lib/commands/SyncCommand.js +481 -244
  63. package/dist/lib/commands/SyncCommand.js.map +1 -1
  64. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js +6 -1
  65. package/dist/lib/commands/mongo/GetItemEstimateCommandMongo.js.map +1 -1
  66. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js +3 -1
  67. package/dist/lib/commands/mongo/ItemOperationsCommandMongo.js.map +1 -1
  68. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js +2 -1
  69. package/dist/lib/commands/mongo/MeetingResponseCommandMongo.js.map +1 -1
  70. package/dist/lib/commands/mongo/PingCommandMongo.js +23 -0
  71. package/dist/lib/commands/mongo/PingCommandMongo.js.map +1 -0
  72. package/dist/lib/commands/mongo/SearchCommandMongo.js +3 -1
  73. package/dist/lib/commands/mongo/SearchCommandMongo.js.map +1 -1
  74. package/dist/lib/commands/mongo/SendMailCommandMongo.js +2 -1
  75. package/dist/lib/commands/mongo/SendMailCommandMongo.js.map +1 -1
  76. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js +2 -1
  77. package/dist/lib/commands/mongo/SmartForwardCommandMongo.js.map +1 -1
  78. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js +2 -1
  79. package/dist/lib/commands/mongo/SmartReplyCommandMongo.js.map +1 -1
  80. package/dist/lib/commands/mongo/SyncCommandMongo.js +7 -1
  81. package/dist/lib/commands/mongo/SyncCommandMongo.js.map +1 -1
  82. package/dist/lib/commands/mongo/index.js +1 -0
  83. package/dist/lib/commands/mongo/index.js.map +1 -1
  84. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js +6 -1
  85. package/dist/lib/commands/sql/GetItemEstimateCommandSQL.js.map +1 -1
  86. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js +3 -1
  87. package/dist/lib/commands/sql/ItemOperationsCommandSQL.js.map +1 -1
  88. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js +2 -1
  89. package/dist/lib/commands/sql/MeetingResponseCommandSQL.js.map +1 -1
  90. package/dist/lib/commands/sql/PingCommandSQL.js +23 -0
  91. package/dist/lib/commands/sql/PingCommandSQL.js.map +1 -0
  92. package/dist/lib/commands/sql/SearchCommandSQL.js +3 -1
  93. package/dist/lib/commands/sql/SearchCommandSQL.js.map +1 -1
  94. package/dist/lib/commands/sql/SendMailCommandSQL.js +2 -1
  95. package/dist/lib/commands/sql/SendMailCommandSQL.js.map +1 -1
  96. package/dist/lib/commands/sql/SmartForwardCommandSQL.js +2 -1
  97. package/dist/lib/commands/sql/SmartForwardCommandSQL.js.map +1 -1
  98. package/dist/lib/commands/sql/SmartReplyCommandSQL.js +2 -1
  99. package/dist/lib/commands/sql/SmartReplyCommandSQL.js.map +1 -1
  100. package/dist/lib/commands/sql/SyncCommandSQL.js +7 -1
  101. package/dist/lib/commands/sql/SyncCommandSQL.js.map +1 -1
  102. package/dist/lib/commands/sql/index.js +1 -0
  103. package/dist/lib/commands/sql/index.js.map +1 -1
  104. package/dist/lib/index.js +5 -0
  105. package/dist/lib/index.js.map +1 -1
  106. package/dist/lib/jobs/EasDeviceStateCleanupJob.js +44 -2
  107. package/dist/lib/jobs/EasDeviceStateCleanupJob.js.map +1 -1
  108. package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js +4 -0
  109. package/dist/lib/jobs/mongo/EasDeviceStateCleanupJobMongo.js.map +1 -1
  110. package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js +9 -0
  111. package/dist/lib/jobs/sql/EasDeviceStateCleanupJobSQL.js.map +1 -1
  112. package/dist/lib/models/EasCollectionChunk.js +2 -0
  113. package/dist/lib/models/EasCollectionChunk.js.map +1 -0
  114. package/dist/lib/models/EasCollectionState.js +2 -0
  115. package/dist/lib/models/EasCollectionState.js.map +1 -0
  116. package/dist/lib/models/mongo/DeviceSyncStateMongo.js +7 -0
  117. package/dist/lib/models/mongo/DeviceSyncStateMongo.js.map +1 -1
  118. package/dist/lib/models/mongo/EasCollectionChunkMongo.js +83 -0
  119. package/dist/lib/models/mongo/EasCollectionChunkMongo.js.map +1 -0
  120. package/dist/lib/models/mongo/EasCollectionStateMongo.js +162 -0
  121. package/dist/lib/models/mongo/EasCollectionStateMongo.js.map +1 -0
  122. package/dist/lib/models/sql/DeviceSyncStateSQL.js +7 -0
  123. package/dist/lib/models/sql/DeviceSyncStateSQL.js.map +1 -1
  124. package/dist/lib/models/sql/EasCollectionChunkSQL.js +83 -0
  125. package/dist/lib/models/sql/EasCollectionChunkSQL.js.map +1 -0
  126. package/dist/lib/models/sql/EasCollectionStateSQL.js +162 -0
  127. package/dist/lib/models/sql/EasCollectionStateSQL.js.map +1 -0
  128. package/dist/lib/mongo/EasRouteMongo.js +2 -2
  129. package/dist/lib/mongo/EasRouteMongo.js.map +1 -1
  130. package/dist/lib/mongo.js +2 -0
  131. package/dist/lib/mongo.js.map +1 -1
  132. package/dist/lib/sql/EasRouteSQL.js +2 -2
  133. package/dist/lib/sql/EasRouteSQL.js.map +1 -1
  134. package/dist/lib/sql.js +2 -0
  135. package/dist/lib/sql.js.map +1 -1
  136. package/dist/types/BaseDeviceSyncStateRoute.d.ts +10 -0
  137. package/dist/types/BaseEasRoute.d.ts +15 -4
  138. package/dist/types/EasAuditLog.d.ts +47 -0
  139. package/dist/types/EasCollectionLease.d.ts +60 -0
  140. package/dist/types/EasCollectionStore.d.ts +51 -0
  141. package/dist/types/EasCollectionSync.d.ts +96 -0
  142. package/dist/types/EasCommandHandler.d.ts +7 -4
  143. package/dist/types/EasSyncKeyUtils.d.ts +73 -42
  144. package/dist/types/MessageMoveRules.d.ts +45 -0
  145. package/dist/types/MimeHeaderUtils.d.ts +73 -0
  146. package/dist/types/RegexPatternUtils.d.ts +14 -0
  147. package/dist/types/RestapiCompat.d.ts +24 -0
  148. package/dist/types/adapters/CalendarSyncAdapter.d.ts +47 -18
  149. package/dist/types/adapters/EasCollectionSyncAdapter.d.ts +18 -2
  150. package/dist/types/adapters/EmailSyncAdapter.d.ts +24 -7
  151. package/dist/types/adapters/mongo/EmailSyncAdapterMongo.d.ts +1 -0
  152. package/dist/types/adapters/sql/EmailSyncAdapterSQL.d.ts +1 -0
  153. package/dist/types/codec/WbxmlDecoder.d.ts +39 -0
  154. package/dist/types/codec/WbxmlEncoder.d.ts +36 -1
  155. package/dist/types/commands/ComposeMailCommand.d.ts +33 -15
  156. package/dist/types/commands/FolderSyncCommand.d.ts +4 -1
  157. package/dist/types/commands/GetItemEstimateCommand.d.ts +20 -15
  158. package/dist/types/commands/ItemOperationsCommand.d.ts +29 -4
  159. package/dist/types/commands/MeetingResponseCommand.d.ts +52 -13
  160. package/dist/types/commands/MoveItemsCommand.d.ts +13 -3
  161. package/dist/types/commands/PingCommand.d.ts +72 -14
  162. package/dist/types/commands/ProvisionCommand.d.ts +16 -11
  163. package/dist/types/commands/ResolveRecipientsCommand.d.ts +4 -0
  164. package/dist/types/commands/SearchCommand.d.ts +13 -1
  165. package/dist/types/commands/SyncCommand.d.ts +102 -62
  166. package/dist/types/commands/mongo/GetItemEstimateCommandMongo.d.ts +3 -0
  167. package/dist/types/commands/mongo/ItemOperationsCommandMongo.d.ts +2 -0
  168. package/dist/types/commands/mongo/MeetingResponseCommandMongo.d.ts +1 -0
  169. package/dist/types/commands/mongo/PingCommandMongo.d.ts +8 -0
  170. package/dist/types/commands/mongo/SearchCommandMongo.d.ts +2 -0
  171. package/dist/types/commands/mongo/SendMailCommandMongo.d.ts +1 -0
  172. package/dist/types/commands/mongo/SmartForwardCommandMongo.d.ts +1 -0
  173. package/dist/types/commands/mongo/SmartReplyCommandMongo.d.ts +1 -0
  174. package/dist/types/commands/mongo/SyncCommandMongo.d.ts +4 -0
  175. package/dist/types/commands/mongo/index.d.ts +1 -0
  176. package/dist/types/commands/sql/GetItemEstimateCommandSQL.d.ts +3 -0
  177. package/dist/types/commands/sql/ItemOperationsCommandSQL.d.ts +2 -0
  178. package/dist/types/commands/sql/MeetingResponseCommandSQL.d.ts +1 -0
  179. package/dist/types/commands/sql/PingCommandSQL.d.ts +8 -0
  180. package/dist/types/commands/sql/SearchCommandSQL.d.ts +2 -0
  181. package/dist/types/commands/sql/SendMailCommandSQL.d.ts +1 -0
  182. package/dist/types/commands/sql/SmartForwardCommandSQL.d.ts +1 -0
  183. package/dist/types/commands/sql/SmartReplyCommandSQL.d.ts +1 -0
  184. package/dist/types/commands/sql/SyncCommandSQL.d.ts +4 -0
  185. package/dist/types/commands/sql/index.d.ts +1 -0
  186. package/dist/types/index.d.ts +5 -0
  187. package/dist/types/jobs/EasDeviceStateCleanupJob.d.ts +15 -0
  188. package/dist/types/jobs/mongo/EasDeviceStateCleanupJobMongo.d.ts +2 -0
  189. package/dist/types/jobs/sql/EasDeviceStateCleanupJobSQL.d.ts +4 -0
  190. package/dist/types/models/DeviceSyncState.d.ts +13 -2
  191. package/dist/types/models/EasCollectionChunk.d.ts +20 -0
  192. package/dist/types/models/EasCollectionState.d.ts +79 -0
  193. package/dist/types/models/mongo/DeviceSyncStateMongo.d.ts +1 -0
  194. package/dist/types/models/mongo/EasCollectionChunkMongo.d.ts +16 -0
  195. package/dist/types/models/mongo/EasCollectionStateMongo.d.ts +27 -0
  196. package/dist/types/models/sql/DeviceSyncStateSQL.d.ts +1 -0
  197. package/dist/types/models/sql/EasCollectionChunkSQL.d.ts +16 -0
  198. package/dist/types/models/sql/EasCollectionStateSQL.d.ts +27 -0
  199. package/dist/types/mongo.d.ts +2 -0
  200. package/dist/types/sql.d.ts +2 -0
  201. package/package.json +267 -238
@@ -13,29 +13,61 @@ var __metadata = (this && this.__metadata) || function (k, v) {
13
13
  ///////////////////////////////////////////////////////////////////////////////
14
14
  import { createClient } from "redis";
15
15
  import { ObjectDecorators } from "@rapidrest/core";
16
- import { ACLAction, ACLUtils } from "@rapidrest/service-core";
16
+ import { ACLAction, ACLUtils, RepoUtils } from "@rapidrest/service-core";
17
+ import { RecoverableRepoUtils } from "@rapidmx/restapi";
17
18
  import { WbxmlCodePage } from "../codec/WbxmlCodePages.js";
18
19
  import { childText, element, findChild, findChildren, textElement } from "../codec/WbxmlElement.js";
19
- const { Config, Inject } = ObjectDecorators;
20
+ import { compareCursor, cursorOf, isListableUid, scanAfter } from "../EasSyncKeyUtils.js";
21
+ const { Config, Init, Inject } = ObjectDecorators;
20
22
  /** MS-ASCMD `Ping` `Status` codes this pragmatic subset distinguishes - not the full enumeration the real
21
- * spec defines (e.g. it also has codes for "too many folders", "folder hierarchy changed", etc.), matching
22
- * this library's "pragmatic subset, not full fidelity" precedent elsewhere. */
23
+ * spec defines (e.g. it also has a code for "folder hierarchy changed"), matching this library's "pragmatic
24
+ * subset, not full fidelity" precedent elsewhere. */
23
25
  const STATUS_NO_CHANGES = "1";
24
26
  const STATUS_CHANGES_FOUND = "2";
25
27
  const STATUS_MISSING_PARAMETERS = "3";
28
+ const STATUS_TOO_MANY_FOLDERS = "6";
29
+ /** How many `ACLUtils.hasPermission()` checks run concurrently. */
30
+ const ACL_CHECK_CHUNK_SIZE = 25;
31
+ /** Rows read per folder when looking for changes a device hasn't synced yet - enough to see past a few of the
32
+ * device's own writes (`echoes`); a full page is reported as a change regardless. */
33
+ const PENDING_CHANGE_SCAN_LIMIT = 5;
34
+ /** Most per-folder fallback scans (`scanAfter`) `pendingInClass` runs at once. */
35
+ const FALLBACK_SCAN_CHUNK_SIZE = 25;
36
+ /** Folder uids per batched `EasCollectionState` lookup, and folders per batched pending-change check. */
37
+ const STATE_LOOKUP_CHUNK = 500;
38
+ /** Rows per stream (live, soft-deleted) one batched pending-change check reads before falling back to per-folder scans. */
39
+ const PENDING_BATCH_ROW_LIMIT = 500;
40
+ /** The `(dateModified, uid)` stream order, as `scanAfter()` reads it. */
41
+ const PENDING_BATCH_SORT = JSON.stringify({ dateModified: "ASC", uid: "ASC" });
26
42
  /**
27
43
  * Handles EAS `Ping`: a long-poll HTTP request that blocks for up to `HeartbeatInterval` seconds waiting for a
28
- * change in any of the client-specified folders, then reports which (if any) actually changed. No websocket
29
- * needed - subscribes a plain, request-scoped Redis client (the same construction `BasePushRoute.connect()`
30
- * uses, minus its own per-socket bookkeeping this one-shot request doesn't need) directly to the requested
31
- * `folderUid` channels. Every `Message`/`CalendarEvent`/etc. mutation already publishes to exactly these
32
- * channels via `BaseScopedChildRoute.notify()`/`RepoUtils`'s own push - `Ping` needs no new publish call site
33
- * of its own, only a subscriber.
44
+ * change in any of the client-specified folders, then reports which (if any) actually changed. Every
45
+ * `Message`/`CalendarEvent`/etc. mutation already publishes to the `folderUid` channels via
46
+ * `BaseScopedChildRoute.notify()`/`RepoUtils`'s own push - `Ping` only needs a subscriber.
47
+ *
48
+ * Resource bounds:
49
+ * - One shared Redis subscriber client per process (per Redis URL), lazily connected once. Each `Ping` attaches
50
+ * its own listener to its channels and removes exactly that listener when it settles. A connect/subscribe
51
+ * failure fails open (the `Ping` just waits out its heartbeat and reports no changes) and a failed connect is
52
+ * forgotten so a later `Ping` retries it.
53
+ * - At most one active `Ping` per (mailbox, device) per process: a newer one supersedes (answers Status 1) the
54
+ * older one.
55
+ * - The wait ends as soon as the HTTP response finishes (including a client abort).
56
+ * - More than `mail:eas:ping_max_folders` folders is rejected with Status 6 before any ACL work, and the ACL
57
+ * checks themselves run in bounded concurrent chunks.
58
+ * - Without a `datastores:events` config the `Ping` still waits the full (clamped) heartbeat before answering
59
+ * Status 1, so a device can't hot-loop against it.
60
+ *
61
+ * **Changes made before the `Ping` started**: a publish only reaches a subscriber that exists at that moment, so a
62
+ * change landing between the device's last `Sync` and this `Ping`'s subscribe would otherwise go unnoticed until
63
+ * the next change. Once subscribed (or right away, without Redis), each folder's stream is checked for a row after
64
+ * the cursor its `EasCollectionState` recorded, and any folder with one is answered with Status 2 immediately. This
65
+ * needs `collectionStateClass`/`collectionBindings` (set by `PingCommandMongo`/`PingCommandSQL`); a folder the
66
+ * device never synced has no cursor and isn't checked.
34
67
  *
35
68
  * Requested folder uids are filtered down to only those the caller currently has `READ` on before subscribing -
36
- * matching every other command's ownership check on a client-supplied id, since without it a device could
37
- * long-poll indefinitely on any folder uid it happens to know (including one it used to have legitimate access
38
- * to and no longer does) and learn purely from this channel when that other mailbox's data changes.
69
+ * without it a device could long-poll on any folder uid it happens to know (including one whose share was since
70
+ * revoked) and learn from this channel when that other mailbox's data changes.
39
71
  *
40
72
  * @author Jean-Philippe Steinmetz
41
73
  */
@@ -44,6 +76,26 @@ export class PingCommand {
44
76
  this.command = "Ping";
45
77
  this.minHeartbeatSeconds = 60;
46
78
  this.maxHeartbeatSeconds = 1740;
79
+ this.maxFolders = 300;
80
+ this.collectionBindings = {};
81
+ this.repos = new Map();
82
+ }
83
+ async init() {
84
+ if (!this.collectionStateClass) {
85
+ return;
86
+ }
87
+ this.collectionStateRepo = await this._objectFactory.newInstance(RepoUtils, {
88
+ name: this.collectionStateClass.name,
89
+ args: [this.collectionStateClass],
90
+ });
91
+ for (const [collectionClass, binding] of Object.entries(this.collectionBindings)) {
92
+ this.repos.set(collectionClass, await this._objectFactory.newInstance(RecoverableRepoUtils, { name: binding.entityClass.name, args: [binding.entityClass] }));
93
+ }
94
+ }
95
+ /** Forgets all process-wide shared state (subscriber clients and active pings). Intended for tests. */
96
+ static resetSharedState() {
97
+ PingCommand.subscribers.clear();
98
+ PingCommand.activePings.clear();
47
99
  }
48
100
  async handle(ctx) {
49
101
  if (!ctx.request) {
@@ -58,20 +110,21 @@ export class PingCommand {
58
110
  if (requestedFolderUids.length === 0) {
59
111
  return this.statusResponse(STATUS_MISSING_PARAMETERS);
60
112
  }
61
- // Every other command checks ownership before acting on a client-supplied folder id - `Ping` must too,
62
- // or a device that once had a folder shared with it (and so learned its real uid) could keep watching
63
- // that folder's live activity via this long-poll indefinitely, even after the share is later revoked.
113
+ if (requestedFolderUids.length > this.maxFolders) {
114
+ return element(WbxmlCodePage.Ping, "Ping", [
115
+ textElement(WbxmlCodePage.Ping, "Status", STATUS_TOO_MANY_FOLDERS),
116
+ textElement(WbxmlCodePage.Ping, "MaxFolders", String(this.maxFolders)),
117
+ ]);
118
+ }
64
119
  // Filtered down to the permitted subset rather than failing the whole request: `Ping`'s wire response
65
- // has no per-folder status to report a partial denial through, and a client legitimately re-sends the
66
- // same folder list across requests regardless of access changes it has no way to know about yet.
67
- const permitted = await Promise.all(requestedFolderUids.map((uid) => this.aclUtils.hasPermission(ctx.user, uid, ACLAction.READ)));
68
- const folderUids = requestedFolderUids.filter((_uid, i) => permitted[i]);
120
+ // has no per-folder status to report a partial denial through.
121
+ const folderUids = await this.filterPermitted(ctx, requestedFolderUids);
69
122
  if (folderUids.length === 0) {
70
123
  return this.statusResponse(STATUS_MISSING_PARAMETERS);
71
124
  }
72
125
  const requestedSeconds = Number(childText(ctx.request, "HeartbeatInterval") ?? this.minHeartbeatSeconds);
73
126
  const heartbeatSeconds = Math.min(Math.max(Number.isFinite(requestedSeconds) ? requestedSeconds : this.minHeartbeatSeconds, this.minHeartbeatSeconds), this.maxHeartbeatSeconds);
74
- const changedFolderUids = await this.waitForChange(folderUids, heartbeatSeconds);
127
+ const changedFolderUids = await this.waitForChange(ctx, folderUids, heartbeatSeconds);
75
128
  if (changedFolderUids.length === 0) {
76
129
  return this.statusResponse(STATUS_NO_CHANGES);
77
130
  }
@@ -83,49 +136,218 @@ export class PingCommand {
83
136
  statusResponse(status) {
84
137
  return element(WbxmlCodePage.Ping, "Ping", [textElement(WbxmlCodePage.Ping, "Status", status)]);
85
138
  }
86
- /** Subscribes to `folderUids` and resolves with whichever of them published a change first, or `[]` if
87
- * `timeoutSeconds` elapses with no publish. A missing `datastores:events` config (Redis pub/sub not set up
88
- * for this deployment) fails open to "no changes" rather than blocking forever or throwing - `Ping` is a
89
- * best-effort low-latency notification path, not the only way a client ever discovers new mail (it will
90
- * eventually poll a real `Sync`/`FolderSync` regardless). */
91
- async waitForChange(folderUids, timeoutSeconds) {
92
- if (!this.redisConfig) {
139
+ /** Returns the subset of `folderUids` the caller has `READ` on, checking at most `ACL_CHECK_CHUNK_SIZE` at once. */
140
+ async filterPermitted(ctx, folderUids) {
141
+ const result = [];
142
+ for (let i = 0; i < folderUids.length; i += ACL_CHECK_CHUNK_SIZE) {
143
+ const chunk = folderUids.slice(i, i + ACL_CHECK_CHUNK_SIZE);
144
+ const permitted = await Promise.all(chunk.map((uid) => this.aclUtils.hasPermission(ctx.user, uid, ACLAction.READ)));
145
+ result.push(...chunk.filter((_uid, j) => permitted[j]));
146
+ }
147
+ return result;
148
+ }
149
+ /**
150
+ * The subset of `folderUids` whose change stream has a row the device hasn't synced yet (after its collection's
151
+ * recorded cursor, other than the device's own writes). A failed lookup counts as "no pending change".
152
+ *
153
+ * Batched, so a `Ping` watching hundreds of folders costs a handful of queries rather than three per folder: every
154
+ * folder's `EasCollectionState` is read in one `in(...)` query per `STATE_LOOKUP_CHUNK`, and each collection class's
155
+ * folders are checked together (`pendingInClass()`); only a folder that batch can't decide is scanned on its own.
156
+ */
157
+ async pendingChanges(ctx, folderUids) {
158
+ if (!this.collectionStateRepo) {
93
159
  return [];
94
160
  }
95
- const client = createClient({ url: this.redisConfig.url });
96
- await client.connect();
161
+ let states;
97
162
  try {
98
- return await new Promise((resolve) => {
99
- let settled = false;
100
- const timer = setTimeout(() => {
101
- if (!settled) {
102
- settled = true;
103
- resolve([]);
104
- }
105
- }, timeoutSeconds * 1000);
106
- client
107
- .subscribe(folderUids, (_message, channel) => {
108
- if (!settled) {
109
- settled = true;
110
- clearTimeout(timer);
111
- resolve([channel]);
112
- }
113
- })
114
- .catch(() => {
115
- if (!settled) {
116
- settled = true;
117
- clearTimeout(timer);
118
- resolve([]);
163
+ states = await this.loadStates(ctx, folderUids);
164
+ }
165
+ catch {
166
+ return [];
167
+ }
168
+ const byClass = new Map();
169
+ for (const folderUid of folderUids) {
170
+ const state = states.get(folderUid);
171
+ if (state && this.repos.has(state.collectionClass)) {
172
+ byClass.set(state.collectionClass, [...(byClass.get(state.collectionClass) ?? []), state]);
173
+ }
174
+ }
175
+ const changed = new Set();
176
+ for (const [collectionClass, classStates] of byClass) {
177
+ for (let i = 0; i < classStates.length; i += STATE_LOOKUP_CHUNK) {
178
+ const found = await this.pendingInClass(this.repos.get(collectionClass), classStates.slice(i, i + STATE_LOOKUP_CHUNK)).catch(() => []);
179
+ found.forEach((uid) => changed.add(uid));
180
+ }
181
+ }
182
+ return folderUids.filter((uid) => changed.has(uid));
183
+ }
184
+ /** Every requested folder's collection state for this device, keyed by folder uid - one query per chunk of plain
185
+ * folder uids (exact-matched in memory), and one query per folder uid that can't be listed in `in(...)`. */
186
+ async loadStates(ctx, folderUids) {
187
+ const wanted = new Set(folderUids);
188
+ const states = new Map();
189
+ const keep = (rows) => {
190
+ for (const row of rows) {
191
+ if (wanted.has(row.folderUid) && row.mailboxUid === ctx.mailboxUid && row.deviceId === ctx.deviceId && !states.has(row.folderUid)) {
192
+ states.set(row.folderUid, row);
193
+ }
194
+ }
195
+ };
196
+ const listable = folderUids.filter(isListableUid);
197
+ for (let i = 0; i < listable.length; i += STATE_LOOKUP_CHUNK) {
198
+ const chunk = listable.slice(i, i + STATE_LOOKUP_CHUNK);
199
+ const limit = Math.min(chunk.length * 2, 1000);
200
+ keep(await this.collectionStateRepo.find({ mailboxUid: ctx.mailboxUid, deviceId: ctx.deviceId, folderUid: `in(${chunk.join(",")})`, limit }, { ignoreACL: true, limit }));
201
+ }
202
+ for (const folderUid of folderUids.filter((uid) => !isListableUid(uid))) {
203
+ keep(await this.collectionStateRepo.find({ mailboxUid: ctx.mailboxUid, deviceId: ctx.deviceId, folderUid }, { ignoreACL: true, limit: 1 }));
204
+ }
205
+ return states;
206
+ }
207
+ /**
208
+ * The folders among `states` (all of one collection class, stored in `repo`) with a pending change. One pair of
209
+ * queries (live and soft-deleted rows) reads, across all of them, the rows at or after the earliest cursor, in
210
+ * stream order, up to `PENDING_BATCH_ROW_LIMIT`. When neither page is full, that is every row that could be pending
211
+ * for any of the folders, so each folder is decided exactly in memory - the same rule as a per-folder `scanAfter()`.
212
+ * When a page is full, a folder with a pending row among the rows read is still pending; any other folder is scanned
213
+ * on its own, as before. A folder uid that can't be listed in `in(...)` is always scanned on its own.
214
+ */
215
+ async pendingInClass(repo, states) {
216
+ const cursorFor = (state) => ({ date: new Date(state.cursorDate), uid: state.cursorUid });
217
+ const isPending = (state, rows, complete) => {
218
+ const echoes = state.echoes ?? {};
219
+ const after = rows.filter((row) => row.folderUid === state.folderUid && compareCursor(cursorOf(row), cursorFor(state)) > 0);
220
+ if (after.length > PENDING_CHANGE_SCAN_LIMIT || after.some((row) => echoes[row.uid] !== new Date(row.dateModified).toISOString())) {
221
+ return true;
222
+ }
223
+ return complete ? false : undefined;
224
+ };
225
+ const listed = states.filter((state) => isListableUid(state.folderUid));
226
+ let rows = [];
227
+ let complete = false;
228
+ if (listed.length > 0) {
229
+ const earliest = new Date(Math.min(...listed.map((state) => new Date(state.cursorDate).getTime())));
230
+ const query = {
231
+ folderUid: `in(${listed.map((state) => state.folderUid).join(",")})`,
232
+ dateModified: `gte(${earliest.toISOString()})`,
233
+ sort: PENDING_BATCH_SORT,
234
+ limit: PENDING_BATCH_ROW_LIMIT + 1,
235
+ };
236
+ const options = { ignoreACL: true, limit: PENDING_BATCH_ROW_LIMIT + 1 };
237
+ const [live, deleted] = await Promise.all([repo.find(query, options), repo.find({ ...query, deleted: true }, options)]);
238
+ rows = [...live, ...deleted];
239
+ complete = live.length <= PENDING_BATCH_ROW_LIMIT && deleted.length <= PENDING_BATCH_ROW_LIMIT;
240
+ }
241
+ const decided = states.map((state) => (isListableUid(state.folderUid) ? isPending(state, rows, complete) : undefined));
242
+ // Undecided folders fall back to their own scan, `FALLBACK_SCAN_CHUNK_SIZE` at a time rather than one by one.
243
+ const undecided = decided.flatMap((pending, index) => (pending === undefined ? [index] : []));
244
+ for (let i = 0; i < undecided.length; i += FALLBACK_SCAN_CHUNK_SIZE) {
245
+ await Promise.all(undecided.slice(i, i + FALLBACK_SCAN_CHUNK_SIZE).map(async (index) => {
246
+ const state = states[index];
247
+ const scanned = await scanAfter(repo, { folderUid: state.folderUid }, cursorFor(state), PENDING_CHANGE_SCAN_LIMIT);
248
+ decided[index] = isPending(state, scanned.rows, true) || scanned.more;
249
+ }));
250
+ }
251
+ return states.filter((_state, index) => decided[index]).map((state) => state.folderUid);
252
+ }
253
+ /** Returns the process-wide subscriber client for `url`, connecting it on first use. A failed connect is
254
+ * evicted from the cache (and the client destroyed) so a later call retries. */
255
+ static getSubscriber(url) {
256
+ let pending = PingCommand.subscribers.get(url);
257
+ if (!pending) {
258
+ const client = createClient({ url });
259
+ // An unhandled `error` event would crash the process; the client reconnects on its own.
260
+ client.on("error", () => undefined);
261
+ const connecting = client.connect().then(() => client);
262
+ connecting.catch(() => {
263
+ if (PingCommand.subscribers.get(url) === connecting) {
264
+ PingCommand.subscribers.delete(url);
265
+ }
266
+ try {
267
+ client.destroy();
268
+ }
269
+ catch {
270
+ // ignored
271
+ }
272
+ });
273
+ PingCommand.subscribers.set(url, connecting);
274
+ pending = connecting;
275
+ }
276
+ return pending;
277
+ }
278
+ /** Waits up to `timeoutSeconds` for a publish on any of `folderUids`, resolving with the channel that changed,
279
+ * or `[]` on timeout, supersede by a newer `Ping` from the same device, request close, or Redis being
280
+ * unavailable (in which case the full heartbeat is still waited). */
281
+ waitForChange(ctx, folderUids, timeoutSeconds) {
282
+ const key = JSON.stringify([ctx.mailboxUid, ctx.deviceId]);
283
+ const redisUrl = this.redisConfig ? this.redisConfig.url : undefined;
284
+ return new Promise((resolve) => {
285
+ let settled = false;
286
+ let unsubscribe;
287
+ const finish = (changed) => {
288
+ if (settled) {
289
+ return;
290
+ }
291
+ settled = true;
292
+ clearTimeout(timer);
293
+ if (PingCommand.activePings.get(key) === cancel) {
294
+ PingCommand.activePings.delete(key);
295
+ }
296
+ if (unsubscribe) {
297
+ void unsubscribe();
298
+ }
299
+ resolve(changed);
300
+ };
301
+ const cancel = () => finish([]);
302
+ const checkPending = () => {
303
+ void this.pendingChanges(ctx, folderUids).then((changed) => {
304
+ if (changed.length > 0) {
305
+ finish(changed);
119
306
  }
120
307
  });
308
+ };
309
+ PingCommand.activePings.get(key)?.();
310
+ PingCommand.activePings.set(key, cancel);
311
+ const timer = setTimeout(cancel, timeoutSeconds * 1000);
312
+ ctx.res?.onFinish(cancel);
313
+ if (redisUrl === undefined) {
314
+ checkPending();
315
+ return;
316
+ }
317
+ const listener = (_message, channel) => finish([channel]);
318
+ PingCommand.getSubscriber(redisUrl)
319
+ .then(async (client) => {
320
+ if (settled) {
321
+ return;
322
+ }
323
+ const release = () => client.unsubscribe(folderUids, listener).catch(() => undefined);
324
+ try {
325
+ await client.subscribe(folderUids, listener);
326
+ }
327
+ catch {
328
+ // Fail open: keep waiting out the heartbeat, just without notifications.
329
+ }
330
+ if (settled) {
331
+ // Settled while the subscribe was in flight - `finish()` had nothing to release yet.
332
+ await release();
333
+ }
334
+ else {
335
+ unsubscribe = release;
336
+ // Subscribed: every later change is published to the listener, so this covers the ones before.
337
+ checkPending();
338
+ }
339
+ })
340
+ .catch(() => {
341
+ // Connect failed - fail open, the timer/cancel still answers Status 1.
342
+ checkPending();
121
343
  });
122
- }
123
- finally {
124
- await client.unsubscribe(folderUids).catch(() => undefined);
125
- await client.disconnect().catch(() => undefined);
126
- }
344
+ });
127
345
  }
128
346
  }
347
+ /** Shared subscriber connections, keyed by Redis URL - each value resolves once that client is connected. */
348
+ PingCommand.subscribers = new Map();
349
+ /** The cancel function of the currently active `Ping` for each (mailbox, device) pair. */
350
+ PingCommand.activePings = new Map();
129
351
  __decorate([
130
352
  Config("datastores:events", null),
131
353
  __metadata("design:type", Object)
@@ -138,8 +360,18 @@ __decorate([
138
360
  Config("mail:eas:ping_max_heartbeat_seconds", 1740),
139
361
  __metadata("design:type", Number)
140
362
  ], PingCommand.prototype, "maxHeartbeatSeconds", void 0);
363
+ __decorate([
364
+ Config("mail:eas:ping_max_folders", 300),
365
+ __metadata("design:type", Number)
366
+ ], PingCommand.prototype, "maxFolders", void 0);
141
367
  __decorate([
142
368
  Inject(ACLUtils),
143
369
  __metadata("design:type", ACLUtils)
144
370
  ], PingCommand.prototype, "aclUtils", void 0);
371
+ __decorate([
372
+ Init,
373
+ __metadata("design:type", Function),
374
+ __metadata("design:paramtypes", []),
375
+ __metadata("design:returntype", Promise)
376
+ ], PingCommand.prototype, "init", null);
145
377
  //# sourceMappingURL=PingCommand.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PingCommand.js","sourceRoot":"","sources":["../../../src/commands/PingCommand.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PingCommand.js","sourceRoot":"","sources":["../../../src/commands/PingCommand.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,8 @@ import { childText, element, findChild, textElement } from "../codec/WbxmlElemen
18
18
  import { persistDeviceSyncState } from "../EasSyncKeyUtils.js";
19
19
  const { Config } = ObjectDecorators;
20
20
  const DEFAULT_POLICY_TYPE = "MS-EAS-Provisioning-WBXML";
21
+ /** [MS-ASCMD] common status 129 (DeviceIsBlockedForThisUser). */
22
+ const STATUS_DEVICE_BLOCKED = "129";
21
23
  /**
22
24
  * Handles the two-request EAS `Provision` handshake (MS-ASPROV) every client must complete before any other
23
25
  * command is honored (see `BaseEasRoute`'s provisioning gate), plus the three-step `RemoteWipe` sub-flow that
@@ -33,19 +35,25 @@ const DEFAULT_POLICY_TYPE = "MS-EAS-Provisioning-WBXML";
33
35
  * no way for the server to inspect device state directly either).
34
36
  *
35
37
  * - **Request 1** (no `PolicyKey` in the body): mint a new policy key, store it on `DeviceSyncState` (not yet
36
- * provisioned), and send back the policy document under that key. If a `RemoteWipe` was requested for this
37
- * device (`DeviceSyncState.remoteWipeRequested`, set by an admin - see the remote-wipe route), skip normal
38
- * policy issuance entirely and send the `RemoteWipe` directive instead.
38
+ * provisioned), and send back the policy document under that key.
39
39
  * - **Request 2** (client echoes the `PolicyKey` back, acknowledging the policy): if the key matches what was
40
40
  * minted in request 1 *and* the client's own `Status` is `1`, mark the device provisioned and re-confirm the
41
41
  * same key; anything else (a stale/replayed key, a device that never actually saw request 1's response, or a
42
42
  * device reporting it could not comply) is rejected without provisioning.
43
+ * - **While a wipe is pending**, every other Provision request (a policy request *or* an acknowledgement of an
44
+ * older key) gets the `RemoteWipe` directive and never provisions. Requesting the wipe also clears the stored
45
+ * policy key (`BaseDeviceSyncStateRoute.remoteWipe`), and `BaseEasRoute` refuses any command whose presented
46
+ * `X-MS-PolicyKey` doesn't match the stored key, so a device can't keep syncing on its old key.
43
47
  * - **RemoteWipe acknowledgement**: after wiping itself, a device sends a bare `<Provision><RemoteWipe>
44
48
  * <Status>1</Status></RemoteWipe></Provision>` (no `Policies`). Detected first, ahead of the normal
45
- * issue/acknowledge branching. Clears `remoteWipeRequested` and stamps `remoteWipeAcknowledgedAt` for audit,
46
- * but deliberately leaves `provisioned` untouched (`false`, from when the wipe was requested) - the device
47
- * must complete a genuine fresh Provision handshake to re-add the account, it does not fall straight back into
48
- * "provisioned". `remoteWipeAccountOnly` is recorded for admin audit only; the wire directive sent to the
49
+ * issue/acknowledge branching, and ignored (Status 2) unless a wipe is actually pending. Clears `remoteWipeRequested`,
50
+ * stamps `remoteWipeAcknowledgedAt` for audit and sets `blocked`, leaving `provisioned` `false`.
51
+ * - **A blocked device** (one that acknowledged a wipe) is refused every Provision request with Status 129
52
+ * (DeviceIsBlockedForThisUser) - and `BaseEasRoute` refuses its other commands - until an administrator clears the
53
+ * flag (`BaseDeviceSyncStateRoute.unblock`). Otherwise a device (or whoever holds it) could acknowledge the wipe
54
+ * without wiping anything and simply provision again. The block (like the wipe itself) is keyed on the client-supplied
55
+ * `DeviceId`: a client that ignores the directive can pair again under another `DeviceId` with the same credentials -
56
+ * see `DeviceSyncState.blocked`; revoking the account's credentials is what stops that. `remoteWipeAccountOnly` is recorded for admin audit only; the wire directive sent to the
49
57
  * device is identical either way (a real "wipe just this account's data" vs. "wipe the whole device"
50
58
  * distinction would require an MDM-capable client extension this library doesn't implement).
51
59
  *
@@ -61,9 +69,20 @@ export class ProvisionCommand {
61
69
  this.allowSimplePassword = false;
62
70
  }
63
71
  async handle(ctx) {
72
+ if (ctx.deviceSyncState.blocked) {
73
+ return element(WbxmlCodePage.Provision, "Provision", [textElement(WbxmlCodePage.Provision, "Status", STATUS_DEVICE_BLOCKED)]);
74
+ }
64
75
  if (ctx.request && findChild(ctx.request, "RemoteWipe")) {
65
76
  return await this.acknowledgeRemoteWipe(ctx);
66
77
  }
78
+ // While a wipe is pending, no Provision request - neither a fresh policy request nor an acknowledgement of a
79
+ // key issued before the wipe was requested - may (re)provision the device: every one gets the directive.
80
+ if (ctx.deviceSyncState.remoteWipeRequested) {
81
+ return element(WbxmlCodePage.Provision, "Provision", [
82
+ textElement(WbxmlCodePage.Provision, "Status", "1"),
83
+ element(WbxmlCodePage.Provision, "RemoteWipe", [textElement(WbxmlCodePage.Provision, "Status", "1")]),
84
+ ]);
85
+ }
67
86
  const policiesEl = ctx.request ? findChild(ctx.request, "Policies") : undefined;
68
87
  const policyEl = policiesEl ? findChild(policiesEl, "Policy") : undefined;
69
88
  const policyType = (policyEl ? childText(policyEl, "PolicyType") : undefined) ?? DEFAULT_POLICY_TYPE;
@@ -74,15 +93,8 @@ export class ProvisionCommand {
74
93
  }
75
94
  return await this.acknowledgePolicy(ctx, policyType, clientPolicyKey, clientStatus);
76
95
  }
77
- /** Request 1: mint and store a new policy key, send the policy document - or, if a remote wipe is
78
- * pending for this device, the `RemoteWipe` directive instead. */
96
+ /** Request 1: mint and store a new policy key and send the policy document. */
79
97
  async issuePolicy(ctx, policyType) {
80
- if (ctx.deviceSyncState.remoteWipeRequested) {
81
- return element(WbxmlCodePage.Provision, "Provision", [
82
- textElement(WbxmlCodePage.Provision, "Status", "1"),
83
- element(WbxmlCodePage.Provision, "RemoteWipe", [textElement(WbxmlCodePage.Provision, "Status", "1")]),
84
- ]);
85
- }
86
98
  const policyKey = crypto.randomBytes(8).toString("hex");
87
99
  await this.persist(ctx, { policyKey, provisioned: false });
88
100
  return element(WbxmlCodePage.Provision, "Provision", [
@@ -128,12 +140,17 @@ export class ProvisionCommand {
128
140
  ]),
129
141
  ]);
130
142
  }
131
- /** The device has wiped itself and is acknowledging - clear the pending flag but leave `provisioned`
132
- * alone (still `false`, from when the wipe was requested) so a genuine re-provision is required. */
143
+ /** The device has wiped itself and is acknowledging - clear the pending flag and block the device until an
144
+ * administrator unblocks it; `provisioned` stays `false` (from when the wipe was requested). */
133
145
  async acknowledgeRemoteWipe(ctx) {
146
+ // Only a wipe that was actually requested can be acknowledged; an unsolicited acknowledgement changes nothing.
147
+ if (!ctx.deviceSyncState.remoteWipeRequested) {
148
+ return element(WbxmlCodePage.Provision, "Provision", [textElement(WbxmlCodePage.Provision, "Status", "2")]);
149
+ }
134
150
  await persistDeviceSyncState(ctx.deviceSyncState, ctx.deviceSyncStateRepo, {
135
151
  remoteWipeRequested: false,
136
152
  remoteWipeAcknowledgedAt: new Date(),
153
+ blocked: true,
137
154
  });
138
155
  return element(WbxmlCodePage.Provision, "Provision", [textElement(WbxmlCodePage.Provision, "Status", "1")]);
139
156
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ProvisionCommand.js","sourceRoot":"","sources":["../../../src/commands/ProvisionCommand.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ProvisionCommand.js","sourceRoot":"","sources":["../../../src/commands/ProvisionCommand.ts"],"names":[],"mappings":";;;;;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAqB,MAAM,0BAA0B,CAAC;AACzG,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC;AAEpC,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AAExD,iEAAiE;AACjE,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,OAAO,gBAAgB;IAA7B;QACoB,YAAO,GAAG,WAAW,CAAC;QAG9B,oBAAe,GAAY,IAAI,CAAC;QAGhC,sBAAiB,GAAW,CAAC,CAAC;QAG9B,sBAAiB,GAAW,CAAC,CAAC;QAG9B,4BAAuB,GAAY,IAAI,CAAC;QAGxC,wBAAmB,GAAY,KAAK,CAAC;IAsHjD,CAAC;IApHU,KAAK,CAAC,MAAM,CAAC,GAAsB;QACtC,IAAI,GAAG,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAClI,CAAC;QACD,IAAI,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;YACtD,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;QACjD,CAAC;QAED,6GAA6G;QAC7G,yGAAyG;QACzG,IAAI,GAAG,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC;YAC1C,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE;gBACjD,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC;gBACnD,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;aACxG,CAAC,CAAC;QACP,CAAC;QAED,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChF,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1E,MAAM,UAAU,GAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,mBAAmB,CAAC;QAC7G,MAAM,eAAe,GAAuB,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpG,MAAM,YAAY,GAAuB,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE9F,IAAI,CAAC,eAAe,EAAE,CAAC;YACnB,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;IACxF,CAAC;IAED,+EAA+E;IACvE,KAAK,CAAC,WAAW,CAAC,GAAsB,EAAE,UAAkB;QAChE,MAAM,SAAS,GAAW,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;QAE3D,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE;YACjD,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC;YACnD,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE;gBACzC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE;oBACvC,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC;oBAC9D,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC;oBACnD,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,CAAC;oBAC5D,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE;wBACrC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE;4BAChD,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,uBAAuB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;4BAC/F,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,yBAAyB,EAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;4BAC/F,WAAW,CACP,aAAa,CAAC,SAAS,EACvB,iCAAiC,EACjC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CACjC;4BACD,WAAW,CACP,aAAa,CAAC,SAAS,EACvB,2BAA2B,EAC3B,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CACvC;4BACD,WAAW,CACP,aAAa,CAAC,SAAS,EACvB,yBAAyB,EACzB,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAC3C;4BACD,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,oBAAoB,EAAE,GAAG,CAAC;yBAClE,CAAC;qBACL,CAAC;iBACL,CAAC;aACL,CAAC;SACL,CAAC,CAAC;IACP,CAAC;IAED;8DAC0D;IAClD,KAAK,CAAC,iBAAiB,CAC3B,GAAsB,EACtB,UAAkB,EAClB,eAAuB,EACvB,YAAgC;QAEhC,IAAI,eAAe,KAAK,GAAG,CAAC,eAAe,CAAC,SAAS,IAAI,YAAY,KAAK,GAAG,EAAE,CAAC;YAC5E,gGAAgG;YAChG,kGAAkG;YAClG,iGAAiG;YACjG,mFAAmF;YACnF,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAChH,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3E,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE;YACjD,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC;YACnD,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE;gBACzC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE;oBACvC,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC;oBAC9D,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC;oBACnD,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,eAAe,CAAC;iBACrE,CAAC;aACL,CAAC;SACL,CAAC,CAAC;IACP,CAAC;IAED;oGACgG;IACxF,KAAK,CAAC,qBAAqB,CAAC,GAAsB;QACtD,+GAA+G;QAC/G,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,sBAAsB,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,mBAAmB,EAAE;YACvE,mBAAmB,EAAE,KAAK;YAC1B,wBAAwB,EAAE,IAAI,IAAI,EAAE;YACpC,OAAO,EAAE,IAAI;SAChB,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAChH,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,GAAsB,EAAE,OAAoD;QAC9F,MAAM,sBAAsB,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACxF,CAAC;CACJ;AAlIW;IADP,MAAM,CAAC,qCAAqC,EAAE,IAAI,CAAC;;yDACZ;AAGhC;IADP,MAAM,CAAC,wCAAwC,EAAE,CAAC,CAAC;;2DACd;AAG9B;IADP,MAAM,CAAC,wCAAwC,EAAE,CAAC,CAAC;;2DACd;AAG9B;IADP,MAAM,CAAC,8CAA8C,EAAE,IAAI,CAAC;;iEACb;AAGxC;IADP,MAAM,CAAC,0CAA0C,EAAE,KAAK,CAAC;;6DACb"}