signup-flow-helpers.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. (function attachSignupFlowHelpers(root, factory) {
  2. root.MultiPageSignupFlowHelpers = factory();
  3. })(typeof self !== 'undefined' ? self : globalThis, function createSignupFlowHelpersModule() {
  4. function createSignupFlowHelpers(deps = {}) {
  5. const {
  6. addLog,
  7. buildGeneratedAliasEmail,
  8. chrome,
  9. ensureContentScriptReadyOnTab,
  10. ensureHotmailAccountForFlow,
  11. ensureLuckmailPurchaseForFlow,
  12. getTabId,
  13. isGeneratedAliasProvider,
  14. isHotmailProvider,
  15. isLuckmailProvider,
  16. isSignupPasswordPageUrl,
  17. isTabAlive,
  18. reuseOrCreateTab,
  19. sendToContentScriptResilient,
  20. setEmailState,
  21. SIGNUP_ENTRY_URL,
  22. SIGNUP_PAGE_INJECT_FILES,
  23. waitForTabUrlMatch,
  24. } = deps;
  25. async function openSignupEntryTab(step = 1) {
  26. const tabId = await reuseOrCreateTab('signup-page', SIGNUP_ENTRY_URL, {
  27. inject: SIGNUP_PAGE_INJECT_FILES,
  28. injectSource: 'signup-page',
  29. });
  30. await ensureContentScriptReadyOnTab('signup-page', tabId, {
  31. inject: SIGNUP_PAGE_INJECT_FILES,
  32. injectSource: 'signup-page',
  33. timeoutMs: 45000,
  34. retryDelayMs: 900,
  35. logMessage: `步骤 ${step}:ChatGPT 官网仍在加载,正在重试连接内容脚本...`,
  36. });
  37. return tabId;
  38. }
  39. async function ensureSignupEntryPageReady(step = 1) {
  40. const tabId = await openSignupEntryTab(step);
  41. const result = await sendToContentScriptResilient('signup-page', {
  42. type: 'ENSURE_SIGNUP_ENTRY_READY',
  43. step,
  44. source: 'background',
  45. payload: {},
  46. }, {
  47. timeoutMs: 20000,
  48. retryDelayMs: 700,
  49. logMessage: `步骤 ${step}:官网注册入口正在切换,等待页面恢复...`,
  50. });
  51. if (result?.error) {
  52. throw new Error(result.error);
  53. }
  54. return { tabId, result: result || {} };
  55. }
  56. async function ensureSignupPasswordPageReadyInTab(tabId, step = 2, options = {}) {
  57. const { skipUrlWait = false } = options;
  58. if (!skipUrlWait) {
  59. const matchedTab = await waitForTabUrlMatch(tabId, (url) => isSignupPasswordPageUrl(url), {
  60. timeoutMs: 45000,
  61. retryDelayMs: 300,
  62. });
  63. if (!matchedTab) {
  64. throw new Error('等待进入密码页超时,请检查邮箱提交后页面是否仍停留在官网或邮箱页。');
  65. }
  66. }
  67. await ensureContentScriptReadyOnTab('signup-page', tabId, {
  68. inject: SIGNUP_PAGE_INJECT_FILES,
  69. injectSource: 'signup-page',
  70. timeoutMs: 45000,
  71. retryDelayMs: 900,
  72. logMessage: `步骤 ${step}:密码页仍在加载,正在重试连接内容脚本...`,
  73. });
  74. const result = await sendToContentScriptResilient('signup-page', {
  75. type: 'ENSURE_SIGNUP_PASSWORD_PAGE_READY',
  76. step,
  77. source: 'background',
  78. payload: {},
  79. }, {
  80. timeoutMs: 20000,
  81. retryDelayMs: 700,
  82. logMessage: `步骤 ${step}:认证页正在切换,等待密码页重新就绪...`,
  83. });
  84. if (result?.error) {
  85. throw new Error(result.error);
  86. }
  87. return result || {};
  88. }
  89. async function resolveSignupEmailForFlow(state) {
  90. let resolvedEmail = state.email;
  91. if (isHotmailProvider(state)) {
  92. const account = await ensureHotmailAccountForFlow({
  93. allowAllocate: true,
  94. markUsed: true,
  95. preferredAccountId: state.currentHotmailAccountId || null,
  96. });
  97. resolvedEmail = account.email;
  98. } else if (isLuckmailProvider(state)) {
  99. const purchase = await ensureLuckmailPurchaseForFlow({ allowReuse: true });
  100. resolvedEmail = purchase.email_address;
  101. } else if (isGeneratedAliasProvider(state)) {
  102. resolvedEmail = buildGeneratedAliasEmail(state);
  103. }
  104. if (!resolvedEmail) {
  105. throw new Error('缺少邮箱地址,请先在侧边栏粘贴邮箱。');
  106. }
  107. if (resolvedEmail !== state.email) {
  108. await setEmailState(resolvedEmail);
  109. }
  110. return resolvedEmail;
  111. }
  112. return {
  113. ensureSignupEntryPageReady,
  114. ensureSignupPasswordPageReadyInTab,
  115. openSignupEntryTab,
  116. resolveSignupEmailForFlow,
  117. };
  118. }
  119. return {
  120. createSignupFlowHelpers,
  121. };
  122. });