oauth-login.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. completeStepFromBackground,
  8. getErrorMessage,
  9. getLoginAuthStateLabel,
  10. getOAuthFlowStepTimeoutMs,
  11. getState,
  12. isStep6RecoverableResult,
  13. isStep6SuccessResult,
  14. refreshOAuthUrlBeforeStep6,
  15. reuseOrCreateTab,
  16. sendToContentScriptResilient,
  17. shouldSkipLoginVerificationForCpaCallback,
  18. skipLoginVerificationStepsForCpaCallback,
  19. startOAuthFlowTimeoutWindow,
  20. STEP6_MAX_ATTEMPTS,
  21. throwIfStopped,
  22. } = deps;
  23. async function executeStep7(state) {
  24. if (shouldSkipLoginVerificationForCpaCallback(state)) {
  25. await skipLoginVerificationStepsForCpaCallback();
  26. return;
  27. }
  28. if (!state.email) {
  29. throw new Error('缺少邮箱地址,请先完成步骤 3。');
  30. }
  31. let attempt = 0;
  32. let lastError = null;
  33. while (attempt < STEP6_MAX_ATTEMPTS) {
  34. throwIfStopped();
  35. attempt += 1;
  36. try {
  37. const currentState = attempt === 1 ? state : await getState();
  38. const password = currentState.password || currentState.customPassword || '';
  39. const oauthUrl = await refreshOAuthUrlBeforeStep6(currentState);
  40. if (typeof startOAuthFlowTimeoutWindow === 'function') {
  41. await startOAuthFlowTimeoutWindow({ step: 7, oauthUrl });
  42. }
  43. const loginTimeoutMs = typeof getOAuthFlowStepTimeoutMs === 'function'
  44. ? await getOAuthFlowStepTimeoutMs(180000, {
  45. step: 7,
  46. actionLabel: 'OAuth 登录并进入验证码页',
  47. })
  48. : 180000;
  49. if (attempt === 1) {
  50. await addLog('步骤 7:正在打开最新 OAuth 链接并登录...');
  51. } else {
  52. await addLog(`步骤 7:上一轮失败后,正在进行第 ${attempt} 次尝试(最多 ${STEP6_MAX_ATTEMPTS} 次)...`, 'warn');
  53. }
  54. await reuseOrCreateTab('signup-page', oauthUrl);
  55. const result = await sendToContentScriptResilient(
  56. 'signup-page',
  57. {
  58. type: 'EXECUTE_STEP',
  59. step: 7,
  60. source: 'background',
  61. payload: {
  62. email: currentState.email,
  63. password,
  64. },
  65. },
  66. {
  67. timeoutMs: loginTimeoutMs,
  68. responseTimeoutMs: loginTimeoutMs,
  69. retryDelayMs: 700,
  70. logMessage: '步骤 7:认证页正在切换,等待页面重新就绪后继续登录...',
  71. }
  72. );
  73. if (result?.error) {
  74. throw new Error(result.error);
  75. }
  76. if (isStep6SuccessResult(result)) {
  77. await completeStepFromBackground(7, {
  78. loginVerificationRequestedAt: result.loginVerificationRequestedAt || null,
  79. });
  80. return;
  81. }
  82. if (isStep6RecoverableResult(result)) {
  83. const reasonMessage = result.message
  84. || `当前停留在${getLoginAuthStateLabel(result.state)},准备重新执行步骤 7。`;
  85. throw new Error(reasonMessage);
  86. }
  87. throw new Error('步骤 7:认证页未返回可识别的登录结果。');
  88. } catch (err) {
  89. throwIfStopped(err);
  90. lastError = err;
  91. if (attempt >= STEP6_MAX_ATTEMPTS) {
  92. break;
  93. }
  94. await addLog(`步骤 7:第 ${attempt} 次尝试失败,原因:${getErrorMessage(err)};准备重试...`, 'warn');
  95. }
  96. }
  97. throw new Error(`步骤 7:判断失败后已重试 ${STEP6_MAX_ATTEMPTS - 1} 次,仍未成功。最后原因:${getErrorMessage(lastError)}`);
  98. }
  99. return { executeStep7 };
  100. }
  101. return { createStep7Executor };
  102. });