@rapidmx/mapi-plugin 1.0.0-beta.3 → 1.0.0-beta.4

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 (154) hide show
  1. package/README.md +4 -4
  2. package/dist/lib/BaseMapiEmsmdbRoute.js +211 -36
  3. package/dist/lib/BaseMapiEmsmdbRoute.js.map +1 -1
  4. package/dist/lib/MapiSessionManager.js +404 -48
  5. package/dist/lib/MapiSessionManager.js.map +1 -1
  6. package/dist/lib/RegexPatternUtils.js +30 -0
  7. package/dist/lib/RegexPatternUtils.js.map +1 -0
  8. package/dist/lib/RopDispatcher.js +130 -19
  9. package/dist/lib/RopDispatcher.js.map +1 -1
  10. package/dist/lib/codec/AppointmentRecurrence.js +22 -21
  11. package/dist/lib/codec/AppointmentRecurrence.js.map +1 -1
  12. package/dist/lib/codec/BufferCursor.js +41 -12
  13. package/dist/lib/codec/BufferCursor.js.map +1 -1
  14. package/dist/lib/codec/GlobalObjectId.js +26 -20
  15. package/dist/lib/codec/GlobalObjectId.js.map +1 -1
  16. package/dist/lib/codec/MapiTimeZone.js +43 -10
  17. package/dist/lib/codec/MapiTimeZone.js.map +1 -1
  18. package/dist/lib/codec/PropertyValue.js +28 -2
  19. package/dist/lib/codec/PropertyValue.js.map +1 -1
  20. package/dist/lib/codec/RopBuffer.js +15 -3
  21. package/dist/lib/codec/RopBuffer.js.map +1 -1
  22. package/dist/lib/mongo/MapiEmsmdbRouteMongo.js +2 -1
  23. package/dist/lib/mongo/MapiEmsmdbRouteMongo.js.map +1 -1
  24. package/dist/lib/nspi/NspiCodec.js +5 -5
  25. package/dist/lib/nspi/NspiCodec.js.map +1 -1
  26. package/dist/lib/nspi/NspiGetMatchesHandler.js +14 -14
  27. package/dist/lib/nspi/NspiGetMatchesHandler.js.map +1 -1
  28. package/dist/lib/rop/AddressList.js +109 -0
  29. package/dist/lib/rop/AddressList.js.map +1 -0
  30. package/dist/lib/rop/CalendarEventTarget.js +7 -4
  31. package/dist/lib/rop/CalendarEventTarget.js.map +1 -1
  32. package/dist/lib/rop/ContactTarget.js +2 -6
  33. package/dist/lib/rop/ContactTarget.js.map +1 -1
  34. package/dist/lib/rop/ContentsTable.js +60 -0
  35. package/dist/lib/rop/ContentsTable.js.map +1 -0
  36. package/dist/lib/rop/ExecuteBudget.js +82 -0
  37. package/dist/lib/rop/ExecuteBudget.js.map +1 -0
  38. package/dist/lib/rop/FastTransferStream.js +99 -2
  39. package/dist/lib/rop/FastTransferStream.js.map +1 -1
  40. package/dist/lib/rop/FolderTarget.js +13 -6
  41. package/dist/lib/rop/FolderTarget.js.map +1 -1
  42. package/dist/lib/rop/HandleDataCache.js +412 -0
  43. package/dist/lib/rop/HandleDataCache.js.map +1 -0
  44. package/dist/lib/rop/MeetingMessageClassHandler.js +194 -48
  45. package/dist/lib/rop/MeetingMessageClassHandler.js.map +1 -1
  46. package/dist/lib/rop/MessageBodyStream.js +33 -7
  47. package/dist/lib/rop/MessageBodyStream.js.map +1 -1
  48. package/dist/lib/rop/MessageTarget.js +17 -4
  49. package/dist/lib/rop/MessageTarget.js.map +1 -1
  50. package/dist/lib/rop/NamedPropertyRegistry.js +8 -5
  51. package/dist/lib/rop/NamedPropertyRegistry.js.map +1 -1
  52. package/dist/lib/rop/PropertyResolvers.js +3 -1
  53. package/dist/lib/rop/PropertyResolvers.js.map +1 -1
  54. package/dist/lib/rop/RepoPaging.js +54 -0
  55. package/dist/lib/rop/RepoPaging.js.map +1 -0
  56. package/dist/lib/rop/RestapiRules.js +52 -0
  57. package/dist/lib/rop/RestapiRules.js.map +1 -0
  58. package/dist/lib/rop/RopCreateMessageHandler.js +4 -2
  59. package/dist/lib/rop/RopCreateMessageHandler.js.map +1 -1
  60. package/dist/lib/rop/RopDeleteFolderHandler.js +112 -77
  61. package/dist/lib/rop/RopDeleteFolderHandler.js.map +1 -1
  62. package/dist/lib/rop/RopDeleteMessagesHandler.js +17 -1
  63. package/dist/lib/rop/RopDeleteMessagesHandler.js.map +1 -1
  64. package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js +14 -14
  65. package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js.map +1 -1
  66. package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js +13 -14
  67. package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js.map +1 -1
  68. package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js +33 -32
  69. package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js.map +1 -1
  70. package/dist/lib/rop/RopGetContentsTableHandler.js +17 -38
  71. package/dist/lib/rop/RopGetContentsTableHandler.js.map +1 -1
  72. package/dist/lib/rop/RopGetHierarchyTableHandler.js +4 -2
  73. package/dist/lib/rop/RopGetHierarchyTableHandler.js.map +1 -1
  74. package/dist/lib/rop/RopGetPropertiesSpecificHandler.js +6 -8
  75. package/dist/lib/rop/RopGetPropertiesSpecificHandler.js.map +1 -1
  76. package/dist/lib/rop/RopHandler.js +5 -1
  77. package/dist/lib/rop/RopHandler.js.map +1 -1
  78. package/dist/lib/rop/RopLogonHandler.js +5 -2
  79. package/dist/lib/rop/RopLogonHandler.js.map +1 -1
  80. package/dist/lib/rop/RopOpenFolderHandler.js +3 -1
  81. package/dist/lib/rop/RopOpenFolderHandler.js.map +1 -1
  82. package/dist/lib/rop/RopOpenMessageHandler.js +3 -1
  83. package/dist/lib/rop/RopOpenMessageHandler.js.map +1 -1
  84. package/dist/lib/rop/RopOpenStreamHandler.js +11 -8
  85. package/dist/lib/rop/RopOpenStreamHandler.js.map +1 -1
  86. package/dist/lib/rop/RopQueryRowsHandler.js +31 -5
  87. package/dist/lib/rop/RopQueryRowsHandler.js.map +1 -1
  88. package/dist/lib/rop/RopReadStreamHandler.js +22 -4
  89. package/dist/lib/rop/RopReadStreamHandler.js.map +1 -1
  90. package/dist/lib/rop/RopReleaseHandler.js +4 -1
  91. package/dist/lib/rop/RopReleaseHandler.js.map +1 -1
  92. package/dist/lib/rop/RopSaveChangesMessageHandler.js +66 -7
  93. package/dist/lib/rop/RopSaveChangesMessageHandler.js.map +1 -1
  94. package/dist/lib/rop/RopSetColumnsHandler.js +6 -8
  95. package/dist/lib/rop/RopSetColumnsHandler.js.map +1 -1
  96. package/dist/lib/rop/RopSetPropertiesHandler.js +23 -12
  97. package/dist/lib/rop/RopSetPropertiesHandler.js.map +1 -1
  98. package/dist/lib/rop/RopSubmitMessageHandler.js +144 -120
  99. package/dist/lib/rop/RopSubmitMessageHandler.js.map +1 -1
  100. package/dist/lib/rop/RopWriteStreamHandler.js +37 -10
  101. package/dist/lib/rop/RopWriteStreamHandler.js.map +1 -1
  102. package/dist/lib/rop/TaskTarget.js +2 -6
  103. package/dist/lib/rop/TaskTarget.js.map +1 -1
  104. package/dist/lib/rop/TransportSend.js +16 -0
  105. package/dist/lib/rop/TransportSend.js.map +1 -0
  106. package/dist/lib/sql/MapiEmsmdbRouteSQL.js +2 -1
  107. package/dist/lib/sql/MapiEmsmdbRouteSQL.js.map +1 -1
  108. package/dist/types/BaseMapiEmsmdbRoute.d.ts +52 -2
  109. package/dist/types/MapiSessionManager.d.ts +218 -63
  110. package/dist/types/RegexPatternUtils.d.ts +14 -0
  111. package/dist/types/RopDispatcher.d.ts +47 -11
  112. package/dist/types/codec/BufferCursor.d.ts +14 -0
  113. package/dist/types/codec/GlobalObjectId.d.ts +9 -5
  114. package/dist/types/codec/PropertyValue.d.ts +10 -0
  115. package/dist/types/codec/RopBuffer.d.ts +7 -0
  116. package/dist/types/mongo/MapiEmsmdbRouteMongo.d.ts +1 -0
  117. package/dist/types/nspi/NspiGetMatchesHandler.d.ts +2 -0
  118. package/dist/types/rop/AddressList.d.ts +48 -0
  119. package/dist/types/rop/CalendarEventTarget.d.ts +7 -3
  120. package/dist/types/rop/ContactTarget.d.ts +3 -3
  121. package/dist/types/rop/ContentsTable.d.ts +16 -0
  122. package/dist/types/rop/ExecuteBudget.d.ts +48 -0
  123. package/dist/types/rop/FastTransferStream.d.ts +41 -2
  124. package/dist/types/rop/FolderTarget.d.ts +3 -2
  125. package/dist/types/rop/HandleDataCache.d.ts +145 -0
  126. package/dist/types/rop/MeetingMessageClassHandler.d.ts +23 -29
  127. package/dist/types/rop/MessageBodyStream.d.ts +16 -7
  128. package/dist/types/rop/MessageTarget.d.ts +10 -3
  129. package/dist/types/rop/NamedPropertyRegistry.d.ts +6 -2
  130. package/dist/types/rop/PropertyResolvers.d.ts +1 -1
  131. package/dist/types/rop/RepoPaging.d.ts +30 -0
  132. package/dist/types/rop/RestapiRules.d.ts +32 -0
  133. package/dist/types/rop/RopCreateMessageHandler.d.ts +1 -0
  134. package/dist/types/rop/RopDeleteFolderHandler.d.ts +36 -21
  135. package/dist/types/rop/RopDeleteMessagesHandler.d.ts +7 -0
  136. package/dist/types/rop/RopFastTransferSourceCopyPropertiesHandler.d.ts +1 -0
  137. package/dist/types/rop/RopFastTransferSourceCopyToHandler.d.ts +1 -0
  138. package/dist/types/rop/RopFastTransferSourceGetBufferHandler.d.ts +10 -11
  139. package/dist/types/rop/RopGetContentsTableHandler.d.ts +7 -13
  140. package/dist/types/rop/RopGetHierarchyTableHandler.d.ts +1 -0
  141. package/dist/types/rop/RopHandler.d.ts +25 -1
  142. package/dist/types/rop/RopOpenFolderHandler.d.ts +1 -0
  143. package/dist/types/rop/RopOpenMessageHandler.d.ts +1 -0
  144. package/dist/types/rop/RopOpenStreamHandler.d.ts +1 -0
  145. package/dist/types/rop/RopQueryRowsHandler.d.ts +3 -0
  146. package/dist/types/rop/RopReadStreamHandler.d.ts +3 -1
  147. package/dist/types/rop/RopReleaseHandler.d.ts +1 -0
  148. package/dist/types/rop/RopSaveChangesMessageHandler.d.ts +16 -1
  149. package/dist/types/rop/RopSubmitMessageHandler.d.ts +33 -23
  150. package/dist/types/rop/RopWriteStreamHandler.d.ts +18 -8
  151. package/dist/types/rop/TaskTarget.d.ts +3 -3
  152. package/dist/types/rop/TransportSend.d.ts +10 -0
  153. package/dist/types/sql/MapiEmsmdbRouteSQL.d.ts +1 -0
  154. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import { resolveMessageBodyBytes } from "./MessageBodyStream.js";
