Skip to content

Commit 41e47ab

Browse files
committed
fix: 收紧登录规则并优化重复识别
1 parent 1f06749 commit 41e47ab

8 files changed

Lines changed: 98 additions & 8 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "stackprism",
33
"private": true,
4-
"version": "1.2.69",
4+
"version": "1.2.70",
55
"type": "module",
66
"description": "StackPrism 用于检测网页前端、后端、CDN、SaaS、广告营销、统计、登录、支付、网站程序和主题模板线索。",
77
"scripts": {

public/rules/page/cdn-providers-page.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
"name": "cdnjs",
2727
"patterns": ["cdnjs\\.cloudflare\\.com"]
2828
},
29+
{
30+
"name": "cdnjs 国内镜像",
31+
"patterns": [
32+
"cdnjs\\.webstatic\\.cn(?:/ajax/libs/|[/?#]|$)",
33+
"mirrors\\.sustech\\.edu\\.cn/cdnjs/",
34+
"s4\\.zstatic\\.net/ajax/libs/"
35+
]
36+
},
2937
{
3038
"name": "Google Hosted Libraries / Fonts",
3139
"patterns": ["ajax\\.googleapis\\.com|fonts\\.googleapis\\.com|fonts\\.gstatic\\.com"]

public/rules/page/frontend-local-libraries.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,28 @@
5454
"name": "LazyLoad",
5555
"patterns": ["(?:^|/)(?:lazyload|lazy-load|vanilla-lazyload)(?:\\.min)?\\.js(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)"]
5656
},
57+
{
58+
"name": "OwlCarousel2",
59+
"patterns": [
60+
"(?:^|/)owl\\.carousel(?:\\.min)?\\.(?:js|css)(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)",
61+
"(?:^|/)owl\\.carousel/.+\\.(?:js|css)(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)"
62+
]
63+
},
64+
{
65+
"name": "magnific-popup.js",
66+
"patterns": ["(?:^|/)(?:jquery\\.)?magnific-popup(?:\\.min)?\\.(?:js|css)(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)"]
67+
},
68+
{
69+
"name": "font-awesome",
70+
"patterns": [
71+
"(?:^|/)font-?awesome(?:\\.min)?\\.css(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)",
72+
"(?:^|/)font-?awesome/.+\\.css(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)"
73+
]
74+
},
75+
{
76+
"name": "spin.js",
77+
"patterns": ["(?:^|/)spin(?:\\.min)?\\.js(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)"]
78+
},
5779
{
5880
"name": "Layer.js",
5981
"patterns": ["(?:^|/)layer(?:\\.min)?\\.js(?:[?#][^\\s\"'<>]*)?(?:[\"'<>\\s]|$)"]

public/rules/page/third-party-logins.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@
8484
"name": "钉钉登录",
8585
"patterns": ["(?:^|/)assets/icon/dingtalk\\.(?:png|svg|webp)(?:[?#]|[\"'<>\\s]|$)"]
8686
},
87+
{
88+
"name": "企业微信登录",
89+
"patterns": ["(?:^|/)assets/icon/(?:wxwork|qywechat|wecom|wework|work-weixin|workwx)\\.(?:png|svg|webp)(?:[?#]|[\"'<>\\s]|$)"]
90+
},
8791
{
8892
"name": "飞书 / Lark 登录",
8993
"patterns": ["(?:^|/)assets/icon/(?:feishu|lark)\\.(?:png|svg|webp)(?:[?#]|[\"'<>\\s]|$)"]
@@ -130,7 +134,7 @@
130134
"rules": [
131135
{
132136
"name": "钉钉登录",
133-
"patterns": ["oapi\\.dingtalk\\.com/connect/qrconnect", "login\\.dingtalk\\.com", "DingTalk", "钉钉登录"]
137+
"patterns": ["oapi\\.dingtalk\\.com/connect/qrconnect", "login\\.dingtalk\\.com/(?:oauth2|login|authorize)"]
134138
},
135139
{
136140
"name": "飞书 / Lark 登录",
@@ -144,7 +148,7 @@
144148
},
145149
{
146150
"name": "企业微信登录",
147-
"patterns": ["open\\.work\\.weixin\\.qq\\.com", "work.weixin.qq.com", "企业微信登录", "wecom"]
151+
"patterns": ["open\\.work\\.weixin\\.qq\\.com", "work\\.weixin\\.qq\\.com/[^\\s\"'<>]*(?:oauth|login|qrconnect|wwopen)"]
148152
}
149153
]
150154
},

