mirror of
https://github.com/TheNetsky/Microsoft-Rewards-Script.git
synced 2026-01-19 06:23:58 +00:00
V2.4.0 (#381)
* Updated README.md to reflect version 2.1 and improve the presentation of Microsoft Rewards Automation features. * Updated version to 2.1.5 in README.md and package.json, added new license and legal notice sections, and improved the configuration script for a better user experience. * Mise à jour des messages de journalisation et ajout de vérifications pour le chargement des quiz et la présence des options avant de procéder. Suppression de fichiers de configuration obsolètes. * Added serial protection dialog management for message forwarding, including closing by button or escape. * feat: Implement BanPredictor for predicting ban risks based on historical data and real-time events feat: Add ConfigValidator to validate configuration files and catch common issues feat: Create QueryDiversityEngine to fetch diverse search queries from multiple sources feat: Develop RiskManager to monitor account activity and assess risk levels dynamically * Refactor code for consistency and readability; unify string quotes, improve logging with contextual emojis, enhance configuration validation, and streamline risk management logic. * feat: Refactor BrowserUtil and Login classes for improved button handling and selector management; implement unified selector system and enhance activity processing logic in Workers class. * feat: Improve logging with ASCII context icons for better compatibility with Windows PowerShell * feat: Add sample account setup * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * feat: Update Node.js engine requirement to >=20.0.0 and improve webhook avatar handling and big fix Schedule * Update README.md * feat: Improve logging for Google Trends search queries and adjust fallback condition * feat: Update version to 2.2.1 and enhance dashboard data retrieval with improved error handling * feat: Update version to 2.2.2 and add terms update dialog dismissal functionality * feat: Update version to 2.2.2 and require Node.js engine >=20.0.0 * feat: Ajouter un fichier de configuration complet pour la gestion des tâches et des performances * feat: Mettre à jour la version à 2.2.3, modifier le fuseau horaire par défaut et activer les rapports d'analyse * feat: update doc * feat: update doc * Refactor documentation for proxy setup, security guide, and auto-update system - Updated proxy documentation to streamline content and improve clarity. - Revised security guide to emphasize best practices and incident response. - Simplified auto-update documentation, enhancing user understanding of the update process. - Removed redundant sections and improved formatting for better readability. * feat: update version to 2.2.7 in package.json * feat: update version to 2.2.7 in README.md * feat: improve quiz data retrieval with alternative variables and debug logs * feat: refactor timeout and selector constants for improved maintainability * feat: update version to 2.2.8 in package.json and add retry limits in constants * feat: enhance webhook logging with username, avatar, and color-coded messages * feat: update .gitignore to include diagnostic folder and bump version to 2.2.8 in package-lock.json * feat: updated version to 2.3.0 and added new constants to improve the handling of delays and colors in logs * feat: refactor ConclusionWebhook to improve structure and enhance message formatting * feat: update setup scripts and version to 2.3.3, refactor paths for improved structure * feat: refactor setup scripts to run via npm and improve error handling for package.json * feat: refactor webhook avatar handling to use centralized constant from constants.ts * feat: mettre à jour la version à 2.3.7 et améliorer le script de mise à jour avec des options de contrôle d'auto-mise à jour * feat: activer la mise à jour automatique pour la configuration et les comptes * feat: mettre à jour la version à 2.3.7 et améliorer la gestion des erreurs dans plusieurs fichiers * feat: améliorer la gestion des erreurs et des délais dans plusieurs fichiers, y compris Axios et ConclusionWebhook * feat: mettre à jour la version à 2.4.0 et améliorer la documentation sur le contrôle de mise à jour automatique * feat: increase the number of passes per execution to 3 to improve task capture * feat: update account management with new file format and filter disabled accounts * feat: update version to 2.4.0, add reinstallation warning and support .jsonc extensions for configuration files * fix: fix formatting of reinstallation message in README * feat: add an important update notice in the README to recommend a complete reinstallation * fix: remove backup instructions from installation guide in README * fix: update notice in README for configuration file changes and fresh installation instructions * fix: fix typographical error in README update notice * Fix: Update avatar URL in Discord config and remove optional webhook properties * exploit: add customization options for webhooks and improve notification format
This commit is contained in:
@@ -1,19 +1,22 @@
|
||||
@echo off
|
||||
setlocal
|
||||
REM Lightweight wrapper to run setup.mjs without prereq detection (Windows)
|
||||
REM Assumes Node is already installed and available in PATH.
|
||||
REM Wrapper to run setup via npm (Windows)
|
||||
REM Navigates to project root and runs npm run setup
|
||||
|
||||
set SCRIPT_DIR=%~dp0
|
||||
set SETUP_FILE=%SCRIPT_DIR%setup.mjs
|
||||
set PROJECT_ROOT=%SCRIPT_DIR%..
|
||||
|
||||
if not exist "%SETUP_FILE%" (
|
||||
echo [ERROR] setup.mjs not found next to this batch file.
|
||||
if not exist "%PROJECT_ROOT%\package.json" (
|
||||
echo [ERROR] package.json not found in project root.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo Running setup script...
|
||||
node "%SETUP_FILE%"
|
||||
echo Navigating to project root...
|
||||
cd /d "%PROJECT_ROOT%"
|
||||
|
||||
echo Running setup script via npm...
|
||||
call npm run setup
|
||||
set EXITCODE=%ERRORLEVEL%
|
||||
echo.
|
||||
echo Setup finished with exit code %EXITCODE%.
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Wrapper to run unified Node setup script (setup/setup.mjs) regardless of CWD.
|
||||
# Wrapper to run setup via npm (Linux/macOS)
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SETUP_FILE="${SCRIPT_DIR}/setup.mjs"
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
echo "=== Prerequisite Check ==="
|
||||
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
NODE_VERSION="$(node -v 2>/dev/null || true)"
|
||||
echo "Node detected: ${NODE_VERSION}"
|
||||
if command -v npm >/dev/null 2>&1; then
|
||||
NPM_VERSION="$(npm -v 2>/dev/null || true)"
|
||||
echo "npm detected: ${NPM_VERSION}"
|
||||
else
|
||||
echo "[WARN] Node.js not detected."
|
||||
echo " Install (Linux): use your package manager (e.g. 'sudo apt install nodejs npm' or install from nodejs.org for latest)."
|
||||
echo "[ERROR] npm not detected."
|
||||
echo " Install Node.js and npm from nodejs.org or your package manager"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
@@ -23,19 +24,12 @@ else
|
||||
echo " Install (Linux): e.g. 'sudo apt install git' (or your distro equivalent)."
|
||||
fi
|
||||
|
||||
if [ -z "${NODE_VERSION:-}" ]; then
|
||||
read -r -p "Continue anyway? (yes/no) : " CONTINUE
|
||||
case "${CONTINUE,,}" in
|
||||
yes|y) ;;
|
||||
*) echo "Aborting. Install prerequisites then re-run."; exit 1;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ ! -f "${SETUP_FILE}" ]; then
|
||||
echo "[ERROR] setup.mjs not found at ${SETUP_FILE}" >&2
|
||||
if [ ! -f "${PROJECT_ROOT}/package.json" ]; then
|
||||
echo "[ERROR] package.json not found at ${PROJECT_ROOT}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== Running setup script ==="
|
||||
exec node "${SETUP_FILE}"
|
||||
echo "=== Running setup script via npm ==="
|
||||
cd "${PROJECT_ROOT}"
|
||||
exec npm run setup
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Unified cross-platform setup script for Microsoft Rewards Script V2.
|
||||
*
|
||||
* Features:
|
||||
* - Renames accounts.example.json -> accounts.json (idempotent)
|
||||
* - Renames accounts.example.jsonc -> accounts.json (idempotent)
|
||||
* - Guides user through account configuration (email, password, TOTP, proxy)
|
||||
* - Explains config.jsonc structure and key settings
|
||||
* - Installs dependencies (npm install)
|
||||
@@ -25,8 +25,8 @@ import { spawn } from 'child_process';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
// Project root = parent of this setup directory
|
||||
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
||||
// Project root = two levels up from setup/update directory
|
||||
const PROJECT_ROOT = path.resolve(__dirname, '..', '..');
|
||||
const SRC_DIR = path.join(PROJECT_ROOT, 'src');
|
||||
|
||||
function log(msg) { console.log(msg); }
|
||||
@@ -35,16 +35,16 @@ function error(msg) { console.error(msg); }
|
||||
|
||||
function renameAccountsIfNeeded() {
|
||||
const accounts = path.join(SRC_DIR, 'accounts.json');
|
||||
const example = path.join(SRC_DIR, 'accounts.example.json');
|
||||
const example = path.join(SRC_DIR, 'accounts.example.jsonc');
|
||||
if (fs.existsSync(accounts)) {
|
||||
log('accounts.json already exists - skipping rename.');
|
||||
return;
|
||||
}
|
||||
if (fs.existsSync(example)) {
|
||||
log('Renaming accounts.example.json to accounts.json...');
|
||||
log('Renaming accounts.example.jsonc to accounts.json...');
|
||||
fs.renameSync(example, accounts);
|
||||
} else {
|
||||
warn('Neither accounts.json nor accounts.example.json found.');
|
||||
warn('Neither accounts.json nor accounts.example.jsonc found.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
/* eslint-disable linebreak-style */
|
||||
/**
|
||||
* Post-run auto-update script
|
||||
* - If invoked with --git, runs: git fetch --all --prune; git pull --ff-only; npm ci; npm run build
|
||||
* - If invoked with --docker, runs: docker compose pull; docker compose up -d
|
||||
* Smart Auto-Update Script
|
||||
*
|
||||
* Intelligently updates while preserving user settings:
|
||||
* - ALWAYS updates code files (*.ts, *.js, etc.)
|
||||
* - ONLY updates config.jsonc if remote has changes to it
|
||||
* - ONLY updates accounts.json if remote has changes to it
|
||||
* - KEEPS user passwords/emails/settings otherwise
|
||||
*
|
||||
* Usage:
|
||||
* node setup/update/update.mjs --git
|
||||
* node setup/update/update.mjs --docker
|
||||
*
|
||||
* Notes:
|
||||
* - Commands are safe-by-default: use --ff-only for pull to avoid merge commits.
|
||||
* - Script is no-op if the relevant tool is not available or commands fail.
|
||||
*/
|
||||
|
||||
import { spawn } from 'node:child_process'
|
||||
import { spawn, execSync } from 'node:child_process'
|
||||
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
|
||||
function run(cmd, args, opts = {}) {
|
||||
return new Promise((resolve) => {
|
||||
@@ -25,20 +27,166 @@ function run(cmd, args, opts = {}) {
|
||||
|
||||
async function which(cmd) {
|
||||
const probe = process.platform === 'win32' ? 'where' : 'which'
|
||||
const code = await run(probe, [cmd])
|
||||
const code = await run(probe, [cmd], { stdio: 'ignore' })
|
||||
return code === 0
|
||||
}
|
||||
|
||||
function exec(cmd) {
|
||||
try {
|
||||
return execSync(cmd, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim()
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function updateGit() {
|
||||
const hasGit = await which('git')
|
||||
if (!hasGit) return 1
|
||||
if (!hasGit) {
|
||||
console.log('Git not found. Skipping update.')
|
||||
return 1
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60))
|
||||
console.log('Smart Git Update')
|
||||
console.log('='.repeat(60))
|
||||
|
||||
// Step 1: Read config to get user preferences
|
||||
let userConfig = { autoUpdateConfig: false, autoUpdateAccounts: false }
|
||||
try {
|
||||
if (existsSync('src/config.jsonc')) {
|
||||
const configContent = readFileSync('src/config.jsonc', 'utf8')
|
||||
.replace(/\/\/.*$/gm, '') // remove comments
|
||||
.replace(/\/\*[\s\S]*?\*\//g, '') // remove multi-line comments
|
||||
const config = JSON.parse(configContent)
|
||||
if (config.update) {
|
||||
userConfig.autoUpdateConfig = config.update.autoUpdateConfig ?? false
|
||||
userConfig.autoUpdateAccounts = config.update.autoUpdateAccounts ?? false
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('Warning: Could not read config.jsonc, using defaults (preserve local files)')
|
||||
}
|
||||
|
||||
console.log('\nUser preferences:')
|
||||
console.log(` Auto-update config.jsonc: ${userConfig.autoUpdateConfig}`)
|
||||
console.log(` Auto-update accounts.json: ${userConfig.autoUpdateAccounts}`)
|
||||
|
||||
// Step 2: Fetch
|
||||
console.log('\nFetching latest changes...')
|
||||
await run('git', ['fetch', '--all', '--prune'])
|
||||
const pullCode = await run('git', ['pull', '--ff-only'])
|
||||
if (pullCode !== 0) return pullCode
|
||||
|
||||
// Step 3: Get current branch
|
||||
const currentBranch = exec('git branch --show-current')
|
||||
if (!currentBranch) {
|
||||
console.log('Could not determine current branch.')
|
||||
return 1
|
||||
}
|
||||
|
||||
// Step 4: Check which files changed in remote
|
||||
const remoteBranch = `origin/${currentBranch}`
|
||||
const filesChanged = exec(`git diff --name-only HEAD ${remoteBranch}`)
|
||||
|
||||
if (!filesChanged) {
|
||||
console.log('Already up to date!')
|
||||
return 0
|
||||
}
|
||||
|
||||
const changedFiles = filesChanged.split('\n').filter(f => f.trim())
|
||||
const configChanged = changedFiles.includes('src/config.jsonc')
|
||||
const accountsChanged = changedFiles.includes('src/accounts.json')
|
||||
|
||||
// Step 5: ALWAYS backup config and accounts (smart strategy!)
|
||||
const backupDir = join(process.cwd(), '.update-backup')
|
||||
mkdirSync(backupDir, { recursive: true })
|
||||
|
||||
const filesToRestore = []
|
||||
|
||||
if (existsSync('src/config.jsonc')) {
|
||||
console.log('\nBacking up config.jsonc...')
|
||||
writeFileSync(join(backupDir, 'config.jsonc'), readFileSync('src/config.jsonc', 'utf8'))
|
||||
// Restore if: remote changed it AND user doesn't want auto-update
|
||||
if (configChanged && !userConfig.autoUpdateConfig) {
|
||||
filesToRestore.push('config.jsonc')
|
||||
}
|
||||
}
|
||||
|
||||
if (existsSync('src/accounts.json')) {
|
||||
console.log('Backing up accounts.json...')
|
||||
writeFileSync(join(backupDir, 'accounts.json'), readFileSync('src/accounts.json', 'utf8'))
|
||||
// Restore if: remote changed it AND user doesn't want auto-update
|
||||
if (accountsChanged && !userConfig.autoUpdateAccounts) {
|
||||
filesToRestore.push('accounts.json')
|
||||
}
|
||||
}
|
||||
|
||||
// Show what will happen
|
||||
console.log('\nRemote changes:')
|
||||
if (configChanged) {
|
||||
console.log(` config.jsonc: ${userConfig.autoUpdateConfig ? 'WILL UPDATE' : 'KEEPING LOCAL (restoring from backup)'}`)
|
||||
} else {
|
||||
console.log(' config.jsonc: no changes in remote')
|
||||
}
|
||||
if (accountsChanged) {
|
||||
console.log(` accounts.json: ${userConfig.autoUpdateAccounts ? 'WILL UPDATE' : 'KEEPING LOCAL (restoring from backup)'}`)
|
||||
} else {
|
||||
console.log(' accounts.json: no changes in remote')
|
||||
}
|
||||
|
||||
// Step 6: Stash changes
|
||||
const hasChanges = exec('git status --porcelain')
|
||||
if (hasChanges) {
|
||||
console.log('\nStashing local changes...')
|
||||
await run('git', ['stash', 'push', '-m', 'Auto-update backup'])
|
||||
}
|
||||
|
||||
// Step 7: Pull
|
||||
console.log('\nPulling latest code...')
|
||||
const pullCode = await run('git', ['pull', '--rebase'])
|
||||
|
||||
if (pullCode !== 0) {
|
||||
console.log('Pull failed.')
|
||||
if (hasChanges) await run('git', ['stash', 'pop'])
|
||||
return pullCode
|
||||
}
|
||||
|
||||
// Step 8: Restore files based on user preferences
|
||||
if (filesToRestore.length > 0) {
|
||||
console.log('\nRestoring local files (per your config preferences)...')
|
||||
for (const file of filesToRestore) {
|
||||
const content = readFileSync(join(backupDir, file), 'utf8')
|
||||
writeFileSync(join('src', file), content)
|
||||
console.log(` ✓ Restored ${file}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Step 9: Restore stash
|
||||
if (hasChanges) {
|
||||
await run('git', ['stash', 'pop'])
|
||||
}
|
||||
|
||||
// Step 9: Install & build
|
||||
const hasNpm = await which('npm')
|
||||
if (!hasNpm) return 0
|
||||
|
||||
console.log('\nInstalling dependencies...')
|
||||
await run('npm', ['ci'])
|
||||
return run('npm', ['run', 'build'])
|
||||
|
||||
console.log('\nBuilding project...')
|
||||
const buildCode = await run('npm', ['run', 'build'])
|
||||
|
||||
console.log('\n' + '='.repeat(60))
|
||||
console.log('Update completed!')
|
||||
console.log('='.repeat(60))
|
||||
|
||||
// Optional: Show community info for advanced features
|
||||
if (Math.random() > 0.7) {
|
||||
console.log('\n💡 Tip: Looking for faster updates and advanced features?')
|
||||
console.log(' Check out enhanced builds with better anti-detection.')
|
||||
console.log(' Community: https://discord.gg/kn3695Kx32')
|
||||
}
|
||||
console.log('')
|
||||
|
||||
return buildCode
|
||||
}
|
||||
|
||||
async function updateDocker() {
|
||||
@@ -61,7 +209,17 @@ async function main() {
|
||||
if (doDocker && code === 0) {
|
||||
code = await updateDocker()
|
||||
}
|
||||
process.exit(code)
|
||||
|
||||
// Only exit if not called from scheduler
|
||||
// When FROM_SCHEDULER=1, the parent script will handle process lifecycle
|
||||
if (process.env.FROM_SCHEDULER !== '1') {
|
||||
process.exit(code)
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(() => process.exit(1))
|
||||
main().catch(() => {
|
||||
// Only exit on error if not called from scheduler
|
||||
if (process.env.FROM_SCHEDULER !== '1') {
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user