1
+ import { loadStreamBody } from "./MessageBodyStream.js";
2
2
  const ROP_ID_READ_STREAM = 0x2c;
3
3
  /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a stream (or
4
4
  * doesn't exist)" - the same constant `RopGetHierarchyTableHandler` uses for its own analogous check. */
@@ -12,12 +12,15 @@ const BYTE_COUNT_USE_MAXIMUM = 0xbabe;
12
12
  * requested is spec-legal (the client just calls `RopReadStream` again for the rest, exactly how paging a large
13
13
  * stream is meant to work) - `writeUInt16LE` throwing `RangeError` for an out-of-range value is not. */
14
14
  const MAX_DATA_SIZE = 0xffff;
15
+ /** RopId, InputHandleIndex, ReturnValue and DataSize. */
16
+ const RESPONSE_HEADER_BYTES = 8;
15
17
  /**
16
18
  * `RopReadStream` (`[MS-OXCPRPT]`/`[MS-OXCROPS]`): reads up to `ByteCount` (or `MaximumByteCount`, if
17
19
  * `ByteCount` is the `0xBABE` sentinel) bytes from an already-opened stream (`RopOpenStream`), advancing the
18
20
  * stream's read position - clamped to `MAX_DATA_SIZE` (`0xFFFF`) regardless of what the client asked for, since
19
21
  * the response's own `DataSize` field can't carry more than that; a client wanting more of a large body simply
20
- * calls `RopReadStream` again from the advanced `streamPosition`, the same paging behavior real Exchange uses.
22
+ * calls `RopReadStream` again from the advanced `streamPosition`, the same paging behavior real Exchange uses. It is
23
+ * likewise held to the room left in the request's ROP output buffer (`context.ropOutputRemaining`).
21
24
  * Unlike most other ROPs in this pragmatic subset, `[MS-OXCROPS]` documents only one combined response-buffer
22
25
  * shape for this ROP (no separate Success/Failure pages) - `DataSize`/`Data` are always present, `DataSize = 0`
23
26
  * (empty `Data`) standing in for the failure case rather than the fields being omitted entirely.
@@ -27,6 +30,7 @@ const MAX_DATA_SIZE = 0xffff;
27
30
  export class RopReadStreamHandler {
28
31
  constructor() {
29
32
  this.ropId = ROP_ID_READ_STREAM;
33
+ this.failureTailBytes = 2; // DataSize/WrittenSize
30
34
  }
31
35
  async handle(reader, writer, context) {
32
36
  reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
@@ -41,9 +45,23 @@ export class RopReadStreamHandler {
41
45
  writer.writeUInt16LE(0); // DataSize - see class doc comment on why this is still written on failure
42
46
  return;
43
47
  }
44
- const bytes = await resolveMessageBodyBytes(handle.entityUid, context.messageRepo, context.blobStore);
48
+ const bytes = await loadStreamBody(context, inputHandleIndex, handle);
45
49
  const position = handle.streamPosition ?? 0;
46
- const slice = bytes.subarray(position, position + Math.min(requestedCount, MAX_DATA_SIZE));
50
+ // Also held to the room left in this request's ROP output buffer, after this response's 8 fixed bytes.
51
+ const room = Math.max(0, (context.ropOutputRemaining ?? Infinity) - RESPONSE_HEADER_BYTES);
52
+ const wanted = Math.min(requestedCount, MAX_DATA_SIZE);
53
+ const available = bytes.subarray(position, position + wanted);
54
+ if (room === 0 && available.length > 0) {
55
+ // No room for even one byte: a DataSize of 0 would read as the end of the stream. Answer with what the read
56
+ // needs instead, which doesn't fit, so the dispatcher turns it into RopBufferTooSmall. The position stays.
57
+ writer.writeUInt8(ROP_ID_READ_STREAM);
58
+ writer.writeUInt8(inputHandleIndex);
59
+ writer.writeUInt32LE(0);
60
+ writer.writeUInt16LE(available.length);
61
+ writer.writeBytes(available);
62
+ return;
63
+ }
64
+ const slice = available.subarray(0, room);
47
65
  handle.streamPosition = position + slice.length;
48
66
  writer.writeUInt8(ROP_ID_READ_STREAM);
49
67
  writer.writeUInt8(inputHandleIndex);
@@ -1 +1 @@
1
- {"version":3,"file":"RopReadStreamHandler.js","sourceRoot":"","sources":["../../../src/rop/RopReadStreamHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;yGACyG;AACzG,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;gFACgF;AAChF,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAEtC;;;;wGAIwG;AACxG,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,oBAAoB;IAAjC;QACoB,UAAK,GAAG,kBAAkB,CAAC;IA4B/C,CAAC;IA1BU,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,SAAS,GAAW,MAAM,CAAC,YAAY,EAAE,CAAC;QAChD,MAAM,cAAc,GAAW,SAAS,KAAK,sBAAsB,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAExG,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;YACtC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YACpC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,2EAA2E;YACpG,OAAO;QACX,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,uBAAuB,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACtG,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,CAAC;QAC3F,MAAM,CAAC,cAAc,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;QAEhD,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;QACtC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;QACjD,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW;QAC/C,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;CACJ"}
1
+ {"version":3,"file":"RopReadStreamHandler.js","sourceRoot":"","sources":["../../../src/rop/RopReadStreamHandler.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { releaseHandle } from "../MapiSessionManager.js";
1
2
  const ROP_ID_RELEASE = 0x01;
2
3
  /**
3
4
  * `RopRelease` (`[MS-OXCROPS]`): releases a Server object handle. Confirmed against the spec's own real
@@ -10,11 +11,13 @@ const ROP_ID_RELEASE = 0x01;
10
11
  export class RopReleaseHandler {
11
12
  constructor() {
12
13
  this.ropId = ROP_ID_RELEASE;
14
+ this.hasNoResponse = true;
13
15
  }
14
16
  handle(reader, _writer, context) {
15
17
  reader.readUInt8(); // LogonId - this pragmatic subset doesn't track per-logon-id state separately
16
18
  const inputHandleIndex = reader.readUInt8();
17
- delete context.session.handles[inputHandleIndex];
19
+ // Also releases write streams opened against this handle and drops its cached data - see releaseHandle.
20
+ releaseHandle(context.session, inputHandleIndex);
18
21
  }
19
22
  }
20
23
  //# sourceMappingURL=RopReleaseHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RopReleaseHandler.js","sourceRoot":"","sources":["../../../src/rop/RopReleaseHandler.ts"],"names":[],"mappings":"AAOA,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAiB;IAA9B;QACoB,UAAK,GAAG,cAAc,CAAC;IAO3C,CAAC;IALU,MAAM,CAAC,MAAoB,EAAE,OAAqB,EAAE,OAAmB;QAC1E,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,8EAA8E;QAClG,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrD,CAAC;CACJ"}
1
+ {"version":3,"file":"RopReleaseHandler.js","sourceRoot":"","sources":["../../../src/rop/RopReleaseHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAiB;IAA9B;QACoB,UAAK,GAAG,cAAc,CAAC;QACvB,kBAAa,GAAG,IAAI,CAAC;IAQzC,CAAC;IANU,MAAM,CAAC,MAAoB,EAAE,OAAqB,EAAE,OAAmB;QAC1E,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,8EAA8E;QAClG,MAAM,gBAAgB,GAAW,MAAM,CAAC,SAAS,EAAE,CAAC;QACpD,wGAAwG;QACxG,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACrD,CAAC;CACJ"}
@@ -10,11 +10,15 @@ import { decodeTimeZoneStruct } from "../codec/MapiTimeZone.js";
10
10
  import { BUSY_STATUS_FROM_CODE, LID_APPOINTMENT_END_WHOLE, LID_APPOINTMENT_RECUR, LID_APPOINTMENT_START_WHOLE, LID_BUSY_STATUS, LID_LOCATION, LID_REMINDER_DELTA, LID_TIME_ZONE_STRUCT, PSETID_APPOINTMENT, PSETID_COMMON, } from "./CalendarNamedProperties.js";
11
11
  import { assignOrGetMid } from "./MessageTarget.js";
12
12
  import { resolveNamedProperty } from "./NamedPropertyRegistry.js";
13
+ import { MAX_RECIPIENTS_PER_MESSAGE } from "./AddressList.js";
14
+ import { asEntity, isInvitePending } from "./RestapiRules.js";
13
15
  import { parseAddressList } from "./RopSubmitMessageHandler.js";
14
16
  const ROP_ID_SAVE_CHANGES_MESSAGE = 0x0c;
15
17
  /** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a message (or
16
18
  * doesn't exist)" - the same constant `RopGetPropertiesSpecificHandler` uses for its own analogous check. */
17
19
  const ERROR_INVALID_OBJECT = 0x80070005;
20
+ /** `MAPI_E_TOO_BIG`: a meeting with more than `MAX_RECIPIENTS_PER_MESSAGE` attendees. */
21
+ const ERROR_TOO_BIG = 0x80040305;
18
22
  // The same well-known property IDs RopSetPropertiesHandler tracks - duplicated here (rather than imported)
19
23
  // since importing them would only save a handful of literals; see that file for the real documentation of what
20
24
  // each means.
@@ -50,7 +54,11 @@ const MESSAGE_CLASS_APPOINTMENT_PREFIX = "IPM.Appointment";
50
54
  * `"calendarEvent:<uid>"`) a real `CalendarEvent` row, so a subsequent `RopGetPropertiesSpecific` can read it
