From 56bfb7102eb70dbfabcdc8c93219f9e799ceaa4d Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 17 May 2026 21:02:13 +0800 Subject: [PATCH] fix: store qdreader remarks by saved uid --- js/qdreader_sign_autman.js | 87 +++++++++++++++++------- plugins/qdreader/qdreader_sign_autman.js | 87 +++++++++++++++++------- tests/qdreader_plugin.test.mjs | 42 ++++++++++++ 3 files changed, 164 insertions(+), 52 deletions(-) diff --git a/js/qdreader_sign_autman.js b/js/qdreader_sign_autman.js index 1c6ca86..363a98d 100644 --- a/js/qdreader_sign_autman.js +++ b/js/qdreader_sign_autman.js @@ -4,7 +4,7 @@ //[author: Hermes] //[service: BOSS] //[class: 工具类] -//[version: 2.3.8] +//[version: 2.3.9] //[platform: web,qq,wx,tg,tb,fs,we] //[public: false] //[price: 0] @@ -89,6 +89,24 @@ function getBindStore() { return cleanStringMap(safeJsonParse(cfgGet(BIND_KEY, " function setBindStore(obj) { return cfgSet(BIND_KEY, JSON.stringify(obj || {})) } function getRemarkStore() { return cleanStringMap(safeJsonParse(cfgGet(REMARK_KEY, "{}"), {})) } function setRemarkStore(obj) { return cfgSet(REMARK_KEY, JSON.stringify(obj || {})) } +function cookieGuid(cookie) { + var jar = parseCookieString(cookie) + return trim(jar.ywguid || jar.gwguid || jar.guid || "") +} +function remarksForStore(store) { + var remarks = getRemarkStore() + var changed = false + for (var uid in (store || {})) if (store.hasOwnProperty(uid)) { + var guid = cookieGuid(store[uid]) + if (guid && guid !== uid && remarks[guid] && !remarks[uid]) { + remarks[uid] = remarks[guid] + delete remarks[guid] + changed = true + } + } + if (changed) setRemarkStore(remarks) + return remarks +} function callNoArg(obj, name) { try { if (obj && typeof obj[name] === "function") return obj[name]() } catch (e) {} return "" @@ -148,7 +166,23 @@ function b64decode(s) { s = s.replace(/-/g, "+").replace(/_/g, "/") while (s.length % 4) s += "=" try { if (typeof Buffer !== "undefined") return Buffer.from(s, "base64").toString("utf8") } catch (e) {} - try { return decodeURIComponent(escape(atob(s))) } catch (e) { return "" } + try { if (typeof atob === "function") return decodeURIComponent(escape(atob(s))) } catch (e) {} + try { + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" + var output = "", buffer = 0, bits = 0 + for (var i = 0; i < s.length; i++) { + var c = chars.indexOf(s.charAt(i)) + if (c < 0) continue + if (c === 64) break + buffer = (buffer << 6) | c + bits += 6 + if (bits >= 8) { + bits -= 8 + output += String.fromCharCode((buffer >> bits) & 0xff) + } + } + try { return decodeURIComponent(escape(output)) } catch (e2) { return output } + } catch (e3) { return "" } } function isRealUid(uid) { uid = String(uid === undefined || uid === null ? "" : uid).trim() @@ -199,7 +233,7 @@ function contentText() { } function usage() { return [ - "启点读书签到插件 v2.3.8", + "启点读书签到插件 v2.3.9", "【一级菜单】", "账号管理:启点账号", "执行查询:启点查询", @@ -366,7 +400,7 @@ function signAll(targetUid, allUsers, source) { var runId = startedAt.replace(/[-:.TZ]/g, "").slice(0, 14) + "_" + source var store = getStore() var bind = getBindStore() - var remarks = getRemarkStore() + var remarks = remarksForStore(store) var uids = visibleUids(store, bind, !!allUsers) if (targetUid) uids = uids.filter(function (u) { return u === targetUid }) if (!uids.length) { @@ -412,7 +446,7 @@ function queryStatus(targetUid) { var bind = getBindStore() var last = getLastResults() var run = getLastRunLog() - var remarks = getRemarkStore() + var remarks = remarksForStore(store) var uids = visibleUids(store, bind, false) if (targetUid) { if (uids.indexOf(targetUid) < 0) return store[targetUid] ? ("无权查询 uid: " + targetUid) : ("未找到 uid: " + targetUid) @@ -454,7 +488,7 @@ function queryMenuText() { } function accountListText(store, bind) { var uids = visibleUids(store, bind, false) - var remarks = getRemarkStore() + var remarks = remarksForStore(store) if (!uids.length) return "当前用户还没有保存启点读书CK" var lines = ["启点账号:当前用户共 " + uids.length + " 个账号"] for (var i = 0; i < uids.length; i++) { @@ -468,7 +502,7 @@ function accountListText(store, bind) { function accountSelectText(store, bind, title) { var uids = visibleUids(store, bind, false) - var remarks = getRemarkStore() + var remarks = remarksForStore(store) if (!uids.length) return { text: "当前用户还没有保存启点读书CK", uids: [] } var lines = [title || "请选择账号:"] for (var i = 0; i < uids.length; i++) { @@ -489,12 +523,12 @@ function chooseUid(store, bind, title) { if (isNaN(n) || n < 1 || n > sel.uids.length) { reply("编号无效,已退出"); return "" } return sel.uids[n - 1] } -function maybePromptRemark(uid) { +function maybePromptRemark(uid, store) { if (!uid) return "" reply("是否为该账号添加备注?回复备注名,发送 n/跳过 则不添加") var remark = listenInput(60000) if (!remark || /^(n|no|否|不|跳过|q|退出|取消)$/i.test(remark)) return "" - var remarks = getRemarkStore() + var remarks = store ? remarksForStore(store) : getRemarkStore() remarks[uid] = remark.slice(0, 30) setRemarkStore(remarks) return "\n备注: " + remarks[uid] @@ -502,7 +536,7 @@ function maybePromptRemark(uid) { function accountDetailText(uid, store, bind) { var uids = visibleUids(store, bind, false) if (uids.indexOf(uid) < 0) return store[uid] ? ("无权查看 uid: " + uid) : ("未找到 uid: " + uid) - var remarks = getRemarkStore() + var remarks = remarksForStore(store) var last = getLastResults() return [ "启点账号详情:", @@ -521,7 +555,7 @@ function accountDetailMenu(store, bind) { if (/^(无权|未找到)/.test(detail)) return var remark = listenInput(60000) if (!remark || /^(q|退出|取消)$/i.test(remark)) return reply("已退出") - var remarks = getRemarkStore() + var remarks = remarksForStore(store) if (/^(清空|删除|none)$/i.test(remark)) delete remarks[uid]; else remarks[uid] = remark.slice(0, 30) setRemarkStore(remarks) return reply("已更新备注:" + maskUid(uid) + (remarks[uid] ? "(" + remarks[uid] + ")" : "")) @@ -535,10 +569,9 @@ function accountMenu(store, bind) { reply("请在60秒内发送 QX 抓到的完整 Cookie(q:退出)") var ck = listenInput(60000) if (!ck || /^(q|退出|取消)$/i.test(ck)) return reply("已退出") - var uid = extractUid(ck) - var msg = handleSaveCookie(ck, store, bind) - var remarkMsg = uid ? maybePromptRemark(uid) : "" - return reply(msg + remarkMsg) + var save = handleSaveCookie(ck, store, bind) + var remarkMsg = (save.ok && save.uids.length === 1) ? maybePromptRemark(save.uids[0], store) : "" + return reply(save.text + remarkMsg) } if (/^(3|详情|备注|改名|名称)$/i.test(op)) return accountDetailMenu(store, bind) if (/^(4|删除)$/i.test(op)) { @@ -571,13 +604,13 @@ function handleDelete(arg, store, bind) { var uids = visibleUids(store, bind, false) if (/^(all|全部|所有)$/i.test(duid)) { for (var i = 0; i < uids.length; i++) { delete store[uids[i]]; delete bind[uids[i]] } - var remarks = getRemarkStore(); for (var j = 0; j < uids.length; j++) delete remarks[uids[j]] + var remarks = remarksForStore(store); for (var j = 0; j < uids.length; j++) delete remarks[uids[j]] setStore(store); setBindStore(bind); setRemarkStore(remarks) return "已删除全部当前用户绑定的启点读书CK,共 " + uids.length + " 个账号" } if (uids.indexOf(duid) < 0) return store[duid] ? ("无权删除 uid: " + duid) : ("未找到 uid: " + duid) delete store[duid]; delete bind[duid] - var remarks = getRemarkStore(); delete remarks[duid] + var remarks = remarksForStore(store); delete remarks[duid] setStore(store); setBindStore(bind); setRemarkStore(remarks) return "已删除 uid: " + duid } @@ -598,15 +631,16 @@ function normalizeCookieInput(arg) { } function handleSaveCookie(arg, store, bind) { var entries = normalizeCookieInput(arg) - if (!entries.length) return "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck " + if (!entries.length) return { ok: false, text: "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck ", uids: [] } var me = currentOwnerId() var lines = [] + var savedUids = [] for (var i = 0; i < entries.length; i++) { var cookie = entries[i].cookie - if (cookie.indexOf("=") < 0 || cookie.indexOf(";") < 0) return "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck " + if (cookie.indexOf("=") < 0 || cookie.indexOf(";") < 0) return { ok: false, text: "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck ", uids: savedUids } var parsedUid = extractUid(cookie) var uid = entries[i].uid || parsedUid - if (!uid) return "无法从 Cookie 识别 uid。请确认 QX 抓的是启点读书福利中心 getlogininfo 请求,Cookie 内应包含 QDHeader 或 uid。" + if (!uid) return { ok: false, text: "无法从 Cookie 识别 uid。请确认 QX 抓的是启点读书福利中心 getlogininfo 请求,Cookie 内应包含 QDHeader 或 uid。", uids: savedUids } var isNew = !store[uid] var oldOwner = bind[uid] || "" if (store[uid] && oldOwner && me && oldOwner !== me) { @@ -616,6 +650,7 @@ function handleSaveCookie(arg, store, bind) { var changed = store[uid] !== cookie store[uid] = cookie bind[uid] = me + savedUids.push(uid) lines.push("启点读书CK" + (isNew ? "新增" : (changed ? "更新" : "未变化")) + "成功") lines.push("uid: " + uid) if (entries.length > 1 && parsedUid && parsedUid !== uid) lines.push("提示: JSON uid 与 Cookie 解析 uid 不一致,已按 JSON uid 保存") @@ -625,7 +660,7 @@ function handleSaveCookie(arg, store, bind) { lines.push("账号数: " + visibleUids(store, bind, false).length) lines.push("cookie: " + maskCookie(entries[0].cookie)) lines.push("签到:发送 启点签到") - return lines.join("\n") + return { ok: savedUids.length > 0, text: lines.join("\n"), uids: savedUids } } function main() { var text = contentText() @@ -649,12 +684,12 @@ function main() { var delMsg = handleDelete(arg, store, bind) if (delMsg !== null) { reply(delMsg); return } if (cmd === "ck") { - var saveUid = extractUid(arg) - var saveMsg = handleSaveCookie(arg, store, bind) - if (/成功|未变化/.test(saveMsg) && saveUid) saveMsg += maybePromptRemark(saveUid) - reply(saveMsg) + var save = handleSaveCookie(arg, store, bind) + if (save.ok && save.uids.length === 1) save.text += maybePromptRemark(save.uids[0], store) + reply(save.text) return } - reply(handleSaveCookie(arg, store, bind)) + var fallbackSave = handleSaveCookie(arg, store, bind) + reply(fallbackSave.text) } main() diff --git a/plugins/qdreader/qdreader_sign_autman.js b/plugins/qdreader/qdreader_sign_autman.js index 1c6ca86..363a98d 100644 --- a/plugins/qdreader/qdreader_sign_autman.js +++ b/plugins/qdreader/qdreader_sign_autman.js @@ -4,7 +4,7 @@ //[author: Hermes] //[service: BOSS] //[class: 工具类] -//[version: 2.3.8] +//[version: 2.3.9] //[platform: web,qq,wx,tg,tb,fs,we] //[public: false] //[price: 0] @@ -89,6 +89,24 @@ function getBindStore() { return cleanStringMap(safeJsonParse(cfgGet(BIND_KEY, " function setBindStore(obj) { return cfgSet(BIND_KEY, JSON.stringify(obj || {})) } function getRemarkStore() { return cleanStringMap(safeJsonParse(cfgGet(REMARK_KEY, "{}"), {})) } function setRemarkStore(obj) { return cfgSet(REMARK_KEY, JSON.stringify(obj || {})) } +function cookieGuid(cookie) { + var jar = parseCookieString(cookie) + return trim(jar.ywguid || jar.gwguid || jar.guid || "") +} +function remarksForStore(store) { + var remarks = getRemarkStore() + var changed = false + for (var uid in (store || {})) if (store.hasOwnProperty(uid)) { + var guid = cookieGuid(store[uid]) + if (guid && guid !== uid && remarks[guid] && !remarks[uid]) { + remarks[uid] = remarks[guid] + delete remarks[guid] + changed = true + } + } + if (changed) setRemarkStore(remarks) + return remarks +} function callNoArg(obj, name) { try { if (obj && typeof obj[name] === "function") return obj[name]() } catch (e) {} return "" @@ -148,7 +166,23 @@ function b64decode(s) { s = s.replace(/-/g, "+").replace(/_/g, "/") while (s.length % 4) s += "=" try { if (typeof Buffer !== "undefined") return Buffer.from(s, "base64").toString("utf8") } catch (e) {} - try { return decodeURIComponent(escape(atob(s))) } catch (e) { return "" } + try { if (typeof atob === "function") return decodeURIComponent(escape(atob(s))) } catch (e) {} + try { + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" + var output = "", buffer = 0, bits = 0 + for (var i = 0; i < s.length; i++) { + var c = chars.indexOf(s.charAt(i)) + if (c < 0) continue + if (c === 64) break + buffer = (buffer << 6) | c + bits += 6 + if (bits >= 8) { + bits -= 8 + output += String.fromCharCode((buffer >> bits) & 0xff) + } + } + try { return decodeURIComponent(escape(output)) } catch (e2) { return output } + } catch (e3) { return "" } } function isRealUid(uid) { uid = String(uid === undefined || uid === null ? "" : uid).trim() @@ -199,7 +233,7 @@ function contentText() { } function usage() { return [ - "启点读书签到插件 v2.3.8", + "启点读书签到插件 v2.3.9", "【一级菜单】", "账号管理:启点账号", "执行查询:启点查询", @@ -366,7 +400,7 @@ function signAll(targetUid, allUsers, source) { var runId = startedAt.replace(/[-:.TZ]/g, "").slice(0, 14) + "_" + source var store = getStore() var bind = getBindStore() - var remarks = getRemarkStore() + var remarks = remarksForStore(store) var uids = visibleUids(store, bind, !!allUsers) if (targetUid) uids = uids.filter(function (u) { return u === targetUid }) if (!uids.length) { @@ -412,7 +446,7 @@ function queryStatus(targetUid) { var bind = getBindStore() var last = getLastResults() var run = getLastRunLog() - var remarks = getRemarkStore() + var remarks = remarksForStore(store) var uids = visibleUids(store, bind, false) if (targetUid) { if (uids.indexOf(targetUid) < 0) return store[targetUid] ? ("无权查询 uid: " + targetUid) : ("未找到 uid: " + targetUid) @@ -454,7 +488,7 @@ function queryMenuText() { } function accountListText(store, bind) { var uids = visibleUids(store, bind, false) - var remarks = getRemarkStore() + var remarks = remarksForStore(store) if (!uids.length) return "当前用户还没有保存启点读书CK" var lines = ["启点账号:当前用户共 " + uids.length + " 个账号"] for (var i = 0; i < uids.length; i++) { @@ -468,7 +502,7 @@ function accountListText(store, bind) { function accountSelectText(store, bind, title) { var uids = visibleUids(store, bind, false) - var remarks = getRemarkStore() + var remarks = remarksForStore(store) if (!uids.length) return { text: "当前用户还没有保存启点读书CK", uids: [] } var lines = [title || "请选择账号:"] for (var i = 0; i < uids.length; i++) { @@ -489,12 +523,12 @@ function chooseUid(store, bind, title) { if (isNaN(n) || n < 1 || n > sel.uids.length) { reply("编号无效,已退出"); return "" } return sel.uids[n - 1] } -function maybePromptRemark(uid) { +function maybePromptRemark(uid, store) { if (!uid) return "" reply("是否为该账号添加备注?回复备注名,发送 n/跳过 则不添加") var remark = listenInput(60000) if (!remark || /^(n|no|否|不|跳过|q|退出|取消)$/i.test(remark)) return "" - var remarks = getRemarkStore() + var remarks = store ? remarksForStore(store) : getRemarkStore() remarks[uid] = remark.slice(0, 30) setRemarkStore(remarks) return "\n备注: " + remarks[uid] @@ -502,7 +536,7 @@ function maybePromptRemark(uid) { function accountDetailText(uid, store, bind) { var uids = visibleUids(store, bind, false) if (uids.indexOf(uid) < 0) return store[uid] ? ("无权查看 uid: " + uid) : ("未找到 uid: " + uid) - var remarks = getRemarkStore() + var remarks = remarksForStore(store) var last = getLastResults() return [ "启点账号详情:", @@ -521,7 +555,7 @@ function accountDetailMenu(store, bind) { if (/^(无权|未找到)/.test(detail)) return var remark = listenInput(60000) if (!remark || /^(q|退出|取消)$/i.test(remark)) return reply("已退出") - var remarks = getRemarkStore() + var remarks = remarksForStore(store) if (/^(清空|删除|none)$/i.test(remark)) delete remarks[uid]; else remarks[uid] = remark.slice(0, 30) setRemarkStore(remarks) return reply("已更新备注:" + maskUid(uid) + (remarks[uid] ? "(" + remarks[uid] + ")" : "")) @@ -535,10 +569,9 @@ function accountMenu(store, bind) { reply("请在60秒内发送 QX 抓到的完整 Cookie(q:退出)") var ck = listenInput(60000) if (!ck || /^(q|退出|取消)$/i.test(ck)) return reply("已退出") - var uid = extractUid(ck) - var msg = handleSaveCookie(ck, store, bind) - var remarkMsg = uid ? maybePromptRemark(uid) : "" - return reply(msg + remarkMsg) + var save = handleSaveCookie(ck, store, bind) + var remarkMsg = (save.ok && save.uids.length === 1) ? maybePromptRemark(save.uids[0], store) : "" + return reply(save.text + remarkMsg) } if (/^(3|详情|备注|改名|名称)$/i.test(op)) return accountDetailMenu(store, bind) if (/^(4|删除)$/i.test(op)) { @@ -571,13 +604,13 @@ function handleDelete(arg, store, bind) { var uids = visibleUids(store, bind, false) if (/^(all|全部|所有)$/i.test(duid)) { for (var i = 0; i < uids.length; i++) { delete store[uids[i]]; delete bind[uids[i]] } - var remarks = getRemarkStore(); for (var j = 0; j < uids.length; j++) delete remarks[uids[j]] + var remarks = remarksForStore(store); for (var j = 0; j < uids.length; j++) delete remarks[uids[j]] setStore(store); setBindStore(bind); setRemarkStore(remarks) return "已删除全部当前用户绑定的启点读书CK,共 " + uids.length + " 个账号" } if (uids.indexOf(duid) < 0) return store[duid] ? ("无权删除 uid: " + duid) : ("未找到 uid: " + duid) delete store[duid]; delete bind[duid] - var remarks = getRemarkStore(); delete remarks[duid] + var remarks = remarksForStore(store); delete remarks[duid] setStore(store); setBindStore(bind); setRemarkStore(remarks) return "已删除 uid: " + duid } @@ -598,15 +631,16 @@ function normalizeCookieInput(arg) { } function handleSaveCookie(arg, store, bind) { var entries = normalizeCookieInput(arg) - if (!entries.length) return "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck " + if (!entries.length) return { ok: false, text: "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck ", uids: [] } var me = currentOwnerId() var lines = [] + var savedUids = [] for (var i = 0; i < entries.length; i++) { var cookie = entries[i].cookie - if (cookie.indexOf("=") < 0 || cookie.indexOf(";") < 0) return "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck " + if (cookie.indexOf("=") < 0 || cookie.indexOf(";") < 0) return { ok: false, text: "未识别到 Cookie。请发送:启点ck {\"uid\":\"cookie\"} 或 启点ck ", uids: savedUids } var parsedUid = extractUid(cookie) var uid = entries[i].uid || parsedUid - if (!uid) return "无法从 Cookie 识别 uid。请确认 QX 抓的是启点读书福利中心 getlogininfo 请求,Cookie 内应包含 QDHeader 或 uid。" + if (!uid) return { ok: false, text: "无法从 Cookie 识别 uid。请确认 QX 抓的是启点读书福利中心 getlogininfo 请求,Cookie 内应包含 QDHeader 或 uid。", uids: savedUids } var isNew = !store[uid] var oldOwner = bind[uid] || "" if (store[uid] && oldOwner && me && oldOwner !== me) { @@ -616,6 +650,7 @@ function handleSaveCookie(arg, store, bind) { var changed = store[uid] !== cookie store[uid] = cookie bind[uid] = me + savedUids.push(uid) lines.push("启点读书CK" + (isNew ? "新增" : (changed ? "更新" : "未变化")) + "成功") lines.push("uid: " + uid) if (entries.length > 1 && parsedUid && parsedUid !== uid) lines.push("提示: JSON uid 与 Cookie 解析 uid 不一致,已按 JSON uid 保存") @@ -625,7 +660,7 @@ function handleSaveCookie(arg, store, bind) { lines.push("账号数: " + visibleUids(store, bind, false).length) lines.push("cookie: " + maskCookie(entries[0].cookie)) lines.push("签到:发送 启点签到") - return lines.join("\n") + return { ok: savedUids.length > 0, text: lines.join("\n"), uids: savedUids } } function main() { var text = contentText() @@ -649,12 +684,12 @@ function main() { var delMsg = handleDelete(arg, store, bind) if (delMsg !== null) { reply(delMsg); return } if (cmd === "ck") { - var saveUid = extractUid(arg) - var saveMsg = handleSaveCookie(arg, store, bind) - if (/成功|未变化/.test(saveMsg) && saveUid) saveMsg += maybePromptRemark(saveUid) - reply(saveMsg) + var save = handleSaveCookie(arg, store, bind) + if (save.ok && save.uids.length === 1) save.text += maybePromptRemark(save.uids[0], store) + reply(save.text) return } - reply(handleSaveCookie(arg, store, bind)) + var fallbackSave = handleSaveCookie(arg, store, bind) + reply(fallbackSave.text) } main() diff --git a/tests/qdreader_plugin.test.mjs b/tests/qdreader_plugin.test.mjs index f440c9b..a76b2a3 100644 --- a/tests/qdreader_plugin.test.mjs +++ b/tests/qdreader_plugin.test.mjs @@ -100,6 +100,48 @@ test('quick submit prompts remark after saving cookie', () => { assert.equal(JSON.parse(r.store.qdreader_remark_json)['12345'], '主号'); }); +test('quick submit remark uses saved QDHeader uid instead of ywguid', () => { + const streamQdheader = 'KG51bGwpfChudWxsKXwxMTc5fDI1NTZ8KG51bGwpfDE2LjEwfDB8aU9TL2lQaG9uZS8obnVsbCl8MHwobnVsbCl8KG51bGwpfDQ3NTcwMDk3NXwxNzc5MDA5MTM2MDAwfDB8KG51bGwpfHx8KG51bGwpfChudWxsKXww'; + const streamCookie = `QDHeader=${streamQdheader}; ywguid=120098575768; qdh=qdh; sessionyw=s; appId=12`; + const r = runPlugin({ content: '启点ck ' + streamCookie, userId: 'user-a', listens: ['01'] }); + assert.match(r.replies.join('\n'), /uid: 475700975/); + assert.equal(JSON.parse(r.store.qdreader_cookie_json)['475700975'], streamCookie); + assert.equal(JSON.parse(r.store.qdreader_remark_json)['475700975'], '01'); + assert.equal(JSON.parse(r.store.qdreader_remark_json)['120098575768'], undefined); +}); + +test('quick submit can decode QDHeader uid without Buffer or atob', () => { + const streamQdheader = 'KG51bGwpfChudWxsKXwxMTc5fDI1NTZ8KG51bGwpfDE2LjEwfDB8aU9TL2lQaG9uZS8obnVsbCl8MHwobnVsbCl8KG51bGwpfDQ3NTcwMDk3NXwxNzc5MDA5MTM2MDAwfDB8KG51bGwpfHx8KG51bGwpfChudWxsKXww'; + const streamCookie = `QDHeader=${streamQdheader}; ywguid=120098575768; qdh=qdh; sessionyw=s; appId=12`; + const r = runPlugin({ content: '启点ck ' + streamCookie, globals: { Buffer: undefined, atob: undefined }, listens: ['n'] }); + assert.match(r.replies.join('\n'), /uid: 475700975/); + assert.equal(JSON.parse(r.store.qdreader_cookie_json)['475700975'], streamCookie); + assert.equal(JSON.parse(r.store.qdreader_cookie_json)['120098575768'], undefined); +}); + +test('account menu add remark uses saved QDHeader uid instead of ywguid', () => { + const streamQdheader = 'KG51bGwpfChudWxsKXwxMTc5fDI1NTZ8KG51bGwpfDE2LjEwfDB8aU9TL2lQaG9uZS8obnVsbCl8MHwobnVsbCl8KG51bGwpfDQ3NTcwMDk3NXwxNzc5MDA5MTM2MDAwfDB8KG51bGwpfHx8KG51bGwpfChudWxsKXww'; + const streamCookie = `QDHeader=${streamQdheader}; ywguid=120098575768; qdh=qdh; sessionyw=s; appId=12`; + const r = runPlugin({ content: '启点账号', userId: 'user-a', listens: ['2', streamCookie, '01'] }); + assert.match(r.replies.join('\n'), /uid: 475700975/); + assert.equal(JSON.parse(r.store.qdreader_remark_json)['475700975'], '01'); + assert.equal(JSON.parse(r.store.qdreader_remark_json)['120098575768'], undefined); +}); + +test('mis-keyed ywguid remark is migrated to saved uid on account list', () => { + const streamQdheader = 'KG51bGwpfChudWxsKXwxMTc5fDI1NTZ8KG51bGwpfDE2LjEwfDB8aU9TL2lQaG9uZS8obnVsbCl8MHwobnVsbCl8KG51bGwpfDQ3NTcwMDk3NXwxNzc5MDA5MTM2MDAwfDB8KG51bGwpfHx8KG51bGwpfChudWxsKXww'; + const streamCookie = `QDHeader=${streamQdheader}; ywguid=120098575768; qdh=qdh; sessionyw=s; appId=12`; + const store = { + qdreader_cookie_json: JSON.stringify({ '475700975': streamCookie }), + qdreader_user_bind_json: JSON.stringify({ '475700975': 'user-a' }), + qdreader_remark_json: JSON.stringify({ '120098575768': '01' }), + }; + const r = runPlugin({ content: '启点账号', store, userId: 'user-a', listens: ['1'] }); + assert.match(r.replies.join('\n'), /01/); + assert.equal(JSON.parse(r.store.qdreader_remark_json)['475700975'], '01'); + assert.equal(JSON.parse(r.store.qdreader_remark_json)['120098575768'], undefined); +}); + test('quick submit can bind user from alternate Autman sender fields', () => { const r = runPlugin({ content: '启点ck ' + cookie,