@rapidmx/mapi-plugin 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 (180) hide show
  1. package/LICENSE +382 -0
  2. package/README.md +60 -0
  3. package/dist/lib/BaseMapiEmsmdbRoute.js +297 -0
  4. package/dist/lib/BaseMapiEmsmdbRoute.js.map +1 -0
  5. package/dist/lib/BaseMapiNspiRoute.js +114 -0
  6. package/dist/lib/BaseMapiNspiRoute.js.map +1 -0
  7. package/dist/lib/MapiSessionManager.js +119 -0
  8. package/dist/lib/MapiSessionManager.js.map +1 -0
  9. package/dist/lib/RopDispatcher.js +34 -0
  10. package/dist/lib/RopDispatcher.js.map +1 -0
  11. package/dist/lib/codec/AppointmentRecurrence.js +314 -0
  12. package/dist/lib/codec/AppointmentRecurrence.js.map +1 -0
  13. package/dist/lib/codec/BufferCursor.js +213 -0
  14. package/dist/lib/codec/BufferCursor.js.map +1 -0
  15. package/dist/lib/codec/GlobalObjectId.js +92 -0
  16. package/dist/lib/codec/GlobalObjectId.js.map +1 -0
  17. package/dist/lib/codec/MapiGuid.js +41 -0
  18. package/dist/lib/codec/MapiGuid.js.map +1 -0
  19. package/dist/lib/codec/MapiTimeZone.js +93 -0
  20. package/dist/lib/codec/MapiTimeZone.js.map +1 -0
  21. package/dist/lib/codec/PropertyValue.js +214 -0
  22. package/dist/lib/codec/PropertyValue.js.map +1 -0
  23. package/dist/lib/codec/RopBuffer.js +26 -0
  24. package/dist/lib/codec/RopBuffer.js.map +1 -0
  25. package/dist/lib/codec/TypedString.js +54 -0
  26. package/dist/lib/codec/TypedString.js.map +1 -0
  27. package/dist/lib/index.js +99 -0
  28. package/dist/lib/index.js.map +1 -0
  29. package/dist/lib/mongo/MapiEmsmdbRouteMongo.js +84 -0
  30. package/dist/lib/mongo/MapiEmsmdbRouteMongo.js.map +1 -0
  31. package/dist/lib/mongo/MapiNspiRouteMongo.js +33 -0
  32. package/dist/lib/mongo/MapiNspiRouteMongo.js.map +1 -0
  33. package/dist/lib/mongo/index.js +7 -0
  34. package/dist/lib/mongo/index.js.map +1 -0
  35. package/dist/lib/mongo.js +6 -0
  36. package/dist/lib/mongo.js.map +1 -0
  37. package/dist/lib/nspi/NspiBindHandler.js +54 -0
  38. package/dist/lib/nspi/NspiBindHandler.js.map +1 -0
  39. package/dist/lib/nspi/NspiCodec.js +106 -0
  40. package/dist/lib/nspi/NspiCodec.js.map +1 -0
  41. package/dist/lib/nspi/NspiGetMatchesHandler.js +142 -0
  42. package/dist/lib/nspi/NspiGetMatchesHandler.js.map +1 -0
  43. package/dist/lib/rop/CalendarEventTarget.js +27 -0
  44. package/dist/lib/rop/CalendarEventTarget.js.map +1 -0
  45. package/dist/lib/rop/CalendarNamedProperties.js +57 -0
  46. package/dist/lib/rop/CalendarNamedProperties.js.map +1 -0
  47. package/dist/lib/rop/ContactTarget.js +23 -0
  48. package/dist/lib/rop/ContactTarget.js.map +1 -0
  49. package/dist/lib/rop/FastTransferStream.js +98 -0
  50. package/dist/lib/rop/FastTransferStream.js.map +1 -0
  51. package/dist/lib/rop/FolderTarget.js +111 -0
  52. package/dist/lib/rop/FolderTarget.js.map +1 -0
  53. package/dist/lib/rop/MeetingMessageClassHandler.js +95 -0
  54. package/dist/lib/rop/MeetingMessageClassHandler.js.map +1 -0
  55. package/dist/lib/rop/MessageBodyStream.js +42 -0
  56. package/dist/lib/rop/MessageBodyStream.js.map +1 -0
  57. package/dist/lib/rop/MessageTarget.js +44 -0
  58. package/dist/lib/rop/MessageTarget.js.map +1 -0
  59. package/dist/lib/rop/NamedPropertyRegistry.js +66 -0
  60. package/dist/lib/rop/NamedPropertyRegistry.js.map +1 -0
  61. package/dist/lib/rop/PropertyResolvers.js +313 -0
  62. package/dist/lib/rop/PropertyResolvers.js.map +1 -0
  63. package/dist/lib/rop/RopCreateMessageHandler.js +53 -0
  64. package/dist/lib/rop/RopCreateMessageHandler.js.map +1 -0
  65. package/dist/lib/rop/RopDeleteFolderHandler.js +133 -0
  66. package/dist/lib/rop/RopDeleteFolderHandler.js.map +1 -0
  67. package/dist/lib/rop/RopDeleteMessagesHandler.js +70 -0
  68. package/dist/lib/rop/RopDeleteMessagesHandler.js.map +1 -0
  69. package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js +61 -0
  70. package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js.map +1 -0
  71. package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js +61 -0
  72. package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js.map +1 -0
  73. package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js +75 -0
  74. package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js.map +1 -0
  75. package/dist/lib/rop/RopGetContentsTableHandler.js +76 -0
  76. package/dist/lib/rop/RopGetContentsTableHandler.js.map +1 -0
  77. package/dist/lib/rop/RopGetHierarchyTableHandler.js +40 -0
  78. package/dist/lib/rop/RopGetHierarchyTableHandler.js.map +1 -0
  79. package/dist/lib/rop/RopGetPropertiesSpecificHandler.js +55 -0
  80. package/dist/lib/rop/RopGetPropertiesSpecificHandler.js.map +1 -0
  81. package/dist/lib/rop/RopGetPropertyIdsFromNamesHandler.js +92 -0
  82. package/dist/lib/rop/RopGetPropertyIdsFromNamesHandler.js.map +1 -0
  83. package/dist/lib/rop/RopHandler.js +2 -0
  84. package/dist/lib/rop/RopHandler.js.map +1 -0
  85. package/dist/lib/rop/RopLogonHandler.js +132 -0
  86. package/dist/lib/rop/RopLogonHandler.js.map +1 -0
  87. package/dist/lib/rop/RopOpenFolderHandler.js +46 -0
  88. package/dist/lib/rop/RopOpenFolderHandler.js.map +1 -0
  89. package/dist/lib/rop/RopOpenMessageHandler.js +81 -0
  90. package/dist/lib/rop/RopOpenMessageHandler.js.map +1 -0
  91. package/dist/lib/rop/RopOpenStreamHandler.js +81 -0
  92. package/dist/lib/rop/RopOpenStreamHandler.js.map +1 -0
  93. package/dist/lib/rop/RopQueryRowsHandler.js +91 -0
  94. package/dist/lib/rop/RopQueryRowsHandler.js.map +1 -0
  95. package/dist/lib/rop/RopReadStreamHandler.js +55 -0
  96. package/dist/lib/rop/RopReadStreamHandler.js.map +1 -0
  97. package/dist/lib/rop/RopReleaseHandler.js +20 -0
  98. package/dist/lib/rop/RopReleaseHandler.js.map +1 -0
  99. package/dist/lib/rop/RopSaveChangesMessageHandler.js +210 -0
  100. package/dist/lib/rop/RopSaveChangesMessageHandler.js.map +1 -0
  101. package/dist/lib/rop/RopSetColumnsHandler.js +52 -0
  102. package/dist/lib/rop/RopSetColumnsHandler.js.map +1 -0
  103. package/dist/lib/rop/RopSetPropertiesHandler.js +162 -0
  104. package/dist/lib/rop/RopSetPropertiesHandler.js.map +1 -0
  105. package/dist/lib/rop/RopSubmitMessageHandler.js +314 -0
  106. package/dist/lib/rop/RopSubmitMessageHandler.js.map +1 -0
  107. package/dist/lib/rop/RopWriteStreamHandler.js +45 -0
  108. package/dist/lib/rop/RopWriteStreamHandler.js.map +1 -0
  109. package/dist/lib/rop/TaskNamedProperties.js +29 -0
  110. package/dist/lib/rop/TaskNamedProperties.js.map +1 -0
  111. package/dist/lib/rop/TaskTarget.js +19 -0
  112. package/dist/lib/rop/TaskTarget.js.map +1 -0
  113. package/dist/lib/sql/MapiEmsmdbRouteSQL.js +84 -0
  114. package/dist/lib/sql/MapiEmsmdbRouteSQL.js.map +1 -0
  115. package/dist/lib/sql/MapiNspiRouteSQL.js +33 -0
  116. package/dist/lib/sql/MapiNspiRouteSQL.js.map +1 -0
  117. package/dist/lib/sql/index.js +7 -0
  118. package/dist/lib/sql/index.js.map +1 -0
  119. package/dist/lib/sql.js +6 -0
  120. package/dist/lib/sql.js.map +1 -0
  121. package/dist/types/BaseMapiEmsmdbRoute.d.ts +82 -0
  122. package/dist/types/BaseMapiNspiRoute.d.ts +38 -0
  123. package/dist/types/MapiSessionManager.d.ts +130 -0
  124. package/dist/types/RopDispatcher.d.ts +17 -0
  125. package/dist/types/codec/AppointmentRecurrence.d.ts +14 -0
  126. package/dist/types/codec/BufferCursor.d.ts +78 -0
  127. package/dist/types/codec/GlobalObjectId.d.ts +11 -0
  128. package/dist/types/codec/MapiGuid.d.ts +6 -0
  129. package/dist/types/codec/MapiTimeZone.d.ts +7 -0
  130. package/dist/types/codec/PropertyValue.d.ts +77 -0
  131. package/dist/types/codec/RopBuffer.d.ts +25 -0
  132. package/dist/types/codec/TypedString.d.ts +17 -0
  133. package/dist/types/index.d.ts +94 -0
  134. package/dist/types/mongo/MapiEmsmdbRouteMongo.d.ts +19 -0
  135. package/dist/types/mongo/MapiNspiRouteMongo.d.ts +13 -0
  136. package/dist/types/mongo/index.d.ts +2 -0
  137. package/dist/types/mongo.d.ts +1 -0
  138. package/dist/types/nspi/NspiBindHandler.d.ts +22 -0
  139. package/dist/types/nspi/NspiCodec.d.ts +59 -0
  140. package/dist/types/nspi/NspiGetMatchesHandler.d.ts +24 -0
  141. package/dist/types/rop/CalendarEventTarget.d.ts +29 -0
  142. package/dist/types/rop/CalendarNamedProperties.d.ts +37 -0
  143. package/dist/types/rop/ContactTarget.d.ts +29 -0
  144. package/dist/types/rop/FastTransferStream.d.ts +18 -0
  145. package/dist/types/rop/FolderTarget.d.ts +63 -0
  146. package/dist/types/rop/MeetingMessageClassHandler.d.ts +36 -0
  147. package/dist/types/rop/MessageBodyStream.d.ts +26 -0
  148. package/dist/types/rop/MessageTarget.d.ts +38 -0
  149. package/dist/types/rop/NamedPropertyRegistry.d.ts +46 -0
  150. package/dist/types/rop/PropertyResolvers.d.ts +60 -0
  151. package/dist/types/rop/RopCreateMessageHandler.d.ts +23 -0
  152. package/dist/types/rop/RopDeleteFolderHandler.d.ts +38 -0
  153. package/dist/types/rop/RopDeleteMessagesHandler.d.ts +31 -0
  154. package/dist/types/rop/RopFastTransferSourceCopyPropertiesHandler.d.ts +24 -0
  155. package/dist/types/rop/RopFastTransferSourceCopyToHandler.d.ts +24 -0
  156. package/dist/types/rop/RopFastTransferSourceGetBufferHandler.d.ts +23 -0
  157. package/dist/types/rop/RopGetContentsTableHandler.d.ts +31 -0
  158. package/dist/types/rop/RopGetHierarchyTableHandler.d.ts +17 -0
  159. package/dist/types/rop/RopGetPropertiesSpecificHandler.d.ts +23 -0
  160. package/dist/types/rop/RopGetPropertyIdsFromNamesHandler.d.ts +23 -0
  161. package/dist/types/rop/RopHandler.d.ts +67 -0
  162. package/dist/types/rop/RopLogonHandler.d.ts +31 -0
  163. package/dist/types/rop/RopOpenFolderHandler.d.ts +19 -0
  164. package/dist/types/rop/RopOpenMessageHandler.d.ts +27 -0
  165. package/dist/types/rop/RopOpenStreamHandler.d.ts +27 -0
  166. package/dist/types/rop/RopQueryRowsHandler.d.ts +36 -0
  167. package/dist/types/rop/RopReadStreamHandler.d.ts +18 -0
  168. package/dist/types/rop/RopReleaseHandler.d.ts +14 -0
  169. package/dist/types/rop/RopSaveChangesMessageHandler.d.ts +44 -0
  170. package/dist/types/rop/RopSetColumnsHandler.d.ts +21 -0
  171. package/dist/types/rop/RopSetPropertiesHandler.d.ts +38 -0
  172. package/dist/types/rop/RopSubmitMessageHandler.d.ts +70 -0
  173. package/dist/types/rop/RopWriteStreamHandler.d.ts +21 -0
  174. package/dist/types/rop/TaskNamedProperties.d.ts +24 -0
  175. package/dist/types/rop/TaskTarget.d.ts +24 -0
  176. package/dist/types/sql/MapiEmsmdbRouteSQL.d.ts +19 -0
  177. package/dist/types/sql/MapiNspiRouteSQL.d.ts +13 -0
  178. package/dist/types/sql/index.d.ts +2 -0
  179. package/dist/types/sql.d.ts +1 -0
  180. package/package.json +104 -0
