@xuanyue202/wechat-mp 2026.3.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/src/api.d.ts +101 -0
- package/dist/src/api.d.ts.map +1 -0
- package/dist/src/api.js +142 -0
- package/dist/src/api.js.map +1 -0
- package/dist/src/channel.d.ts +296 -0
- package/dist/src/channel.d.ts.map +1 -0
- package/dist/src/channel.js +341 -0
- package/dist/src/channel.js.map +1 -0
- package/dist/src/config.d.ts +69 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +167 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/crypto.d.ts +117 -0
- package/dist/src/crypto.d.ts.map +1 -0
- package/dist/src/crypto.js +270 -0
- package/dist/src/crypto.js.map +1 -0
- package/dist/src/crypto.test.d.ts +2 -0
- package/dist/src/crypto.test.d.ts.map +1 -0
- package/dist/src/crypto.test.js +76 -0
- package/dist/src/crypto.test.js.map +1 -0
- package/dist/src/dispatch.d.ts +15 -0
- package/dist/src/dispatch.d.ts.map +1 -0
- package/dist/src/dispatch.js +193 -0
- package/dist/src/dispatch.js.map +1 -0
- package/dist/src/dispatch.test.d.ts +2 -0
- package/dist/src/dispatch.test.d.ts.map +1 -0
- package/dist/src/dispatch.test.js +231 -0
- package/dist/src/dispatch.test.js.map +1 -0
- package/dist/src/inbound.d.ts +7 -0
- package/dist/src/inbound.d.ts.map +1 -0
- package/dist/src/inbound.js +82 -0
- package/dist/src/inbound.js.map +1 -0
- package/dist/src/onboarding.d.ts +25 -0
- package/dist/src/onboarding.d.ts.map +1 -0
- package/dist/src/onboarding.js +49 -0
- package/dist/src/onboarding.js.map +1 -0
- package/dist/src/outbound.d.ts +17 -0
- package/dist/src/outbound.d.ts.map +1 -0
- package/dist/src/outbound.js +55 -0
- package/dist/src/outbound.js.map +1 -0
- package/dist/src/outbound.test.d.ts +2 -0
- package/dist/src/outbound.test.d.ts.map +1 -0
- package/dist/src/outbound.test.js +175 -0
- package/dist/src/outbound.test.js.map +1 -0
- package/dist/src/probe.d.ts +15 -0
- package/dist/src/probe.d.ts.map +1 -0
- package/dist/src/probe.js +55 -0
- package/dist/src/probe.js.map +1 -0
- package/dist/src/runtime.d.ts +22 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +33 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/send.d.ts +27 -0
- package/dist/src/send.d.ts.map +1 -0
- package/dist/src/send.js +103 -0
- package/dist/src/send.js.map +1 -0
- package/dist/src/state.d.ts +7 -0
- package/dist/src/state.d.ts.map +1 -0
- package/dist/src/state.js +109 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/text.d.ts +46 -0
- package/dist/src/text.d.ts.map +1 -0
- package/dist/src/text.js +192 -0
- package/dist/src/text.js.map +1 -0
- package/dist/src/text.test.d.ts +2 -0
- package/dist/src/text.test.d.ts.map +1 -0
- package/dist/src/text.test.js +110 -0
- package/dist/src/text.test.js.map +1 -0
- package/dist/src/token.d.ts +40 -0
- package/dist/src/token.d.ts.map +1 -0
- package/dist/src/token.js +154 -0
- package/dist/src/token.js.map +1 -0
- package/dist/src/token.test.d.ts +2 -0
- package/dist/src/token.test.d.ts.map +1 -0
- package/dist/src/token.test.js +74 -0
- package/dist/src/token.test.js.map +1 -0
- package/dist/src/types.d.ts +320 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/webhook.d.ts +6 -0
- package/dist/src/webhook.d.ts.map +1 -0
- package/dist/src/webhook.js +381 -0
- package/dist/src/webhook.js.map +1 -0
- package/dist/src/webhook.test.d.ts +2 -0
- package/dist/src/webhook.test.d.ts.map +1 -0
- package/dist/src/webhook.test.js +737 -0
- package/dist/src/webhook.test.js.map +1 -0
- package/openclaw.plugin.json +83 -0
- package/package.json +103 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { PluginConfig, WechatMpAccountConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Default account identifier for single-account configurations.
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_ACCOUNT_ID = "default";
|
|
6
|
+
/**
|
|
7
|
+
* List all configured WeChat MP account IDs.
|
|
8
|
+
* Returns the default account ID if no multi-account config exists.
|
|
9
|
+
*/
|
|
10
|
+
export declare function listWechatMpAccountIds(cfg: PluginConfig): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Resolve the default WeChat MP account ID.
|
|
13
|
+
* Returns the first available account or "default".
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveDefaultWechatMpAccountId(cfg: PluginConfig): string;
|
|
16
|
+
/**
|
|
17
|
+
* Resolved WeChat MP account with merged configuration.
|
|
18
|
+
*/
|
|
19
|
+
export interface ResolvedWechatMpAccount {
|
|
20
|
+
accountId: string;
|
|
21
|
+
name: string;
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
configured: boolean;
|
|
24
|
+
canSendActive: boolean;
|
|
25
|
+
config: WechatMpAccountConfig;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a WeChat MP account configuration.
|
|
29
|
+
* Merges root config with account-specific overrides.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveWechatMpAccount(params: {
|
|
32
|
+
cfg: PluginConfig;
|
|
33
|
+
accountId?: string;
|
|
34
|
+
}): ResolvedWechatMpAccount;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the allowFrom list from account configuration.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveAllowFrom(config: WechatMpAccountConfig): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Parse an external target string into openId and accountId components.
|
|
41
|
+
* Supports formats:
|
|
42
|
+
* - `user:<openid>` (default account)
|
|
43
|
+
* - `user:<openid>@<accountId>` (explicit account)
|
|
44
|
+
* - `wechat-mp:user:<openid>` (legacy prefix)
|
|
45
|
+
* - `wechat-mp:user:<openid>@<accountId>` (legacy with account)
|
|
46
|
+
* - `<openid>` (bare openid, default account)
|
|
47
|
+
* - `<openid>@<accountId>` (bare with account)
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseWechatMpTarget(target: string): {
|
|
50
|
+
openId: string;
|
|
51
|
+
accountId?: string;
|
|
52
|
+
} | null;
|
|
53
|
+
/**
|
|
54
|
+
* Build an external target string from openId and optional accountId.
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildWechatMpTarget(openId: string, accountId?: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Build an internal session key from appId and openId.
|
|
59
|
+
* Format: `dm:<appId>:<openId>`
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildWechatMpSessionKey(appId: string, openId: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Parse an internal session key to extract appId and openId.
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseWechatMpSessionKey(sessionKey: string): {
|
|
66
|
+
appId: string;
|
|
67
|
+
openId: string;
|
|
68
|
+
} | null;
|
|
69
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEtF;;GAEG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE,CAoBlE;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAQzE;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,GAAG,EAAE,YAAY,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,uBAAuB,CAiE1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,EAAE,CAKxE;AAMD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GACb;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA0B/C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,GACjB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI1C"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default account identifier for single-account configurations.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_ACCOUNT_ID = "default";
|
|
5
|
+
/**
|
|
6
|
+
* List all configured WeChat MP account IDs.
|
|
7
|
+
* Returns the default account ID if no multi-account config exists.
|
|
8
|
+
*/
|
|
9
|
+
export function listWechatMpAccountIds(cfg) {
|
|
10
|
+
const channelCfg = cfg?.channels?.["wechat-mp"];
|
|
11
|
+
if (!channelCfg)
|
|
12
|
+
return [];
|
|
13
|
+
const ids = [];
|
|
14
|
+
// Add dedicated accounts
|
|
15
|
+
if (channelCfg.accounts) {
|
|
16
|
+
ids.push(...Object.keys(channelCfg.accounts));
|
|
17
|
+
}
|
|
18
|
+
// Include default if root config has credentials
|
|
19
|
+
const hasRootConfig = Boolean(channelCfg.appId || channelCfg.appSecret || channelCfg.token);
|
|
20
|
+
if (hasRootConfig && !ids.includes(DEFAULT_ACCOUNT_ID)) {
|
|
21
|
+
ids.unshift(DEFAULT_ACCOUNT_ID);
|
|
22
|
+
}
|
|
23
|
+
return ids.length > 0 ? ids : [DEFAULT_ACCOUNT_ID];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the default WeChat MP account ID.
|
|
27
|
+
* Returns the first available account or "default".
|
|
28
|
+
*/
|
|
29
|
+
export function resolveDefaultWechatMpAccountId(cfg) {
|
|
30
|
+
const ids = listWechatMpAccountIds(cfg);
|
|
31
|
+
const channelCfg = cfg?.channels?.["wechat-mp"];
|
|
32
|
+
const explicitDefault = channelCfg?.defaultAccount;
|
|
33
|
+
if (explicitDefault && ids.includes(explicitDefault)) {
|
|
34
|
+
return explicitDefault;
|
|
35
|
+
}
|
|
36
|
+
return ids[0] ?? DEFAULT_ACCOUNT_ID;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a WeChat MP account configuration.
|
|
40
|
+
* Merges root config with account-specific overrides.
|
|
41
|
+
*/
|
|
42
|
+
export function resolveWechatMpAccount(params) {
|
|
43
|
+
const { cfg, accountId } = params;
|
|
44
|
+
const channelCfg = (cfg?.channels?.["wechat-mp"] ?? {});
|
|
45
|
+
const targetId = accountId?.trim() || resolveDefaultWechatMpAccountId(cfg);
|
|
46
|
+
// Check if dedicated account exists
|
|
47
|
+
const dedicatedAccount = channelCfg.accounts?.[targetId];
|
|
48
|
+
// Merge configurations: root defaults + account overrides
|
|
49
|
+
const merged = dedicatedAccount
|
|
50
|
+
? {
|
|
51
|
+
name: channelCfg.name,
|
|
52
|
+
enabled: channelCfg.enabled,
|
|
53
|
+
appId: channelCfg.appId,
|
|
54
|
+
appSecret: channelCfg.appSecret,
|
|
55
|
+
encodingAESKey: channelCfg.encodingAESKey,
|
|
56
|
+
token: channelCfg.token,
|
|
57
|
+
webhookPath: channelCfg.webhookPath,
|
|
58
|
+
messageMode: channelCfg.messageMode,
|
|
59
|
+
replyMode: channelCfg.replyMode,
|
|
60
|
+
activeDeliveryMode: channelCfg.activeDeliveryMode,
|
|
61
|
+
renderMarkdown: channelCfg.renderMarkdown,
|
|
62
|
+
welcomeText: channelCfg.welcomeText,
|
|
63
|
+
dmPolicy: channelCfg.dmPolicy,
|
|
64
|
+
allowFrom: channelCfg.allowFrom,
|
|
65
|
+
...dedicatedAccount,
|
|
66
|
+
}
|
|
67
|
+
: {
|
|
68
|
+
name: channelCfg.name,
|
|
69
|
+
enabled: channelCfg.enabled,
|
|
70
|
+
appId: channelCfg.appId,
|
|
71
|
+
appSecret: channelCfg.appSecret,
|
|
72
|
+
encodingAESKey: channelCfg.encodingAESKey,
|
|
73
|
+
token: channelCfg.token,
|
|
74
|
+
webhookPath: channelCfg.webhookPath,
|
|
75
|
+
messageMode: channelCfg.messageMode,
|
|
76
|
+
replyMode: channelCfg.replyMode,
|
|
77
|
+
activeDeliveryMode: channelCfg.activeDeliveryMode,
|
|
78
|
+
renderMarkdown: channelCfg.renderMarkdown,
|
|
79
|
+
welcomeText: channelCfg.welcomeText,
|
|
80
|
+
dmPolicy: channelCfg.dmPolicy,
|
|
81
|
+
allowFrom: channelCfg.allowFrom,
|
|
82
|
+
};
|
|
83
|
+
const configured = Boolean(merged.appId &&
|
|
84
|
+
merged.token &&
|
|
85
|
+
(merged.messageMode === "plain" || merged.encodingAESKey));
|
|
86
|
+
const canSendActive = Boolean(configured &&
|
|
87
|
+
merged.appId &&
|
|
88
|
+
merged.appSecret);
|
|
89
|
+
return {
|
|
90
|
+
accountId: targetId,
|
|
91
|
+
name: merged.name ?? `WeChat MP (${targetId})`,
|
|
92
|
+
enabled: merged.enabled !== false,
|
|
93
|
+
configured,
|
|
94
|
+
canSendActive,
|
|
95
|
+
config: merged,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve the allowFrom list from account configuration.
|
|
100
|
+
*/
|
|
101
|
+
export function resolveAllowFrom(config) {
|
|
102
|
+
const list = config.allowFrom ?? [];
|
|
103
|
+
return list
|
|
104
|
+
.map((entry) => String(entry).trim().toLowerCase())
|
|
105
|
+
.filter(Boolean);
|
|
106
|
+
}
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// TARGET AND SESSION KEY HELPERS
|
|
109
|
+
// ============================================================================
|
|
110
|
+
/**
|
|
111
|
+
* Parse an external target string into openId and accountId components.
|
|
112
|
+
* Supports formats:
|
|
113
|
+
* - `user:<openid>` (default account)
|
|
114
|
+
* - `user:<openid>@<accountId>` (explicit account)
|
|
115
|
+
* - `wechat-mp:user:<openid>` (legacy prefix)
|
|
116
|
+
* - `wechat-mp:user:<openid>@<accountId>` (legacy with account)
|
|
117
|
+
* - `<openid>` (bare openid, default account)
|
|
118
|
+
* - `<openid>@<accountId>` (bare with account)
|
|
119
|
+
*/
|
|
120
|
+
export function parseWechatMpTarget(target) {
|
|
121
|
+
let raw = String(target ?? "").trim();
|
|
122
|
+
if (!raw)
|
|
123
|
+
return null;
|
|
124
|
+
// Strip wechat-mp: prefix if present
|
|
125
|
+
if (raw.startsWith("wechat-mp:")) {
|
|
126
|
+
raw = raw.slice("wechat-mp:".length);
|
|
127
|
+
}
|
|
128
|
+
// Extract accountId from @ suffix
|
|
129
|
+
let accountId;
|
|
130
|
+
const atIndex = raw.lastIndexOf("@");
|
|
131
|
+
if (atIndex > 0 && atIndex < raw.length - 1) {
|
|
132
|
+
accountId = raw.slice(atIndex + 1).trim();
|
|
133
|
+
raw = raw.slice(0, atIndex);
|
|
134
|
+
}
|
|
135
|
+
// Strip user: prefix if present
|
|
136
|
+
if (raw.startsWith("user:")) {
|
|
137
|
+
raw = raw.slice("user:".length);
|
|
138
|
+
}
|
|
139
|
+
const openId = raw.trim();
|
|
140
|
+
if (!openId)
|
|
141
|
+
return null;
|
|
142
|
+
return { openId, accountId };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Build an external target string from openId and optional accountId.
|
|
146
|
+
*/
|
|
147
|
+
export function buildWechatMpTarget(openId, accountId) {
|
|
148
|
+
const base = `user:${openId}`;
|
|
149
|
+
return accountId ? `${base}@${accountId}` : base;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Build an internal session key from appId and openId.
|
|
153
|
+
* Format: `dm:<appId>:<openId>`
|
|
154
|
+
*/
|
|
155
|
+
export function buildWechatMpSessionKey(appId, openId) {
|
|
156
|
+
return `dm:${appId}:${openId}`;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Parse an internal session key to extract appId and openId.
|
|
160
|
+
*/
|
|
161
|
+
export function parseWechatMpSessionKey(sessionKey) {
|
|
162
|
+
const parts = sessionKey.split(":");
|
|
163
|
+
if (parts.length !== 3 || parts[0] !== "dm")
|
|
164
|
+
return null;
|
|
165
|
+
return { appId: parts[1], openId: parts[2] };
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeChat MP crypto utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - computeSignature: Compute signature for GET verification
|
|
6
|
+
* - verifySignature: Verify signature for GET validation
|
|
7
|
+
* - computeMsgSignature: Compute msg_signature for POST validation
|
|
8
|
+
* - verifyMsgSignature: Verify msg_signature for POST validation (safe mode)
|
|
9
|
+
* - decryptWechatMpMessage: Decrypt AES encrypted message
|
|
10
|
+
* - encryptWechatMpMessage: Encrypt plaintext for encrypted reply (safe mode)
|
|
11
|
+
* - parseWechatMpXml: Parse XML message body
|
|
12
|
+
* - buildWechatMpXml: Build XML message for passive reply
|
|
13
|
+
*/
|
|
14
|
+
import type { ResolvedWechatMpAccount } from "./types.js";
|
|
15
|
+
/**
|
|
16
|
+
* Compute signature for GET callback verification
|
|
17
|
+
* Used for URL callback verification
|
|
18
|
+
*/
|
|
19
|
+
export declare function computeSignature(params: {
|
|
20
|
+
token: string;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
nonce: string;
|
|
23
|
+
}): string;
|
|
24
|
+
/**
|
|
25
|
+
* Verify GET callback signature (URL verification)
|
|
26
|
+
*/
|
|
27
|
+
export declare function verifySignature(params: {
|
|
28
|
+
token: string;
|
|
29
|
+
timestamp: string;
|
|
30
|
+
nonce: string;
|
|
31
|
+
signature: string;
|
|
32
|
+
}): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Compute msg_signature for POST body validation (safe mode)
|
|
35
|
+
*/
|
|
36
|
+
export declare function computeMsgSignature(params: {
|
|
37
|
+
token: string;
|
|
38
|
+
timestamp: string;
|
|
39
|
+
nonce: string;
|
|
40
|
+
encrypt: string;
|
|
41
|
+
}): string;
|
|
42
|
+
/**
|
|
43
|
+
* Verify msg_signature for POST body validation (safe mode)
|
|
44
|
+
*/
|
|
45
|
+
export declare function verifyMsgSignature(params: {
|
|
46
|
+
token: string;
|
|
47
|
+
timestamp: string;
|
|
48
|
+
nonce: string;
|
|
49
|
+
encrypt: string;
|
|
50
|
+
msgSignature: string;
|
|
51
|
+
}): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Decrypt AES-256-CBC encrypted message (safe mode)
|
|
54
|
+
* Returns the plaintext XML content
|
|
55
|
+
*/
|
|
56
|
+
export declare function decryptWechatMpMessage(params: {
|
|
57
|
+
encodingAESKey: string;
|
|
58
|
+
encrypt: string;
|
|
59
|
+
expectedAppId?: string;
|
|
60
|
+
}): {
|
|
61
|
+
plaintext: string;
|
|
62
|
+
appId: string;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Encrypt plaintext for encrypted reply (safe mode)
|
|
66
|
+
*/
|
|
67
|
+
export declare function encryptWechatMpMessage(params: {
|
|
68
|
+
encodingAESKey: string;
|
|
69
|
+
appId: string;
|
|
70
|
+
plaintext: string;
|
|
71
|
+
}): {
|
|
72
|
+
encrypt: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Build encrypted reply XML
|
|
76
|
+
*/
|
|
77
|
+
export declare function buildEncryptedReplyXml(params: {
|
|
78
|
+
encrypt: string;
|
|
79
|
+
signature: string;
|
|
80
|
+
timestamp: string;
|
|
81
|
+
nonce: string;
|
|
82
|
+
}): string;
|
|
83
|
+
/**
|
|
84
|
+
* Parse XML message body to structured object (lightweight, no external deps)
|
|
85
|
+
*/
|
|
86
|
+
export declare function parseWechatMpXml(xml: string): Record<string, string>;
|
|
87
|
+
/**
|
|
88
|
+
* Build XML message for WeChat MP passive reply
|
|
89
|
+
*/
|
|
90
|
+
export declare function buildWechatMpXml(data: Record<string, string | number>): string;
|
|
91
|
+
/**
|
|
92
|
+
* Build raw XML message (without CDATA escaping)
|
|
93
|
+
*/
|
|
94
|
+
export declare function buildWechatMpXmlRaw(data: Record<string, string | number>): string;
|
|
95
|
+
/**
|
|
96
|
+
* Check if message mode requires encryption
|
|
97
|
+
*/
|
|
98
|
+
export declare function isSafeMode(account: ResolvedWechatMpAccount): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Check if plain mode is enabled
|
|
101
|
+
*/
|
|
102
|
+
export declare function isPlainMode(account: ResolvedWechatMpAccount): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Check if compat mode is enabled (both encrypted and plain supported)
|
|
105
|
+
*/
|
|
106
|
+
export declare function isCompatMode(account: ResolvedWechatMpAccount): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Build plain text reply XML for passive reply
|
|
109
|
+
*/
|
|
110
|
+
export declare function buildPlainReplyXml(params: {
|
|
111
|
+
toUserName: string;
|
|
112
|
+
fromUserName: string;
|
|
113
|
+
createTime: number;
|
|
114
|
+
msgType: "text";
|
|
115
|
+
content: string;
|
|
116
|
+
}): string;
|
|
117
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAU1D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAKT;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAOV;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAKT;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAQV;AAqDD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAsCvC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAsBtB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAOT;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuBpE;AAqBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAO9E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAMjF;AAMD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAEpE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAErE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAEtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAQT"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeChat MP crypto utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - computeSignature: Compute signature for GET verification
|
|
6
|
+
* - verifySignature: Verify signature for GET validation
|
|
7
|
+
* - computeMsgSignature: Compute msg_signature for POST validation
|
|
8
|
+
* - verifyMsgSignature: Verify msg_signature for POST validation (safe mode)
|
|
9
|
+
* - decryptWechatMpMessage: Decrypt AES encrypted message
|
|
10
|
+
* - encryptWechatMpMessage: Encrypt plaintext for encrypted reply (safe mode)
|
|
11
|
+
* - parseWechatMpXml: Parse XML message body
|
|
12
|
+
* - buildWechatMpXml: Build XML message for passive reply
|
|
13
|
+
*/
|
|
14
|
+
import crypto from "node:crypto";
|
|
15
|
+
const BLOCK_SIZE = 32;
|
|
16
|
+
const AES_KEY_SIZE = 32;
|
|
17
|
+
const IV_SIZE = 16;
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Signature Utilities
|
|
20
|
+
// ============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Compute signature for GET callback verification
|
|
23
|
+
* Used for URL callback verification
|
|
24
|
+
*/
|
|
25
|
+
export function computeSignature(params) {
|
|
26
|
+
const parts = [params.token, params.timestamp, params.nonce]
|
|
27
|
+
.map((v) => String(v ?? "").trim())
|
|
28
|
+
.sort();
|
|
29
|
+
return crypto.createHash("sha1").update(parts.join("")).digest("hex");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Verify GET callback signature (URL verification)
|
|
33
|
+
*/
|
|
34
|
+
export function verifySignature(params) {
|
|
35
|
+
const computed = computeSignature({
|
|
36
|
+
token: params.token,
|
|
37
|
+
timestamp: params.timestamp,
|
|
38
|
+
nonce: params.nonce,
|
|
39
|
+
});
|
|
40
|
+
return computed === params.signature;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute msg_signature for POST body validation (safe mode)
|
|
44
|
+
*/
|
|
45
|
+
export function computeMsgSignature(params) {
|
|
46
|
+
const parts = [params.token, params.timestamp, params.nonce, params.encrypt]
|
|
47
|
+
.map((v) => String(v ?? "").trim())
|
|
48
|
+
.sort();
|
|
49
|
+
return crypto.createHash("sha1").update(parts.join("")).digest("hex");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Verify msg_signature for POST body validation (safe mode)
|
|
53
|
+
*/
|
|
54
|
+
export function verifyMsgSignature(params) {
|
|
55
|
+
const computed = computeMsgSignature({
|
|
56
|
+
token: params.token,
|
|
57
|
+
timestamp: params.timestamp,
|
|
58
|
+
nonce: params.nonce,
|
|
59
|
+
encrypt: params.encrypt,
|
|
60
|
+
});
|
|
61
|
+
return computed === params.msgSignature;
|
|
62
|
+
}
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// AES Encryption/Decryption
|
|
65
|
+
// ============================================================================
|
|
66
|
+
/**
|
|
67
|
+
* Decode encodingAESKey from base64 to 32-byte AES key
|
|
68
|
+
*/
|
|
69
|
+
function decodeEncodingAESKey(encodingAESKey) {
|
|
70
|
+
const trimmed = encodingAESKey.trim();
|
|
71
|
+
if (!trimmed) {
|
|
72
|
+
throw new Error("encodingAESKey is required");
|
|
73
|
+
}
|
|
74
|
+
// Add base64 padding if needed
|
|
75
|
+
const withPadding = trimmed.endsWith("=") ? trimmed : `${trimmed}=`;
|
|
76
|
+
const decoded = Buffer.from(withPadding, "base64");
|
|
77
|
+
if (decoded.length !== AES_KEY_SIZE) {
|
|
78
|
+
throw new Error(`Invalid encodingAESKey: expected ${AES_KEY_SIZE} bytes, got ${decoded.length}`);
|
|
79
|
+
}
|
|
80
|
+
return decoded;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* PKCS7 unpad
|
|
84
|
+
*/
|
|
85
|
+
function pkcs7Unpad(buf, blockSize) {
|
|
86
|
+
if (buf.length === 0) {
|
|
87
|
+
throw new Error("Invalid PKCS7 payload: empty buffer");
|
|
88
|
+
}
|
|
89
|
+
const pad = buf[buf.length - 1];
|
|
90
|
+
if (pad < 1 || pad > blockSize) {
|
|
91
|
+
throw new Error(`Invalid PKCS7 padding: ${pad}`);
|
|
92
|
+
}
|
|
93
|
+
for (let i = 1; i <= pad; i++) {
|
|
94
|
+
if (buf[buf.length - i] !== pad) {
|
|
95
|
+
throw new Error("Invalid PKCS7 padding: inconsistent bytes");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return buf.subarray(0, buf.length - pad);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* PKCS7 pad
|
|
102
|
+
*/
|
|
103
|
+
function pkcs7Pad(buf, blockSize) {
|
|
104
|
+
const padLen = blockSize - (buf.length % blockSize);
|
|
105
|
+
const pad = Buffer.alloc(padLen, padLen);
|
|
106
|
+
return Buffer.concat([buf, pad]);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Decrypt AES-256-CBC encrypted message (safe mode)
|
|
110
|
+
* Returns the plaintext XML content
|
|
111
|
+
*/
|
|
112
|
+
export function decryptWechatMpMessage(params) {
|
|
113
|
+
const aesKey = decodeEncodingAESKey(params.encodingAESKey);
|
|
114
|
+
const iv = aesKey.subarray(0, IV_SIZE);
|
|
115
|
+
const decipher = crypto.createDecipheriv("aes-256-cbc", aesKey, iv);
|
|
116
|
+
decipher.setAutoPadding(false);
|
|
117
|
+
const decryptedPadded = Buffer.concat([
|
|
118
|
+
decipher.update(Buffer.from(params.encrypt, "base64")),
|
|
119
|
+
decipher.final(),
|
|
120
|
+
]);
|
|
121
|
+
const decrypted = pkcs7Unpad(decryptedPadded, BLOCK_SIZE);
|
|
122
|
+
// Format: random(16) + msgLen(4) + msg + appId
|
|
123
|
+
if (decrypted.length < 20) {
|
|
124
|
+
throw new Error(`Invalid decrypted payload length: ${decrypted.length}`);
|
|
125
|
+
}
|
|
126
|
+
const msgLen = decrypted.readUInt32BE(16);
|
|
127
|
+
const msgStart = 20;
|
|
128
|
+
const msgEnd = msgStart + msgLen;
|
|
129
|
+
if (msgEnd > decrypted.length) {
|
|
130
|
+
throw new Error("Invalid decrypted message length");
|
|
131
|
+
}
|
|
132
|
+
const plaintext = decrypted.subarray(msgStart, msgEnd).toString("utf8");
|
|
133
|
+
const appId = decrypted.subarray(msgEnd).toString("utf8").trim();
|
|
134
|
+
// Verify appId if expected
|
|
135
|
+
if (params.expectedAppId && appId !== params.expectedAppId) {
|
|
136
|
+
throw new Error(`AppId mismatch: expected "${params.expectedAppId}", got "${appId}"`);
|
|
137
|
+
}
|
|
138
|
+
return { plaintext, appId };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Encrypt plaintext for encrypted reply (safe mode)
|
|
142
|
+
*/
|
|
143
|
+
export function encryptWechatMpMessage(params) {
|
|
144
|
+
const aesKey = decodeEncodingAESKey(params.encodingAESKey);
|
|
145
|
+
const iv = aesKey.subarray(0, IV_SIZE);
|
|
146
|
+
// Build plaintext: random(16) + msgLen(4) + msg + appId
|
|
147
|
+
const randomBytes = crypto.randomBytes(16);
|
|
148
|
+
const msgBuffer = Buffer.from(params.plaintext, "utf8");
|
|
149
|
+
const msgLenBuffer = Buffer.alloc(4);
|
|
150
|
+
msgLenBuffer.writeUInt32BE(msgBuffer.length, 0);
|
|
151
|
+
const appIdBuffer = Buffer.from(params.appId, "utf8");
|
|
152
|
+
const plainBuffer = Buffer.concat([randomBytes, msgLenBuffer, msgBuffer, appIdBuffer]);
|
|
153
|
+
// PKCS7 pad
|
|
154
|
+
const padded = pkcs7Pad(plainBuffer, BLOCK_SIZE);
|
|
155
|
+
// Encrypt
|
|
156
|
+
const cipher = crypto.createCipheriv("aes-256-cbc", aesKey, iv);
|
|
157
|
+
cipher.setAutoPadding(false);
|
|
158
|
+
const encryptedBuffer = Buffer.concat([cipher.update(padded), cipher.final()]);
|
|
159
|
+
return { encrypt: encryptedBuffer.toString("base64") };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Build encrypted reply XML
|
|
163
|
+
*/
|
|
164
|
+
export function buildEncryptedReplyXml(params) {
|
|
165
|
+
return `<xml>
|
|
166
|
+
<Encrypt><![CDATA[${params.encrypt}]]></Encrypt>
|
|
167
|
+
<MsgSignature><![CDATA[${params.signature}]]></MsgSignature>
|
|
168
|
+
<TimeStamp>${params.timestamp}</TimeStamp>
|
|
169
|
+
<Nonce><![CDATA[${params.nonce}]]></Nonce>
|
|
170
|
+
</xml>`;
|
|
171
|
+
}
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// XML Utilities
|
|
174
|
+
// ============================================================================
|
|
175
|
+
/**
|
|
176
|
+
* Parse XML message body to structured object (lightweight, no external deps)
|
|
177
|
+
*/
|
|
178
|
+
export function parseWechatMpXml(xml) {
|
|
179
|
+
const result = {};
|
|
180
|
+
// Match CDATA format: <Tag><![CDATA[value]]></Tag>
|
|
181
|
+
const cdataRegex = /<([\w:-]+)><!\[CDATA\[([\s\S]*?)\]\]><\/\1>/g;
|
|
182
|
+
let match;
|
|
183
|
+
while ((match = cdataRegex.exec(xml)) !== null) {
|
|
184
|
+
const [, key, value] = match;
|
|
185
|
+
if (key) {
|
|
186
|
+
result[key] = value ?? "";
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Match simple format: <Tag>value</Tag>
|
|
190
|
+
const simpleRegex = /<([\w:-]+)>([^<]*)<\/\1>/g;
|
|
191
|
+
while ((match = simpleRegex.exec(xml)) !== null) {
|
|
192
|
+
const [, key, value] = match;
|
|
193
|
+
if (key && result[key] === undefined) {
|
|
194
|
+
result[key] = value ?? "";
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Escape XML special characters
|
|
201
|
+
*/
|
|
202
|
+
function escapeXml(str) {
|
|
203
|
+
return str
|
|
204
|
+
.replace(/&/g, "&")
|
|
205
|
+
.replace(/</g, "<")
|
|
206
|
+
.replace(/>/g, ">")
|
|
207
|
+
.replace(/"/g, """)
|
|
208
|
+
.replace(/'/g, "'");
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Escape CDATA ending
|
|
212
|
+
*/
|
|
213
|
+
function escapeCData(str) {
|
|
214
|
+
return str.replace(/\]\]>/g, "]]>");
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Build XML message for WeChat MP passive reply
|
|
218
|
+
*/
|
|
219
|
+
export function buildWechatMpXml(data) {
|
|
220
|
+
const parts = [];
|
|
221
|
+
for (const [key, value] of Object.entries(data)) {
|
|
222
|
+
const strValue = String(value);
|
|
223
|
+
parts.push(`<${key}><![CDATA[${escapeCData(strValue)}]]></${key}>`);
|
|
224
|
+
}
|
|
225
|
+
return `<xml>${parts.join("")}</xml>`;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Build raw XML message (without CDATA escaping)
|
|
229
|
+
*/
|
|
230
|
+
export function buildWechatMpXmlRaw(data) {
|
|
231
|
+
const parts = [];
|
|
232
|
+
for (const [key, value] of Object.entries(data)) {
|
|
233
|
+
parts.push(`<${key}>${value}</${key}>`);
|
|
234
|
+
}
|
|
235
|
+
return `<xml>${parts.join("")}</xml>`;
|
|
236
|
+
}
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// Mode Detection
|
|
239
|
+
// ============================================================================
|
|
240
|
+
/**
|
|
241
|
+
* Check if message mode requires encryption
|
|
242
|
+
*/
|
|
243
|
+
export function isSafeMode(account) {
|
|
244
|
+
return account.config.messageMode === "safe" || account.config.messageMode === "compat";
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Check if plain mode is enabled
|
|
248
|
+
*/
|
|
249
|
+
export function isPlainMode(account) {
|
|
250
|
+
return account.config.messageMode === "plain" || !account.config.messageMode;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Check if compat mode is enabled (both encrypted and plain supported)
|
|
254
|
+
*/
|
|
255
|
+
export function isCompatMode(account) {
|
|
256
|
+
return account.config.messageMode === "compat";
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Build plain text reply XML for passive reply
|
|
260
|
+
*/
|
|
261
|
+
export function buildPlainReplyXml(params) {
|
|
262
|
+
return buildWechatMpXml({
|
|
263
|
+
ToUserName: params.toUserName,
|
|
264
|
+
FromUserName: params.fromUserName,
|
|
265
|
+
CreateTime: String(params.createTime),
|
|
266
|
+
MsgType: params.msgType,
|
|
267
|
+
Content: params.content,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.test.d.ts","sourceRoot":"","sources":["../../src/crypto.test.ts"],"names":[],"mappings":""}
|