51
55
  * back before `RopSubmitMessage` is ever called (a calendar item must exist as soon as it's saved, the same way
52
56
  * a real Exchange server behaves - unlike a mail draft, which this pragmatic subset never persists at all until
53
- * Submit).
57
+ * Submit). Saving never invites anyone: a saved revision is stamped as already handled (`inviteSequenceSent =
58
+ * sequence`), so restapi's `MeetingSchedulingJob` skips it until `RopSubmitMessageHandler.submitAppointment` asks for
59
+ * invites. Attendees of a submitted meeting are then mailed by that job, which is why a meeting is capped at
60
+ * `MAX_RECIPIENTS_PER_MESSAGE` attendees here. Client-supplied times and reminder minutes that don't parse are ignored (the field keeps its
61
+ * existing or default value) rather than stored as `Invalid Date`/`NaN`, and an update is versioned (`asEntity`).
54
62
  *
55
63
  * @author Jean-Philippe Steinmetz
56
64
  */
@@ -75,6 +83,12 @@ export class RopSaveChangesMessageHandler {
75
83
  const mid = messageClass.startsWith(MESSAGE_CLASS_APPOINTMENT_PREFIX)
76
84
  ? await this.saveAppointment(handle, draftProperties, context)
77
85
  : BigInt(assignOrGetMid(context.session, handle.entityUid !== "" ? handle.entityUid : `draft:${inputHandleIndex}`));
86
+ if (mid === undefined) {
87
+ writer.writeUInt8(ROP_ID_SAVE_CHANGES_MESSAGE);
88
+ writer.writeUInt8(responseHandleIndex);
89
+ writer.writeUInt32LE(ERROR_TOO_BIG);
90
+ return;
91
+ }
78
92
  writer.writeUInt8(ROP_ID_SAVE_CHANGES_MESSAGE);
79
93
  writer.writeUInt8(responseHandleIndex);
80
94
  writer.writeUInt32LE(0); // ReturnValue - success
@@ -88,9 +102,15 @@ export class RopSaveChangesMessageHandler {
88
102
  * below - the write-side mirror of `PropertyResolvers.calendarEventValueFor`'s read-side switch. A field the
89
103
  * client never set (e.g. no `RopSetProperties` call touched `PidLidBusyStatus`) falls back to the existing
90
104
  * row's own value on an update, or the entity class's own default on a fresh create.
105
+ *
106
+ * Returns `undefined`, saving nothing, for more than `MAX_RECIPIENTS_PER_MESSAGE` attendees: restapi's
107
+ * `MeetingSchedulingJob` mails every attendee of a saved meeting.
91
108
  */
92
109
  async saveAppointment(handle, draftProperties, context) {
93
110
  const decoded = decodeCalendarFieldsFromDraft(context.session, draftProperties);
111
+ if (decoded.attendeeAddresses.length > MAX_RECIPIENTS_PER_MESSAGE) {
112
+ return undefined;
113
+ }
94
114
  const attendees = decoded.attendeeAddresses.map((address) => ({
95
115
  address,
96
116
  role: AttendeeRole.REQUIRED,
@@ -103,7 +123,7 @@ export class RopSaveChangesMessageHandler {
103
123
  ignoreACL: true,
104
124
  });
105
125
  if (existing) {
106
- await context.calendarEventRepo.update({
126
+ const updated = {
107
127
  uid: existing.uid,
108
128
  version: existing.version,
109
129
  title: decoded.title ?? existing.title,
@@ -114,8 +134,20 @@ export class RopSaveChangesMessageHandler {
114
134
  recurrenceRule: decoded.recurrenceRule ?? existing.recurrenceRule,
115
135
  timezone: decoded.timezone ?? existing.timezone,
116
136
  reminderMinutesBeforeStart: decoded.reminderMinutesBeforeStart ?? existing.reminderMinutesBeforeStart,
117
- attendees: attendees.length > 0 ? attendees : existing.attendees,
118
- }, existing, { ignoreACL: true });
137
+ // An attendee who is still invited keeps their recorded response.
138
+ attendees: attendees.length > 0
139
+ ? attendees.map((attendee) => existing.attendees.find((prior) => prior.address.toLowerCase() === attendee.address.toLowerCase()) ??
140
+ attendee)
141
+ : existing.attendees,
142
+ };
143
+ const sequence = (existing.sequence ?? 0) + (isSchedulingRelevantChange(existing, updated) ? 1 : 0);
144
+ await context.calendarEventRepo.update({
145
+ ...updated,
146
+ sequence,
147
+ // Saving sends nothing, so this revision counts as handled - unless a submitted revision is still
148
+ // waiting for the job, which then sends the meeting as it now stands rather than not at all.
149
+ inviteSequenceSent: isInvitePending(existing) ? (existing.inviteSequenceSent ?? null) : sequence,
150
+ }, asEntity(context.calendarEventRepo, existing), { ignoreACL: true });
119
151
  }
120
152
  return BigInt(assignOrGetMid(context.session, handle.entityUid));
121
153
  }
@@ -139,11 +171,27 @@ export class RopSaveChangesMessageHandler {
139
171
  reminderMinutesBeforeStart: decoded.reminderMinutesBeforeStart,
140
172
  icalUid: `${crypto.randomUUID()}@mapi`,
141
173
  sequence: 0,
174
+ // Handled until submitted: saving a meeting doesn't invite its attendees.
175
+ inviteSequenceSent: 0,
142
176
  }), { ignoreACL: true });
143
177
  handle.entityUid = `calendarEvent:${created.uid}`;
144
178
  return BigInt(assignOrGetMid(context.session, handle.entityUid));
145
179
  }
146
180
  }
181
+ /**
182
+ * `true` when an update changes what attendees were invited to: the start or end time, location, recurrence, or
183
+ * who is invited. The same fields restapi's `BaseCalendarEventRoute.update()` bumps `sequence` for (a MAPI save
184
+ * never sets `status`), so an edit made in Outlook is re-sent to attendees and supersedes their copy (RFC 5546
185
+ * `SEQUENCE`) exactly like one made through REST.
186
+ */
187
+ export function isSchedulingRelevantChange(existing, updated) {
188
+ const addresses = (attendees) => JSON.stringify(attendees.map((attendee) => attendee.address.toLowerCase()).sort());
189
+ return (new Date(updated.startDate).getTime() !== new Date(existing.startDate).getTime() ||
190
+ new Date(updated.endDate).getTime() !== new Date(existing.endDate).getTime() ||
191
+ (updated.location ?? "") !== (existing.location ?? "") ||
192
+ JSON.stringify(updated.recurrenceRule ?? null) !== JSON.stringify(existing.recurrenceRule ?? null) ||
193
+ addresses(updated.attendees) !== addresses(existing.attendees));
194
+ }
147
195
  /** Decodes a draft message handle's accumulated `RopSetProperties` values (`Record<string, string>`, keyed by
148
196
  * decimal `PropertyId`) back into typed `CalendarEvent` fields - the write-side mirror of
149
197
  * `PropertyResolvers.calendarEventValueFor`'s read-side switch, sharing the same `CalendarNamedProperties.ts`
@@ -183,10 +231,10 @@ function decodeCalendarFieldsFromDraft(session, properties) {
183
231
  decoded.location = value;
184
232
  break;
185
233
  case LID_APPOINTMENT_START_WHOLE:
186
- decoded.startDate = new Date(value);
234
+ decoded.startDate = validDate(value);
187
235
  break;
188
236
  case LID_APPOINTMENT_END_WHOLE:
189
- decoded.endDate = new Date(value);
237
+ decoded.endDate = validDate(value);
190
238
  break;
191
239
  case LID_BUSY_STATUS:
192
240
  decoded.busyStatus = BUSY_STATUS_FROM_CODE[Number(value)] ?? BusyStatus.BUSY;
@@ -202,9 +250,20 @@ function decodeCalendarFieldsFromDraft(session, properties) {
202
250
  }
203
251
  }
204
252
  else if (guid === PSETID_COMMON && named.lid === LID_REMINDER_DELTA) {
205
- decoded.reminderMinutesBeforeStart = Number(value);
253
+ decoded.reminderMinutesBeforeStart = validMinutes(value);
206
254
  }
207
255
  }
208
256
  return decoded;
209
257
  }
258
+ /** `value` as a date, or `undefined` (the field is left as it was) when it doesn't parse. A client picks the property
259
+ * type it sends, so a "time" can arrive as any string. */
260
+ function validDate(value) {
261
+ const date = new Date(value);
262
+ return Number.isNaN(date.getTime()) ? undefined : date;
263
+ }
264
+ /** `value` as a whole, non-negative number of minutes, or `undefined` when it isn't one. */
265
+ function validMinutes(value) {
266
+ const minutes = Number(value);
267
+ return value.trim() !== "" && Number.isSafeInteger(minutes) && minutes >= 0 ? minutes : undefined;
268
+ }
210
269
  //# sourceMappingURL=RopSaveChangesMessageHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RopSaveChangesMessageHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSaveChangesMessageHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RopSaveChangesMessageHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSaveChangesMessageHandler.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { readPropertyTag } from "../codec/PropertyValue.js";
1
+ import { readPropertyTagArray } from "../codec/PropertyValue.js";
2
2
  const ROP_ID_SET_COLUMNS = 0x12;
3
3
  /** `TBLSTAT_COMPLETE` - this pragmatic subset's tables are always populated synchronously, so `RopSetColumns`
4
4
  * (and every other table ROP) never reports any other `TableStatus` value. */
@@ -7,6 +7,8 @@ const TABLE_STATUS_COMPLETE = 0x00;
7
7
  * doesn't exist)" - the same constant `RopQueryRowsHandler`/`RopGetHierarchyTableHandler` use for their own
8
8
  * analogous checks. */
9
9
  const ERROR_INVALID_OBJECT = 0x80070005;
10
+ /** `MAPI_E_TOO_BIG`, for more than `MAX_PROPERTY_TAG_COUNT` columns. */
11
+ const ERROR_TOO_BIG = 0x80040305;
10
12
  /**
11
13
  * `RopSetColumns` (`[MS-OXCTABL]`/`[MS-OXCROPS]`): configures which properties a table's subsequent
12
14
  * `RopQueryRows` calls return, and in what order. Unlike `RopOpenFolder`/`RopGetHierarchyTable`, this ROP
@@ -30,16 +32,12 @@ export class RopSetColumnsHandler {
30
32
  reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
31
33
  const inputHandleIndex = reader.readUInt8();
32
34
  reader.readUInt8(); // SetColumnsFlags - this pragmatic subset has no async/deferred column-set variant
33
- const propertyTagCount = reader.readUInt16LE();
34
- const columns = [];
35
- for (let i = 0; i < propertyTagCount; i++) {
36
- columns.push(readPropertyTag(reader));
37
- }
35
+ const columns = readPropertyTagArray(reader, reader.readUInt16LE());
38
36
  const handle = context.session.handles[inputHandleIndex];
39
- if (!handle || handle.type !== "table") {
37
+ if (!handle || handle.type !== "table" || !columns) {
40
38
  writer.writeUInt8(ROP_ID_SET_COLUMNS);
41
39
  writer.writeUInt8(inputHandleIndex);
42
- writer.writeUInt32LE(ERROR_INVALID_OBJECT);
40
+ writer.writeUInt32LE(columns ? ERROR_INVALID_OBJECT : ERROR_TOO_BIG);
43
41
  return;
44
42
  }
45
43
  handle.columns = columns;
@@ -1 +1 @@
1
- {"version":3,"file":"RopSetColumnsHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSetColumnsHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;8EAC8E;AAC9E,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC;;uBAEuB;AACvB,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,oBAAoB;IAAjC;QACoB,UAAK,GAAG,kBAAkB,CAAC;IA0B/C,CAAC;IAxBU,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,CAAC,SAAS,EAAE,CAAC,CAAC,mFAAmF;QACvG,MAAM,gBAAgB,GAAW,MAAM,CAAC,YAAY,EAAE,CAAC;QACvD,MAAM,OAAO,GAAmD,EAAE,CAAC;QACnE,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,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACrC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;YACtC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YACpC,MAAM,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;YAC3C,OAAO;QACX,CAAC;QACD,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;QAEzB,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;QACtC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;QACjD,MAAM,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAC7C,CAAC;CACJ"}
1
+ {"version":3,"file":"RopSetColumnsHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSetColumnsHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;8EAC8E;AAC9E,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC;;uBAEuB;AACvB,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAExC,wEAAwE;AACxE,MAAM,aAAa,GAAG,UAAU,CAAC;AAEjC;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,oBAAoB;IAAjC;QACoB,UAAK,GAAG,kBAAkB,CAAC;IAsB/C,CAAC;IApBU,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,CAAC,SAAS,EAAE,CAAC,CAAC,mFAAmF;QACvG,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YACjD,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;YACtC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YACpC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;YACrE,OAAO;QACX,CAAC;QACD,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;QAEzB,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;QACtC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACpC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB;QACjD,MAAM,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAC7C,CAAC;CACJ"}
@@ -7,6 +7,8 @@ const ROP_ID_SET_PROPERTIES = 0x0a;
7
7
  * `RopSetProperties` is also spec-valid on Folder/Attachment/Logon objects, none of which this pragmatic
8
8
  * subset's compose/send path ever needs to set properties on. */
9
9
  const ERROR_INVALID_OBJECT = 0x80070005;
10
+ /** `MAPI_E_INVALID_PARAMETER`: `PropertyValues` couldn't be decoded, or didn't match `PropertyValueSize`. */
11
+ const ERROR_INVALID_PARAMETER = 0x80070057;
10
12
  // The small, well-known set of plain (non-named) properties this pragmatic subset's compose/send path tracks -
11
13
  // exactly what RopSubmitMessageHandler/RopSaveChangesMessageHandler need to build a MIME message or persist a
12
14
  // CalendarEvent (Subject, an inline small body, the PidTagDisplayTo/Cc/Bcc "cached recipient display string"
@@ -94,21 +96,30 @@ export class RopSetPropertiesHandler {
94
96
  // PropertyValueSize covers the PropertyValueCount field itself plus PropertyValues, counted from right
95
97
  // here (immediately after the PropertyValueSize field, before PropertyValueCount is read).
96
98
  const propertyValuesEnd = reader.position + propertyValueSize;
97
- const propertyValueCount = reader.readUInt16LE();
98
- const values = [];
99
- for (let i = 0; i < propertyValueCount; i++) {
100
- values.push(readTaggedPropertyValue(reader));
99
+ let values = [];
100
+ try {
101
+ const propertyValueCount = reader.readUInt16LE();
102
+ for (let i = 0; i < propertyValueCount; i++) {
103
+ values.push(readTaggedPropertyValue(reader));
104
+ }
105
+ }
106
+ catch {
107
+ values = undefined; // e.g. an unsupported property type, whose size can't be known
101
108
  }
102
- // PropertyValueSize is a byte-count check the request buffer itself provides for framing purposes (so a
103
- // generic ROP-skipping implementation could skip this ROP without decoding it) - this handler already
104
- // decoded PropertyValues field-by-field above, so the only remaining use is confirming the reader ended
105
- // up exactly where PropertyValueSize said it would, catching a malformed request loudly rather than
106
- // silently misaligning every ROP that follows in the same RopsList.
107
- if (reader.position !== propertyValuesEnd) {
108
- throw new Error("RopSetProperties: PropertyValueSize did not match the decoded PropertyValues length.");
109
+ // PropertyValueSize frames this ROP, so a list that couldn't be decoded, or decoded to a different length, is
110
+ // skipped by it and only this ROP fails; the ROPs after it are still where PropertyValueSize says. When
111
+ // PropertyValueSize itself points past the request, seek throws and the whole request is rejected.
112
+ const decodedEnd = reader.position;
113
+ reader.seek(propertyValuesEnd);
114
+ if (!values || decodedEnd !== propertyValuesEnd) {
115
+ writer.writeUInt8(ROP_ID_SET_PROPERTIES);
116
+ writer.writeUInt8(inputHandleIndex);
117
+ writer.writeUInt32LE(ERROR_INVALID_PARAMETER);
118
+ return;
109
119
  }
110
120
  const handle = context.session.handles[inputHandleIndex];
111
- if (!handle || handle.type !== "message") {
121
+ // A draft already submitted is finished: changing it can't change what was sent, and must not set up a resend.
122
+ if (!handle || handle.type !== "message" || handle.submitted) {
112
123
  writer.writeUInt8(ROP_ID_SET_PROPERTIES);
113
124
  writer.writeUInt8(inputHandleIndex);
114
125
  writer.writeUInt32LE(ERROR_INVALID_OBJECT);
@@ -1 +1 @@
1
- {"version":3,"file":"RopSetPropertiesHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSetPropertiesHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RopSetPropertiesHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSetPropertiesHandler.ts"],"names":[],"mappings":"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"}