feat: Implement account suspension checks and improve error handling

- Added a method to check for account suspension using multiple detection methods in BrowserFunc.
- Refactored existing suspension checks to utilize the new method, reducing code duplication.
- Enhanced error handling in various functions to throw original errors instead of wrapping them.
- Improved environment variable parsing in constants to streamline validation.
- Updated login flow to optimize session restoration and error handling.
- Refined Axios request logic to include retry mechanisms for proxy authentication and network errors.
- Enhanced logging functionality to provide clearer output and error context.
- Improved utility functions with additional validation for input parameters.
This commit is contained in:
2025-11-03 21:21:13 +01:00
parent f1db62823c
commit 39b62a4190
9 changed files with 318 additions and 340 deletions

View File

@@ -5,85 +5,83 @@
/**
* Parse environment variable as number with validation
* @param key Environment variable name
* @param defaultValue Default value if parsing fails or out of range
* @param min Minimum allowed value
* @param max Maximum allowed value
* @returns Parsed number or default value
*/
function parseEnvNumber(key: string, defaultValue: number, min: number, max: number): number {
const raw = process.env[key]
if (!raw) return defaultValue
const parsed = Number(raw)
if (isNaN(parsed)) {
console.warn(`[Constants] Invalid ${key}="${raw}". Using default ${defaultValue}`)
return defaultValue
}
if (parsed < min || parsed > max) {
console.warn(`[Constants] ${key}=${parsed} out of range [${min}, ${max}]. Using default ${defaultValue}`)
return defaultValue
}
return parsed
const raw = process.env[key]
if (!raw) return defaultValue
const parsed = Number(raw)
if (isNaN(parsed) || parsed < min || parsed > max) return defaultValue
return parsed
}
export const TIMEOUTS = {
SHORT: 500,
MEDIUM: 1500,
MEDIUM_LONG: 2000,
LONG: 3000,
VERY_LONG: 5000,
EXTRA_LONG: 10000,
DASHBOARD_WAIT: 10000,
LOGIN_MAX: parseEnvNumber('LOGIN_MAX_WAIT_MS', 180000, 30000, 600000),
NETWORK_IDLE: 5000
SHORT: 500,
MEDIUM: 1500,
MEDIUM_LONG: 2000,
LONG: 3000,
VERY_LONG: 5000,
EXTRA_LONG: 10000,
DASHBOARD_WAIT: 10000,
LOGIN_MAX: parseEnvNumber('LOGIN_MAX_WAIT_MS', 180000, 30000, 600000),
NETWORK_IDLE: 5000
} as const
export const RETRY_LIMITS = {
MAX_ITERATIONS: 5,
DASHBOARD_RELOAD: 2,
MOBILE_SEARCH: 3,
ABC_MAX: 15,
POLL_MAX: 15,
QUIZ_MAX: 15,
QUIZ_ANSWER_TIMEOUT: 10000,
GO_HOME_MAX: 5
MAX_ITERATIONS: 5,
DASHBOARD_RELOAD: 2,
MOBILE_SEARCH: 3,
ABC_MAX: 15,
POLL_MAX: 15,
QUIZ_MAX: 15,
QUIZ_ANSWER_TIMEOUT: 10000,
GO_HOME_MAX: 5
} as const
export const DELAYS = {
ACTION_MIN: 1000,
ACTION_MAX: 3000,
SEARCH_DEFAULT_MIN: 2000,
SEARCH_DEFAULT_MAX: 5000,
BROWSER_CLOSE: 2000,
TYPING_DELAY: 20,
SEARCH_ON_BING_WAIT: 5000,
SEARCH_ON_BING_COMPLETE: 3000,
SEARCH_ON_BING_FOCUS: 200,
SEARCH_BAR_TIMEOUT: 15000,
QUIZ_ANSWER_WAIT: 2000,
THIS_OR_THAT_START: 2000
ACTION_MIN: 1000,
ACTION_MAX: 3000,
SEARCH_DEFAULT_MIN: 2000,
SEARCH_DEFAULT_MAX: 5000,
BROWSER_CLOSE: 2000,
TYPING_DELAY: 20,
SEARCH_ON_BING_WAIT: 5000,
SEARCH_ON_BING_COMPLETE: 3000,
SEARCH_ON_BING_FOCUS: 200,
SEARCH_BAR_TIMEOUT: 15000,
QUIZ_ANSWER_WAIT: 2000,
THIS_OR_THAT_START: 2000
} as const
export const SELECTORS = {
MORE_ACTIVITIES: '#more-activities',
SUSPENDED_ACCOUNT: '#suspendedAccountHeader',
QUIZ_COMPLETE: '#quizCompleteContainer',
QUIZ_CREDITS: 'span.rqMCredits'
MORE_ACTIVITIES: '#more-activities',
SUSPENDED_ACCOUNT: '#suspendedAccountHeader',
QUIZ_COMPLETE: '#quizCompleteContainer',
QUIZ_CREDITS: 'span.rqMCredits'
} as const
export const URLS = {
REWARDS_BASE: 'https://rewards.bing.com',
REWARDS_SIGNIN: 'https://rewards.bing.com/signin',
APP_USER_DATA: 'https://prod.rewardsplatform.microsoft.com/dapi/me?channel=SAAndroid&options=613'
REWARDS_BASE: 'https://rewards.bing.com',
REWARDS_SIGNIN: 'https://rewards.bing.com/signin',
APP_USER_DATA: 'https://prod.rewardsplatform.microsoft.com/dapi/me?channel=SAAndroid&options=613'
} as const
export const DISCORD = {
MAX_EMBED_LENGTH: 1900,
RATE_LIMIT_DELAY: 500,
WEBHOOK_TIMEOUT: 10000,
DEBOUNCE_DELAY: 750,
COLOR_RED: 0xFF0000,
COLOR_CRIMSON: 0xDC143C,
COLOR_ORANGE: 0xFFA500,
COLOR_BLUE: 0x3498DB,
COLOR_GREEN: 0x00D26A,
AVATAR_URL: 'https://media.discordapp.net/attachments/1421163952972369931/1434918661235282144/logo.png?ex=690a13a4&is=6908c224&hm=6bae81966da32e73a647f46fde268011fcf460c7071082dd5fd76cf22d04af65&=&format=png&quality=lossless&width=653&height=638'
MAX_EMBED_LENGTH: 1900,
RATE_LIMIT_DELAY: 500,
WEBHOOK_TIMEOUT: 10000,
DEBOUNCE_DELAY: 750,
COLOR_RED: 0xFF0000,
COLOR_CRIMSON: 0xDC143C,
COLOR_ORANGE: 0xFFA500,
COLOR_BLUE: 0x3498DB,
COLOR_GREEN: 0x00D26A,
COLOR_GRAY: 0x95A5A6,
AVATAR_URL: 'https://media.discordapp.net/attachments/1421163952972369931/1434918661235282144/logo.png?ex=690a13a4&is=6908c224&hm=6bae81966da32e73a647f46fde268011fcf460c7071082dd5fd76cf22d04af65&=&format=png&quality=lossless&width=653&height=638'
} as const