oauth-login.js 4.1 KB

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