mirror of
https://github.com/LightZirconite/Microsoft-Rewards-Bot.git
synced 2026-01-10 01:06:17 +00:00
Clean up and fix
This commit is contained in:
@@ -350,6 +350,7 @@ export class AccountCreator {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: Math.min(maxWaitMs, 10000) })
|
||||
|
||||
// STEP 2: Wait for DOM to be fully loaded
|
||||
// Silent catch justified: DOMContentLoaded may already be complete
|
||||
await this.page.waitForLoadState('domcontentloaded', { timeout: 3000 }).catch(() => {})
|
||||
|
||||
// STEP 3: REDUCED delay - pages load fast
|
||||
@@ -369,7 +370,7 @@ export class AccountCreator {
|
||||
const visible = await element.isVisible().catch(() => false)
|
||||
|
||||
if (visible) {
|
||||
// Wait silently, no spam logs
|
||||
// Silent catch justified: Loading indicators may disappear before timeout, which is fine
|
||||
await element.waitFor({ state: 'hidden', timeout: Math.min(5000, maxWaitMs - (Date.now() - startTime)) }).catch(() => {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,6 +543,7 @@ export class Login {
|
||||
await this.bot.utils.wait(500) // Increased from 250ms
|
||||
|
||||
// IMPROVEMENT: Wait for page to be fully ready before looking for email field
|
||||
// Silent catch justified: DOMContentLoaded may already be complete, which is fine
|
||||
await page.waitForLoadState('domcontentloaded', { timeout: 10000 }).catch(() => {})
|
||||
await this.bot.utils.wait(300) // Extra settling time
|
||||
|
||||
@@ -572,6 +573,7 @@ export class Login {
|
||||
const content = await page.content().catch(() => '')
|
||||
if (content.length < 1000) {
|
||||
this.bot.log(this.bot.isMobile, 'LOGIN', 'Page content too small, reloading...', 'warn')
|
||||
// Silent catch justified: Reload may timeout if page is slow, but we continue anyway
|
||||
await page.reload({ waitUntil: 'domcontentloaded', timeout: 15000 }).catch(() => {})
|
||||
await this.bot.utils.wait(1500)
|
||||
}
|
||||
|
||||
@@ -387,7 +387,8 @@ export class Search extends Workers {
|
||||
|
||||
private async clickRandomLink(page: Page) {
|
||||
try {
|
||||
await page.click('#b_results .b_algo h2', { timeout: 2000 }).catch(() => { }) // Since we don't really care if it did it or not
|
||||
// Silent catch justified: Click is best-effort humanization, failure is acceptable
|
||||
await page.click('#b_results .b_algo h2', { timeout: 2000 }).catch(() => {})
|
||||
|
||||
// Only used if the browser is not the edge browser (continue on Edge popup)
|
||||
await this.closeContinuePopup(page)
|
||||
|
||||
@@ -41,7 +41,11 @@ export class JobState {
|
||||
const raw = fs.readFileSync(file, 'utf-8')
|
||||
const parsed = JSON.parse(raw)
|
||||
return parsed && typeof parsed === 'object' && parsed.days ? parsed as FileState : { days: {} }
|
||||
} catch { return { days: {} } }
|
||||
} catch (error) {
|
||||
// Silent catch justified: Corrupted job state files should be reset to empty state
|
||||
// rather than crashing the bot. This is a recoverable error.
|
||||
return { days: {} }
|
||||
}
|
||||
}
|
||||
|
||||
private save(email: string, state: FileState): void {
|
||||
|
||||
@@ -70,12 +70,15 @@ function stripJsonComments(input: string): string {
|
||||
|
||||
// Normalize both legacy (flat) and new (nested) config schemas into the flat Config interface
|
||||
function normalizeConfig(raw: unknown): Config {
|
||||
// TYPE SAFETY NOTE: Using `any` here is intentional and justified
|
||||
// Reason: Config format evolved from flat → nested structure. This function must support BOTH
|
||||
// for backward compatibility. Runtime validation via explicit checks ensures safety.
|
||||
// Return type (Config interface) provides type safety at function boundary.
|
||||
// TYPE SAFETY: Validate raw input before processing
|
||||
// Config files are untrusted JSON that could have any structure
|
||||
// We use explicit runtime checks for each property below
|
||||
if (!raw || typeof raw !== 'object') {
|
||||
throw new Error('Config must be a valid object')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const n = (raw || {}) as any
|
||||
const n = raw as Record<string, any>
|
||||
|
||||
// Browser settings
|
||||
const browserConfig = n.browser ?? {}
|
||||
@@ -356,19 +359,20 @@ export function loadAccounts(): Account[] {
|
||||
// Accept either a root array or an object with an `accounts` array, ignore `_note`
|
||||
const parsed = Array.isArray(parsedUnknown) ? parsedUnknown : (parsedUnknown && typeof parsedUnknown === 'object' && Array.isArray((parsedUnknown as { accounts?: unknown }).accounts) ? (parsedUnknown as { accounts: unknown[] }).accounts : null)
|
||||
if (!Array.isArray(parsed)) throw new Error('accounts must be an array')
|
||||
// FIXED: Validate entries BEFORE type assertion for better type safety
|
||||
// TYPE SAFETY: Validate entries BEFORE processing
|
||||
for (const entry of parsed) {
|
||||
// Pre-validation: Check basic structure before casting
|
||||
// Pre-validation: Check basic structure
|
||||
if (!entry || typeof entry !== 'object') {
|
||||
throw new Error('each account entry must be an object')
|
||||
}
|
||||
|
||||
// JUSTIFIED USE OF `any`: Accounts come from untrusted user JSON with unpredictable structure
|
||||
// We perform explicit runtime validation of each property below (typeof checks, regex validation, etc.)
|
||||
// This is safer than trusting a type assertion to a specific interface
|
||||
// Use Record<string, any> to access dynamic properties from untrusted JSON
|
||||
// Runtime validation below ensures type safety
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const a = entry as any
|
||||
if (!a || typeof a.email !== 'string' || typeof a.password !== 'string') {
|
||||
const a = entry as Record<string, any>
|
||||
|
||||
// Validate required fields with proper type checking
|
||||
if (typeof a.email !== 'string' || typeof a.password !== 'string') {
|
||||
throw new Error('each account must have email and password strings')
|
||||
}
|
||||
a.email = String(a.email).trim()
|
||||
@@ -392,11 +396,15 @@ export function loadAccounts(): Account[] {
|
||||
if (!a.proxy || typeof a.proxy !== 'object') {
|
||||
a.proxy = { proxyAxios: true, url: '', port: 0, username: '', password: '' }
|
||||
} else {
|
||||
a.proxy.proxyAxios = a.proxy.proxyAxios !== false
|
||||
a.proxy.url = typeof a.proxy.url === 'string' ? a.proxy.url : ''
|
||||
a.proxy.port = typeof a.proxy.port === 'number' ? a.proxy.port : 0
|
||||
a.proxy.username = typeof a.proxy.username === 'string' ? a.proxy.username : ''
|
||||
a.proxy.password = typeof a.proxy.password === 'string' ? a.proxy.password : ''
|
||||
// Safe proxy property access with runtime validation
|
||||
const proxy = a.proxy as Record<string, unknown>
|
||||
a.proxy = {
|
||||
proxyAxios: proxy.proxyAxios !== false,
|
||||
url: typeof proxy.url === 'string' ? proxy.url : '',
|
||||
port: typeof proxy.port === 'number' ? proxy.port : 0,
|
||||
username: typeof proxy.username === 'string' ? proxy.username : '',
|
||||
password: typeof proxy.password === 'string' ? proxy.password : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
// Filter out disabled accounts (enabled: false)
|
||||
|
||||
@@ -114,7 +114,7 @@ export class Util {
|
||||
* @example utils.chunkArray([1,2,3,4,5], 2) // [[1,2,3], [4,5]]
|
||||
*/
|
||||
chunkArray<T>(arr: T[], numChunks: number): T[][] {
|
||||
// FIXED: Stricter validation with better error messages
|
||||
// Validate input parameters
|
||||
if (!Array.isArray(arr)) {
|
||||
throw new Error('Invalid input: arr must be an array.')
|
||||
}
|
||||
@@ -123,11 +123,6 @@ export class Util {
|
||||
return []
|
||||
}
|
||||
|
||||
// Check for undefined/null elements which could cause issues downstream
|
||||
if (arr.some(item => item === undefined || item === null)) {
|
||||
throw new Error('Array contains undefined or null elements which are not allowed.')
|
||||
}
|
||||
|
||||
if (!Number.isFinite(numChunks) || numChunks <= 0) {
|
||||
throw new Error(`Invalid numChunks: ${numChunks}. Must be a positive finite number.`)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user