147 lines
4.1 KiB
TypeScript
147 lines
4.1 KiB
TypeScript
function normalizeText(value: unknown): string | null {
|
|
if (typeof value !== 'string') {
|
|
return null
|
|
}
|
|
const trimmed = value.trim()
|
|
return trimmed ? trimmed : null
|
|
}
|
|
|
|
function normalizeURLPath(pathname: string): string {
|
|
const normalized = pathname.replace(/\/+$/, '')
|
|
return normalized === '/' ? '' : normalized
|
|
}
|
|
|
|
function safeParseURL(input: string): URL | null {
|
|
try {
|
|
return new URL(input)
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
function genericAIConversationPath(pathname: string): boolean {
|
|
return /^\/(?:chat|c|conversation)(?:\/|$)/i.test(pathname)
|
|
}
|
|
|
|
export interface GenericAIPageState {
|
|
displayName: string | null
|
|
avatarUrl: string | null
|
|
fingerprint: string | null
|
|
credentialFingerprint: string | null
|
|
currentPath: string | null
|
|
strongAuthSignalCount: number
|
|
loginSignalCount: number
|
|
loggedOutSignalCount: number
|
|
challengeSignalCount: number
|
|
}
|
|
|
|
export function isLikelyGenericAICredentialName(name: string): boolean {
|
|
const normalized = name.trim().toLowerCase()
|
|
if (!normalized) {
|
|
return false
|
|
}
|
|
|
|
if (/(?:^|[-_.])(?:x[-_]?csrf|xsrf|csrf)(?:[-_]?token)?(?:$|[-_.])/.test(normalized)) {
|
|
return false
|
|
}
|
|
|
|
if (
|
|
/(?:^|[-_.])(?:slardar|analytics|monitor|telemetry|trace|tracing|log|logger|sentry|rum|perf|performance|abtest|experiment|visitor|guest|anonymous|device|webid|web_id|ttwid|hook|mstoken|ms_token|odin_tt|s_v_web_id|__ac_nonce|__ac_signature)(?:$|[-_.])/i.test(
|
|
normalized,
|
|
)
|
|
) {
|
|
return false
|
|
}
|
|
|
|
return /(token|session|auth|login|passport|ticket|jwt|refresh|access|sso)/i.test(normalized)
|
|
}
|
|
|
|
export function isLikelyGenericAICredentialValue(value: string | null | undefined): boolean {
|
|
const normalized = normalizeText(value)
|
|
if (!normalized) {
|
|
return false
|
|
}
|
|
|
|
if (/^(true|false|null|undefined|0|1)$/i.test(normalized)) {
|
|
return false
|
|
}
|
|
|
|
return normalized.length >= 8
|
|
}
|
|
|
|
export function genericAIHasVisibleAccountSignal(pageState: GenericAIPageState | null): boolean {
|
|
return (
|
|
Boolean(pageState?.displayName || pageState?.avatarUrl) ||
|
|
(pageState?.strongAuthSignalCount ?? 0) >= 2
|
|
)
|
|
}
|
|
|
|
export function genericAIPlatformRequiresVisibleCredentialSignal(platformId: string): boolean {
|
|
const normalizedPlatformId = platformId.trim().toLowerCase()
|
|
return normalizedPlatformId === 'qwen'
|
|
}
|
|
|
|
export function isLikelyPlatformAICredentialCookie(
|
|
platformId: string,
|
|
name: string,
|
|
value: string | null | undefined,
|
|
pageState?: GenericAIPageState | null,
|
|
): boolean {
|
|
const normalizedPlatformId = platformId.trim().toLowerCase()
|
|
const hasVisibleAccountSignal = genericAIHasVisibleAccountSignal(pageState ?? null)
|
|
|
|
if (normalizedPlatformId === 'doubao' || normalizedPlatformId === 'kimi') {
|
|
return false
|
|
}
|
|
|
|
if (!isLikelyGenericAICredentialName(name) || !isLikelyGenericAICredentialValue(value)) {
|
|
return false
|
|
}
|
|
|
|
if (
|
|
genericAIPlatformRequiresVisibleCredentialSignal(platformId) &&
|
|
!hasVisibleAccountSignal
|
|
) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
export function genericAIPageLooksAuthenticated(
|
|
currentURL: string,
|
|
pageState: GenericAIPageState | null,
|
|
): boolean {
|
|
const current = safeParseURL(currentURL)
|
|
const currentPath = normalizeURLPath(current?.pathname ?? pageState?.currentPath ?? '')
|
|
const strongAuthSignalCount = pageState?.strongAuthSignalCount ?? 0
|
|
const loginSignalCount = pageState?.loginSignalCount ?? 0
|
|
const loggedOutSignalCount = pageState?.loggedOutSignalCount ?? 0
|
|
const challengeSignalCount = pageState?.challengeSignalCount ?? 0
|
|
const hasCredentialFingerprint = Boolean(normalizeText(pageState?.credentialFingerprint))
|
|
const onConversationPath = genericAIConversationPath(currentPath)
|
|
|
|
if (challengeSignalCount > 0) {
|
|
return false
|
|
}
|
|
|
|
if (loggedOutSignalCount > 0) {
|
|
return false
|
|
}
|
|
|
|
if (
|
|
loginSignalCount > 0 &&
|
|
strongAuthSignalCount === 0 &&
|
|
!onConversationPath &&
|
|
!hasCredentialFingerprint
|
|
) {
|
|
return false
|
|
}
|
|
|
|
if (loginSignalCount > 0) {
|
|
return (strongAuthSignalCount >= 2 || hasCredentialFingerprint) && !onConversationPath
|
|
}
|
|
|
|
return strongAuthSignalCount > 0 || hasCredentialFingerprint
|
|
}
|