#!/usr/bin/env python3 from pathlib import Path path = Path("/Users/john/Project/Memind/server.mjs") text = path.read_text() if "function verifyWechatMpUrlChallenge" not in text: text = text.replace( ' acceptLink: env.H5_WECHAT_MP_ACCEPT_LINK !== "0"\n };\n}', ' acceptLink: env.H5_WECHAT_MP_ACCEPT_LINK !== "0",\n encodingAesKey: env.H5_WECHAT_MP_ENCODING_AES_KEY?.trim() ?? ""\n };\n}', 1, ) old_sig = """function verifyWechatMpSignature({ token, timestamp, nonce, signature }) { const digest = crypto27.createHash("sha1").update([token, timestamp, nonce].sort().join("")).digest("hex"); return digest === String(signature ?? ""); }""" new_sig = """function sha1WechatHex(parts) { return crypto27.createHash("sha1").update([...parts].sort().join("")).digest("hex"); } function verifyWechatMpSignature({ token, timestamp, nonce, signature }) { return sha1WechatHex([token, timestamp, nonce]) === String(signature ?? ""); } function verifyWechatMpMsgSignature({ token, timestamp, nonce, echoStr, msgSignature }) { return sha1WechatHex([token, timestamp, nonce, echoStr]) === String(msgSignature ?? ""); } function decodeWechatMpAesKey(encodingAesKey) { const key = Buffer.from(`${String(encodingAesKey ?? "").trim()}=`, "base64"); if (key.length !== 32) throw new Error("invalid encoding aes key"); return key; } function decryptWechatMpPayload({ encodingAesKey, appId, encrypted }) { const key = decodeWechatMpAesKey(encodingAesKey); const iv = key.subarray(0, 16); const decipher = crypto27.createDecipheriv("aes-256-cbc", key, iv); decipher.setAutoPadding(false); const cipherBuf = Buffer.from(String(encrypted ?? ""), "base64"); let decoded = Buffer.concat([decipher.update(cipherBuf), decipher.final()]); const pad = decoded.at(-1); if (!Number.isInteger(pad) || pad < 1 || pad > 32) throw new Error("invalid padding"); decoded = decoded.subarray(0, decoded.length - pad); const content = decoded.subarray(16); const msgLen = content.readUInt32BE(0); const msg = content.subarray(4, 4 + msgLen).toString("utf8"); const receivedAppId = content.subarray(4 + msgLen).toString("utf8"); if (receivedAppId !== String(appId ?? "")) throw new Error("appid mismatch"); return msg; } function verifyWechatMpUrlChallenge(query = {}, config = {}) { const timestamp = String(query.timestamp ?? ""); const nonce = String(query.nonce ?? ""); const echostr = String(query.echostr ?? ""); const encryptType = String(query.encrypt_type ?? "").toLowerCase(); if (encryptType === "aes") { const msgSignature = String(query.msg_signature ?? ""); if (!config?.token || !config?.encodingAesKey || !config?.appId) { return { ok: false, status: 503, body: "wechat mp aes mode not configured" }; } if (!verifyWechatMpMsgSignature({ token: config.token, timestamp, nonce, echoStr: echostr, msgSignature })) { return { ok: false, status: 403, body: "invalid signature" }; } try { const plain = decryptWechatMpPayload({ encodingAesKey: config.encodingAesKey, appId: config.appId, encrypted: echostr }); return { ok: true, status: 200, body: plain }; } catch { return { ok: false, status: 403, body: "invalid echostr" }; } } if (!verifyWechatMpSignature({ token: config?.token, timestamp, nonce, signature: String(query.signature ?? "") })) { return { ok: false, status: 403, body: "invalid signature" }; } return { ok: true, status: 200, body: echostr }; }""" if old_sig not in text: raise SystemExit("signature block not found") text = text.replace(old_sig, new_sig, 1) text = text.replace( """ const verifyRequest = (query = {}) => verifyWechatMpSignature({ token: config.token, timestamp: String(query.timestamp ?? ""), nonce: String(query.nonce ?? ""), signature: String(query.signature ?? "") });""", """ const verifyRequest = (query = {}) => verifyWechatMpSignature({ token: config.token, timestamp: String(query.timestamp ?? ""), nonce: String(query.nonce ?? ""), signature: String(query.signature ?? "") }); const verifyUrlChallenge = (query = {}) => verifyWechatMpUrlChallenge(query, config);""", 1, ) text = text.replace( " verifyRequest,\n handleInboundMessage,", " verifyRequest,\n verifyUrlChallenge,\n handleInboundMessage,", 1, ) path.write_text(text) print("bundled server.mjs aes patch applied") else: print("bundled aes helpers already present") release = Path("/Users/john/Project/releases/memind-live-before-20260626-095637-d51df2f/wechat-mp.mjs") if release.exists(): Path("/Users/john/Project/Memind/wechat-mp.mjs").write_text(release.read_text()) print("wechat-mp.mjs restored from release")