您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
wechat end to end encrypt by rsa!
// ==UserScript== // @name wx_e2e // @namespace https://github.com/ygcaicn/wx_e2e // @version 0.1.2 // @description wechat end to end encrypt by rsa! // @author Jachin // @match *://wx.qq.com/* // @grant none // ==/UserScript== (function() {"use strict"; function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"; script.onload = function () { console.log("jQuery is ready!"); }; document.body.appendChild(script); script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://cdn.bootcss.com/jsencrypt/3.0.0-rc.1/jsencrypt.min.js"; script.onload = function () { console.log("jsencrypt is ready!"); }; document.body.appendChild(script); var log = function log(msg) { return console.log("[wx_e2e]:", msg); }; // 监听收到新消息 var origOpen = XMLHttpRequest.prototype.open; var origsendTextMessage = angular.element('#editArea').scope().sendTextMessage; var open_prototype = XMLHttpRequest.prototype.open; var intercept_response = function intercept_response(callback) { XMLHttpRequest.prototype.open = function () { // console.log(arguments); /\/mmwebwx-bin\/webwxsync/.test(arguments['1']) && this.addEventListener('readystatechange', function (event) { // console.log('readystate: ' + this.readyState); // console.log(this); if (this.responseText !== '' && this.readyState === 4) { // console.log(this.responseText); var original_response = this.responseText; var modified_response = JSON.parse(original_response); // 每次轮询可能收到多条消息 var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = modified_response.AddMsgList[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var msg = _step.value; log(msg); if (msg.MsgType == 1) msg = callback(msg); } // modify the response } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } Object.defineProperty(this, 'response', { writable: true }); Object.defineProperty(this, 'responseText', { writable: true }); this.response = this.responseText = JSON.stringify(modified_response); // console.log(this.responseText); } }); return open_prototype.apply(this, arguments); }; }; //保存所有的e2e会话 var e2e_list = []; var WX_E2E = /*#__PURE__*/ function () { function WX_E2E(username) { var _this = this; var key_size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1024; _classCallCheck(this, WX_E2E); this.getThis = function () { return _this; }; this.username = username; this.state = 1; this.key_size = key_size; this.crypt = new JSEncrypt({ default_key_size: key_size }); this.pri_key = this.crypt.getPrivateKey(); this.pub_key = this.crypt.getPublicKey(); this.other_key = undefined; } _createClass(WX_E2E, [{ key: "sendTextMessage", value: function sendTextMessage() { var msg = angular.element('#editArea').scope().editAreaCtn; log(msg); //发送加密消息 if (this.state === 3) { this.crypt.setPublicKey(this.other_key); var msg_l = _toConsumableArray(msg); var e_msg_l = []; while (true) { var group = msg_l.splice(0, 117).join(''); if (group.length == 0) break; e_msg_l.push(this.crypt.encrypt(group)); } var e_msg = e_msg_l.flat().join(''); log(e_msg); angular.element('#editArea').scope().editAreaCtn = 'wx_e2e://' + e_msg; var orig_ret = origsendTextMessage(); angular.element('#editArea').scope().editAreaCtn = ''; this.modifyLastTextMessage(msg); return orig_ret; } //未连接,提示明文发送 else { var ret = confirm('对方尚未连接,此消息未加密,将明文发送!\r\n' + '对方尚未连接,此消息未加密,将明文发送!\r\n' + '点击确认,承担风险。\r\n' + '点击取消,返回编辑。'); if (ret) { if (msg.search("\r\n\u6211\u6B63\u5728\u4F7F\u7528wx_e2e\u53D1\u9001\u6D88\u606F\u3002\r\n github.com/ygcaicn/wx_e2e") < 0) msg = msg + "\r\n\u6211\u6B63\u5728\u4F7F\u7528wx_e2e\u53D1\u9001\u6D88\u606F\u3002\r\n github.com/ygcaicn/wx_e2e"; angular.element('#editArea').scope().editAreaCtn = msg; var _orig_ret = origsendTextMessage(); angular.element('#editArea').scope().editAreaCtn = ''; this.modifyLastTextMessage("尚未连接,此消息未加密,为明文发送!"); return _orig_ret; } else return; } } // 参数为发送的明文消息 }, { key: "modifyLastTextMessage", value: function modifyLastTextMessage(msg) { var username = this.username; var ret = angular.element("#chatArea").scope().chatContent.filter(function (item) { if (item.MsgType == 1 && item.MMIsSend && item.ToUserName === username) { return true; } }); var last = ret.pop(); last.MMActualContent = "<span class=\"emoji emoji1f510\"></span>: ".concat(last.MMActualContent, " \n <br><hr><span class=\"e_msg\">").concat(msg, "</span>"); $('body').click(); } }, { key: "sendRequest", value: function sendRequest() { var content = "wx_e2e://hi/".concat(this.pub_key); angular.element('#editArea').scope().editAreaCtn = content; return origsendTextMessage(); this.state = 4; } }, { key: "sendClose", value: function sendClose() { var content = "wx_e2e://close"; angular.element('#editArea').scope().editAreaCtn = content; return origsendTextMessage(); this.state = 0; } }, { key: "decrypt", value: function decrypt(e_message) { this.crypt.setPrivateKey(this.pri_key); var e_message_l = _toConsumableArray(e_message); var message_l = []; while (true) { var group = e_message_l.splice(0, 172).join(''); if (group.length == 0) break; message_l.push(this.crypt.decrypt(group)); } var message = message_l.flat().join(''); return message || "密钥出错,请重新连接!"; } }, { key: "enter_state_2", value: function enter_state_2(other_key) { log(this.username + ": enter_state_2"); // log(other_key); this.state = 2; this.other_key = other_key; log(this.other_key); log(this); // this.enter_state_3(); // ui_setState(3); //弹框提示确认 //弹框 //TODO log('弹框确认'); var con = confirm("\u6536\u5230\u8BF7\u6C42\u8FDE\u63A5\uFF0C\u5BF9\u65B9\u7684Key\u4E3A\uFF1A\r\n".concat(this.other_key)); if (con) { this.enter_state_3(); ui_setState(3); // 调整消息顺序 // TODO 放在当前位置无效 var username = this.username; //得到我方发送的消息列表 var ret = angular.element("#chatArea").scope().chatContent.filter(function (item) { if (item.MsgType == 1 && item.MMIsSend && item.ToUserName === username) { return true; } }); // 找到最后一个 var last = ret.pop(); angular.element("#chatArea").scope().chatContent.splice(angular.element("#chatArea").scope().chatContent.findIndex(function (item) { return item.MsgId === last.MsgId; }), 1); angular.element("#chatArea").scope().chatContent.push(last); $("body").click(); } } // 我方发出的请求被对方确认(对方回复key) // 对方发出的请求连接 }, { key: "enter_state_3", value: function enter_state_3(other_key) { log(this.username + ": enter_state_3"); this.state = 3; // 我方发出的请求被对方确认(对方回复key) if (other_key) { this.other_key = other_key; log('我方发出的请求被对方确认'); } // 对方发出的请求连接,弹窗确认后 else { var content = "wx_e2e://ok/".concat(this.pub_key); angular.element('#editArea').scope().editAreaCtn = content; var o_ret = origsendTextMessage(); return o_ret; } } }, { key: "enter_state_4", value: function enter_state_4() { log(this.username + ": enter_state_4"); this.sendRequest(); this.state = 4; } }]); return WX_E2E; }(); //消息处理函数,msg的格式为chatContent.json的第二个消息格式 var messageHandler = function messageHandler(msg) { log('------------------------'); log(msg); //只处理文本消息 if (msg.MsgType != 1) return msg; var username = msg.FromUserName; // 判断是否需要处理 var ret = e2e_list.filter(function (item) { return item.username === username; }); // 不需要处理 if (ret.length == 0) return msg; if (ret.length > 1) { log("e2e_list 出现重复用户。"); return; } var e2e = ret[0]; var content = msg.Content; // 请求连接 // wx_e2e://hi/ // -----BEGIN PUBLIC KEY----- // MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHMiD3c1O+ZvC1HKwc1H+RC9B9wL // /en0EMTtKw4PcGPXRV0MNBHYuOXYiF/34iTLnHa2JMDiTbeAazvUdq9tbE1hqU81 // Mu53dp8uC5s66x9d5VmAxFztoSYUXFLY1/tY8lpnnMYQbyP3bSM0BlIOxZZDRMHE // k+qUpBL7tCcQU+WjAgMBAAE= // -----END PUBLIC KEY----- ret = /wx_e2e:\/\/hi\/(-----BEGIN PUBLIC KEY-----[\S\s]+)/m.exec(content); if (ret && ret.length == 2) { var other_key = ret[1]; other_key = other_key.replace(/<br\/>/gm, "\n"); log("收到请求连接,对方的Key为:\r\n" + other_key); if (e2e.state == 1 || e2e.state == 4) { //调整当前聊天 // angular.element('.chat_item').scope().itemClick(username); $("div[data-username=\"".concat(username, "\"]")).click(); e2e.enter_state_2(other_key); ui_setState(2); msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(content, " \n <br><hr><span class=\"e_msg\">\u5BF9\u65B9\u8BF7\u6C42e2e\u8FDE\u63A5\u3002</span>"); return msg; } msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(content, " \n <br><hr><span class=\"e_msg\">\u9519\u8BEF\u6D88\u606F-\u72B6\u6001\u4E0D\u5339\u914D</span>"); return msg; } // 对方退出(请求终止) // wx_e2e://close if (/wx_e2e:\/\/close/.test(content)) { log("对方退出!"); if (e2e.state == 3) { e2e_list.splice(e2e_list.findIndex(function (item) { return item.username === e2e.username; }), 1); ui_setState(0); msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(content, " \n <br><hr><span class=\"e_msg\">\u5BF9\u65B9\u65AD\u5F00e2e\u8FDE\u63A5\u3002</span>"); e2e_exit(); return msg; } msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(content, " \n <br><hr><span class=\"e_msg\">\u9519\u8BEF\u6D88\u606F-\u72B6\u6001\u4E0D\u5339\u914D</span>"); return msg; } //对方确认(收到的消息为公钥,当前状态为4) // wx_e2e://ok/ // -----BEGIN PUBLIC KEY----- // MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHMiD3c1O+ZvC1HKwc1H+RC9B9wL // /en0EMTtKw4PcGPXRV0MNBHYuOXYiF/34iTLnHa2JMDiTbeAazvUdq9tbE1hqU81 // Mu53dp8uC5s66x9d5VmAxFztoSYUXFLY1/tY8lpnnMYQbyP3bSM0BlIOxZZDRMHE // k+qUpBL7tCcQU+WjAgMBAAE= // -----END PUBLIC KEY----- ret = /wx_e2e:\/\/ok\/(-----BEGIN PUBLIC KEY-----[\S\s]+)/m.exec(content); if (ret && ret.length == 2) { var _other_key = ret[1]; _other_key = _other_key.replace(/<br\/>/gm, "\n"); log("收到对方确认,对方的Key为:\r\n" + _other_key); if (e2e.state == 4) { e2e.enter_state_3(_other_key); ui_setState(3); msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(content, " \n <br><hr><span class=\"e_msg\">\u5BF9\u65B9\u5DF2\u786E\u8BA4\uFF0C\u8FDE\u63A5\u6210\u529F\uFF01</span>"); return msg; } msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(content, " \n <br><hr><span class=\"e_msg\">\u9519\u8BEF\u6D88\u606F-\u72B6\u6001\u4E0D\u5339\u914D</span>"); return msg; } //加密消息,当前状态为3 // wx_e2e://xxxxx ret = /wx_e2e:\/\/([\S\s]+)/m.exec(content); if (ret && e2e.state == 3) { var s = e2e.decrypt(ret[1]); msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(s, " \n <br><hr><span class=\"e_msg\">").concat(content, "</span>"); return msg; } //非加密消息 msg.Content = "<span class=\"emoji emoji1f510\"></span>: ".concat(content, " \n <br><hr><span class=\"e_msg\">\u975E\u52A0\u5BC6\u6D88\u606F\u3002</span>"); // 必须要返回msg return msg; }; // 进入e2e会话状态 // state 0->1 // username 联系人的username angular.element("#chatArea").scope().currentContact.UserName var e2e_enter = function e2e_enter(username) { var e2e = new WX_E2E(username); e2e_list.push(e2e); ui_setState(1); log(username + ": enter_state_1"); // 正在等待对方的邀请, // confirm(`进入等待邀请状态\r\n点击确认`) // $("#e2e_state").click }; // 退出会话状态 // username 联系人的username angular.element("#chatArea").scope().currentContact.UserName var e2e_exit = function e2e_exit(username) { var e2e = undefined; // 告诉对方退出 // 判断是否需要处理 var ret = e2e_list.filter(function (item) { return item.username === username; }); // 不需要处理 if (ret.length == 1) { e2e = ret[0]; if (e2e.state > 1) e2e.sendClose(); } if (ret.length > 1) { log("e2e_list 出现重复用户。请检查"); return; } // 将会话从e2e_list删除 e2e_list.splice(e2e_list.findIndex(function (item) { return item.username === e2e.username; }), 1); // TODO // 提示保存rsa公钥与密钥,以及e2e会话聊天记录 // 恢复原始聊天功能 ui_setState(0); }; // 11 收到对方e2e请求 // var ui_init = function ui_init() { log('ui_init.'); var css = "<style type=\"text/css\">\n .e2e_toolbar{\n width: 30px;\n height: 30px;\n text-decoration: none;\n font-size: 30px;\n line-height: 30px;\n margin-left: 5px;\n color: #4d4d4d9e;\n // background: gold;\n //background: url(//res.wx.qq.com/a/wx_fed/webwx/res/static/css/5af37c4\[email protected]) no-repeat;\n background-position: -404px -398px;\n -webkit-background-size: 487px 462px;\n background-size: 487px 462px;\n vertical-align: middle;\n display: none;\n }\n .e2e_display{\n display: inline-block;\n }\n .e2e_hide{\n display: none;\n }\n .e2e_disable{\n color: #4d4d4d9e;\n }\n .e2e_enable{\n color: #7fac4d;\n }\n .e_msg{\n display: inline;\n }\n .e2e_box:before{/*\u4F7F\u7528\u4F2A\u7C7B\u5143\u7D20,after \u548Cbefore\u90FD\u884C*/\n content:\"\";\n height:100%;\n display:inline-block;\n vertical-align:middle;\n }\n .e2e_box{\n position: fixed;\n left: 0px;\n right: 0px;\n top:0px;\n bottom:0px;\n background-color: rgba(0,0,0,0.4);z-index:9999;\n opacity: 1;\n text-align: center;/**\u4F7F\u5185\u8054\u5143\u7D20\u5C45\u4E2D**/\n }\n .e2e_donate_box{\n background: #fff;\n display:inline-block;/*\u8BBE\u7F6E\u4E3A\u5185\u8054\u5143\u7D20*/\n }\n .e2e_donate_box img{\n display: block;\n width: 400px;\n height: 622px;\n }\n .\n </style>\n "; $("body").append(css); var tools = "\n <a class=\"e2e_toolbar e2e_display e2e_enable\" id=\"e2e_enter\" href=\"javascript:;\" title=\"WX_E2E\">\uD83D\uDD10</a>\n <a class=\"e2e_toolbar\" id=\"e2e_state\" href=\"javascript:;\" title=\"\">\uD83D\uDD10</a>\n <a class=\"e2e_toolbar\" id=\"e2e_update_key\" href=\"javascript:;\" title=\"WX_E2E update key\">\u2699</a>\n <a class=\"e2e_toolbar\" id=\"e2e_donate\" href=\"javascript:;\" title=\"WX_E2E\u7ED9\u4F5C\u8005\u4E70\u4E00\u676F\u5496\u5561!\">\uD83D\uDCB0</a>\n <a class=\"e2e_toolbar\" id=\"e2e_exit\" href=\"javascript:;\" title=\"WX_E2E Exit\">\u274C</a>\n "; $("#tool_bar").append(tools); var e2e_box = "\n <div id=\"e2e_box\" class=\"e2e_box e2e_hide\">\n <div class=\"e2e_donate_box\"><img src=\"https://github.com/ygcaicn/wx_e2e/raw/master/alipay.jpg\"/></div>\n <p>\u4E07\u5206\u611F\u8C22</p>\n </div>\n "; $("body").append(e2e_box); $("#J_NavChatScrollBody").click(function () { log('click left'); var username = angular.element("#chatArea").scope().currentContact.UserName; if (angular.element("#chatArea").scope().currentContact.MMInChatroom) { ui_setState(0); $("#e2e_enter").attr("class", "e2e_toolbar e2e_hide e2e_disable"); return; } var ret = e2e_list.filter(function (item) { return item.username === username; }); if (ret.length == 1) { var e2e = ret[0]; ui_setState(e2e.state); } else { ui_setState(0); } }); $(".e2e_donate_box").css('margin-top', ((window.innerHeight - 630) / 2).toString() + 'px'); $("#e2e_donate").click(function () { $("#e2e_box").show(); }); $("#e2e_box").click(function (e) { e.preventDefault(); $("#e2e_box").hide(); }); $("#e2e_enter").click(function () { log('click e2e_enter'); if ($("#e2e_enter").attr("class").search('e2e_enable') >= 0) { var username = angular.element("#chatArea").scope().currentContact.UserName; e2e_enter(username); } }); $("#e2e_state").click(function () { log('click e2e_state'); if ($("#e2e_state").attr("class").search('e2e_enable') >= 0) { var username = angular.element("#chatArea").scope().currentContact.UserName; // 判断是否需要处理 var ret = e2e_list.filter(function (item) { return item.username === username; }); if (ret.length == 1) { var e2e = ret[0]; log('e2e state:' + e2e.state); if (e2e.state == 1 || e2e.state == 4) { e2e.enter_state_4(); ui_setState(4); return; } if (e2e.state == 2) { return; } if (e2e.state == 3) { alert("wx_e2e 已连接!"); return; } } } }); $("#e2e_update_key").click(function () { log('click e2e_update_key'); if ($("#e2e_update_key").attr("class").search('e2e_enable') >= 0) { alert("设置功能正在开发中!..."); } }); $("#e2e_exit").click(function () { if ($("#e2e_exit").attr("class").search('e2e_enable') >= 0) { var username = angular.element("#chatArea").scope().currentContact.UserName; e2e_exit(username); } }); ui_setState(0); }; // 设置ui状态 // state 状态号 e2e_enter e2e_state e2e_update_key e2e_exit // 0 原生状态 display,enable hide hide hide // 1 e2e未连接状态 diaplay,disable ❓ ⛔ display,enable 🔑 display,enable ❌ // 2 收到请求,待确认 display,disable ❇️ display,enable 🔑 display,enable ❌ // 3 连接成功 display,disable 🍻 ✅ 🔗 display,enable 🔑 display,enable ❌ // 4 发出请求,待对方确认 display,disable ⁉️ display,disable 🔑⚙ display,enable ❌ var ui_setState = function ui_setState(state) { var e2e = undefined; //判断是否已经进行初始化 if ($('#e2e_box').length === 0) { ui_init(); } if (state != 0) { var username = angular.element("#chatArea").scope().currentContact.UserName; var ret = e2e_list.filter(function (item) { return item.username === username; }); if (ret.length < 1) { log("严重错误,找不到e2e"); return; } e2e = ret[0]; } if (state == 0) { $("#e2e_enter").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_state").attr("class", "e2e_toolbar e2e_hide"); $("#e2e_update_key").attr("class", "e2e_toolbar e2e_hide"); $("#e2e_donate").attr("class", "e2e_toolbar e2e_hide"); $("#e2e_exit").attr("class", "e2e_toolbar e2e_hide"); angular.element('#editArea').scope().sendTextMessage = origsendTextMessage; return; } if (state == 1) { $("#e2e_enter").attr("class", "e2e_toolbar e2e_display e2e_disable"); $("#e2e_state").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_state").attr("title", "WX_E2E未连接,点击发送请求!"); $("#e2e_state").text('⛔'); $("#e2e_update_key").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_donate").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_exit").attr("class", "e2e_toolbar e2e_display e2e_enable"); angular.element('#editArea').scope().sendTextMessage = function () { return e2e.sendTextMessage(); }; return; } if (state == 2) { $("#e2e_enter").attr("class", "e2e_toolbar e2e_display e2e_disable"); $("#e2e_state").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_state").attr("title", "WX_E2E收到请求,点击查看!"); $("#e2e_state").text('❇️'); $("#e2e_update_key").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_donate").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_exit").attr("class", "e2e_toolbar e2e_display e2e_enable"); angular.element('#editArea').scope().sendTextMessage = function () { return e2e.sendTextMessage(); }; return; } if (state == 3) { $("#e2e_enter").attr("class", "e2e_toolbar e2e_display e2e_disable"); $("#e2e_state").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_state").attr("title", "WX_E2E连接成功!"); $("#e2e_state").text('🔗'); $("#e2e_donate").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_exit").attr("class", "e2e_toolbar e2e_display e2e_enable"); angular.element('#editArea').scope().sendTextMessage = function () { return e2e.sendTextMessage(); }; return; } if (state == 4) { $("#e2e_enter").attr("class", "e2e_toolbar e2e_display e2e_disable"); $("#e2e_state").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_state").attr("title", "WX_E2E已发出请求,待对方确认,点击再次发送请求!"); $("#e2e_state").text('⁉️ '); $("#e2e_donate").attr("class", "e2e_toolbar e2e_display e2e_enable"); $("#e2e_exit").attr("class", "e2e_toolbar e2e_display e2e_enable"); angular.element('#editArea').scope().sendTextMessage = function () { return e2e.sendTextMessage(); }; return; } }; (function () { log("wechat end to end encrypt by rsa."); // 拦截消息 intercept_response(function (msg) { return messageHandler(msg) || msg; }); // ui初始化 ui_init(); })(); })();