proton-mail-bridge-client 2.1.38 → 2.1.40
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -58
- package/dist/index.js.map +1 -1
- package/dist/services/local-index-service.d.ts +2 -0
- package/dist/services/local-index-service.d.ts.map +1 -1
- package/dist/services/local-index-service.js +53 -5
- package/dist/services/local-index-service.js.map +1 -1
- package/dist/services/smtp-service.d.ts.map +1 -1
- package/dist/services/smtp-service.js +22 -3
- package/dist/services/smtp-service.js.map +1 -1
- package/dist/utils/runtime-policy.js +3 -3
- package/dist/utils/runtime-policy.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -137,6 +137,7 @@ export declare function createServer(config: ProtonMailConfig, options?: {
|
|
|
137
137
|
deliveryQueueService: import("./services/delivery-queue-service.js").DeliveryQueueService;
|
|
138
138
|
snoozeService: import("./services/snooze-service.js").SnoozeService;
|
|
139
139
|
auditService: AuditService;
|
|
140
|
+
accountManager: AccountManager;
|
|
140
141
|
};
|
|
141
142
|
export declare function main(): Promise<void>;
|
|
142
143
|
export {};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3763,15 +3763,10 @@ export function createServer(config, options = {}) {
|
|
|
3763
3763
|
}
|
|
3764
3764
|
// dryRun: preview without sending
|
|
3765
3765
|
const dryRunSend = normalizeBoolean(args.dryRun, false);
|
|
3766
|
-
// RESTRICT_OUTBOUND_TO_SELF check
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
const ext = allR.filter(r => r.toLowerCase() !== selfAddr);
|
|
3771
|
-
if (ext.length > 0) {
|
|
3772
|
-
throw new McpError(ErrorCode.InvalidParams, `RESTRICT_OUTBOUND_TO_SELF is enabled. Cannot send to: ${ext.join(", ")}`);
|
|
3773
|
-
}
|
|
3774
|
-
}
|
|
3766
|
+
// RESTRICT_OUTBOUND_TO_SELF check — shared helper so a self-send to
|
|
3767
|
+
// "you+tag@..." isn't wrongly rejected (see its comment in runtime-policy.ts).
|
|
3768
|
+
// `from`'s own account (if any) is the correct "self" for a multi-account send.
|
|
3769
|
+
ensureOutboundRecipientsAllowed(config.runtime, (from ? accountManager.byAddress(from)?.config.smtp.username : undefined) ?? config.smtp.username, [...to, ...(cc ?? []), ...(bcc ?? [])]);
|
|
3775
3770
|
if (dryRunSend) {
|
|
3776
3771
|
return createTextResult({ dryRun: true, wouldSendTo: { to, cc: cc ?? [], bcc: bcc ?? [] }, subject, note: "No email was sent." });
|
|
3777
3772
|
}
|
|
@@ -3847,6 +3842,9 @@ export function createServer(config, options = {}) {
|
|
|
3847
3842
|
});
|
|
3848
3843
|
}
|
|
3849
3844
|
case "cancel_send": {
|
|
3845
|
+
// Zero policy gate: canceling a queued send mutates local delivery-queue
|
|
3846
|
+
// state, but nothing here ever checked read-only mode.
|
|
3847
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
3850
3848
|
// The queue id carries an account-slug prefix when the item was enqueued
|
|
3851
3849
|
// through a non-primary account (see send_email/schedule_draft) — resolve
|
|
3852
3850
|
// it back to that account's own deliveryQueueService, same as an
|
|
@@ -4002,14 +4000,9 @@ export function createServer(config, options = {}) {
|
|
|
4002
4000
|
const replyHtmlBody = includeQuoteReply && signedReply.htmlBody !== undefined
|
|
4003
4001
|
? buildReplyHtml(detail, signedReply.htmlBody)
|
|
4004
4002
|
: signedReply.htmlBody;
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
const ext = allR.filter(r => r.toLowerCase() !== selfAddr);
|
|
4009
|
-
if (ext.length > 0) {
|
|
4010
|
-
throw new McpError(ErrorCode.InvalidParams, `RESTRICT_OUTBOUND_TO_SELF is enabled. Cannot send to: ${ext.join(", ")}`);
|
|
4011
|
-
}
|
|
4012
|
-
}
|
|
4003
|
+
// Shared helper, and the sending account's own address as "self" —
|
|
4004
|
+
// see send_email's comment.
|
|
4005
|
+
ensureOutboundRecipientsAllowed(config.runtime, sendBundleForReply.config.smtp.username, [...to, ...cc, ...extraBcc]);
|
|
4013
4006
|
if (dryRunReply) {
|
|
4014
4007
|
return createTextResult({ dryRun: true, wouldSendTo: { to, cc, bcc: extraBcc }, subject: prefixedSubject(detail.subject, "Re:"), note: "No email was sent." }, false, [emailSource({ ...detail, id: prefixedIdFor(readBundleReply, detail.id) })]);
|
|
4015
4008
|
}
|
|
@@ -4087,14 +4080,9 @@ export function createServer(config, options = {}) {
|
|
|
4087
4080
|
throw new McpError(ErrorCode.InvalidParams, "Unable to infer reply recipients.");
|
|
4088
4081
|
}
|
|
4089
4082
|
const dryRunRa = normalizeBoolean(args.dryRun, false);
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
const ext = allR.filter(r => r.toLowerCase() !== selfAddr);
|
|
4094
|
-
if (ext.length > 0) {
|
|
4095
|
-
throw new McpError(ErrorCode.InvalidParams, `RESTRICT_OUTBOUND_TO_SELF is enabled. Cannot send to: ${ext.join(", ")}`);
|
|
4096
|
-
}
|
|
4097
|
-
}
|
|
4083
|
+
// Shared helper, and the sending account's own address as "self" —
|
|
4084
|
+
// see send_email's comment.
|
|
4085
|
+
ensureOutboundRecipientsAllowed(config.runtime, sendBundleForRa.config.smtp.username, [...toRa, ...ccRa, ...extraBccRa]);
|
|
4098
4086
|
if (dryRunRa) {
|
|
4099
4087
|
return createTextResult({ dryRun: true, wouldSendTo: { to: toRa, cc: ccRa, bcc: extraBccRa }, subject: prefixedSubject(detailRa.subject, "Re:"), note: "No email was sent." });
|
|
4100
4088
|
}
|
|
@@ -4189,14 +4177,9 @@ export function createServer(config, options = {}) {
|
|
|
4189
4177
|
ensureValidEmails(cc, "cc");
|
|
4190
4178
|
ensureValidEmails(bcc, "bcc");
|
|
4191
4179
|
const dryRunFwd = normalizeBoolean(args.dryRun, false);
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
const ext = allR.filter(r => r.toLowerCase() !== selfAddr);
|
|
4196
|
-
if (ext.length > 0) {
|
|
4197
|
-
throw new McpError(ErrorCode.InvalidParams, `RESTRICT_OUTBOUND_TO_SELF is enabled. Cannot send to: ${ext.join(", ")}`);
|
|
4198
|
-
}
|
|
4199
|
-
}
|
|
4180
|
+
// Shared helper, and the sending account's own address as "self" —
|
|
4181
|
+
// see send_email's comment.
|
|
4182
|
+
ensureOutboundRecipientsAllowed(config.runtime, sendBundleForFwd.config.smtp.username, [...to, ...cc, ...bcc]);
|
|
4200
4183
|
if (dryRunFwd) {
|
|
4201
4184
|
return createTextResult({ dryRun: true, wouldSendTo: { to, cc, bcc }, subject: prefixedSubject(detail.subject, "Fwd:"), note: "No email was sent." });
|
|
4202
4185
|
}
|
|
@@ -4267,6 +4250,9 @@ export function createServer(config, options = {}) {
|
|
|
4267
4250
|
}, false, [emailSource({ ...detail, id: prefixedIdFor(readBundleFwd, detail.id) })]);
|
|
4268
4251
|
}
|
|
4269
4252
|
case "create_draft": {
|
|
4253
|
+
// Local draft write — was only gated on the remote-sync side, so
|
|
4254
|
+
// PROTONMAIL_READ_ONLY never actually stopped a local draft being created.
|
|
4255
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
4270
4256
|
const to = parseEmails(optionalString(args, "to"));
|
|
4271
4257
|
const cc = parseEmails(optionalString(args, "cc"));
|
|
4272
4258
|
const bcc = parseEmails(optionalString(args, "bcc"));
|
|
@@ -4338,6 +4324,8 @@ export function createServer(config, options = {}) {
|
|
|
4338
4324
|
]);
|
|
4339
4325
|
}
|
|
4340
4326
|
case "create_reply_draft": {
|
|
4327
|
+
// Local draft write — same gap as create_draft, see its comment.
|
|
4328
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
4341
4329
|
// emailId carries the same "<slug>::" account prefix as everywhere else —
|
|
4342
4330
|
// this previously always read via the PRIMARY account's imapService
|
|
4343
4331
|
// regardless of that prefix, so replying to a non-primary account's email
|
|
@@ -4422,6 +4410,8 @@ export function createServer(config, options = {}) {
|
|
|
4422
4410
|
]);
|
|
4423
4411
|
}
|
|
4424
4412
|
case "create_forward_draft": {
|
|
4413
|
+
// Local draft write — same gap as create_draft, see its comment.
|
|
4414
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
4425
4415
|
// Same emailId account resolution as create_reply_draft — see its comment.
|
|
4426
4416
|
const { bundle: createForwardReadBundle, rest: createForwardEmailIdRest } = resolveAccountForEmailId(requireString(args, "emailId"));
|
|
4427
4417
|
const detail = await createForwardReadBundle.imapService.getEmailById(createForwardEmailIdRest);
|
|
@@ -4568,6 +4558,8 @@ export function createServer(config, options = {}) {
|
|
|
4568
4558
|
]);
|
|
4569
4559
|
}
|
|
4570
4560
|
case "update_draft": {
|
|
4561
|
+
// Local draft write — same gap as create_draft, see its comment.
|
|
4562
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
4571
4563
|
const { bundle: updateDraftBundle, rest: updateDraftIdRest } = resolveAccountForDraftId(requireString(args, "draftId"));
|
|
4572
4564
|
const to = args.to === undefined ? undefined : parseEmails(optionalString(args, "to"));
|
|
4573
4565
|
const cc = args.cc === undefined ? undefined : parseEmails(optionalString(args, "cc"));
|
|
@@ -4745,21 +4737,10 @@ export function createServer(config, options = {}) {
|
|
|
4745
4737
|
if (draft.replyTo && !isValidEmail(draft.replyTo)) {
|
|
4746
4738
|
throw new McpError(ErrorCode.InvalidParams, "replyTo must be a valid email address.");
|
|
4747
4739
|
}
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
// recipients against the IMAP login instead — rejecting mail to
|
|
4753
|
-
// the real self as "external" (and, the other way round, would
|
|
4754
|
-
// let mail to that IMAP-only address through as if it were
|
|
4755
|
-
// self). Every other RESTRICT_OUTBOUND_TO_SELF check in this
|
|
4756
|
-
// file already uses smtp.username, since that's the identity
|
|
4757
|
-
// mail actually sends as; this was the one inconsistent copy.
|
|
4758
|
-
const selfAddr = config.smtp.username.toLowerCase();
|
|
4759
|
-
const external = allRecipients.filter(r => r.toLowerCase() !== selfAddr);
|
|
4760
|
-
if (external.length > 0)
|
|
4761
|
-
throw new McpError(ErrorCode.InvalidParams, "PROTONMAIL_RESTRICT_OUTBOUND_TO_SELF is enabled. All recipients must be the authenticated user.");
|
|
4762
|
-
}
|
|
4740
|
+
// Shared helper, and the sending account's own address as "self" —
|
|
4741
|
+
// see send_email's comment. isSelfAddress also fixes the IMAP-vs-SMTP
|
|
4742
|
+
// username mismatch the old inline check's comment warned about.
|
|
4743
|
+
ensureOutboundRecipientsAllowed(config.runtime, sendBundleForDraft.config.smtp.username, [...draft.to, ...draft.cc, ...draft.bcc]);
|
|
4763
4744
|
if (normalizeBoolean(args.dryRun, false)) {
|
|
4764
4745
|
return createTextResult({
|
|
4765
4746
|
dryRun: true,
|
|
@@ -4953,14 +4934,9 @@ export function createServer(config, options = {}) {
|
|
|
4953
4934
|
if (draft.replyTo && !isValidEmail(draft.replyTo)) {
|
|
4954
4935
|
throw new McpError(ErrorCode.InvalidParams, "replyTo must be a valid email address.");
|
|
4955
4936
|
}
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
const selfAddr = config.smtp.username.toLowerCase();
|
|
4960
|
-
const external = allRecipients.filter((r) => r.toLowerCase() !== selfAddr);
|
|
4961
|
-
if (external.length > 0)
|
|
4962
|
-
throw new McpError(ErrorCode.InvalidParams, "PROTONMAIL_RESTRICT_OUTBOUND_TO_SELF is enabled. All recipients must be the authenticated user.");
|
|
4963
|
-
}
|
|
4937
|
+
// Shared helper, and the sending account's own address as "self" —
|
|
4938
|
+
// see send_draft's identical fix.
|
|
4939
|
+
ensureOutboundRecipientsAllowed(config.runtime, sendBundleForScheduleDraft.config.smtp.username, [...draft.to, ...draft.cc, ...draft.bcc]);
|
|
4964
4940
|
const queued = await withAudit(auditService, name, args, async () => sendBundleForScheduleDraft.deliveryQueueService.enqueue({
|
|
4965
4941
|
to: draft.to,
|
|
4966
4942
|
cc: draft.cc,
|
|
@@ -4990,6 +4966,8 @@ export function createServer(config, options = {}) {
|
|
|
4990
4966
|
});
|
|
4991
4967
|
}
|
|
4992
4968
|
case "delete_draft": {
|
|
4969
|
+
// Local draft write — same gap as create_draft, see its comment.
|
|
4970
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
4993
4971
|
const { bundle: deleteDraftBundle, rest: deleteDraftIdRest } = resolveAccountForDraftId(requireString(args, "draftId"));
|
|
4994
4972
|
const draft = await deleteDraftBundle.draftStore.getDraft(deleteDraftIdRest);
|
|
4995
4973
|
ensureDestructiveConfirmed(config.runtime, normalizeBoolean(args?.confirmed, false), "Permanently delete draft: " + draft.id);
|
|
@@ -5894,6 +5872,8 @@ export function createServer(config, options = {}) {
|
|
|
5894
5872
|
return createTextResult(filtered);
|
|
5895
5873
|
}
|
|
5896
5874
|
case "create_template": {
|
|
5875
|
+
// Local template write — same gap as create_draft, see its comment.
|
|
5876
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
5897
5877
|
const result = await withAudit(auditService, name, args, async () => templateService.create({
|
|
5898
5878
|
name: requireString(args, "name"),
|
|
5899
5879
|
subject: requireString(args, "subject"),
|
|
@@ -5911,6 +5891,8 @@ export function createServer(config, options = {}) {
|
|
|
5911
5891
|
return createTextResult(result);
|
|
5912
5892
|
}
|
|
5913
5893
|
case "delete_template": {
|
|
5894
|
+
// Local template write — same gap as create_draft, see its comment.
|
|
5895
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
5914
5896
|
const templateId = requireString(args, "id");
|
|
5915
5897
|
ensureDestructiveConfirmed(config.runtime, normalizeBoolean(args?.confirmed, false), "Permanently delete template: " + templateId);
|
|
5916
5898
|
const result = await withAudit(auditService, name, args, async () => templateService.delete(templateId));
|
|
@@ -7154,12 +7136,17 @@ export function createServer(config, options = {}) {
|
|
|
7154
7136
|
return createTextResult(result, false, result.saved.map((entry) => attachmentSource(result.emailId, entry.attachment)));
|
|
7155
7137
|
}
|
|
7156
7138
|
case "clear_cache":
|
|
7139
|
+
// Zero policy gate: this mutates local cache state, but nothing here
|
|
7140
|
+
// ever checked read-only mode.
|
|
7141
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
7157
7142
|
analyticsService.clearCache();
|
|
7158
7143
|
return createTextResult({
|
|
7159
7144
|
clearedAt: new Date().toISOString(),
|
|
7160
7145
|
...imapService.clearCache(),
|
|
7161
7146
|
});
|
|
7162
7147
|
case "clear_index":
|
|
7148
|
+
// Zero policy gate — same gap as clear_cache, see its comment.
|
|
7149
|
+
ensureMailboxWriteAllowed(config.runtime);
|
|
7163
7150
|
return createTextResult({
|
|
7164
7151
|
clearedAt: new Date().toISOString(),
|
|
7165
7152
|
...(await localIndexService.clear()),
|
|
@@ -7227,6 +7214,7 @@ export function createServer(config, options = {}) {
|
|
|
7227
7214
|
deliveryQueueService,
|
|
7228
7215
|
snoozeService,
|
|
7229
7216
|
auditService,
|
|
7217
|
+
accountManager,
|
|
7230
7218
|
};
|
|
7231
7219
|
}
|
|
7232
7220
|
export async function main() {
|
|
@@ -7245,7 +7233,7 @@ export async function main() {
|
|
|
7245
7233
|
// Explicitly chmod it too so the restriction actually takes effect on
|
|
7246
7234
|
// upgrade, not only on a brand-new dataDir.
|
|
7247
7235
|
await chmod(config.dataDir, 0o700).catch(() => { });
|
|
7248
|
-
const { server, smtpService, imapService, backgroundSyncService, deliveryQueueService, snoozeService } = createServer(config, {
|
|
7236
|
+
const { server, smtpService, imapService, backgroundSyncService, deliveryQueueService, snoozeService, accountManager } = createServer(config, {
|
|
7249
7237
|
startBackgroundSync: true,
|
|
7250
7238
|
});
|
|
7251
7239
|
logger.info("Starting ProtonMail MCP server", "MCPServer");
|
|
@@ -7262,7 +7250,11 @@ export async function main() {
|
|
|
7262
7250
|
backgroundSyncService.stop();
|
|
7263
7251
|
deliveryQueueService.stop();
|
|
7264
7252
|
snoozeService.stop();
|
|
7265
|
-
await Promise.allSettled([
|
|
7253
|
+
await Promise.allSettled([
|
|
7254
|
+
imapService.disconnect(),
|
|
7255
|
+
smtpService.close(),
|
|
7256
|
+
...accountManager.all().map((bundle) => bundle.localIndexService.close()),
|
|
7257
|
+
]);
|
|
7266
7258
|
process.exit(0);
|
|
7267
7259
|
};
|
|
7268
7260
|
process.on("SIGINT", () => {
|