Add OAuth flow timeout toggle
This commit is contained in:
@@ -296,3 +296,99 @@ return {
|
||||
|
||||
assert.equal(timeoutMs, 15000);
|
||||
});
|
||||
|
||||
test('oauth timeout budget clamps local timeout when enabled by default', async () => {
|
||||
const api = new Function(`
|
||||
const LOG_PREFIX = '[test]';
|
||||
const OAUTH_FLOW_TIMEOUT_MS = 5 * 60 * 1000;
|
||||
${extractFunction('buildOAuthFlowTimeoutError')}
|
||||
${extractFunction('normalizeOAuthFlowDeadlineAt')}
|
||||
${extractFunction('normalizeOAuthFlowSourceUrl')}
|
||||
${extractFunction('getOAuthFlowRemainingMs')}
|
||||
${extractFunction('getOAuthFlowStepTimeoutMs')}
|
||||
return {
|
||||
getOAuthFlowStepTimeoutMs,
|
||||
};
|
||||
`)();
|
||||
|
||||
const timeoutMs = await api.getOAuthFlowStepTimeoutMs(15000, {
|
||||
step: 8,
|
||||
actionLabel: '登录验证码流程',
|
||||
state: {
|
||||
oauthUrl: 'https://oauth.example/current',
|
||||
oauthFlowDeadlineAt: Date.now() + 1200,
|
||||
oauthFlowDeadlineSourceUrl: 'https://oauth.example/current',
|
||||
},
|
||||
});
|
||||
|
||||
assert(timeoutMs <= 1200);
|
||||
assert(timeoutMs >= 1000);
|
||||
});
|
||||
|
||||
test('oauth timeout budget disabled mode ignores active deadlines', async () => {
|
||||
const api = new Function(`
|
||||
const LOG_PREFIX = '[test]';
|
||||
const OAUTH_FLOW_TIMEOUT_MS = 5 * 60 * 1000;
|
||||
${extractFunction('buildOAuthFlowTimeoutError')}
|
||||
${extractFunction('normalizeOAuthFlowDeadlineAt')}
|
||||
${extractFunction('normalizeOAuthFlowSourceUrl')}
|
||||
${extractFunction('getOAuthFlowRemainingMs')}
|
||||
${extractFunction('getOAuthFlowStepTimeoutMs')}
|
||||
return {
|
||||
getOAuthFlowStepTimeoutMs,
|
||||
};
|
||||
`)();
|
||||
|
||||
const timeoutMs = await api.getOAuthFlowStepTimeoutMs(15000, {
|
||||
step: 9,
|
||||
actionLabel: 'OAuth localhost 回调',
|
||||
state: {
|
||||
oauthFlowTimeoutEnabled: false,
|
||||
oauthUrl: 'https://oauth.example/current',
|
||||
oauthFlowDeadlineAt: Date.now() - 1000,
|
||||
oauthFlowDeadlineSourceUrl: 'https://oauth.example/current',
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(timeoutMs, 15000);
|
||||
});
|
||||
|
||||
test('startOAuthFlowTimeoutWindow clears stale deadline when timeout is disabled', async () => {
|
||||
const events = {
|
||||
stateUpdates: [],
|
||||
logs: [],
|
||||
};
|
||||
const api = new Function('events', `
|
||||
const OAUTH_FLOW_TIMEOUT_MS = 5 * 60 * 1000;
|
||||
async function getState() {
|
||||
return {
|
||||
oauthFlowTimeoutEnabled: false,
|
||||
oauthFlowDeadlineAt: Date.now() - 1000,
|
||||
oauthFlowDeadlineSourceUrl: 'https://oauth.example/old',
|
||||
};
|
||||
}
|
||||
async function setState(update) {
|
||||
events.stateUpdates.push(update);
|
||||
}
|
||||
async function addLog(message, level) {
|
||||
events.logs.push({ message, level });
|
||||
}
|
||||
${extractFunction('normalizeOAuthFlowSourceUrl')}
|
||||
${extractFunction('startOAuthFlowTimeoutWindow')}
|
||||
return {
|
||||
startOAuthFlowTimeoutWindow,
|
||||
};
|
||||
`)(events);
|
||||
|
||||
const result = await api.startOAuthFlowTimeoutWindow({
|
||||
step: 7,
|
||||
oauthUrl: 'https://oauth.example/current',
|
||||
});
|
||||
|
||||
assert.equal(result, null);
|
||||
assert.deepStrictEqual(events.stateUpdates, [{
|
||||
oauthFlowDeadlineAt: null,
|
||||
oauthFlowDeadlineSourceUrl: null,
|
||||
}]);
|
||||
assert.match(events.logs[0].message, /授权后链总超时已关闭/);
|
||||
});
|
||||
|
||||
@@ -143,3 +143,81 @@ return {
|
||||
domains: ['mail.example.com'],
|
||||
});
|
||||
});
|
||||
|
||||
test('oauth flow timeout setting is persisted and normalized as boolean', () => {
|
||||
const api = new Function(`
|
||||
const DEFAULT_VERIFICATION_RESEND_COUNT = 4;
|
||||
const PERSISTED_SETTING_DEFAULTS = {
|
||||
panelMode: 'cpa',
|
||||
oauthFlowTimeoutEnabled: true,
|
||||
autoStepDelaySeconds: null,
|
||||
verificationResendCount: DEFAULT_VERIFICATION_RESEND_COUNT,
|
||||
mailProvider: '163',
|
||||
mail2925Mode: 'provide',
|
||||
emailGenerator: 'duck',
|
||||
autoDeleteUsedIcloudAlias: false,
|
||||
accountRunHistoryTextEnabled: false,
|
||||
cloudflareTempEmailUseRandomSubdomain: false,
|
||||
cloudflareTempEmailDomain: '',
|
||||
cloudflareTempEmailDomains: [],
|
||||
};
|
||||
const PERSISTED_SETTING_KEYS = Object.keys(PERSISTED_SETTING_DEFAULTS);
|
||||
function normalizePanelMode(value) { return value === 'sub2api' ? 'sub2api' : 'cpa'; }
|
||||
function normalizeLocalCpaStep9Mode(value) { return value === 'bypass' ? 'bypass' : 'submit'; }
|
||||
function normalizeAutoRunFallbackThreadIntervalMinutes(value) { return Number(value) || 0; }
|
||||
function normalizeAutoRunDelayMinutes(value) { return Number(value) || 30; }
|
||||
function normalizeAutoStepDelaySeconds(value, fallback = null) { return value == null || value === '' ? fallback : Number(value); }
|
||||
function normalizeVerificationResendCount(value, fallback) { return Number.isFinite(Number(value)) ? Number(value) : fallback; }
|
||||
function normalizeMailProvider(value) { return String(value || '').trim().toLowerCase() || '163'; }
|
||||
function normalizeMail2925Mode(value) { return String(value || '').trim().toLowerCase() === 'receive' ? 'receive' : 'provide'; }
|
||||
function normalizeEmailGenerator(value) { return String(value || '').trim().toLowerCase() || 'duck'; }
|
||||
function normalizeIcloudHost(value) { return ''; }
|
||||
function normalizeIcloudTargetMailboxType(value) { return String(value || '').trim() || 'icloud-inbox'; }
|
||||
function normalizeIcloudForwardMailProvider(value) { return String(value || '').trim() || 'qq'; }
|
||||
function normalizeIcloudFetchMode(value) { return String(value || '').trim() === 'always_new' ? 'always_new' : 'reuse_existing'; }
|
||||
function normalizeAccountRunHistoryHelperBaseUrl(value) { return String(value || '').trim(); }
|
||||
function normalizeHotmailServiceMode(value) { return String(value || '').trim().toLowerCase() === 'remote' ? 'remote' : 'local'; }
|
||||
function normalizeHotmailRemoteBaseUrl(value) { return String(value || '').trim(); }
|
||||
function normalizeHotmailLocalBaseUrl(value) { return String(value || '').trim(); }
|
||||
function normalizeLuckmailBaseUrl(value) { return String(value || '').trim(); }
|
||||
function normalizeLuckmailEmailType(value) { return String(value || '').trim(); }
|
||||
function normalizeCloudflareDomain(value) { return String(value || '').trim().toLowerCase(); }
|
||||
function normalizeCloudflareDomains(value) { return Array.isArray(value) ? value.map((item) => String(item || '').trim().toLowerCase()).filter(Boolean) : []; }
|
||||
function normalizeCustomEmailPool(value) { return Array.isArray(value) ? value : []; }
|
||||
function normalizeCloudflareTempEmailBaseUrl(value) { return String(value || '').trim(); }
|
||||
function normalizeCloudflareTempEmailAddress(value = '') { return String(value || '').trim().toLowerCase(); }
|
||||
function normalizeCloudflareTempEmailReceiveMailbox(value = '') { return String(value || '').trim().toLowerCase(); }
|
||||
function normalizeCloudflareTempEmailDomain(value) { return String(value || '').trim().toLowerCase(); }
|
||||
function normalizeCloudflareTempEmailDomains(value) { return Array.isArray(value) ? value.map((item) => String(item || '').trim().toLowerCase()).filter(Boolean) : []; }
|
||||
function normalizeHotmailAccounts(value) { return Array.isArray(value) ? value : []; }
|
||||
function normalizeMail2925Accounts(value) { return Array.isArray(value) ? value : []; }
|
||||
function normalizePayPalAccounts(value) { return Array.isArray(value) ? value : []; }
|
||||
function normalizeHeroSmsAcquirePriority(value) { return String(value || '').trim() === 'price' ? 'price' : 'country'; }
|
||||
function normalizeHeroSmsMaxPrice(value) { return String(value || '').trim(); }
|
||||
function normalizeHeroSmsCountryFallback(value) { return Array.isArray(value) ? value : []; }
|
||||
function normalizePhoneVerificationReplacementLimit(value) { return Number(value) || 3; }
|
||||
function normalizePhoneCodeWaitSeconds(value) { return Number(value) || 60; }
|
||||
function normalizePhoneCodeTimeoutWindows(value) { return Number(value) || 2; }
|
||||
function normalizePhoneCodePollIntervalSeconds(value) { return Number(value) || 5; }
|
||||
function normalizePhoneCodePollMaxRounds(value) { return Number(value) || 4; }
|
||||
function resolveLegacyAutoStepDelaySeconds() { return undefined; }
|
||||
${extractFunction('normalizePersistentSettingValue')}
|
||||
${extractFunction('buildPersistentSettingsPayload')}
|
||||
return {
|
||||
buildPersistentSettingsPayload,
|
||||
normalizePersistentSettingValue,
|
||||
};
|
||||
`)();
|
||||
|
||||
assert.equal(api.normalizePersistentSettingValue('oauthFlowTimeoutEnabled', 0), false);
|
||||
assert.equal(api.normalizePersistentSettingValue('oauthFlowTimeoutEnabled', 1), true);
|
||||
|
||||
assert.deepEqual(api.buildPersistentSettingsPayload({
|
||||
oauthFlowTimeoutEnabled: false,
|
||||
}), {
|
||||
oauthFlowTimeoutEnabled: false,
|
||||
});
|
||||
|
||||
const defaults = api.buildPersistentSettingsPayload({}, { fillDefaults: true });
|
||||
assert.equal(defaults.oauthFlowTimeoutEnabled, true);
|
||||
});
|
||||
|
||||
@@ -220,6 +220,7 @@ const inputAutoSkipFailuresThreadIntervalMinutes = { value: '5' };
|
||||
const inputAutoDelayEnabled = { checked: true };
|
||||
const inputAutoDelayMinutes = { value: '30' };
|
||||
const inputAutoStepDelaySeconds = { value: '10' };
|
||||
const inputOAuthFlowTimeoutEnabled = { checked: true };
|
||||
const inputVerificationResendCount = { value: '6' };
|
||||
const DEFAULT_VERIFICATION_RESEND_COUNT = 4;
|
||||
const DEFAULT_PHONE_VERIFICATION_REPLACEMENT_LIMIT = 3;
|
||||
|
||||
@@ -128,6 +128,7 @@ const inputAutoSkipFailuresThreadIntervalMinutes = { value: '0' };
|
||||
const inputAutoDelayEnabled = { checked: false };
|
||||
const inputAutoDelayMinutes = { value: '30' };
|
||||
const inputAutoStepDelaySeconds = { value: '' };
|
||||
const inputOAuthFlowTimeoutEnabled = { checked: true };
|
||||
const inputVerificationResendCount = { value: '4' };
|
||||
const DEFAULT_VERIFICATION_RESEND_COUNT = 4;
|
||||
const DEFAULT_PHONE_VERIFICATION_REPLACEMENT_LIMIT = 3;
|
||||
@@ -375,6 +376,7 @@ const inputAutoSkipFailuresThreadIntervalMinutes = { value: '' };
|
||||
const inputAutoDelayEnabled = { checked: false };
|
||||
const inputAutoDelayMinutes = { value: '' };
|
||||
const inputAutoStepDelaySeconds = { value: '' };
|
||||
const inputOAuthFlowTimeoutEnabled = { checked: true };
|
||||
const inputVerificationResendCount = { value: '' };
|
||||
const inputPhoneVerificationEnabled = { checked: false };
|
||||
const DEFAULT_PHONE_VERIFICATION_ENABLED = false;
|
||||
|
||||
@@ -199,6 +199,7 @@ const inputAutoSkipFailuresThreadIntervalMinutes = { value: '0' };
|
||||
const inputAutoDelayEnabled = { checked: false };
|
||||
const inputAutoDelayMinutes = { value: '30' };
|
||||
const inputAutoStepDelaySeconds = { value: '' };
|
||||
const inputOAuthFlowTimeoutEnabled = { checked: true };
|
||||
const inputVerificationResendCount = { value: '4' };
|
||||
const DEFAULT_VERIFICATION_RESEND_COUNT = 4;
|
||||
const DEFAULT_PHONE_VERIFICATION_REPLACEMENT_LIMIT = 3;
|
||||
|
||||
@@ -77,6 +77,9 @@ test('sidepanel html exposes phone verification toggle and dedicated HeroSMS row
|
||||
assert.match(html, /id="row-phone-code-timeout-windows"/);
|
||||
assert.match(html, /id="row-phone-code-poll-interval-seconds"/);
|
||||
assert.match(html, /id="row-phone-code-poll-max-rounds"/);
|
||||
assert.match(html, /id="row-oauth-flow-timeout"/);
|
||||
assert.match(html, /id="input-oauth-flow-timeout-enabled"/);
|
||||
assert.match(html, /只取消 Step 7 后链总预算/);
|
||||
assert.doesNotMatch(html, /id="input-account-run-history-text-enabled"/);
|
||||
});
|
||||
|
||||
@@ -222,6 +225,7 @@ const inputAutoSkipFailuresThreadIntervalMinutes = { value: '0' };
|
||||
const inputAutoDelayEnabled = { checked: false };
|
||||
const inputAutoDelayMinutes = { value: '30' };
|
||||
const inputAutoStepDelaySeconds = { value: '' };
|
||||
const inputOAuthFlowTimeoutEnabled = { checked: false };
|
||||
const inputPhoneVerificationEnabled = { checked: true };
|
||||
const inputVerificationResendCount = { value: '4' };
|
||||
const inputHeroSmsApiKey = { value: 'demo-key' };
|
||||
@@ -299,6 +303,7 @@ return { collectSettingsPayload };
|
||||
const payload = api.collectSettingsPayload();
|
||||
|
||||
assert.equal(payload.phoneVerificationEnabled, true);
|
||||
assert.equal(payload.oauthFlowTimeoutEnabled, false);
|
||||
assert.equal(payload.accountRunHistoryTextEnabled, true);
|
||||
assert.equal(payload.accountRunHistoryHelperBaseUrl, 'http://127.0.0.1:17373');
|
||||
assert.equal(payload.heroSmsApiKey, 'demo-key');
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
|
||||
const step9ModuleSource = fs.readFileSync('background/steps/confirm-oauth.js', 'utf8');
|
||||
|
||||
test('step9 observes disabled oauth timeout while waiting for localhost callback', async () => {
|
||||
const api = new Function('step9ModuleSource', `
|
||||
const self = {};
|
||||
let webNavListener = null;
|
||||
let webNavCommittedListener = null;
|
||||
let step8TabUpdatedListener = null;
|
||||
let step8PendingReject = null;
|
||||
let cleanupCalls = 0;
|
||||
let remainingCalls = 0;
|
||||
let recoveryCalls = 0;
|
||||
let completePayload = null;
|
||||
const callbackUrl = 'http://localhost:1455/auth/callback?code=abc&state=xyz';
|
||||
|
||||
const chrome = {
|
||||
webNavigation: {
|
||||
onBeforeNavigate: {
|
||||
addListener(listener) {
|
||||
webNavListener = listener;
|
||||
setTimeout(() => {
|
||||
if (typeof webNavListener === 'function') {
|
||||
webNavListener({ tabId: 123, url: callbackUrl });
|
||||
}
|
||||
}, 25);
|
||||
},
|
||||
removeListener() {},
|
||||
},
|
||||
onCommitted: {
|
||||
addListener(listener) {
|
||||
webNavCommittedListener = listener;
|
||||
},
|
||||
removeListener() {},
|
||||
},
|
||||
},
|
||||
tabs: {
|
||||
onUpdated: {
|
||||
addListener(listener) {
|
||||
step8TabUpdatedListener = listener;
|
||||
},
|
||||
removeListener() {},
|
||||
},
|
||||
async update() {},
|
||||
},
|
||||
};
|
||||
|
||||
async function addLog() {}
|
||||
function cleanupStep8NavigationListeners() {
|
||||
cleanupCalls += 1;
|
||||
webNavListener = null;
|
||||
webNavCommittedListener = null;
|
||||
step8TabUpdatedListener = null;
|
||||
}
|
||||
function throwIfStep8SettledOrStopped(resolved) {
|
||||
if (resolved) throw new Error('already resolved');
|
||||
}
|
||||
async function getTabId() { return 123; }
|
||||
async function isTabAlive() { return true; }
|
||||
async function ensureStep8SignupPageReady() {}
|
||||
async function getOAuthFlowStepTimeoutMs(defaultTimeoutMs, options = {}) {
|
||||
if (options.actionLabel === 'OAuth localhost 回调') {
|
||||
return 1;
|
||||
}
|
||||
return defaultTimeoutMs;
|
||||
}
|
||||
async function getOAuthFlowRemainingMs() {
|
||||
remainingCalls += 1;
|
||||
return null;
|
||||
}
|
||||
async function recoverOAuthLocalhostTimeout() {
|
||||
recoveryCalls += 1;
|
||||
throw new Error('should not recover when timeout has been disabled');
|
||||
}
|
||||
async function waitForStep8Ready() {
|
||||
return {
|
||||
consentReady: true,
|
||||
url: 'https://auth.openai.com/sign-in-with-chatgpt/codex/consent',
|
||||
};
|
||||
}
|
||||
async function triggerStep8ContentStrategy() {}
|
||||
async function waitForStep8ClickEffect() {
|
||||
return { progressed: true, reason: 'url_changed', url: 'https://chatgpt.com/' };
|
||||
}
|
||||
function getStep8CallbackUrlFromNavigation(details, signupTabId) {
|
||||
return Number(details?.tabId) === Number(signupTabId) ? details.url : '';
|
||||
}
|
||||
function getStep8CallbackUrlFromTabUpdate() { return ''; }
|
||||
function getStep8EffectLabel() { return 'URL 已变化'; }
|
||||
async function prepareStep8DebuggerClick() { return { rect: { centerX: 10, centerY: 10 } }; }
|
||||
async function clickWithDebugger() {}
|
||||
async function reloadStep8ConsentPage() {}
|
||||
async function reuseOrCreateTab() { return 123; }
|
||||
async function sleepWithStop() {}
|
||||
function setWebNavListener(listener) { webNavListener = listener; }
|
||||
function getWebNavListener() { return webNavListener; }
|
||||
function setWebNavCommittedListener(listener) { webNavCommittedListener = listener; }
|
||||
function getWebNavCommittedListener() { return webNavCommittedListener; }
|
||||
function setStep8TabUpdatedListener(listener) { step8TabUpdatedListener = listener; }
|
||||
function getStep8TabUpdatedListener() { return step8TabUpdatedListener; }
|
||||
function setStep8PendingReject(handler) { step8PendingReject = handler; }
|
||||
async function completeStepFromBackground(step, payload) {
|
||||
completePayload = { step, payload };
|
||||
}
|
||||
|
||||
const STEP8_CLICK_RETRY_DELAY_MS = 1;
|
||||
const STEP8_READY_WAIT_TIMEOUT_MS = 5;
|
||||
const STEP8_MAX_ROUNDS = 1;
|
||||
const STEP8_STRATEGIES = [
|
||||
{ mode: 'content', strategy: 'requestSubmit', label: 'form.requestSubmit' },
|
||||
];
|
||||
|
||||
${step9ModuleSource}
|
||||
|
||||
const executor = self.MultiPageBackgroundStep9.createStep9Executor({
|
||||
addLog,
|
||||
chrome,
|
||||
cleanupStep8NavigationListeners,
|
||||
clickWithDebugger,
|
||||
completeStepFromBackground,
|
||||
ensureStep8SignupPageReady,
|
||||
getOAuthFlowRemainingMs,
|
||||
getOAuthFlowStepTimeoutMs,
|
||||
getStep8CallbackUrlFromNavigation,
|
||||
getStep8CallbackUrlFromTabUpdate,
|
||||
getStep8EffectLabel,
|
||||
getTabId,
|
||||
getWebNavCommittedListener,
|
||||
getWebNavListener,
|
||||
getStep8TabUpdatedListener,
|
||||
isTabAlive,
|
||||
prepareStep8DebuggerClick,
|
||||
recoverOAuthLocalhostTimeout,
|
||||
reloadStep8ConsentPage,
|
||||
reuseOrCreateTab,
|
||||
setStep8PendingReject,
|
||||
setStep8TabUpdatedListener,
|
||||
setWebNavCommittedListener,
|
||||
setWebNavListener,
|
||||
sleepWithStop,
|
||||
STEP8_CLICK_RETRY_DELAY_MS,
|
||||
STEP8_MAX_ROUNDS,
|
||||
STEP8_READY_WAIT_TIMEOUT_MS,
|
||||
STEP8_STRATEGIES,
|
||||
throwIfStep8SettledOrStopped,
|
||||
triggerStep8ContentStrategy,
|
||||
waitForStep8ClickEffect,
|
||||
waitForStep8Ready,
|
||||
});
|
||||
|
||||
return {
|
||||
executeStep9: executor.executeStep9,
|
||||
snapshot() {
|
||||
return {
|
||||
cleanupCalls,
|
||||
remainingCalls,
|
||||
recoveryCalls,
|
||||
completePayload,
|
||||
hasPendingReject: Boolean(step8PendingReject),
|
||||
};
|
||||
},
|
||||
};
|
||||
`)(step9ModuleSource);
|
||||
|
||||
await api.executeStep9({
|
||||
oauthUrl: 'https://auth.openai.com/original-oauth',
|
||||
visibleStep: 9,
|
||||
});
|
||||
|
||||
const snapshot = api.snapshot();
|
||||
assert.equal(snapshot.recoveryCalls, 0);
|
||||
assert.equal(snapshot.remainingCalls >= 1, true);
|
||||
assert.equal(snapshot.cleanupCalls >= 1, true);
|
||||
assert.equal(snapshot.hasPendingReject, false);
|
||||
assert.deepEqual(snapshot.completePayload, {
|
||||
step: 9,
|
||||
payload: {
|
||||
localhostUrl: 'http://localhost:1455/auth/callback?code=abc&state=xyz',
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -11,6 +11,7 @@ let step8TabUpdatedListener = null;
|
||||
let step8PendingReject = null;
|
||||
let cleanupCalls = 0;
|
||||
let timeoutCalls = 0;
|
||||
let remainingCalls = 0;
|
||||
let recoveryCalls = 0;
|
||||
let completePayload = null;
|
||||
const logs = [];
|
||||
@@ -25,7 +26,7 @@ const chrome = {
|
||||
if (typeof webNavListener === 'function') {
|
||||
webNavListener({ tabId: 123, url: callbackUrl });
|
||||
}
|
||||
}, 0);
|
||||
}, 25);
|
||||
},
|
||||
removeListener() {},
|
||||
},
|
||||
@@ -107,6 +108,11 @@ async function recoverOAuthLocalhostTimeout(details = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
async function getOAuthFlowRemainingMs() {
|
||||
remainingCalls += 1;
|
||||
return null;
|
||||
}
|
||||
|
||||
function getStep8CallbackUrlFromNavigation(details, signupTabId) {
|
||||
if (
|
||||
Number(signupTabId) === Number(details?.tabId)
|
||||
@@ -163,6 +169,7 @@ const executor = self.MultiPageBackgroundStep9.createStep9Executor({
|
||||
clickWithDebugger,
|
||||
completeStepFromBackground,
|
||||
ensureStep8SignupPageReady,
|
||||
getOAuthFlowRemainingMs,
|
||||
getOAuthFlowStepTimeoutMs,
|
||||
getStep8CallbackUrlFromNavigation,
|
||||
getStep8CallbackUrlFromTabUpdate,
|
||||
@@ -197,6 +204,7 @@ return {
|
||||
return {
|
||||
cleanupCalls,
|
||||
timeoutCalls,
|
||||
remainingCalls,
|
||||
recoveryCalls,
|
||||
completePayload,
|
||||
hasPendingReject: Boolean(step8PendingReject),
|
||||
|
||||
Reference in New Issue
Block a user