feat: Add recovery email and 2FA support to account creation process

This commit is contained in:
2025-11-09 12:43:31 +01:00
parent e495fa18b2
commit cbe9a11f95
5 changed files with 500 additions and 49 deletions

View File

@@ -128,29 +128,58 @@ Access at `http://localhost:3000` to:
## 🆕 Account Creator (BETA)
Automatically create new Microsoft accounts with referral link support:
Automatically create new Microsoft accounts with advanced security features:
```bash
# Create account without referral
# Basic account creation
npm run creator
# Create account with your referral link
# With referral link (earn rewards credit)
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE&ref=rafsrchae
# With recovery email for account security
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE -r backup@gmail.com
# With 2FA enabled automatically
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE --2fa
# Full automation mode (skip all prompts)
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE -r backup@gmail.com -y --2fa
```
**Features:**
- 🎯 Language-independent (works in any language)
- 🔐 Generates strong passwords automatically
- 📧 Creates unique email addresses
- 🎂 Realistic birthdates (18-50 years old)
- 🤖 CAPTCHA support (manual solving required)
- 💾 Saves all account details to `accounts-created/` directory
**Features:**
- 🎯 **Language-independent** — Works in any language
- 🔐 **Strong passwords** — Automatically generated (12-16 chars)
- 📧 **Realistic emails** — 200+ name database for natural-looking addresses
- 🎂 **Natural birthdates** — Random age 18-50 years old
- 🛡️ **Recovery email** — Optional backup email for account recovery
- 🔒 **2FA support** — TOTP authentication with Google Authenticator
- 🔑 **TOTP secrets** — Extracts and saves secret keys
- 💾 **Complete backups** — Saves all details including recovery codes
- 🤖 **CAPTCHA support** — Manual solving (human verification)
- <20> **Organized storage** — Individual files per account
**What happens:**
1. Opens browser to Microsoft signup page
2. Automatically fills email, password, birthdate, and name
3. Waits for you to solve CAPTCHA
4. Saves complete account info to file
**🎛️ Command Arguments:**
- `<url>` — Referral URL (optional)
- `-r <email>` — Recovery email address
- `-y` — Auto-accept mode (skip prompts)
- `--2fa` — Enable 2FA automatically
**📋 What happens:**
1. Creates Microsoft account (email, password, birthdate, names)
2. Enrolls in Microsoft Rewards (if referral URL provided)
3. **[Optional]** Adds recovery email with verification
4. **[Optional]** Sets up 2FA with TOTP (Google Authenticator compatible)
5. Extracts and saves TOTP secret key and recovery code
6. Saves complete account info to `accounts-created/` directory
**🔐 Saved Information:**
- Email and password
- Full name and birthdate
- Referral URL (if used)
- Recovery email (if added)
- TOTP secret key (for authenticator apps)
- 5-part recovery code (emergency access)
**[📖 Full Account Creator Guide](src/account-creation/README.md)**

View File

