aaaaa
This commit is contained in:
parent
740456ba56
commit
5d1d4e51ac
@ -79,7 +79,7 @@ class ImapConnector {
|
|||||||
const sinceDate = new Date();
|
const sinceDate = new Date();
|
||||||
sinceDate.setDate(sinceDate.getDate() - sinceDays);
|
sinceDate.setDate(sinceDate.getDate() - sinceDays);
|
||||||
|
|
||||||
// 搜索条件:最近N天的邮件
|
// 搜索条件:最近N天的未读邮件
|
||||||
this.imap.search(['UNSEEN', ['SINCE', sinceDate]], async (err, results) => {
|
this.imap.search(['UNSEEN', ['SINCE', sinceDate]], async (err, results) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
|
|||||||
@ -49,15 +49,19 @@ class EmailVerificationService {
|
|||||||
const emails = await this.connector.getLatestEmails(10, 1);
|
const emails = await this.connector.getLatestEmails(10, 1);
|
||||||
|
|
||||||
if (emails && emails.length > 0) {
|
if (emails && emails.length > 0) {
|
||||||
|
logger.info('EmailVerification', `找到 ${emails.length} 封未读邮件`);
|
||||||
|
|
||||||
// 3. 查找匹配的邮件并提取验证码
|
// 3. 查找匹配的邮件并提取验证码
|
||||||
for (const email of emails.reverse()) { // 从最新的开始
|
for (const email of emails.reverse()) { // 从最新的开始
|
||||||
|
logger.info('EmailVerification', `检查邮件: 发件人="${email.from}", 主题="${email.subject}"`);
|
||||||
|
|
||||||
for (const parser of this.parsers) {
|
for (const parser of this.parsers) {
|
||||||
if (parser.canParse(email)) {
|
if (parser.canParse(email)) {
|
||||||
logger.success('EmailVerification', `找到匹配的邮件: ${email.subject}`);
|
logger.success('EmailVerification', `✓ 找到匹配的邮件: ${email.subject}`);
|
||||||
|
|
||||||
const code = parser.extractCode(email);
|
const code = parser.extractCode(email);
|
||||||
if (code) {
|
if (code) {
|
||||||
logger.success('EmailVerification', `成功提取验证码: ${code}`);
|
logger.success('EmailVerification', `✓ 成功提取验证码: ${code}`);
|
||||||
|
|
||||||
// 标记为已读
|
// 标记为已读
|
||||||
try {
|
try {
|
||||||
@ -70,10 +74,15 @@ class EmailVerificationService {
|
|||||||
this.connector.disconnect();
|
this.connector.disconnect();
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
} else {
|
||||||
|
logger.warn('EmailVerification', `邮件匹配但无法提取验证码`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger.warn('EmailVerification', `未找到匹配的Windsurf验证码邮件`);
|
||||||
|
} else {
|
||||||
|
logger.info('EmailVerification', `没有未读邮件`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待一段时间后再检查
|
// 等待一段时间后再检查
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
* ... 根据实际情况继续添加步骤
|
* ... 根据实际情况继续添加步骤
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const BaseSite = require('../base-site');
|
const AccountDataGenerator = require('../generator');
|
||||||
const HumanBehavior = require('../utils/human-behavior');
|
const HumanBehavior = require('../utils/human-behavior');
|
||||||
const CloudflareHandler = require('../utils/cloudflare-handler');
|
const CloudflareHandler = require('../utils/cloudflare-handler');
|
||||||
const logger = require('../../../shared/logger');
|
const logger = require('../../../shared/logger');
|
||||||
@ -321,8 +321,63 @@ class WindsurfRegister {
|
|||||||
*/
|
*/
|
||||||
async handleCloudflareVerification() {
|
async handleCloudflareVerification() {
|
||||||
const cloudflareMode = DEFAULT_CONFIG.cloudflare.mode;
|
const cloudflareMode = DEFAULT_CONFIG.cloudflare.mode;
|
||||||
const handler = new CloudflareHandler(this.page, this.human, this.siteName, cloudflareMode);
|
|
||||||
return await handler.handle();
|
// 自定义检测函数:检查Continue按钮是否激活
|
||||||
|
const customCheck = async () => {
|
||||||
|
try {
|
||||||
|
const buttonEnabled = await this.page.evaluate(() => {
|
||||||
|
const button = document.querySelector('button');
|
||||||
|
return button && !button.disabled;
|
||||||
|
});
|
||||||
|
return buttonEnabled;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handler = new CloudflareHandler(this.page, this.human, this.siteName, cloudflareMode, customCheck);
|
||||||
|
const result = await handler.handle();
|
||||||
|
|
||||||
|
// 如果验证通过,点击Continue按钮进入下一页
|
||||||
|
if (result === 'passed') {
|
||||||
|
logger.info(this.siteName, '[Cloudflare] 点击Continue按钮进入验证码页面...');
|
||||||
|
try {
|
||||||
|
const currentUrl = this.page.url();
|
||||||
|
const button = await this.page.$('button:not([disabled])');
|
||||||
|
if (button) {
|
||||||
|
await button.click();
|
||||||
|
|
||||||
|
// 等待页面跳转或内容改变
|
||||||
|
try {
|
||||||
|
// 方法1: 等待URL改变
|
||||||
|
await this.page.waitForFunction(
|
||||||
|
(oldUrl) => window.location.href !== oldUrl,
|
||||||
|
{ timeout: 10000 },
|
||||||
|
currentUrl
|
||||||
|
);
|
||||||
|
logger.success(this.siteName, '[Cloudflare] 页面已跳转');
|
||||||
|
} catch (e) {
|
||||||
|
// 方法2: 如果URL没变,等待"Check your inbox"文本出现
|
||||||
|
try {
|
||||||
|
await this.page.waitForFunction(
|
||||||
|
() => document.body.textContent.includes('Check your inbox'),
|
||||||
|
{ timeout: 5000 }
|
||||||
|
);
|
||||||
|
logger.success(this.siteName, '[Cloudflare] 验证码页面已加载');
|
||||||
|
} catch (e2) {
|
||||||
|
logger.warn(this.siteName, '[Cloudflare] 等待页面改变超时,继续...');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 额外等待确保页面稳定
|
||||||
|
await this.human.randomDelay(2000, 3000);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.warn(this.siteName, `[Cloudflare] 点击按钮失败: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -347,14 +402,18 @@ class WindsurfRegister {
|
|||||||
// 获取验证码(从邮箱)
|
// 获取验证码(从邮箱)
|
||||||
logger.info(this.siteName, ' → 正在从邮箱获取验证码...');
|
logger.info(this.siteName, ' → 正在从邮箱获取验证码...');
|
||||||
logger.info(this.siteName, ` → 接收邮箱: ${this.accountData.email}`);
|
logger.info(this.siteName, ` → 接收邮箱: ${this.accountData.email}`);
|
||||||
|
logger.info(this.siteName, ' → 注意:如果长时间无响应,请检查:');
|
||||||
|
logger.info(this.siteName, ' 1. 邮件是否已发送到邮箱');
|
||||||
|
logger.info(this.siteName, ' 2. QQ邮箱IMAP配置是否正确');
|
||||||
|
logger.info(this.siteName, ' 3. 邮件是否被标记为垃圾邮件');
|
||||||
|
|
||||||
const code = await this.emailService.getVerificationCode(
|
const code = await this.emailService.getVerificationCode(
|
||||||
'windsurf',
|
'windsurf',
|
||||||
this.accountData.email,
|
this.accountData.email,
|
||||||
90 // 90秒超时
|
120 // 增加到120秒超时
|
||||||
);
|
);
|
||||||
|
|
||||||
logger.success(this.siteName, ` → 验证码: ${code}`);
|
logger.success(this.siteName, ` → ✓ 验证码: ${code}`);
|
||||||
|
|
||||||
// 等待验证码输入框加载
|
// 等待验证码输入框加载
|
||||||
await this.human.randomDelay(2000, 3000);
|
await this.human.randomDelay(2000, 3000);
|
||||||
|
|||||||
@ -11,12 +11,14 @@ class CloudflareHandler {
|
|||||||
* @param {HumanBehavior} human - 人类行为模拟对象
|
* @param {HumanBehavior} human - 人类行为模拟对象
|
||||||
* @param {string} siteName - 网站名称(用于日志)
|
* @param {string} siteName - 网站名称(用于日志)
|
||||||
* @param {string} mode - 验证模式: 'auto' 或 'manual' (默认 'manual')
|
* @param {string} mode - 验证模式: 'auto' 或 'manual' (默认 'manual')
|
||||||
|
* @param {Function} customCheck - 自定义检测函数,返回Promise<boolean>,检测验证是否完成
|
||||||
*/
|
*/
|
||||||
constructor(page, human, siteName, mode = 'manual') {
|
constructor(page, human, siteName, mode = 'manual', customCheck = null) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.human = human;
|
this.human = human;
|
||||||
this.siteName = siteName;
|
this.siteName = siteName;
|
||||||
this.mode = mode; // 'auto' 或 'manual'
|
this.mode = mode; // 'auto' 或 'manual'
|
||||||
|
this.customCheck = customCheck; // 自定义检测函数
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,15 +185,25 @@ class CloudflareHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 方法4: 自定义检测(由网站自己定义)
|
||||||
|
let customCheckPassed = false;
|
||||||
|
if (this.customCheck) {
|
||||||
|
try {
|
||||||
|
customCheckPassed = await this.customCheck();
|
||||||
|
} catch (e) {
|
||||||
|
// 忽略错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 每15秒输出一次状态
|
// 每15秒输出一次状态
|
||||||
if (attempts % 15 === 0) {
|
if (attempts % 15 === 0) {
|
||||||
const minutes = Math.floor(attempts / 60);
|
const minutes = Math.floor(attempts / 60);
|
||||||
const seconds = attempts % 60;
|
const seconds = attempts % 60;
|
||||||
logger.info(this.siteName, `[Cloudflare] 等待中... (${minutes}分${seconds}秒/${Math.floor(maxAttempts/60)}分钟)`);
|
logger.info(this.siteName, `[Cloudflare] 等待中... (${minutes}分${seconds}秒/${Math.floor(maxAttempts/60)}分钟) - custom=${customCheckPassed}, iframe=${iframeSuccess}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断验证完成
|
// 判断验证完成
|
||||||
if (iframeSuccess || (!hasVerifyText && attempts > 3) || urlChanged) {
|
if (customCheckPassed || iframeSuccess || (!hasVerifyText && attempts > 3) || urlChanged) {
|
||||||
verified = true;
|
verified = true;
|
||||||
logger.success(this.siteName, '[Cloudflare] ✓✓✓ 检测到验证完成!');
|
logger.success(this.siteName, '[Cloudflare] ✓✓✓ 检测到验证完成!');
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user