weaver-work-cli 0.1.28 → 0.1.31
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/chunks/archive-U766FTFH.js +2537 -0
- package/dist/chunks/archive-oa-DMWEKX3L.js +1317 -0
- package/dist/chunks/asset-TCR7VDEV.js +2109 -0
- package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
- package/dist/chunks/blog-EVZWGDVM.js +2157 -0
- package/dist/chunks/caizhilian-JOWS6SL5.js +10087 -0
- package/dist/chunks/calendar-5WNCV66Q.js +1195 -0
- package/dist/chunks/chunk-2DUV44UX.js +15606 -0
- package/dist/chunks/chunk-324YPTC2.js +1607 -0
- package/dist/chunks/chunk-65QMVWHS.js +231 -0
- package/dist/chunks/chunk-6V7ZLF34.js +387 -0
- package/dist/chunks/chunk-AC7KJWC5.js +358 -0
- package/dist/chunks/chunk-AJ62BGAW.js +29 -0
- package/dist/chunks/chunk-BUSC6UAE.js +43 -0
- package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
- package/dist/chunks/chunk-D4LTJSJD.js +477 -0
- package/dist/chunks/chunk-EG6ZU444.js +654 -0
- package/dist/chunks/chunk-EZALDOQH.js +383 -0
- package/dist/chunks/chunk-FMPJJYYI.js +106 -0
- package/dist/chunks/chunk-G2JSIUWF.js +769 -0
- package/dist/chunks/chunk-GCG2NMWR.js +703 -0
- package/dist/chunks/chunk-GPMFD4RD.js +75 -0
- package/dist/chunks/chunk-H3WDBYJW.js +508 -0
- package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
- package/dist/chunks/chunk-J7RJTZSV.js +5556 -0
- package/dist/chunks/chunk-LUSPKZKY.js +53 -0
- package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
- package/dist/chunks/chunk-NOODWMCL.js +584 -0
- package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
- package/dist/chunks/chunk-P26ZWSKU.js +73 -0
- package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
- package/dist/chunks/chunk-R2IJAK7T.js +464 -0
- package/dist/chunks/chunk-R7O5PUWO.js +205 -0
- package/dist/chunks/chunk-RCGYCOMG.js +6962 -0
- package/dist/chunks/chunk-VZTXRG6X.js +403 -0
- package/dist/chunks/chunk-WHD4XMRP.js +161 -0
- package/dist/chunks/chunk-YLCYX7LE.js +371 -0
- package/dist/chunks/chunk-ZEDWSH32.js +68 -0
- package/dist/chunks/continuation-2CKSBLA6.js +11 -0
- package/dist/chunks/continuation-HZIZRZBX.js +13 -0
- package/dist/chunks/continuation-NLECEJPX.js +11 -0
- package/dist/chunks/ebuilder-form-NJ4YK6CC.js +2276 -0
- package/dist/chunks/ehr-MMYN36VA.js +5241 -0
- package/dist/chunks/employee-SAK2QYXX.js +11 -0
- package/dist/chunks/esb-HIWHOU7Q.js +141 -0
- package/dist/chunks/fna-KBACQTA5.js +1444 -0
- package/dist/chunks/host-3OHS5QUX.js +21 -0
- package/dist/chunks/host-IG6KEH5Q.js +19 -0
- package/dist/chunks/host-KQL5N4HO.js +23 -0
- package/dist/chunks/host-LLSZQCWR.js +17 -0
- package/dist/chunks/hrm-LYEC67ZQ.js +244 -0
- package/dist/chunks/im-RN2UKAEU.js +252 -0
- package/dist/chunks/invoice-EEPHLAF6.js +5179 -0
- package/dist/chunks/jiuchuanhui-WVVZYSJE.js +1940 -0
- package/dist/chunks/lazy-dispatch-MDOFFL2S.js +28 -0
- package/dist/chunks/mail-LNQLTF6L.js +2695 -0
- package/dist/chunks/meeting-XSD3BDVQ.js +504 -0
- package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
- package/dist/chunks/okr-TMWTIU2K.js +2482 -0
- package/dist/chunks/plan-A2FSFA7T.js +2025 -0
- package/dist/chunks/project-T26QLBQF.js +1361 -0
- package/dist/chunks/registry-2VLUAESA.js +14 -0
- package/dist/chunks/registry-JCFEYXOE.js +18 -0
- package/dist/chunks/registry-NYPYMZXG.js +16 -0
- package/dist/chunks/registry-Q7OQJ3SU.js +19 -0
- package/dist/chunks/registry-ZJMJVWFA.js +19 -0
- package/dist/chunks/room-recommend-UR4ZDZS6.js +20 -0
- package/dist/chunks/schedule-5L2PM4M6.js +24 -0
- package/dist/chunks/state-Y2XBP6YE.js +15 -0
- package/dist/chunks/workflow-TR6PG2SL.js +245 -0
- package/dist/cmd/argv.js +45 -0
- package/dist/cmd/docs/index.js +3 -3
- package/dist/cmd/lazy-dispatch.js +20 -0
- package/dist/cmd/root.js +2 -4
- package/dist/cmd/setup/index.js +2 -2
- package/dist/cmd/skills/index.js +2 -2
- package/dist/core/package-paths.js +47 -0
- package/dist/index.js +163 -7
- package/dist/internal/e10/auth/xiaoe.js +3 -3
- package/dist/internal/e10/request-runtime.js +18 -62
- package/dist/internal/skills/detector.js +2 -2
- package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
- package/dist/shortcuts/contract/host.js +91 -35
- package/dist/shortcuts/contract/index.js +213 -0
- package/dist/shortcuts/contract/manifest.js +928 -0
- package/dist/shortcuts/contract/ooxml/docx.js +295 -0
- package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
- package/dist/shortcuts/contract/ooxml/zip.js +158 -0
- package/dist/shortcuts/contract/operations/assistant.js +1156 -0
- package/dist/shortcuts/contract/operations/clause-library.js +522 -0
- package/dist/shortcuts/contract/operations/compare.js +193 -0
- package/dist/shortcuts/contract/operations/credit-page.js +34 -0
- package/dist/shortcuts/contract/operations/flow.js +98 -0
- package/dist/shortcuts/contract/operations/page.js +66 -0
- package/dist/shortcuts/contract/operations/performance.js +733 -0
- package/dist/shortcuts/contract/operations/quote.js +557 -0
- package/dist/shortcuts/contract/operations/recommend.js +78 -0
- package/dist/shortcuts/contract/operations/registry.js +18 -0
- package/dist/shortcuts/contract/operations/review.js +83 -0
- package/dist/shortcuts/contract/operations/shared.js +37 -0
- package/dist/shortcuts/contract/operations/upload.js +108 -0
- package/dist/shortcuts/contract/operations/write.js +3 -2
- package/dist/shortcuts/index.js +140 -40
- package/dist/shortcuts/invoice/host.js +2 -1
- package/dist/shortcuts/invoice/manifest.js +36 -12
- package/dist/shortcuts/invoice/operations/issuing-qys.js +132 -36
- package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
- package/dist/shortcuts/invoice/operations/reim.js +81 -5
- package/dist/shortcuts/invoice/operations/shared.js +12 -5
- package/dist/shortcuts/meeting/host.js +45 -3
- package/dist/shortcuts/meeting/invitation/docx.js +442 -0
- package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
- package/dist/shortcuts/meeting/operations/attachment.js +442 -0
- package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
- package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
- package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
- package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
- package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
- package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
- package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
- package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
- package/dist/shortcuts/meeting/operations/invitation.js +458 -0
- package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
- package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
- package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
- package/dist/shortcuts/meeting/operations/receipts.js +1 -1
- package/dist/shortcuts/meeting/operations/registry.js +18 -0
- package/dist/shortcuts/meeting/operations/summary.js +276 -0
- package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
- package/dist/shortcuts/meeting/operations.js +42 -1
- package/dist/shortcuts/meeting/qr/encoder.js +427 -0
- package/dist/shortcuts/meeting/qr/render.js +103 -0
- package/dist/shortcuts/workflow/index.js +3 -0
- package/dist/shortcuts/workflow/operations/form.js +17 -5
- package/dist/shortcuts/workflow/operations/read.js +13 -6
- package/dist/shortcuts/workflow/operations/registry.js +2 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +331 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +133 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +326 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +113 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +259 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoListRows.js +64 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoOutputPlanner.js +28 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.aggregate.js +70 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +267 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +392 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +165 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +448 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +348 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +222 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +66 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +502 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +540 -0
- package/docs/_catalog.md +1 -0
- package/docs/contract.md +39 -4
- package/docs/invoice.md +7 -7
- package/docs/todo-smart-convert/README.md +171 -0
- package/docs/todo-smart-convert/data-contract.md +236 -0
- package/docs/todo-smart-convert/mock/ai-todo-query-target.json +209 -0
- package/docs/todo-smart-convert/subgroup-rules.md +245 -0
- package/package.json +3 -2
- package/scripts/bundle.mjs +63 -0
- package/scripts/package-skill.mjs +1 -1
- package/skill-template/business-info.json +25 -4
- package/skill-template/domains/jinchengda.md +16 -3
- package/skill-template/domains/yepiaotong.md +3 -3
- package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
- package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
- package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
- package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
- package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
- package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
- package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
- package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
- package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
- package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
- package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
- package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
- package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
- package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
- package/skills/weaver-e10-meeting/SKILL.md +493 -17
- package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
- package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
- package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-workflow/SKILL.md +23 -1
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +282 -0
- package/skills/weaver-e10-workflow/scripts/todo-summary.cjs +695 -0
- package/skills/weaver-e10-yepiaotong/SKILL.md +15 -11
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +10 -7
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +41 -14
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +54 -26
- package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +8 -2
- package/templates/meeting/invitation.docx +0 -0
|
@@ -0,0 +1,2695 @@
|
|
|
1
|
+
import { createRequire as __esbuildCreateRequire } from 'node:module';
|
|
2
|
+
const require = __esbuildCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
E10ApiError,
|
|
5
|
+
createE10RequestRuntime,
|
|
6
|
+
requireE10Session
|
|
7
|
+
} from "./chunk-H3WDBYJW.js";
|
|
8
|
+
import {
|
|
9
|
+
E10_SESSION_EXPIRED_MESSAGE,
|
|
10
|
+
getActiveProfile
|
|
11
|
+
} from "./chunk-324YPTC2.js";
|
|
12
|
+
import {
|
|
13
|
+
CliError,
|
|
14
|
+
isCliError,
|
|
15
|
+
toErrorEnvelope
|
|
16
|
+
} from "./chunk-LUSPKZKY.js";
|
|
17
|
+
import "./chunk-BUSC6UAE.js";
|
|
18
|
+
|
|
19
|
+
// src/shortcuts/mail/index.ts
|
|
20
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
21
|
+
|
|
22
|
+
// src/shortcuts/mail/continuation.ts
|
|
23
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { resolve } from "node:path";
|
|
28
|
+
|
|
29
|
+
// src/shortcuts/mail/errors.ts
|
|
30
|
+
var MailCliError = class extends CliError {
|
|
31
|
+
type;
|
|
32
|
+
subtype;
|
|
33
|
+
code;
|
|
34
|
+
retryable;
|
|
35
|
+
stage;
|
|
36
|
+
details;
|
|
37
|
+
partialData;
|
|
38
|
+
constructor(type, subtype, message, options = {}) {
|
|
39
|
+
super(message, options.exitCode ?? 5 /* InternalError */);
|
|
40
|
+
this.name = "MailCliError";
|
|
41
|
+
this.type = type;
|
|
42
|
+
this.subtype = subtype;
|
|
43
|
+
this.code = options.code;
|
|
44
|
+
this.retryable = options.retryable ?? false;
|
|
45
|
+
this.stage = options.stage;
|
|
46
|
+
this.details = options.details;
|
|
47
|
+
this.partialData = options.partialData;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
function mailValidationError(subtype, message, details) {
|
|
51
|
+
return new MailCliError("validation", subtype, message, {
|
|
52
|
+
details,
|
|
53
|
+
exitCode: 2 /* UsageError */
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function mailAuthError(subtype, message, details) {
|
|
57
|
+
return new MailCliError("authentication", subtype, message, {
|
|
58
|
+
details,
|
|
59
|
+
exitCode: 3 /* AuthError */
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function mailNetworkError(subtype, message, options = {}) {
|
|
63
|
+
return new MailCliError("network", subtype, message, {
|
|
64
|
+
...options,
|
|
65
|
+
retryable: options.retryable ?? true,
|
|
66
|
+
exitCode: 4 /* NetworkError */
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/shortcuts/mail/continuation.ts
|
|
71
|
+
function stateRoot(ctx) {
|
|
72
|
+
const configured = ctx?.config?.path();
|
|
73
|
+
if (configured) return resolve(configured, "..");
|
|
74
|
+
return process.env.WEAVER_WORK_CLI_HOME || process.env.WORK_CLI_HOME || resolve(homedir(), ".weaver-work-cli");
|
|
75
|
+
}
|
|
76
|
+
async function loadKey(ctx) {
|
|
77
|
+
const keysDir = resolve(stateRoot(ctx), "keys");
|
|
78
|
+
const filename = resolve(keysDir, "mail-continuation.key");
|
|
79
|
+
await mkdir(keysDir, { recursive: true, mode: 448 });
|
|
80
|
+
if (existsSync(filename)) return readFile(filename);
|
|
81
|
+
const key = randomBytes(32);
|
|
82
|
+
try {
|
|
83
|
+
await writeFile(filename, key, { flag: "wx", mode: 384 });
|
|
84
|
+
if (process.platform !== "win32") await chmod(filename, 384).catch(() => void 0);
|
|
85
|
+
return key;
|
|
86
|
+
} catch {
|
|
87
|
+
return readFile(filename);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function encode(value) {
|
|
91
|
+
return Buffer.from(JSON.stringify(value)).toString("base64url");
|
|
92
|
+
}
|
|
93
|
+
function signature(payload, key) {
|
|
94
|
+
return createHmac("sha256", key).update(payload).digest("base64url");
|
|
95
|
+
}
|
|
96
|
+
function createMailContinuationSigner(ctx) {
|
|
97
|
+
return {
|
|
98
|
+
async issue(payload, ttlMs = 10 * 6e4) {
|
|
99
|
+
const issuedAt = Date.now();
|
|
100
|
+
const body = encode({ ...payload, issuedAt, expiresAt: issuedAt + ttlMs });
|
|
101
|
+
const sig = signature(body, await loadKey(ctx));
|
|
102
|
+
return `${body}.${sig}`;
|
|
103
|
+
},
|
|
104
|
+
async verify(token, expectedOperation) {
|
|
105
|
+
if (typeof token !== "string" || !token.includes(".")) {
|
|
106
|
+
throw mailValidationError("continuation_invalid", "continuation \u65E0\u6548");
|
|
107
|
+
}
|
|
108
|
+
const [body, provided] = token.split(".");
|
|
109
|
+
const expected = signature(body, await loadKey(ctx));
|
|
110
|
+
const valid = provided.length === expected.length && timingSafeEqual(Buffer.from(provided), Buffer.from(expected));
|
|
111
|
+
if (!valid) throw mailValidationError("continuation_invalid", "continuation \u7B7E\u540D\u6821\u9A8C\u5931\u8D25");
|
|
112
|
+
let value;
|
|
113
|
+
try {
|
|
114
|
+
value = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
|
|
115
|
+
} catch {
|
|
116
|
+
throw mailValidationError("continuation_invalid", "continuation \u5185\u5BB9\u65E0\u6CD5\u89E3\u6790");
|
|
117
|
+
}
|
|
118
|
+
if (value.operation !== expectedOperation) {
|
|
119
|
+
throw mailValidationError("continuation_mismatch", "continuation \u4E0D\u5C5E\u4E8E\u5F53\u524D\u64CD\u4F5C");
|
|
120
|
+
}
|
|
121
|
+
if (!Number.isSafeInteger(value.expiresAt) || value.expiresAt < Date.now()) {
|
|
122
|
+
throw mailValidationError("continuation_expired", "continuation \u5DF2\u8FC7\u671F");
|
|
123
|
+
}
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/shortcuts/mail/host.ts
|
|
130
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
131
|
+
function inferProfile(ctx) {
|
|
132
|
+
const options = ctx.getGlobalOptions();
|
|
133
|
+
return options.profile || getActiveProfile();
|
|
134
|
+
}
|
|
135
|
+
function mailRandomKey() {
|
|
136
|
+
const r = randomBytes2(3).toString("hex").slice(0, 6).toLowerCase();
|
|
137
|
+
return `randomkey_${r}=${r}`;
|
|
138
|
+
}
|
|
139
|
+
function formBody(form) {
|
|
140
|
+
if (!form) return void 0;
|
|
141
|
+
const params = new URLSearchParams();
|
|
142
|
+
for (const [key, value] of Object.entries(form)) {
|
|
143
|
+
if (value === void 0 || value === null) continue;
|
|
144
|
+
params.set(key, typeof value === "string" ? value : String(value));
|
|
145
|
+
}
|
|
146
|
+
return params;
|
|
147
|
+
}
|
|
148
|
+
function omitEmptyQueryValues(query) {
|
|
149
|
+
if (!query) return void 0;
|
|
150
|
+
return Object.fromEntries(Object.entries(query).filter(([, value]) => value !== "" && value !== void 0 && value !== null));
|
|
151
|
+
}
|
|
152
|
+
function assertPath(requestPath) {
|
|
153
|
+
if (typeof requestPath !== "string" || !requestPath.startsWith("/") || requestPath.startsWith("//")) {
|
|
154
|
+
throw mailValidationError("path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u5FC5\u987B\u662F\u76F8\u5BF9\u7EDD\u5BF9\u8DEF\u5F84");
|
|
155
|
+
}
|
|
156
|
+
if (/^https?:/i.test(requestPath) || /[\r\n]/.test(requestPath) || requestPath.includes("/../")) {
|
|
157
|
+
throw mailValidationError("path_invalid", "\u8BF7\u6C42\u8DEF\u5F84\u4E0D\u5141\u8BB8\u8DE8\u57DF\u6216\u8DEF\u5F84\u9003\u9038");
|
|
158
|
+
}
|
|
159
|
+
if (!requestPath.startsWith("/api/")) {
|
|
160
|
+
throw mailValidationError("path_not_allowed", "\u90AE\u4EF6\u6A21\u5757\u53EA\u80FD\u8C03\u7528 /api/ \u8DEF\u5F84");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function isMailSuccess(value) {
|
|
164
|
+
if (!value || typeof value !== "object") return false;
|
|
165
|
+
const code = value.code;
|
|
166
|
+
if (code !== void 0) {
|
|
167
|
+
const c = Number(code);
|
|
168
|
+
if (!Number.isFinite(c) || c !== 200 && c !== 0) return false;
|
|
169
|
+
}
|
|
170
|
+
if (value.success === false) return false;
|
|
171
|
+
if (value.status === false) return false;
|
|
172
|
+
const data = value.data;
|
|
173
|
+
if (data === null || data === void 0) return true;
|
|
174
|
+
if (typeof data === "string") return data.length > 0;
|
|
175
|
+
if (typeof data === "boolean") return data === true;
|
|
176
|
+
if (Array.isArray(data)) return true;
|
|
177
|
+
if (typeof data === "object") {
|
|
178
|
+
if (data.success === 0 || data.success === false) return false;
|
|
179
|
+
if (data.status === 0 || data.status === false) return false;
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
function mailMessage(value) {
|
|
185
|
+
if (!value || typeof value !== "object") return "\u90AE\u4EF6\u63A5\u53E3\u8FD4\u56DE\u4E1A\u52A1\u5931\u8D25";
|
|
186
|
+
const candidates = [value.msg, value.message, value.data?.message, value.data?.msg];
|
|
187
|
+
for (const item of candidates) {
|
|
188
|
+
if (typeof item === "string" && item.trim()) return item;
|
|
189
|
+
}
|
|
190
|
+
return "\u90AE\u4EF6\u63A5\u53E3\u8FD4\u56DE\u4E1A\u52A1\u5931\u8D25";
|
|
191
|
+
}
|
|
192
|
+
function createMailHost(ctx, dependencies = {}) {
|
|
193
|
+
let e10Session = null;
|
|
194
|
+
let sessionContext = null;
|
|
195
|
+
const requireSession = dependencies.requireSession || requireE10Session;
|
|
196
|
+
async function ensureSession() {
|
|
197
|
+
if (!e10Session) {
|
|
198
|
+
e10Session = await requireSession(ctx);
|
|
199
|
+
sessionContext = {
|
|
200
|
+
baseUrl: e10Session.getBaseUrl(),
|
|
201
|
+
profile: inferProfile(ctx),
|
|
202
|
+
userId: e10Session.userId,
|
|
203
|
+
tenantKey: e10Session.tenantKey,
|
|
204
|
+
eteamsId: e10Session.eteamsId
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return e10Session;
|
|
208
|
+
}
|
|
209
|
+
async function getSession() {
|
|
210
|
+
await ensureSession();
|
|
211
|
+
return sessionContext;
|
|
212
|
+
}
|
|
213
|
+
async function runtime() {
|
|
214
|
+
return createE10RequestRuntime(ctx, await ensureSession(), {
|
|
215
|
+
interceptors: dependencies.interceptors,
|
|
216
|
+
fetch: dependencies.fetch
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async function request(request2) {
|
|
220
|
+
const {
|
|
221
|
+
method,
|
|
222
|
+
path,
|
|
223
|
+
query,
|
|
224
|
+
body,
|
|
225
|
+
operation,
|
|
226
|
+
form,
|
|
227
|
+
multipart,
|
|
228
|
+
headers: extraHeaders = {},
|
|
229
|
+
timeoutMs = 3e4
|
|
230
|
+
} = request2;
|
|
231
|
+
assertPath(path);
|
|
232
|
+
const resolvedMethod = method || (body === void 0 && form === void 0 && multipart === void 0 ? "GET" : "POST");
|
|
233
|
+
let response;
|
|
234
|
+
try {
|
|
235
|
+
response = await (await runtime()).requestJson({
|
|
236
|
+
module: "mail",
|
|
237
|
+
operation,
|
|
238
|
+
method: resolvedMethod,
|
|
239
|
+
path,
|
|
240
|
+
query: omitEmptyQueryValues(query),
|
|
241
|
+
body: multipart === void 0 ? body : void 0,
|
|
242
|
+
form: multipart === void 0 && form === void 0 ? void 0 : formBody(form ?? {}),
|
|
243
|
+
formData: multipart,
|
|
244
|
+
// 邮件接口依赖 langType / timeZoneOffset 头
|
|
245
|
+
headers: { "X-Requested-With": "XMLHttpRequest", "langType": "zh_CN", "timeZoneOffset": "-480", ...extraHeaders },
|
|
246
|
+
timeoutMs
|
|
247
|
+
});
|
|
248
|
+
} catch (error) {
|
|
249
|
+
if (error instanceof E10ApiError && error.type === "network") {
|
|
250
|
+
throw mailNetworkError(error.subtype, error.message, {
|
|
251
|
+
retryable: error.retryable,
|
|
252
|
+
details: error.details
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
if (response.status === 401 || response.status === 302) {
|
|
258
|
+
throw mailAuthError("session_expired", E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
259
|
+
}
|
|
260
|
+
if (response.parseError) {
|
|
261
|
+
if (response.status < 200 || response.status >= 300) {
|
|
262
|
+
throw new MailCliError("api", "http_error", `\u90AE\u4EF6\u63A5\u53E3 HTTP ${response.status}`, {
|
|
263
|
+
code: response.status,
|
|
264
|
+
details: { status: response.status },
|
|
265
|
+
exitCode: 1
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
throw mailNetworkError("protocol", `\u63A5\u53E3\u8FD4\u56DE\u4E0D\u662F\u5408\u6CD5 JSON\uFF08HTTP ${response.status}\uFF09`, { retryable: false });
|
|
269
|
+
}
|
|
270
|
+
if (response.status < 200 || response.status >= 300) {
|
|
271
|
+
throw new MailCliError("api", "http_error", `\u90AE\u4EF6\u63A5\u53E3 HTTP ${response.status}`, {
|
|
272
|
+
code: response.status,
|
|
273
|
+
details: { status: response.status, message: mailMessage(response.value) },
|
|
274
|
+
exitCode: 1
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (!isMailSuccess(response.value)) {
|
|
278
|
+
const value = response.value;
|
|
279
|
+
throw new MailCliError("api", "business_error", mailMessage(value), {
|
|
280
|
+
code: value?.code ?? response.status,
|
|
281
|
+
details: { code: value?.code, message: mailMessage(value) },
|
|
282
|
+
exitCode: 1
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
return response.value;
|
|
286
|
+
}
|
|
287
|
+
return { request, getSession };
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/shortcuts/mail/operations/types.ts
|
|
291
|
+
var READ = "read";
|
|
292
|
+
var WRITE = "write";
|
|
293
|
+
function mailSuccess(action, data, meta) {
|
|
294
|
+
const payload = { ok: true, action, data };
|
|
295
|
+
if (meta && Object.keys(meta).length > 0) payload.meta = meta;
|
|
296
|
+
return payload;
|
|
297
|
+
}
|
|
298
|
+
function schemaOf(properties, options = {}) {
|
|
299
|
+
return {
|
|
300
|
+
type: "object",
|
|
301
|
+
additionalProperties: false,
|
|
302
|
+
properties,
|
|
303
|
+
...options.required?.length ? { required: options.required } : {},
|
|
304
|
+
...options.description ? { description: options.description } : {}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
var SCHEMA_STRING = { type: "string" };
|
|
308
|
+
var SCHEMA_INTEGER = { type: "integer" };
|
|
309
|
+
var SCHEMA_BOOLEAN = { type: "boolean" };
|
|
310
|
+
|
|
311
|
+
// src/shortcuts/mail/operations/mail-read.ts
|
|
312
|
+
var FOLDER_TEXT = {
|
|
313
|
+
"-10": "\u5168\u90E8",
|
|
314
|
+
"0": "\u6536\u4EF6\u7BB1",
|
|
315
|
+
"-1": "\u5DF2\u53D1\u9001",
|
|
316
|
+
"-3": "\u5783\u573E\u7BB1",
|
|
317
|
+
"-2": "\u8349\u7A3F\u7BB1",
|
|
318
|
+
"-4": "\u5DF2\u5220\u9664"
|
|
319
|
+
};
|
|
320
|
+
function num(value, fallback) {
|
|
321
|
+
if (value === void 0 || value === null || value === "") return fallback;
|
|
322
|
+
const n = Number(value);
|
|
323
|
+
return Number.isFinite(n) ? n : fallback;
|
|
324
|
+
}
|
|
325
|
+
function buildTopFields(args) {
|
|
326
|
+
const t = {};
|
|
327
|
+
if (args.unread === true) t.readStatus = "0";
|
|
328
|
+
if (args.keyword) t.mailSubject = String(args.keyword);
|
|
329
|
+
if (args.from) t.sendFrom = String(args.from);
|
|
330
|
+
if (args.to) t.sendTo = String(args.to);
|
|
331
|
+
if (args.hasFile === true) t.hasFile = "1";
|
|
332
|
+
if (args.star === true) {
|
|
333
|
+
t.star = "1";
|
|
334
|
+
t.menu_star = 1;
|
|
335
|
+
}
|
|
336
|
+
if (args.todo === true) {
|
|
337
|
+
t.waitdeal = "1";
|
|
338
|
+
t.menu_waitdeal = 1;
|
|
339
|
+
}
|
|
340
|
+
if (args.startDate) t.startDate = String(args.startDate);
|
|
341
|
+
if (args.endDate) t.endDate = String(args.endDate);
|
|
342
|
+
return t;
|
|
343
|
+
}
|
|
344
|
+
async function listMails(env, args, folderId, extra = {}) {
|
|
345
|
+
const body = {
|
|
346
|
+
current: num(args.page, 1),
|
|
347
|
+
folderId,
|
|
348
|
+
menuId: folderId,
|
|
349
|
+
isMobile: 0,
|
|
350
|
+
orders: [{ column: "send_date", asc: false }],
|
|
351
|
+
type: "and",
|
|
352
|
+
isTableView: false,
|
|
353
|
+
...buildTopFields(extra)
|
|
354
|
+
};
|
|
355
|
+
if (args.size) body.pageSize = num(args.size, 20);
|
|
356
|
+
const value = await env.host.request({
|
|
357
|
+
path: "/api/mail/base/resource/getMailResourceList",
|
|
358
|
+
method: "POST",
|
|
359
|
+
body
|
|
360
|
+
});
|
|
361
|
+
return value?.data || {};
|
|
362
|
+
}
|
|
363
|
+
async function unreadCount(env, box) {
|
|
364
|
+
const rk = `${box}`;
|
|
365
|
+
const value = await env.host.request({
|
|
366
|
+
path: "/api/mail/base/view/getInboxUnReadCount",
|
|
367
|
+
method: "GET",
|
|
368
|
+
query: { mailBox: rk }
|
|
369
|
+
});
|
|
370
|
+
return Number(value?.data?.count ?? 0);
|
|
371
|
+
}
|
|
372
|
+
var opList = {
|
|
373
|
+
name: "mail.list",
|
|
374
|
+
resource: "mail/base/resource/getMailResourceList",
|
|
375
|
+
method: "POST",
|
|
376
|
+
action: "mail.list",
|
|
377
|
+
summary: "\u67E5\u8BE2\u90AE\u4EF6\u5217\u8868\uFF08\u652F\u6301\u6587\u4EF6\u5939/\u5173\u952E\u5B57/\u672A\u8BFB/\u661F\u6807/\u5F85\u529E/\u9644\u4EF6/\u65F6\u95F4\u8FC7\u6EE4\uFF09",
|
|
378
|
+
risk: READ,
|
|
379
|
+
inputSchema: schemaOf(
|
|
380
|
+
{
|
|
381
|
+
folder: { type: "string", description: "\u6587\u4EF6\u5939\uFF1A0 \u6536\u4EF6\u7BB1 / -1 \u5DF2\u53D1\u9001 / -2 \u8349\u7A3F\u7BB1 / -3 \u5783\u573E\u7BB1 / -4 \u5DF2\u5220\u9664 / -10 \u5168\u90E8\uFF0C\u9ED8\u8BA4 0" },
|
|
382
|
+
keyword: SCHEMA_STRING,
|
|
383
|
+
from: SCHEMA_STRING,
|
|
384
|
+
to: SCHEMA_STRING,
|
|
385
|
+
unread: SCHEMA_BOOLEAN,
|
|
386
|
+
star: SCHEMA_BOOLEAN,
|
|
387
|
+
todo: SCHEMA_BOOLEAN,
|
|
388
|
+
hasFile: SCHEMA_BOOLEAN,
|
|
389
|
+
startDate: SCHEMA_STRING,
|
|
390
|
+
endDate: SCHEMA_STRING,
|
|
391
|
+
page: SCHEMA_INTEGER,
|
|
392
|
+
size: SCHEMA_INTEGER
|
|
393
|
+
},
|
|
394
|
+
{ description: "\u90AE\u4EF6\u5217\u8868\u67E5\u8BE2" }
|
|
395
|
+
),
|
|
396
|
+
async handler(args, env) {
|
|
397
|
+
const folderId = num(args.folder, 0);
|
|
398
|
+
const data = await listMails(env, args, folderId, args);
|
|
399
|
+
return mailSuccess("mail.list", data, {
|
|
400
|
+
folder: FOLDER_TEXT[String(folderId)] ?? folderId,
|
|
401
|
+
total: data.total
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
var opContactList = {
|
|
406
|
+
name: "mail.contact.list",
|
|
407
|
+
resource: "mail/base/resource/getMailResourceList",
|
|
408
|
+
method: "POST",
|
|
409
|
+
action: "mail.contact.list",
|
|
410
|
+
summary: "\u5F80\u6765\u90AE\u4EF6\uFF08\u5BF9\u65B9\u53D1\u6765 + \u6211\u53D1\u7ED9\u5BF9\u65B9\uFF09",
|
|
411
|
+
risk: READ,
|
|
412
|
+
inputSchema: schemaOf(
|
|
413
|
+
{
|
|
414
|
+
name: { type: "string", description: "\u4EBA\u5458\u59D3\u540D/\u5DE5\u53F7" },
|
|
415
|
+
page: SCHEMA_INTEGER,
|
|
416
|
+
size: SCHEMA_INTEGER
|
|
417
|
+
},
|
|
418
|
+
{ required: ["name"], description: "\u5F80\u6765\u90AE\u4EF6\u67E5\u8BE2" }
|
|
419
|
+
),
|
|
420
|
+
async handler(args, env) {
|
|
421
|
+
const name = String(args.name || "").trim();
|
|
422
|
+
if (!name) throw new Error("name\uFF08\u4EBA\u5458\u59D3\u540D/\u5DE5\u53F7\uFF09\u5FC5\u586B");
|
|
423
|
+
const [inbox, sent] = await Promise.all([
|
|
424
|
+
listMails(env, { ...args, size: args.size ?? 100 }, 0, { from: name }),
|
|
425
|
+
listMails(env, { ...args, size: args.size ?? 100 }, -1, { to: name })
|
|
426
|
+
]);
|
|
427
|
+
return mailSuccess("mail.contact.list", {
|
|
428
|
+
contact: name,
|
|
429
|
+
inbox: { folder: "\u6536\u4EF6\u7BB1\uFF08\u5BF9\u65B9\u53D1\u6765\uFF09", total: inbox.total, rows: inbox.data },
|
|
430
|
+
sent: { folder: "\u5DF2\u53D1\u9001\uFF08\u6211\u53D1\u7ED9\u5BF9\u65B9\uFF09", total: sent.total, rows: sent.data },
|
|
431
|
+
total: (Number(inbox.total) || 0) + (Number(sent.total) || 0)
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
var opViewInfo = {
|
|
436
|
+
name: "mail.view.info",
|
|
437
|
+
resource: "mail/base/view/getMailResourceInfoView",
|
|
438
|
+
method: "GET",
|
|
439
|
+
action: "mail.view.info",
|
|
440
|
+
summary: "\u67E5\u770B\u90AE\u4EF6\u8BE6\u60C5\uFF08\u542B\u6B63\u6587/\u9644\u4EF6\uFF09",
|
|
441
|
+
risk: READ,
|
|
442
|
+
inputSchema: schemaOf(
|
|
443
|
+
{ id: { type: "string", description: "\u90AE\u4EF6 id\uFF08mailResourceId\uFF09" } },
|
|
444
|
+
{ required: ["id"], description: "\u90AE\u4EF6\u8BE6\u60C5" }
|
|
445
|
+
),
|
|
446
|
+
async handler(args, env) {
|
|
447
|
+
const id = String(args.id || "").trim();
|
|
448
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
449
|
+
const rk = mailRandomKey();
|
|
450
|
+
const [rkKey, rkVal] = rk.split("=");
|
|
451
|
+
const value = await env.host.request({
|
|
452
|
+
path: "/api/mail/base/view/getMailResourceInfoView",
|
|
453
|
+
method: "GET",
|
|
454
|
+
query: { mailResourceId: id, [rkKey]: rkVal }
|
|
455
|
+
});
|
|
456
|
+
const data = value?.data || {};
|
|
457
|
+
if (!data.clobContent) {
|
|
458
|
+
try {
|
|
459
|
+
const rk2 = mailRandomKey();
|
|
460
|
+
const [k2, v2] = rk2.split("=");
|
|
461
|
+
const c = await env.host.request({
|
|
462
|
+
path: "/api/mail/base/view/getMailContentView",
|
|
463
|
+
method: "GET",
|
|
464
|
+
query: { mailResourceId: id, [k2]: v2 }
|
|
465
|
+
});
|
|
466
|
+
data.clobContent = c?.data?.clobContent || "";
|
|
467
|
+
} catch {
|
|
468
|
+
data.clobContent = "";
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return mailSuccess("mail.view.info", data, { id: data.mailResourceId });
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
var opViewContent = {
|
|
475
|
+
name: "mail.view.content",
|
|
476
|
+
resource: "mail/base/view/getMailContentView",
|
|
477
|
+
method: "GET",
|
|
478
|
+
action: "mail.view.content",
|
|
479
|
+
summary: "\u67E5\u770B\u90AE\u4EF6\u6B63\u6587",
|
|
480
|
+
risk: READ,
|
|
481
|
+
inputSchema: schemaOf(
|
|
482
|
+
{ id: { type: "string", description: "\u90AE\u4EF6 id\uFF08mailResourceId\uFF09" } },
|
|
483
|
+
{ required: ["id"], description: "\u90AE\u4EF6\u6B63\u6587" }
|
|
484
|
+
),
|
|
485
|
+
async handler(args, env) {
|
|
486
|
+
const id = String(args.id || "").trim();
|
|
487
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
488
|
+
const rk = mailRandomKey();
|
|
489
|
+
const [rkKey, rkVal] = rk.split("=");
|
|
490
|
+
const value = await env.host.request({
|
|
491
|
+
path: "/api/mail/base/view/getMailContentView",
|
|
492
|
+
method: "GET",
|
|
493
|
+
query: { mailResourceId: id, [rkKey]: rkVal }
|
|
494
|
+
});
|
|
495
|
+
return mailSuccess("mail.view.content", value?.data || {});
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
var opUnreadCount = {
|
|
499
|
+
name: "mail.unread.count",
|
|
500
|
+
resource: "mail/base/view/getInboxUnReadCount",
|
|
501
|
+
method: "GET",
|
|
502
|
+
action: "mail.unread.count",
|
|
503
|
+
summary: "\u672A\u8BFB\u90AE\u4EF6\u7EDF\u8BA1\uFF08\u6536\u4EF6\u7BB1/\u5DF2\u5220\u9664/\u5783\u573E\u7BB1/\u5F85\u529E/\u661F\u6807\uFF09",
|
|
504
|
+
risk: READ,
|
|
505
|
+
inputSchema: schemaOf({}, { description: "\u672A\u8BFB\u7EDF\u8BA1" }),
|
|
506
|
+
async handler(args, env) {
|
|
507
|
+
const boxes = ["inbox", "deleted", "trash", "todo", "star"];
|
|
508
|
+
const entries = await Promise.all(
|
|
509
|
+
boxes.map(async (box) => [box, await unreadCount(env, box)])
|
|
510
|
+
);
|
|
511
|
+
return mailSuccess("mail.unread.count", Object.fromEntries(entries));
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
var opConfigGet = {
|
|
515
|
+
name: "mail.config.get",
|
|
516
|
+
resource: "mail/base/getEmailAllConfig",
|
|
517
|
+
method: "POST",
|
|
518
|
+
action: "mail.config.get",
|
|
519
|
+
summary: "\u83B7\u53D6\u90AE\u4EF6\u914D\u7F6E\uFF08\u53D1\u9001\u5F00\u5173/\u9644\u4EF6\u9650\u5236\uFF09",
|
|
520
|
+
risk: READ,
|
|
521
|
+
inputSchema: schemaOf({}, { description: "\u90AE\u4EF6\u914D\u7F6E" }),
|
|
522
|
+
async handler(args, env) {
|
|
523
|
+
const value = await env.host.request({
|
|
524
|
+
path: "/api/mail/base/getEmailAllConfig",
|
|
525
|
+
method: "POST",
|
|
526
|
+
query: { from: "mailadd" }
|
|
527
|
+
});
|
|
528
|
+
return mailSuccess("mail.config.get", value?.data || {});
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
var opPersonSearch = {
|
|
532
|
+
name: "mail.person.search",
|
|
533
|
+
resource: "mail/base/common/browser/complete/resource",
|
|
534
|
+
method: "POST",
|
|
535
|
+
action: "mail.person.search",
|
|
536
|
+
summary: "\u5185\u90E8\u4EBA\u5458/\u90E8\u95E8\u641C\u7D22\uFF08\u586B\u6536\u4EF6\u4EBA\uFF09",
|
|
537
|
+
risk: READ,
|
|
538
|
+
inputSchema: schemaOf(
|
|
539
|
+
{ keyword: { type: "string", description: "\u59D3\u540D/\u5DE5\u53F7" } },
|
|
540
|
+
{ required: ["keyword"], description: "\u5185\u90E8\u4EBA\u5458\u641C\u7D22" }
|
|
541
|
+
),
|
|
542
|
+
async handler(args, env) {
|
|
543
|
+
const keyword = String(args.keyword || "").trim();
|
|
544
|
+
if (!keyword) throw new Error("keyword\uFF08\u59D3\u540D/\u5DE5\u53F7\uFF09\u5FC5\u586B");
|
|
545
|
+
const value = await env.host.request({
|
|
546
|
+
path: "/api/mail/base/common/browser/complete/resource",
|
|
547
|
+
method: "POST",
|
|
548
|
+
body: {
|
|
549
|
+
browserMultiple: true,
|
|
550
|
+
authWecahtBook: false,
|
|
551
|
+
wxDepNeedConvertCount: 0,
|
|
552
|
+
wxEmpNeedConvertCount: 0,
|
|
553
|
+
wxTotalNeedConvertCount: 0,
|
|
554
|
+
secretLevel: "",
|
|
555
|
+
newly: 1,
|
|
556
|
+
searchValue: keyword
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
const data = value?.data?.data || value?.data || [];
|
|
560
|
+
return mailSuccess("mail.person.search", data);
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
async function searchDepartmentTree(env, parentId) {
|
|
564
|
+
const body = {
|
|
565
|
+
browserMultiple: true,
|
|
566
|
+
authWecahtBook: false,
|
|
567
|
+
wxDepNeedConvertCount: 0,
|
|
568
|
+
wxEmpNeedConvertCount: 0,
|
|
569
|
+
wxTotalNeedConvertCount: 0,
|
|
570
|
+
secretLevel: "",
|
|
571
|
+
cmd: "teams",
|
|
572
|
+
containsPartTimeEmployee: false,
|
|
573
|
+
browserLeftTreeDefaultExpandedLevel: "1",
|
|
574
|
+
pageSize: 30,
|
|
575
|
+
current: 1
|
|
576
|
+
};
|
|
577
|
+
if (parentId) Object.assign(body, { leftCompanyId: "1", type: "department", id: parentId });
|
|
578
|
+
const value = await env.host.request({
|
|
579
|
+
path: "/api/mail/base/common/browser/leftData/resource",
|
|
580
|
+
method: "POST",
|
|
581
|
+
body
|
|
582
|
+
});
|
|
583
|
+
return value?.data?.data || [];
|
|
584
|
+
}
|
|
585
|
+
var opDepSearch = {
|
|
586
|
+
name: "mail.dep.search",
|
|
587
|
+
resource: "mail/base/common/browser/leftData/resource",
|
|
588
|
+
method: "POST",
|
|
589
|
+
action: "mail.dep.search",
|
|
590
|
+
summary: "\u90E8\u95E8\u6811\u5B9A\u4F4D\uFF08\u8FD4\u56DE\u5339\u914D\u90E8\u95E8 id \u4E0E\u6210\u5458\u5C55\u5F00\u5165\u53E3\uFF09",
|
|
591
|
+
risk: READ,
|
|
592
|
+
inputSchema: schemaOf(
|
|
593
|
+
{ keyword: { type: "string", description: "\u90E8\u95E8\u540D\uFF08\u4E3A\u7A7A\u5219\u8FD4\u56DE\u9876\u7EA7\u90E8\u95E8\u6811\uFF09" } },
|
|
594
|
+
{ description: "\u90E8\u95E8\u641C\u7D22" }
|
|
595
|
+
),
|
|
596
|
+
async handler(args, env) {
|
|
597
|
+
const keyword = args.keyword ? String(args.keyword).trim() : "";
|
|
598
|
+
const matches = [];
|
|
599
|
+
async function walk(nodes, depth) {
|
|
600
|
+
for (const n of nodes || []) {
|
|
601
|
+
const nm = n.content || n.contentDesc || "";
|
|
602
|
+
if (keyword && nm === keyword) matches.push({ id: n.id, name: nm, isLeaf: !!n.isLeaf });
|
|
603
|
+
if (!n.isLeaf) {
|
|
604
|
+
if (n.children?.length) await walk(n.children, depth + 1);
|
|
605
|
+
else if (depth < 4) {
|
|
606
|
+
try {
|
|
607
|
+
await walk(await searchDepartmentTree(env, n.id), depth + 1);
|
|
608
|
+
} catch {
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
await walk(await searchDepartmentTree(env, void 0), 0);
|
|
615
|
+
const topLevel = await searchDepartmentTree(env, void 0);
|
|
616
|
+
return mailSuccess("mail.dep.search", { keyword, matches, topLevel });
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
var opAddressSearch = {
|
|
620
|
+
name: "mail.address.search",
|
|
621
|
+
resource: "mail/base/add/addressFullsearch",
|
|
622
|
+
method: "POST",
|
|
623
|
+
action: "mail.address.search",
|
|
624
|
+
summary: "\u5916\u90E8\u90AE\u7BB1\u641C\u7D22",
|
|
625
|
+
risk: READ,
|
|
626
|
+
inputSchema: schemaOf(
|
|
627
|
+
{ keyword: { type: "string", description: "\u90AE\u7BB1\u5173\u952E\u5B57" } },
|
|
628
|
+
{ required: ["keyword"], description: "\u5916\u90E8\u90AE\u7BB1\u641C\u7D22" }
|
|
629
|
+
),
|
|
630
|
+
async handler(args, env) {
|
|
631
|
+
const keyword = String(args.keyword || "").trim();
|
|
632
|
+
if (!keyword) throw new Error("keyword\uFF08\u90AE\u7BB1\u5173\u952E\u5B57\uFF09\u5FC5\u586B");
|
|
633
|
+
const value = await env.host.request({
|
|
634
|
+
path: "/api/mail/base/add/addressFullsearch",
|
|
635
|
+
method: "POST",
|
|
636
|
+
query: { keyword: encodeURIComponent(keyword), sf_request_type: "ajax" }
|
|
637
|
+
});
|
|
638
|
+
return mailSuccess("mail.address.search", value?.data || []);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
var opContactsList = {
|
|
642
|
+
name: "mail.contacts.list",
|
|
643
|
+
resource: "mail/base/contacts/getMailContactsList",
|
|
644
|
+
method: "POST",
|
|
645
|
+
action: "mail.contacts.list",
|
|
646
|
+
summary: "\u8054\u7CFB\u4EBA\u5217\u8868/\u641C\u7D22",
|
|
647
|
+
risk: READ,
|
|
648
|
+
inputSchema: schemaOf(
|
|
649
|
+
{ keyword: SCHEMA_STRING, page: SCHEMA_INTEGER, size: SCHEMA_INTEGER },
|
|
650
|
+
{ description: "\u8054\u7CFB\u4EBA\u5217\u8868" }
|
|
651
|
+
),
|
|
652
|
+
async handler(args, env) {
|
|
653
|
+
const body = { current: num(args.page, 1), isMobile: 0 };
|
|
654
|
+
if (args.keyword) body.searchName = String(args.keyword);
|
|
655
|
+
if (args.size) body.pageSize = num(args.size, 20);
|
|
656
|
+
const value = await env.host.request({
|
|
657
|
+
path: "/api/mail/base/contacts/getMailContactsList",
|
|
658
|
+
method: "POST",
|
|
659
|
+
body
|
|
660
|
+
});
|
|
661
|
+
return mailSuccess("mail.contacts.list", value?.data || {});
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
var opGroupList = {
|
|
665
|
+
name: "mail.contacts.group.list",
|
|
666
|
+
resource: "mail/base/contacts/getMailContactsGroupList",
|
|
667
|
+
method: "POST",
|
|
668
|
+
action: "mail.contacts.group.list",
|
|
669
|
+
summary: "\u8054\u7CFB\u4EBA\u5206\u7EC4\u5217\u8868",
|
|
670
|
+
risk: READ,
|
|
671
|
+
inputSchema: schemaOf({}, { description: "\u5206\u7EC4\u5217\u8868" }),
|
|
672
|
+
async handler(args, env) {
|
|
673
|
+
const value = await env.host.request({
|
|
674
|
+
path: "/api/mail/base/contacts/getMailContactsGroupList",
|
|
675
|
+
method: "POST",
|
|
676
|
+
body: {}
|
|
677
|
+
});
|
|
678
|
+
return mailSuccess("mail.contacts.group.list", value?.data || []);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
var opGroupDetail = {
|
|
682
|
+
name: "mail.contacts.group.detail",
|
|
683
|
+
resource: "mail/base/contacts/getMailContactsGroupVosByGroupId",
|
|
684
|
+
method: "POST",
|
|
685
|
+
action: "mail.contacts.group.detail",
|
|
686
|
+
summary: "\u5206\u7EC4\u8BE6\u60C5\uFF08\u542B\u7EDF\u8BA1\uFF09",
|
|
687
|
+
risk: READ,
|
|
688
|
+
inputSchema: schemaOf(
|
|
689
|
+
{ id: { type: "string", description: "\u5206\u7EC4 id" } },
|
|
690
|
+
{ required: ["id"], description: "\u5206\u7EC4\u8BE6\u60C5" }
|
|
691
|
+
),
|
|
692
|
+
async handler(args, env) {
|
|
693
|
+
const id = String(args.id || "").trim();
|
|
694
|
+
if (!id) throw new Error("id\uFF08\u5206\u7EC4 id\uFF09\u5FC5\u586B");
|
|
695
|
+
const value = await env.host.request({
|
|
696
|
+
path: "/api/mail/base/contacts/getMailContactsGroupVosByGroupId",
|
|
697
|
+
method: "POST",
|
|
698
|
+
body: { groupId: id }
|
|
699
|
+
});
|
|
700
|
+
return mailSuccess("mail.contacts.group.detail", value?.data || {});
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
var opTemplateList = {
|
|
704
|
+
name: "mail.template.list",
|
|
705
|
+
resource: "mail/base/setting/template/getMailTemplateList",
|
|
706
|
+
method: "POST",
|
|
707
|
+
action: "mail.template.list",
|
|
708
|
+
summary: "\u6A21\u677F\u5217\u8868",
|
|
709
|
+
risk: READ,
|
|
710
|
+
inputSchema: schemaOf({}, { description: "\u6A21\u677F\u5217\u8868" }),
|
|
711
|
+
async handler(args, env) {
|
|
712
|
+
const value = await env.host.request({
|
|
713
|
+
path: "/api/mail/base/setting/template/getMailTemplateList",
|
|
714
|
+
method: "POST",
|
|
715
|
+
body: {}
|
|
716
|
+
});
|
|
717
|
+
return mailSuccess("mail.template.list", value?.data || []);
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
var opSignList = {
|
|
721
|
+
name: "mail.sign.list",
|
|
722
|
+
resource: "mail/base/setting/sign/getMailSignList",
|
|
723
|
+
method: "POST",
|
|
724
|
+
action: "mail.sign.list",
|
|
725
|
+
summary: "\u7B7E\u540D\u5217\u8868",
|
|
726
|
+
risk: READ,
|
|
727
|
+
inputSchema: schemaOf({}, { description: "\u7B7E\u540D\u5217\u8868" }),
|
|
728
|
+
async handler(args, env) {
|
|
729
|
+
const value = await env.host.request({
|
|
730
|
+
path: "/api/mail/base/setting/sign/getMailSignList",
|
|
731
|
+
method: "POST",
|
|
732
|
+
body: {}
|
|
733
|
+
});
|
|
734
|
+
return mailSuccess("mail.sign.list", value?.data || []);
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
var opBlacklistList = {
|
|
738
|
+
name: "mail.blacklist.list",
|
|
739
|
+
resource: "mail/base/setting/blacklist/getMailBlacklist",
|
|
740
|
+
method: "POST",
|
|
741
|
+
action: "mail.blacklist.list",
|
|
742
|
+
summary: "\u9ED1\u540D\u5355\u5217\u8868",
|
|
743
|
+
risk: READ,
|
|
744
|
+
inputSchema: schemaOf({}, { description: "\u9ED1\u540D\u5355\u5217\u8868" }),
|
|
745
|
+
async handler(args, env) {
|
|
746
|
+
const value = await env.host.request({
|
|
747
|
+
path: "/api/mail/base/setting/blacklist/getMailBlacklist",
|
|
748
|
+
method: "POST",
|
|
749
|
+
body: {}
|
|
750
|
+
});
|
|
751
|
+
return mailSuccess("mail.blacklist.list", value?.data || []);
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
var opAttachmentCenter = {
|
|
755
|
+
name: "mail.attachment.center",
|
|
756
|
+
resource: "mail/base/attachment/list",
|
|
757
|
+
method: "POST",
|
|
758
|
+
action: "mail.attachment.center",
|
|
759
|
+
summary: "\u9644\u4EF6\u4E2D\u5FC3\u5217\u8868/\u641C\u7D22",
|
|
760
|
+
risk: READ,
|
|
761
|
+
inputSchema: schemaOf(
|
|
762
|
+
{ keyword: SCHEMA_STRING, page: SCHEMA_INTEGER, size: SCHEMA_INTEGER },
|
|
763
|
+
{ description: "\u9644\u4EF6\u4E2D\u5FC3" }
|
|
764
|
+
),
|
|
765
|
+
async handler(args, env) {
|
|
766
|
+
const body = { current: num(args.page, 1), isMobile: 0 };
|
|
767
|
+
if (args.keyword) body.searchName = String(args.keyword);
|
|
768
|
+
if (args.size) body.pageSize = num(args.size, 20);
|
|
769
|
+
const value = await env.host.request({
|
|
770
|
+
path: "/api/mail/base/attachment/list",
|
|
771
|
+
method: "POST",
|
|
772
|
+
body
|
|
773
|
+
});
|
|
774
|
+
return mailSuccess("mail.attachment.center", value?.data || {});
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
var opClearlogList = {
|
|
778
|
+
name: "mail.clearlog.list",
|
|
779
|
+
resource: "mail/base/setting/mailClear/getEmailClearLogList",
|
|
780
|
+
method: "POST",
|
|
781
|
+
action: "mail.clearlog.list",
|
|
782
|
+
summary: "\u90AE\u4EF6\u6E05\u7406\u65E5\u5FD7\u5217\u8868",
|
|
783
|
+
risk: READ,
|
|
784
|
+
inputSchema: schemaOf(
|
|
785
|
+
{ page: SCHEMA_INTEGER, size: SCHEMA_INTEGER },
|
|
786
|
+
{ description: "\u6E05\u7406\u65E5\u5FD7\u5217\u8868" }
|
|
787
|
+
),
|
|
788
|
+
async handler(args, env) {
|
|
789
|
+
const body = { current: num(args.page, 1), pageSize: num(args.size, 20) };
|
|
790
|
+
const value = await env.host.request({
|
|
791
|
+
path: "/api/mail/base/setting/mailClear/getEmailClearLogList",
|
|
792
|
+
method: "POST",
|
|
793
|
+
body
|
|
794
|
+
});
|
|
795
|
+
return mailSuccess("mail.clearlog.list", value?.data || {});
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
var mailReadOperations = [
|
|
799
|
+
opList,
|
|
800
|
+
opContactList,
|
|
801
|
+
opViewInfo,
|
|
802
|
+
opViewContent,
|
|
803
|
+
opUnreadCount,
|
|
804
|
+
opConfigGet,
|
|
805
|
+
opPersonSearch,
|
|
806
|
+
opDepSearch,
|
|
807
|
+
opAddressSearch,
|
|
808
|
+
opContactsList,
|
|
809
|
+
opGroupList,
|
|
810
|
+
opGroupDetail,
|
|
811
|
+
opTemplateList,
|
|
812
|
+
opSignList,
|
|
813
|
+
opBlacklistList,
|
|
814
|
+
opAttachmentCenter,
|
|
815
|
+
opClearlogList
|
|
816
|
+
];
|
|
817
|
+
|
|
818
|
+
// src/shortcuts/mail/operations/mail-send.ts
|
|
819
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
820
|
+
var CONTINUATION_TTL_MS = 6e5;
|
|
821
|
+
function b64(s) {
|
|
822
|
+
return Buffer.from(s, "utf8").toString("base64");
|
|
823
|
+
}
|
|
824
|
+
function splitNames(s) {
|
|
825
|
+
if (!s) return [];
|
|
826
|
+
return String(s).split(/[,,;;、\s]+/).map((x) => x.trim()).filter(Boolean);
|
|
827
|
+
}
|
|
828
|
+
function looksLikeEmail(s) {
|
|
829
|
+
return /@/.test(s);
|
|
830
|
+
}
|
|
831
|
+
var CandidateError = class extends Error {
|
|
832
|
+
pending;
|
|
833
|
+
constructor(pending) {
|
|
834
|
+
super("\u6536\u4EF6\u4EBA\u5B58\u5728\u91CD\u540D/\u591A\u5019\u9009\uFF0C\u9700\u7528\u6237\u786E\u8BA4\u540E\u4EE5 toId/ccId/bccId \u7CBE\u786E\u6307\u5B9A");
|
|
835
|
+
this.pending = pending;
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
async function mailAdd(env, flag, mailResourceId) {
|
|
839
|
+
const params = { flag: String(flag) };
|
|
840
|
+
if (mailResourceId) params.mailResourceId = String(mailResourceId);
|
|
841
|
+
if (flag === "3") params.emlMailResourceIds = String(mailResourceId);
|
|
842
|
+
const rk = randomBytes3(3).toString("hex").slice(0, 6);
|
|
843
|
+
const value = await env.host.request({
|
|
844
|
+
path: "/api/mail/base/add/mailAdd",
|
|
845
|
+
method: "POST",
|
|
846
|
+
query: { v: rk },
|
|
847
|
+
form: params
|
|
848
|
+
});
|
|
849
|
+
const d = value?.data || {};
|
|
850
|
+
if (!d.sessionUuid) throw new Error("mailAdd \u672A\u8FD4\u56DE sessionUuid\uFF1A" + JSON.stringify(value).slice(0, 300));
|
|
851
|
+
return d;
|
|
852
|
+
}
|
|
853
|
+
async function searchInternal(env, keyword) {
|
|
854
|
+
const value = await env.host.request({
|
|
855
|
+
path: "/api/mail/base/common/browser/complete/resource",
|
|
856
|
+
method: "POST",
|
|
857
|
+
body: {
|
|
858
|
+
browserMultiple: true,
|
|
859
|
+
authWecahtBook: false,
|
|
860
|
+
wxDepNeedConvertCount: 0,
|
|
861
|
+
wxEmpNeedConvertCount: 0,
|
|
862
|
+
wxTotalNeedConvertCount: 0,
|
|
863
|
+
secretLevel: "",
|
|
864
|
+
newly: 1,
|
|
865
|
+
searchValue: keyword
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
return value?.data?.data || [];
|
|
869
|
+
}
|
|
870
|
+
async function searchExternal(env, keyword) {
|
|
871
|
+
const value = await env.host.request({
|
|
872
|
+
path: "/api/mail/base/add/addressFullsearch",
|
|
873
|
+
method: "POST",
|
|
874
|
+
query: { keyword: encodeURIComponent(keyword), sf_request_type: "ajax" }
|
|
875
|
+
});
|
|
876
|
+
return value?.data || [];
|
|
877
|
+
}
|
|
878
|
+
async function resolveInternal(env, names) {
|
|
879
|
+
const out = [];
|
|
880
|
+
const pending = [];
|
|
881
|
+
for (const n of names) {
|
|
882
|
+
if (/^\d+$/.test(n)) {
|
|
883
|
+
out.push({ id: n, type: "resource", userids: n, name: n });
|
|
884
|
+
continue;
|
|
885
|
+
}
|
|
886
|
+
const list = await searchInternal(env, n);
|
|
887
|
+
const exact = list.filter((x) => x.name === n || x.content === n);
|
|
888
|
+
const toItem = (x) => ({ id: x.id, type: "resource", userids: x.id, name: x.name || x.content || n });
|
|
889
|
+
const cand = (x) => ({ id: x.id, name: x.name || x.content, department: x.department, position: x.position });
|
|
890
|
+
if (exact.length === 1) out.push(toItem(exact[0]));
|
|
891
|
+
else if (exact.length > 1) pending.push({ keyword: n, reason: "\u91CD\u540D", candidates: exact.map(cand) });
|
|
892
|
+
else if (list.length === 1) out.push(toItem(list[0]));
|
|
893
|
+
else if (list.length > 1) pending.push({ keyword: n, reason: "\u591A\u5019\u9009\uFF08\u65E0\u7CBE\u786E\u5339\u914D\uFF09", candidates: list.slice(0, 5).map(cand) });
|
|
894
|
+
else throw new Error("\u672A\u627E\u5230\u5185\u90E8\u4EBA\u5458\uFF1A" + n + "\uFF08\u53EF\u5C1D\u8BD5\u59D3\u540D/\u5DE5\u53F7\uFF1B\u82E5\u662F\u90E8\u95E8\u8BF7\u7528 to-dep/cc-dep/bcc-dep \u6307\u5B9A\uFF09");
|
|
895
|
+
}
|
|
896
|
+
if (pending.length) throw new CandidateError(pending);
|
|
897
|
+
return out;
|
|
898
|
+
}
|
|
899
|
+
async function searchDepartmentTree2(env, parentId) {
|
|
900
|
+
const body = {
|
|
901
|
+
browserMultiple: true,
|
|
902
|
+
authWecahtBook: false,
|
|
903
|
+
wxDepNeedConvertCount: 0,
|
|
904
|
+
wxEmpNeedConvertCount: 0,
|
|
905
|
+
wxTotalNeedConvertCount: 0,
|
|
906
|
+
secretLevel: "",
|
|
907
|
+
cmd: "teams",
|
|
908
|
+
containsPartTimeEmployee: false,
|
|
909
|
+
browserLeftTreeDefaultExpandedLevel: "1",
|
|
910
|
+
pageSize: 30,
|
|
911
|
+
current: 1
|
|
912
|
+
};
|
|
913
|
+
if (parentId) Object.assign(body, { leftCompanyId: "1", type: "department", id: parentId });
|
|
914
|
+
const value = await env.host.request({
|
|
915
|
+
path: "/api/mail/base/common/browser/leftData/resource",
|
|
916
|
+
method: "POST",
|
|
917
|
+
body
|
|
918
|
+
});
|
|
919
|
+
return value?.data?.data || [];
|
|
920
|
+
}
|
|
921
|
+
async function collectDepartmentMatches(env, name) {
|
|
922
|
+
const matches = [];
|
|
923
|
+
async function walk(nodes, depth) {
|
|
924
|
+
for (const n of nodes || []) {
|
|
925
|
+
const nm = n.content || n.contentDesc || "";
|
|
926
|
+
if (nm === name) matches.push({ id: n.id, name: nm, isLeaf: !!n.isLeaf });
|
|
927
|
+
if (!n.isLeaf) {
|
|
928
|
+
if (n.children?.length) await walk(n.children, depth + 1);
|
|
929
|
+
else if (depth < 5) {
|
|
930
|
+
try {
|
|
931
|
+
await walk(await searchDepartmentTree2(env, n.id), depth + 1);
|
|
932
|
+
} catch {
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
await walk(await searchDepartmentTree2(env, void 0), 0);
|
|
939
|
+
return matches;
|
|
940
|
+
}
|
|
941
|
+
async function resolveDepartmentMemberIds(env, deptId) {
|
|
942
|
+
const value = await env.host.request({
|
|
943
|
+
path: "/api/mail/base/common/browser/data/resource",
|
|
944
|
+
method: "POST",
|
|
945
|
+
body: {
|
|
946
|
+
browserMultiple: true,
|
|
947
|
+
authWecahtBook: false,
|
|
948
|
+
wxDepNeedConvertCount: 0,
|
|
949
|
+
wxEmpNeedConvertCount: 0,
|
|
950
|
+
wxTotalNeedConvertCount: 0,
|
|
951
|
+
secretLevel: "",
|
|
952
|
+
cmd: "teams",
|
|
953
|
+
current: 1,
|
|
954
|
+
leftTreeSelectedId: String(deptId),
|
|
955
|
+
pageSize: 200,
|
|
956
|
+
formDatas: {
|
|
957
|
+
username: [{ usernameOpt: "in" }],
|
|
958
|
+
status: [{ statusSelect: ["normal"] }],
|
|
959
|
+
subcompany: [{ subcompanyOpt: "in" }],
|
|
960
|
+
department: [{ departmentOpt: "in" }],
|
|
961
|
+
role: [{ roleOpt: "in" }],
|
|
962
|
+
position: [{ positionOpt: "in" }]
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
const arr = value?.data?.data || [];
|
|
967
|
+
return arr.map((x) => x.id).filter(Boolean);
|
|
968
|
+
}
|
|
969
|
+
async function resolveDepartment(env, names) {
|
|
970
|
+
const out = [];
|
|
971
|
+
const pending = [];
|
|
972
|
+
for (const n of names) {
|
|
973
|
+
const matches = await collectDepartmentMatches(env, n);
|
|
974
|
+
if (matches.length === 1) {
|
|
975
|
+
const ids = await resolveDepartmentMemberIds(env, matches[0].id);
|
|
976
|
+
out.push({
|
|
977
|
+
id: matches[0].id,
|
|
978
|
+
type: "department",
|
|
979
|
+
userids: ids.join(","),
|
|
980
|
+
leftAllLevel: true,
|
|
981
|
+
name: matches[0].name,
|
|
982
|
+
memberCount: ids.length
|
|
983
|
+
});
|
|
984
|
+
} else if (matches.length > 1) {
|
|
985
|
+
pending.push({ keyword: n, reason: "\u540C\u540D\u90E8\u95E8\uFF08\u8BF7\u5728\u7ED3\u679C\u4E2D\u9009\u62E9\uFF09", candidates: matches.map((x) => ({ id: x.id, name: x.name, type: "\u90E8\u95E8" })) });
|
|
986
|
+
} else {
|
|
987
|
+
throw new Error("\u672A\u627E\u5230\u90E8\u95E8\uFF1A" + n + "\uFF08\u8BF7\u786E\u8BA4\u90E8\u95E8\u540D\u79F0\uFF0C\u6216\u7528 to \u6307\u5B9A\u4EBA\u5458\uFF09");
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
if (pending.length) throw new CandidateError(pending);
|
|
991
|
+
return out;
|
|
992
|
+
}
|
|
993
|
+
async function resolveExternal(env, emails) {
|
|
994
|
+
const out = [];
|
|
995
|
+
for (const e of emails) {
|
|
996
|
+
if (looksLikeEmail(e)) {
|
|
997
|
+
out.push({ mailAddress: e, mailNickName: e.split("@")[0] });
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
const list = await searchExternal(env, e);
|
|
1001
|
+
const hit = list.find((x) => x.mailAddress?.includes(e)) || list[0];
|
|
1002
|
+
if (!hit) throw new Error("\u672A\u627E\u5230\u5916\u90E8\u90AE\u7BB1\uFF1A" + e + "\uFF08\u53EF\u5C1D\u8BD5\u5B8C\u6574\u90AE\u7BB1\u5730\u5740\uFF09");
|
|
1003
|
+
out.push({ mailAddress: hit.mailAddress, mailNickName: hit.mailNickName });
|
|
1004
|
+
}
|
|
1005
|
+
return out;
|
|
1006
|
+
}
|
|
1007
|
+
function wrapContent(userHtml, clobContent) {
|
|
1008
|
+
const u = userHtml ? "<div>" + userHtml + "</div><div> </div><div> </div>" : "";
|
|
1009
|
+
return '<div class="cke__pc cke_editable cke_editable_themed cke_contents_ltr" style="font-size: 12px;">' + u + (clobContent || "") + "</div>";
|
|
1010
|
+
}
|
|
1011
|
+
async function parseRecipients(env, add, args) {
|
|
1012
|
+
const flag = String(args.flag ?? "-1");
|
|
1013
|
+
const explicit = args.external === true ? "external" : args.internal === true ? "internal" : null;
|
|
1014
|
+
const toList = splitNames(args.to);
|
|
1015
|
+
const ccList = splitNames(args.cc);
|
|
1016
|
+
const bccList = splitNames(args.bcc);
|
|
1017
|
+
const toIdList = splitNames(args.toId);
|
|
1018
|
+
const ccIdList = splitNames(args.ccId);
|
|
1019
|
+
const bccIdList = splitNames(args.bccId);
|
|
1020
|
+
const toDepList = splitNames(args.toDep);
|
|
1021
|
+
const ccDepList = splitNames(args.ccDep);
|
|
1022
|
+
const bccDepList = splitNames(args.bccDep);
|
|
1023
|
+
let prefilled = null;
|
|
1024
|
+
if ((flag === "1" || flag === "4") && toList.length === 0) {
|
|
1025
|
+
const inner = (add.sendTo_internal || []).map((x) => ({ id: x.id, type: "resource", userids: x.id }));
|
|
1026
|
+
const outer = add.sendTo_outer || [];
|
|
1027
|
+
if (outer.length) prefilled = { kind: "external", to: outer.map((x) => x.mailAddress), cc: [], bcc: [] };
|
|
1028
|
+
else if (inner.length) prefilled = { kind: "internal", to: inner.map((x) => x.id), cc: [], bcc: [] };
|
|
1029
|
+
}
|
|
1030
|
+
let kind = explicit || (prefilled ? prefilled.kind : null);
|
|
1031
|
+
if (!kind) {
|
|
1032
|
+
const hasDep = toDepList.length || ccDepList.length || bccDepList.length;
|
|
1033
|
+
const hasId = toIdList.length || ccIdList.length || bccIdList.length;
|
|
1034
|
+
if (hasDep || hasId) kind = "internal";
|
|
1035
|
+
else {
|
|
1036
|
+
const all = [...toList, ...ccList, ...bccList];
|
|
1037
|
+
const hasEmail = all.some(looksLikeEmail);
|
|
1038
|
+
const hasName = all.some((x) => !looksLikeEmail(x));
|
|
1039
|
+
if (hasEmail && hasName) {
|
|
1040
|
+
throw new Error("\u6536\u4EF6\u4EBA\u5185\u5916\u90E8\u6DF7\u7528\uFF1A\u90AE\u7BB1\u5730\u5740=\u5916\u90E8\u90AE\u4EF6\u3001\u59D3\u540D=\u5185\u90E8\u90AE\u4EF6\uFF0C\u8BF7\u7EDF\u4E00\uFF0C\u6216\u7528 --internal/--external \u660E\u786E\u90AE\u4EF6\u7C7B\u578B");
|
|
1041
|
+
}
|
|
1042
|
+
if (!all.length) throw new Error("\u8BF7\u5148\u8BF4\u660E\u6536\u4EF6\u4EBA\uFF08\u59D3\u540D=\u5185\u90E8\u90AE\u4EF6 / \u90AE\u7BB1\u5730\u5740=\u5916\u90E8\u90AE\u4EF6 / \u90E8\u95E8\u7528 to-dep\uFF09");
|
|
1043
|
+
kind = hasEmail ? "external" : "internal";
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
const to = prefilled ? prefilled.to : toList;
|
|
1047
|
+
const cc = prefilled ? prefilled.cc : ccList;
|
|
1048
|
+
const bcc = prefilled ? prefilled.bcc : bccList;
|
|
1049
|
+
if (kind === "internal") {
|
|
1050
|
+
const resolveGroup = async (nameList, idList, depList) => {
|
|
1051
|
+
const persons = idList.length ? await resolveInternal(env, idList) : nameList.length ? await resolveInternal(env, nameList) : [];
|
|
1052
|
+
const deps = depList.length ? await resolveDepartment(env, depList) : [];
|
|
1053
|
+
return [...persons, ...deps];
|
|
1054
|
+
};
|
|
1055
|
+
const rawTo2 = await resolveGroup(to, toIdList, toDepList);
|
|
1056
|
+
const rawCc2 = await resolveGroup(cc, ccIdList, ccDepList);
|
|
1057
|
+
const rawBcc2 = await resolveGroup(bcc, bccIdList, bccDepList);
|
|
1058
|
+
const clean = (arr) => arr.map((x) => x.type === "department" ? { id: x.id, type: "department", userids: x.userids, leftAllLevel: x.leftAllLevel } : { id: x.id, type: "resource", userids: x.userids });
|
|
1059
|
+
const ids = (arr) => [...new Set(arr.flatMap((x) => String(x.userids || "").split(",").filter(Boolean)))].join(",");
|
|
1060
|
+
const names2 = (arr) => arr.map((x) => x.type === "department" ? `${x.name}\uFF08${x.memberCount}\u4EBA\uFF09` : x.name).join("\u3001");
|
|
1061
|
+
const totalCount2 = ids([...rawTo2, ...rawCc2, ...rawBcc2]).split(",").filter(Boolean).length;
|
|
1062
|
+
return {
|
|
1063
|
+
fields: {
|
|
1064
|
+
isInternal: 1,
|
|
1065
|
+
internalTo: clean(rawTo2),
|
|
1066
|
+
internalCc: clean(rawCc2),
|
|
1067
|
+
internalBcc: clean(rawBcc2),
|
|
1068
|
+
internaltonewIds: ids(rawTo2),
|
|
1069
|
+
internalccnewIds: ids(rawCc2),
|
|
1070
|
+
internalbccnewIds: ids(rawBcc2),
|
|
1071
|
+
usernameTo: JSON.stringify(clean(rawTo2)),
|
|
1072
|
+
usernameCc: JSON.stringify(clean(rawCc2)),
|
|
1073
|
+
usernameBcc: JSON.stringify(clean(rawBcc2))
|
|
1074
|
+
},
|
|
1075
|
+
display: { to: names2(rawTo2), cc: names2(rawCc2), bcc: names2(rawBcc2) },
|
|
1076
|
+
recipientCount: totalCount2
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
const rawTo = to.length ? await resolveExternal(env, to) : [];
|
|
1080
|
+
const rawCc = cc.length ? await resolveExternal(env, cc) : [];
|
|
1081
|
+
const rawBcc = bcc.length ? await resolveExternal(env, bcc) : [];
|
|
1082
|
+
const emails = (arr) => arr.map((x) => x.mailAddress).join(",");
|
|
1083
|
+
const names = (arr) => arr.map((x) => x.mailNickName || x.mailAddress).join("\u3001");
|
|
1084
|
+
const from = (add.sendFrom_outer || []).find((x) => x.selected) || (add.sendFrom_outer || [])[0];
|
|
1085
|
+
if (!from || !from.mailAddress) {
|
|
1086
|
+
throw new Error("\u5F53\u524D\u8D26\u53F7\u672A\u914D\u7F6E\u5916\u90E8\u90AE\u7BB1\u53D1\u4EF6\u8D26\u53F7\uFF08mailAdd.sendFrom_outer \u4E3A\u7A7A\uFF09\uFF0C\u65E0\u6CD5\u53D1\u9001\u5916\u90E8\u90AE\u4EF6\uFF1B\u8BF7\u5148\u5728\u90AE\u4EF6\u8BBE\u7F6E\u4E2D\u7ED1\u5B9A\u5916\u90E8\u90AE\u7BB1\u8D26\u53F7");
|
|
1087
|
+
}
|
|
1088
|
+
const totalCount = [...rawTo, ...rawCc, ...rawBcc].length;
|
|
1089
|
+
return {
|
|
1090
|
+
fields: {
|
|
1091
|
+
isInternal: 0,
|
|
1092
|
+
sendTo: emails(rawTo),
|
|
1093
|
+
sendCc: emails(rawCc),
|
|
1094
|
+
sendBcc: emails(rawBcc),
|
|
1095
|
+
usernameTo: JSON.stringify(rawTo),
|
|
1096
|
+
usernameCc: JSON.stringify(rawCc),
|
|
1097
|
+
usernameBcc: JSON.stringify(rawBcc),
|
|
1098
|
+
mailAccountId: from.id ? String(from.id) : "",
|
|
1099
|
+
sendFrom: from.mailAddress || ""
|
|
1100
|
+
},
|
|
1101
|
+
display: { to: names(rawTo) || "(\u672A\u6307\u5B9A\u6536\u4EF6\u4EBA)", cc: names(rawCc), bcc: names(rawBcc) },
|
|
1102
|
+
recipientCount: totalCount
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
async function checkMailConfig(env, isInternal) {
|
|
1106
|
+
const value = await env.host.request({
|
|
1107
|
+
path: "/api/mail/base/getEmailAllConfig",
|
|
1108
|
+
method: "POST",
|
|
1109
|
+
query: { from: "mailadd" }
|
|
1110
|
+
});
|
|
1111
|
+
const sys = value?.data?.sysConfig || {};
|
|
1112
|
+
if (isInternal === 1) {
|
|
1113
|
+
if (sys.innerMail !== void 0 && Number(sys.innerMail) !== 1) {
|
|
1114
|
+
throw new Error("\u5F53\u524D\u73AF\u5883\u672A\u542F\u7528\u5185\u90E8\u90AE\u4EF6\uFF08getEmailAllConfig.sysConfig.innerMail=" + sys.innerMail + "\uFF09\uFF0C\u65E0\u6CD5\u53D1\u9001\u5185\u90E8\u90AE\u4EF6");
|
|
1115
|
+
}
|
|
1116
|
+
} else {
|
|
1117
|
+
if (sys.outterMail !== void 0 && Number(sys.outterMail) !== 1) {
|
|
1118
|
+
throw new Error("\u5F53\u524D\u73AF\u5883\u672A\u542F\u7528\u5916\u90E8\u90AE\u4EF6\uFF08getEmailAllConfig.outterMail=0\uFF09\uFF0C\u65E0\u6CD5\u53D1\u9001\u5916\u90E8\u90AE\u4EF6");
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
if (sys.innerMail !== void 0 && sys.outterMail !== void 0 && Number(sys.innerMail) !== 1 && Number(sys.outterMail) !== 1) {
|
|
1122
|
+
throw new Error("\u7CFB\u7EDF\u672A\u542F\u7528\u90AE\u4EF6\u529F\u80FD\uFF08\u5185\u90E8/\u5916\u90E8\u90AE\u4EF6\u5747\u672A\u5F00\u542F\uFF09\uFF0C\u65E0\u6CD5\u53D1\u9001\u90AE\u4EF6");
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
async function precheckSend(env, body) {
|
|
1126
|
+
const c = await env.host.request({ path: "/api/mail/send/canSendMail", method: "POST", body });
|
|
1127
|
+
const cdata = c?.data || {};
|
|
1128
|
+
if (cdata.success !== void 0 && cdata.success !== 1) {
|
|
1129
|
+
throw new Error("\u53D1\u9001\u524D\u6821\u9A8C\u672A\u901A\u8FC7\uFF1A" + (cdata.msg || "\u672A\u77E5\u62E6\u622A\uFF08canSendMail\uFF09"));
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
async function buildBody(env, add, args, draft) {
|
|
1133
|
+
const flag = String(args.flag ?? "-1");
|
|
1134
|
+
const isReply = flag === "1" || flag === "3";
|
|
1135
|
+
const fullHtml = wrapContent(String(args.content || ""), isReply ? add.clobContent || "" : "");
|
|
1136
|
+
const { fields, display, recipientCount } = await parseRecipients(env, add, args);
|
|
1137
|
+
const body = {
|
|
1138
|
+
saveDraft: draft,
|
|
1139
|
+
content: b64(fullHtml),
|
|
1140
|
+
sessionUuid: add.sessionUuid,
|
|
1141
|
+
subject: args.subject || add.mailSubject || "",
|
|
1142
|
+
mailResourceId: args.id ? String(args.id) : "",
|
|
1143
|
+
isInternal: fields.isInternal,
|
|
1144
|
+
flag: Number(flag),
|
|
1145
|
+
files: args.files || "",
|
|
1146
|
+
filesizes: args.filesizes || "",
|
|
1147
|
+
...fields,
|
|
1148
|
+
mailPriority: "0",
|
|
1149
|
+
saveToSent: true,
|
|
1150
|
+
isHtmlMode: "1",
|
|
1151
|
+
op_isTimingSend: args.timing ? "1" : "0",
|
|
1152
|
+
timingdate: args.timing || "",
|
|
1153
|
+
secretLevel: "40",
|
|
1154
|
+
fromModule: "mail"
|
|
1155
|
+
};
|
|
1156
|
+
if (isReply) body.oldMailId = String(args.id);
|
|
1157
|
+
return { body, display, recipientCount };
|
|
1158
|
+
}
|
|
1159
|
+
var SEND_SCHEMA = schemaOf(
|
|
1160
|
+
{
|
|
1161
|
+
flag: { type: "string", description: "\u65B0\u5EFA -1 / \u56DE\u590D 1 / \u8F6C\u53D1 3 / \u7F16\u8F91\u8349\u7A3F 4" },
|
|
1162
|
+
id: SCHEMA_STRING,
|
|
1163
|
+
to: SCHEMA_STRING,
|
|
1164
|
+
cc: SCHEMA_STRING,
|
|
1165
|
+
bcc: SCHEMA_STRING,
|
|
1166
|
+
toDep: SCHEMA_STRING,
|
|
1167
|
+
ccDep: SCHEMA_STRING,
|
|
1168
|
+
bccDep: SCHEMA_STRING,
|
|
1169
|
+
toId: SCHEMA_STRING,
|
|
1170
|
+
ccId: SCHEMA_STRING,
|
|
1171
|
+
bccId: SCHEMA_STRING,
|
|
1172
|
+
external: { type: "boolean" },
|
|
1173
|
+
internal: { type: "boolean" },
|
|
1174
|
+
subject: SCHEMA_STRING,
|
|
1175
|
+
content: SCHEMA_STRING,
|
|
1176
|
+
timing: SCHEMA_STRING,
|
|
1177
|
+
files: SCHEMA_STRING,
|
|
1178
|
+
filesizes: SCHEMA_STRING,
|
|
1179
|
+
draft: { type: "boolean" },
|
|
1180
|
+
confirm: { type: "boolean" },
|
|
1181
|
+
continuation: SCHEMA_STRING
|
|
1182
|
+
},
|
|
1183
|
+
{ description: "\u90AE\u4EF6\u53D1\u9001\uFF08prepare/apply\uFF09" }
|
|
1184
|
+
);
|
|
1185
|
+
var opSendPrepare = {
|
|
1186
|
+
name: "mail.send.prepare",
|
|
1187
|
+
resource: "mail/base/add/mailAdd",
|
|
1188
|
+
method: "POST",
|
|
1189
|
+
action: "mail.send.prepare",
|
|
1190
|
+
summary: "\u51C6\u5907\u53D1\u9001\uFF08\u7EC4\u88C5\u8BF7\u6C42 + \u5B89\u5168\u9884\u68C0 + \u8F93\u51FA\u6458\u8981\uFF0C\u4E0D\u53D1\u9001\uFF09",
|
|
1191
|
+
risk: WRITE,
|
|
1192
|
+
requiresConfirmation: true,
|
|
1193
|
+
inputSchema: SEND_SCHEMA,
|
|
1194
|
+
async handler(args, env) {
|
|
1195
|
+
const flag = String(args.flag ?? "-1");
|
|
1196
|
+
const draft = args.draft === true;
|
|
1197
|
+
const session = await env.host.getSession();
|
|
1198
|
+
const add = await mailAdd(env, flag, args.id ? String(args.id) : void 0);
|
|
1199
|
+
const { body, display, recipientCount } = await buildBody(env, add, args, draft);
|
|
1200
|
+
await checkMailConfig(env, body.isInternal);
|
|
1201
|
+
await precheckSend(env, body);
|
|
1202
|
+
const flagText = { "-1": "\u65B0\u5EFA", "1": "\u56DE\u590D", "3": "\u8F6C\u53D1", "4": "\u7F16\u8F91\u8349\u7A3F" }[flag] || flag;
|
|
1203
|
+
const continuation = await env.continuation.issue(
|
|
1204
|
+
{
|
|
1205
|
+
operation: "mail.send.apply",
|
|
1206
|
+
baseUrl: session.baseUrl,
|
|
1207
|
+
profile: session.profile,
|
|
1208
|
+
userId: session.userId,
|
|
1209
|
+
body,
|
|
1210
|
+
draft,
|
|
1211
|
+
subject: body.subject
|
|
1212
|
+
},
|
|
1213
|
+
CONTINUATION_TTL_MS
|
|
1214
|
+
);
|
|
1215
|
+
return mailSuccess("mail.send.prepare", {
|
|
1216
|
+
action: flagText,
|
|
1217
|
+
type: body.isInternal === 1 ? "\u5185\u90E8\u90AE\u4EF6" : "\u5916\u90E8\u90AE\u4EF6",
|
|
1218
|
+
subject: body.subject,
|
|
1219
|
+
to: display.to || "(\u672A\u6307\u5B9A\u6536\u4EF6\u4EBA)",
|
|
1220
|
+
cc: display.cc || "",
|
|
1221
|
+
bcc: display.bcc || "",
|
|
1222
|
+
recipientCount: recipientCount || 0,
|
|
1223
|
+
contentPreview: String(args.content || "").slice(0, 100),
|
|
1224
|
+
includeOriginal: flag === "1" || flag === "3" ? "\u662F\uFF08\u542B\u539F\u90AE\u4EF6\u5F15\u7528\uFF09" : "\u5426",
|
|
1225
|
+
timing: args.timing ? String(args.timing) : "\u5373\u65F6\u53D1\u9001",
|
|
1226
|
+
tip: "\u53D1\u9001\u524D\u5B89\u5168\u9884\u68C0\u5DF2\u901A\u8FC7\uFF1B\u7528\u6237\u786E\u8BA4\u540E\u4EE5 mail send apply --continuation <token> --yes \u6267\u884C"
|
|
1227
|
+
}, { continuation });
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
var opSendApply = {
|
|
1231
|
+
name: "mail.send.apply",
|
|
1232
|
+
resource: "mail/send/sendMail",
|
|
1233
|
+
method: "POST",
|
|
1234
|
+
action: "mail.send.apply",
|
|
1235
|
+
summary: "\u6267\u884C\u53D1\u9001\uFF08\u9700 continuation \u4E0E confirm\uFF09",
|
|
1236
|
+
risk: WRITE,
|
|
1237
|
+
requiresConfirmation: true,
|
|
1238
|
+
inputSchema: SEND_SCHEMA,
|
|
1239
|
+
async handler(args, env) {
|
|
1240
|
+
if (args.confirm !== true) {
|
|
1241
|
+
throw mailValidationError("confirm_required", "mail.send.apply \u5FC5\u987B\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation");
|
|
1242
|
+
}
|
|
1243
|
+
if (!args.continuation) {
|
|
1244
|
+
throw mailValidationError("continuation_required", "mail.send.apply \u5FC5\u987B\u4F20\u5165 prepare \u8FD4\u56DE\u7684 continuation");
|
|
1245
|
+
}
|
|
1246
|
+
const lease = await env.continuation.verify(String(args.continuation), "mail.send.apply");
|
|
1247
|
+
const session = await env.host.getSession();
|
|
1248
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
1249
|
+
throw mailValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
1250
|
+
}
|
|
1251
|
+
const body = lease.body;
|
|
1252
|
+
const draft = lease.draft === true;
|
|
1253
|
+
await checkMailConfig(env, body.isInternal);
|
|
1254
|
+
if (!draft) await precheckSend(env, body);
|
|
1255
|
+
const path = draft ? "/api/mail/send/saveDraft" : "/api/mail/send/sendMail";
|
|
1256
|
+
const value = await env.host.request({ path, method: "POST", body });
|
|
1257
|
+
const d = value?.data || {};
|
|
1258
|
+
if (draft) {
|
|
1259
|
+
return mailSuccess("mail.send.apply", { success: d.status === 1, draft: true, mailResourceId: d.mailResourceId, subject: lease.subject }, { savedDraft: true });
|
|
1260
|
+
}
|
|
1261
|
+
return mailSuccess("mail.send.apply", { success: d.success === 1, msg: d.msg || "\u90AE\u4EF6\u5DF2\u53D1\u9001", subject: lease.subject }, { sent: true });
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
var mailSendOperations = [opSendPrepare, opSendApply];
|
|
1265
|
+
|
|
1266
|
+
// src/shortcuts/mail/operations/mail-manage.ts
|
|
1267
|
+
import { createHash } from "node:crypto";
|
|
1268
|
+
import { statSync, readFileSync } from "node:fs";
|
|
1269
|
+
import { extname } from "node:path";
|
|
1270
|
+
var MIME_BY_EXT = {
|
|
1271
|
+
txt: "text/plain",
|
|
1272
|
+
html: "text/html",
|
|
1273
|
+
htm: "text/html",
|
|
1274
|
+
json: "application/json",
|
|
1275
|
+
pdf: "application/pdf",
|
|
1276
|
+
doc: "application/msword",
|
|
1277
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1278
|
+
xls: "application/vnd.ms-excel",
|
|
1279
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
1280
|
+
png: "image/png",
|
|
1281
|
+
jpg: "image/jpeg",
|
|
1282
|
+
jpeg: "image/jpeg",
|
|
1283
|
+
gif: "image/gif",
|
|
1284
|
+
zip: "application/zip"
|
|
1285
|
+
};
|
|
1286
|
+
function mimeOf(name) {
|
|
1287
|
+
const ext = extname(name).replace(".", "").toLowerCase();
|
|
1288
|
+
return MIME_BY_EXT[ext] || "application/octet-stream";
|
|
1289
|
+
}
|
|
1290
|
+
async function fetchSubject(env, id) {
|
|
1291
|
+
const rk = mailRandomKey();
|
|
1292
|
+
const [rkKey, rkVal] = rk.split("=");
|
|
1293
|
+
const value = await env.host.request({
|
|
1294
|
+
path: "/api/mail/base/view/getMailResourceInfoView",
|
|
1295
|
+
method: "GET",
|
|
1296
|
+
query: { mailResourceId: id, [rkKey]: rkVal }
|
|
1297
|
+
});
|
|
1298
|
+
return value?.data?.mailSubject || "";
|
|
1299
|
+
}
|
|
1300
|
+
var opStar = {
|
|
1301
|
+
name: "mail.star",
|
|
1302
|
+
resource: "mail/base/resource/starMail",
|
|
1303
|
+
method: "POST",
|
|
1304
|
+
action: "mail.star",
|
|
1305
|
+
summary: "\u6807\u661F/\u53D6\u6D88\u6807\u661F",
|
|
1306
|
+
risk: WRITE,
|
|
1307
|
+
inputSchema: schemaOf(
|
|
1308
|
+
{ id: { type: "string", description: "\u90AE\u4EF6 id" }, star: { type: "string", description: "1 \u6807\u661F / 0 \u53D6\u6D88" } },
|
|
1309
|
+
{ required: ["id", "star"], description: "\u6807\u661F" }
|
|
1310
|
+
),
|
|
1311
|
+
async handler(args, env) {
|
|
1312
|
+
const id = String(args.id || "").trim();
|
|
1313
|
+
const star = String(args.star ?? "1");
|
|
1314
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
1315
|
+
const value = await env.host.request({
|
|
1316
|
+
path: "/api/mail/base/resource/starMail",
|
|
1317
|
+
method: "POST",
|
|
1318
|
+
query: { ids: id, star }
|
|
1319
|
+
});
|
|
1320
|
+
return mailSuccess("mail.star", value?.data ?? "SUCCESS", { id, star });
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1323
|
+
var opReadStatus = {
|
|
1324
|
+
name: "mail.read.status",
|
|
1325
|
+
resource: "mail/base/resource/setMailReadStatus",
|
|
1326
|
+
method: "POST",
|
|
1327
|
+
action: "mail.read.status",
|
|
1328
|
+
summary: "\u6807\u8BB0\u5355\u5C01\u5DF2\u8BFB/\u672A\u8BFB",
|
|
1329
|
+
risk: WRITE,
|
|
1330
|
+
inputSchema: schemaOf(
|
|
1331
|
+
{ id: { type: "string", description: "\u90AE\u4EF6 id" }, read: { type: "string", description: "1 \u5DF2\u8BFB / 0 \u672A\u8BFB" } },
|
|
1332
|
+
{ required: ["id", "read"], description: "\u6807\u8BB0\u5DF2\u8BFB" }
|
|
1333
|
+
),
|
|
1334
|
+
async handler(args, env) {
|
|
1335
|
+
const id = String(args.id || "").trim();
|
|
1336
|
+
const read = String(args.read ?? "1");
|
|
1337
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
1338
|
+
const value = await env.host.request({
|
|
1339
|
+
path: "/api/mail/base/resource/setMailReadStatus",
|
|
1340
|
+
method: "POST",
|
|
1341
|
+
form: { ids: id, readStatus: read }
|
|
1342
|
+
});
|
|
1343
|
+
return mailSuccess("mail.read.status", value?.data ?? "SUCCESS", { id, readStatus: read });
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
var opReadAll = {
|
|
1347
|
+
name: "mail.read.all",
|
|
1348
|
+
resource: "mail/base/resource/setMailAllRead",
|
|
1349
|
+
method: "POST",
|
|
1350
|
+
action: "mail.read.all",
|
|
1351
|
+
summary: "\u6807\u8BB0\u5168\u90E8\u5DF2\u8BFB",
|
|
1352
|
+
risk: WRITE,
|
|
1353
|
+
inputSchema: schemaOf(
|
|
1354
|
+
{ folder: { type: "string", description: "\u6587\u4EF6\u5939 id\uFF08\u9ED8\u8BA4\u5168\u90E8\uFF09" } },
|
|
1355
|
+
{ description: "\u5168\u90E8\u5DF2\u8BFB" }
|
|
1356
|
+
),
|
|
1357
|
+
async handler(args, env) {
|
|
1358
|
+
const value = await env.host.request({
|
|
1359
|
+
path: "/api/mail/base/resource/setMailAllRead",
|
|
1360
|
+
method: "POST",
|
|
1361
|
+
body: {}
|
|
1362
|
+
});
|
|
1363
|
+
return mailSuccess("mail.read.all", value?.data ?? "SUCCESS", { folder: args.folder ?? "current" });
|
|
1364
|
+
}
|
|
1365
|
+
};
|
|
1366
|
+
var opWaitAdd = {
|
|
1367
|
+
name: "mail.wait.add",
|
|
1368
|
+
resource: "my/wait/addWait",
|
|
1369
|
+
method: "POST",
|
|
1370
|
+
action: "mail.wait.add",
|
|
1371
|
+
summary: "\u521B\u5EFA\u5F85\u529E/\u63D0\u9192",
|
|
1372
|
+
risk: WRITE,
|
|
1373
|
+
inputSchema: schemaOf(
|
|
1374
|
+
{
|
|
1375
|
+
id: { type: "string", description: "\u90AE\u4EF6 id" },
|
|
1376
|
+
title: SCHEMA_STRING,
|
|
1377
|
+
endDate: SCHEMA_STRING,
|
|
1378
|
+
reminderWay: SCHEMA_STRING,
|
|
1379
|
+
reminderTime: SCHEMA_STRING,
|
|
1380
|
+
remark: SCHEMA_STRING
|
|
1381
|
+
},
|
|
1382
|
+
{ required: ["id"], description: "\u5F85\u529E" }
|
|
1383
|
+
),
|
|
1384
|
+
async handler(args, env) {
|
|
1385
|
+
const id = String(args.id || "").trim();
|
|
1386
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
1387
|
+
const content = args.title ? String(args.title) : await fetchSubject(env, id);
|
|
1388
|
+
const processTime = args.endDate ? String(args.endDate) : "";
|
|
1389
|
+
const reminderTime = args.reminderTime ? String(args.reminderTime) : "";
|
|
1390
|
+
const body = {
|
|
1391
|
+
module: "mail",
|
|
1392
|
+
processTime,
|
|
1393
|
+
reminderWay: args.reminderWay ? String(args.reminderWay) : "",
|
|
1394
|
+
reminderTime,
|
|
1395
|
+
remark: args.remark ? String(args.remark) : "",
|
|
1396
|
+
waitEntityDTOS: [{ entityId: id, content, module: "mail" }],
|
|
1397
|
+
processTimeTamp: processTime ? Date.parse(processTime + (processTime.length <= 10 ? "T23:59:59" : "")) || 0 : 0,
|
|
1398
|
+
reminderTimeTamp: reminderTime ? Date.parse(reminderTime.replace(" ", "T")) || 0 : 0
|
|
1399
|
+
};
|
|
1400
|
+
const value = await env.host.request({ path: "/api/my/wait/addWait", method: "POST", body });
|
|
1401
|
+
return mailSuccess("mail.wait.add", value?.data ?? [], { id, content });
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
var opMoveFolder = {
|
|
1405
|
+
name: "mail.move.folder",
|
|
1406
|
+
resource: "mail/base/resource/moveMailToFolder",
|
|
1407
|
+
method: "POST",
|
|
1408
|
+
action: "mail.move.folder",
|
|
1409
|
+
summary: "\u79FB\u52A8\u90AE\u4EF6\u81F3\u6587\u4EF6\u5939",
|
|
1410
|
+
risk: WRITE,
|
|
1411
|
+
inputSchema: schemaOf(
|
|
1412
|
+
{ id: { type: "string", description: "\u90AE\u4EF6 id \u6216\u9017\u53F7\u5206\u9694\u591A\u4E2A" }, folder: { type: "string", description: "\u76EE\u6807\u6587\u4EF6\u5939 id\uFF08-1\u5DF2\u53D1\u9001/-3\u5DF2\u5220\u9664/\u6B63\u6570\u81EA\u5B9A\u4E49\uFF09" } },
|
|
1413
|
+
{ required: ["id", "folder"], description: "\u79FB\u52A8" }
|
|
1414
|
+
),
|
|
1415
|
+
async handler(args, env) {
|
|
1416
|
+
const id = String(args.id || "").trim();
|
|
1417
|
+
const folder = String(args.folder || "").trim();
|
|
1418
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
1419
|
+
if (!folder) throw new Error("folder\uFF08\u76EE\u6807\u6587\u4EF6\u5939 id\uFF09\u5FC5\u586B");
|
|
1420
|
+
const value = await env.host.request({
|
|
1421
|
+
path: "/api/mail/base/resource/moveMailToFolder",
|
|
1422
|
+
method: "POST",
|
|
1423
|
+
form: { ids: id, folderId: folder }
|
|
1424
|
+
});
|
|
1425
|
+
return mailSuccess("mail.move.folder", value?.data ?? "SUCCESS", { id, folderId: folder });
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
var opDeleteMove = {
|
|
1429
|
+
name: "mail.delete.move",
|
|
1430
|
+
resource: "mail/base/resource/deleteMailResourceByMoveBatch",
|
|
1431
|
+
method: "POST",
|
|
1432
|
+
action: "mail.delete.move",
|
|
1433
|
+
summary: "\u903B\u8F91\u5220\u9664\uFF08\u79FB\u81F3\u5DF2\u5220\u9664\uFF0C\u53EF\u6062\u590D\uFF09",
|
|
1434
|
+
risk: WRITE,
|
|
1435
|
+
inputSchema: schemaOf(
|
|
1436
|
+
{ id: { type: "string", description: "\u90AE\u4EF6 id \u6216\u9017\u53F7\u5206\u9694\u591A\u4E2A" } },
|
|
1437
|
+
{ required: ["id"], description: "\u903B\u8F91\u5220\u9664" }
|
|
1438
|
+
),
|
|
1439
|
+
async handler(args, env) {
|
|
1440
|
+
const id = String(args.id || "").trim();
|
|
1441
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
1442
|
+
const value = await env.host.request({
|
|
1443
|
+
path: "/api/mail/base/resource/deleteMailResourceByMoveBatch",
|
|
1444
|
+
method: "POST",
|
|
1445
|
+
query: { sf_request_type: "ajax" },
|
|
1446
|
+
form: { ids: id }
|
|
1447
|
+
});
|
|
1448
|
+
return mailSuccess("mail.delete.move", value?.data ?? "SUCCESS", { id });
|
|
1449
|
+
}
|
|
1450
|
+
};
|
|
1451
|
+
var opFolderCreate = {
|
|
1452
|
+
name: "mail.folder.create",
|
|
1453
|
+
resource: "mail/base/setting/folder/saveMailFolder",
|
|
1454
|
+
method: "POST",
|
|
1455
|
+
action: "mail.folder.create",
|
|
1456
|
+
summary: "\u65B0\u5EFA\u90AE\u4EF6\u6587\u4EF6\u5939",
|
|
1457
|
+
risk: WRITE,
|
|
1458
|
+
inputSchema: schemaOf(
|
|
1459
|
+
{ name: { type: "string", description: "\u6587\u4EF6\u5939\u540D" }, id: { type: "string", description: "\u7F16\u8F91\u65F6\u4F20\u539F id\uFF08\u53EF\u9009\uFF09" } },
|
|
1460
|
+
{ required: ["name"], description: "\u65B0\u5EFA\u6587\u4EF6\u5939" }
|
|
1461
|
+
),
|
|
1462
|
+
async handler(args, env) {
|
|
1463
|
+
const name = String(args.name || "").trim();
|
|
1464
|
+
if (!name) throw new Error("name\uFF08\u6587\u4EF6\u5939\u540D\uFF09\u5FC5\u586B");
|
|
1465
|
+
const body = { name };
|
|
1466
|
+
if (args.id) body.id = String(args.id);
|
|
1467
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/folder/saveMailFolder", method: "POST", body });
|
|
1468
|
+
return mailSuccess("mail.folder.create", value?.data ?? "SUCCESS", { name });
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
var opFolderDelete = {
|
|
1472
|
+
name: "mail.folder.delete",
|
|
1473
|
+
resource: "mail/base/setting/folder/deleteMailFolder",
|
|
1474
|
+
method: "POST",
|
|
1475
|
+
action: "mail.folder.delete",
|
|
1476
|
+
summary: "\u5220\u9664\u90AE\u4EF6\u6587\u4EF6\u5939",
|
|
1477
|
+
risk: WRITE,
|
|
1478
|
+
inputSchema: schemaOf(
|
|
1479
|
+
{ id: { type: "string", description: "\u6587\u4EF6\u5939 id" } },
|
|
1480
|
+
{ required: ["id"], description: "\u5220\u9664\u6587\u4EF6\u5939" }
|
|
1481
|
+
),
|
|
1482
|
+
async handler(args, env) {
|
|
1483
|
+
const id = String(args.id || "").trim();
|
|
1484
|
+
if (!id) throw new Error("id\uFF08\u6587\u4EF6\u5939 id\uFF09\u5FC5\u586B");
|
|
1485
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/folder/deleteMailFolder", method: "POST", body: { id } });
|
|
1486
|
+
return mailSuccess("mail.folder.delete", value?.data ?? "SUCCESS", { id });
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
var opRecall = {
|
|
1490
|
+
name: "mail.recall",
|
|
1491
|
+
resource: "mail/base/recallMail",
|
|
1492
|
+
method: "POST",
|
|
1493
|
+
action: "mail.recall",
|
|
1494
|
+
summary: "\u64A4\u56DE\u5DF2\u53D1\u9001\u7684\u5185\u90E8\u90AE\u4EF6",
|
|
1495
|
+
risk: WRITE,
|
|
1496
|
+
inputSchema: schemaOf(
|
|
1497
|
+
{ id: { type: "string", description: "\u90AE\u4EF6 id" } },
|
|
1498
|
+
{ required: ["id"], description: "\u64A4\u56DE" }
|
|
1499
|
+
),
|
|
1500
|
+
async handler(args, env) {
|
|
1501
|
+
const id = String(args.id || "").trim();
|
|
1502
|
+
if (!id) throw new Error("id\uFF08\u90AE\u4EF6 id\uFF09\u5FC5\u586B");
|
|
1503
|
+
const value = await env.host.request({ path: "/api/mail/base/recallMail", method: "POST", body: { mailResourceId: id, ids: id } });
|
|
1504
|
+
const d = value?.data || {};
|
|
1505
|
+
return mailSuccess("mail.recall", { success: d.success === 1, msg: d.msg }, { id });
|
|
1506
|
+
}
|
|
1507
|
+
};
|
|
1508
|
+
var opAttachmentUpload = {
|
|
1509
|
+
name: "mail.attachment.upload",
|
|
1510
|
+
resource: "file/module/upload",
|
|
1511
|
+
method: "POST",
|
|
1512
|
+
action: "mail.attachment.upload",
|
|
1513
|
+
summary: "\u4E0A\u4F20\u9644\u4EF6\uFF08\u9884\u68C0\u2192\u4E0A\u4F20\u2192\u7ED1\u5B9A\uFF0C\u8FD4\u56DE fileid\uFF09",
|
|
1514
|
+
risk: WRITE,
|
|
1515
|
+
inputSchema: schemaOf(
|
|
1516
|
+
{ file: { type: "string", description: "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84\uFF08Windows \u7EDD\u5BF9\u8DEF\u5F84\uFF09" }, name: { type: "string", description: "\u9644\u4EF6\u540D\uFF08\u9ED8\u8BA4\u53D6\u6587\u4EF6\u540D\uFF09" } },
|
|
1517
|
+
{ required: ["file"], description: "\u9644\u4EF6\u4E0A\u4F20" }
|
|
1518
|
+
),
|
|
1519
|
+
async handler(args, env) {
|
|
1520
|
+
const filePath = String(args.file || "").trim();
|
|
1521
|
+
if (!filePath) throw new Error("file\uFF08\u672C\u5730\u6587\u4EF6\u8DEF\u5F84\uFF09\u5FC5\u586B");
|
|
1522
|
+
const name = args.name ? String(args.name) : filePath.split(/[\\/]/).pop() || "attachment";
|
|
1523
|
+
let buffer;
|
|
1524
|
+
let size;
|
|
1525
|
+
try {
|
|
1526
|
+
const stat = statSync(filePath);
|
|
1527
|
+
size = stat.size;
|
|
1528
|
+
buffer = readFileSync(filePath);
|
|
1529
|
+
} catch {
|
|
1530
|
+
throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u672C\u5730\u6587\u4EF6\uFF1A" + filePath);
|
|
1531
|
+
}
|
|
1532
|
+
const md5 = createHash("md5").update(buffer).digest("hex");
|
|
1533
|
+
const lastModified = Date.now();
|
|
1534
|
+
const base = {
|
|
1535
|
+
compressImg: "false",
|
|
1536
|
+
fileFrom: "mail_info",
|
|
1537
|
+
createDoc: "false",
|
|
1538
|
+
module: "mail",
|
|
1539
|
+
refId: "-2",
|
|
1540
|
+
size: String(size),
|
|
1541
|
+
name,
|
|
1542
|
+
MD5: md5,
|
|
1543
|
+
lastModified: String(lastModified),
|
|
1544
|
+
lastModifiedDate: String(lastModified)
|
|
1545
|
+
};
|
|
1546
|
+
const precheck = await env.host.request({
|
|
1547
|
+
path: "/api/file/preUploadCheck",
|
|
1548
|
+
method: "POST",
|
|
1549
|
+
multipart: buildMultipart({ ...base })
|
|
1550
|
+
});
|
|
1551
|
+
const preUploadId = precheck?.data?.preUploadId;
|
|
1552
|
+
if (!preUploadId) throw new Error("\u9644\u4EF6\u9884\u68C0\u672A\u8FD4\u56DE preUploadId\uFF1A" + JSON.stringify(precheck?.data).slice(0, 200));
|
|
1553
|
+
const upload = await env.host.request({
|
|
1554
|
+
path: "/api/file/module/upload",
|
|
1555
|
+
method: "POST",
|
|
1556
|
+
multipart: buildMultipart({ ...base, preUploadId, uploadType: "common" }, { file: buffer, filename: name, type: mimeOf(name) })
|
|
1557
|
+
});
|
|
1558
|
+
const fileid = upload?.data?.fileid;
|
|
1559
|
+
if (!fileid) throw new Error("\u9644\u4EF6\u4E0A\u4F20\u672A\u8FD4\u56DE fileid\uFF1A" + JSON.stringify(upload?.data).slice(0, 200));
|
|
1560
|
+
await env.host.request({
|
|
1561
|
+
path: "/api/mail/base/add/addPermissionFile",
|
|
1562
|
+
method: "POST",
|
|
1563
|
+
body: { fileIds: String(fileid) }
|
|
1564
|
+
});
|
|
1565
|
+
return mailSuccess("mail.attachment.upload", { fileid, name, size }, { fileid });
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
var opAttachmentDownload = {
|
|
1569
|
+
name: "mail.attachment.download",
|
|
1570
|
+
resource: "mail/base/file/batchDownload",
|
|
1571
|
+
method: "POST",
|
|
1572
|
+
action: "mail.attachment.download",
|
|
1573
|
+
summary: "\u6279\u91CF\u4E0B\u8F7D\u9644\u4EF6",
|
|
1574
|
+
risk: WRITE,
|
|
1575
|
+
inputSchema: schemaOf(
|
|
1576
|
+
{ ids: { type: "string", description: "\u9644\u4EF6 id\uFF08\u9017\u53F7\u5206\u9694\uFF09" }, output: { type: "string", description: "\u8F93\u51FA\u76EE\u5F55" } },
|
|
1577
|
+
{ required: ["ids"], description: "\u9644\u4EF6\u4E0B\u8F7D" }
|
|
1578
|
+
),
|
|
1579
|
+
async handler(args, env) {
|
|
1580
|
+
const ids = String(args.ids || "").trim();
|
|
1581
|
+
if (!ids) throw new Error("ids\uFF08\u9644\u4EF6 id\uFF09\u5FC5\u586B");
|
|
1582
|
+
const value = await env.host.request({
|
|
1583
|
+
path: "/api/mail/base/file/batchDownload",
|
|
1584
|
+
method: "POST",
|
|
1585
|
+
body: { ids, output: args.output ? String(args.output) : "" }
|
|
1586
|
+
});
|
|
1587
|
+
return mailSuccess("mail.attachment.download", value?.data ?? "SUCCESS", { ids });
|
|
1588
|
+
}
|
|
1589
|
+
};
|
|
1590
|
+
function buildMultipart(fields, file) {
|
|
1591
|
+
const fd = new FormData();
|
|
1592
|
+
for (const [k, v] of Object.entries(fields)) fd.append(k, v);
|
|
1593
|
+
if (file) fd.append("file", new Blob([new Uint8Array(file.file)], { type: file.type }), file.filename);
|
|
1594
|
+
return fd;
|
|
1595
|
+
}
|
|
1596
|
+
var mailManageOperations = [
|
|
1597
|
+
opStar,
|
|
1598
|
+
opReadStatus,
|
|
1599
|
+
opReadAll,
|
|
1600
|
+
opWaitAdd,
|
|
1601
|
+
opMoveFolder,
|
|
1602
|
+
opDeleteMove,
|
|
1603
|
+
opFolderCreate,
|
|
1604
|
+
opFolderDelete,
|
|
1605
|
+
opRecall,
|
|
1606
|
+
opAttachmentUpload,
|
|
1607
|
+
opAttachmentDownload
|
|
1608
|
+
];
|
|
1609
|
+
|
|
1610
|
+
// src/shortcuts/mail/operations/mail-contacts.ts
|
|
1611
|
+
var CONTINUATION_TTL_MS2 = 6e5;
|
|
1612
|
+
var CONTACT_SCHEMA = schemaOf(
|
|
1613
|
+
{
|
|
1614
|
+
id: SCHEMA_STRING,
|
|
1615
|
+
mailUserName: SCHEMA_STRING,
|
|
1616
|
+
mailAddress: SCHEMA_STRING,
|
|
1617
|
+
mailUserTel: SCHEMA_STRING,
|
|
1618
|
+
mailUserCompany: SCHEMA_STRING,
|
|
1619
|
+
mailUserDesc: SCHEMA_STRING,
|
|
1620
|
+
groupId: SCHEMA_STRING,
|
|
1621
|
+
confirm: { type: "boolean" },
|
|
1622
|
+
continuation: SCHEMA_STRING
|
|
1623
|
+
},
|
|
1624
|
+
{ description: "\u8054\u7CFB\u4EBA\u4FDD\u5B58\uFF08prepare/apply\uFF09" }
|
|
1625
|
+
);
|
|
1626
|
+
function buildContactBody(args) {
|
|
1627
|
+
const name = String(args.mailUserName || "").trim();
|
|
1628
|
+
const address = String(args.mailAddress || "").trim();
|
|
1629
|
+
if (!name) throw new Error("mailUserName\uFF08\u59D3\u540D\uFF09\u5FC5\u586B");
|
|
1630
|
+
if (!address) throw new Error("mailAddress\uFF08\u90AE\u7BB1\u5730\u5740\uFF09\u5FC5\u586B");
|
|
1631
|
+
const body = {
|
|
1632
|
+
mailUserName: name,
|
|
1633
|
+
mailAddress: address,
|
|
1634
|
+
mailUserTel: args.mailUserTel ? String(args.mailUserTel) : "",
|
|
1635
|
+
mailUserCompany: args.mailUserCompany ? String(args.mailUserCompany) : "",
|
|
1636
|
+
mailUserDesc: args.mailUserDesc ? String(args.mailUserDesc) : "",
|
|
1637
|
+
groupId: args.groupId ? String(args.groupId) : ""
|
|
1638
|
+
};
|
|
1639
|
+
if (args.id) body.id = String(args.id);
|
|
1640
|
+
return body;
|
|
1641
|
+
}
|
|
1642
|
+
var opContactSavePrepare = {
|
|
1643
|
+
name: "mail.contacts.save.prepare",
|
|
1644
|
+
resource: "mail/base/contacts/getMailContactsForm",
|
|
1645
|
+
method: "POST",
|
|
1646
|
+
action: "mail.contacts.save.prepare",
|
|
1647
|
+
summary: "\u65B0\u589E/\u7F16\u8F91\u8054\u7CFB\u4EBA\uFF08\u67E5\u5168\u91CF + \u8F93\u51FA\u6458\u8981\uFF0C\u4E0D\u4FDD\u5B58\uFF09",
|
|
1648
|
+
risk: WRITE,
|
|
1649
|
+
requiresConfirmation: true,
|
|
1650
|
+
inputSchema: CONTACT_SCHEMA,
|
|
1651
|
+
async handler(args, env) {
|
|
1652
|
+
const body = buildContactBody(args);
|
|
1653
|
+
const session = await env.host.getSession();
|
|
1654
|
+
const form = await env.host.request({ path: "/api/mail/base/contacts/getMailContactsForm", method: "POST", body: { id: args.id ? String(args.id) : "" } });
|
|
1655
|
+
const continuation = await env.continuation.issue(
|
|
1656
|
+
{
|
|
1657
|
+
operation: "mail.contacts.save.apply",
|
|
1658
|
+
baseUrl: session.baseUrl,
|
|
1659
|
+
profile: session.profile,
|
|
1660
|
+
userId: session.userId,
|
|
1661
|
+
body
|
|
1662
|
+
},
|
|
1663
|
+
CONTINUATION_TTL_MS2
|
|
1664
|
+
);
|
|
1665
|
+
return mailSuccess("mail.contacts.save.prepare", {
|
|
1666
|
+
mode: body.id ? "edit" : "create",
|
|
1667
|
+
mailUserName: body.mailUserName,
|
|
1668
|
+
mailAddress: body.mailAddress,
|
|
1669
|
+
groupId: body.groupId || "",
|
|
1670
|
+
tip: "\u786E\u8BA4\u540E\u4EE5 mail contacts save --apply --continuation <token> --yes \u6267\u884C\u4FDD\u5B58"
|
|
1671
|
+
}, { continuation, formFields: form?.data });
|
|
1672
|
+
}
|
|
1673
|
+
};
|
|
1674
|
+
var opContactSaveApply = {
|
|
1675
|
+
name: "mail.contacts.save.apply",
|
|
1676
|
+
resource: "mail/base/contacts/saveMailContacts",
|
|
1677
|
+
method: "POST",
|
|
1678
|
+
action: "mail.contacts.save.apply",
|
|
1679
|
+
summary: "\u6267\u884C\u4FDD\u5B58\u8054\u7CFB\u4EBA",
|
|
1680
|
+
risk: WRITE,
|
|
1681
|
+
requiresConfirmation: true,
|
|
1682
|
+
inputSchema: CONTACT_SCHEMA,
|
|
1683
|
+
async handler(args, env) {
|
|
1684
|
+
if (args.confirm !== true) throw new Error("mail.contacts.save.apply \u5FC5\u987B\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation");
|
|
1685
|
+
if (!args.continuation) throw new Error("mail.contacts.save.apply \u5FC5\u987B\u4F20\u5165 prepare \u8FD4\u56DE\u7684 continuation");
|
|
1686
|
+
const lease = await env.continuation.verify(String(args.continuation), "mail.contacts.save.apply");
|
|
1687
|
+
const session = await env.host.getSession();
|
|
1688
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
1689
|
+
throw mailValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
1690
|
+
}
|
|
1691
|
+
const value = await env.host.request({ path: "/api/mail/base/contacts/saveMailContacts", method: "POST", body: lease.body });
|
|
1692
|
+
return mailSuccess("mail.contacts.save.apply", { id: value?.data ?? "SUCCESS", mode: lease.body?.id ? "edit" : "create" }, {});
|
|
1693
|
+
}
|
|
1694
|
+
};
|
|
1695
|
+
var opContactDelete = {
|
|
1696
|
+
name: "mail.contacts.delete",
|
|
1697
|
+
resource: "mail/base/contacts/delContacts",
|
|
1698
|
+
method: "POST",
|
|
1699
|
+
action: "mail.contacts.delete",
|
|
1700
|
+
summary: "\u5220\u9664\u8054\u7CFB\u4EBA",
|
|
1701
|
+
risk: WRITE,
|
|
1702
|
+
inputSchema: schemaOf(
|
|
1703
|
+
{ id: { type: "string", description: "\u8054\u7CFB\u4EBA id \u6216\u9017\u53F7\u5206\u9694\u591A\u4E2A" } },
|
|
1704
|
+
{ required: ["id"], description: "\u5220\u9664\u8054\u7CFB\u4EBA" }
|
|
1705
|
+
),
|
|
1706
|
+
async handler(args, env) {
|
|
1707
|
+
const id = String(args.id || "").trim();
|
|
1708
|
+
if (!id) throw new Error("id\uFF08\u8054\u7CFB\u4EBA id\uFF09\u5FC5\u586B");
|
|
1709
|
+
const value = await env.host.request({ path: "/api/mail/base/contacts/delContacts", method: "POST", body: { ids: id } });
|
|
1710
|
+
return mailSuccess("mail.contacts.delete", value?.data ?? true, { id });
|
|
1711
|
+
}
|
|
1712
|
+
};
|
|
1713
|
+
var GROUP_SCHEMA = schemaOf(
|
|
1714
|
+
{
|
|
1715
|
+
id: SCHEMA_STRING,
|
|
1716
|
+
groupName: SCHEMA_STRING,
|
|
1717
|
+
confirm: { type: "boolean" },
|
|
1718
|
+
continuation: SCHEMA_STRING
|
|
1719
|
+
},
|
|
1720
|
+
{ description: "\u5206\u7EC4\u4FDD\u5B58\uFF08prepare/apply\uFF09" }
|
|
1721
|
+
);
|
|
1722
|
+
function buildGroupBody(args) {
|
|
1723
|
+
const groupName = String(args.groupName || "").trim();
|
|
1724
|
+
if (!groupName) throw new Error("groupName\uFF08\u5206\u7EC4\u540D\uFF09\u5FC5\u586B");
|
|
1725
|
+
const body = { groupName };
|
|
1726
|
+
if (args.id) body.groupId = String(args.id);
|
|
1727
|
+
return body;
|
|
1728
|
+
}
|
|
1729
|
+
var opGroupSavePrepare = {
|
|
1730
|
+
name: "mail.contacts.group.save.prepare",
|
|
1731
|
+
resource: "mail/base/contacts/saveMailContactsGroup",
|
|
1732
|
+
method: "POST",
|
|
1733
|
+
action: "mail.contacts.group.save.prepare",
|
|
1734
|
+
summary: "\u65B0\u589E/\u7F16\u8F91\u5206\u7EC4\uFF08prepare\uFF0C\u4E0D\u4FDD\u5B58\uFF09",
|
|
1735
|
+
risk: WRITE,
|
|
1736
|
+
requiresConfirmation: true,
|
|
1737
|
+
inputSchema: GROUP_SCHEMA,
|
|
1738
|
+
async handler(args, env) {
|
|
1739
|
+
const body = buildGroupBody(args);
|
|
1740
|
+
const session = await env.host.getSession();
|
|
1741
|
+
const continuation = await env.continuation.issue(
|
|
1742
|
+
{
|
|
1743
|
+
operation: "mail.contacts.group.save.apply",
|
|
1744
|
+
baseUrl: session.baseUrl,
|
|
1745
|
+
profile: session.profile,
|
|
1746
|
+
userId: session.userId,
|
|
1747
|
+
body
|
|
1748
|
+
},
|
|
1749
|
+
CONTINUATION_TTL_MS2
|
|
1750
|
+
);
|
|
1751
|
+
return mailSuccess("mail.contacts.group.save.prepare", {
|
|
1752
|
+
mode: body.groupId ? "edit" : "create",
|
|
1753
|
+
groupName: body.groupName,
|
|
1754
|
+
tip: "\u786E\u8BA4\u540E\u4EE5 mail contacts group save --apply --continuation <token> --yes \u6267\u884C\u4FDD\u5B58"
|
|
1755
|
+
}, { continuation });
|
|
1756
|
+
}
|
|
1757
|
+
};
|
|
1758
|
+
var opGroupSaveApply = {
|
|
1759
|
+
name: "mail.contacts.group.save.apply",
|
|
1760
|
+
resource: "mail/base/contacts/saveMailContactsGroup",
|
|
1761
|
+
method: "POST",
|
|
1762
|
+
action: "mail.contacts.group.save.apply",
|
|
1763
|
+
summary: "\u6267\u884C\u4FDD\u5B58\u5206\u7EC4",
|
|
1764
|
+
risk: WRITE,
|
|
1765
|
+
requiresConfirmation: true,
|
|
1766
|
+
inputSchema: GROUP_SCHEMA,
|
|
1767
|
+
async handler(args, env) {
|
|
1768
|
+
if (args.confirm !== true) throw new Error("mail.contacts.group.save.apply \u5FC5\u987B\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation");
|
|
1769
|
+
if (!args.continuation) throw new Error("mail.contacts.group.save.apply \u5FC5\u987B\u4F20\u5165 prepare \u8FD4\u56DE\u7684 continuation");
|
|
1770
|
+
const lease = await env.continuation.verify(String(args.continuation), "mail.contacts.group.save.apply");
|
|
1771
|
+
const session = await env.host.getSession();
|
|
1772
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
1773
|
+
throw mailValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
1774
|
+
}
|
|
1775
|
+
const value = await env.host.request({ path: "/api/mail/base/contacts/saveMailContactsGroup", method: "POST", body: lease.body });
|
|
1776
|
+
return mailSuccess("mail.contacts.group.save.apply", { id: value?.data ?? "SUCCESS", mode: lease.body?.groupId ? "edit" : "create" }, {});
|
|
1777
|
+
}
|
|
1778
|
+
};
|
|
1779
|
+
var opGroupDelete = {
|
|
1780
|
+
name: "mail.contacts.group.delete",
|
|
1781
|
+
resource: "mail/base/contacts/delContactsGroup",
|
|
1782
|
+
method: "POST",
|
|
1783
|
+
action: "mail.contacts.group.delete",
|
|
1784
|
+
summary: "\u5220\u9664\u5206\u7EC4",
|
|
1785
|
+
risk: WRITE,
|
|
1786
|
+
inputSchema: schemaOf(
|
|
1787
|
+
{ id: { type: "string", description: "\u5206\u7EC4 id" } },
|
|
1788
|
+
{ required: ["id"], description: "\u5220\u9664\u5206\u7EC4" }
|
|
1789
|
+
),
|
|
1790
|
+
async handler(args, env) {
|
|
1791
|
+
const id = String(args.id || "").trim();
|
|
1792
|
+
if (!id) throw new Error("id\uFF08\u5206\u7EC4 id\uFF09\u5FC5\u586B");
|
|
1793
|
+
const value = await env.host.request({ path: "/api/mail/base/contacts/delContactsGroup", method: "POST", body: { groupId: id } });
|
|
1794
|
+
return mailSuccess("mail.contacts.group.delete", value?.data ?? true, { id });
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
var mailContactsOperations = [
|
|
1798
|
+
opContactSavePrepare,
|
|
1799
|
+
opContactSaveApply,
|
|
1800
|
+
opContactDelete,
|
|
1801
|
+
opGroupSavePrepare,
|
|
1802
|
+
opGroupSaveApply,
|
|
1803
|
+
opGroupDelete
|
|
1804
|
+
];
|
|
1805
|
+
|
|
1806
|
+
// src/shortcuts/mail/operations/mail-template.ts
|
|
1807
|
+
var CONTINUATION_TTL_MS3 = 6e5;
|
|
1808
|
+
var TEMPLATE_SCHEMA = schemaOf(
|
|
1809
|
+
{
|
|
1810
|
+
id: SCHEMA_STRING,
|
|
1811
|
+
templateType: SCHEMA_STRING,
|
|
1812
|
+
subject: SCHEMA_STRING,
|
|
1813
|
+
mailSubject: SCHEMA_STRING,
|
|
1814
|
+
clobContent: SCHEMA_STRING,
|
|
1815
|
+
templateDesc: SCHEMA_STRING,
|
|
1816
|
+
defaultUse: SCHEMA_STRING,
|
|
1817
|
+
contentId: SCHEMA_STRING,
|
|
1818
|
+
confirm: { type: "boolean" },
|
|
1819
|
+
continuation: SCHEMA_STRING
|
|
1820
|
+
},
|
|
1821
|
+
{ description: "\u6A21\u677F\u4FDD\u5B58\uFF08prepare/apply\uFF09" }
|
|
1822
|
+
);
|
|
1823
|
+
function buildTemplateBody(args) {
|
|
1824
|
+
const subject = String(args.subject || "").trim();
|
|
1825
|
+
const clobContent = String(args.clobContent || "").trim();
|
|
1826
|
+
if (!subject) throw new Error("subject\uFF08\u6A21\u677F\u4E3B\u9898\uFF09\u5FC5\u586B");
|
|
1827
|
+
if (!clobContent) throw new Error("clobContent\uFF08Base64 \u7F16\u7801\u7684 HTML \u5185\u5BB9\uFF09\u5FC5\u586B");
|
|
1828
|
+
const body = {
|
|
1829
|
+
templateType: args.templateType ? String(args.templateType) : "personal",
|
|
1830
|
+
subject,
|
|
1831
|
+
mailSubject: args.mailSubject ? String(args.mailSubject) : subject,
|
|
1832
|
+
clobContent,
|
|
1833
|
+
templateDesc: args.templateDesc ? String(args.templateDesc) : "",
|
|
1834
|
+
defaultUse: args.defaultUse !== void 0 ? Number(args.defaultUse) : 0,
|
|
1835
|
+
contentId: args.contentId ? String(args.contentId) : "null",
|
|
1836
|
+
id: "null",
|
|
1837
|
+
templateFile: []
|
|
1838
|
+
};
|
|
1839
|
+
if (args.id) body.id = String(args.id);
|
|
1840
|
+
return body;
|
|
1841
|
+
}
|
|
1842
|
+
var opTemplateSavePrepare = {
|
|
1843
|
+
name: "mail.template.save.prepare",
|
|
1844
|
+
resource: "mail/base/setting/template/saveMailTemplate",
|
|
1845
|
+
method: "POST",
|
|
1846
|
+
action: "mail.template.save.prepare",
|
|
1847
|
+
summary: "\u65B0\u589E\u6A21\u677F\uFF08prepare\uFF0C\u4E0D\u4FDD\u5B58\uFF09",
|
|
1848
|
+
risk: WRITE,
|
|
1849
|
+
requiresConfirmation: true,
|
|
1850
|
+
inputSchema: TEMPLATE_SCHEMA,
|
|
1851
|
+
async handler(args, env) {
|
|
1852
|
+
const body = buildTemplateBody(args);
|
|
1853
|
+
const session = await env.host.getSession();
|
|
1854
|
+
const continuation = await env.continuation.issue(
|
|
1855
|
+
{
|
|
1856
|
+
operation: "mail.template.save.apply",
|
|
1857
|
+
baseUrl: session.baseUrl,
|
|
1858
|
+
profile: session.profile,
|
|
1859
|
+
userId: session.userId,
|
|
1860
|
+
body
|
|
1861
|
+
},
|
|
1862
|
+
CONTINUATION_TTL_MS3
|
|
1863
|
+
);
|
|
1864
|
+
return mailSuccess("mail.template.save.prepare", {
|
|
1865
|
+
subject: body.subject,
|
|
1866
|
+
templateType: body.templateType,
|
|
1867
|
+
defaultUse: body.defaultUse,
|
|
1868
|
+
tip: "\u786E\u8BA4\u540E\u4EE5 mail template save --apply --continuation <token> --yes \u6267\u884C\u4FDD\u5B58"
|
|
1869
|
+
}, { continuation });
|
|
1870
|
+
}
|
|
1871
|
+
};
|
|
1872
|
+
var opTemplateSaveApply = {
|
|
1873
|
+
name: "mail.template.save.apply",
|
|
1874
|
+
resource: "mail/base/setting/template/saveMailTemplate",
|
|
1875
|
+
method: "POST",
|
|
1876
|
+
action: "mail.template.save.apply",
|
|
1877
|
+
summary: "\u6267\u884C\u65B0\u589E\u6A21\u677F",
|
|
1878
|
+
risk: WRITE,
|
|
1879
|
+
requiresConfirmation: true,
|
|
1880
|
+
inputSchema: TEMPLATE_SCHEMA,
|
|
1881
|
+
async handler(args, env) {
|
|
1882
|
+
if (args.confirm !== true) throw new Error("mail.template.save.apply \u5FC5\u987B\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation");
|
|
1883
|
+
if (!args.continuation) throw new Error("mail.template.save.apply \u5FC5\u987B\u4F20\u5165 prepare \u8FD4\u56DE\u7684 continuation");
|
|
1884
|
+
const lease = await env.continuation.verify(String(args.continuation), "mail.template.save.apply");
|
|
1885
|
+
const session = await env.host.getSession();
|
|
1886
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
1887
|
+
throw mailValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
1888
|
+
}
|
|
1889
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/template/saveMailTemplate", method: "POST", body: lease.body });
|
|
1890
|
+
return mailSuccess("mail.template.save.apply", { id: value?.data ?? "SUCCESS" }, {});
|
|
1891
|
+
}
|
|
1892
|
+
};
|
|
1893
|
+
var opTemplateUpdate = {
|
|
1894
|
+
name: "mail.template.update",
|
|
1895
|
+
resource: "mail/base/setting/template/updateMailTemplate",
|
|
1896
|
+
method: "POST",
|
|
1897
|
+
action: "mail.template.update",
|
|
1898
|
+
summary: "\u7F16\u8F91\u6A21\u677F\uFF08GET \u5168\u91CF + \u4FDD\u5B58\uFF09",
|
|
1899
|
+
risk: WRITE,
|
|
1900
|
+
inputSchema: schemaOf(
|
|
1901
|
+
{
|
|
1902
|
+
id: { type: "string", description: "\u6A21\u677F id" },
|
|
1903
|
+
subject: SCHEMA_STRING,
|
|
1904
|
+
clobContent: SCHEMA_STRING,
|
|
1905
|
+
templateDesc: SCHEMA_STRING,
|
|
1906
|
+
defaultUse: SCHEMA_STRING,
|
|
1907
|
+
templateType: SCHEMA_STRING
|
|
1908
|
+
},
|
|
1909
|
+
{ required: ["id"], description: "\u7F16\u8F91\u6A21\u677F" }
|
|
1910
|
+
),
|
|
1911
|
+
async handler(args, env) {
|
|
1912
|
+
const id = String(args.id || "").trim();
|
|
1913
|
+
if (!id) throw new Error("id\uFF08\u6A21\u677F id\uFF09\u5FC5\u586B");
|
|
1914
|
+
const info = await env.host.request({
|
|
1915
|
+
path: "/api/mail/base/setting/template/getMailTemplateInfo",
|
|
1916
|
+
method: "POST",
|
|
1917
|
+
form: { id, fromModule: "mail" }
|
|
1918
|
+
});
|
|
1919
|
+
const cur = info?.data || {};
|
|
1920
|
+
const body = {
|
|
1921
|
+
id,
|
|
1922
|
+
templateType: args.templateType ? String(args.templateType) : cur.templateType ?? "personal",
|
|
1923
|
+
mailSubject: args.mailSubject ? String(args.mailSubject) : cur.mailSubject ?? "",
|
|
1924
|
+
subject: args.subject ? String(args.subject) : cur.subject ?? "",
|
|
1925
|
+
clobContent: args.clobContent ? String(args.clobContent) : cur.clobContent ?? "",
|
|
1926
|
+
templateDesc: args.templateDesc ? String(args.templateDesc) : cur.templateDesc ?? "",
|
|
1927
|
+
defaultUse: args.defaultUse !== void 0 ? Number(args.defaultUse) : cur.defaultUse ?? 0,
|
|
1928
|
+
contentId: cur.contentId ?? "null",
|
|
1929
|
+
templateFile: cur.templateFile ?? []
|
|
1930
|
+
};
|
|
1931
|
+
if (!body.subject) throw new Error("\u6A21\u677F\u4E3B\u9898\u4E3A\u7A7A\uFF08\u539F\u503C\u7F3A\u5931\u4E14\u672A\u63D0\u4F9B subject\uFF09");
|
|
1932
|
+
if (!body.clobContent) throw new Error("\u6A21\u677F\u5185\u5BB9\u4E3A\u7A7A\uFF08\u539F\u503C\u7F3A\u5931\u4E14\u672A\u63D0\u4F9B clobContent\uFF09");
|
|
1933
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/template/updateMailTemplate", method: "POST", body });
|
|
1934
|
+
return mailSuccess("mail.template.update", value?.data ?? "SUCCESS", { id });
|
|
1935
|
+
}
|
|
1936
|
+
};
|
|
1937
|
+
var opTemplateDelete = {
|
|
1938
|
+
name: "mail.template.delete",
|
|
1939
|
+
resource: "mail/base/setting/template/deleteMailTemplate",
|
|
1940
|
+
method: "POST",
|
|
1941
|
+
action: "mail.template.delete",
|
|
1942
|
+
summary: "\u5220\u9664\u6A21\u677F",
|
|
1943
|
+
risk: WRITE,
|
|
1944
|
+
inputSchema: schemaOf(
|
|
1945
|
+
{ id: { type: "string", description: "\u6A21\u677F id" } },
|
|
1946
|
+
{ required: ["id"], description: "\u5220\u9664\u6A21\u677F" }
|
|
1947
|
+
),
|
|
1948
|
+
async handler(args, env) {
|
|
1949
|
+
const id = String(args.id || "").trim();
|
|
1950
|
+
if (!id) throw new Error("id\uFF08\u6A21\u677F id\uFF09\u5FC5\u586B");
|
|
1951
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/template/deleteMailTemplate", method: "POST", body: { id } });
|
|
1952
|
+
return mailSuccess("mail.template.delete", value?.data ?? "SUCCESS", { id });
|
|
1953
|
+
}
|
|
1954
|
+
};
|
|
1955
|
+
var opTemplateDefault = {
|
|
1956
|
+
name: "mail.template.default",
|
|
1957
|
+
resource: "mail/base/setting/template/defaultMailTemplate",
|
|
1958
|
+
method: "POST",
|
|
1959
|
+
action: "mail.template.default",
|
|
1960
|
+
summary: "\u8BBE\u4E3A\u9ED8\u8BA4\u6A21\u677F",
|
|
1961
|
+
risk: WRITE,
|
|
1962
|
+
inputSchema: schemaOf(
|
|
1963
|
+
{ id: { type: "string", description: "\u6A21\u677F id" } },
|
|
1964
|
+
{ required: ["id"], description: "\u8BBE\u9ED8\u8BA4\u6A21\u677F" }
|
|
1965
|
+
),
|
|
1966
|
+
async handler(args, env) {
|
|
1967
|
+
const id = String(args.id || "").trim();
|
|
1968
|
+
if (!id) throw new Error("id\uFF08\u6A21\u677F id\uFF09\u5FC5\u586B");
|
|
1969
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/template/defaultMailTemplate", method: "POST", body: { id } });
|
|
1970
|
+
return mailSuccess("mail.template.default", value?.data ?? "SUCCESS", { id });
|
|
1971
|
+
}
|
|
1972
|
+
};
|
|
1973
|
+
var mailTemplateOperations = [
|
|
1974
|
+
opTemplateSavePrepare,
|
|
1975
|
+
opTemplateSaveApply,
|
|
1976
|
+
opTemplateUpdate,
|
|
1977
|
+
opTemplateDelete,
|
|
1978
|
+
opTemplateDefault
|
|
1979
|
+
];
|
|
1980
|
+
|
|
1981
|
+
// src/shortcuts/mail/operations/mail-sign.ts
|
|
1982
|
+
var CONTINUATION_TTL_MS4 = 6e5;
|
|
1983
|
+
var SIGN_SCHEMA = schemaOf(
|
|
1984
|
+
{
|
|
1985
|
+
id: SCHEMA_STRING,
|
|
1986
|
+
signName: SCHEMA_STRING,
|
|
1987
|
+
clobContent: SCHEMA_STRING,
|
|
1988
|
+
signDesc: SCHEMA_STRING,
|
|
1989
|
+
defaultUse: SCHEMA_STRING,
|
|
1990
|
+
signType: SCHEMA_STRING,
|
|
1991
|
+
electronSignEnable: SCHEMA_STRING,
|
|
1992
|
+
confirm: { type: "boolean" },
|
|
1993
|
+
continuation: SCHEMA_STRING
|
|
1994
|
+
},
|
|
1995
|
+
{ description: "\u7B7E\u540D\u4FDD\u5B58\uFF08prepare/apply\uFF09" }
|
|
1996
|
+
);
|
|
1997
|
+
function buildSignBody(args) {
|
|
1998
|
+
const signName = String(args.signName || "").trim();
|
|
1999
|
+
const clobContent = String(args.clobContent || "").trim();
|
|
2000
|
+
if (!signName) throw new Error("signName\uFF08\u7B7E\u540D\u540D\u79F0\uFF09\u5FC5\u586B");
|
|
2001
|
+
if (!clobContent) throw new Error("clobContent\uFF08Base64 \u7F16\u7801\u7684 HTML \u5185\u5BB9\uFF09\u5FC5\u586B");
|
|
2002
|
+
const body = {
|
|
2003
|
+
signName,
|
|
2004
|
+
clobContent,
|
|
2005
|
+
signDesc: args.signDesc ? String(args.signDesc) : "",
|
|
2006
|
+
defaultUse: args.defaultUse !== void 0 ? Number(args.defaultUse) : 0,
|
|
2007
|
+
signType: args.signType ? String(args.signType) : "0",
|
|
2008
|
+
electronSignEnable: args.electronSignEnable !== void 0 ? Number(args.electronSignEnable) : 0
|
|
2009
|
+
};
|
|
2010
|
+
if (args.id) body.id = String(args.id);
|
|
2011
|
+
return body;
|
|
2012
|
+
}
|
|
2013
|
+
var opSignSavePrepare = {
|
|
2014
|
+
name: "mail.sign.save.prepare",
|
|
2015
|
+
resource: "mail/base/setting/sign/saveMailSign",
|
|
2016
|
+
method: "POST",
|
|
2017
|
+
action: "mail.sign.save.prepare",
|
|
2018
|
+
summary: "\u65B0\u589E\u7B7E\u540D\uFF08prepare\uFF0C\u4E0D\u4FDD\u5B58\uFF09",
|
|
2019
|
+
risk: WRITE,
|
|
2020
|
+
requiresConfirmation: true,
|
|
2021
|
+
inputSchema: SIGN_SCHEMA,
|
|
2022
|
+
async handler(args, env) {
|
|
2023
|
+
const body = buildSignBody(args);
|
|
2024
|
+
const session = await env.host.getSession();
|
|
2025
|
+
const continuation = await env.continuation.issue(
|
|
2026
|
+
{
|
|
2027
|
+
operation: "mail.sign.save.apply",
|
|
2028
|
+
baseUrl: session.baseUrl,
|
|
2029
|
+
profile: session.profile,
|
|
2030
|
+
userId: session.userId,
|
|
2031
|
+
body
|
|
2032
|
+
},
|
|
2033
|
+
CONTINUATION_TTL_MS4
|
|
2034
|
+
);
|
|
2035
|
+
return mailSuccess("mail.sign.save.prepare", {
|
|
2036
|
+
signName: body.signName,
|
|
2037
|
+
defaultUse: body.defaultUse,
|
|
2038
|
+
tip: "\u786E\u8BA4\u540E\u4EE5 mail sign save --apply --continuation <token> --yes \u6267\u884C\u4FDD\u5B58"
|
|
2039
|
+
}, { continuation });
|
|
2040
|
+
}
|
|
2041
|
+
};
|
|
2042
|
+
var opSignSaveApply = {
|
|
2043
|
+
name: "mail.sign.save.apply",
|
|
2044
|
+
resource: "mail/base/setting/sign/saveMailSign",
|
|
2045
|
+
method: "POST",
|
|
2046
|
+
action: "mail.sign.save.apply",
|
|
2047
|
+
summary: "\u6267\u884C\u65B0\u589E\u7B7E\u540D",
|
|
2048
|
+
risk: WRITE,
|
|
2049
|
+
requiresConfirmation: true,
|
|
2050
|
+
inputSchema: SIGN_SCHEMA,
|
|
2051
|
+
async handler(args, env) {
|
|
2052
|
+
if (args.confirm !== true) throw new Error("mail.sign.save.apply \u5FC5\u987B\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation");
|
|
2053
|
+
if (!args.continuation) throw new Error("mail.sign.save.apply \u5FC5\u987B\u4F20\u5165 prepare \u8FD4\u56DE\u7684 continuation");
|
|
2054
|
+
const lease = await env.continuation.verify(String(args.continuation), "mail.sign.save.apply");
|
|
2055
|
+
const session = await env.host.getSession();
|
|
2056
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
2057
|
+
throw mailValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
2058
|
+
}
|
|
2059
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/sign/saveMailSign", method: "POST", body: lease.body });
|
|
2060
|
+
return mailSuccess("mail.sign.save.apply", { id: value?.data ?? "SUCCESS" }, {});
|
|
2061
|
+
}
|
|
2062
|
+
};
|
|
2063
|
+
var opSignUpdate = {
|
|
2064
|
+
name: "mail.sign.update",
|
|
2065
|
+
resource: "mail/base/setting/sign/updateMailSign",
|
|
2066
|
+
method: "POST",
|
|
2067
|
+
action: "mail.sign.update",
|
|
2068
|
+
summary: "\u7F16\u8F91\u7B7E\u540D\uFF08GET \u5168\u91CF + \u4FDD\u5B58\uFF09",
|
|
2069
|
+
risk: WRITE,
|
|
2070
|
+
inputSchema: schemaOf(
|
|
2071
|
+
{
|
|
2072
|
+
id: { type: "string", description: "\u7B7E\u540D id" },
|
|
2073
|
+
signName: SCHEMA_STRING,
|
|
2074
|
+
clobContent: SCHEMA_STRING,
|
|
2075
|
+
signDesc: SCHEMA_STRING,
|
|
2076
|
+
defaultUse: SCHEMA_STRING,
|
|
2077
|
+
signType: SCHEMA_STRING,
|
|
2078
|
+
electronSignEnable: SCHEMA_STRING
|
|
2079
|
+
},
|
|
2080
|
+
{ required: ["id"], description: "\u7F16\u8F91\u7B7E\u540D" }
|
|
2081
|
+
),
|
|
2082
|
+
async handler(args, env) {
|
|
2083
|
+
const id = String(args.id || "").trim();
|
|
2084
|
+
if (!id) throw new Error("id\uFF08\u7B7E\u540D id\uFF09\u5FC5\u586B");
|
|
2085
|
+
const form = await env.host.request({ path: "/api/mail/base/setting/sign/getMailSignForm", method: "POST", body: { id } });
|
|
2086
|
+
const cur = form?.data?.formData || {};
|
|
2087
|
+
const body = {
|
|
2088
|
+
id,
|
|
2089
|
+
signName: args.signName ? String(args.signName) : cur.signName ?? "",
|
|
2090
|
+
clobContent: args.clobContent ? String(args.clobContent) : cur.clobContent ?? "",
|
|
2091
|
+
signDesc: args.signDesc ? String(args.signDesc) : cur.signDesc ?? "",
|
|
2092
|
+
defaultUse: args.defaultUse !== void 0 ? Number(args.defaultUse) : cur.defaultUse ?? 0,
|
|
2093
|
+
signType: args.signType ? String(args.signType) : cur.signType ?? "0",
|
|
2094
|
+
electronSignEnable: args.electronSignEnable !== void 0 ? Number(args.electronSignEnable) : cur.electronSignEnable ?? 0
|
|
2095
|
+
};
|
|
2096
|
+
if (!body.signName) throw new Error("\u7B7E\u540D\u540D\u79F0\u4E3A\u7A7A\uFF08\u539F\u503C\u7F3A\u5931\u4E14\u672A\u63D0\u4F9B signName\uFF09");
|
|
2097
|
+
if (!body.clobContent) throw new Error("\u7B7E\u540D\u5185\u5BB9\u4E3A\u7A7A\uFF08\u539F\u503C\u7F3A\u5931\u4E14\u672A\u63D0\u4F9B clobContent\uFF09");
|
|
2098
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/sign/updateMailSign", method: "POST", body });
|
|
2099
|
+
return mailSuccess("mail.sign.update", value?.data ?? "SUCCESS", { id });
|
|
2100
|
+
}
|
|
2101
|
+
};
|
|
2102
|
+
var opSignDelete = {
|
|
2103
|
+
name: "mail.sign.delete",
|
|
2104
|
+
resource: "mail/base/setting/sign/deleteMailSign",
|
|
2105
|
+
method: "POST",
|
|
2106
|
+
action: "mail.sign.delete",
|
|
2107
|
+
summary: "\u5220\u9664\u7B7E\u540D",
|
|
2108
|
+
risk: WRITE,
|
|
2109
|
+
inputSchema: schemaOf(
|
|
2110
|
+
{ id: { type: "string", description: "\u7B7E\u540D id" } },
|
|
2111
|
+
{ required: ["id"], description: "\u5220\u9664\u7B7E\u540D" }
|
|
2112
|
+
),
|
|
2113
|
+
async handler(args, env) {
|
|
2114
|
+
const id = String(args.id || "").trim();
|
|
2115
|
+
if (!id) throw new Error("id\uFF08\u7B7E\u540D id\uFF09\u5FC5\u586B");
|
|
2116
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/sign/deleteMailSign", method: "POST", body: { id } });
|
|
2117
|
+
return mailSuccess("mail.sign.delete", value?.data ?? "SUCCESS", { id });
|
|
2118
|
+
}
|
|
2119
|
+
};
|
|
2120
|
+
var opSignDefault = {
|
|
2121
|
+
name: "mail.sign.default",
|
|
2122
|
+
resource: "mail/base/setting/sign/defaultMailSign",
|
|
2123
|
+
method: "POST",
|
|
2124
|
+
action: "mail.sign.default",
|
|
2125
|
+
summary: "\u8BBE\u4E3A\u9ED8\u8BA4\u7B7E\u540D",
|
|
2126
|
+
risk: WRITE,
|
|
2127
|
+
inputSchema: schemaOf(
|
|
2128
|
+
{ id: { type: "string", description: "\u7B7E\u540D id" } },
|
|
2129
|
+
{ required: ["id"], description: "\u8BBE\u9ED8\u8BA4\u7B7E\u540D" }
|
|
2130
|
+
),
|
|
2131
|
+
async handler(args, env) {
|
|
2132
|
+
const id = String(args.id || "").trim();
|
|
2133
|
+
if (!id) throw new Error("id\uFF08\u7B7E\u540D id\uFF09\u5FC5\u586B");
|
|
2134
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/sign/defaultMailSign", method: "POST", body: { id } });
|
|
2135
|
+
return mailSuccess("mail.sign.default", value?.data ?? "SUCCESS", { id });
|
|
2136
|
+
}
|
|
2137
|
+
};
|
|
2138
|
+
var opSignQrcode = {
|
|
2139
|
+
name: "mail.sign.qrcode",
|
|
2140
|
+
resource: "mail/base/setting/sign/createQRcode",
|
|
2141
|
+
method: "POST",
|
|
2142
|
+
action: "mail.sign.qrcode",
|
|
2143
|
+
summary: "\u751F\u6210\u4E8C\u7EF4\u7801\u540D\u7247",
|
|
2144
|
+
risk: READ,
|
|
2145
|
+
inputSchema: schemaOf(
|
|
2146
|
+
{
|
|
2147
|
+
id: SCHEMA_STRING,
|
|
2148
|
+
userName: SCHEMA_STRING,
|
|
2149
|
+
jobtitle: SCHEMA_STRING,
|
|
2150
|
+
email: SCHEMA_STRING,
|
|
2151
|
+
signLocation: SCHEMA_STRING,
|
|
2152
|
+
mobile: SCHEMA_STRING,
|
|
2153
|
+
telephone: SCHEMA_STRING,
|
|
2154
|
+
fax: SCHEMA_STRING,
|
|
2155
|
+
selected: SCHEMA_STRING
|
|
2156
|
+
},
|
|
2157
|
+
{ description: "\u4E8C\u7EF4\u7801\u540D\u7247" }
|
|
2158
|
+
),
|
|
2159
|
+
async handler(args, env) {
|
|
2160
|
+
let userName = args.userName ? String(args.userName) : "";
|
|
2161
|
+
if (!userName && args.id) {
|
|
2162
|
+
try {
|
|
2163
|
+
const form = await env.host.request({ path: "/api/mail/base/setting/sign/getMailSignForm", method: "POST", body: { id: String(args.id) } });
|
|
2164
|
+
const cur = form?.data?.formData || {};
|
|
2165
|
+
userName = cur.signName || "";
|
|
2166
|
+
} catch {
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
const body = {
|
|
2170
|
+
userName,
|
|
2171
|
+
jobtitle: args.jobtitle ? String(args.jobtitle) : "",
|
|
2172
|
+
email: args.email ? String(args.email) : "",
|
|
2173
|
+
signLocation: args.signLocation ? String(args.signLocation) : "",
|
|
2174
|
+
mobile: args.mobile ? String(args.mobile) : "",
|
|
2175
|
+
telephone: args.telephone ? String(args.telephone) : "",
|
|
2176
|
+
fax: args.fax ? String(args.fax) : "",
|
|
2177
|
+
selected: args.selected ? String(args.selected) : userName ? "1,2,3,5" : "1"
|
|
2178
|
+
};
|
|
2179
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/sign/createQRcode", method: "POST", body });
|
|
2180
|
+
return mailSuccess("mail.sign.qrcode", { qrcode: value?.data ?? "" }, {});
|
|
2181
|
+
}
|
|
2182
|
+
};
|
|
2183
|
+
var mailSignOperations = [
|
|
2184
|
+
opSignSavePrepare,
|
|
2185
|
+
opSignSaveApply,
|
|
2186
|
+
opSignUpdate,
|
|
2187
|
+
opSignDelete,
|
|
2188
|
+
opSignDefault,
|
|
2189
|
+
opSignQrcode
|
|
2190
|
+
];
|
|
2191
|
+
|
|
2192
|
+
// src/shortcuts/mail/operations/mail-blacklist.ts
|
|
2193
|
+
var CONTINUATION_TTL_MS5 = 6e5;
|
|
2194
|
+
var BLACKLIST_SCHEMA = schemaOf(
|
|
2195
|
+
{
|
|
2196
|
+
operateType: { type: "string", description: "add / delete" },
|
|
2197
|
+
mailAddress: SCHEMA_STRING,
|
|
2198
|
+
id: SCHEMA_STRING,
|
|
2199
|
+
confirm: { type: "boolean" },
|
|
2200
|
+
continuation: SCHEMA_STRING
|
|
2201
|
+
},
|
|
2202
|
+
{ description: "\u9ED1\u540D\u5355\u64CD\u4F5C\uFF08prepare/apply\uFF09" }
|
|
2203
|
+
);
|
|
2204
|
+
function buildBlacklistBody(args) {
|
|
2205
|
+
const operateType = String(args.operateType || "add").toLowerCase();
|
|
2206
|
+
if (operateType !== "add" && operateType !== "delete") throw new Error("operateType \u5FC5\u987B\u662F add \u6216 delete");
|
|
2207
|
+
const body = { operateType };
|
|
2208
|
+
if (operateType === "add") {
|
|
2209
|
+
const mailAddress = String(args.mailAddress || "").trim();
|
|
2210
|
+
if (!mailAddress) throw new Error("add \u64CD\u4F5C\u5FC5\u987B\u63D0\u4F9B mailAddress\uFF08\u90AE\u7BB1\u5730\u5740\uFF09");
|
|
2211
|
+
body.mailAddress = mailAddress;
|
|
2212
|
+
} else {
|
|
2213
|
+
const id = String(args.id || "").trim();
|
|
2214
|
+
if (!id) throw new Error("delete \u64CD\u4F5C\u5FC5\u987B\u63D0\u4F9B id\uFF08\u9ED1\u540D\u5355\u8BB0\u5F55 id\uFF09");
|
|
2215
|
+
body.id = id;
|
|
2216
|
+
}
|
|
2217
|
+
return body;
|
|
2218
|
+
}
|
|
2219
|
+
var opBlacklistOperatePrepare = {
|
|
2220
|
+
name: "mail.blacklist.operate.prepare",
|
|
2221
|
+
resource: "mail/base/setting/blacklist/operateUserMailBlacklist",
|
|
2222
|
+
method: "POST",
|
|
2223
|
+
action: "mail.blacklist.operate.prepare",
|
|
2224
|
+
summary: "\u65B0\u589E/\u5220\u9664\u9ED1\u540D\u5355\uFF08prepare\uFF0C\u4E0D\u6267\u884C\uFF09",
|
|
2225
|
+
risk: WRITE,
|
|
2226
|
+
requiresConfirmation: true,
|
|
2227
|
+
inputSchema: BLACKLIST_SCHEMA,
|
|
2228
|
+
async handler(args, env) {
|
|
2229
|
+
const body = buildBlacklistBody(args);
|
|
2230
|
+
const session = await env.host.getSession();
|
|
2231
|
+
const continuation = await env.continuation.issue(
|
|
2232
|
+
{
|
|
2233
|
+
operation: "mail.blacklist.operate.apply",
|
|
2234
|
+
baseUrl: session.baseUrl,
|
|
2235
|
+
profile: session.profile,
|
|
2236
|
+
userId: session.userId,
|
|
2237
|
+
body
|
|
2238
|
+
},
|
|
2239
|
+
CONTINUATION_TTL_MS5
|
|
2240
|
+
);
|
|
2241
|
+
return mailSuccess("mail.blacklist.operate.prepare", {
|
|
2242
|
+
operateType: body.operateType,
|
|
2243
|
+
target: body.mailAddress || body.id,
|
|
2244
|
+
tip: "\u786E\u8BA4\u540E\u4EE5 mail blacklist operate --apply --continuation <token> --yes \u6267\u884C"
|
|
2245
|
+
}, { continuation });
|
|
2246
|
+
}
|
|
2247
|
+
};
|
|
2248
|
+
var opBlacklistOperateApply = {
|
|
2249
|
+
name: "mail.blacklist.operate.apply",
|
|
2250
|
+
resource: "mail/base/setting/blacklist/operateUserMailBlacklist",
|
|
2251
|
+
method: "POST",
|
|
2252
|
+
action: "mail.blacklist.operate.apply",
|
|
2253
|
+
summary: "\u6267\u884C\u9ED1\u540D\u5355\u65B0\u589E/\u5220\u9664",
|
|
2254
|
+
risk: WRITE,
|
|
2255
|
+
requiresConfirmation: true,
|
|
2256
|
+
inputSchema: BLACKLIST_SCHEMA,
|
|
2257
|
+
async handler(args, env) {
|
|
2258
|
+
if (args.confirm !== true) throw new Error("mail.blacklist.operate.apply \u5FC5\u987B\u4F20\u5165 confirm=true \u4E0E prepare \u8FD4\u56DE\u7684 continuation");
|
|
2259
|
+
if (!args.continuation) throw new Error("mail.blacklist.operate.apply \u5FC5\u987B\u4F20\u5165 prepare \u8FD4\u56DE\u7684 continuation");
|
|
2260
|
+
const lease = await env.continuation.verify(String(args.continuation), "mail.blacklist.operate.apply");
|
|
2261
|
+
const session = await env.host.getSession();
|
|
2262
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
2263
|
+
throw mailValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
|
|
2264
|
+
}
|
|
2265
|
+
const value = await env.host.request({ path: "/api/mail/base/setting/blacklist/operateUserMailBlacklist", method: "POST", body: lease.body });
|
|
2266
|
+
return mailSuccess("mail.blacklist.operate.apply", value?.data ?? "SUCCESS", { operateType: lease.body?.operateType, target: lease.body?.mailAddress || lease.body?.id });
|
|
2267
|
+
}
|
|
2268
|
+
};
|
|
2269
|
+
var mailBlacklistOperations = [opBlacklistOperatePrepare, opBlacklistOperateApply];
|
|
2270
|
+
|
|
2271
|
+
// src/shortcuts/mail/operations/registry.ts
|
|
2272
|
+
function buildRegistry() {
|
|
2273
|
+
const registry = /* @__PURE__ */ new Map();
|
|
2274
|
+
const definitions = [
|
|
2275
|
+
...mailReadOperations,
|
|
2276
|
+
...mailSendOperations,
|
|
2277
|
+
...mailManageOperations,
|
|
2278
|
+
...mailContactsOperations,
|
|
2279
|
+
...mailTemplateOperations,
|
|
2280
|
+
...mailSignOperations,
|
|
2281
|
+
...mailBlacklistOperations
|
|
2282
|
+
];
|
|
2283
|
+
for (const definition of definitions) {
|
|
2284
|
+
if (registry.has(definition.name)) {
|
|
2285
|
+
throw new Error(`duplicate mail operation: ${definition.name}`);
|
|
2286
|
+
}
|
|
2287
|
+
registry.set(definition.name, definition);
|
|
2288
|
+
}
|
|
2289
|
+
return registry;
|
|
2290
|
+
}
|
|
2291
|
+
var mailOperationRegistry = buildRegistry();
|
|
2292
|
+
function mailOperationDefinitions() {
|
|
2293
|
+
return [...mailOperationRegistry.values()];
|
|
2294
|
+
}
|
|
2295
|
+
function getMailOperation(operation) {
|
|
2296
|
+
const definition = mailOperationRegistry.get(operation);
|
|
2297
|
+
if (!definition) {
|
|
2298
|
+
throw mailValidationError("operation_unknown", `\u90AE\u4EF6\u6A21\u5757\u4E0D\u652F\u6301\u64CD\u4F5C\uFF1A${operation}`);
|
|
2299
|
+
}
|
|
2300
|
+
return definition;
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
// src/shortcuts/mail/manifest.ts
|
|
2304
|
+
var MAIL_WITHHELD = ["mail.delete.batch", "mail.resend"];
|
|
2305
|
+
function buildOperations() {
|
|
2306
|
+
return mailOperationDefinitions().map((definition) => ({
|
|
2307
|
+
name: definition.name,
|
|
2308
|
+
resource: definition.resource,
|
|
2309
|
+
summary: definition.summary,
|
|
2310
|
+
...definition.capability ? { capability: definition.capability } : {},
|
|
2311
|
+
risk: definition.risk,
|
|
2312
|
+
...definition.requiresConfirmation ? { requiresConfirmation: true } : {},
|
|
2313
|
+
inputSchema: definition.inputSchema
|
|
2314
|
+
}));
|
|
2315
|
+
}
|
|
2316
|
+
var mailManifest = {
|
|
2317
|
+
schemaVersion: 1,
|
|
2318
|
+
name: "mail",
|
|
2319
|
+
title: "\u6CDB\u5FAEE10\u90AE\u4EF6\u7BA1\u7406",
|
|
2320
|
+
version: "0.1.0",
|
|
2321
|
+
host: "e10-mail",
|
|
2322
|
+
status: "builtin",
|
|
2323
|
+
sourceSkill: "weaver-e10-mail",
|
|
2324
|
+
capabilities: ["mail"],
|
|
2325
|
+
operations: buildOperations(),
|
|
2326
|
+
withheldOperations: MAIL_WITHHELD.map((name) => ({
|
|
2327
|
+
name,
|
|
2328
|
+
reason: name === "mail.delete.batch" ? "\u7269\u7406\u6C38\u4E45\u5220\u9664\uFF08deleteMailResourceBatch\uFF09\u4E0D\u53EF\u9006\u3001\u65E0\u6CD5\u64A4\u9500\uFF0C\u7834\u574F\u6027\u6700\u5F3A\uFF1B\u5982\u786E\u9700\u6267\u884C\uFF0C\u8BF7\u5728\u786E\u8BA4\u98CE\u9669\u540E\u4EE5\u5355\u72EC\u6388\u6743\u65B9\u5F0F\u5904\u7406\uFF0C\u4E0D\u5728\u5E38\u89C4 CLI \u63D0\u4F9B\u3002" : "\u91CD\u53D1\u90AE\u4EF6\uFF08resendMail\uFF09\u4F9D\u8D56\u300C\u90AE\u4EF6\u53D1\u9001\u65E5\u5FD7 id\u300D(mailRemindLogId)\uFF0C\u6E90\u6280\u80FD\u672A\u5C01\u88C5\u65E5\u5FD7\u67E5\u8BE2\u63A5\u53E3\uFF0C\u65E0\u6CD5\u83B7\u5F97\u8BE5 id \u65F6\u5982\u5B9E\u63D0\u793A\uFF0C\u4E0D\u81C6\u9020\uFF1B\u6682\u7F13\u5B9E\u73B0\u3002"
|
|
2329
|
+
}))
|
|
2330
|
+
};
|
|
2331
|
+
|
|
2332
|
+
// src/shortcuts/mail/operations/shared.ts
|
|
2333
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
2334
|
+
function asObject(value) {
|
|
2335
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2336
|
+
throw mailValidationError("input_not_object", "\u8F93\u5165\u5FC5\u987B\u662F JSON \u5BF9\u8C61");
|
|
2337
|
+
}
|
|
2338
|
+
return value;
|
|
2339
|
+
}
|
|
2340
|
+
function assertNoForbiddenKeys(input) {
|
|
2341
|
+
for (const key of Object.keys(input)) {
|
|
2342
|
+
if (FORBIDDEN_KEYS.has(key)) {
|
|
2343
|
+
throw mailValidationError("forbidden_key", `\u8F93\u5165\u5305\u542B\u975E\u6CD5\u5B57\u6BB5\uFF1A${key}`);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
// src/shortcuts/mail/operations.ts
|
|
2349
|
+
async function executeMailOperation(operation, rawInput, context) {
|
|
2350
|
+
const definition = getMailOperation(operation);
|
|
2351
|
+
const input = asObject(rawInput);
|
|
2352
|
+
assertNoForbiddenKeys(input);
|
|
2353
|
+
const host = {
|
|
2354
|
+
request(request) {
|
|
2355
|
+
return context.host.request({
|
|
2356
|
+
...request,
|
|
2357
|
+
operation: request.operation || operation
|
|
2358
|
+
});
|
|
2359
|
+
},
|
|
2360
|
+
getSession() {
|
|
2361
|
+
return context.host.getSession();
|
|
2362
|
+
}
|
|
2363
|
+
};
|
|
2364
|
+
return definition.handler(input, { ...context, host });
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
// src/shortcuts/mail/index.ts
|
|
2368
|
+
function asOptions(value) {
|
|
2369
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2370
|
+
}
|
|
2371
|
+
function stripBom(value) {
|
|
2372
|
+
return value.replace(/^\uFEFF+/, "");
|
|
2373
|
+
}
|
|
2374
|
+
async function readStdin() {
|
|
2375
|
+
const chunks = [];
|
|
2376
|
+
for await (const chunk of process.stdin) {
|
|
2377
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
2378
|
+
}
|
|
2379
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
2380
|
+
}
|
|
2381
|
+
async function inputFrom(options, extra = {}) {
|
|
2382
|
+
const opts = asOptions(options);
|
|
2383
|
+
let input = {};
|
|
2384
|
+
if (opts.input && opts.inputJson) {
|
|
2385
|
+
throw mailValidationError("input_conflict", "\u4E0D\u80FD\u540C\u65F6\u4F20 --input \u548C --input-json");
|
|
2386
|
+
}
|
|
2387
|
+
if (opts.inputJson) {
|
|
2388
|
+
input = parseJsonInput(String(opts.inputJson), "--input-json");
|
|
2389
|
+
}
|
|
2390
|
+
if (opts.input) {
|
|
2391
|
+
let raw;
|
|
2392
|
+
try {
|
|
2393
|
+
raw = stripBom(opts.input === "-" ? await readStdin() : await readFile2(String(opts.input), "utf8"));
|
|
2394
|
+
} catch {
|
|
2395
|
+
throw mailValidationError("input_unreadable", `\u65E0\u6CD5\u8BFB\u53D6 --input\uFF1A${String(opts.input)}`);
|
|
2396
|
+
}
|
|
2397
|
+
input = parseJsonInput(raw, "--input");
|
|
2398
|
+
}
|
|
2399
|
+
return {
|
|
2400
|
+
...input,
|
|
2401
|
+
...Object.fromEntries(Object.entries(extra).filter(([, value]) => value !== void 0 && value !== ""))
|
|
2402
|
+
};
|
|
2403
|
+
}
|
|
2404
|
+
function parseJsonInput(raw, label) {
|
|
2405
|
+
try {
|
|
2406
|
+
const parsed = JSON.parse(stripBom(raw));
|
|
2407
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2408
|
+
throw new Error("input must be an object");
|
|
2409
|
+
}
|
|
2410
|
+
return parsed;
|
|
2411
|
+
} catch {
|
|
2412
|
+
throw mailValidationError("input_invalid", `${label} \u4E0D\u662F\u5408\u6CD5 JSON \u5BF9\u8C61`);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
function successEnvelope(operation, result) {
|
|
2416
|
+
return {
|
|
2417
|
+
schemaVersion: 1,
|
|
2418
|
+
ok: true,
|
|
2419
|
+
operation,
|
|
2420
|
+
data: result.data === void 0 ? null : result.data,
|
|
2421
|
+
...result.meta ? { meta: result.meta } : {},
|
|
2422
|
+
warnings: []
|
|
2423
|
+
};
|
|
2424
|
+
}
|
|
2425
|
+
function failureEnvelope(error) {
|
|
2426
|
+
const structured = error;
|
|
2427
|
+
return {
|
|
2428
|
+
schemaVersion: 1,
|
|
2429
|
+
ok: false,
|
|
2430
|
+
...structured?.partialData === void 0 ? {} : { data: structured.partialData },
|
|
2431
|
+
error: toErrorEnvelope(error)
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2434
|
+
async function executeAndPrint(ctx, operation, input) {
|
|
2435
|
+
try {
|
|
2436
|
+
const result = await executeMailOperation(operation, input, {
|
|
2437
|
+
ctx,
|
|
2438
|
+
host: createMailHost(ctx),
|
|
2439
|
+
continuation: createMailContinuationSigner(ctx)
|
|
2440
|
+
});
|
|
2441
|
+
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
2442
|
+
} catch (error) {
|
|
2443
|
+
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
2444
|
+
process.exitCode = isCliError(error) ? error.exitCode : 1 /* GeneralError */;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
var mailShortcut = {
|
|
2448
|
+
name: "mail",
|
|
2449
|
+
description: "\u6CDB\u5FAEE10\u90AE\u4EF6\u7BA1\u7406 CLI",
|
|
2450
|
+
category: "shortcut",
|
|
2451
|
+
register({ program, action }) {
|
|
2452
|
+
const mail = program.command("mail").description("\u6CDB\u5FAEE10\u90AE\u4EF6\u7BA1\u7406\uFF08\u67E5\u8BE2/\u53D1\u9001/\u7BA1\u7406\uFF09");
|
|
2453
|
+
mail.command("schema").description("Print mail operation manifest for agents").action(action((ctx) => {
|
|
2454
|
+
ctx.output.write(mailManifest, { json: true });
|
|
2455
|
+
}));
|
|
2456
|
+
mail.command("run").description("Run a mail operation with JSON input").argument("<operation>", "operation name, e.g. mail.list").option("--input <path>", "JSON input file, or - for stdin").option("--input-json <json>", "inline JSON input object").action(action(async (ctx, operation, options) => {
|
|
2457
|
+
await executeAndPrint(ctx, String(operation), await inputFrom(options));
|
|
2458
|
+
}));
|
|
2459
|
+
const withJson = (command) => command.option("--input <path>", "JSON input file, or - for stdin").option("--input-json <json>", "inline JSON input object");
|
|
2460
|
+
mail.command("list").description("\u67E5\u8BE2\u90AE\u4EF6\u5217\u8868\uFF08\u652F\u6301\u6587\u4EF6\u5939/\u5173\u952E\u5B57/\u672A\u8BFB/\u9644\u4EF6/\u65F6\u95F4\u8FC7\u6EE4\uFF09").option("--folder <id>", "\u6587\u4EF6\u5939\uFF1A0\u6536\u4EF6\u7BB1 -1\u5DF2\u53D1\u9001 -2\u8349\u7A3F\u7BB1 -3\u5783\u573E\u7BB1 -4\u5DF2\u5220\u9664 -10\u5168\u90E8").option("--keyword <kw>", "\u4E3B\u9898\u5173\u952E\u5B57").option("--from <name>", "\u53D1\u4EF6\u4EBA").option("--to <name>", "\u6536\u4EF6\u4EBA").option("--unread", "\u4EC5\u672A\u8BFB").option("--star", "\u4EC5\u661F\u6807").option("--todo", "\u4EC5\u5F85\u529E").option("--attach", "\u4EC5\u5E26\u9644\u4EF6").option("--date <range>", "\u65F6\u95F4\u8303\u56F4 \u8D77\u59CB,\u7ED3\u675F (YYYY-MM-DD)").option("--page <n>", "\u9875\u7801").option("--size <n>", "\u6BCF\u9875\u6761\u6570").action(action(async (ctx, options) => {
|
|
2461
|
+
const opts = asOptions(options);
|
|
2462
|
+
const extra = {
|
|
2463
|
+
folder: opts.folder,
|
|
2464
|
+
keyword: opts.keyword,
|
|
2465
|
+
from: opts.from,
|
|
2466
|
+
to: opts.to,
|
|
2467
|
+
unread: opts.unread === true ? true : void 0,
|
|
2468
|
+
star: opts.star === true ? true : void 0,
|
|
2469
|
+
todo: opts.todo === true ? true : void 0,
|
|
2470
|
+
hasFile: opts.attach === true ? true : void 0,
|
|
2471
|
+
page: opts.page,
|
|
2472
|
+
size: opts.size
|
|
2473
|
+
};
|
|
2474
|
+
if (opts.date) {
|
|
2475
|
+
const [s, e] = String(opts.date).split(",");
|
|
2476
|
+
extra.startDate = s?.trim();
|
|
2477
|
+
extra.endDate = e?.trim();
|
|
2478
|
+
}
|
|
2479
|
+
await executeAndPrint(ctx, "mail.list", await inputFrom(options, extra));
|
|
2480
|
+
}));
|
|
2481
|
+
mail.command("contact").description("\u5F80\u6765\u90AE\u4EF6\uFF08\u5BF9\u65B9\u53D1\u6765 + \u6211\u53D1\u7ED9\u5BF9\u65B9\uFF09").option("--name <name>", "\u4EBA\u5458\u59D3\u540D/\u5DE5\u53F7").action(action(async (ctx, options) => {
|
|
2482
|
+
const opts = asOptions(options);
|
|
2483
|
+
await executeAndPrint(ctx, "mail.contact.list", await inputFrom(options, { name: opts.name }));
|
|
2484
|
+
}));
|
|
2485
|
+
mail.command("view").description("\u67E5\u770B\u90AE\u4EF6\u8BE6\u60C5\uFF08\u542B\u6B63\u6587/\u9644\u4EF6\uFF09").option("--id <id>", "\u90AE\u4EF6 id").action(action(async (ctx, options) => {
|
|
2486
|
+
const opts = asOptions(options);
|
|
2487
|
+
await executeAndPrint(ctx, "mail.view.info", await inputFrom(options, { id: opts.id }));
|
|
2488
|
+
}));
|
|
2489
|
+
mail.command("content").description("\u67E5\u770B\u90AE\u4EF6\u6B63\u6587").option("--id <id>", "\u90AE\u4EF6 id").action(action(async (ctx, options) => {
|
|
2490
|
+
const opts = asOptions(options);
|
|
2491
|
+
await executeAndPrint(ctx, "mail.view.content", await inputFrom(options, { id: opts.id }));
|
|
2492
|
+
}));
|
|
2493
|
+
mail.command("unread").description("\u672A\u8BFB\u90AE\u4EF6\u7EDF\u8BA1\uFF08\u6536\u4EF6\u7BB1/\u5DF2\u5220\u9664/\u5783\u573E\u7BB1/\u5F85\u529E/\u661F\u6807\uFF09").action(action(async (ctx, options) => {
|
|
2494
|
+
await executeAndPrint(ctx, "mail.unread.count", await inputFrom(options));
|
|
2495
|
+
}));
|
|
2496
|
+
mail.command("config").description("\u83B7\u53D6\u90AE\u4EF6\u914D\u7F6E\uFF08\u53D1\u9001\u5F00\u5173/\u9644\u4EF6\u9650\u5236\uFF09").action(action(async (ctx, options) => {
|
|
2497
|
+
await executeAndPrint(ctx, "mail.config.get", await inputFrom(options));
|
|
2498
|
+
}));
|
|
2499
|
+
const search = mail.command("search").description("\u6536\u4EF6\u4EBA\u89E3\u6790\u547D\u4EE4");
|
|
2500
|
+
withJson(search.command("person").description("\u5185\u90E8\u4EBA\u5458/\u90E8\u95E8\u641C\u7D22").option("--keyword <kw>", "\u59D3\u540D/\u5DE5\u53F7").action(action(async (ctx, options) => {
|
|
2501
|
+
const opts = asOptions(options);
|
|
2502
|
+
await executeAndPrint(ctx, "mail.person.search", await inputFrom(options, { keyword: opts.keyword }));
|
|
2503
|
+
})));
|
|
2504
|
+
withJson(search.command("dep").description("\u90E8\u95E8\u6811\u5B9A\u4F4D").option("--keyword <kw>", "\u90E8\u95E8\u540D").action(action(async (ctx, options) => {
|
|
2505
|
+
const opts = asOptions(options);
|
|
2506
|
+
await executeAndPrint(ctx, "mail.dep.search", await inputFrom(options, { keyword: opts.keyword }));
|
|
2507
|
+
})));
|
|
2508
|
+
withJson(search.command("address").description("\u5916\u90E8\u90AE\u7BB1\u641C\u7D22").option("--keyword <kw>", "\u90AE\u7BB1\u5173\u952E\u5B57").action(action(async (ctx, options) => {
|
|
2509
|
+
const opts = asOptions(options);
|
|
2510
|
+
await executeAndPrint(ctx, "mail.address.search", await inputFrom(options, { keyword: opts.keyword }));
|
|
2511
|
+
})));
|
|
2512
|
+
const send = mail.command("send").description("\u53D1\u9001/\u56DE\u590D/\u8F6C\u53D1/\u5B58\u8349\u7A3F\uFF08prepare\u2192apply\uFF09");
|
|
2513
|
+
withJson(send.command("prepare").description("\u51C6\u5907\u53D1\u9001\uFF08\u7EC4\u88C5\u8BF7\u6C42 + \u5B89\u5168\u9884\u68C0 + \u8F93\u51FA\u6458\u8981\uFF0C\u4E0D\u53D1\u9001\uFF09").option("--flag <flag>", "\u65B0\u5EFA -1 / \u56DE\u590D 1 / \u8F6C\u53D1 3 / \u7F16\u8F91\u8349\u7A3F 4").option("--id <id>", "\u539F\u90AE\u4EF6 id\uFF08\u56DE\u590D/\u8F6C\u53D1/\u7F16\u8F91\u8349\u7A3F\uFF09").option("--to <names>", "\u6536\u4EF6\u4EBA\uFF08\u59D3\u540D/\u5DE5\u53F7/\u90E8\u95E8 --to-dep\uFF09").option("--cc <names>", "\u6284\u9001").option("--bcc <names>", "\u5BC6\u9001").option("--to-dep <deps>", "\u90E8\u95E8\u6536\u4EF6\u4EBA").option("--to-id <ids>", "\u7CBE\u786E\u6536\u4EF6\u4EBA id").option("--cc-id <ids>", "\u7CBE\u786E\u6284\u9001 id").option("--bcc-id <ids>", "\u7CBE\u786E\u5BC6\u9001 id").option("--external", "\u5916\u90E8\u90AE\u4EF6").option("--subject <subject>", "\u4E3B\u9898").option("--content <content>", "\u6B63\u6587").option("--timing <datetime>", "\u5B9A\u65F6\u53D1\u9001 YYYY-MM-DD HH:mm:ss").option("--files <ids>", "\u9644\u4EF6 fileid\uFF08\u9017\u53F7\uFF09").option("--filesizes <sizes>", "\u9644\u4EF6\u5927\u5C0F\uFF08\u9017\u53F7\uFF09").option("--draft", "\u5B58\u8349\u7A3F\uFF08\u4E0D\u53D1\u9001\uFF09").action(action(async (ctx, options) => {
|
|
2514
|
+
const o = asOptions(options);
|
|
2515
|
+
await executeAndPrint(ctx, "mail.send.prepare", await inputFrom(options, {
|
|
2516
|
+
flag: o.flag,
|
|
2517
|
+
id: o.id,
|
|
2518
|
+
to: o.to,
|
|
2519
|
+
cc: o.cc,
|
|
2520
|
+
bcc: o.bcc,
|
|
2521
|
+
toDep: o.toDep,
|
|
2522
|
+
ccDep: o.ccDep,
|
|
2523
|
+
bccDep: o.bccDep,
|
|
2524
|
+
toId: o.toId,
|
|
2525
|
+
ccId: o.ccId,
|
|
2526
|
+
bccId: o.bccId,
|
|
2527
|
+
external: o.external === true ? true : void 0,
|
|
2528
|
+
subject: o.subject,
|
|
2529
|
+
content: o.content,
|
|
2530
|
+
timing: o.timing,
|
|
2531
|
+
files: o.files,
|
|
2532
|
+
filesizes: o.filesizes,
|
|
2533
|
+
draft: o.draft === true ? true : void 0
|
|
2534
|
+
}));
|
|
2535
|
+
})));
|
|
2536
|
+
withJson(send.command("apply").description("\u6267\u884C\u53D1\u9001\uFF08\u9700 --continuation \u4E0E --yes\uFF09").option("--continuation <token>", "prepare \u8FD4\u56DE\u7684 continuation").option("--yes", "\u786E\u8BA4\u53D1\u9001").action(action(async (ctx, options) => {
|
|
2537
|
+
const o = asOptions(options);
|
|
2538
|
+
await executeAndPrint(ctx, "mail.send.apply", await inputFrom(options, {
|
|
2539
|
+
continuation: o.continuation,
|
|
2540
|
+
confirm: o.yes === true ? true : void 0
|
|
2541
|
+
}));
|
|
2542
|
+
})));
|
|
2543
|
+
withJson(mail.command("star").description("\u6807\u661F/\u53D6\u6D88\u6807\u661F").option("--id <id>", "\u90AE\u4EF6 id").option("--star <0|1>", "1 \u6807\u661F / 0 \u53D6\u6D88").action(action(async (ctx, options) => {
|
|
2544
|
+
const o = asOptions(options);
|
|
2545
|
+
await executeAndPrint(ctx, "mail.star", await inputFrom(options, { id: o.id, star: o.star }));
|
|
2546
|
+
})));
|
|
2547
|
+
withJson(mail.command("read-status").description("\u6807\u8BB0\u5355\u5C01\u5DF2\u8BFB/\u672A\u8BFB").option("--id <id>", "\u90AE\u4EF6 id").option("--read <0|1>", "1 \u5DF2\u8BFB / 0 \u672A\u8BFB").action(action(async (ctx, options) => {
|
|
2548
|
+
const o = asOptions(options);
|
|
2549
|
+
await executeAndPrint(ctx, "mail.read.status", await inputFrom(options, { id: o.id, read: o.read }));
|
|
2550
|
+
})));
|
|
2551
|
+
withJson(mail.command("read-all").description("\u6807\u8BB0\u5168\u90E8\u5DF2\u8BFB").option("--folder <id>", "\u6587\u4EF6\u5939 id\uFF08\u9ED8\u8BA4\u5168\u90E8\uFF09").action(action(async (ctx, options) => {
|
|
2552
|
+
const o = asOptions(options);
|
|
2553
|
+
await executeAndPrint(ctx, "mail.read.all", await inputFrom(options, { folder: o.folder }));
|
|
2554
|
+
})));
|
|
2555
|
+
withJson(mail.command("wait").description("\u521B\u5EFA\u5F85\u529E/\u63D0\u9192").option("--id <id>", "\u90AE\u4EF6 id").option("--title <title>", "\u5F85\u529E\u6807\u9898").option("--enddate <date>", "\u622A\u6B62\u65E5\u671F").action(action(async (ctx, options) => {
|
|
2556
|
+
const o = asOptions(options);
|
|
2557
|
+
await executeAndPrint(ctx, "mail.wait.add", await inputFrom(options, { id: o.id, title: o.title, endDate: o.enddate }));
|
|
2558
|
+
})));
|
|
2559
|
+
withJson(mail.command("move").description("\u79FB\u52A8\u90AE\u4EF6\u81F3\u6587\u4EF6\u5939").option("--id <id>", "\u90AE\u4EF6 id").option("--folder <id>", "\u76EE\u6807\u6587\u4EF6\u5939 id").action(action(async (ctx, options) => {
|
|
2560
|
+
const o = asOptions(options);
|
|
2561
|
+
await executeAndPrint(ctx, "mail.move.folder", await inputFrom(options, { id: o.id, folder: o.folder }));
|
|
2562
|
+
})));
|
|
2563
|
+
mail.command("delete").description("\u5220\u9664\u90AE\u4EF6\uFF08\u9ED8\u8BA4\u903B\u8F91\u5220\u9664\u79FB\u81F3\u5DF2\u5220\u9664\uFF09").option("--id <id>", "\u90AE\u4EF6 id \u6216\u9017\u53F7\u5206\u9694\u591A\u4E2A").option("--permanent", "\u6C38\u4E45\u5220\u9664\uFF08WITHHELD\uFF0C\u672A\u5B9E\u73B0\uFF09").action(action(async (ctx, options) => {
|
|
2564
|
+
const o = asOptions(options);
|
|
2565
|
+
if (o.permanent === true) {
|
|
2566
|
+
throw mailValidationError("operation_withheld", "\u6C38\u4E45\u5220\u9664\uFF08mail.delete.batch\uFF09\u5DF2\u6682\u7F13\u5B9E\u73B0\uFF0C\u4E0D\u53EF\u9006\u4E14\u65E0\u6CD5\u64A4\u9500");
|
|
2567
|
+
}
|
|
2568
|
+
await executeAndPrint(ctx, "mail.delete.move", await inputFrom(options, { id: o.id }));
|
|
2569
|
+
}));
|
|
2570
|
+
const folder = mail.command("folder").description("\u6587\u4EF6\u5939\u7BA1\u7406");
|
|
2571
|
+
withJson(folder.command("create").description("\u65B0\u5EFA\u90AE\u4EF6\u6587\u4EF6\u5939").option("--name <name>", "\u6587\u4EF6\u5939\u540D").action(action(async (ctx, options) => {
|
|
2572
|
+
const o = asOptions(options);
|
|
2573
|
+
await executeAndPrint(ctx, "mail.folder.create", await inputFrom(options, { name: o.name }));
|
|
2574
|
+
})));
|
|
2575
|
+
withJson(folder.command("delete").description("\u5220\u9664\u90AE\u4EF6\u6587\u4EF6\u5939").option("--id <id>", "\u6587\u4EF6\u5939 id").action(action(async (ctx, options) => {
|
|
2576
|
+
const o = asOptions(options);
|
|
2577
|
+
await executeAndPrint(ctx, "mail.folder.delete", await inputFrom(options, { id: o.id }));
|
|
2578
|
+
})));
|
|
2579
|
+
const contacts = mail.command("contacts").description("\u8054\u7CFB\u4EBA\u7BA1\u7406");
|
|
2580
|
+
withJson(contacts.command("list").description("\u8054\u7CFB\u4EBA\u5217\u8868/\u641C\u7D22").option("--keyword <kw>", "\u5173\u952E\u5B57").option("--page <n>", "\u9875\u7801").option("--size <n>", "\u6BCF\u9875\u6761\u6570").action(action(async (ctx, options) => {
|
|
2581
|
+
const o = asOptions(options);
|
|
2582
|
+
await executeAndPrint(ctx, "mail.contacts.list", await inputFrom(options, { keyword: o.keyword, page: o.page, size: o.size }));
|
|
2583
|
+
})));
|
|
2584
|
+
withJson(contacts.command("save").description("\u65B0\u589E/\u7F16\u8F91\u8054\u7CFB\u4EBA\uFF08GET \u5168\u91CF + \u4FDD\u5B58\uFF0Cprepare\u2192apply\uFF09").option("--prepare", "\u51C6\u5907\uFF08\u67E5\u5168\u91CF + \u8F93\u51FA\u6458\u8981\uFF09").option("--apply", "\u6267\u884C\u4FDD\u5B58\uFF08\u9700 --continuation \u4E0E --yes\uFF09").option("--continuation <token>", "prepare \u8FD4\u56DE\u7684 continuation").option("--yes", "\u786E\u8BA4").action(action(async (ctx, options) => {
|
|
2585
|
+
const o = asOptions(options);
|
|
2586
|
+
const op = o.prepare === true ? "mail.contacts.save.prepare" : "mail.contacts.save.apply";
|
|
2587
|
+
await executeAndPrint(ctx, op, await inputFrom(options, {
|
|
2588
|
+
continuation: o.continuation,
|
|
2589
|
+
confirm: o.yes === true ? true : void 0
|
|
2590
|
+
}));
|
|
2591
|
+
})));
|
|
2592
|
+
withJson(contacts.command("delete").description("\u5220\u9664\u8054\u7CFB\u4EBA").option("--id <id>", "\u8054\u7CFB\u4EBA id").action(action(async (ctx, options) => {
|
|
2593
|
+
const o = asOptions(options);
|
|
2594
|
+
await executeAndPrint(ctx, "mail.contacts.delete", await inputFrom(options, { id: o.id }));
|
|
2595
|
+
})));
|
|
2596
|
+
const group = contacts.command("group").description("\u8054\u7CFB\u4EBA\u5206\u7EC4");
|
|
2597
|
+
withJson(group.command("list").description("\u5206\u7EC4\u5217\u8868").action(action(async (ctx, options) => {
|
|
2598
|
+
await executeAndPrint(ctx, "mail.contacts.group.list", await inputFrom(options));
|
|
2599
|
+
})));
|
|
2600
|
+
withJson(group.command("detail").description("\u5206\u7EC4\u8BE6\u60C5\uFF08\u542B\u7EDF\u8BA1\uFF09").option("--id <id>", "\u5206\u7EC4 id").action(action(async (ctx, options) => {
|
|
2601
|
+
const o = asOptions(options);
|
|
2602
|
+
await executeAndPrint(ctx, "mail.contacts.group.detail", await inputFrom(options, { id: o.id }));
|
|
2603
|
+
})));
|
|
2604
|
+
withJson(group.command("save").description("\u65B0\u589E/\u7F16\u8F91\u5206\u7EC4\uFF08prepare\u2192apply\uFF09").option("--prepare", "\u51C6\u5907").option("--apply", "\u6267\u884C\uFF08\u9700 --continuation \u4E0E --yes\uFF09").option("--continuation <token>", "continuation").option("--yes", "\u786E\u8BA4").action(action(async (ctx, options) => {
|
|
2605
|
+
const o = asOptions(options);
|
|
2606
|
+
const op = o.prepare === true ? "mail.contacts.group.save.prepare" : "mail.contacts.group.save.apply";
|
|
2607
|
+
await executeAndPrint(ctx, op, await inputFrom(options, { continuation: o.continuation, confirm: o.yes === true ? true : void 0 }));
|
|
2608
|
+
})));
|
|
2609
|
+
withJson(group.command("delete").description("\u5220\u9664\u5206\u7EC4").option("--id <id>", "\u5206\u7EC4 id").action(action(async (ctx, options) => {
|
|
2610
|
+
const o = asOptions(options);
|
|
2611
|
+
await executeAndPrint(ctx, "mail.contacts.group.delete", await inputFrom(options, { id: o.id }));
|
|
2612
|
+
})));
|
|
2613
|
+
const template = mail.command("template").description("\u6A21\u677F\u7BA1\u7406");
|
|
2614
|
+
withJson(template.command("list").description("\u6A21\u677F\u5217\u8868").action(action(async (ctx, options) => {
|
|
2615
|
+
await executeAndPrint(ctx, "mail.template.list", await inputFrom(options));
|
|
2616
|
+
})));
|
|
2617
|
+
withJson(template.command("save").description("\u65B0\u589E\u6A21\u677F\uFF08prepare\u2192apply\uFF09").option("--prepare", "\u51C6\u5907").option("--apply", "\u6267\u884C\uFF08\u9700 --continuation \u4E0E --yes\uFF09").option("--continuation <token>", "continuation").option("--yes", "\u786E\u8BA4").action(action(async (ctx, options) => {
|
|
2618
|
+
const o = asOptions(options);
|
|
2619
|
+
const op = o.prepare === true ? "mail.template.save.prepare" : "mail.template.save.apply";
|
|
2620
|
+
await executeAndPrint(ctx, op, await inputFrom(options, { continuation: o.continuation, confirm: o.yes === true ? true : void 0 }));
|
|
2621
|
+
})));
|
|
2622
|
+
withJson(template.command("update").description("\u7F16\u8F91\u6A21\u677F\uFF08GET \u5168\u91CF + \u4FDD\u5B58\uFF09").option("--id <id>", "\u6A21\u677F id").action(action(async (ctx, options) => {
|
|
2623
|
+
const o = asOptions(options);
|
|
2624
|
+
await executeAndPrint(ctx, "mail.template.update", await inputFrom(options, { id: o.id }));
|
|
2625
|
+
})));
|
|
2626
|
+
withJson(template.command("delete").description("\u5220\u9664\u6A21\u677F").option("--id <id>", "\u6A21\u677F id").action(action(async (ctx, options) => {
|
|
2627
|
+
const o = asOptions(options);
|
|
2628
|
+
await executeAndPrint(ctx, "mail.template.delete", await inputFrom(options, { id: o.id }));
|
|
2629
|
+
})));
|
|
2630
|
+
withJson(template.command("default").description("\u8BBE\u4E3A\u9ED8\u8BA4\u6A21\u677F").option("--id <id>", "\u6A21\u677F id").action(action(async (ctx, options) => {
|
|
2631
|
+
const o = asOptions(options);
|
|
2632
|
+
await executeAndPrint(ctx, "mail.template.default", await inputFrom(options, { id: o.id }));
|
|
2633
|
+
})));
|
|
2634
|
+
const sign = mail.command("sign").description("\u7B7E\u540D\u7BA1\u7406");
|
|
2635
|
+
withJson(sign.command("list").description("\u7B7E\u540D\u5217\u8868").action(action(async (ctx, options) => {
|
|
2636
|
+
await executeAndPrint(ctx, "mail.sign.list", await inputFrom(options));
|
|
2637
|
+
})));
|
|
2638
|
+
withJson(sign.command("save").description("\u65B0\u589E\u7B7E\u540D\uFF08prepare\u2192apply\uFF09").option("--prepare", "\u51C6\u5907").option("--apply", "\u6267\u884C\uFF08\u9700 --continuation \u4E0E --yes\uFF09").option("--continuation <token>", "continuation").option("--yes", "\u786E\u8BA4").action(action(async (ctx, options) => {
|
|
2639
|
+
const o = asOptions(options);
|
|
2640
|
+
const op = o.prepare === true ? "mail.sign.save.prepare" : "mail.sign.save.apply";
|
|
2641
|
+
await executeAndPrint(ctx, op, await inputFrom(options, { continuation: o.continuation, confirm: o.yes === true ? true : void 0 }));
|
|
2642
|
+
})));
|
|
2643
|
+
withJson(sign.command("update").description("\u7F16\u8F91\u7B7E\u540D").option("--id <id>", "\u7B7E\u540D id").action(action(async (ctx, options) => {
|
|
2644
|
+
const o = asOptions(options);
|
|
2645
|
+
await executeAndPrint(ctx, "mail.sign.update", await inputFrom(options, { id: o.id }));
|
|
2646
|
+
})));
|
|
2647
|
+
withJson(sign.command("delete").description("\u5220\u9664\u7B7E\u540D").option("--id <id>", "\u7B7E\u540D id").action(action(async (ctx, options) => {
|
|
2648
|
+
const o = asOptions(options);
|
|
2649
|
+
await executeAndPrint(ctx, "mail.sign.delete", await inputFrom(options, { id: o.id }));
|
|
2650
|
+
})));
|
|
2651
|
+
withJson(sign.command("default").description("\u8BBE\u4E3A\u9ED8\u8BA4\u7B7E\u540D").option("--id <id>", "\u7B7E\u540D id").action(action(async (ctx, options) => {
|
|
2652
|
+
const o = asOptions(options);
|
|
2653
|
+
await executeAndPrint(ctx, "mail.sign.default", await inputFrom(options, { id: o.id }));
|
|
2654
|
+
})));
|
|
2655
|
+
withJson(sign.command("qrcode").description("\u751F\u6210\u4E8C\u7EF4\u7801\u540D\u7247").option("--id <id>", "\u7B7E\u540D id").action(action(async (ctx, options) => {
|
|
2656
|
+
const o = asOptions(options);
|
|
2657
|
+
await executeAndPrint(ctx, "mail.sign.qrcode", await inputFrom(options, { id: o.id }));
|
|
2658
|
+
})));
|
|
2659
|
+
const blacklist = mail.command("blacklist").description("\u9ED1\u540D\u5355\u7BA1\u7406");
|
|
2660
|
+
withJson(blacklist.command("list").description("\u9ED1\u540D\u5355\u5217\u8868").action(action(async (ctx, options) => {
|
|
2661
|
+
await executeAndPrint(ctx, "mail.blacklist.list", await inputFrom(options));
|
|
2662
|
+
})));
|
|
2663
|
+
withJson(blacklist.command("operate").description("\u65B0\u589E/\u5220\u9664\u9ED1\u540D\u5355\uFF08prepare\u2192apply\uFF09").option("--prepare", "\u51C6\u5907").option("--apply", "\u6267\u884C\uFF08\u9700 --continuation \u4E0E --yes\uFF09").option("--continuation <token>", "continuation").option("--yes", "\u786E\u8BA4").action(action(async (ctx, options) => {
|
|
2664
|
+
const o = asOptions(options);
|
|
2665
|
+
const op = o.prepare === true ? "mail.blacklist.operate.prepare" : "mail.blacklist.operate.apply";
|
|
2666
|
+
await executeAndPrint(ctx, op, await inputFrom(options, { continuation: o.continuation, confirm: o.yes === true ? true : void 0 }));
|
|
2667
|
+
})));
|
|
2668
|
+
const attachment = mail.command("attachment").description("\u9644\u4EF6\u4E2D\u5FC3");
|
|
2669
|
+
withJson(attachment.command("center").description("\u9644\u4EF6\u4E2D\u5FC3\u5217\u8868/\u641C\u7D22").option("--keyword <kw>", "\u5173\u952E\u5B57").option("--page <n>", "\u9875\u7801").option("--size <n>", "\u6BCF\u9875\u6761\u6570").action(action(async (ctx, options) => {
|
|
2670
|
+
const o = asOptions(options);
|
|
2671
|
+
await executeAndPrint(ctx, "mail.attachment.center", await inputFrom(options, { keyword: o.keyword, page: o.page, size: o.size }));
|
|
2672
|
+
})));
|
|
2673
|
+
withJson(attachment.command("upload").description("\u4E0A\u4F20\u9644\u4EF6\uFF08\u4E09\u6B65\uFF1A\u9884\u68C0\u2192\u4E0A\u4F20\u2192\u7ED1\u5B9A\uFF0C\u8FD4\u56DE fileid\uFF09").option("--file <path>", "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84").option("--name <name>", "\u9644\u4EF6\u540D").action(action(async (ctx, options) => {
|
|
2674
|
+
const o = asOptions(options);
|
|
2675
|
+
await executeAndPrint(ctx, "mail.attachment.upload", await inputFrom(options, { file: o.file, name: o.name }));
|
|
2676
|
+
})));
|
|
2677
|
+
withJson(attachment.command("download").description("\u6279\u91CF\u4E0B\u8F7D\u9644\u4EF6").option("--ids <ids>", "\u9644\u4EF6 id\uFF08\u9017\u53F7\uFF09").option("--output <dir>", "\u8F93\u51FA\u76EE\u5F55").action(action(async (ctx, options) => {
|
|
2678
|
+
const o = asOptions(options);
|
|
2679
|
+
await executeAndPrint(ctx, "mail.attachment.download", await inputFrom(options, { ids: o.ids, output: o.output }));
|
|
2680
|
+
})));
|
|
2681
|
+
withJson(mail.command("clearlog").description("\u90AE\u4EF6\u6E05\u7406\u65E5\u5FD7\u5217\u8868").option("--page <n>", "\u9875\u7801").option("--size <n>", "\u6BCF\u9875\u6761\u6570").action(action(async (ctx, options) => {
|
|
2682
|
+
const o = asOptions(options);
|
|
2683
|
+
await executeAndPrint(ctx, "mail.clearlog.list", await inputFrom(options, { page: o.page, size: o.size }));
|
|
2684
|
+
})));
|
|
2685
|
+
withJson(mail.command("recall").description("\u64A4\u56DE\u5DF2\u53D1\u9001\u7684\u5185\u90E8\u90AE\u4EF6").option("--id <id>", "\u90AE\u4EF6 id").action(action(async (ctx, options) => {
|
|
2686
|
+
const o = asOptions(options);
|
|
2687
|
+
await executeAndPrint(ctx, "mail.recall", await inputFrom(options, { id: o.id }));
|
|
2688
|
+
})));
|
|
2689
|
+
}
|
|
2690
|
+
};
|
|
2691
|
+
export {
|
|
2692
|
+
inputFrom,
|
|
2693
|
+
mailShortcut,
|
|
2694
|
+
successEnvelope
|
|
2695
|
+
};
|