@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
|
@@ -4,14 +4,28 @@
|
|
|
4
4
|
///////////////////////////////////////////////////////////////////////////////
|
|
5
5
|
import * as crypto from "crypto";
|
|
6
6
|
import MailComposer from "nodemailer/lib/mail-composer/index.js";
|
|
7
|
+
import { ApiErrors } from "@rapidrest/service-core";
|
|
7
8
|
import { findOrCreateWellKnownFolder, FolderType, MessageImportance, RecipientType, scanAndRelay, } from "@rapidmx/restapi";
|
|
9
|
+
import { MAX_RECIPIENTS_PER_MESSAGE, parseRecipientList, resolveRecipientList } from "./AddressList.js";
|
|
10
|
+
import { handleDataOwners, writeStreamKey } from "./HandleDataCache.js";
|
|
8
11
|
import { submitMeetingResponse } from "./MeetingMessageClassHandler.js";
|
|
12
|
+
import { handleDataStoreOf } from "./RopHandler.js";
|
|
13
|
+
import { readWriteStream } from "./RopWriteStreamHandler.js";
|
|
14
|
+
import { asEntity, isInvitePending } from "./RestapiRules.js";
|
|
9
15
|
const ROP_ID_SUBMIT_MESSAGE = 0x32;
|
|
10
16
|
/** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for both "the referenced handle isn't a draft
|
|
11
17
|
* message" and "the draft has no resolvable recipients/sender" - the same constant reused throughout this
|
|
12
18
|
* pragmatic subset as a generic "can't do this" signal, not a claim of exact per-condition `[MS-OXCRPC]`
|
|
13
19
|
* return-value-table parity. */
|
|
14
20
|
const ERROR_INVALID_OBJECT = 0x80070005;
|
|
21
|
+
/** `MAPI_E_INVALID_PARAMETER`: the draft has no recipients, a recipient that isn't a usable address, or no sender. */
|
|
22
|
+
const ERROR_INVALID_PARAMETER = 0x80070057;
|
|
23
|
+
/** `MAPI_E_NOT_FOUND`: a recipient given only by display name matches no single contact of the caller's. */
|
|
24
|
+
const ERROR_NOT_FOUND = 0x8004010f;
|
|
25
|
+
/** `MAPI_E_TOO_BIG`: more than `MAX_RECIPIENTS_PER_MESSAGE` recipients. */
|
|
26
|
+
const ERROR_TOO_BIG = 0x80040305;
|
|
27
|
+
/** `MAPI_E_CALL_FAILED`: the body written through `RopWriteStream` can no longer be reassembled (its chunks expired). */
|
|
28
|
+
const ERROR_CALL_FAILED = 0x80004005;
|
|
15
29
|
// The same well-known property IDs RopSetPropertiesHandler tracks - duplicated here (rather than imported)
|
|
16
30
|
// since importing them would only save a handful of literals; see that file for the real documentation of what
|
|
17
31
|
// each means.
|
|
@@ -31,18 +45,12 @@ const MESSAGE_CLASS_APPOINTMENT_PREFIX = "IPM.Appointment";
|
|
|
31
45
|
* through `MeetingMessageClassHandler.submitMeetingResponse()` instead of every other path here - see that
|
|
32
46
|
* function's own doc comment. */
|
|
33
47
|
const MESSAGE_CLASS_MEETING_RESPONSE_PREFIX = "IPM.Schedule.Meeting.Resp.";
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
return value
|
|
43
|
-
.split(/[;,]/)
|
|
44
|
-
.map((s) => s.trim())
|
|
45
|
-
.filter((s) => s.length > 0);
|
|
48
|
+
// Re-exported for existing importers; the implementation lives in AddressList.ts.
|
|
49
|
+
export { isPlainEmailAddress, parseAddressList } from "./AddressList.js";
|
|
50
|
+
function writeResult(writer, inputHandleIndex, returnValue) {
|
|
51
|
+
writer.writeUInt8(ROP_ID_SUBMIT_MESSAGE);
|
|
52
|
+
writer.writeUInt8(inputHandleIndex);
|
|
53
|
+
writer.writeUInt32LE(returnValue);
|
|
46
54
|
}
|
|
47
55
|
/**
|
|
48
56
|
* `RopSubmitMessage` (`[MS-OXOMSG]`/`[MS-OXCROPS]`): sends a composed message - the actual trigger point for
|
|
@@ -61,12 +69,12 @@ export function parseAddressList(value) {
|
|
|
61
69
|
* pragmatic subset's ROP coverage doesn't include. Instead, addressing is read from `PidTagDisplayTo`/
|
|
62
70
|
* `DisplayCc`/`DisplayBcc` - the same semicolon-separated "cached recipient display string" properties real
|
|
63
71
|
* Outlook *also* always sets via `RopSetProperties` alongside `RopModifyRecipients` (as a display-only
|
|
64
|
-
* convenience cache).
|
|
65
|
-
* addresses
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* than
|
|
72
|
+
* convenience cache). Entries are separated by `;` and parsed with nodemailer's `addressparser`, so both bare
|
|
73
|
+
* addresses and resolved `Name <address>` forms work. A client that resolved a name against an address book may
|
|
74
|
+
* write the display name alone; that is looked up among the caller's own contacts (see `resolveRecipientList`), and
|
|
75
|
+
* a name matching no single contact fails the submit with `MAPI_E_NOT_FOUND`. It is still **not** a substitute for
|
|
76
|
+
* real recipient rows (there is no recipient table to fall back on), so the whole send is refused rather than sent to
|
|
77
|
+
* fewer people than the user addressed. A malformed recipient fails with `MAPI_E_INVALID_PARAMETER`.
|
|
70
78
|
*
|
|
71
79
|
* `SubmitFlags` (`PreprocessOnly`, ...) is decoded to advance past it correctly but not honored - this
|
|
72
80
|
* pragmatic subset has no transport-agent preprocessing distinction to vary by flag.
|
|
@@ -79,6 +87,12 @@ export function parseAddressList(value) {
|
|
|
79
87
|
* own `requestReceipt` field - honored only when the client explicitly sets it, not this mailbox's
|
|
80
88
|
* `alwaysRequestReceiptInternal`/`External` defaults (those apply to the REST/webmail compose path only).
|
|
81
89
|
*
|
|
90
|
+
* **Once per draft.** A mail or meeting-response draft is marked `submitted` as soon as a submit gets past the handle
|
|
91
|
+
* check, whatever the outcome, and a submitted draft can't be submitted again (`MAPI_E_INVALID_OBJECT`) or changed by
|
|
92
|
+
* `RopSetProperties`/`RopWriteStream`; its write-stream chunks are deleted once read. Each `Execute` runs at most
|
|
93
|
+
* `MAX_SUBMITS_PER_EXECUTE` submits, and a message may have at most `MAX_RECIPIENTS_PER_MESSAGE` recipients
|
|
94
|
+
* (`MAPI_E_TOO_BIG`), counted before any display name is looked up.
|
|
95
|
+
*
|
|
82
96
|
* **Calendar branches**: a draft whose `PidTagMessageClass` starts with `"IPM.Appointment"` is routed to
|
|
83
97
|
* `submitAppointment()` instead of the mail path below - see that method's own doc comment. One starting with
|
|
84
98
|
* `"IPM.Schedule.Meeting.Resp."` (an attendee's own accept/decline/tentative response to a meeting this server
|
|
@@ -96,39 +110,53 @@ export class RopSubmitMessageHandler {
|
|
|
96
110
|
const inputHandleIndex = reader.readUInt8();
|
|
97
111
|
reader.readUInt8(); // SubmitFlags - see class doc comment
|
|
98
112
|
const handle = context.session.handles[inputHandleIndex];
|
|
99
|
-
if (!handle || handle.type !== "message") {
|
|
113
|
+
if (!handle || handle.type !== "message" || handle.submitted) {
|
|
100
114
|
writer.writeUInt8(ROP_ID_SUBMIT_MESSAGE);
|
|
101
115
|
writer.writeUInt8(inputHandleIndex);
|
|
102
116
|
writer.writeUInt32LE(ERROR_INVALID_OBJECT);
|
|
103
117
|
return;
|
|
104
118
|
}
|
|
119
|
+
context.budget?.chargeSubmit();
|
|
105
120
|
const properties = handle.draftProperties ?? {};
|
|
106
121
|
const messageClass = properties[String(PID_TAG_MESSAGE_CLASS)] ?? "IPM.Note";
|
|
107
122
|
if (messageClass.startsWith(MESSAGE_CLASS_APPOINTMENT_PREFIX)) {
|
|
108
123
|
await this.submitAppointment(handle, context, writer, inputHandleIndex);
|
|
109
124
|
return;
|
|
110
125
|
}
|
|
126
|
+
// From here on the draft is used up by this attempt, whatever its outcome, so it can't be sent again.
|
|
127
|
+
handle.submitted = true;
|
|
111
128
|
if (messageClass.startsWith(MESSAGE_CLASS_MEETING_RESPONSE_PREFIX)) {
|
|
112
|
-
await submitMeetingResponse(messageClass, properties, context);
|
|
113
|
-
writer.writeUInt8(ROP_ID_SUBMIT_MESSAGE);
|
|
114
|
-
writer.writeUInt8(inputHandleIndex);
|
|
115
|
-
writer.writeUInt32LE(0); // ReturnValue - success, see MeetingMessageClassHandler's own doc comment
|
|
116
|
-
// on why every failure mode there is a silent no-op rather than surfaced here.
|
|
129
|
+
writeResult(writer, inputHandleIndex, await submitMeetingResponse(messageClass, properties, context));
|
|
117
130
|
return;
|
|
118
131
|
}
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
132
|
+
const recipientCount = [PID_TAG_DISPLAY_TO, PID_TAG_DISPLAY_CC, PID_TAG_DISPLAY_BCC].reduce((count, propertyId) => count + parseRecipientList(properties[String(propertyId)]).length, 0);
|
|
133
|
+
if (recipientCount > MAX_RECIPIENTS_PER_MESSAGE) {
|
|
134
|
+
writeResult(writer, inputHandleIndex, ERROR_TOO_BIG);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const resolutions = [
|
|
138
|
+
await resolveRecipientList(properties[String(PID_TAG_DISPLAY_TO)], context),
|
|
139
|
+
await resolveRecipientList(properties[String(PID_TAG_DISPLAY_CC)], context),
|
|
140
|
+
await resolveRecipientList(properties[String(PID_TAG_DISPLAY_BCC)], context),
|
|
141
|
+
];
|
|
142
|
+
const [to, cc, bcc] = resolutions.map((resolution) => resolution.recipients);
|
|
122
143
|
const mailbox = await context.mailboxRepo.findOne(context.mailboxUid, { ignoreACL: true });
|
|
123
144
|
const envelopeFrom = mailbox?.primarySmtpAddress;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
writer
|
|
127
|
-
|
|
145
|
+
// Refuse the whole send over one malformed or unresolvable recipient rather than silently dropping it.
|
|
146
|
+
if (!envelopeFrom || to.length + cc.length + bcc.length === 0 || resolutions.some((resolution) => resolution.invalid.length > 0)) {
|
|
147
|
+
writeResult(writer, inputHandleIndex, ERROR_INVALID_PARAMETER);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (resolutions.some((resolution) => resolution.unresolved.length > 0)) {
|
|
151
|
+
writeResult(writer, inputHandleIndex, ERROR_NOT_FOUND);
|
|
128
152
|
return;
|
|
129
153
|
}
|
|
130
154
|
const subject = properties[String(PID_TAG_SUBJECT)] ?? "";
|
|
131
|
-
const bodyText = resolveDraftBody(context, inputHandleIndex, properties);
|
|
155
|
+
const bodyText = await resolveDraftBody(context, inputHandleIndex, properties);
|
|
156
|
+
if (bodyText === undefined) {
|
|
157
|
+
writeResult(writer, inputHandleIndex, ERROR_CALL_FAILED);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
132
160
|
const requestReceipt = properties[String(PID_TAG_READ_RECEIPT_REQUESTED)] === "true";
|
|
133
161
|
// "Do not deliver before" - a real Outlook compose option, tracked as a plain ISO-8601 string by
|
|
134
162
|
// RopSetPropertiesHandler.stringifyValue()'s PtypTime encoding.
|
|
@@ -137,9 +165,9 @@ export class RopSubmitMessageHandler {
|
|
|
137
165
|
const isDeferred = deferredSendTime !== undefined && deferredSendTime.getTime() > Date.now();
|
|
138
166
|
const raw = await new MailComposer({
|
|
139
167
|
from: envelopeFrom,
|
|
140
|
-
to,
|
|
141
|
-
cc,
|
|
142
|
-
bcc,
|
|
168
|
+
to: to.map(mailAddress),
|
|
169
|
+
cc: cc.map(mailAddress),
|
|
170
|
+
bcc: bcc.map(mailAddress),
|
|
143
171
|
subject,
|
|
144
172
|
text: bodyText,
|
|
145
173
|
// A real Disposition-Notification-To request, mirroring BaseMessageRoute.send()'s own explicit
|
|
@@ -151,12 +179,12 @@ export class RopSubmitMessageHandler {
|
|
|
151
179
|
})
|
|
152
180
|
.compile()
|
|
153
181
|
.build();
|
|
154
|
-
const envelopeTo = [...to, ...cc, ...bcc];
|
|
182
|
+
const envelopeTo = [...to, ...cc, ...bcc].map((recipient) => recipient.address);
|
|
155
183
|
const bodyBlobKey = `bodies/${crypto.randomUUID()}`;
|
|
156
184
|
const recipients = [
|
|
157
|
-
...to.map((
|
|
158
|
-
...cc.map((
|
|
159
|
-
...bcc.map((
|
|
185
|
+
...to.map((recipient) => storedRecipient(recipient, RecipientType.TO)),
|
|
186
|
+
...cc.map((recipient) => storedRecipient(recipient, RecipientType.CC)),
|
|
187
|
+
...bcc.map((recipient) => storedRecipient(recipient, RecipientType.BCC)),
|
|
160
188
|
];
|
|
161
189
|
if (isDeferred) {
|
|
162
190
|
// Mirrors BaseMessageRoute.send()'s own scheduledSendTime branch: park the message in Outbox,
|
|
@@ -182,25 +210,31 @@ export class RopSubmitMessageHandler {
|
|
|
182
210
|
scheduledSendTime: deferredSendTime,
|
|
183
211
|
requestReceipt,
|
|
184
212
|
}), { ignoreACL: true });
|
|
213
|
+
// Adding a message to a folder always bumps its sync key too - see `refreshFolderCounts()`'s own doc comment.
|
|
214
|
+
await context.notifyFolderCounts?.([outbox.uid], { bumpSyncKey: true });
|
|
185
215
|
writer.writeUInt8(ROP_ID_SUBMIT_MESSAGE);
|
|
186
216
|
writer.writeUInt8(inputHandleIndex);
|
|
187
217
|
writer.writeUInt32LE(0); // ReturnValue - success
|
|
188
218
|
return;
|
|
189
219
|
}
|
|
190
|
-
const
|
|
191
|
-
|
|
220
|
+
const relayed = await scanAndRelay(raw, envelopeFrom, envelopeTo, context.scanPipeline, context.mailTransport, context.blobStore);
|
|
221
|
+
// The Sent Items copy stores exactly what was relayed: scanAndRelay may have added a Message-ID header, and
|
|
222
|
+
// that header's value (plus the thread it derived) is what recipients' copies carry and what recall targets.
|
|
223
|
+
await context.blobStore.put(bodyBlobKey, relayed.raw, { contentType: "message/rfc822" });
|
|
192
224
|
const sentFolder = await findOrCreateWellKnownFolder(context.folderRepo, context.folderClass, context.mailboxUid, FolderType.SENT_ITEMS);
|
|
193
225
|
await context.messageRepo.create(new context.messageClass({
|
|
194
226
|
folderUid: sentFolder.uid,
|
|
195
227
|
mailboxUid: context.mailboxUid,
|
|
196
|
-
messageId:
|
|
228
|
+
messageId: relayed.messageId,
|
|
229
|
+
conversationId: relayed.conversationId,
|
|
230
|
+
encrypted: relayed.encrypted,
|
|
197
231
|
subject,
|
|
198
232
|
from: { address: envelopeFrom, type: RecipientType.TO },
|
|
199
233
|
recipients,
|
|
200
234
|
sentDate: new Date(),
|
|
201
235
|
receivedDate: new Date(),
|
|
202
236
|
bodyBlobKey,
|
|
203
|
-
sanitizedHtmlBlobKey,
|
|
237
|
+
sanitizedHtmlBlobKey: relayed.sanitizedHtmlBlobKey,
|
|
204
238
|
bodyPreview: bodyText.slice(0, 200),
|
|
205
239
|
flags: { read: true, flagged: false, answered: false, forwarded: false },
|
|
206
240
|
importance: MessageImportance.NORMAL,
|
|
@@ -208,105 +242,99 @@ export class RopSubmitMessageHandler {
|
|
|
208
242
|
hasAttachments: false,
|
|
209
243
|
requestReceipt,
|
|
210
244
|
}), { ignoreACL: true });
|
|
245
|
+
// Adding a message to a folder always bumps its sync key too - see `refreshFolderCounts()`'s own doc comment.
|
|
246
|
+
await context.notifyFolderCounts?.([sentFolder.uid], { bumpSyncKey: true });
|
|
211
247
|
writer.writeUInt8(ROP_ID_SUBMIT_MESSAGE);
|
|
212
248
|
writer.writeUInt8(inputHandleIndex);
|
|
213
249
|
writer.writeUInt32LE(0); // ReturnValue - success
|
|
214
250
|
}
|
|
215
251
|
/**
|
|
216
|
-
* Submits a Calendar item. The appointment itself is already persisted (`RopSaveChangesMessageHandler`
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* decoded into `CalendarEvent.attendees` at Save time). No attendees means no invite to send (e.g. a private,
|
|
220
|
-
* non-meeting appointment) - a well-formed success response either way, since the appointment already exists.
|
|
252
|
+
* Submits a Calendar item. The appointment itself is already persisted (`RopSaveChangesMessageHandler` writes the
|
|
253
|
+
* real `CalendarEvent` row at Save time, unlike a mail draft, which stays purely in-session until Submit), so there
|
|
254
|
+
* is nothing left to store and nothing is sent from here.
|
|
221
255
|
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
256
|
+
* **Invites are restapi's `MeetingSchedulingJob`'s job.** That job sends an iTIP `REQUEST` for every
|
|
257
|
+
* organizer-owned event whose `inviteSequenceSent` differs from its `sequence`, claiming each revision with a
|
|
258
|
+
* versioned update before sending and building the invite with restapi's own `buildEventIcs` (so a recurring
|
|
259
|
+
* meeting's invite carries its `RRULE` and exceptions). Saving stamps `inviteSequenceSent = sequence`, so a meeting
|
|
260
|
+
* that is only saved ("Save & Close", or "save changes but don't send") invites no one. Submitting clears the stamp
|
|
261
|
+
* (`inviteSequenceSent: null`) with a versioned update, which makes the job send the current revision exactly once.
|
|
262
|
+
* - A revision that is already waiting for the job (submitted and not yet sent, or never stamped) is left alone, so
|
|
263
|
+
* submitting it again before the job runs doesn't cause a second invite.
|
|
264
|
+
* - The update is versioned (`asEntity`). The job only ever claims a waiting revision, so a conflict here comes from
|
|
265
|
+
* some other edit (an attendee's reply updating the row, a REST edit); the row is read again and the check repeated,
|
|
266
|
+
* up to `MAX_INVITE_REQUEST_ATTEMPTS` times, after which the ROP fails (`MAPI_E_CALL_FAILED`).
|
|
267
|
+
* - Submitting a revision the job has already sent sends it again: the client asked to send.
|
|
224
268
|
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
* method=REQUEST` MIME alternative and an `.ics` attachment - the standard dual form real invite emails use)
|
|
228
|
-
* - reusing the identical `scanAndRelay()` pipeline the mail path above already calls.
|
|
269
|
+
* Only the organizer's own copy may be submitted (an attendee's copy of someone else's meeting answers
|
|
270
|
+
* `MAPI_E_INVALID_OBJECT`, as before, and nothing is changed).
|
|
229
271
|
*/
|
|
230
272
|
async submitAppointment(handle, context, writer, inputHandleIndex) {
|
|
231
273
|
const uid = handle.entityUid.startsWith("calendarEvent:") ? handle.entityUid.slice("calendarEvent:".length) : undefined;
|
|
232
274
|
const event = uid ? await context.calendarEventRepo.findOne(uid, { ignoreACL: true }) : undefined;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
275
|
+
const mailbox = event?.mailboxUid === context.mailboxUid ? await context.mailboxRepo.findOne(context.mailboxUid, { ignoreACL: true }) : undefined;
|
|
276
|
+
const callerAddresses = mailbox ? [mailbox.primarySmtpAddress, ...(mailbox.aliasAddresses ?? [])].map((a) => a.toLowerCase()) : [];
|
|
277
|
+
const isOrganizer = !!event && callerAddresses.includes((event.organizer?.address ?? "").toLowerCase());
|
|
278
|
+
if (!isOrganizer) {
|
|
279
|
+
writeResult(writer, inputHandleIndex, ERROR_INVALID_OBJECT);
|
|
237
280
|
return;
|
|
238
281
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
282
|
+
writeResult(writer, inputHandleIndex, (await requestInvites(context, uid, event)) ? 0 : ERROR_NOT_FOUND);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/** How many times `requestInvites` re-reads a row whose versioned update lost to another edit before giving up. */
|
|
286
|
+
export const MAX_INVITE_REQUEST_ATTEMPTS = 3;
|
|
287
|
+
/** Makes restapi's `MeetingSchedulingJob` send invites for the organizer copy `event`'s current revision (see
|
|
288
|
+
* `submitAppointment`). `false` when the row disappeared meanwhile. */
|
|
289
|
+
async function requestInvites(context, uid, event) {
|
|
290
|
+
let row = event;
|
|
291
|
+
for (let attempt = 0; attempt < MAX_INVITE_REQUEST_ATTEMPTS; attempt++) {
|
|
292
|
+
if (!row) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
if (isInvitePending(row)) {
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
await context.calendarEventRepo.update({ uid: row.uid, version: row.version, inviteSequenceSent: null }, asEntity(context.calendarEventRepo, row), { ignoreACL: true });
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
if (err?.code !== ApiErrors.INVALID_OBJECT_VERSION) {
|
|
304
|
+
throw err;
|
|
255
305
|
}
|
|
306
|
+
row = await context.calendarEventRepo.findOne(uid, { ignoreACL: true });
|
|
256
307
|
}
|
|
257
|
-
writer.writeUInt8(ROP_ID_SUBMIT_MESSAGE);
|
|
258
|
-
writer.writeUInt8(inputHandleIndex);
|
|
259
|
-
writer.writeUInt32LE(0); // ReturnValue - success
|
|
260
308
|
}
|
|
309
|
+
throw new Error("RopSubmitMessage: the meeting kept changing while its invites were requested.");
|
|
261
310
|
}
|
|
262
|
-
/**
|
|
263
|
-
function
|
|
264
|
-
return
|
|
311
|
+
/** A recipient as nodemailer's `MailComposer` takes it: a display name only when there is one. */
|
|
312
|
+
function mailAddress(recipient) {
|
|
313
|
+
return recipient.name ? { name: recipient.name, address: recipient.address } : recipient.address;
|
|
265
314
|
}
|
|
266
|
-
/**
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return value.replace(/\\/g, "\\\\").replace(/;/g, "\\;").replace(/,/g, "\\,").replace(/\r?\n/g, "\\n");
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Builds a minimal `RFC 5545`/`RFC 5546` `METHOD:REQUEST` iCalendar document for `event`. Deliberately not a
|
|
273
|
-
* general-purpose iCalendar writer (see `AutodiscoverXml.ts`'s own doc comment for the same "hand-build just
|
|
274
|
-
* the fields this pass needs" precedent) - no `RRULE` (recurring meeting invites are a documented gap, same as
|
|
275
|
-
* this pragmatic subset's other recurrence-adjacent limitations), no line-folding at the 75-octet boundary
|
|
276
|
-
* `RFC 5545` §3.1 technically requires (every field emitted here is short enough in practice that folding would
|
|
277
|
-
* never trigger), no `VTIMEZONE` block (times are always emitted as UTC `Z`-suffixed values instead).
|
|
278
|
-
*/
|
|
279
|
-
function buildMeetingRequestIcs(event, organizerAddress) {
|
|
280
|
-
const lines = [
|
|
281
|
-
"BEGIN:VCALENDAR",
|
|
282
|
-
"PRODID:-//RapidREST//Mail//EN",
|
|
283
|
-
"VERSION:2.0",
|
|
284
|
-
"METHOD:REQUEST",
|
|
285
|
-
"BEGIN:VEVENT",
|
|
286
|
-
`UID:${event.icalUid}`,
|
|
287
|
-
`SEQUENCE:${event.sequence}`,
|
|
288
|
-
`DTSTAMP:${formatIcsDateUtc(new Date())}`,
|
|
289
|
-
`DTSTART:${formatIcsDateUtc(event.startDate)}`,
|
|
290
|
-
`DTEND:${formatIcsDateUtc(event.endDate)}`,
|
|
291
|
-
`SUMMARY:${escapeIcsText(event.title)}`,
|
|
292
|
-
...(event.location ? [`LOCATION:${escapeIcsText(event.location)}`] : []),
|
|
293
|
-
`ORGANIZER:mailto:${organizerAddress}`,
|
|
294
|
-
...event.attendees.map((attendee) => `ATTENDEE;RSVP=TRUE:mailto:${attendee.address}`),
|
|
295
|
-
"STATUS:CONFIRMED",
|
|
296
|
-
"END:VEVENT",
|
|
297
|
-
"END:VCALENDAR",
|
|
298
|
-
];
|
|
299
|
-
return lines.join("\r\n");
|
|
315
|
+
/** A recipient as the Sent Items copy stores it. */
|
|
316
|
+
function storedRecipient(recipient, type) {
|
|
317
|
+
return { address: recipient.address, ...(recipient.name ? { displayName: recipient.name } : {}), type };
|
|
300
318
|
}
|
|
301
319
|
/** Prefers a `RopWriteStream`-accumulated body (the real path a large body takes) over an inline `PidTagBody`
|
|
302
320
|
* set directly via `RopSetProperties` (only realistic for a short body small enough to set inline) - see
|
|
303
321
|
* `RopOpenStreamHandler`'s write-mode branch for how `writeTargetHandleIndex` links a stream handle back to the
|
|
304
|
-
* draft message handle it was opened against.
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
322
|
+
* draft message handle it was opened against. The generation must match too, so a stream left over from an
|
|
323
|
+
* earlier message at the same handle index never supplies this message's body. `undefined` when the stream's
|
|
324
|
+
* chunks can no longer be reassembled - sending a truncated body would be worse than failing. */
|
|
325
|
+
async function resolveDraftBody(context, messageHandleIndex, properties) {
|
|
326
|
+
const generation = context.session.handles[messageHandleIndex].generation;
|
|
327
|
+
for (const [index, candidate] of Object.entries(context.session.handles)) {
|
|
328
|
+
if (candidate.type === "stream" &&
|
|
329
|
+
candidate.writeTargetHandleIndex === messageHandleIndex &&
|
|
330
|
+
candidate.writeTargetGeneration === generation &&
|
|
331
|
+
candidate.writeSize) {
|
|
332
|
+
const raw = await readWriteStream(context, Number(index), candidate);
|
|
333
|
+
// The chunks are only needed for this one submit; best effort, they expire anyway.
|
|
334
|
+
await handleDataStoreOf(context)
|
|
335
|
+
.delete(writeStreamKey(context.session.uid, Number(index), candidate.generation), handleDataOwners(context.session.uid, context.session.userUid))
|
|
336
|
+
.catch(() => undefined);
|
|
337
|
+
return raw?.toString("utf16le").replace(/\0+$/, "");
|
|
310
338
|
}
|
|
311
339
|
}
|
|
312
340
|
return properties[String(PID_TAG_BODY)] ?? "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RopSubmitMessageHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSubmitMessageHandler.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RopSubmitMessageHandler.js","sourceRoot":"","sources":["../../../src/rop/RopSubmitMessageHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
+
import { handleDataOwners, writeStreamKey } from "./HandleDataCache.js";
|
|
2
|
+
import { handleDataStoreOf } from "./RopHandler.js";
|
|
1
3
|
const ROP_ID_WRITE_STREAM = 0x2d;
|
|
2
4
|
/** The well-known MAPI HRESULT `MAPI_E_INVALID_OBJECT`, reused for "the referenced handle isn't a write-mode
|
|
3
5
|
* stream (or doesn't exist)" - the same constant `RopReadStreamHandler` uses for its own analogous check. */
|
|
4
6
|
const ERROR_INVALID_OBJECT = 0x80070005;
|
|
7
|
+
/** `MAPI_E_TOO_BIG`, for a write that would take the stream past `MAX_WRITE_STREAM_BYTES`. */
|
|
8
|
+
const ERROR_TOO_BIG = 0x80040305;
|
|
9
|
+
/** The largest body a write stream accumulates. */
|
|
10
|
+
export const MAX_WRITE_STREAM_BYTES = 4 * 1024 * 1024;
|
|
11
|
+
/** How long a write stream's chunks are kept after its last write - the session's own idle lifetime. */
|
|
12
|
+
export const WRITE_STREAM_TTL_SECONDS = 15 * 60;
|
|
13
|
+
// Re-exported for existing importers; the key lives next to the other handle data keys.
|
|
14
|
+
export { writeStreamKey } from "./HandleDataCache.js";
|
|
5
15
|
/**
|
|
6
16
|
* `RopWriteStream` (`[MS-OXCPRPT]`/`[MS-OXCROPS]`): writes bytes to a stream opened in `ReadWrite`/`Create`
|
|
7
17
|
* mode (`RopOpenStreamHandler`'s write-mode branch - the only kind of writable stream this pragmatic subset
|
|
8
|
-
* ever produces, always a `RopCreateMessage` draft's `PidTagBody`).
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
18
|
+
* ever produces, always a `RopCreateMessage` draft's `PidTagBody`). Each write is stored as a chunk keyed by its
|
|
19
|
+
* offset in the `HandleDataStore` (Redis when configured), not in the session: only `writeSize` is session state.
|
|
20
|
+
* Keying by offset makes a retried write (after a request whose session save lost a conflict) replace its chunk
|
|
21
|
+
* instead of appending it twice. Up to `MAX_WRITE_STREAM_BYTES`; a write past that fails with `MAPI_E_TOO_BIG` and
|
|
22
|
+
* nothing is stored, as it is when the session's or user's handle data quota (`handleDataOwners`) is used up. A stream
|
|
23
|
+
* whose draft has already been submitted takes no more writes. `RopSubmitMessageHandler` reassembles the body (`readWriteStream`) once composing is complete.
|
|
14
24
|
*
|
|
15
25
|
* Like `RopReadStream`, `[MS-OXCROPS]` documents only one combined response-buffer shape for this ROP (no
|
|
16
26
|
* separate Success/Failure pages) - `WrittenSize` is always present, `0` standing in for the failure case.
|
|
@@ -20,26 +30,43 @@ const ERROR_INVALID_OBJECT = 0x80070005;
|
|
|
20
30
|
export class RopWriteStreamHandler {
|
|
21
31
|
constructor() {
|
|
22
32
|
this.ropId = ROP_ID_WRITE_STREAM;
|
|
33
|
+
this.failureTailBytes = 2; // DataSize/WrittenSize
|
|
23
34
|
}
|
|
24
|
-
handle(reader, writer, context) {
|
|
35
|
+
async handle(reader, writer, context) {
|
|
25
36
|
reader.readUInt8(); // LogonId - this pragmatic subset doesn't track multiple concurrent logons per session
|
|
26
37
|
const inputHandleIndex = reader.readUInt8();
|
|
27
38
|
const dataSize = reader.readUInt16LE();
|
|
28
39
|
const data = reader.readBytes(dataSize);
|
|
29
40
|
const handle = context.session.handles[inputHandleIndex];
|
|
30
|
-
|
|
41
|
+
const target = handle?.writeTargetHandleIndex !== undefined ? context.session.handles[handle.writeTargetHandleIndex] : undefined;
|
|
42
|
+
if (!handle || handle.type !== "stream" || handle.writeTargetHandleIndex === undefined || target?.submitted) {
|
|
31
43
|
writer.writeUInt8(ROP_ID_WRITE_STREAM);
|
|
32
44
|
writer.writeUInt8(inputHandleIndex);
|
|
33
45
|
writer.writeUInt32LE(ERROR_INVALID_OBJECT);
|
|
34
46
|
writer.writeUInt16LE(0); // WrittenSize - see class doc comment on why this is still written on failure
|
|
35
47
|
return;
|
|
36
48
|
}
|
|
37
|
-
const
|
|
38
|
-
|
|
49
|
+
const existingSize = handle.writeSize ?? 0;
|
|
50
|
+
const stored = existingSize + data.length <= MAX_WRITE_STREAM_BYTES &&
|
|
51
|
+
(data.length === 0 ||
|
|
52
|
+
(await handleDataStoreOf(context).putChunk(writeStreamKey(context.session.uid, inputHandleIndex, handle.generation), existingSize, data, WRITE_STREAM_TTL_SECONDS, handleDataOwners(context.session.uid, context.session.userUid))));
|
|
53
|
+
if (!stored) {
|
|
54
|
+
writer.writeUInt8(ROP_ID_WRITE_STREAM);
|
|
55
|
+
writer.writeUInt8(inputHandleIndex);
|
|
56
|
+
writer.writeUInt32LE(ERROR_TOO_BIG);
|
|
57
|
+
writer.writeUInt16LE(0); // WrittenSize
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
handle.writeSize = existingSize + data.length;
|
|
39
61
|
writer.writeUInt8(ROP_ID_WRITE_STREAM);
|
|
40
62
|
writer.writeUInt8(inputHandleIndex);
|
|
41
63
|
writer.writeUInt32LE(0); // ReturnValue - success
|
|
42
64
|
writer.writeUInt16LE(data.length); // WrittenSize
|
|
43
65
|
}
|
|
44
66
|
}
|
|
67
|
+
/** The bytes written so far to the write stream `stream` at `handleIndex`, or `undefined` when they can no longer be
|
|
68
|
+
* reassembled (a chunk expired or was evicted). */
|
|
69
|
+
export async function readWriteStream(context, handleIndex, stream) {
|
|
70
|
+
return handleDataStoreOf(context).readChunks(writeStreamKey(context.session.uid, handleIndex, stream.generation), stream.writeSize ?? 0);
|
|
71
|
+
}
|
|
45
72
|
//# sourceMappingURL=RopWriteStreamHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RopWriteStreamHandler.js","sourceRoot":"","sources":["../../../src/rop/RopWriteStreamHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RopWriteStreamHandler.js","sourceRoot":"","sources":["../../../src/rop/RopWriteStreamHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,10 +10,6 @@ export async function resolveTaskInfo(target, taskRepo) {
|
|
|
10
10
|
dueDate: task?.dueDate,
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
export async function resolveFolderTasks(folderUid, taskRepo) {
|
|
16
|
-
const tasks = await taskRepo.find({ folderUid }, { ignoreACL: true });
|
|
17
|
-
return tasks.map((t) => `task:${t.uid}`);
|
|
18
|
-
}
|
|
13
|
+
/** The order a `TASKS` folder's contents table lists tasks in (see `ContentsTable.ts`). */
|
|
14
|
+
export const TASK_SORT = { title: "ASC", uid: "ASC" };
|
|
19
15
|
//# sourceMappingURL=TaskTarget.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskTarget.js","sourceRoot":"","sources":["../../../src/rop/TaskTarget.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TaskTarget.js","sourceRoot":"","sources":["../../../src/rop/TaskTarget.ts"],"names":[],"mappings":"AAyBA;;0FAE0F;AAC1F,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,QAAwB;IAC1E,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAqB,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,OAAO;QACH,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;QACxB,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,KAAK;QACnC,OAAO,EAAE,IAAI,EAAE,OAAO;KACzB,CAAC;AACN,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,MAAM,SAAS,GAAa,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sends `message` and throws unless the transport accepted it for at least one recipient and rejected none.
|
|
3
|
+
*
|
|
4
|
+
* The same rule as restapi's own `sendOrThrow()` (`transport/TransportResultUtils.ts`), which isn't exported from
|
|
5
|
+
* the `@rapidmx/restapi` package root, so it can't be imported here; keep the two in sync. Every bundled transport
|
|
6
|
+
* reports a failed relay through `TransportResult.rejected` rather than throwing, so a bare `send()` would treat a
|
|
7
|
+
* rejected message as sent.
|
|
8
|
+
*/
|
|
9
|
+
export async function sendOrThrow(transport, message) {
|
|
10
|
+
const result = await transport.send(message);
|
|
11
|
+
if (!result || (result.accepted ?? []).length === 0 || (result.rejected ?? []).length > 0) {
|
|
12
|
+
throw new Error(`The mail transport did not accept the message (rejected: ${(result?.rejected ?? []).length}).`);
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=TransportSend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransportSend.js","sourceRoot":"","sources":["../../../src/rop/TransportSend.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAwB,EAAE,OAAwB;IAChF,MAAM,MAAM,GAAgC,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1E,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;IACrH,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC"}
|