New structure

This commit is contained in:
2025-11-11 12:59:42 +01:00
parent 088a3a024f
commit 89bc226d6b
46 changed files with 990 additions and 944 deletions

View File

@@ -52,16 +52,12 @@ browser/
.eslintcache .eslintcache
setup/ setup/
# Docker files (no recursion) # Docker files (organized in docker/ folder - no recursion needed)
Dockerfile docker/
docker-compose.yml
compose.yaml
.dockerignore .dockerignore
# NixOS specific files (not needed in Docker) # Scripts (organized in scripts/ folder - not needed in Docker)
flake.nix scripts/
flake.lock
run.sh
# Asset files (not needed for runtime) # Asset files (not needed for runtime)
assets/ assets/

View File

@@ -44,17 +44,33 @@ src/
│ ├── Poll.ts # Poll completion │ ├── Poll.ts # Poll completion
│ ├── ThisOrThat.ts # This or That game │ ├── ThisOrThat.ts # This or That game
│ └── ... │ └── ...
├── util/ # Shared utilities + infrastructure ├── util/ # Shared utilities (ORGANIZED BY CATEGORY)
│ ├── Axios.ts # HTTP client with proxy support │ ├── core/ # Core utilities
│ ├── BrowserFactory.ts # Centralized browser creation │ ├── Utils.ts # General-purpose helpers
├── Humanizer.ts # Random delays, mouse gestures │ └── Retry.ts # Exponential backoff retry logic
│ ├── BanDetector.ts # Heuristic ban detection │ ├── network/ # HTTP & API utilities
│ ├── QueryDiversityEngine.ts # Multi-source search query generation │ ├── Axios.ts # HTTP client with proxy support
├── JobState.ts # Persistent job state tracking │ └── QueryDiversityEngine.ts # Multi-source search query generation
│ ├── browser/ # Browser automation utilities
│ │ ├── BrowserFactory.ts # Centralized browser creation
│ │ ├── Humanizer.ts # Random delays, mouse gestures
│ │ └── UserAgent.ts # User agent generation
│ ├── state/ # State & persistence
│ │ ├── JobState.ts # Persistent job state tracking
│ │ ├── Load.ts # Configuration & session loading
│ │ └── MobileRetryTracker.ts # Mobile search retry tracking
│ ├── validation/ # Validation & detection
│ │ ├── StartupValidator.ts # Comprehensive startup validation
│ │ ├── BanDetector.ts # Heuristic ban detection
│ │ └── LoginStateDetector.ts # Login state detection
│ ├── security/ # Authentication & security
│ │ └── Totp.ts # TOTP generation for 2FA
│ └── notifications/ # Logging & notifications
│ ├── Logger.ts # Centralized logging with redaction │ ├── Logger.ts # Centralized logging with redaction
├── Retry.ts # Exponential backoff retry logic ├── ConclusionWebhook.ts # Summary webhook notifications
├── Utils.ts # General-purpose helpers ├── ErrorReportingWebhook.ts # Error reporting
└── ... ├── Ntfy.ts # Push notifications
│ └── AdaptiveThrottler.ts # Adaptive delay management
├── dashboard/ # Real-time web dashboard (Express + WebSocket) ├── dashboard/ # Real-time web dashboard (Express + WebSocket)
│ ├── server.ts # Express server + routes │ ├── server.ts # Express server + routes
│ ├── routes.ts # API endpoints │ ├── routes.ts # API endpoints
@@ -73,9 +89,20 @@ src/
├── nameDatabase.ts # First/last name pool ├── nameDatabase.ts # First/last name pool
├── types.ts # Account creation interfaces ├── types.ts # Account creation interfaces
└── README.md # Account creation guide └── README.md # Account creation guide
docker/ # Docker deployment files
├── Dockerfile # Multi-stage Docker build
├── compose.yaml # Docker Compose configuration
├── entrypoint.sh # Container initialization script
├── run_daily.sh # Daily execution wrapper (cron)
└── crontab.template # Cron schedule template
scripts/ # Utility scripts
└── run.sh # Nix development environment launcher
setup/ setup/
├── setup.bat # Windows setup script ├── setup.bat # Windows setup script
├── setup.sh # Linux/Mac setup script ├── setup.sh # Linux/Mac setup script
├── nix/ # NixOS configuration
│ ├── flake.nix # Nix flake definition
│ └── flake.lock # Nix flake lock file
└── update/ └── update/
├── setup.mjs # Initial setup automation ├── setup.mjs # Initial setup automation
└── update.mjs # GitHub ZIP-based auto-updater (NO GIT REQUIRED!) └── update.mjs # GitHub ZIP-based auto-updater (NO GIT REQUIRED!)
@@ -986,8 +1013,8 @@ private combinedDeduplication(queries: string[], threshold = 0.65): string[] {
### Docker & Scheduling Context ### Docker & Scheduling Context
**entrypoint.sh:** **docker/entrypoint.sh:**
- **Purpose:** Docker container initialization script - **Purpose:** Docker container initialization script (located in `docker/` directory)
- **Key Features:** - **Key Features:**
- Timezone configuration (env: `TZ`, default UTC) - Timezone configuration (env: `TZ`, default UTC)
- Initial run on start (env: `RUN_ON_START=true`) - Initial run on start (env: `RUN_ON_START=true`)
@@ -995,8 +1022,8 @@ private combinedDeduplication(queries: string[], threshold = 0.65): string[] {
- Playwright browser preinstallation (`PLAYWRIGHT_BROWSERS_PATH=0`) - Playwright browser preinstallation (`PLAYWRIGHT_BROWSERS_PATH=0`)
- **Usage:** Docker Compose sets `CRON_SCHEDULE`, container runs cron in foreground - **Usage:** Docker Compose sets `CRON_SCHEDULE`, container runs cron in foreground
**run_daily.sh:** **docker/run_daily.sh:**
- **Purpose:** Daily execution wrapper for cron jobs - **Purpose:** Daily execution wrapper for cron jobs (located in `docker/` directory)
- **Key Features:** - **Key Features:**
- Random sleep delay (0-30min) to avoid simultaneous runs across containers - Random sleep delay (0-30min) to avoid simultaneous runs across containers
- Environment variable: `SKIP_RANDOM_SLEEP=true` to disable delay - Environment variable: `SKIP_RANDOM_SLEEP=true` to disable delay

View File

@@ -80,11 +80,12 @@ COPY --from=builder /usr/src/microsoft-rewards-bot/package*.json ./
COPY --from=builder /usr/src/microsoft-rewards-bot/node_modules ./node_modules COPY --from=builder /usr/src/microsoft-rewards-bot/node_modules ./node_modules
# Copy runtime scripts with proper permissions and normalize line endings for non-Unix users # Copy runtime scripts with proper permissions and normalize line endings for non-Unix users
COPY --chmod=755 src/run_daily.sh ./src/run_daily.sh # IMPROVED: Scripts now organized in docker/ folder
COPY --chmod=644 src/crontab.template /etc/cron.d/microsoft-rewards-cron.template COPY --chmod=755 docker/run_daily.sh ./docker/run_daily.sh
COPY --chmod=755 entrypoint.sh /usr/local/bin/entrypoint.sh COPY --chmod=644 docker/crontab.template /etc/cron.d/microsoft-rewards-cron.template
COPY --chmod=755 docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN sed -i 's/\r$//' /usr/local/bin/entrypoint.sh \ RUN sed -i 's/\r$//' /usr/local/bin/entrypoint.sh \
&& sed -i 's/\r$//' ./src/run_daily.sh && sed -i 's/\r$//' ./docker/run_daily.sh
# Entrypoint handles TZ, initial run toggle, cron templating & launch # Entrypoint handles TZ, initial run toggle, cron templating & launch
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

View File

@@ -1,3 +1,3 @@
# Run automation according to CRON_SCHEDULE; redirect both stdout & stderr to Docker logs # Run automation according to CRON_SCHEDULE; redirect both stdout & stderr to Docker logs
${CRON_SCHEDULE} TZ=${TZ} /bin/bash /usr/src/microsoft-rewards-bot/src/run_daily.sh >> /proc/1/fd/1 2>&1 ${CRON_SCHEDULE} TZ=${TZ} /bin/bash /usr/src/microsoft-rewards-bot/docker/run_daily.sh >> /proc/1/fd/1 2>&1

View File

@@ -26,7 +26,7 @@ if [ "${RUN_ON_START:-false}" = "true" ]; then
exit 1 exit 1
} }
# Skip random sleep for initial run, but preserve setting for cron jobs # Skip random sleep for initial run, but preserve setting for cron jobs
SKIP_RANDOM_SLEEP=true src/run_daily.sh SKIP_RANDOM_SLEEP=true docker/run_daily.sh
echo "[entrypoint-bg] Initial run completed at $(date)" echo "[entrypoint-bg] Initial run completed at $(date)"
) & ) &
echo "[entrypoint] Background process started (PID: $!)" echo "[entrypoint] Background process started (PID: $!)"