public/tech-links.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,7 @@
10341034
"jsDelivr": "https://www.jsdelivr.com",
10351035
"UNPKG": "https://unpkg.com",
10361036
"cdnjs": "https://cdnjs.com",
1037+
"cdnjs 国内镜像": "https://cdnjs.com",
10371038
"Google Hosted Libraries / Fonts": "https://developers.google.com/speed/libraries",
10381039
"Google Cloud CDN / Storage": "https://cloud.google.com/cdn",
10391040
"Microsoft Ajax CDN": "https://learn.microsoft.com/aspnet/ajax/cdn/overview",

src/background/merge.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,51 @@ export const shortHeaderUrl = (raw: unknown): string => {
2727
}
2828
}
2929

30-
export const normalizeDynamicFallbackTechName = (name: unknown): string => {
31-
const normalized = String(name || '')
30+
const normalizeFrontendTechKey = (name: unknown): string =>
31+
String(name || '')
3232
.toLowerCase()
3333
.replace(/^:\s*/, '')
3434
.replace(/(?:\.js|js)$/i, '')
3535
.replace(/(?:[._-]pkgd)$/i, '')
3636
.replace(/[^a-z0-9-]+/g, '')
3737

38+
export const normalizeDynamicFallbackTechName = (name: unknown): string => {
39+
const normalized = normalizeFrontendTechKey(name)
3840
const aliases: Record<string, string> = {
3941
clipboardjs: 'clipboard',
42+
jquerycompat: 'jquery',
4043
imagesloadedjs: 'imagesloaded',
4144
slickcarousel: 'slick',
45+
twitterbootstrap: 'bootstrap',
4246
vuejs: 'vue'
4347
}
4448
return aliases[normalized] || normalized
4549
}
4650

4751
export const isFrontendFallback = (item: any) => item?.category === '前端库' && /^:/i.test(String(item?.name || '').trim())
4852

53+
const frontendTechnologyCategories = new Set(['前端库', '前端框架', 'UI / CSS 框架'])
54+
55+
const frontendAliasTechnologies: Record<string, { category: string; name: string }> = {
56+
jquerycompat: { category: '前端库', name: 'jQuery' },
57+
twitterbootstrap: { category: 'UI / CSS 框架', name: 'Bootstrap' }
58+
}
59+
60+
export const canonicalizeFrontendAliasTechnologies = (items: any[]) => {
61+
if (!Array.isArray(items) || !items.length) return []
62+
63+
return items.map(item => {
64+
if (!frontendTechnologyCategories.has(item?.category)) return item
65+
const canonical = frontendAliasTechnologies[normalizeFrontendTechKey(item.name)]
66+
if (!canonical) return item
67+
return {
68+
...item,
69+
category: canonical.category,
70+
name: canonical.name
71+
}
72+
})
73+
}
74+
4975
const isWordPressThemeDirectoryFallbackEvidence = (evidenceText: string) =>
5076
/(?:|)/i.test(evidenceText) && /\/wp-content\/themes\//i.test(evidenceText)
5177

@@ -117,7 +143,7 @@ export const suppressWordPressThemeDirectoryFallbacks = (items: any[]) => {
117143
export const mergeTechnologyRecords = (items: any[]) => {
118144
const map = new Map<string, any>()
119145
for (const item of suppressDuplicateWebsiteProgramCategories(
120-
suppressWordPressThemeDirectoryFallbacks(suppressFrontendFallbackDuplicates(items))
146+
suppressWordPressThemeDirectoryFallbacks(canonicalizeFrontendAliasTechnologies(suppressFrontendFallbackDuplicates(items)))
121147
)) {
122148
const key = `${item.category}::${item.name}`.toLowerCase()
123149
const current = map.get(key) || { ...item, evidence: [] }

src/background/popup-cache.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { attachTechnologyLinks } from './tech-links'
22
import { addStoredCustomHeaderRules } from './headers'
33
import { clearBadge, clearTabSession, getPopupCache, getTabData, getTabSnapshot, popupStorageKey, storageKey } from './tab-store'
44
import {
5+
canonicalizeFrontendAliasTechnologies,
56
strongerConfidence,
67
suppressDuplicateWebsiteProgramCategories,
78
suppressFrontendFallbackDuplicates,
@@ -134,7 +135,7 @@ export const filterTechnologiesBySettings = (technologies: any[], settings: any)
134135
const mergeDisplayTechnologyRecords = (items: any[]) => {
135136
const map = new Map()
136137
for (const item of suppressDuplicateWebsiteProgramCategories(
137-
suppressWordPressThemeDirectoryFallbacks(suppressFrontendFallbackDuplicates(items))
138+
suppressWordPressThemeDirectoryFallbacks(canonicalizeFrontendAliasTechnologies(suppressFrontendFallbackDuplicates(items)))
138139
)) {
139140
if (!item?.name) continue
140141
const category = item.category || '其他库'

src/injected/page-detector.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ const detectPageTechnologies = (ruleConfig: Record<string, unknown> = {}) => {
4646
url: location.href,
4747
title: document.title,
4848
generatedAt: new Date().toISOString(),
49-
technologies: suppressDuplicateWebsiteProgramCategories(suppressFrontendFallbackDuplicates(technologies)),
49+
technologies: suppressDuplicateWebsiteProgramCategories(
50+
suppressFrontendAliasTechnologies(suppressFrontendFallbackDuplicates(technologies))
51+
),
5052
resources: {
5153
total: resources.all.length,
5254
scripts: resources.scripts.slice(0, 120),
@@ -351,13 +353,39 @@ const detectPageTechnologies = (ruleConfig: Record<string, unknown> = {}) => {
351353
.replace(/[^a-z0-9\u4e00-\u9fa5]+/g, '')
352354
const aliases = {
353355
clipboardjs: 'clipboard',
356+
jquerycompat: 'jquery',
354357
imagesloadedjs: 'imagesloaded',
355358
slickcarousel: 'slick',
359+
twitterbootstrap: 'bootstrap',
356360
vuejs: 'vue'
357361
}
358362
return aliases[normalized] || normalized
359363
}
360364

365+
function suppressFrontendAliasTechnologies(items) {
366+
if (!Array.isArray(items) || !items.length) {
367+
return []
368+
}
369+
const aliases = {
370+
jquerycompat: { category: '前端库', name: 'jQuery' },
371+
twitterbootstrap: { category: 'UI / CSS 框架', name: 'Bootstrap' }
372+
}
373+
const frontendCategories = new Set(['前端库', '前端框架', 'UI / CSS 框架'])
374+
return items.map(item => {
375+
if (!frontendCategories.has(item?.category)) {
376+
return item
377+
}
378+
const key = String(item?.name || '')
379+
.toLowerCase()
380+
.replace(/^:\s*/, '')
381+
.replace(/(?:\.js|js)$/i, '')
382+
.replace(/(?:[._-]pkgd)$/i, '')
383+
.replace(/[^a-z0-9\u4e00-\u9fa5]+/g, '')
384+
const canonical = aliases[key]
385+
return canonical ? { ...item, category: canonical.category, name: canonical.name } : item
386+
})
387+
}
388+
361389
function suppressFrontendFallbackDuplicates(items) {
362390
if (!Array.isArray(items) || !items.length) {
363391
return []

0 commit comments

Comments
 (0)