修复火箭工单过盾同步问题
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* 火箭云控 URL 解析(与 PHP HuojianUrlHelper 对齐)
|
||||
* 长链域名动态识别,禁止写死 v3.url66.me
|
||||
*/
|
||||
|
||||
const BUSINESS_PATH_NEEDLE = '/gds';
|
||||
const LINK_QUERY_PARAM = 'link';
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
*/
|
||||
function isHuojianLongLinkUrl(url) {
|
||||
if (!url || typeof url !== 'string') {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
if (!parsed.pathname.includes(BUSINESS_PATH_NEEDLE)) {
|
||||
return false;
|
||||
}
|
||||
const link = (parsed.searchParams.get(LINK_QUERY_PARAM) || '').trim();
|
||||
return link !== '';
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns {string}
|
||||
*/
|
||||
function extractHuojianBusinessHost(url) {
|
||||
if (!isHuojianLongLinkUrl(url)) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
return new URL(url).hostname.toLowerCase();
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns {string}
|
||||
*/
|
||||
function extractHuojianShareToken(url) {
|
||||
if (!url || typeof url !== 'string') {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
if (isHuojianLongLinkUrl(url)) {
|
||||
return (parsed.searchParams.get(LINK_QUERY_PARAM) || '').trim();
|
||||
}
|
||||
const path = parsed.pathname.replace(/^\/+|\/+$/g, '');
|
||||
if (path === '' || path.includes('/')) {
|
||||
return '';
|
||||
}
|
||||
if (/^[a-zA-Z0-9]+$/.test(path)) {
|
||||
return path;
|
||||
}
|
||||
} catch (_) {
|
||||
/* ignore */
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
*/
|
||||
function isHuojianShortEntryUrl(url) {
|
||||
if (isHuojianLongLinkUrl(url)) {
|
||||
return false;
|
||||
}
|
||||
return extractHuojianShareToken(url) !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 落地后补全 businessHostHint(多长链域名兼容)
|
||||
* @param {object} antiBot
|
||||
* @param {string} finalPageUrl
|
||||
*/
|
||||
function applyHuojianBusinessHostHint(antiBot, finalPageUrl) {
|
||||
if (!antiBot) {
|
||||
return antiBot;
|
||||
}
|
||||
const host = extractHuojianBusinessHost(finalPageUrl);
|
||||
if (host !== '') {
|
||||
antiBot.businessHostHint = host;
|
||||
console.log(`[Huojian] 落地业务域=${host} url=${finalPageUrl}`);
|
||||
}
|
||||
return antiBot;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isHuojianLongLinkUrl,
|
||||
extractHuojianBusinessHost,
|
||||
extractHuojianShareToken,
|
||||
isHuojianShortEntryUrl,
|
||||
applyHuojianBusinessHostHint,
|
||||
BUSINESS_PATH_NEEDLE,
|
||||
};
|
||||
@@ -55,7 +55,11 @@ const {
|
||||
} = require('./lib/session-store');
|
||||
const { resolveSessionContext, touchSessionIfPresent } = require('./lib/session-context');
|
||||
const { getProfileStats, profileExists } = require('./lib/profile-dir');
|
||||
const { runUiPagination } = require('./lib/ui-pagination-runner');
|
||||
const {
|
||||
isHuojianLongLinkUrl,
|
||||
isHuojianShortEntryUrl,
|
||||
applyHuojianBusinessHostHint,
|
||||
} = require('./lib/huojian-url');
|
||||
|
||||
const app = express();
|
||||
app.use(express.json({ limit: '50mb' }));
|
||||
@@ -269,10 +273,50 @@ function applyA2cPostCfDefaults(antiBot, pageUrl) {
|
||||
};
|
||||
}
|
||||
|
||||
/** 按 pageUrl 合并 antiBot(含 Whatshub / A2C 默认 postCf) */
|
||||
/**
|
||||
* 火箭短链 → 动态长链域 /gds?link=:PHP 未传 postCfReady* 时 Node 侧自动补全
|
||||
* @param {object} antiBot
|
||||
* @param {string} pageUrl
|
||||
*/
|
||||
function applyHuojianPostCfDefaults(antiBot, pageUrl) {
|
||||
if (!antiBot || !antiBot.enabled) {
|
||||
return antiBot;
|
||||
}
|
||||
if ((antiBot.postCfReadyUrlContains || '').trim()) {
|
||||
return antiBot;
|
||||
}
|
||||
|
||||
let shouldApply = false;
|
||||
const sessionKey = String(antiBot.sessionKey || '').toLowerCase();
|
||||
if (sessionKey.startsWith('huojian:')) {
|
||||
shouldApply = true;
|
||||
}
|
||||
if (isHuojianLongLinkUrl(pageUrl) || isHuojianShortEntryUrl(pageUrl)) {
|
||||
shouldApply = true;
|
||||
}
|
||||
|
||||
if (!shouldApply) {
|
||||
return antiBot;
|
||||
}
|
||||
|
||||
console.log('[CF] 火箭 自动启用 postCfReady 默认配置');
|
||||
return {
|
||||
...antiBot,
|
||||
postCfReadyUrlContains: '/gds',
|
||||
postCfReadySelector: '.el-message-box__input',
|
||||
postCfReadyTimeoutMs: antiBot.postCfReadyTimeoutMs || 45000,
|
||||
postCfSettleMs: antiBot.postCfSettleMs || 500,
|
||||
postCfSpaWaitMs: antiBot.postCfSpaWaitMs || 8000,
|
||||
};
|
||||
}
|
||||
|
||||
/** 按 pageUrl 合并 antiBot(含 Whatshub / A2C / 火箭 默认 postCf) */
|
||||
function resolveAntiBotForPage(rawAntiBot, pageUrl) {
|
||||
return applyA2cPostCfDefaults(
|
||||
applyWhatshubPostCfDefaults(resolveAntiBot(rawAntiBot), pageUrl),
|
||||
return applyHuojianPostCfDefaults(
|
||||
applyA2cPostCfDefaults(
|
||||
applyWhatshubPostCfDefaults(resolveAntiBot(rawAntiBot), pageUrl),
|
||||
pageUrl
|
||||
),
|
||||
pageUrl
|
||||
);
|
||||
}
|
||||
@@ -361,6 +405,9 @@ function isOnShortLinkNotBusiness(page, urlNeedle) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (urlNeedle && urlNeedle.includes('/gds')) {
|
||||
return !url.includes('/gds');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1218,6 +1265,7 @@ app.post('/api/auth-and-intercept', async (req, res) => {
|
||||
await navigateToPage(page, pageUrl);
|
||||
|
||||
let finalPageUrl = await waitForUrlSettled(page);
|
||||
applyHuojianBusinessHostHint(antiBot, finalPageUrl);
|
||||
if (finalPageUrl !== pageUrl) {
|
||||
console.log(`[URL解析] 浏览器落地: ${pageUrl} -> ${finalPageUrl}`);
|
||||
}
|
||||
@@ -1246,6 +1294,7 @@ app.post('/api/auth-and-intercept', async (req, res) => {
|
||||
}
|
||||
|
||||
finalPageUrl = page.url();
|
||||
applyHuojianBusinessHostHint(antiBot, finalPageUrl);
|
||||
touchSessionIfPresent(antiBot.sessionKey);
|
||||
|
||||
await awaitPostCfBusinessReady(page, antiBot, waitForUrlSettled, storedSession, pageUrl);
|
||||
@@ -1599,6 +1648,7 @@ app.post('/api/auth-intercept-and-paginate', async (req, res) => {
|
||||
await prepareWhatshubShortLinkBeforeNav(page, pageUrl, antiBot);
|
||||
await navigateToPage(page, pageUrl);
|
||||
let finalPageUrl = await waitForUrlSettled(page);
|
||||
applyHuojianBusinessHostHint(antiBot, finalPageUrl);
|
||||
|
||||
let interceptor;
|
||||
if (antiBot.enabled) {
|
||||
@@ -1623,6 +1673,7 @@ app.post('/api/auth-intercept-and-paginate', async (req, res) => {
|
||||
return;
|
||||
}
|
||||
finalPageUrl = page.url();
|
||||
applyHuojianBusinessHostHint(antiBot, finalPageUrl);
|
||||
touchSessionIfPresent(antiBot.sessionKey);
|
||||
|
||||
await awaitPostCfBusinessReady(page, antiBot, waitForUrlSettled, storedSession, pageUrl);
|
||||
|
||||
Reference in New Issue
Block a user