22
scripts/README.md Normal file
View File

@@ -0,0 +1,22 @@
# Scripts Directory
This directory contains utility scripts for development and deployment.
## Available Scripts
### `run.sh`
**Purpose:** Nix development environment launcher
**Usage:** `./run.sh`
**Description:** Launches the bot using Nix develop environment with xvfb-run for headless browser support.
**Requirements:**
- Nix package manager
- xvfb (X Virtual Framebuffer)
**Environment:**
This script is designed for NixOS or systems with Nix installed. It provides a reproducible development environment as defined in `setup/nix/flake.nix`.
---
For Docker deployment, see the `docker/` directory.
For setup scripts, see the `setup/` directory.

View File

View File

@@ -2,7 +2,7 @@ import fs from 'fs'
import path from 'path' import path from 'path'
import * as readline from 'readline' import * as readline from 'readline'
import type { BrowserContext, Page } from 'rebrowser-playwright' import type { BrowserContext, Page } from 'rebrowser-playwright'
import { log } from '../util/Logger' import { log } from '../util/notifications/Logger'
import { DataGenerator } from './DataGenerator' import { DataGenerator } from './DataGenerator'
import { CreatedAccount } from './types' import { CreatedAccount } from './types'

View File

@@ -1,6 +1,6 @@
import Browser from '../browser/Browser' import Browser from '../browser/Browser'
import { MicrosoftRewardsBot } from '../index' import { MicrosoftRewardsBot } from '../index'
import { log } from '../util/Logger' import { log } from '../util/notifications/Logger'
import { AccountCreator } from './AccountCreator' import { AccountCreator } from './AccountCreator'
async function main(): Promise<void> { async function main(): Promise<void> {

View File

@@ -4,8 +4,8 @@ import playwright, { BrowserContext } from 'rebrowser-playwright'
import { MicrosoftRewardsBot } from '../index' import { MicrosoftRewardsBot } from '../index'
import { AccountProxy } from '../interface/Account' import { AccountProxy } from '../interface/Account'
import { loadSessionData, saveFingerprintData } from '../util/Load' import { updateFingerprintUserAgent } from '../util/browser/UserAgent'
import { updateFingerprintUserAgent } from '../util/UserAgent' import { loadSessionData, saveFingerprintData } from '../util/state/Load'
class Browser { class Browser {
private bot: MicrosoftRewardsBot private bot: MicrosoftRewardsBot

View File

@@ -8,7 +8,7 @@ import { AppUserData } from '../interface/AppUserData'
import { Counters, DashboardData, MorePromotion, PromotionalItem } from '../interface/DashboardData' import { Counters, DashboardData, MorePromotion, PromotionalItem } from '../interface/DashboardData'
import { EarnablePoints } from '../interface/Points' import { EarnablePoints } from '../interface/Points'
import { QuizData } from '../interface/QuizData' import { QuizData } from '../interface/QuizData'
import { saveSessionData } from '../util/Load' import { saveSessionData } from '../util/state/Load'
export default class BrowserFunc { export default class BrowserFunc {

View File

@@ -1,7 +1,7 @@
import { load } from 'cheerio' import { load } from 'cheerio'
import { Page } from 'rebrowser-playwright' import { Page } from 'rebrowser-playwright'
import { MicrosoftRewardsBot } from '../index' import { MicrosoftRewardsBot } from '../index'
import { logError } from '../util/Logger' import { logError } from '../util/notifications/Logger'
type DismissButton = { selector: string; label: string; isXPath?: boolean } type DismissButton = { selector: string; label: string; isXPath?: boolean }

View File

@@ -18,7 +18,7 @@ function parseEnvNumber(key: string, defaultValue: number, min: number, max: num
const parsed = Number(raw) const parsed = Number(raw)
if (!Number.isFinite(parsed)) { if (!Number.isFinite(parsed)) {
queueMicrotask(() => { queueMicrotask(() => {
import('./util/Logger').then(({ log }) => { import('./util/notifications/Logger').then(({ log }) => {
log('main', 'CONSTANTS', `Invalid ${key}="${raw}" (not a finite number), using default: ${defaultValue}`, 'warn') log('main', 'CONSTANTS', `Invalid ${key}="${raw}" (not a finite number), using default: ${defaultValue}`, 'warn')
}).catch(() => { }).catch(() => {
process.stderr.write(`[Constants] Invalid ${key}="${raw}" (not a finite number), using default: ${defaultValue}\n`) process.stderr.write(`[Constants] Invalid ${key}="${raw}" (not a finite number), using default: ${defaultValue}\n`)
@@ -29,7 +29,7 @@ function parseEnvNumber(key: string, defaultValue: number, min: number, max: num
if (parsed < min || parsed > max) { if (parsed < min || parsed > max) {
queueMicrotask(() => { queueMicrotask(() => {
import('./util/Logger').then(({ log }) => { import('./util/notifications/Logger').then(({ log }) => {
log('main', 'CONSTANTS', `${key}=${parsed} out of range [${min}, ${max}], using default: ${defaultValue}`, 'warn') log('main', 'CONSTANTS', `${key}=${parsed} out of range [${min}, ${max}], using default: ${defaultValue}`, 'warn')
}).catch(() => { }).catch(() => {
process.stderr.write(`[Constants] ${key}=${parsed} out of range [${min}, ${max}], using default: ${defaultValue}\n`) process.stderr.write(`[Constants] ${key}=${parsed} out of range [${min}, ${max}], using default: ${defaultValue}\n`)

View File

@@ -1,6 +1,6 @@
import type { MicrosoftRewardsBot } from '../index' import type { MicrosoftRewardsBot } from '../index'
import { log as botLog } from '../util/Logger' import { getErrorMessage } from '../util/core/Utils'
import { getErrorMessage } from '../util/Utils' import { log as botLog } from '../util/notifications/Logger'
import { dashboardState } from './state' import { dashboardState } from './state'
export class BotController { export class BotController {

View File

@@ -1,7 +1,7 @@
import { Request, Response, Router } from 'express' import { Request, Response, Router } from 'express'
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import { getConfigPath, loadAccounts, loadConfig } from '../util/Load' import { getConfigPath, loadAccounts, loadConfig } from '../util/state/Load'
import { botController } from './BotController' import { botController } from './BotController'
import { dashboardState } from './state' import { dashboardState } from './state'

View File

@@ -3,7 +3,7 @@ import fs from 'fs'
import { createServer } from 'http' import { createServer } from 'http'
import path from 'path' import path from 'path'
import { WebSocket, WebSocketServer } from 'ws' import { WebSocket, WebSocketServer } from 'ws'
import { log as botLog } from '../util/Logger' import { log as botLog } from '../util/notifications/Logger'
import { apiRouter } from './routes' import { apiRouter } from './routes'
import { DashboardLog, dashboardState } from './state' import { DashboardLog, dashboardState } from './state'

View File

@@ -12,7 +12,7 @@
import type { MicrosoftRewardsBot } from '../index' import type { MicrosoftRewardsBot } from '../index'
import type { Account } from '../interface/Account' import type { Account } from '../interface/Account'
import { closeBrowserSafely, createBrowserInstance } from '../util/BrowserFactory' import { closeBrowserSafely, createBrowserInstance } from '../util/browser/BrowserFactory'
import { handleCompromisedMode } from './FlowUtils' import { handleCompromisedMode } from './FlowUtils'
export interface DesktopFlowResult { export interface DesktopFlowResult {

View File

@@ -4,7 +4,7 @@
*/ */
import type { MicrosoftRewardsBot } from '../index' import type { MicrosoftRewardsBot } from '../index'
import { saveSessionData } from '../util/Load' import { saveSessionData } from '../util/state/Load'
/** /**
* Handle compromised/security check mode for an account * Handle compromised/security check mode for an account
@@ -38,7 +38,7 @@ export async function handleCompromisedMode(
// Send security alert webhook // Send security alert webhook
try { try {
const { ConclusionWebhook } = await import('../util/ConclusionWebhook') const { ConclusionWebhook } = await import('../util/notifications/ConclusionWebhook')
await ConclusionWebhook( await ConclusionWebhook(
bot.config, bot.config,
isMobile ? '🔐 Security Check (Mobile)' : '🔐 Security Check', isMobile ? '🔐 Security Check (Mobile)' : '🔐 Security Check',

View File

@@ -13,8 +13,8 @@
import type { MicrosoftRewardsBot } from '../index' import type { MicrosoftRewardsBot } from '../index'
import type { Account } from '../interface/Account' import type { Account } from '../interface/Account'
import { closeBrowserSafely, createBrowserInstance } from '../util/BrowserFactory' import { closeBrowserSafely, createBrowserInstance } from '../util/browser/BrowserFactory'
import { MobileRetryTracker } from '../util/MobileRetryTracker' import { MobileRetryTracker } from '../util/state/MobileRetryTracker'
import { handleCompromisedMode } from './FlowUtils' import { handleCompromisedMode } from './FlowUtils'
export interface MobileFlowResult { export interface MobileFlowResult {

View File

@@ -10,10 +10,10 @@
*/ */
import type { Config } from '../interface/Config' import type { Config } from '../interface/Config'
import { ConclusionWebhook } from '../util/ConclusionWebhook' import { ConclusionWebhook } from '../util/notifications/ConclusionWebhook'
import { JobState } from '../util/JobState' import { log } from '../util/notifications/Logger'
import { log } from '../util/Logger' import { Ntfy } from '../util/notifications/Ntfy'
import { Ntfy } from '../util/Ntfy' import { JobState } from '../util/state/JobState'
export interface AccountResult { export interface AccountResult {
email: string email: string

View File

@@ -5,11 +5,11 @@ import readline from 'readline'
import { MicrosoftRewardsBot } from '../index' import { MicrosoftRewardsBot } from '../index'
import { OAuth } from '../interface/OAuth' import { OAuth } from '../interface/OAuth'
import { saveSessionData } from '../util/Load' import { Retry } from '../util/core/Retry'
import { logError } from '../util/Logger' import { logError } from '../util/notifications/Logger'
import { LoginState, LoginStateDetector } from '../util/LoginStateDetector' import { generateTOTP } from '../util/security/Totp'
import { Retry } from '../util/Retry' import { saveSessionData } from '../util/state/Load'
import { generateTOTP } from '../util/Totp' import { LoginState, LoginStateDetector } from '../util/validation/LoginStateDetector'
// ------------------------------- // -------------------------------
// REFACTORING NOTE (1700+ lines) // REFACTORING NOTE (1700+ lines)
@@ -1603,7 +1603,7 @@ export class Login {
const level: 'warn' | 'error' = severity === 'critical' ? 'error' : 'warn' const level: 'warn' | 'error' = severity === 'critical' ? 'error' : 'warn'
this.bot.log(this.bot.isMobile, 'SECURITY', lines.join(' | '), level) this.bot.log(this.bot.isMobile, 'SECURITY', lines.join(' | '), level)
try { try {
const { ConclusionWebhook } = await import('../util/ConclusionWebhook') const { ConclusionWebhook } = await import('../util/notifications/ConclusionWebhook')
const fields = [ const fields = [
{ name: 'Account', value: incident.account }, { name: 'Account', value: incident.account },
...(incident.details?.length ? [{ name: 'Details', value: incident.details.join('\n') }] : []), ...(incident.details?.length ? [{ name: 'Details', value: incident.details.join('\n') }] : []),

View File

@@ -4,10 +4,10 @@ import { TIMEOUTS } from '../constants'
import { DashboardData, MorePromotion, PromotionalItem, PunchCard } from '../interface/DashboardData' import { DashboardData, MorePromotion, PromotionalItem, PunchCard } from '../interface/DashboardData'
import { MicrosoftRewardsBot } from '../index' import { MicrosoftRewardsBot } from '../index'
import { AdaptiveThrottler } from '../util/AdaptiveThrottler' import { Retry } from '../util/core/Retry'
import JobState from '../util/JobState' import { AdaptiveThrottler } from '../util/notifications/AdaptiveThrottler'
import { logError } from '../util/Logger' import { logError } from '../util/notifications/Logger'
import { Retry } from '../util/Retry' import JobState from '../util/state/JobState'
// Selector patterns (extracted to avoid magic strings) // Selector patterns (extracted to avoid magic strings)
const ACTIVITY_SELECTORS = { const ACTIVITY_SELECTORS = {

View File

@@ -7,16 +7,16 @@ import type { Page } from 'playwright'
import { createInterface } from 'readline' import { createInterface } from 'readline'
import BrowserFunc from './browser/BrowserFunc' import BrowserFunc from './browser/BrowserFunc'
import BrowserUtil from './browser/BrowserUtil' import BrowserUtil from './browser/BrowserUtil'
import Axios from './util/Axios' import Humanizer from './util/browser/Humanizer'
import { detectBanReason } from './util/BanDetector' import { formatDetailedError, normalizeRecoveryEmail, shortErrorMessage, Util } from './util/core/Utils'
import Humanizer from './util/Humanizer' import Axios from './util/network/Axios'
import JobState from './util/JobState' import { QueryDiversityEngine } from './util/network/QueryDiversityEngine'
import { loadAccounts, loadConfig } from './util/Load' import { log } from './util/notifications/Logger'
import { log } from './util/Logger' import JobState from './util/state/JobState'
import { MobileRetryTracker } from './util/MobileRetryTracker' import { loadAccounts, loadConfig } from './util/state/Load'
import { QueryDiversityEngine } from './util/QueryDiversityEngine' import { MobileRetryTracker } from './util/state/MobileRetryTracker'
import { StartupValidator } from './util/StartupValidator' import { detectBanReason } from './util/validation/BanDetector'
import { formatDetailedError, normalizeRecoveryEmail, shortErrorMessage, Util } from './util/Utils' import { StartupValidator } from './util/validation/StartupValidator'
import { Activities } from './functions/Activities' import { Activities } from './functions/Activities'
import { Login } from './functions/Login' import { Login } from './functions/Login'
@@ -629,7 +629,7 @@ export class MicrosoftRewardsBot {
try { try {
const h = this.config?.humanization const h = this.config?.humanization
if (!h || h.immediateBanAlert === false) return if (!h || h.immediateBanAlert === false) return
const { ConclusionWebhook } = await import('./util/ConclusionWebhook') const { ConclusionWebhook } = await import('./util/notifications/ConclusionWebhook')
await ConclusionWebhook( await ConclusionWebhook(
this.config, this.config,
'🚫 Ban Detected', '🚫 Ban Detected',
@@ -806,7 +806,7 @@ export class MicrosoftRewardsBot {
/** Send a strong alert to all channels and mention @everyone when entering global security standby. */ /** Send a strong alert to all channels and mention @everyone when entering global security standby. */
private async sendGlobalSecurityStandbyAlert(email: string, reason: string): Promise<void> { private async sendGlobalSecurityStandbyAlert(email: string, reason: string): Promise<void> {
try { try {
const { ConclusionWebhook } = await import('./util/ConclusionWebhook') const { ConclusionWebhook } = await import('./util/notifications/ConclusionWebhook')
await ConclusionWebhook( await ConclusionWebhook(
this.config, this.config,
'🚨 Critical Security Alert', '🚨 Critical Security Alert',

View File

@@ -6,8 +6,8 @@
*/ */
import type { BrowserContext } from 'rebrowser-playwright' import type { BrowserContext } from 'rebrowser-playwright'
import type { MicrosoftRewardsBot } from '../index' import type { MicrosoftRewardsBot } from '../../index'
import type { AccountProxy } from '../interface/Account' import type { AccountProxy } from '../../interface/Account'
/** /**
* Create a browser instance for the given account * Create a browser instance for the given account
@@ -26,7 +26,7 @@ export async function createBrowserInstance(
proxy: AccountProxy, proxy: AccountProxy,
email: string email: string
): Promise<BrowserContext> { ): Promise<BrowserContext> {
const browserModule = await import('../browser/Browser') const browserModule = await import('../../browser/Browser')
const Browser = browserModule.default const Browser = browserModule.default
const browserInstance = new Browser(bot) const browserInstance = new Browser(bot)
return await browserInstance.createBrowser(proxy, email) return await browserInstance.createBrowser(proxy, email)

View File

@@ -1,6 +1,6 @@
import { Page } from 'rebrowser-playwright' import { Page } from 'rebrowser-playwright'
import { Util } from './Utils' import type { ConfigHumanization } from '../../interface/Config'
import type { ConfigHumanization } from '../interface/Config' import { Util } from '../core/Utils'
export class Humanizer { export class Humanizer {
private util: Util private util: Util

View File

@@ -1,8 +1,8 @@
import axios from 'axios' import axios from 'axios'
import { BrowserFingerprintWithHeaders } from 'fingerprint-generator' import { BrowserFingerprintWithHeaders } from 'fingerprint-generator'
import { Architecture, ChromeVersion, EdgeVersion, Platform } from '../interface/UserAgentUtil' import { Architecture, ChromeVersion, EdgeVersion, Platform } from '../../interface/UserAgentUtil'
import { log } from './Logger' import { Retry } from '../core/Retry'
import { Retry } from './Retry' import { log } from '../notifications/Logger'
interface UserAgentMetadata { interface UserAgentMetadata {
mobile: boolean mobile: boolean

View File

@@ -1,4 +1,4 @@
import type { ConfigRetryPolicy } from '../interface/Config' import type { ConfigRetryPolicy } from '../../interface/Config'
import { Util } from './Utils' import { Util } from './Utils'
type NumericPolicy = { type NumericPolicy = {

View File

@@ -2,7 +2,7 @@ import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } f
import { HttpProxyAgent } from 'http-proxy-agent' import { HttpProxyAgent } from 'http-proxy-agent'
import { HttpsProxyAgent } from 'https-proxy-agent' import { HttpsProxyAgent } from 'https-proxy-agent'
import { SocksProxyAgent } from 'socks-proxy-agent' import { SocksProxyAgent } from 'socks-proxy-agent'
import { AccountProxy } from '../interface/Account' import { AccountProxy } from '../../interface/Account'
class AxiosClient { class AxiosClient {
private instance: AxiosInstance private instance: AxiosInstance

View File

@@ -1,5 +1,5 @@
import axios from 'axios' import axios from 'axios'
import { Util } from './Utils' import { Util } from '../core/Utils'
export interface QueryDiversityConfig { export interface QueryDiversityConfig {
sources: Array<'google-trends' | 'reddit' | 'news' | 'wikipedia' | 'local-fallback'> sources: Array<'google-trends' | 'reddit' | 'news' | 'wikipedia' | 'local-fallback'>

View File

@@ -1,8 +1,8 @@
import axios from 'axios' import axios from 'axios'
import { Config } from '../interface/Config' import { DISCORD } from '../../constants'
import { Ntfy } from './Ntfy' import { Config } from '../../interface/Config'
import { log } from './Logger' import { log } from './Logger'
import { DISCORD } from '../constants' import { Ntfy } from './Ntfy'
interface DiscordField { interface DiscordField {
name: string name: string

View File

@@ -1,6 +1,6 @@
import axios from 'axios' import axios from 'axios'
import { DISCORD } from '../constants' import { DISCORD } from '../../constants'
import { Config } from '../interface/Config' import { Config } from '../../interface/Config'
interface ErrorReportPayload { interface ErrorReportPayload {
error: string error: string

View File

@@ -1,8 +1,8 @@
import axios from 'axios' import axios from 'axios'
import chalk from 'chalk' import chalk from 'chalk'
import { DISCORD, LOGGER_CLEANUP } from '../constants' import { DISCORD, LOGGER_CLEANUP } from '../../constants'
import { loadConfig } from '../state/Load'
import { sendErrorReport } from './ErrorReportingWebhook' import { sendErrorReport } from './ErrorReportingWebhook'
import { loadConfig } from './Load'
import { Ntfy } from './Ntfy' import { Ntfy } from './Ntfy'
/** /**

View File

@@ -1,5 +1,5 @@
import { loadConfig } from './Load'
import axios from 'axios' import axios from 'axios'
import { loadConfig } from '../state/Load'
const NOTIFICATION_TYPES = { const NOTIFICATION_TYPES = {
error: { priority: 'max', tags: 'rotating_light' }, // Customize the ERROR icon here, see: https://docs.ntfy.sh/emojis/ error: { priority: 'max', tags: 'rotating_light' }, // Customize the ERROR icon here, see: https://docs.ntfy.sh/emojis/

View File

@@ -1,6 +1,6 @@
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import type { Config } from '../interface/Config' import type { Config } from '../../interface/Config'
type AccountCompletionMeta = { type AccountCompletionMeta = {
runId?: string runId?: string

View File

@@ -2,9 +2,9 @@ import { BrowserFingerprintWithHeaders } from 'fingerprint-generator'
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import { BrowserContext, Cookie } from 'rebrowser-playwright' import { BrowserContext, Cookie } from 'rebrowser-playwright'
import { Account } from '../interface/Account' import { Account } from '../../interface/Account'
import { Config, ConfigBrowser, ConfigSaveFingerprint, ConfigScheduling } from '../interface/Config' import { Config, ConfigBrowser, ConfigSaveFingerprint, ConfigScheduling } from '../../interface/Config'
import { Util } from './Utils' import { Util } from '../core/Utils'
const utils = new Util() const utils = new Util()

View File

@@ -1,9 +1,9 @@
import chalk from 'chalk' import chalk from 'chalk'
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import { Account } from '../interface/Account' import { Account } from '../../interface/Account'
import { Config } from '../interface/Config' import { Config } from '../../interface/Config'
import { log } from './Logger' import { log } from '../notifications/Logger'
interface ValidationError { interface ValidationError {
severity: 'error' | 'warning' severity: 'error' | 'warning'