fix: recognize qdreader uid from response body
This commit is contained in:
@@ -55,7 +55,8 @@ Autman 插件保留快捷命令:
|
|||||||
## 验证清单
|
## 验证清单
|
||||||
|
|
||||||
- `node --check js/qdreader_cookie.js`
|
- `node --check js/qdreader_cookie.js`
|
||||||
- raw 地址返回 HTTP 200:
|
- `node tests/qdreader_cookie.test.mjs`
|
||||||
|
- raw 地址返回 HTTP 200:
|
||||||
- `conf/qdreader.conf`
|
- `conf/qdreader.conf`
|
||||||
- `js/qdreader_cookie.js`
|
- `js/qdreader_cookie.js`
|
||||||
- 订阅文本内容第一行是 `hostname = ...`,第二行是 rewrite rule。
|
- 订阅文本内容第一行是 `hostname = ...`,第二行是 rewrite rule。
|
||||||
|
|||||||
+22
-3
@@ -25,21 +25,40 @@ function parseCookie(cookie) {
|
|||||||
return jar
|
return jar
|
||||||
}
|
}
|
||||||
function b64decode(s) {
|
function b64decode(s) {
|
||||||
try { return decodeURIComponent(escape(atob(String(s || '')))) } catch (e) { return '' }
|
let raw = String(s || '').trim()
|
||||||
|
try { raw = decodeURIComponent(raw) } catch (e) {}
|
||||||
|
raw = raw.replace(/-/g, '+').replace(/_/g, '/')
|
||||||
|
while (raw.length % 4) raw += '='
|
||||||
|
try { return decodeURIComponent(escape(atob(raw))) } catch (e) { return '' }
|
||||||
}
|
}
|
||||||
function uidFromQDHeader(qdheader) {
|
function uidFromQDHeader(qdheader) {
|
||||||
const decoded = b64decode(qdheader)
|
const decoded = b64decode(qdheader)
|
||||||
return decoded ? String(decoded.split('|')[0] || '').trim() : ''
|
return decoded ? String(decoded.split('|')[0] || '').trim() : ''
|
||||||
}
|
}
|
||||||
function parseJson(s, def) { try { return JSON.parse(s) } catch (e) { return def } }
|
function parseJson(s, def) { try { return JSON.parse(s) } catch (e) { return def } }
|
||||||
|
function findUid(obj) {
|
||||||
|
if (!obj || typeof obj !== 'object') return ''
|
||||||
|
const keys = ['UserId', 'userId', 'UserID', 'userid', 'uid', 'UID']
|
||||||
|
for (const key of keys) {
|
||||||
|
const val = obj[key]
|
||||||
|
if (val !== undefined && val !== null && String(val).trim()) return String(val).trim()
|
||||||
|
}
|
||||||
|
for (const key in obj) {
|
||||||
|
const val = obj[key]
|
||||||
|
if (val && typeof val === 'object') {
|
||||||
|
const found = findUid(val)
|
||||||
|
if (found) return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
function getUid(cookie, body) {
|
function getUid(cookie, body) {
|
||||||
const jar = parseCookie(cookie)
|
const jar = parseCookie(cookie)
|
||||||
let uid = uidFromQDHeader(jar.QDHeader || jar.qdheader || jar.QDHEADER || '')
|
let uid = uidFromQDHeader(jar.QDHeader || jar.qdheader || jar.QDHEADER || '')
|
||||||
if (uid) return uid
|
if (uid) return uid
|
||||||
if (jar.uid) return String(jar.uid)
|
if (jar.uid) return String(jar.uid)
|
||||||
const obj = parseJson(body || '', null)
|
const obj = parseJson(body || '', null)
|
||||||
uid = obj && obj.Data && obj.Data.UserInfo && (obj.Data.UserInfo.UserId || obj.Data.UserInfo.userId)
|
return findUid(obj)
|
||||||
return uid ? String(uid) : ''
|
|
||||||
}
|
}
|
||||||
function notify(title, sub, msg, opts) {
|
function notify(title, sub, msg, opts) {
|
||||||
try { $notify(title, sub || '', msg || '', opts || {}) } catch (e) { $notify(title, sub || '', msg || '') }
|
try { $notify(title, sub || '', msg || '', opts || {}) } catch (e) { $notify(title, sub || '', msg || '') }
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import vm from 'node:vm';
|
||||||
|
|
||||||
|
const code = fs.readFileSync(new URL('../js/qdreader_cookie.js', import.meta.url), 'utf8');
|
||||||
|
|
||||||
|
function run({ cookie = '', body = '' }) {
|
||||||
|
const notices = [];
|
||||||
|
const context = {
|
||||||
|
$request: { headers: { Cookie: cookie } },
|
||||||
|
$response: { body },
|
||||||
|
$notify: (...args) => notices.push(args),
|
||||||
|
$done: () => {},
|
||||||
|
atob: (s) => Buffer.from(s, 'base64').toString('binary'),
|
||||||
|
encodeURIComponent,
|
||||||
|
decodeURIComponent,
|
||||||
|
escape,
|
||||||
|
};
|
||||||
|
vm.runInNewContext(code, context);
|
||||||
|
return notices;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const qdheader = Buffer.from('123456|device|more').toString('base64').replace(/=+$/, '');
|
||||||
|
const notices = run({ cookie: `QDHeader=${encodeURIComponent(qdheader)}; QDH=abc` });
|
||||||
|
assert.equal(notices[0][1], '抓取成功 uid:123456');
|
||||||
|
assert.match(notices[0][2], /^启点ck /);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const notices = run({
|
||||||
|
cookie: 'cmfuToken=abc; QDH=def',
|
||||||
|
body: JSON.stringify({ Data: { UserId: 987654 } }),
|
||||||
|
});
|
||||||
|
assert.equal(notices[0][1], '抓取成功 uid:987654');
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const notices = run({
|
||||||
|
cookie: 'cmfuToken=abc; QDH=def',
|
||||||
|
body: JSON.stringify({ Data: { UserInfo: { UserId: 2468 } } }),
|
||||||
|
});
|
||||||
|
assert.equal(notices[0][1], '抓取成功 uid:2468');
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const notices = run({ cookie: 'cmfuToken=abc; QDH=def', body: '{}' });
|
||||||
|
assert.equal(notices[0][1], 'Cookie 获取失败');
|
||||||
|
assert.match(notices[0][2], /无法识别 uid/);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('ok - qdreader qx uid parsing');
|
||||||
Reference in New Issue
Block a user