- vm_api.py: pure FastAPI JSON API on :8098 with CORS - vm-api.service: systemd unit for API (replaces inline HTML vm_web.py for frontend) - vm_web.py: kept intact as fallback; Apache now proxies /api/ -> :8098 - frontend/: Vite + React + TanStack Query scaffold - Apache vhost updated: DocumentRoot -> frontend/dist, /api/ proxy, SPA fallback - All original HTML pages still functional via :8099 during transition
283 lines
7.7 KiB
JavaScript
283 lines
7.7 KiB
JavaScript
// src/patterns.json
|
|
var patterns_default = [
|
|
" daum[ /]",
|
|
" deusu/",
|
|
"(?:^|[^g])news(?!sapphire)",
|
|
"(?<! channel/|google/)google(?!(?:wv|app|/google| pixel))",
|
|
"(?<! cu)bots?(?:\\b|_)",
|
|
"(?<!cam)scan",
|
|
"(?<!lib)http",
|
|
"24x7",
|
|
";\\s\\w+;$",
|
|
"@[a-z][\\w-]+\\.",
|
|
"\\(\\)",
|
|
"\\.com\\b",
|
|
"\\b\\w+\\.ai",
|
|
"\\bbw/",
|
|
"\\bdlc\\b",
|
|
"\\bort/",
|
|
"\\bperl\\b",
|
|
"\\btime/",
|
|
"\\|",
|
|
"^[<\\(;]",
|
|
"^[\\w \\.\\-\\(?:\\):%]+(?:/v?\\d+(?:\\.\\d+)?(?:\\.\\d{1,10})*?)?(?:,|$)",
|
|
"^[\\w\\-]+/[\\w]+$",
|
|
"^[^ ]{50,}$",
|
|
"^\\d+\\b",
|
|
"^\\w*search\\b",
|
|
"^\\w+/[\\w\\(\\)]*$",
|
|
"^\\w+/\\d\\.\\d\\s\\([\\w@]+\\)$",
|
|
"^active",
|
|
"^ad muncher",
|
|
"^amaya",
|
|
"^apache/",
|
|
"^avsdevicesdk/",
|
|
"^azure",
|
|
"^biglotron",
|
|
"^blackbox exporter",
|
|
"^bot",
|
|
"^clamav[ /]",
|
|
"^claude-code/",
|
|
"^client/",
|
|
"^cobweb/",
|
|
"^custom",
|
|
"^ddg[_-]android",
|
|
"^discourse",
|
|
"^dispatch/\\d",
|
|
"^downcast/",
|
|
"^duckduckgo",
|
|
"^email",
|
|
"^exodusmovement",
|
|
"^facebook",
|
|
"^getright/",
|
|
"^gozilla/",
|
|
"^hobbit",
|
|
"^hotzonu",
|
|
"^hwcdn/",
|
|
"^igetter/",
|
|
"^jeode/",
|
|
"^jetty/",
|
|
"^jigsaw",
|
|
"^microsoft bits",
|
|
"^movabletype",
|
|
"^mozilla/\\d\\.\\d\\s[\\w\\.-]+$",
|
|
"^mozilla/\\d\\.\\d\\s\\((?:compatible;)?(?:\\s?[\\w\\d-.]+\\/\\d+\\.\\d+)?\\)$",
|
|
"^navermailapp",
|
|
"^netsurf",
|
|
"^offline",
|
|
"^openai/",
|
|
"^owler",
|
|
"^php",
|
|
"^postman",
|
|
"^ps_daily/",
|
|
"^python",
|
|
"^rank",
|
|
"^read",
|
|
"^reed",
|
|
"^remove\\.bg/",
|
|
"^rest",
|
|
"^rss",
|
|
"^snapchat",
|
|
"^sora ",
|
|
"^space bison",
|
|
"^stape/",
|
|
"^svn",
|
|
"^swcd ",
|
|
"^taringa",
|
|
"^thumbor/",
|
|
"^track",
|
|
"^w3c",
|
|
"^webbandit/",
|
|
"^webcopier",
|
|
"^wget",
|
|
"^whatsapp",
|
|
"^wordpress",
|
|
"^xenu link sleuth",
|
|
"^yahoo",
|
|
"^yandex",
|
|
"^zdm/\\d",
|
|
"^zoom marketplace/",
|
|
"abuse",
|
|
"advisor",
|
|
"agent\\b",
|
|
"analyzer",
|
|
"archive",
|
|
"ask jeeves/teoma",
|
|
"attracta",
|
|
"audit",
|
|
"bluecoat drtr",
|
|
"browsex",
|
|
"burpcollaborator",
|
|
"capture",
|
|
"catch",
|
|
"check\\b",
|
|
"checker",
|
|
"chrome-lighthouse",
|
|
"chromeframe",
|
|
"classifier",
|
|
"cloudflare",
|
|
"collapsify\\b",
|
|
"convertify",
|
|
"cookiehubverify/",
|
|
"crawl",
|
|
"cursor/",
|
|
"cypress/",
|
|
"dareboost",
|
|
"datanyze",
|
|
"dejaclick",
|
|
"detect",
|
|
"discovery",
|
|
"dmbrowser",
|
|
"download",
|
|
"exaleadcloudview",
|
|
"feed",
|
|
"fetcher",
|
|
"firephp",
|
|
"foregenix",
|
|
"functionize",
|
|
"grab",
|
|
"hardenize\\b",
|
|
"headless",
|
|
"hotjar",
|
|
"httrack",
|
|
"hubspot marketing grader",
|
|
"ibisbrowser",
|
|
"infrawatch",
|
|
"insight",
|
|
"inspect",
|
|
"iplabel",
|
|
"java(?!;)",
|
|
"library",
|
|
"linkcheck",
|
|
"linktiger",
|
|
"mail\\.ru/",
|
|
"manager",
|
|
"manus-user/",
|
|
"marketgoo/",
|
|
"measure",
|
|
"monitor\\b",
|
|
"neustar wpm",
|
|
"node\\b",
|
|
"nutch",
|
|
"offbyone",
|
|
"openvas",
|
|
"optimize",
|
|
"pageburst",
|
|
"pagespeed",
|
|
"parser",
|
|
"phantomjs",
|
|
"pingdom",
|
|
"playwright",
|
|
"powermarks",
|
|
"preview",
|
|
"productfinder",
|
|
"prospectingstudio",
|
|
"proxy",
|
|
"ptst[ /]\\d",
|
|
"radar",
|
|
"readable/",
|
|
"retriever",
|
|
"rexx;",
|
|
"rigor",
|
|
"rss\\b",
|
|
"scrape",
|
|
"securityheaders",
|
|
"selenium",
|
|
"server",
|
|
"silktide",
|
|
"sindup/",
|
|
"sogou",
|
|
"sparkler/",
|
|
"speedcurve",
|
|
"spider",
|
|
"splash",
|
|
"statuscake",
|
|
"supercleaner",
|
|
"synapse",
|
|
"synthetic",
|
|
"testlocally",
|
|
"tools",
|
|
"torrent",
|
|
"transcoder",
|
|
"upday/",
|
|
"url",
|
|
"validator",
|
|
"virtuoso",
|
|
"wappalyzer",
|
|
"watchtowr",
|
|
"webglance",
|
|
"webkit2png",
|
|
"whatcms/",
|
|
"xtate/"
|
|
];
|
|
|
|
// src/pattern.ts
|
|
var fullPattern = " daum[ /]| deusu/|(?:^|[^g])news(?!sapphire)|(?<! channel/|google/)google(?!(?:wv|app|/google| pixel))|(?<! cu)bots?(?:\\b|_)|(?<!cam)scan|(?<!lib)http|24x7|;\\s\\w+;$|@[a-z][\\w-]+\\.|\\(\\)|\\.com\\b|\\b\\w+\\.ai|\\bbw/|\\bdlc\\b|\\bort/|\\bperl\\b|\\btime/|\\||^[<\\(;]|^[\\w \\.\\-\\(?:\\):%]+(?:/v?\\d+(?:\\.\\d+)?(?:\\.\\d{1,10})*?)?(?:,|$)|^[\\w\\-]+/[\\w]+$|^[^ ]{50,}$|^\\d+\\b|^\\w*search\\b|^\\w+/[\\w\\(\\)]*$|^\\w+/\\d\\.\\d\\s\\([\\w@]+\\)$|^active|^ad muncher|^amaya|^apache/|^avsdevicesdk/|^azure|^biglotron|^blackbox exporter|^bot|^clamav[ /]|^claude-code/|^client/|^cobweb/|^custom|^ddg[_-]android|^discourse|^dispatch/\\d|^downcast/|^duckduckgo|^email|^exodusmovement|^facebook|^getright/|^gozilla/|^hobbit|^hotzonu|^hwcdn/|^igetter/|^jeode/|^jetty/|^jigsaw|^microsoft bits|^movabletype|^mozilla/\\d\\.\\d\\s[\\w\\.-]+$|^mozilla/\\d\\.\\d\\s\\((?:compatible;)?(?:\\s?[\\w\\d-.]+\\/\\d+\\.\\d+)?\\)$|^navermailapp|^netsurf|^offline|^openai/|^owler|^php|^postman|^ps_daily/|^python|^rank|^read|^reed|^remove\\.bg/|^rest|^rss|^snapchat|^sora |^space bison|^stape/|^svn|^swcd |^taringa|^thumbor/|^track|^w3c|^webbandit/|^webcopier|^wget|^whatsapp|^wordpress|^xenu link sleuth|^yahoo|^yandex|^zdm/\\d|^zoom marketplace/|abuse|advisor|agent\\b|analyzer|archive|ask jeeves/teoma|attracta|audit|bluecoat drtr|browsex|burpcollaborator|capture|catch|check\\b|checker|chrome-lighthouse|chromeframe|classifier|cloudflare|collapsify\\b|convertify|cookiehubverify/|crawl|cursor/|cypress/|dareboost|datanyze|dejaclick|detect|discovery|dmbrowser|download|exaleadcloudview|feed|fetcher|firephp|foregenix|functionize|grab|hardenize\\b|headless|hotjar|httrack|hubspot marketing grader|ibisbrowser|infrawatch|insight|inspect|iplabel|java(?!;)|library|linkcheck|linktiger|mail\\.ru/|manager|manus-user/|marketgoo/|measure|monitor\\b|neustar wpm|node\\b|nutch|offbyone|openvas|optimize|pageburst|pagespeed|parser|phantomjs|pingdom|playwright|powermarks|preview|productfinder|prospectingstudio|proxy|ptst[ /]\\d|radar|readable/|retriever|rexx;|rigor|rss\\b|scrape|securityheaders|selenium|server|silktide|sindup/|sogou|sparkler/|speedcurve|spider|splash|statuscake|supercleaner|synapse|synthetic|testlocally|tools|torrent|transcoder|upday/|url|validator|virtuoso|wappalyzer|watchtowr|webglance|webkit2png|whatcms/|xtate/";
|
|
|
|
// src/index.ts
|
|
var naivePattern = /bot|crawl|http|lighthouse|scan|search|spider/i;
|
|
var pattern;
|
|
function getPattern() {
|
|
if (pattern instanceof RegExp) {
|
|
return pattern;
|
|
}
|
|
try {
|
|
pattern = new RegExp(fullPattern, "i");
|
|
} catch (error) {
|
|
pattern = naivePattern;
|
|
}
|
|
return pattern;
|
|
}
|
|
var isNonEmptyString = (value) => typeof value === "string" && value !== "";
|
|
var list = patterns_default;
|
|
function isBot(userAgent) {
|
|
return isNonEmptyString(userAgent) && getPattern().test(userAgent);
|
|
}
|
|
var isBotNaive = (userAgent) => isNonEmptyString(userAgent) && naivePattern.test(userAgent);
|
|
var createIsBot = (customPattern) => (userAgent) => isNonEmptyString(userAgent) && customPattern.test(userAgent);
|
|
var createIsBotFromList = (list2) => {
|
|
const pattern2 = new RegExp(list2.join("|"), "i");
|
|
return (userAgent) => isNonEmptyString(userAgent) && pattern2.test(userAgent);
|
|
};
|
|
var findBotMatch = (userAgent) => {
|
|
var _a, _b;
|
|
return (_b = (_a = userAgent == null ? void 0 : userAgent.match(getPattern())) == null ? void 0 : _a[0]) != null ? _b : null;
|
|
};
|
|
var findBotMatches = (userAgent) => list.map((part) => {
|
|
var _a;
|
|
return (_a = userAgent == null ? void 0 : userAgent.match(new RegExp(part, "i"))) == null ? void 0 : _a[0];
|
|
}).filter(isNonEmptyString);
|
|
var findBotPattern = (userAgent) => {
|
|
var _a;
|
|
return userAgent ? (_a = list.find((pattern2) => new RegExp(pattern2, "i").test(userAgent))) != null ? _a : null : null;
|
|
};
|
|
var findBotPatterns = (userAgent) => userAgent ? list.filter((pattern2) => new RegExp(pattern2, "i").test(userAgent)) : [];
|
|
var isbot = isBot;
|
|
var isbotNaive = isBotNaive;
|
|
var createIsbot = createIsBot;
|
|
var createIsbotFromList = createIsBotFromList;
|
|
var isbotMatch = findBotMatch;
|
|
var isbotMatches = findBotMatches;
|
|
var isbotPattern = findBotPattern;
|
|
var isbotPatterns = findBotPatterns;
|
|
export {
|
|
createIsBot,
|
|
createIsBotFromList,
|
|
createIsbot,
|
|
createIsbotFromList,
|
|
findBotMatch,
|
|
findBotMatches,
|
|
findBotPattern,
|
|
findBotPatterns,
|
|
getPattern,
|
|
isBot,
|
|
isBotNaive,
|
|
isbot,
|
|
isbotMatch,
|
|
isbotMatches,
|
|
isbotNaive,
|
|
isbotPattern,
|
|
isbotPatterns,
|
|
list
|
|
};
|