@@ -0,0 +1,61 @@
1
+ import { readPropertyTag } from "../codec/PropertyValue.js";
2
+ import { buildFastTransferStream } from "./FastTransferStream.js";
3
+ const ROP_ID_COPY_PROPERTIES = 0x69;
4
+ /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a folder or
5
+ * message (or doesn't exist)" - the same constant `RopGetPropertiesSpecificHandler` uses for its own analogous
6
+ * check. */
7
+ const ERROR_INVALID_OBJECT = 0x80070005;
8
+ /**
9
+ * `RopFastTransferSourceCopyProperties` (`[MS-OXCFXICS]`/`[MS-OXCROPS]`, RopId `0x69`): the explicit-column
10
+ * sibling of `RopFastTransferSourceCopyTo` - `PropertyTags` here is the properties to **copy** (an include
11
+ * list, per `[MS-OXCROPS]`'s own wording, the opposite of `CopyTo`'s exclude list), applied uniformly at both
12
+ * folder- and message-level wherever `FastTransferStream.ts` builds a `propList` - see that file's own doc
13
+ * comment for this pragmatic subset's overall ICS scope. An empty `PropertyTags` list is honored literally
14
+ * (copies zero properties, i.e. empty `propList`s) rather than falling back to `CopyTo`'s own default column
15
+ * set - that fallback belongs to `CopyTo` alone, since an explicit "copy nothing" request here is spec-valid
16
+ * and distinguishable from "use the default set" (`CopyTo` simply has no `PropertyTags`-supplied alternative to
17
+ * fall back from).
18
+ *
19
+ * `Level`/`CopyFlags`/`SendOptions` are decoded to advance the reader correctly but not honored - see
20
+ * `RopFastTransferSourceCopyToHandler`'s own doc comment for the identical reasoning. Note `CopyFlags` here is
21
+ * **1 byte**, not 4 like `CopyTo`'s own field of the same name - confirmed against each ROP's own request-buffer
22
+ * page separately, not assumed identical.
23
+ *
24
+ * @author Jean-Philippe Steinmetz
25
+ */
26
+ export class RopFastTransferSourceCopyPropertiesHandler {
27
+ constructor() {
28
+ this.ropId = ROP_ID_COPY_PROPERTIES;
29
+ }
30
+ async handle(reader, writer, context) {
31
+ reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
32
+ const inputHandleIndex = reader.readUInt8();
33
+ const outputHandleIndex = reader.readUInt8();
34
+ reader.readUInt8(); // Level - subfolder recursion not honored, see class doc comment
35
+ reader.readUInt8(); // CopyFlags (1 byte here, unlike CopyTo's 4) - not honored, see class doc comment
36
+ reader.readUInt8(); // SendOptions - not honored, see class doc comment
37
+ const propertyTagCount = reader.readUInt16LE();
38
+ const columns = [];
39
+ for (let i = 0; i < propertyTagCount; i++) {
40
+ columns.push(readPropertyTag(reader));
41
+ }
42
+ const handle = context.session.handles[inputHandleIndex];
43
+ if (!handle || (handle.type !== "folder" && handle.type !== "message")) {
44
+ writer.writeUInt8(ROP_ID_COPY_PROPERTIES);
45
+ writer.writeUInt8(outputHandleIndex);
46
+ writer.writeUInt32LE(ERROR_INVALID_OBJECT);
47
+ return;
48
+ }
49
+ const transferBuffer = await buildFastTransferStream(handle, context, { columns });
50
+ context.session.handles[outputHandleIndex] = {
51
+ type: "fastTransfer",
52
+ entityUid: handle.entityUid,
53
+ transferBufferBase64: transferBuffer.toString("base64"),
54
+ transferPosition: 0,
55
+ };
56
+ writer.writeUInt8(ROP_ID_COPY_PROPERTIES);
57
+ writer.writeUInt8(outputHandleIndex);
58
+ writer.writeUInt32LE(0); // ReturnValue - success
59
+ }
60
+ }
61
+ //# sourceMappingURL=RopFastTransferSourceCopyPropertiesHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopFastTransferSourceCopyPropertiesHandler.js","sourceRoot":"","sources":["../../../src/rop/RopFastTransferSourceCopyPropertiesHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAEpC;;YAEY;AACZ,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,0CAA0C;IAAvD;QACoB,UAAK,GAAG,sBAAsB,CAAC;IAmCnD,CAAC;IAjCU,KAAK,CAAC,MAAM,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;QAC/E,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,uFAAuF;QAC3G,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,MAAM,iBAAiB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACrD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,iEAAiE;QACrF,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,kFAAkF;QACtG,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,mDAAmD;QACvE,MAAM,gBAAgB,GAAW,MAAM,CAAC,YAAY,EAAE,CAAC;QACvD,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC;YAC1C,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;YACrC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,OAAO;QACX,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACnF,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG;YACzC,IAAI,EAAE,cAAc;YACpB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,oBAAoB,EAAE,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACvD,gBAAgB,EAAE,CAAC;SACtB,CAAC;QAEF,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC;QAC1C,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;QACrC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IACrD,CAAC;CACJ"}
@@ -0,0 +1,61 @@
1
+ import { readPropertyTag } from "../codec/PropertyValue.js";
2
+ import { buildFastTransferStream } from "./FastTransferStream.js";
3
+ const ROP_ID_COPY_TO = 0x4d;
4
+ /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a folder or
5
+ * message (or doesn't exist)" - the same constant `RopGetPropertiesSpecificHandler` uses for its own analogous
6
+ * check. */
7
+ const ERROR_INVALID_OBJECT = 0x80070005;
8
+ /**
9
+ * `RopFastTransferSourceCopyTo` (`[MS-OXCFXICS]`/`[MS-OXCROPS]`, RopId `0x4D`): begins a FastTransfer download
10
+ * of an already-open Folder or Message (or Calendar item, itself a Message object on the wire) object,
11
+ * producing a new `"fastTransfer"` Server object handle `RopFastTransferSourceGetBuffer` pages the built stream
12
+ * out of. See `FastTransferStream.ts`'s own doc comment for this pragmatic subset's "full, non-differential
13
+ * dump" ICS scope and its default property columns.
14
+ *
15
+ * `Level` (whether to recurse into subfolders) is decoded to advance the reader correctly but not honored -
16
+ * this pragmatic subset never recurses into subfolders regardless. `CopyFlags`/`SendOptions` (Move mode, best-
17
+ * body preference, Unicode preference, recoverable-mode, ...) are likewise decoded but not honored - this
18
+ * pragmatic subset always copies (never moves) and always encodes the same way regardless of client
19
+ * preference, matching `RopGetPropertiesSpecificHandler`'s own treatment of its analogous `WantUnicode` field.
20
+ * `PropertyTags` is the properties to *exclude* from the default column set (`[MS-OXCROPS]`'s own wording) -
21
+ * see `FastTransferStream.ts` for why an explicit include list instead is `RopFastTransferSourceCopyProperties`'s
22
+ * own job, not this ROP's.
23
+ *
24
+ * @author Jean-Philippe Steinmetz
25
+ */
26
+ export class RopFastTransferSourceCopyToHandler {
27
+ constructor() {
28
+ this.ropId = ROP_ID_COPY_TO;
29
+ }
30
+ async handle(reader, writer, context) {
31
+ reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
32
+ const inputHandleIndex = reader.readUInt8();
33
+ const outputHandleIndex = reader.readUInt8();
34
+ reader.readUInt8(); // Level - subfolder recursion not honored, see class doc comment
35
+ reader.readUInt32LE(); // CopyFlags - not honored, see class doc comment
36
+ reader.readUInt8(); // SendOptions - not honored, see class doc comment
37
+ const propertyTagCount = reader.readUInt16LE();
38
+ const excludePropertyIds = new Set();
39
+ for (let i = 0; i < propertyTagCount; i++) {
40
+ excludePropertyIds.add(readPropertyTag(reader).propertyId);
41
+ }
42
+ const handle = context.session.handles[inputHandleIndex];
43
+ if (!handle || (handle.type !== "folder" && handle.type !== "message")) {
44
+ writer.writeUInt8(ROP_ID_COPY_TO);
45
+ writer.writeUInt8(outputHandleIndex);
46
+ writer.writeUInt32LE(ERROR_INVALID_OBJECT);
47
+ return;
48
+ }
49
+ const transferBuffer = await buildFastTransferStream(handle, context, { excludePropertyIds });
50
+ context.session.handles[outputHandleIndex] = {
51
+ type: "fastTransfer",
52
+ entityUid: handle.entityUid,
53
+ transferBufferBase64: transferBuffer.toString("base64"),
54
+ transferPosition: 0,
55
+ };
56
+ writer.writeUInt8(ROP_ID_COPY_TO);
57
+ writer.writeUInt8(outputHandleIndex);
58
+ writer.writeUInt32LE(0); // ReturnValue - success
59
+ }
60
+ }
61
+ //# sourceMappingURL=RopFastTransferSourceCopyToHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopFastTransferSourceCopyToHandler.js","sourceRoot":"","sources":["../../../src/rop/RopFastTransferSourceCopyToHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B;;YAEY;AACZ,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,kCAAkC;IAA/C;QACoB,UAAK,GAAG,cAAc,CAAC;IAmC3C,CAAC;IAjCU,KAAK,CAAC,MAAM,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;QAC/E,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,uFAAuF;QAC3G,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,MAAM,iBAAiB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACrD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,iEAAiE;QACrF,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,iDAAiD;QACxE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,mDAAmD;QACvE,MAAM,gBAAgB,GAAW,MAAM,CAAC,YAAY,EAAE,CAAC;QACvD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,kBAAkB,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAClC,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;YACrC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,OAAO;QACX,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC9F,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG;YACzC,IAAI,EAAE,cAAc;YACpB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,oBAAoB,EAAE,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACvD,gBAAgB,EAAE,CAAC;SACtB,CAAC;QAEF,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QAClC,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;QACrC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IACrD,CAAC;CACJ"}
@@ -0,0 +1,75 @@
1
+ const ROP_ID_GET_BUFFER = 0x4e;
2
+ /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a
3
+ * `fastTransfer` handle (or doesn't exist)" - the same constant `RopGetPropertiesSpecificHandler` uses for its
4
+ * own analogous check. */
5
+ const ERROR_INVALID_OBJECT = 0x80070005;
6
+ /** The `BufferSize` sentinel (`[MS-OXCROPS]`'s own documented value) meaning "let the server pick the chunk
7
+ * size". */
8
+ const BUFFER_SIZE_SERVER_DETERMINED = 0xbabe;
9
+ /** The response's own `TransferBufferSize` field is a 16-bit count (`[MS-OXCFXICS]`'s own `RopFastTransferSourceGetBuffer`
10
+ * response-buffer page), so a single call can never actually return more than this many bytes. For the
11
+ * `0xBABE` "server-determined" sentinel this caps what would otherwise be "the entire remaining buffer in one
12
+ * call" (only spec-valid when that buffer happens to fit in a `uint16`) down to the same paging behavior a
13
+ * client-specified `BufferSize` already gets - `writeUInt16LE` throwing `RangeError` for an out-of-range value
14
+ * is not spec-valid for any size of transfer. */
15
+ const MAX_TRANSFER_BUFFER_SIZE = 0xffff;
16
+ /** `TransferStatus` values (`[MS-OXCFXICS]` §2.2.3.1.1.5.2, confirmed this session) - only the two this
17
+ * pragmatic subset (which never errors mid-transfer once a `"fastTransfer"` handle exists, and never returns
18
+ * `NoRoom`) ever produces. */
19
+ const TRANSFER_STATUS_PARTIAL = 0x0001;
20
+ const TRANSFER_STATUS_DONE = 0x0003;
21
+ /**
22
+ * `RopFastTransferSourceGetBuffer` (`[MS-OXCFXICS]`/`[MS-OXCROPS]`, RopId `0x4E`): pages the FastTransfer
23
+ * stream a prior `RopFastTransferSourceCopyTo`/`CopyProperties` built (`FastTransferStream.ts`) out of its
24
+ * `"fastTransfer"` handle, `BufferSize` bytes at a time (or the entire remaining buffer, capped to
25
+ * `MAX_TRANSFER_BUFFER_SIZE`, for the `0xBABE` "server-determined" sentinel - `MaximumBufferSize`, present only
26
+ * in that case, is decoded to advance the reader correctly but not honored, since honoring it would mean
27
+ * returning *more* than one chunk can carry, not less). Reports `Done` once the whole buffer has been returned
28
+ * across one or more calls, `Partial` otherwise - `NoRoom` and `Error` are never produced (a `"fastTransfer"`
29
+ * handle, once created, always has a complete, already-valid buffer to page from).
30
+ *
31
+ * `BackoffTime` is never emitted (this pragmatic subset never returns the one `ReturnValue` that field is
32
+ * conditional on), and the failure path (`ERROR_INVALID_OBJECT`) omits every field after `ReturnValue` entirely
33
+ * - the same "just the fixed header, no success-only tail" shape every other failing handler in this pragmatic
34
+ * subset already uses, not a specific claim about the real spec's own error-path byte layout.
35
+ *
36
+ * @author Jean-Philippe Steinmetz
37
+ */
38
+ export class RopFastTransferSourceGetBufferHandler {
39
+ constructor() {
40
+ this.ropId = ROP_ID_GET_BUFFER;
41
+ }
42
+ handle(reader, writer, context) {
43
+ reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
44
+ const inputHandleIndex = reader.readUInt8();
45
+ const bufferSize = reader.readUInt16LE();
46
+ if (bufferSize === BUFFER_SIZE_SERVER_DETERMINED) {
47
+ reader.readUInt16LE(); // MaximumBufferSize - see class doc comment
48
+ }
49
+ const handle = context.session.handles[inputHandleIndex];
50
+ if (!handle || handle.type !== "fastTransfer") {
51
+ writer.writeUInt8(ROP_ID_GET_BUFFER);
52
+ writer.writeUInt8(inputHandleIndex);
53
+ writer.writeUInt32LE(ERROR_INVALID_OBJECT);
54
+ return;
55
+ }
56
+ const fullBuffer = Buffer.from(handle.transferBufferBase64 ?? "", "base64");
57
+ const position = handle.transferPosition ?? 0;
58
+ const remaining = fullBuffer.length - position;
59
+ const requestedSize = bufferSize === BUFFER_SIZE_SERVER_DETERMINED ? remaining : bufferSize;
60
+ const chunkSize = Math.min(requestedSize, remaining, MAX_TRANSFER_BUFFER_SIZE);
61
+ const chunk = fullBuffer.subarray(position, position + chunkSize);
62
+ handle.transferPosition = position + chunk.length;
63
+ const done = handle.transferPosition >= fullBuffer.length;
64
+ writer.writeUInt8(ROP_ID_GET_BUFFER);
65
+ writer.writeUInt8(inputHandleIndex);
66
+ writer.writeUInt32LE(0); // ReturnValue - success
67
+ writer.writeUInt16LE(done ? TRANSFER_STATUS_DONE : TRANSFER_STATUS_PARTIAL);
68
+ writer.writeUInt16LE(0); // InProgressCount - no real progress tracking in this pragmatic subset
69
+ writer.writeUInt16LE(1); // TotalStepCount - pragmatic constant, only ever used for progress-bar display
70
+ writer.writeUInt8(0); // Reserved
71
+ writer.writeUInt16LE(chunk.length); // TransferBufferSize
72
+ writer.writeBytes(chunk); // TransferBuffer
73
+ }
74
+ }
75
+ //# sourceMappingURL=RopFastTransferSourceGetBufferHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopFastTransferSourceGetBufferHandler.js","sourceRoot":"","sources":["../../../src/rop/RopFastTransferSourceGetBufferHandler.ts"],"names":[],"mappings":"AAOA,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAE/B;;0BAE0B;AAC1B,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;YACY;AACZ,MAAM,6BAA6B,GAAG,MAAM,CAAC;AAE7C;;;;;iDAKiD;AACjD,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAExC;;8BAE8B;AAC9B,MAAM,uBAAuB,GAAG,MAAM,CAAC;AACvC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAEpC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,qCAAqC;IAAlD;QACoB,UAAK,GAAG,iBAAiB,CAAC;IAqC9C,CAAC;IAnCU,MAAM,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;QACzE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,uFAAuF;QAC3G,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,MAAM,UAAU,GAAW,MAAM,CAAC,YAAY,EAAE,CAAC;QACjD,IAAI,UAAU,KAAK,6BAA6B,EAAE,CAAC;YAC/C,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,4CAA4C;QACvE,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC5C,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;YACrC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YACpC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,OAAO;QACX,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5E,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,GAAG,QAAQ,CAAC;QAC/C,MAAM,aAAa,GAAG,UAAU,KAAK,6BAA6B,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QAC5F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,EAAE,wBAAwB,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC;QAClE,MAAM,CAAC,gBAAgB,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,gBAAgB,IAAI,UAAU,CAAC,MAAM,CAAC;QAE1D,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;QACrC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;QACjD,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAC5E,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,uEAAuE;QAChG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,+EAA+E;QACxG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW;QACjC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB;QACzD,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB;IAC/C,CAAC;CACJ"}
@@ -0,0 +1,76 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import { FolderType } from "@rapidmx/restapi";
6
+ import { resolveFolderCalendarEvents } from "./CalendarEventTarget.js";
7
+ import { resolveFolderContacts } from "./ContactTarget.js";
8
+ import { resolveFolderMessages } from "./MessageTarget.js";
9
+ import { resolveFolderTasks } from "./TaskTarget.js";
10
+ const ROP_ID_GET_CONTENTS_TABLE = 0x05;
11
+ /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a folder (or
12
+ * doesn't exist)" - the same constant `RopGetHierarchyTableHandler` uses for its own analogous check. */
13
+ const ERROR_INVALID_OBJECT = 0x80070005;
14
+ /**
15
+ * `RopGetContentsTable` (`[MS-OXCFOLD]`/`[MS-OXCROPS]`): opens a table listing an already-opened folder's
16
+ * messages, producing a new `"table"` Server object handle `RopSetColumns`/`RopQueryRows` reference by
17
+ * `InputHandleIndex` - the exact same request/response shape as `RopGetHierarchyTable` (confirmed identical
18
+ * field-by-field against `[MS-OXCROPS]`'s own request-buffer page, differing only in `RopId`), just listing
19
+ * messages instead of child folders. `RopSetColumns`/`RopQueryRows` themselves need no changes at all to
20
+ * support this - they already operate generically on whatever `rows`/`columns` a table handle carries,
21
+ * dispatching to `FolderTarget`'s or `MessageTarget`'s resolvers by row-target prefix (`"folder:"`/`"virtual:"`
22
+ * vs `"message:"`).
23
+ *
24
+ * A folder's contents table is only ever non-empty for a real folder (`"folder:<uid>"`) - the virtual special
25
+ * folders (`RopLogonHandler`'s own doc comment) have no real backing row to hold messages under, so opening a
26
+ * contents table on one always yields an empty table rather than an error.
27
+ *
28
+ * **Calendar folders** (`Folder.type === FolderType.CALENDAR`) list `"calendarEvent:<uid>"` rows resolved via
29
+ * `calendarEventRepo` instead of `"message:<uid>"` rows - a single table handle only ever holds one kind of
30
+ * row, decided once here by checking the folder's own `type`, exactly the same "resolve by target-string
31
+ * prefix downstream" design `MessageTarget`/`FolderTarget` already use for their own rows. **Contacts and
32
+ * Tasks** folders (`FolderType.CONTACTS`/`TASKS`) list `"contact:<uid>"`/`"task:<uid>"` rows the same way, via
33
+ * `contactRepo`/`taskRepo` - empty (rather than an error) when the context has neither wired up, the same
34
+ * optional-repo degradation `RopContext`'s own doc comment describes.
35
+ *
36
+ * @author Jean-Philippe Steinmetz
37
+ */
38
+ export class RopGetContentsTableHandler {
39
+ constructor() {
40
+ this.ropId = ROP_ID_GET_CONTENTS_TABLE;
41
+ }
42
+ async handle(reader, writer, context) {
43
+ reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
44
+ const inputHandleIndex = reader.readUInt8();
45
+ const outputHandleIndex = reader.readUInt8();
46
+ reader.readUInt8(); // TableFlags - only the Standard (0x00) case is supported; see RopGetHierarchyTableHandler's own doc comment
47
+ const folderHandle = context.session.handles[inputHandleIndex];
48
+ if (!folderHandle || folderHandle.type !== "folder") {
49
+ writer.writeUInt8(ROP_ID_GET_CONTENTS_TABLE);
50
+ writer.writeUInt8(outputHandleIndex);
51
+ writer.writeUInt32LE(ERROR_INVALID_OBJECT);
52
+ return;
53
+ }
54
+ const rows = folderHandle.entityUid.startsWith("folder:")
55
+ ? await this.resolveRows(folderHandle.entityUid.slice("folder:".length), context)
56
+ : [];
57
+ context.session.handles[outputHandleIndex] = { type: "table", entityUid: folderHandle.entityUid, rows, cursor: 0 };
58
+ writer.writeUInt8(ROP_ID_GET_CONTENTS_TABLE);
59
+ writer.writeUInt8(outputHandleIndex);
60
+ writer.writeUInt32LE(0); // ReturnValue - success
61
+ }
62
+ async resolveRows(folderUid, context) {
63
+ const folder = await context.folderRepo.findOne(folderUid, { ignoreACL: true });
64
+ if (folder?.type === FolderType.CALENDAR) {
65
+ return resolveFolderCalendarEvents(folderUid, context.calendarEventRepo);
66
+ }
67
+ if (folder?.type === FolderType.CONTACTS) {
68
+ return context.contactRepo ? resolveFolderContacts(folderUid, context.contactRepo) : [];
69
+ }
70
+ if (folder?.type === FolderType.TASKS) {
71
+ return context.taskRepo ? resolveFolderTasks(folderUid, context.taskRepo) : [];
72
+ }
73
+ return resolveFolderMessages(folderUid, context.messageRepo);
74
+ }
75
+ }
76
+ //# sourceMappingURL=RopGetContentsTableHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopGetContentsTableHandler.js","sourceRoot":"","sources":["../../../src/rop/RopGetContentsTableHandler.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAU,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAEvC;yGACyG;AACzG,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,0BAA0B;IAAvC;QACoB,UAAK,GAAG,yBAAyB,CAAC;IAuCtD,CAAC;IArCU,KAAK,CAAC,MAAM,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;QAC/E,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,uFAAuF;QAC3G,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,MAAM,iBAAiB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACrD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,6GAA6G;QAEjI,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC/D,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;YACrC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,OAAO;QACX,CAAC;QAED,MAAM,IAAI,GAAa,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC;YAC/D,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;YACjF,CAAC,CAAC,EAAE,CAAC;QACT,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAEnH,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC;QAC7C,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;QACrC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IACrD,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,SAAiB,EAAE,OAAmB;QAC5D,MAAM,MAAM,GAAuB,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpG,IAAI,MAAM,EAAE,IAAI,KAAK,UAAU,CAAC,QAAQ,EAAE,CAAC;YACvC,OAAO,2BAA2B,CAAC,SAAS,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC7E,CAAC;QACD,IAAI,MAAM,EAAE,IAAI,KAAK,UAAU,CAAC,QAAQ,EAAE,CAAC;YACvC,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,CAAC;QACD,IAAI,MAAM,EAAE,IAAI,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;YACpC,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,CAAC;QACD,OAAO,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACjE,CAAC;CACJ"}
@@ -0,0 +1,40 @@
1
+ import { resolveFolderChildren } from "./FolderTarget.js";
2
+ const ROP_ID_GET_HIERARCHY_TABLE = 0x04;
3
+ /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a folder
4
+ * (or doesn't exist)". */
5
+ const ERROR_INVALID_OBJECT = 0x80070005;
6
+ /**
7
+ * `RopGetHierarchyTable` (`[MS-OXCFOLD]`/`[MS-OXCROPS]`): opens a table listing an already-opened folder's
8
+ * direct child folders, producing a new `"table"` Server object handle `RopSetColumns`/`RopQueryRows`
9
+ * reference by `InputHandleIndex`. Only `TableFlags = 0x00` ("Standard") is supported - this pragmatic subset
10
+ * has no deferred/async table population, so the immediate-row-count-returning variants some `TableFlags`
11
+ * values request are moot, and the response omits the row-count field those variants add (confirmed absent
12
+ * for the Standard case against `[MS-OXCROPS]`'s own request-buffer page, which explicitly lists `TableFlags`
13
+ * as this ROP's only request payload beyond the common handle-index header).
14
+ *
15
+ * @author Jean-Philippe Steinmetz
16
+ */
17
+ export class RopGetHierarchyTableHandler {
18
+ constructor() {
19
+ this.ropId = ROP_ID_GET_HIERARCHY_TABLE;
20
+ }
21
+ async handle(reader, writer, context) {
22
+ reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
23
+ const inputHandleIndex = reader.readUInt8();
24
+ const outputHandleIndex = reader.readUInt8();
25
+ reader.readUInt8(); // TableFlags - only the Standard (0x00) case is supported; see class doc comment
26
+ const folderHandle = context.session.handles[inputHandleIndex];
27
+ if (!folderHandle || folderHandle.type !== "folder") {
28
+ writer.writeUInt8(ROP_ID_GET_HIERARCHY_TABLE);
29
+ writer.writeUInt8(outputHandleIndex);
30
+ writer.writeUInt32LE(ERROR_INVALID_OBJECT);
31
+ return;
32
+ }
33
+ const rows = await resolveFolderChildren(context.mailboxUid, folderHandle.entityUid, context.folderRepo);
34
+ context.session.handles[outputHandleIndex] = { type: "table", entityUid: folderHandle.entityUid, rows, cursor: 0 };
35
+ writer.writeUInt8(ROP_ID_GET_HIERARCHY_TABLE);
36
+ writer.writeUInt8(outputHandleIndex);
37
+ writer.writeUInt32LE(0); // ReturnValue - success
38
+ }
39
+ }
40
+ //# sourceMappingURL=RopGetHierarchyTableHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopGetHierarchyTableHandler.js","sourceRoot":"","sources":["../../../src/rop/RopGetHierarchyTableHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAExC;0BAC0B;AAC1B,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;;;;;;;;;;GAUG;AACH,MAAM,OAAO,2BAA2B;IAAxC;QACoB,UAAK,GAAG,0BAA0B,CAAC;IAuBvD,CAAC;IArBU,KAAK,CAAC,MAAM,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;QAC/E,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,uFAAuF;QAC3G,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,MAAM,iBAAiB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACrD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,iFAAiF;QAErG,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC/D,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC;YAC9C,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;YACrC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,OAAO;QACX,CAAC;QAED,MAAM,IAAI,GAAa,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACnH,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAEnH,MAAM,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;QACrC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;IACrD,CAAC;CACJ"}
@@ -0,0 +1,55 @@
1
+ import { readPropertyTag, writePropertyValue } from "../codec/PropertyValue.js";
2
+ import { resolvePropertyValues } from "./PropertyResolvers.js";
3
+ const ROP_ID_GET_PROPERTIES_SPECIFIC = 0x07;
4
+ /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a
5
+ * folder/message (or doesn't exist)" - the same constant `RopGetHierarchyTableHandler`/`RopGetContentsTableHandler`
6
+ * use for their own analogous checks. Attachment/Logon objects (also spec-valid targets for this ROP) aren't
7
+ * supported in this pragmatic subset. */
8
+ const ERROR_INVALID_OBJECT = 0x80070005;
9
+ /**
10
+ * `RopGetPropertiesSpecific` (`[MS-OXCPRPT]`/`[MS-OXCROPS]`): fetches named property values for a single
11
+ * already-opened Folder or Message object (`RopOpenFolder`/`RopOpenMessage`), by an explicit `PropertyTags`
12
+ * list - the single-object analog of `RopQueryRows`' per-row column fetch, reusing the exact same
13
+ * `PropertyResolvers` value-resolution logic (a folder/message handle's `entityUid` is already the same
14
+ * `"folder:"`/`"virtual:"`/`"message:"` target-string format a table row uses). Like `RopQueryRows`, this
15
+ * pragmatic subset always emits a `StandardPropertyRow` (`Flags = 0x00`, confirmed as the response's `RowData`
16
+ * format via `[MS-OXCROPS]`'s own "Success Response Buffer" page, which names `[MS-OXCDATA]` §2.8's
17
+ * `PropertyRow` structure directly) - an unsupported property falls back to a type-appropriate default rather
18
+ * than a `FlaggedPropertyRow`'s per-column error signaling, exactly as `RopQueryRows` already does.
19
+ *
20
+ * `PropertySizeLimit`/`WantUnicode` are decoded (to advance the reader correctly) but not honored - this
21
+ * pragmatic subset never truncates a property value and always encodes strings the same way regardless of the
22
+ * client's Unicode preference (see `PropertyValue.ts`'s own string-encoding doc comments).
23
+ *
24
+ * @author Jean-Philippe Steinmetz
25
+ */
26
+ export class RopGetPropertiesSpecificHandler {
27
+ constructor() {
28
+ this.ropId = ROP_ID_GET_PROPERTIES_SPECIFIC;
29
+ }
30
+ async handle(reader, writer, context) {
31
+ reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
32
+ const inputHandleIndex = reader.readUInt8();
33
+ reader.readUInt16LE(); // PropertySizeLimit - no truncation support in this pragmatic subset
34
+ reader.readUInt16LE(); // WantUnicode - this pragmatic subset always encodes strings the same way regardless
35
+ const propertyTagCount = reader.readUInt16LE();
36
+ const propertyTags = [];
37
+ for (let i = 0; i < propertyTagCount; i++) {
38
+ propertyTags.push(readPropertyTag(reader));
39
+ }
40
+ const handle = context.session.handles[inputHandleIndex];
41
+ if (!handle || (handle.type !== "folder" && handle.type !== "message")) {
42
+ writer.writeUInt8(ROP_ID_GET_PROPERTIES_SPECIFIC);
43
+ writer.writeUInt8(inputHandleIndex);
44
+ writer.writeUInt32LE(ERROR_INVALID_OBJECT);
45
+ return;
46
+ }
47
+ const values = await resolvePropertyValues(handle.entityUid, propertyTags, context);
48
+ writer.writeUInt8(ROP_ID_GET_PROPERTIES_SPECIFIC);
49
+ writer.writeUInt8(inputHandleIndex);
50
+ writer.writeUInt32LE(0); // ReturnValue - success
51
+ writer.writeUInt8(0x00); // PropertyRow Flags - StandardPropertyRow, see class doc comment
52
+ propertyTags.forEach((tag, index) => writePropertyValue(writer, tag.propertyType, values[index]));
53
+ }
54
+ }
55
+ //# sourceMappingURL=RopGetPropertiesSpecificHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopGetPropertiesSpecificHandler.js","sourceRoot":"","sources":["../../../src/rop/RopGetPropertiesSpecificHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,MAAM,8BAA8B,GAAG,IAAI,CAAC;AAE5C;;;yCAGyC;AACzC,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,+BAA+B;IAA5C;QACoB,UAAK,GAAG,8BAA8B,CAAC;IA6B3D,CAAC;IA3BU,KAAK,CAAC,MAAM,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;QAC/E,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,uFAAuF;QAC3G,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,qEAAqE;QAC5F,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,qFAAqF;QAC5G,MAAM,gBAAgB,GAAW,MAAM,CAAC,YAAY,EAAE,CAAC;QACvD,MAAM,YAAY,GAAmD,EAAE,CAAC;QACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC;YAClD,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YACpC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,OAAO;QACX,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;QAEpF,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC;QAClD,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;QACjD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,iEAAiE;QAC1F,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtG,CAAC;CACJ"}
@@ -0,0 +1,92 @@
1
+ import { decodeGuid } from "../codec/MapiGuid.js";
2
+ import { assignOrGetNamedPropertyId } from "./NamedPropertyRegistry.js";
3
+ const ROP_ID_GET_PROPERTY_IDS_FROM_NAMES = 0x56;
4
+ /** `PropertyName.Kind` (`[MS-OXCDATA]` §2.6.1) values. */
5
+ const KIND_LID = 0x00;
6
+ const KIND_NAME = 0x01;
7
+ // KIND_NONE = 0xFF ("the property does not have an associated PropertyName field") is a real, spec-defined
8
+ // value but never resolvable to a real named property - handled by readPropertyName()'s default/`undefined`
9
+ // return rather than its own named constant.
10
+ /** The trailing UTF-16LE null-terminator code unit `PropertyName.Name` (Kind=0x01) is documented to always
11
+ * carry - stripped by `charCodeAt`/numeric comparison rather than a string literal containing the null
12
+ * character itself, to avoid embedding a raw control character in source text. */
13
+ const NULL_CODE_UNIT = 0;
14
+ /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle doesn't exist" - the
15
+ * same constant `RopGetPropertiesSpecificHandler` uses for its own analogous check. Real Exchange resolves
16
+ * named properties per-logon regardless of which specific object handle a client happens to call this ROP
17
+ * against (Store/Folder/Message all share one mailbox-wide mapping table) - this pragmatic subset only
18
+ * requires *some* real handle to exist, not a particular type, matching that "any object will do" semantics. */
19
+ const ERROR_INVALID_OBJECT = 0x80070005;
20
+ /** Decodes one `PropertyName` structure (`[MS-OXCDATA]` §2.6.1, confirmed field order this session: `Kind`
21
+ * **then** `GUID` - not the reverse). Returns `undefined` for `Kind = 0xFF` ("no associated PropertyName"),
22
+ * which cannot resolve to any real named property. */
23
+ function readPropertyName(reader) {
24
+ const kind = reader.readUInt8();
25
+ const guid = decodeGuid(reader);
26
+ if (kind === KIND_LID) {
27
+ return { guid, kind: "lid", lid: reader.readUInt32LE() };
28
+ }
29
+ if (kind === KIND_NAME) {
30
+ const nameSize = reader.readUInt8();
31
+ const nameBytes = reader.readBytes(nameSize);
32
+ // The spec text describing NameSize ("the number of bytes in the Name string that follows it") doesn't
33
+ // unambiguously say whether that count includes the field's own trailing 2-zero-byte terminator - this
34
+ // pragmatic subset treats it as inclusive (the common real-world convention for this style of
35
+ // length-prefixed MAPI string) and strips one trailing null code unit if present. Never exercised by
36
+ // this pragmatic subset's own Calendar property table (every property it needs is Kind=LID), so this
37
+ // is defensive completeness for an arbitrary client request, not a property on the critical path.
38
+ let name = nameBytes.toString("utf16le");
39
+ if (name.length > 0 && name.charCodeAt(name.length - 1) === NULL_CODE_UNIT) {
40
+ name = name.slice(0, -1);
41
+ }
42
+ return { guid, kind: "name", name };
43
+ }
44
+ return undefined;
45
+ }
46
+ /**
47
+ * `RopGetPropertyIdsFromNames` (`[MS-OXCPRPT]`/`[MS-OXCROPS]` §2.2.8.1): resolves a list of named properties
48
+ * (`PropertyName` structures - a property-set `GUID` plus a numeric `LID` or string `Name`) into numeric
49
+ * property IDs a subsequent `RopSetProperties`/`RopGetPropertiesSpecific`/`RopQueryRows` call can use directly.
50
+ * This is the mechanism almost every Calendar-specific property (`PidLidAppointmentStartWhole`,
51
+ * `PidLidBusyStatus`, `PidLidAppointmentRecur`, ...) requires, since none of them have a fixed numeric
52
+ * `PidTag*`-style ID the way `PidTagSubject` does - see `NamedPropertyRegistry.ts`'s own doc comment for the
53
+ * session-scoped registry this delegates to.
54
+ *
55
+ * An unresolvable `PropertyName` (`Kind = 0xFF`) maps to `0x0000` in the response, per spec - this pragmatic
56
+ * subset has no other unmappable case (no permission/quota/hard-limit checks), so every `Kind = 0x00`/`0x01`
57
+ * entry always succeeds. `Flags` is decoded to advance past it correctly but not honored - see
58
+ * `assignOrGetNamedPropertyId`'s own doc comment for why "probe" and "assign" collapse to the same behavior
59
+ * for a purely session-scoped registry.
60
+ *
61
+ * @author Jean-Philippe Steinmetz
62
+ */
63
+ export class RopGetPropertyIdsFromNamesHandler {
64
+ constructor() {
65
+ this.ropId = ROP_ID_GET_PROPERTY_IDS_FROM_NAMES;
66
+ }
67
+ handle(reader, writer, context) {
68
+ reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
69
+ const inputHandleIndex = reader.readUInt8();
70
+ reader.readUInt8(); // Flags - see class doc comment
71
+ const propertyNameCount = reader.readUInt16LE();
72
+ const propertyNames = [];
73
+ for (let i = 0; i < propertyNameCount; i++) {
74
+ propertyNames.push(readPropertyName(reader));
75
+ }
76
+ if (!context.session.handles[inputHandleIndex]) {
77
+ writer.writeUInt8(ROP_ID_GET_PROPERTY_IDS_FROM_NAMES);
78
+ writer.writeUInt8(inputHandleIndex);
79
+ writer.writeUInt32LE(ERROR_INVALID_OBJECT);
80
+ return;
81
+ }
82
+ const propertyIds = propertyNames.map((name) => (name ? assignOrGetNamedPropertyId(context.session, name) : 0x0000));
83
+ writer.writeUInt8(ROP_ID_GET_PROPERTY_IDS_FROM_NAMES);
84
+ writer.writeUInt8(inputHandleIndex);
85
+ writer.writeUInt32LE(0); // ReturnValue - success
86
+ writer.writeUInt16LE(propertyIds.length);
87
+ for (const id of propertyIds) {
88
+ writer.writeUInt16LE(id);
89
+ }
90
+ }
91
+ }
92
+ //# sourceMappingURL=RopGetPropertyIdsFromNamesHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopGetPropertyIdsFromNamesHandler.js","sourceRoot":"","sources":["../../../src/rop/RopGetPropertyIdsFromNamesHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=RopHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RopHandler.js","sourceRoot":"","sources":["../../../src/rop/RopHandler.ts"],"names":[],"mappings":""}