@rapidmx/mapi-plugin 1.0.0-beta.3 → 1.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/lib/BaseMapiEmsmdbRoute.js +229 -37
- package/dist/lib/BaseMapiEmsmdbRoute.js.map +1 -1
- package/dist/lib/MapiSessionManager.js +404 -48
- package/dist/lib/MapiSessionManager.js.map +1 -1
- package/dist/lib/RegexPatternUtils.js +30 -0
- package/dist/lib/RegexPatternUtils.js.map +1 -0
- package/dist/lib/RopDispatcher.js +130 -19
- package/dist/lib/RopDispatcher.js.map +1 -1
- package/dist/lib/codec/AppointmentRecurrence.js +22 -21
- package/dist/lib/codec/AppointmentRecurrence.js.map +1 -1
- package/dist/lib/codec/BufferCursor.js +41 -12
- package/dist/lib/codec/BufferCursor.js.map +1 -1
- package/dist/lib/codec/GlobalObjectId.js +26 -20
- package/dist/lib/codec/GlobalObjectId.js.map +1 -1
- package/dist/lib/codec/MapiTimeZone.js +43 -10
- package/dist/lib/codec/MapiTimeZone.js.map +1 -1
- package/dist/lib/codec/PropertyValue.js +28 -2
- package/dist/lib/codec/PropertyValue.js.map +1 -1
- package/dist/lib/codec/RopBuffer.js +15 -3
- package/dist/lib/codec/RopBuffer.js.map +1 -1
- package/dist/lib/mongo/MapiEmsmdbRouteMongo.js +2 -1
- package/dist/lib/mongo/MapiEmsmdbRouteMongo.js.map +1 -1
- package/dist/lib/nspi/NspiCodec.js +5 -5
- package/dist/lib/nspi/NspiCodec.js.map +1 -1
- package/dist/lib/nspi/NspiGetMatchesHandler.js +14 -14
- package/dist/lib/nspi/NspiGetMatchesHandler.js.map +1 -1
- package/dist/lib/rop/AddressList.js +109 -0
- package/dist/lib/rop/AddressList.js.map +1 -0
- package/dist/lib/rop/CalendarEventTarget.js +7 -4
- package/dist/lib/rop/CalendarEventTarget.js.map +1 -1
- package/dist/lib/rop/ContactTarget.js +2 -6
- package/dist/lib/rop/ContactTarget.js.map +1 -1
- package/dist/lib/rop/ContentsTable.js +60 -0
- package/dist/lib/rop/ContentsTable.js.map +1 -0
- package/dist/lib/rop/ExecuteBudget.js +82 -0
- package/dist/lib/rop/ExecuteBudget.js.map +1 -0
- package/dist/lib/rop/FastTransferStream.js +99 -2
- package/dist/lib/rop/FastTransferStream.js.map +1 -1
- package/dist/lib/rop/FolderTarget.js +13 -6
- package/dist/lib/rop/FolderTarget.js.map +1 -1
- package/dist/lib/rop/HandleDataCache.js +412 -0
- package/dist/lib/rop/HandleDataCache.js.map +1 -0
- package/dist/lib/rop/MeetingMessageClassHandler.js +194 -48
- package/dist/lib/rop/MeetingMessageClassHandler.js.map +1 -1
- package/dist/lib/rop/MessageBodyStream.js +33 -7
- package/dist/lib/rop/MessageBodyStream.js.map +1 -1
- package/dist/lib/rop/MessageTarget.js +17 -4
- package/dist/lib/rop/MessageTarget.js.map +1 -1
- package/dist/lib/rop/NamedPropertyRegistry.js +8 -5
- package/dist/lib/rop/NamedPropertyRegistry.js.map +1 -1
- package/dist/lib/rop/PropertyResolvers.js +3 -1
- package/dist/lib/rop/PropertyResolvers.js.map +1 -1
- package/dist/lib/rop/RepoPaging.js +54 -0
- package/dist/lib/rop/RepoPaging.js.map +1 -0
- package/dist/lib/rop/RestapiRules.js +52 -0
- package/dist/lib/rop/RestapiRules.js.map +1 -0
- package/dist/lib/rop/RopCreateMessageHandler.js +4 -2
- package/dist/lib/rop/RopCreateMessageHandler.js.map +1 -1
- package/dist/lib/rop/RopDeleteFolderHandler.js +118 -77
- package/dist/lib/rop/RopDeleteFolderHandler.js.map +1 -1
- package/dist/lib/rop/RopDeleteMessagesHandler.js +26 -1
- package/dist/lib/rop/RopDeleteMessagesHandler.js.map +1 -1
- package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js +14 -14
- package/dist/lib/rop/RopFastTransferSourceCopyPropertiesHandler.js.map +1 -1
- package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js +13 -14
- package/dist/lib/rop/RopFastTransferSourceCopyToHandler.js.map +1 -1
- package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js +33 -32
- package/dist/lib/rop/RopFastTransferSourceGetBufferHandler.js.map +1 -1
- package/dist/lib/rop/RopGetContentsTableHandler.js +17 -38
- package/dist/lib/rop/RopGetContentsTableHandler.js.map +1 -1
- package/dist/lib/rop/RopGetHierarchyTableHandler.js +4 -2
- package/dist/lib/rop/RopGetHierarchyTableHandler.js.map +1 -1
- package/dist/lib/rop/RopGetPropertiesSpecificHandler.js +6 -8
- package/dist/lib/rop/RopGetPropertiesSpecificHandler.js.map +1 -1
- package/dist/lib/rop/RopHandler.js +5 -1
- package/dist/lib/rop/RopHandler.js.map +1 -1
- package/dist/lib/rop/RopLogonHandler.js +5 -2
- package/dist/lib/rop/RopLogonHandler.js.map +1 -1
- package/dist/lib/rop/RopOpenFolderHandler.js +3 -1
- package/dist/lib/rop/RopOpenFolderHandler.js.map +1 -1
- package/dist/lib/rop/RopOpenMessageHandler.js +3 -1
- package/dist/lib/rop/RopOpenMessageHandler.js.map +1 -1
- package/dist/lib/rop/RopOpenStreamHandler.js +11 -8
- package/dist/lib/rop/RopOpenStreamHandler.js.map +1 -1
- package/dist/lib/rop/RopQueryRowsHandler.js +31 -5
- package/dist/lib/rop/RopQueryRowsHandler.js.map +1 -1
- package/dist/lib/rop/RopReadStreamHandler.js +22 -4
- package/dist/lib/rop/RopReadStreamHandler.js.map +1 -1
- package/dist/lib/rop/RopReleaseHandler.js +4 -1
- package/dist/lib/rop/RopReleaseHandler.js.map +1 -1
- package/dist/lib/rop/RopSaveChangesMessageHandler.js +66 -7
- package/dist/lib/rop/RopSaveChangesMessageHandler.js.map +1 -1
- package/dist/lib/rop/RopSetColumnsHandler.js +6 -8
- package/dist/lib/rop/RopSetColumnsHandler.js.map +1 -1
- package/dist/lib/rop/RopSetPropertiesHandler.js +23 -12
- package/dist/lib/rop/RopSetPropertiesHandler.js.map +1 -1
- package/dist/lib/rop/RopSubmitMessageHandler.js +148 -120
- package/dist/lib/rop/RopSubmitMessageHandler.js.map +1 -1
- package/dist/lib/rop/RopWriteStreamHandler.js +37 -10
- package/dist/lib/rop/RopWriteStreamHandler.js.map +1 -1
- package/dist/lib/rop/TaskTarget.js +2 -6
- package/dist/lib/rop/TaskTarget.js.map +1 -1
- package/dist/lib/rop/TransportSend.js +16 -0
- package/dist/lib/rop/TransportSend.js.map +1 -0
- package/dist/lib/sql/MapiEmsmdbRouteSQL.js +2 -1
- package/dist/lib/sql/MapiEmsmdbRouteSQL.js.map +1 -1
- package/dist/types/BaseMapiEmsmdbRoute.d.ts +59 -2
- package/dist/types/MapiSessionManager.d.ts +218 -63
- package/dist/types/RegexPatternUtils.d.ts +14 -0
- package/dist/types/RopDispatcher.d.ts +47 -11
- package/dist/types/codec/BufferCursor.d.ts +14 -0
- package/dist/types/codec/GlobalObjectId.d.ts +9 -5
- package/dist/types/codec/PropertyValue.d.ts +10 -0
- package/dist/types/codec/RopBuffer.d.ts +7 -0
- package/dist/types/mongo/MapiEmsmdbRouteMongo.d.ts +1 -0
- package/dist/types/nspi/NspiGetMatchesHandler.d.ts +2 -0
- package/dist/types/rop/AddressList.d.ts +48 -0
- package/dist/types/rop/CalendarEventTarget.d.ts +7 -3
- package/dist/types/rop/ContactTarget.d.ts +3 -3
- package/dist/types/rop/ContentsTable.d.ts +16 -0
- package/dist/types/rop/ExecuteBudget.d.ts +48 -0
- package/dist/types/rop/FastTransferStream.d.ts +41 -2
- package/dist/types/rop/FolderTarget.d.ts +3 -2
- package/dist/types/rop/HandleDataCache.d.ts +145 -0
- package/dist/types/rop/MeetingMessageClassHandler.d.ts +23 -29
- package/dist/types/rop/MessageBodyStream.d.ts +16 -7
- package/dist/types/rop/MessageTarget.d.ts +10 -3
- package/dist/types/rop/NamedPropertyRegistry.d.ts +6 -2
- package/dist/types/rop/PropertyResolvers.d.ts +1 -1
- package/dist/types/rop/RepoPaging.d.ts +30 -0
- package/dist/types/rop/RestapiRules.d.ts +32 -0
- package/dist/types/rop/RopCreateMessageHandler.d.ts +1 -0
- package/dist/types/rop/RopDeleteFolderHandler.d.ts +36 -21
- package/dist/types/rop/RopDeleteMessagesHandler.d.ts +7 -0
- package/dist/types/rop/RopFastTransferSourceCopyPropertiesHandler.d.ts +1 -0
- package/dist/types/rop/RopFastTransferSourceCopyToHandler.d.ts +1 -0
- package/dist/types/rop/RopFastTransferSourceGetBufferHandler.d.ts +10 -11
- package/dist/types/rop/RopGetContentsTableHandler.d.ts +7 -13
- package/dist/types/rop/RopGetHierarchyTableHandler.d.ts +1 -0
- package/dist/types/rop/RopHandler.d.ts +40 -1
- package/dist/types/rop/RopOpenFolderHandler.d.ts +1 -0
- package/dist/types/rop/RopOpenMessageHandler.d.ts +1 -0
- package/dist/types/rop/RopOpenStreamHandler.d.ts +1 -0
- package/dist/types/rop/RopQueryRowsHandler.d.ts +3 -0
- package/dist/types/rop/RopReadStreamHandler.d.ts +3 -1
- package/dist/types/rop/RopReleaseHandler.d.ts +1 -0
- package/dist/types/rop/RopSaveChangesMessageHandler.d.ts +16 -1
- package/dist/types/rop/RopSubmitMessageHandler.d.ts +33 -23
- package/dist/types/rop/RopWriteStreamHandler.d.ts +18 -8
- package/dist/types/rop/TaskTarget.d.ts +3 -3
- package/dist/types/rop/TransportSend.d.ts +10 -0
- package/dist/types/sql/MapiEmsmdbRouteSQL.d.ts +1 -0
- package/package.json +3 -3
|
@@ -24,10 +24,12 @@ import { BufferWriter } from "./BufferCursor.js";
|
|
|
24
24
|
* actually observes DST - a real client will show the correct offset only for occurrences near the reference
|
|
25
25
|
* instant used at encode time, not a spec violation but a real, documented fidelity gap.
|
|
26
26
|
* - Decoding a struct back into an IANA identifier is fundamentally lossy (a bias alone doesn't identify a
|
|
27
|
-
* unique zone name) - this codec resolves
|
|
28
|
-
* IANA `Etc/GMT` area's own sign convention is POSIX-inverted from common usage: `Etc/GMT+8` means UTC-8,
|
|
29
|
-
* UTC+8)
|
|
30
|
-
*
|
|
27
|
+
* unique zone name) - this codec resolves a whole-hour offset to a synthetic-but-valid `Etc/GMT±N` IANA identifier
|
|
28
|
+
* (note the IANA `Etc/GMT` area's own sign convention is POSIX-inverted from common usage: `Etc/GMT+8` means UTC-8,
|
|
29
|
+
* not UTC+8). A half-hour/quarter-hour offset keeps its minutes: it maps to a real DST-less zone with that offset
|
|
30
|
+
* (e.g. `Asia/Kolkata`, `Asia/Kathmandu`) or otherwise to a fixed-offset identifier like `"-03:30"`. An offset
|
|
31
|
+
* outside UTC-12..UTC+14 decodes as `"UTC"`.
|
|
32
|
+
* - Encoding a zone `Intl` doesn't recognize falls back to UTC instead of throwing.
|
|
31
33
|
*
|
|
32
34
|
* @author Jean-Philippe Steinmetz
|
|
33
35
|
*/
|
|
@@ -66,7 +68,15 @@ function utcOffsetMinutes(timezone, at) {
|
|
|
66
68
|
* reference instant for resolving a non-UTC zone's current fixed offset. */
|
|
67
69
|
export function encodeTimeZoneStruct(timezone, at) {
|
|
68
70
|
const writer = new BufferWriter();
|
|
69
|
-
|
|
71
|
+
let bias = 0;
|
|
72
|
+
try {
|
|
73
|
+
bias = timezone === "UTC" ? 0 : -utcOffsetMinutes(timezone, at);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// An identifier Intl doesn't recognize (e.g. stored by another client) is sent as UTC rather than failing
|
|
77
|
+
// the whole property read.
|
|
78
|
+
bias = 0;
|
|
79
|
+
}
|
|
70
80
|
writer.writeInt32LE(bias); // lBias
|
|
71
81
|
writer.writeInt32LE(0); // lStandardBias - no DST modeled
|
|
72
82
|
writer.writeInt32LE(0); // lDaylightBias - no DST modeled
|
|
@@ -82,12 +92,35 @@ export function decodeTimeZoneStruct(reader) {
|
|
|
82
92
|
reader.readInt32LE(); // lDaylightBias - ditto
|
|
83
93
|
skipTransitionBlock(reader); // wStandardYear + stStandardDate
|
|
84
94
|
skipTransitionBlock(reader); // wDaylightYear + stDaylightDate
|
|
85
|
-
|
|
95
|
+
const offsetMinutes = -bias;
|
|
96
|
+
// No real zone is further than UTC-12/UTC+14; anything else is garbage and treated as UTC.
|
|
97
|
+
if (offsetMinutes === 0 || offsetMinutes < -12 * 60 || offsetMinutes > 14 * 60) {
|
|
86
98
|
return "UTC";
|
|
87
99
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
100
|
+
if (offsetMinutes % 60 === 0) {
|
|
101
|
+
const hours = offsetMinutes / 60;
|
|
102
|
+
return `Etc/GMT${hours < 0 ? "+" : "-"}${Math.abs(hours)}`;
|
|
103
|
+
}
|
|
104
|
+
return FRACTIONAL_OFFSET_ZONES[offsetMinutes] ?? formatFixedOffset(offsetMinutes);
|
|
105
|
+
}
|
|
106
|
+
/** Real zones with a non-whole-hour offset and no daylight saving, so the zone matches a DST-less
|
|
107
|
+
* `TimeZoneStruct` all year. */
|
|
108
|
+
const FRACTIONAL_OFFSET_ZONES = {
|
|
109
|
+
[-570]: "Pacific/Marquesas",
|
|
110
|
+
210: "Asia/Tehran",
|
|
111
|
+
270: "Asia/Kabul",
|
|
112
|
+
330: "Asia/Kolkata",
|
|
113
|
+
345: "Asia/Kathmandu",
|
|
114
|
+
390: "Asia/Yangon",
|
|
115
|
+
525: "Australia/Eucla",
|
|
116
|
+
570: "Australia/Darwin",
|
|
117
|
+
};
|
|
118
|
+
/** A fixed-offset identifier such as `"-03:30"`, which `Intl.DateTimeFormat` accepts as a `timeZone`. Used for a
|
|
119
|
+
* minute-precision offset with no matching DST-less zone, instead of rounding it to a whole hour. */
|
|
120
|
+
function formatFixedOffset(offsetMinutes) {
|
|
121
|
+
const magnitude = Math.abs(offsetMinutes);
|
|
122
|
+
const hours = String(Math.floor(magnitude / 60)).padStart(2, "0");
|
|
123
|
+
const minutes = String(magnitude % 60).padStart(2, "0");
|
|
124
|
+
return `${offsetMinutes < 0 ? "-" : "+"}${hours}:${minutes}`;
|
|
92
125
|
}
|
|
93
126
|
//# sourceMappingURL=MapiTimeZone.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapiTimeZone.js","sourceRoot":"","sources":["../../../src/codec/MapiTimeZone.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAgB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE/D
|
|
1
|
+
{"version":3,"file":"MapiTimeZone.js","sourceRoot":"","sources":["../../../src/codec/MapiTimeZone.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
import { DecodeError } from "./BufferCursor.js";
|
|
1
6
|
import { decodeGuid, encodeGuid } from "./MapiGuid.js";
|
|
2
7
|
/**
|
|
3
8
|
* The property-value system every meaningful ROP depends on (`RopGetPropertiesSpecific`/`RopSetProperties`,
|
|
@@ -41,6 +46,26 @@ export function readPropertyTag(reader) {
|
|
|
41
46
|
const propertyId = reader.readUInt16LE();
|
|
42
47
|
return { propertyId, propertyType };
|
|
43
48
|
}
|
|
49
|
+
/** The most `PropertyTag`s accepted in one request's tag array (`RopSetColumns`, `RopGetPropertiesSpecific`,
|
|
50
|
+
* the FastTransfer source ROPs, NSPI `Columns`). Every tag multiplies the per-row resolution work and, for
|
|
51
|
+
* `RopSetColumns`, the stored session state; a real client asks for far fewer. */
|
|
52
|
+
export const MAX_PROPERTY_TAG_COUNT = 256;
|
|
53
|
+
/**
|
|
54
|
+
* Reads `count` consecutive `PropertyTag`s. When `count` exceeds `MAX_PROPERTY_TAG_COUNT`, the tags' bytes are
|
|
55
|
+
* skipped (still bounds-checked, so a count larger than the buffer throws) and `undefined` is returned, leaving
|
|
56
|
+
* the reader positioned after the array so the caller can send an error response and keep parsing later ROPs.
|
|
57
|
+
*/
|
|
58
|
+
export function readPropertyTagArray(reader, count) {
|
|
59
|
+
if (count > MAX_PROPERTY_TAG_COUNT) {
|
|
60
|
+
reader.readBytes(count * 4);
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const tags = [];
|
|
64
|
+
for (let i = 0; i < count; i++) {
|
|
65
|
+
tags.push(readPropertyTag(reader));
|
|
66
|
+
}
|
|
67
|
+
return tags;
|
|
68
|
+
}
|
|
44
69
|
export function writePropertyTag(writer, tag) {
|
|
45
70
|
writer.writeUInt16LE(tag.propertyType);
|
|
46
71
|
writer.writeUInt16LE(tag.propertyId);
|
|
@@ -111,7 +136,8 @@ export function readPropertyValue(reader, type) {
|
|
|
111
136
|
case PropertyType.PtypMultipleBinary:
|
|
112
137
|
return readCountedArray(reader, () => reader.readBytes(reader.readUInt16LE()));
|
|
113
138
|
default:
|
|
114
|
-
|
|
139
|
+
// The value's size is unknown, so nothing after it in the request can be located.
|
|
140
|
+
throw new DecodeError(`PropertyValue: unsupported PropertyType 0x${type.toString(16)}`);
|
|
115
141
|
}
|
|
116
142
|
}
|
|
117
143
|
export function writePropertyValue(writer, type, value) {
|
|
@@ -184,7 +210,7 @@ export function writePropertyValue(writer, type, value) {
|
|
|
184
210
|
function readCountedArray(reader, readOne) {
|
|
185
211
|
const count = reader.readUInt32LE();
|
|
186
212
|
if (count > reader.remaining) {
|
|
187
|
-
throw new
|
|
213
|
+
throw new DecodeError(`PropertyValue.readCountedArray(): element count ${count} exceeds the remaining buffer size (${reader.remaining}).`);
|
|
188
214
|
}
|
|
189
215
|
const values = [];
|
|
190
216
|
for (let i = 0; i < count; i++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyValue.js","sourceRoot":"","sources":["../../../src/codec/PropertyValue.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PropertyValue.js","sourceRoot":"","sources":["../../../src/codec/PropertyValue.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,20 +3,32 @@
|
|
|
3
3
|
// SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
///////////////////////////////////////////////////////////////////////////////
|
|
5
5
|
import { BufferReader, BufferWriter } from "./BufferCursor.js";
|
|
6
|
+
/** The largest `ServerObjectHandleTable` accepted. Every ROP addresses a handle by a one-byte index, so a table
|
|
7
|
+
* with more than 255 entries can't be referenced anyway; a larger one is only a way to make the server allocate
|
|
8
|
+
* and echo back an oversized array. */
|
|
9
|
+
export const MAX_HANDLE_TABLE_ENTRIES = 255;
|
|
6
10
|
export function encodeRopBuffer(buf) {
|
|
7
11
|
const writer = new BufferWriter();
|
|
8
12
|
// RopSize covers itself (2 bytes) plus ropsList - the handle table isn't part of RopSize's count.
|
|
9
13
|
writer.writeUInt16LE(2 + buf.ropsList.length);
|
|
10
14
|
writer.writeBytes(buf.ropsList);
|
|
11
|
-
for
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
// One allocation for the whole table instead of one small buffer per entry.
|
|
16
|
+
const table = Buffer.alloc(buf.handleTable.length * 4);
|
|
17
|
+
buf.handleTable.forEach((handle, index) => table.writeUInt32LE(handle >>> 0, index * 4));
|
|
18
|
+
writer.writeBytes(table);
|
|
14
19
|
return writer.toBuffer();
|
|
15
20
|
}
|
|
21
|
+
/** Throws a `RangeError` for a malformed buffer: a `RopSize` smaller than its own field or larger than the
|
|
22
|
+
* buffer, a handle table that isn't a whole number of 4-byte entries, or one with more than
|
|
23
|
+
* `MAX_HANDLE_TABLE_ENTRIES` entries. */
|
|
16
24
|
export function decodeRopBuffer(buffer) {
|
|
17
25
|
const reader = new BufferReader(buffer);
|
|
18
26
|
const ropSize = reader.readUInt16LE();
|
|
19
27
|
const ropsList = reader.readBytes(ropSize - 2);
|
|
28
|
+
const tableBytes = reader.remaining;
|
|
29
|
+
if (tableBytes % 4 !== 0 || tableBytes / 4 > MAX_HANDLE_TABLE_ENTRIES) {
|
|
30
|
+
throw new RangeError(`RopBuffer: invalid ServerObjectHandleTable of ${tableBytes} bytes.`);
|
|
31
|
+
}
|
|
20
32
|
const handleTable = [];
|
|
21
33
|
while (reader.hasMore()) {
|
|
22
34
|
handleTable.push(reader.readUInt32LE());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RopBuffer.js","sourceRoot":"","sources":["../../../src/codec/RopBuffer.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA0B/D,MAAM,UAAU,eAAe,CAAC,GAAc;IAC1C,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,kGAAkG;IAClG,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,
|
|
1
|
+
{"version":3,"file":"RopBuffer.js","sourceRoot":"","sources":["../../../src/codec/RopBuffer.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA0B/D;;uCAEuC;AACvC,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAE5C,MAAM,UAAU,eAAe,CAAC,GAAc;IAC1C,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,kGAAkG;IAClG,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,4EAA4E;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvD,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACzF,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED;;yCAEyC;AACzC,MAAM,UAAU,eAAe,CAAC,MAAc;IAC1C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;IACpC,IAAI,UAAU,GAAG,CAAC,KAAK,CAAC,IAAI,UAAU,GAAG,CAAC,GAAG,wBAAwB,EAAE,CAAC;QACpE,MAAM,IAAI,UAAU,CAAC,iDAAiD,UAAU,SAAS,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,OAAO,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACtB,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -8,7 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
9
9
|
// SPDX-License-Identifier: MPL-2.0
|
|
10
10
|
///////////////////////////////////////////////////////////////////////////////
|
|
11
|
-
import { CalendarEventMongo, ContactMongo, FolderMongo, LabelMongo, MailboxMongo, MessageMongo, TaskMongo } from "@rapidmx/restapi/mongo";
|
|
11
|
+
import { AuditLogEntryMongo, CalendarEventMongo, ContactMongo, FolderMongo, LabelMongo, MailboxMongo, MessageMongo, TaskMongo, } from "@rapidmx/restapi/mongo";
|
|
12
12
|
import { BaseMapiEmsmdbRoute } from "../BaseMapiEmsmdbRoute.js";
|
|
13
13
|
import { RopLogonHandler } from "../rop/RopLogonHandler.js";
|
|
14
14
|
import { RopReleaseHandler } from "../rop/RopReleaseHandler.js";
|
|
@@ -51,6 +51,7 @@ let MapiEmsmdbRouteMongo = class MapiEmsmdbRouteMongo extends BaseMapiEmsmdbRout
|
|
|
51
51
|
this.contactClass = ContactMongo;
|
|
52
52
|
this.taskClass = TaskMongo;
|
|
53
53
|
this.labelClass = LabelMongo;
|
|
54
|
+
this.auditLogClass = AuditLogEntryMongo;
|
|
54
55
|
this.ropHandlerClasses = [
|
|
55
56
|
RopLogonHandler,
|
|
56
57
|
RopReleaseHandler,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapiEmsmdbRouteMongo.js","sourceRoot":"","sources":["../../../src/mongo/MapiEmsmdbRouteMongo.ts"],"names":[],"mappings":";;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,
|
|
1
|
+
{"version":3,"file":"MapiEmsmdbRouteMongo.js","sourceRoot":"","sources":["../../../src/mongo/MapiEmsmdbRouteMongo.ts"],"names":[],"mappings":";;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EACH,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,GACZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AACpF,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,+BAA+B,EAAE,MAAM,2CAA2C,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,6CAA6C,CAAC;AAChG,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,kCAAkC,EAAE,MAAM,8CAA8C,CAAC;AAClG,OAAO,EAAE,0CAA0C,EAAE,MAAM,sDAAsD,CAAC;AAClH,OAAO,EAAE,qCAAqC,EAAE,MAAM,iDAAiD,CAAC;AACxG,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC;AAElC;;;;;;GAMG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,mBAAiC;IAApE;;QACO,iBAAY,GAAQ,YAAY,CAAC;QACjC,gBAAW,GAAQ,WAAW,CAAC;QAC/B,iBAAY,GAAQ,YAAY,CAAC;QACjC,uBAAkB,GAAQ,kBAAkB,CAAC;QAC7C,iBAAY,GAAQ,YAAY,CAAC;QACjC,cAAS,GAAQ,SAAS,CAAC;QAC3B,eAAU,GAAQ,UAAU,CAAC;QAC7B,kBAAa,GAAQ,kBAAkB,CAAC;QACxC,sBAAiB,GAAU;YACjC,eAAe;YACf,iBAAiB;YACjB,oBAAoB;YACpB,2BAA2B;YAC3B,0BAA0B;YAC1B,oBAAoB;YACpB,mBAAmB;YACnB,qBAAqB;YACrB,+BAA+B;YAC/B,oBAAoB;YACpB,oBAAoB;YACpB,uBAAuB;YACvB,uBAAuB;YACvB,qBAAqB;YACrB,4BAA4B;YAC5B,uBAAuB;YACvB,iCAAiC;YACjC,wBAAwB;YACxB,sBAAsB;YACtB,kCAAkC;YAClC,0CAA0C;YAC1C,qCAAqC;SACxC,CAAC;IACN,CAAC;CAAA,CAAA;AAjCY,oBAAoB;IADhC,KAAK,CAAC,cAAc,CAAC;GACT,oBAAoB,CAiChC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PropertyType, readPropertyTag, readTaggedPropertyValue, writePropertyTag, writePropertyValue, } from "../codec/PropertyValue.js";
|
|
1
|
+
import { MAX_PROPERTY_TAG_COUNT, PropertyType, readPropertyTag, readPropertyTagArray, readTaggedPropertyValue, writePropertyTag, writePropertyValue, } from "../codec/PropertyValue.js";
|
|
2
2
|
export function readStat(reader) {
|
|
3
3
|
return {
|
|
4
4
|
sortType: reader.readUInt32LE(),
|
|
@@ -41,10 +41,10 @@ export const BLANK_STAT = {
|
|
|
41
41
|
* structures (`[MS-OXCDATA]` §2.9 - the same `PropertyType`-then-`PropertyId` encoding `PropertyValue.ts`'s own
|
|
42
42
|
* `readPropertyTag`/`writePropertyTag` already implement). */
|
|
43
43
|
export function readLargePropertyTagArray(reader) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
tags
|
|
44
|
+
const tags = readPropertyTagArray(reader, reader.readUInt32LE());
|
|
45
|
+
if (!tags) {
|
|
46
|
+
// Every requested column is resolved for every returned row, so the count is capped like EMSMDB's.
|
|
47
|
+
throw new RangeError(`NspiCodec: a LargePropertyTagArray may hold at most ${MAX_PROPERTY_TAG_COUNT} tags.`);
|
|
48
48
|
}
|
|
49
49
|
return tags;
|
|
50
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NspiCodec.js","sourceRoot":"","sources":["../../../src/nspi/NspiCodec.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,YAAY,EACZ,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,GAGrB,MAAM,2BAA2B,CAAC;AA6BnC,MAAM,UAAU,QAAQ,CAAC,MAAoB;IACzC,OAAO;QACH,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE;QAC/B,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE;QAClC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE;QACjC,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE;QAC3B,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE;QAC7B,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE;QAChC,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE;QAC/B,cAAc,EAAE,MAAM,CAAC,YAAY,EAAE;QACrC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE;KACpC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAoB,EAAE,IAAU;IACtD,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1C,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED;;kEAEkE;AAClE,MAAM,CAAC,MAAM,UAAU,GAAS;IAC5B,QAAQ,EAAE,CAAC;IACX,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,CAAC;IACb,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,CAAC;IACX,cAAc,EAAE,CAAC;IACjB,UAAU,EAAE,CAAC;CAChB,CAAC;AAEF;;8DAE8D;AAC9D,MAAM,UAAU,yBAAyB,CAAC,MAAoB;IAC1D,MAAM,
|
|
1
|
+
{"version":3,"file":"NspiCodec.js","sourceRoot":"","sources":["../../../src/nspi/NspiCodec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
3
|
-
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
-
import { StringUtils } from "@rapidrest/core";
|
|
1
|
+
import { boundedEscapedPattern } from "../RegexPatternUtils.js";
|
|
6
2
|
import { BufferReader, BufferWriter } from "../codec/BufferCursor.js";
|
|
7
3
|
import { PropertyType } from "../codec/PropertyValue.js";
|
|
8
4
|
import { defaultValueForType } from "../rop/PropertyResolvers.js";
|
|
@@ -12,6 +8,8 @@ import { BLANK_STAT, extractContentRestrictionSearchTerm, readLargePropertyTagAr
|
|
|
12
8
|
* (`SearchCommand.ts`'s `DisplayName`/`EmailAddress`). */
|
|
13
9
|
const PID_TAG_DISPLAY_NAME = 0x3001;
|
|
14
10
|
const PID_TAG_EMAIL_ADDRESS = 0x3003;
|
|
11
|
+
/** The most rows one `GetMatches` lookup asks the repo for per query - `RepoUtils.find()`'s own page cap. */
|
|
12
|
+
export const MAX_MATCH_ROWS = 1000;
|
|
15
13
|
const DEFAULT_COLUMNS = [
|
|
16
14
|
{ propertyId: PID_TAG_DISPLAY_NAME, propertyType: PropertyType.PtypString },
|
|
17
15
|
{ propertyId: PID_TAG_EMAIL_ADDRESS, propertyType: PropertyType.PtypString },
|
|
@@ -58,12 +56,16 @@ function valueForColumn(contact, column) {
|
|
|
58
56
|
* catastrophic-backtracking shapes, but that guard is for patterns a caller assembles from parts; escaping the
|
|
59
57
|
* entire term with `escapeRegExp` before it ever reaches here already prevents any of those shapes from forming
|
|
60
58
|
* in the first place, since no unescaped metacharacter survives. */
|
|
61
|
-
async function findMatchingContacts(mailboxUid, contactRepo, searchTerm) {
|
|
59
|
+
async function findMatchingContacts(mailboxUid, contactRepo, searchTerm, limit) {
|
|
60
|
+
// `limit` goes in both the query (what the SQL query builder reads) and the options (what Mongo reads);
|
|
61
|
+
// without it each backend silently falls back to its own 100-row default regardless of `RowCount`.
|
|
62
62
|
if (!searchTerm) {
|
|
63
|
-
return contactRepo.find({ mailboxUid }, { ignoreACL: true });
|
|
63
|
+
return contactRepo.find({ mailboxUid, limit }, { ignoreACL: true, limit });
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
// Bounded so the escaped operand never trips service-core's regex length guard, which would fail the whole
|
|
66
|
+
// NSPI call with INVALID_REQUEST for a long or metacharacter-heavy search term.
|
|
67
|
+
const pattern = boundedEscapedPattern(searchTerm);
|
|
68
|
+
const perField = await Promise.all(["displayName", "givenName", "surname", "company"].map((field) => contactRepo.find({ mailboxUid, [field]: `regex(${pattern})`, limit }, { ignoreACL: true, limit })));
|
|
67
69
|
const byUid = new Map();
|
|
68
70
|
for (const contact of perField.flat()) {
|
|
69
71
|
byUid.set(contact.uid, contact);
|
|
@@ -100,10 +102,8 @@ export async function handleNspiGetMatches(req, res, mailboxUid, contactRepo) {
|
|
|
100
102
|
}
|
|
101
103
|
if (reader.readUInt8()) {
|
|
102
104
|
// MinimalIds (an Explicit Table) - not honored, see function doc comment
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
reader.readUInt32LE();
|
|
106
|
-
}
|
|
105
|
+
// Skipped in one bounds-checked read rather than a loop over a client-supplied 32-bit count.
|
|
106
|
+
reader.readBytes(reader.readUInt32LE() * 4);
|
|
107
107
|
}
|
|
108
108
|
reader.readUInt32LE(); // InterfaceOptionFlags - reserved, always 0
|
|
109
109
|
const searchTerm = reader.readUInt8() ? extractContentRestrictionSearchTerm(reader) : undefined;
|
|
@@ -114,7 +114,7 @@ export async function handleNspiGetMatches(req, res, mailboxUid, contactRepo) {
|
|
|
114
114
|
const rowCount = reader.readUInt32LE();
|
|
115
115
|
const columns = reader.readUInt8() ? readLargePropertyTagArray(reader) : DEFAULT_COLUMNS;
|
|
116
116
|
// AuxiliaryBufferSize/AuxiliaryBuffer intentionally left unread - no auxiliary-payload support.
|
|
117
|
-
const matches = await findMatchingContacts(mailboxUid, contactRepo, searchTerm);
|
|
117
|
+
const matches = await findMatchingContacts(mailboxUid, contactRepo, searchTerm, Math.min(Math.max(rowCount, 1), MAX_MATCH_ROWS));
|
|
118
118
|
const page = matches.slice(0, rowCount);
|
|
119
119
|
const body = new BufferWriter();
|
|
120
120
|
body.writeUInt32LE(0); // StatusCode - success
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NspiGetMatchesHandler.js","sourceRoot":"","sources":["../../../src/nspi/NspiGetMatchesHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NspiGetMatchesHandler.js","sourceRoot":"","sources":["../../../src/nspi/NspiGetMatchesHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
import addressparser from "nodemailer/lib/addressparser/index.js";
|
|
6
|
+
import { literalQueryValue } from "./RestapiRules.js";
|
|
7
|
+
/** Splits a `PidTagDisplayTo`/`Cc`/`Bcc`-style string on the semicolons Outlook separates recipients with,
|
|
8
|
+
* trimming and dropping empty entries. Commas are not separators: a resolved recipient's display name commonly
|
|
9
|
+
* contains one (`Doe, Jane <jane@example.com>`). */
|
|
10
|
+
export function splitAddressList(value) {
|
|
11
|
+
if (!value) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
return value
|
|
15
|
+
.split(";")
|
|
16
|
+
.map((s) => s.trim())
|
|
17
|
+
.filter((s) => s.length > 0);
|
|
18
|
+
}
|
|
19
|
+
/** A bare `local@domain.tld` address: no whitespace (so no CR/LF), display name, angle brackets, quoting or
|
|
20
|
+
* separators. */
|
|
21
|
+
const PLAIN_EMAIL_ADDRESS = /^[^\s@<>()[\]",;:\\]+@[^\s@<>()[\]",;:\\]+\.[^\s@<>()[\]",;:\\.]+$/;
|
|
22
|
+
/** `true` for a plain SMTP address (see `PLAIN_EMAIL_ADDRESS`) no longer than RFC 5321's 254 characters. These
|
|
23
|
+
* strings reach MIME headers, the SMTP envelope and iCalendar `mailto:` lines, where a CR/LF would inject content. */
|
|
24
|
+
export function isPlainEmailAddress(value) {
|
|
25
|
+
return value.length <= 254 && PLAIN_EMAIL_ADDRESS.test(value);
|
|
26
|
+
}
|
|
27
|
+
/** Control characters (CR/LF included) are replaced in display names; nodemailer encodes the rest. */
|
|
28
|
+
function cleanName(name) {
|
|
29
|
+
return [...name].map((char) => (char.charCodeAt(0) < 0x20 || char.charCodeAt(0) === 0x7f ? " " : char)).join("").replace(/ +/g, " ").trim();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parses one `;`-separated entry with nodemailer's `addressparser`: `jane@example.com`, `Jane <jane@example.com>`,
|
|
33
|
+
* `"Doe, Jane" <jane@example.com>` or a bare display name `Jane Doe`. An entry holding several addresses yields one
|
|
34
|
+
* recipient each. Any address that isn't a plain SMTP address marks the entry invalid.
|
|
35
|
+
*/
|
|
36
|
+
export function parseRecipientEntry(entry) {
|
|
37
|
+
const parts = addressparser(entry, { flatten: true });
|
|
38
|
+
const addressed = parts.filter((part) => part.address);
|
|
39
|
+
if (addressed.length === 0) {
|
|
40
|
+
const name = cleanName(entry);
|
|
41
|
+
// Something address-shaped that addressparser couldn't take apart isn't a display name to look up.
|
|
42
|
+
return [/[@<>]/.test(name) ? { name, invalid: true } : { name }];
|
|
43
|
+
}
|
|
44
|
+
const nameOnlyParts = parts.filter((part) => !part.address && part.name).map((part) => part.name);
|
|
45
|
+
return addressed.map((part) => {
|
|
46
|
+
const name = cleanName(addressed.length === 1 ? [...nameOnlyParts, part.name].filter(Boolean).join(", ") : part.name);
|
|
47
|
+
const address = String(part.address);
|
|
48
|
+
return isPlainEmailAddress(address) && !/[\r\n]/.test(entry) ? { name, address } : { name, invalid: true };
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Every entry of a `PidTagDisplayTo`/`Cc`/`Bcc`-style string - see `parseRecipientEntry`. */
|
|
52
|
+
export function parseRecipientList(value) {
|
|
53
|
+
return splitAddressList(value).flatMap(parseRecipientEntry);
|
|
54
|
+
}
|
|
55
|
+
/** The plain addresses in a `PidTagDisplayTo`/`Cc`/`Bcc`-style string, including those written as
|
|
56
|
+
* `Name <address>`, skipping display names without an address and anything invalid. */
|
|
57
|
+
export function parseAddressList(value) {
|
|
58
|
+
return parseRecipientList(value)
|
|
59
|
+
.filter((entry) => entry.address !== undefined)
|
|
60
|
+
.map((entry) => entry.address);
|
|
61
|
+
}
|
|
62
|
+
/** The most contacts looked at when resolving one display name - two is enough to tell "exactly one" apart. */
|
|
63
|
+
const MAX_NAME_MATCHES = 2;
|
|
64
|
+
/** The most recipients (To, Cc and Bcc together) one submitted message or meeting may have - the same limit
|
|
65
|
+
* `@rapidmx/activesync`'s `ComposeMailCommand` enforces (`MAX_COMPOSE_RECIPIENTS`). */
|
|
66
|
+
export const MAX_RECIPIENTS_PER_MESSAGE = 500;
|
|
67
|
+
/** The caller's contacts whose display name is exactly `name`. The name comes from the client, so it is matched
|
|
68
|
+
* literally (`literalQueryValue`) and re-checked on the returned rows; a name the query layer rejects matches nothing. */
|
|
69
|
+
async function findContactsByDisplayName(context, name) {
|
|
70
|
+
if (!context.contactRepo) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const rows = await context.contactRepo.find({ mailboxUid: context.mailboxUid, displayName: literalQueryValue(name), limit: MAX_NAME_MATCHES }, { ignoreACL: true, limit: MAX_NAME_MATCHES });
|
|
75
|
+
return rows.filter((row) => row.displayName === name);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolves a display string into addresses. An entry carrying an address is used as is; a bare display name (Outlook
|
|
83
|
+
* writes names, not addresses, into `PidTagDisplayTo` once it has resolved a recipient against an address book) is
|
|
84
|
+
* looked up among the caller's own contacts by exact display name and used when exactly one contact matches, with
|
|
85
|
+
* that contact's first valid email address.
|
|
86
|
+
*/
|
|
87
|
+
export async function resolveRecipientList(value, context) {
|
|
88
|
+
const resolution = { recipients: [], unresolved: [], invalid: [] };
|
|
89
|
+
for (const entry of parseRecipientList(value)) {
|
|
90
|
+
if (entry.invalid) {
|
|
91
|
+
resolution.invalid.push(entry.name);
|
|
92
|
+
}
|
|
93
|
+
else if (entry.address) {
|
|
94
|
+
resolution.recipients.push({ name: entry.name, address: entry.address });
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const contacts = await findContactsByDisplayName(context, entry.name);
|
|
98
|
+
const address = contacts.length === 1 ? contacts[0].emails?.map((email) => email.address).find(isPlainEmailAddress) : undefined;
|
|
99
|
+
if (address) {
|
|
100
|
+
resolution.recipients.push({ name: entry.name, address });
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
resolution.unresolved.push(entry.name);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return resolution;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=AddressList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddressList.js","sourceRoot":"","sources":["../../../src/rop/AddressList.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BusyStatus } from "@rapidmx/restapi";
|
|
2
|
+
import { findAllCapped, MAX_COLLECTION_ROWS } from "./RepoPaging.js";
|
|
2
3
|
/** Degrades to empty-looking values for a `"calendarEvent:<uid>"` target whose real `CalendarEvent` has since
|
|
3
4
|
* vanished (soft-deleted or otherwise) - the same "don't fail the whole ROP over one stale row" principle
|
|
4
5
|
* `MessageTarget.resolveMessageInfo`/`FolderTarget.resolveFolderInfo` already apply. */
|
|
@@ -18,10 +19,12 @@ export async function resolveCalendarEventInfo(target, calendarEventRepo) {
|
|
|
18
19
|
attendees: event?.attendees ?? [],
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
/** The order a calendar folder's events are listed in: latest start first, ties broken by `uid`. */
|
|
23
|
+
export const CALENDAR_EVENT_SORT = { startDate: "DESC", uid: "ASC" };
|
|
24
|
+
/** Resolves the calendar events directly in `folderUid`, latest first and capped at `MAX_COLLECTION_ROWS`, as
|
|
25
|
+
* `"calendarEvent:<uid>"` target strings. */
|
|
26
|
+
export async function resolveFolderCalendarEvents(folderUid, calendarEventRepo, budget) {
|
|
27
|
+
const { items: events } = await findAllCapped(calendarEventRepo, { folderUid }, CALENDAR_EVENT_SORT, MAX_COLLECTION_ROWS, budget);
|
|
25
28
|
return events.map((e) => `calendarEvent:${e.uid}`);
|
|
26
29
|
}
|
|
27
30
|
//# sourceMappingURL=CalendarEventTarget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalendarEventTarget.js","sourceRoot":"","sources":["../../../src/rop/CalendarEventTarget.ts"],"names":[],"mappings":"AAKA,OAAO,EAAY,UAAU,EAAiC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"CalendarEventTarget.js","sourceRoot":"","sources":["../../../src/rop/CalendarEventTarget.ts"],"names":[],"mappings":"AAKA,OAAO,EAAY,UAAU,EAAiC,MAAM,kBAAkB,CAAC;AAEvF,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAiB,MAAM,iBAAiB,CAAC;AAuBpF;;wFAEwF;AACxF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAc,EAAE,iBAAiC;IAC5F,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,KAAK,GAA8B,MAAM,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnG,OAAO;QACH,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE;QACzB,QAAQ,EAAE,KAAK,EAAE,QAAQ;QACzB,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;QAC1C,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;QACtC,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,KAAK;QAClC,UAAU,EAAE,KAAK,EAAE,UAAU,IAAI,UAAU,CAAC,IAAI;QAChD,cAAc,EAAE,KAAK,EAAE,cAAc;QACrC,0BAA0B,EAAE,KAAK,EAAE,0BAA0B;QAC7D,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,IAAI,EAAE;QACjD,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE;KACpC,CAAC;AACN,CAAC;AAED,oGAAoG;AACpG,MAAM,CAAC,MAAM,mBAAmB,GAAa,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAE/E;6CAC6C;AAC7C,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,SAAiB,EAAE,iBAAiC,EAAE,MAAsB;IAC1H,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAgB,iBAAiB,EAAE,EAAE,SAAS,EAAE,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC,CAAC;IACjJ,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -14,10 +14,6 @@ export async function resolveContactInfo(target, contactRepo) {
|
|
|
14
14
|
jobTitle: contact?.jobTitle,
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
export async function resolveFolderContacts(folderUid, contactRepo) {
|
|
20
|
-
const contacts = await contactRepo.find({ folderUid }, { ignoreACL: true });
|
|
21
|
-
return contacts.map((c) => `contact:${c.uid}`);
|
|
22
|
-
}
|
|
17
|
+
/** The order a `CONTACTS` folder's contents table lists contacts in (see `ContentsTable.ts`). */
|
|
18
|
+
export const CONTACT_SORT = { displayName: "ASC", uid: "ASC" };
|
|
23
19
|
//# sourceMappingURL=ContactTarget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactTarget.js","sourceRoot":"","sources":["../../../src/rop/ContactTarget.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ContactTarget.js","sourceRoot":"","sources":["../../../src/rop/ContactTarget.ts"],"names":[],"mappings":"AA8BA;;sGAEsG;AACtG,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,WAA2B;IAChF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAwB,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,OAAO;QACH,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,EAAE;QACvC,SAAS,EAAE,OAAO,EAAE,SAAS;QAC7B,OAAO,EAAE,OAAO,EAAE,OAAO;QACzB,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO;QACpC,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW;QAChD,WAAW,EAAE,OAAO,EAAE,OAAO;QAC7B,QAAQ,EAAE,OAAO,EAAE,QAAQ;KAC9B,CAAC;AACN,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GAAa,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC"}
|