fetch-login-code.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. (function attachBackgroundStep7(root, factory) {
  2. root.MultiPageBackgroundStep7 = factory();
  3. })(typeof self !== 'undefined' ? self : globalThis, function createBackgroundStep7Module() {
  4. function createStep7Executor(deps = {}) {
  5. const {
  6. addLog,
  7. chrome,
  8. CLOUDFLARE_TEMP_EMAIL_PROVIDER,
  9. confirmCustomVerificationStepBypass,
  10. ensureStep7VerificationPageReady,
  11. executeStep6,
  12. getMailConfig,
  13. getState,
  14. getTabId,
  15. HOTMAIL_PROVIDER,
  16. isTabAlive,
  17. isVerificationMailPollingError,
  18. LUCKMAIL_PROVIDER,
  19. resolveVerificationStep,
  20. reuseOrCreateTab,
  21. setState,
  22. setStepStatus,
  23. shouldSkipLoginVerificationForCpaCallback,
  24. shouldUseCustomRegistrationEmail,
  25. sleepWithStop,
  26. STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
  27. STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS,
  28. throwIfStopped,
  29. } = deps;
  30. async function runStep7Attempt(state) {
  31. const mail = getMailConfig(state);
  32. if (mail.error) throw new Error(mail.error);
  33. const stepStartedAt = Date.now();
  34. const authTabId = await getTabId('signup-page');
  35. if (authTabId) {
  36. await chrome.tabs.update(authTabId, { active: true });
  37. } else {
  38. if (!state.oauthUrl) {
  39. throw new Error('缺少登录用 OAuth 链接,请先完成步骤 6。');
  40. }
  41. await reuseOrCreateTab('signup-page', state.oauthUrl);
  42. }
  43. throwIfStopped();
  44. await ensureStep7VerificationPageReady();
  45. await addLog('步骤 7:登录验证码页面已就绪,开始获取验证码。', 'info');
  46. if (shouldUseCustomRegistrationEmail(state)) {
  47. await confirmCustomVerificationStepBypass(7);
  48. return;
  49. }
  50. throwIfStopped();
  51. if (mail.provider === HOTMAIL_PROVIDER || mail.provider === LUCKMAIL_PROVIDER || mail.provider === CLOUDFLARE_TEMP_EMAIL_PROVIDER) {
  52. await addLog(`步骤 7:正在通过 ${mail.label} 轮询验证码...`);
  53. } else {
  54. await addLog(`步骤 7:正在打开${mail.label}...`);
  55. const alive = await isTabAlive(mail.source);
  56. if (alive) {
  57. if (mail.navigateOnReuse) {
  58. await reuseOrCreateTab(mail.source, mail.url, {
  59. inject: mail.inject,
  60. injectSource: mail.injectSource,
  61. });
  62. } else {
  63. const tabId = await getTabId(mail.source);
  64. await chrome.tabs.update(tabId, { active: true });
  65. }
  66. } else {
  67. await reuseOrCreateTab(mail.source, mail.url, {
  68. inject: mail.inject,
  69. injectSource: mail.injectSource,
  70. });
  71. }
  72. }
  73. await resolveVerificationStep(7, state, mail, {
  74. filterAfterTimestamp: mail.provider === HOTMAIL_PROVIDER ? undefined : Math.max(0, stepStartedAt - 60000),
  75. requestFreshCodeFirst: false,
  76. resendIntervalMs: mail.provider === HOTMAIL_PROVIDER ? 0 : STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
  77. });
  78. }
  79. async function rerunStep6ForStep7Recovery() {
  80. const currentState = await getState();
  81. await addLog('步骤 7:正在回到步骤 6,重新发起登录验证码流程...', 'warn');
  82. await executeStep6(currentState);
  83. await sleepWithStop(3000);
  84. }
  85. async function executeStep7(state) {
  86. if (shouldSkipLoginVerificationForCpaCallback(state)) {
  87. await setState({
  88. lastLoginCode: null,
  89. loginVerificationRequestedAt: null,
  90. });
  91. await setStepStatus(7, 'skipped');
  92. await addLog('步骤 7:当前已选择“第六步回调”,本轮无需获取登录验证码。', 'warn');
  93. return;
  94. }
  95. let currentState = state;
  96. let mailPollingAttempt = 1;
  97. let lastMailPollingError = null;
  98. while (true) {
  99. try {
  100. await runStep7Attempt(currentState);
  101. return;
  102. } catch (err) {
  103. if (!isVerificationMailPollingError(err)) {
  104. throw err;
  105. }
  106. lastMailPollingError = err;
  107. if (mailPollingAttempt >= STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS) {
  108. break;
  109. }
  110. mailPollingAttempt += 1;
  111. await addLog(
  112. `步骤 7:检测到邮箱轮询类失败,准备从步骤 6 重新开始(${mailPollingAttempt}/${STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS})...`,
  113. 'warn'
  114. );
  115. await rerunStep6ForStep7Recovery();
  116. currentState = await getState();
  117. }
  118. }
  119. if (lastMailPollingError) {
  120. throw new Error(
  121. `步骤 7:登录验证码流程在 ${STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS} 轮邮箱轮询恢复后仍未成功。最后一次原因:${lastMailPollingError.message}`
  122. );
  123. }
  124. throw new Error('步骤 7:登录验证码流程未成功完成。');
  125. }
  126. return { executeStep7 };
  127. }
  128. return { createStep7Executor };
  129. });