@@ -10,11 +10,17 @@ export class AccountCreator {
private page!: Page
private dataGenerator: DataGenerator
private referralUrl?: string
private recoveryEmail?: string
private autoAccept: boolean
private enable2FA: boolean
private rl: readline.Interface
private rlClosed = false
constructor(referralUrl?: string) {
constructor(referralUrl?: string, recoveryEmail?: string, autoAccept = false, enable2FA = false) {
this.referralUrl = referralUrl
this.recoveryEmail = recoveryEmail
this.autoAccept = autoAccept
this.enable2FA = enable2FA
this.dataGenerator = new DataGenerator()
this.rl = readline.createInterface({
input: process.stdin,
@@ -619,6 +625,28 @@ export class AccountCreator {
// Navigate to Bing Rewards and verify connection
await this.verifyAccountActive()
// Post-setup: Recovery email & 2FA
let recoveryEmailUsed: string | undefined
let totpSecret: string | undefined
let recoveryCode: string | undefined
try {
// Setup recovery email if requested
const emailResult = await this.setupRecoveryEmail(confirmedEmail)
if (emailResult) recoveryEmailUsed = emailResult
// Setup 2FA if requested
if (this.enable2FA || (!this.autoAccept && await this.ask2FASetup())) {
const tfaResult = await this.setup2FA()
if (tfaResult) {
totpSecret = tfaResult.totpSecret
recoveryCode = tfaResult.recoveryCode
}
}
} catch (error) {
log(false, 'CREATOR', `Post-setup error: ${error}`, 'warn', 'yellow')
}
// Create account object
const createdAccount: CreatedAccount = {
email: confirmedEmail,
@@ -631,7 +659,10 @@ export class AccountCreator {
firstName: names.firstName,
lastName: names.lastName,
createdAt: new Date().toISOString(),
referralUrl: this.referralUrl
referralUrl: this.referralUrl,
recoveryEmail: recoveryEmailUsed,
totpSecret: totpSecret,
recoveryCode: recoveryCode
}
// Save to file
@@ -2173,4 +2204,216 @@ ${JSON.stringify(accountData, null, 2)}`
await this.page.close()
}
}
/**
* Setup recovery email for the account
*/
private async setupRecoveryEmail(currentEmail: string): Promise<string | undefined> {
try {
log(false, 'CREATOR', '📧 Setting up recovery email...', 'log', 'cyan')
// Navigate to proofs manage page
await this.page.goto('https://account.live.com/proofs/manage/', {
waitUntil: 'networkidle',
timeout: 30000
})
await this.humanDelay(2000, 3000)
// Check if we're on the "Add security info" page
const addProofTitle = await this.page.locator('#iPageTitle').textContent().catch(() => '')
if (!addProofTitle || !addProofTitle.includes('protect your account')) {
log(false, 'CREATOR', 'Already on security dashboard', 'log', 'gray')
return undefined
}
log(false, 'CREATOR', '🔒 Security setup page detected', 'log', 'yellow')
// Get recovery email
let recoveryEmailToUse = this.recoveryEmail
if (!recoveryEmailToUse && !this.autoAccept) {
recoveryEmailToUse = await this.askRecoveryEmail()
}
if (!recoveryEmailToUse) {
log(false, 'CREATOR', 'Skipping recovery email setup', 'log', 'gray')
return undefined
}
log(false, 'CREATOR', `Using recovery email: ${recoveryEmailToUse}`, 'log', 'cyan')
// Fill email input
const emailInput = this.page.locator('#EmailAddress').first()
await emailInput.fill(recoveryEmailToUse)
await this.humanDelay(500, 1000)
// Click Next
const nextButton = this.page.locator('#iNext').first()
await nextButton.click()
log(false, 'CREATOR', '📨 Code sent to recovery email', 'log', 'green')
log(false, 'CREATOR', '⏳ Please enter the code you received and click Next', 'log', 'yellow')
log(false, 'CREATOR', 'Waiting for you to complete verification...', 'log', 'cyan')
// Wait for URL change (user completes verification)
await this.page.waitForURL((url) => !url.href.includes('/proofs/Verify'), { timeout: 300000 })
log(false, 'CREATOR', '✅ Recovery email verified!', 'log', 'green')
// Click OK on "Quick note" page if present
await this.humanDelay(2000, 3000)
const okButton = this.page.locator('button:has-text("OK")').first()
const okVisible = await okButton.isVisible({ timeout: 5000 }).catch(() => false)
if (okVisible) {
await okButton.click()
await this.humanDelay(1000, 2000)
log(false, 'CREATOR', '✅ Clicked OK on info page', 'log', 'green')
}
return recoveryEmailToUse
} catch (error) {
log(false, 'CREATOR', `Recovery email setup error: ${error}`, 'warn', 'yellow')
return undefined
}
}
/**
* Ask user for recovery email (interactive)
*/
private async askRecoveryEmail(): Promise<string | undefined> {
return new Promise((resolve) => {
this.rl.question('📧 Enter recovery email (or press Enter to skip): ', (answer) => {
const email = answer.trim()
if (email && email.includes('@')) {
resolve(email)
} else {
resolve(undefined)
}
})
})
}
/**
* Ask user if they want 2FA setup
*/
private async ask2FASetup(): Promise<boolean> {
return new Promise((resolve) => {
this.rl.question('🔐 Enable two-factor authentication? (y/n): ', (answer) => {
resolve(answer.trim().toLowerCase() === 'y')
})
})
}
/**
* Setup 2FA with TOTP
*/
private async setup2FA(): Promise<{ totpSecret: string; recoveryCode: string | undefined } | undefined> {
try {
log(false, 'CREATOR', '🔐 Setting up 2FA...', 'log', 'cyan')
// Navigate to 2FA setup page
await this.page.goto('https://account.live.com/proofs/EnableTfa', {
waitUntil: 'networkidle',
timeout: 30000
})
await this.humanDelay(2000, 3000)
// Click Next
const submitButton = this.page.locator('#EnableTfaSubmit').first()
await submitButton.click()
await this.humanDelay(2000, 3000)
// Click "set up a different Authenticator app"
const altAppLink = this.page.locator('#iSelectProofTypeAlternate').first()
const altAppVisible = await altAppLink.isVisible({ timeout: 5000 }).catch(() => false)
if (altAppVisible) {
await altAppLink.click()
await this.humanDelay(2000, 3000)
}
// Click "I can't scan the bar code"
const cantScanLink = this.page.locator('#iShowPlainLink').first()
await cantScanLink.click()
await this.humanDelay(1000, 2000)
// Extract TOTP secret
const secretElement = this.page.locator('#iTOTP_Secret, #totpSecret, [id*="secret"]').first()
const totpSecret = await secretElement.textContent().catch(() => '')
if (!totpSecret) {
log(false, 'CREATOR', '❌ Could not find TOTP secret', 'error')
return undefined
}
log(false, 'CREATOR', `🔑 TOTP Secret: ${totpSecret}`, 'log', 'green')
log(false, 'CREATOR', '⚠️ SAVE THIS SECRET - You will need it to generate codes!', 'warn', 'yellow')
// Click "I'll scan a bar code instead" to go back
await cantScanLink.click()
await this.humanDelay(1000, 2000)
log(false, 'CREATOR', '📱 Please scan the QR code with Google Authenticator or similar app', 'log', 'yellow')
log(false, 'CREATOR', '⏳ Then enter the 6-digit code and click Next', 'log', 'cyan')
log(false, 'CREATOR', 'Waiting for you to complete setup...', 'log', 'cyan')
// Wait for "Two-step verification is turned on" page
await this.page.waitForSelector('#RecoveryCode', { timeout: 300000 })
log(false, 'CREATOR', '✅ 2FA enabled!', 'log', 'green')
// Extract recovery code
const recoveryElement = this.page.locator('#NewRecoveryCode').first()
const recoveryText = await recoveryElement.textContent().catch(() => '') || ''
const recoveryMatch = recoveryText.match(/([A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5})/)
const recoveryCode = recoveryMatch ? recoveryMatch[1] : ''
if (recoveryCode) {
log(false, 'CREATOR', `🔐 Recovery Code: ${recoveryCode}`, 'log', 'green')
log(false, 'CREATOR', '⚠️ SAVE THIS CODE - You can use it to recover your account!', 'warn', 'yellow')
} else {
log(false, 'CREATOR', '⚠️ Could not extract recovery code', 'warn', 'yellow')
}
// Click Next
await this.humanDelay(2000, 3000)
const recoveryNextButton = this.page.locator('#iOptTfaEnabledRecoveryCodeNext').first()
await recoveryNextButton.click()
// Click Next again
await this.humanDelay(2000, 3000)
const nextButton2 = this.page.locator('#iOptTfaEnabledNext').first()
const next2Visible = await nextButton2.isVisible({ timeout: 3000 }).catch(() => false)
if (next2Visible) {
await nextButton2.click()
await this.humanDelay(2000, 3000)
}
// Click Finish
const finishButton = this.page.locator('#EnableTfaFinish').first()
const finishVisible = await finishButton.isVisible({ timeout: 3000 }).catch(() => false)
if (finishVisible) {
await finishButton.click()
await this.humanDelay(1000, 2000)
}
log(false, 'CREATOR', '✅ 2FA setup complete!', 'log', 'green')
if (!totpSecret) {
log(false, 'CREATOR', '❌ TOTP secret missing - 2FA may not work', 'error')
return undefined
}
return { totpSecret, recoveryCode }
} catch (error) {
log(false, 'CREATOR', `2FA setup error: ${error}`, 'warn', 'yellow')
return undefined
}
}
}

View File

@@ -26,11 +26,48 @@ Already integrated - no additional setup needed!
### Command Line
```bash
# Without referral (standalone account)
# Basic usage (standalone account)
npm run creator
# With referral link (earns you referral credit)
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE&ref=rafsrchae
# With recovery email
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE -r recovery@gmail.com
# With auto-accept mode (skip all prompts)
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE -y
# Enable 2FA automatically
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE --2fa
# Complete example with all options
npm run creator https://rewards.bing.com/welcome?rh=YOUR_CODE -r backup@gmail.com -y --2fa
```
### 🎛️ Command Line Arguments
| Argument | Description | Example |
|----------|-------------|---------|
| `<url>` | Referral URL (optional) | `https://rewards.bing.com/welcome?rh=CODE` |
| `-r <email>` | Recovery email address | `-r mybackup@gmail.com` |
| `-y` | Auto-accept mode (skip prompts) | `-y` |
| `--2fa` | Enable 2FA automatically | `--2fa` |
**Examples:**
```bash
# Minimal (no options)
npm run creator
# With referral only
npm run creator https://rewards.bing.com/welcome?rh=B395E9D7
# With recovery email (will be asked for code)
npm run creator -r mybackup@gmail.com
# Full automation with 2FA
npm run creator https://rewards.bing.com/welcome?rh=B395E9D7 -r backup@gmail.com -y --2fa
```
### Interactive Flow
@@ -171,32 +208,56 @@ Saved Account: john.smith247@outlook.com ← Correct!
- Up to 10 minutes timeout
- Logs progress every 30 seconds
10. **Save Account**
- Saves to `accounts-created/created_accounts_YYYY-MM-DD.jsonc`
- Daily files for organization
- All details preserved
10. **Post-Creation Setup** (Optional)
- **Recovery Email**: Adds backup email for account recovery
- **2FA Setup**: Enables two-factor authentication with TOTP
- **Interactive**: Waits for user to enter verification codes
- **TOTP Secret**: Extracts and saves secret key for authenticator apps
- **Recovery Code**: Saves 5x5 backup code for emergency access
11. **Save Account**
- Saves to `accounts-created/account_USERNAME_TIMESTAMP.jsonc`
- Individual files per account for better organization
- All details preserved (including recovery email, TOTP secret, recovery code)
## 📄 Output Format
```jsonc
// accounts-created/created_accounts_2025-01-09.jsonc
[
{
"email": "james.wilson1995@outlook.com",
"password": "Xyz789!@#AbcDef",
"birthdate": {
"day": 17,
"month": 5,
"year": 1995
},
"firstName": "James",
"lastName": "Wilson",
"createdAt": "2025-01-09T10:30:00.000Z",
"referralUrl": "https://rewards.bing.com/welcome?rh=YOUR_CODE&ref=rafsrchae"
}
]
// accounts-created/account_james19951995_2025-11-09T10-30-00-000Z.jsonc
{
"email": "james.wilson1995@outlook.com",
"password": "Xyz789!@#AbcDef",
"birthdate": {
"day": 17,
"month": 5,
"year": 1995
},
"firstName": "James",
"lastName": "Wilson",
"createdAt": "2025-11-09T10:30:00.000Z",
"referralUrl": "https://rewards.bing.com/welcome?rh=YOUR_CODE&ref=rafsrchae",
"recoveryEmail": "mybackup@gmail.com", // Optional: If -r used
"totpSecret": "JBSWY3DPEHPK3PXP", // Optional: If --2fa used
"recoveryCode": "MWGR3-9MJC9-STK76-SZCE5-X77PR" // Optional: If --2fa used
}
```
### 🔐 Security Information
**Recovery Email**: Used to recover account if you forget password
- Microsoft sends verification code to this email
- Required if you want account recovery option
**TOTP Secret**: Secret key for authenticator apps (Google Authenticator, Authy, etc.)
- Format: Base32 string (e.g., `JBSWY3DPEHPK3PXP`)
- Use this to generate 6-digit codes for login
- **SAVE THIS SAFELY** - Cannot be recovered later
**Recovery Code**: 5-part code for emergency account access
- Format: `XXXXX-XXXXX-XXXXX-XXXXX-XXXXX`
- Use this if you lose access to authenticator app
- **SAVE THIS SAFELY** - Only shown once
## 📂 File Structure
```
@@ -261,9 +322,91 @@ src/account-creation/
2. **Use manual mode** if you have specific email format requirements
3. **Let the script handle suggestions** - don't worry about "email taken" errors
4. **Solve CAPTCHA within 10 minutes** when prompted
5. **Check accounts-created/ folder** for all saved accounts
5. **Use `-y` flag** to skip all prompts for automation
6. **Save TOTP secrets** - they're in the JSONC files for later use
7. **Keep recovery codes safe** - they're shown only once
8. **Use Google Authenticator** with cloud backup for 2FA
9. **Check accounts-created/ folder** for all saved accounts
10. **Test 2FA immediately** after setup to ensure it works
## 🐛 Troubleshooting
## <EFBFBD> Recovery Email & 2FA Setup
### Recovery Email Flow
When you use `-r <email>` argument:
1. **Navigate to Security Page**
- Goes to `https://account.live.com/proofs/manage/`
2. **Add Recovery Email**
- Fills your recovery email
- Clicks "Next"
3. **Verification Code**
- Microsoft sends code to recovery email
- Script logs: "⏳ Please enter the code you received and click Next"
- **YOU** open recovery email, get code, enter it, click Next
- Script waits for URL change (up to 5 minutes)
4. **Confirmation**
- Clicks "OK" on info page
- Saves recovery email to JSONC file
### 2FA Setup Flow
When you use `--2fa` argument OR answer 'y' to "Enable 2FA?" prompt:
1. **Navigate to 2FA Page**
- Goes to `https://account.live.com/proofs/EnableTfa`
2. **Setup Different App**
- Clicks "Next"
- Clicks "set up a different Authenticator app"
3. **Extract TOTP Secret**
- Clicks "I can't scan the bar code"
- **Extracts and displays secret key** (e.g., `JBSWY3DPEHPK3PXP`)
- Logs: "🔑 TOTP Secret: XXXXXXX"
- Logs: "⚠️ SAVE THIS SECRET!"
4. **Scan QR Code**
- Clicks "I'll scan a bar code instead"
- Shows QR code
- Logs: "📱 Please scan QR code with Google Authenticator"
5. **Enter Verification Code**
- **YOU** scan QR code with authenticator app
- **YOU** enter 6-digit code from app
- **YOU** click Next
- Script waits (up to 5 minutes)
6. **Recovery Code**
- **Extracts and displays recovery code** (e.g., `MWGR3-9MJC9-STK76-SZCE5-X77PR`)
- Logs: "🔐 Recovery Code: XXXXX-XXXXX-..."
- Logs: "⚠️ SAVE THIS CODE!"
7. **Complete Setup**
- Clicks "Next" → "Next" → "Finish"
- Saves TOTP secret and recovery code to JSONC file
### 📱 Recommended Authenticator Apps
1. **Google Authenticator** (Recommended ✅)
- Cloud backup available
- Easy QR code scanning
- Available: iOS, Android
2. **Microsoft Authenticator**
- Native Microsoft integration
- Cloud backup
3. **Authy**
- Multi-device sync
- Desktop apps available
**Important**: The TOTP secret in the JSONC file can be used to set up the account in any authenticator app later.
## <20>🐛 Troubleshooting
**Q: Email generation too fast?**
A: System uses 0.8-2s delays after each input - looks human.
@@ -278,7 +421,22 @@ A: Press 'n' when asked "Generate automatically?" and type your email.
A: You have 10 minutes to solve it. If timeout, run script again.
**Q: Where are accounts saved?**
A: `accounts-created/created_accounts_YYYY-MM-DD.jsonc` (auto-created folder).
A: `accounts-created/account_USERNAME_TIMESTAMP.jsonc` (individual files per account).
**Q: Recovery email code not received?**
A: Check spam folder. Script waits 5 minutes for you to enter code.
**Q: Lost TOTP secret?**
A: Check the saved JSONC file - it contains the secret key.
**Q: 2FA app not working?**
A: Use the recovery code from JSONC file to access account.
**Q: Can I skip recovery email?**
A: Yes, don't use `-r` argument and press Enter when asked.
**Q: Can I skip 2FA?**
A: Yes, don't use `--2fa` and answer 'n' when asked (or use `-y` to skip prompt).
---

View File

@@ -4,15 +4,32 @@ import { log } from '../util/Logger'
import { AccountCreator } from './AccountCreator'
async function main(): Promise<void> {
// Get referral URL from command line args
// Parse command line args
const args = process.argv.slice(2)
const referralUrl = args[0] // Optional referral URL
let referralUrl: string | undefined
let recoveryEmail: string | undefined
let autoAccept = false
let enable2FA = false
// Validate URL format if provided
if (referralUrl && !referralUrl.startsWith('http')) {
log(false, 'CREATOR-CLI', '❌ Invalid URL format', 'error')
log(false, 'CREATOR-CLI', 'Usage: npm run creator [referralUrl]', 'log')
log(false, 'CREATOR-CLI', 'Example: npm run creator https://rewards.bing.com/welcome?rh=E3DCB441&ref=rafsrchae', 'log', 'cyan')
// Parse arguments
for (let i = 0; i < args.length; i++) {
const arg = args[i]
if (!arg) continue
if (arg === '-r' && i + 1 < args.length) {
recoveryEmail = args[++i]
} else if (arg === '-y') {
autoAccept = true
} else if (arg === '--2fa') {
enable2FA = true
} else if (arg.startsWith('http')) {
referralUrl = arg
}
}
// Validate recovery email if provided
if (recoveryEmail && !recoveryEmail.includes('@')) {
log(false, 'CREATOR-CLI', '❌ Invalid recovery email format', 'error')
process.exit(1)
}
@@ -49,7 +66,7 @@ async function main(): Promise<void> {
log(false, 'CREATOR-CLI', '✅ Browser opened successfully', 'log', 'green')
// Create account
const creator = new AccountCreator(referralUrl)
const creator = new AccountCreator(referralUrl, recoveryEmail, autoAccept, enable2FA)
const result = await creator.create(browserContext)
if (result) {
@@ -107,3 +124,4 @@ if (require.main === module) {
}
export { main as createAccountCLI }

View File

@@ -10,5 +10,8 @@ export interface CreatedAccount {
lastName: string
createdAt: string
referralUrl?: string
recoveryEmail?: string
totpSecret?: string
recoveryCode?: string
notes?: string
}