diff --git a/background.js b/background.js index a016efe..948783d 100644 --- a/background.js +++ b/background.js @@ -936,12 +936,33 @@ function buildResolvedStepDefinitionState(state = {}) { signupMethod: resolvedSignupMethod, resolvedSignupMethod: resolvedSignupMethod, phoneSignupReloginAfterBindEmailEnabled: Boolean(state?.phoneSignupReloginAfterBindEmailEnabled), + phoneVerificationEnabled: Boolean( + stepDefinitionOptions.phoneVerificationEnabled + ?? capabilityState?.runtimeLocks?.phoneVerificationEnabled + ?? state?.phoneVerificationEnabled + ), }; } function getStepDefinitionsForState(state = {}) { const resolvedState = buildResolvedStepDefinitionState(state); const rootScope = typeof self !== 'undefined' ? self : globalThis; + const applyPhoneVerificationStepVisibility = (definitions = []) => { + if (Boolean(resolvedState?.phoneVerificationEnabled)) { + return definitions; + } + const hiddenStepKeys = new Set([ + 'post-login-phone-verification', + 'post-bound-email-phone-verification', + ]); + return (Array.isArray(definitions) ? definitions : []) + .filter((definition) => !hiddenStepKeys.has(String(definition?.key || '').trim())) + .map((definition, index) => ({ + ...definition, + id: index + 1, + order: (index + 1) * 10, + })); + }; if (rootScope.MultiPageStepDefinitions?.getSteps) { const defaultFlowId = typeof DEFAULT_ACTIVE_FLOW_ID === 'string' ? DEFAULT_ACTIVE_FLOW_ID : 'openai'; const activeFlowId = String(resolvedState?.activeFlowId || '').trim().toLowerCase() || defaultFlowId; @@ -951,6 +972,7 @@ function getStepDefinitionsForState(state = {}) { plusPaymentMethod: normalizePlusPaymentMethod(resolvedState?.plusPaymentMethod), plusAccountAccessStrategy: normalizePlusAccountAccessStrategy(resolvedState?.plusAccountAccessStrategy), signupMethod: getSignupMethodForStepDefinitions(resolvedState), + phoneVerificationEnabled: Boolean(resolvedState?.phoneVerificationEnabled), phoneSignupReloginAfterBindEmailEnabled: Boolean(resolvedState?.phoneSignupReloginAfterBindEmailEnabled), }); if (Array.isArray(definitions)) { @@ -962,7 +984,7 @@ function getStepDefinitionsForState(state = {}) { return []; } if (!Boolean(resolvedState?.plusModeEnabled)) { - return NORMAL_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(NORMAL_STEP_DEFINITIONS); } const paymentMethod = normalizePlusPaymentMethod(resolvedState?.plusPaymentMethod); const signupMethod = getSignupMethodForStepDefinitions(resolvedState); @@ -972,58 +994,58 @@ function getStepDefinitionsForState(state = {}) { signupMethod === SIGNUP_METHOD_EMAIL && plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_SUB2API_CODEX_SESSION ) { - return PLUS_GPC_SUB2API_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_GPC_SUB2API_SESSION_STEP_DEFINITIONS); } if ( signupMethod === SIGNUP_METHOD_EMAIL && plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_CPA_CODEX_SESSION ) { - return PLUS_GPC_CPA_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_GPC_CPA_SESSION_STEP_DEFINITIONS); } - return PLUS_GPC_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_GPC_STEP_DEFINITIONS); } if (paymentMethod === PLUS_PAYMENT_METHOD_GOPAY) { if ( signupMethod === SIGNUP_METHOD_EMAIL && plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_SUB2API_CODEX_SESSION ) { - return PLUS_GOPAY_SUB2API_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_GOPAY_SUB2API_SESSION_STEP_DEFINITIONS); } if ( signupMethod === SIGNUP_METHOD_EMAIL && plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_CPA_CODEX_SESSION ) { - return PLUS_GOPAY_CPA_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_GOPAY_CPA_SESSION_STEP_DEFINITIONS); } - return PLUS_GOPAY_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_GOPAY_STEP_DEFINITIONS); } if (paymentMethod === PLUS_PAYMENT_METHOD_PAYPAL_HOSTED) { if (signupMethod === SIGNUP_METHOD_PHONE) { - return Boolean(resolvedState?.phoneSignupReloginAfterBindEmailEnabled) + return applyPhoneVerificationStepVisibility(Boolean(resolvedState?.phoneSignupReloginAfterBindEmailEnabled) ? PLUS_PAYPAL_HOSTED_CHECKOUT_PHONE_BOUND_EMAIL_RELOGIN_STEP_DEFINITIONS - : PLUS_PAYPAL_HOSTED_CHECKOUT_PHONE_STEP_DEFINITIONS; + : PLUS_PAYPAL_HOSTED_CHECKOUT_PHONE_STEP_DEFINITIONS); } if (plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_SUB2API_CODEX_SESSION) { - return PLUS_PAYPAL_HOSTED_CHECKOUT_SUB2API_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_PAYPAL_HOSTED_CHECKOUT_SUB2API_SESSION_STEP_DEFINITIONS); } if (plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_CPA_CODEX_SESSION) { - return PLUS_PAYPAL_HOSTED_CHECKOUT_CPA_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_PAYPAL_HOSTED_CHECKOUT_CPA_SESSION_STEP_DEFINITIONS); } - return PLUS_PAYPAL_HOSTED_CHECKOUT_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_PAYPAL_HOSTED_CHECKOUT_STEP_DEFINITIONS); } if ( signupMethod === SIGNUP_METHOD_EMAIL && plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_SUB2API_CODEX_SESSION ) { - return PLUS_PAYPAL_SUB2API_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_PAYPAL_SUB2API_SESSION_STEP_DEFINITIONS); } if ( signupMethod === SIGNUP_METHOD_EMAIL && plusAccountAccessStrategy === PLUS_ACCOUNT_ACCESS_STRATEGY_CPA_CODEX_SESSION ) { - return PLUS_PAYPAL_CPA_SESSION_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_PAYPAL_CPA_SESSION_STEP_DEFINITIONS); } - return PLUS_PAYPAL_STEP_DEFINITIONS; + return applyPhoneVerificationStepVisibility(PLUS_PAYPAL_STEP_DEFINITIONS); } function getStepIdsForState(state = {}) { diff --git a/core/flow-kernel/flow-capabilities.js b/core/flow-kernel/flow-capabilities.js index ac3dfd3..9bdbb2e 100644 --- a/core/flow-kernel/flow-capabilities.js +++ b/core/flow-kernel/flow-capabilities.js @@ -405,6 +405,7 @@ targetId: effectiveTargetId, plusAccountAccessStrategy: effectivePlusAccountAccessStrategy, plusModeEnabled: runtimeLocks.plusModeEnabled, + phoneVerificationEnabled: runtimeLocks.phoneVerificationEnabled, signupMethod: effectiveSignupMethod, }, supportedPanelModes: supportedTargetIds, diff --git a/flows/openai/workflow.js b/flows/openai/workflow.js index ddd27e8..afd35ef 100644 --- a/flows/openai/workflow.js +++ b/flows/openai/workflow.js @@ -3027,11 +3027,19 @@ 'paypal-hosted-review', 'gopay-subscription-confirm', ]); + const POST_LOGIN_PHONE_VERIFICATION_STEP_KEYS = Object.freeze([ + 'post-login-phone-verification', + 'post-bound-email-phone-verification', + ]); function omitPlusPaymentChainSteps(steps = []) { return steps.filter((step) => !PLUS_PAYMENT_CHAIN_STEP_KEYS.includes(String(step?.key || '').trim())); } + function omitPostLoginPhoneVerificationSteps(steps = []) { + return steps.filter((step) => !POST_LOGIN_PHONE_VERIFICATION_STEP_KEYS.includes(String(step?.key || '').trim())); + } + function reindexModeStepDefinitions(steps = []) { return (Array.isArray(steps) ? steps : []).map((step, index) => ({ ...step, @@ -3116,6 +3124,13 @@ return Boolean(options?.phoneSignupReloginAfterBindEmailEnabled); } + function isPhoneVerificationEnabled(options = {}) { + if (Object.prototype.hasOwnProperty.call(options || {}, 'phoneVerificationEnabled')) { + return Boolean(options.phoneVerificationEnabled); + } + return true; + } + function normalizePlusAccountAccessStrategy(value = '') { const normalized = String(value || '').trim().toLowerCase(); if (normalized === PLUS_ACCOUNT_ACCESS_STRATEGY_SUB2API_CODEX_SESSION) { @@ -3206,6 +3221,9 @@ ) { steps = omitPlusPaymentChainSteps(steps); } + if (!isPhoneVerificationEnabled(options)) { + steps = omitPostLoginPhoneVerificationSteps(steps); + } return reindexModeStepDefinitions(steps); } diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js index 6db8e70..837d976 100644 --- a/sidepanel/sidepanel.js +++ b/sidepanel/sidepanel.js @@ -588,6 +588,7 @@ let currentPlusModeEnabled = false; let currentPlusPaymentMethod = DEFAULT_PLUS_PAYMENT_METHOD; let currentPlusAccountAccessStrategy = DEFAULT_PLUS_ACCOUNT_ACCESS_STRATEGY; let currentSignupMethod = DEFAULT_SIGNUP_METHOD; +let currentPhoneVerificationEnabled = false; let currentPhoneSignupReloginAfterBindEmailEnabled = DEFAULT_PHONE_SIGNUP_RELOGIN_AFTER_BIND_EMAIL_ENABLED; let currentStepDefinitionFlowId = DEFAULT_ACTIVE_FLOW_ID; let phoneSignupReuseUiWasLocked = false; @@ -611,12 +612,14 @@ let stepDefinitions = getStepDefinitionsForMode(false, { plusPaymentMethod: currentPlusPaymentMethod, plusAccountAccessStrategy: currentPlusAccountAccessStrategy, signupMethod: currentSignupMethod, + phoneVerificationEnabled: currentPhoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled: currentPhoneSignupReloginAfterBindEmailEnabled, }); let workflowNodes = getWorkflowNodesForMode(false, { plusPaymentMethod: currentPlusPaymentMethod, plusAccountAccessStrategy: currentPlusAccountAccessStrategy, signupMethod: currentSignupMethod, + phoneVerificationEnabled: currentPhoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled: currentPhoneSignupReloginAfterBindEmailEnabled, }); let STEP_IDS = stepDefinitions.map((step) => Number(step.id)).filter(Number.isFinite); @@ -883,6 +886,13 @@ function getStepDefinitionsForMode(plusModeEnabled = false, options = {}) { const rawSignupMethod = typeof options === 'string' ? currentSignupMethod : (options.signupMethod || currentSignupMethod || DEFAULT_SIGNUP_METHOD); + const phoneVerificationEnabled = typeof options === 'string' + ? (typeof inputPhoneVerificationEnabled !== 'undefined' && inputPhoneVerificationEnabled + ? Boolean(inputPhoneVerificationEnabled.checked) + : Boolean(typeof latestState !== 'undefined' ? latestState?.phoneVerificationEnabled : false)) + : Boolean(options.phoneVerificationEnabled ?? (typeof inputPhoneVerificationEnabled !== 'undefined' && inputPhoneVerificationEnabled + ? inputPhoneVerificationEnabled.checked + : (typeof latestState !== 'undefined' ? latestState?.phoneVerificationEnabled : false))); const phoneSignupReloginAfterBindEmailEnabled = typeof options === 'string' ? currentPhoneSignupReloginAfterBindEmailEnabled : Boolean(options.phoneSignupReloginAfterBindEmailEnabled ?? currentPhoneSignupReloginAfterBindEmailEnabled); @@ -898,6 +908,7 @@ function getStepDefinitionsForMode(plusModeEnabled = false, options = {}) { plusPaymentMethod: normalizePlusPaymentMethod(rawPaymentMethod), plusAccountAccessStrategy: normalizePlusAccountAccessStrategy(rawPlusAccountAccessStrategy), signupMethod: normalizeSignupMethod(rawSignupMethod), + phoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled, accountContributionEnabled, }) || []) @@ -922,6 +933,13 @@ function getWorkflowNodesForMode(plusModeEnabled = false, options = {}) { const rawSignupMethod = typeof options === 'string' ? currentSignupMethod : (options.signupMethod || currentSignupMethod || DEFAULT_SIGNUP_METHOD); + const phoneVerificationEnabled = typeof options === 'string' + ? (typeof inputPhoneVerificationEnabled !== 'undefined' && inputPhoneVerificationEnabled + ? Boolean(inputPhoneVerificationEnabled.checked) + : Boolean(typeof latestState !== 'undefined' ? latestState?.phoneVerificationEnabled : false)) + : Boolean(options.phoneVerificationEnabled ?? (typeof inputPhoneVerificationEnabled !== 'undefined' && inputPhoneVerificationEnabled + ? inputPhoneVerificationEnabled.checked + : (typeof latestState !== 'undefined' ? latestState?.phoneVerificationEnabled : false))); const phoneSignupReloginAfterBindEmailEnabled = typeof options === 'string' ? currentPhoneSignupReloginAfterBindEmailEnabled : Boolean(options.phoneSignupReloginAfterBindEmailEnabled ?? currentPhoneSignupReloginAfterBindEmailEnabled); @@ -937,6 +955,7 @@ function getWorkflowNodesForMode(plusModeEnabled = false, options = {}) { plusPaymentMethod: normalizePlusPaymentMethod(rawPaymentMethod), plusAccountAccessStrategy: normalizePlusAccountAccessStrategy(rawPlusAccountAccessStrategy), signupMethod: normalizeSignupMethod(rawSignupMethod), + phoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled, accountContributionEnabled, }); @@ -1003,6 +1022,13 @@ function rebuildStepDefinitionState(plusModeEnabled = false, options = {}) { const rawSignupMethod = typeof options === 'string' ? currentSignupMethod : (options.signupMethod || currentSignupMethod || DEFAULT_SIGNUP_METHOD); + const phoneVerificationEnabled = typeof options === 'string' + ? (typeof inputPhoneVerificationEnabled !== 'undefined' && inputPhoneVerificationEnabled + ? Boolean(inputPhoneVerificationEnabled.checked) + : Boolean(typeof latestState !== 'undefined' ? latestState?.phoneVerificationEnabled : false)) + : Boolean(options.phoneVerificationEnabled ?? (typeof inputPhoneVerificationEnabled !== 'undefined' && inputPhoneVerificationEnabled + ? inputPhoneVerificationEnabled.checked + : (typeof latestState !== 'undefined' ? latestState?.phoneVerificationEnabled : false))); const phoneSignupReloginAfterBindEmailEnabled = typeof options === 'string' ? currentPhoneSignupReloginAfterBindEmailEnabled : Boolean(options.phoneSignupReloginAfterBindEmailEnabled ?? currentPhoneSignupReloginAfterBindEmailEnabled); @@ -1013,6 +1039,7 @@ function rebuildStepDefinitionState(plusModeEnabled = false, options = {}) { currentPlusPaymentMethod = normalizePlusPaymentMethod(rawPaymentMethod); currentPlusAccountAccessStrategy = normalizePlusAccountAccessStrategy(rawPlusAccountAccessStrategy); currentSignupMethod = normalizeSignupMethod(rawSignupMethod); + currentPhoneVerificationEnabled = Boolean(phoneVerificationEnabled); currentPhoneSignupReloginAfterBindEmailEnabled = phoneSignupReloginAfterBindEmailEnabled; const nextActiveFlowId = String( options?.activeFlowId @@ -1027,6 +1054,7 @@ function rebuildStepDefinitionState(plusModeEnabled = false, options = {}) { plusPaymentMethod: currentPlusPaymentMethod, plusAccountAccessStrategy: currentPlusAccountAccessStrategy, signupMethod: currentSignupMethod, + phoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled: currentPhoneSignupReloginAfterBindEmailEnabled, accountContributionEnabled, }); @@ -1036,6 +1064,7 @@ function rebuildStepDefinitionState(plusModeEnabled = false, options = {}) { plusPaymentMethod: currentPlusPaymentMethod, plusAccountAccessStrategy: currentPlusAccountAccessStrategy, signupMethod: currentSignupMethod, + phoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled: currentPhoneSignupReloginAfterBindEmailEnabled, accountContributionEnabled, }) @@ -9193,6 +9222,9 @@ function resolveStepDefinitionCapabilityState(state = latestState, options = {}) ), signupMethod: capabilityState?.effectiveSignupMethod || normalizeSignupMethod((options?.signupMethod ?? nextState?.signupMethod) || DEFAULT_SIGNUP_METHOD), + phoneVerificationEnabled: capabilityState + ? Boolean(capabilityState.runtimeLocks?.phoneVerificationEnabled) + : Boolean(nextState?.phoneVerificationEnabled), }; } @@ -10850,6 +10882,9 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethodOr || defaultStrategy ); const nextSignupMethod = normalizeSignupMethod(options.signupMethod || currentSignupMethod || DEFAULT_SIGNUP_METHOD); + const nextPhoneVerificationEnabled = Boolean(options.phoneVerificationEnabled ?? (typeof inputPhoneVerificationEnabled !== 'undefined' && inputPhoneVerificationEnabled + ? inputPhoneVerificationEnabled.checked + : (typeof latestState !== 'undefined' ? latestState?.phoneVerificationEnabled : false))); const nextPhoneSignupReloginAfterBindEmailEnabled = Boolean( options.phoneSignupReloginAfterBindEmailEnabled ?? (typeof inputPhoneSignupReloginAfterBindEmail !== 'undefined' && inputPhoneSignupReloginAfterBindEmail @@ -10877,6 +10912,7 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethodOr plusPaymentMethod: nextPaymentMethod, plusAccountAccessStrategy: nextPlusAccountAccessStrategy, signupMethod: nextSignupMethod, + phoneVerificationEnabled: nextPhoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled: nextPhoneSignupReloginAfterBindEmailEnabled, }); const paymentTitleChanged = Boolean(nextPlusModeEnabled && currentPaymentStep && nextPaymentTitle && currentPaymentStep.title !== nextPaymentTitle); @@ -10885,6 +10921,7 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethodOr || nextPaymentMethod !== currentPlusPaymentMethod || nextPlusAccountAccessStrategy !== currentPlusAccountAccessStrategy || nextSignupMethod !== currentSignupMethod + || nextPhoneVerificationEnabled !== currentPhoneVerificationEnabled || nextPhoneSignupReloginAfterBindEmailEnabled !== currentPhoneSignupReloginAfterBindEmailEnabled || nextAccountContributionEnabled !== Boolean(typeof latestState !== 'undefined' ? latestState?.accountContributionEnabled : false) || nextActiveFlowId !== currentFlowId @@ -10898,6 +10935,7 @@ function syncStepDefinitionsForMode(plusModeEnabled = false, plusPaymentMethodOr plusPaymentMethod: nextPaymentMethod, plusAccountAccessStrategy: nextPlusAccountAccessStrategy, signupMethod: nextSignupMethod, + phoneVerificationEnabled: nextPhoneVerificationEnabled, phoneSignupReloginAfterBindEmailEnabled: nextPhoneSignupReloginAfterBindEmailEnabled, accountContributionEnabled: nextAccountContributionEnabled, }); @@ -10925,6 +10963,7 @@ function syncStepDefinitionsFromUiState(stateOverrides = {}) { plusPaymentMethod: getSelectedPlusPaymentMethod(nextState), plusAccountAccessStrategy: stepDefinitionState.plusAccountAccessStrategy, signupMethod: stepDefinitionState.signupMethod, + phoneVerificationEnabled: Boolean(stepDefinitionState.phoneVerificationEnabled), phoneSignupReloginAfterBindEmailEnabled: Boolean(nextState?.phoneSignupReloginAfterBindEmailEnabled), accountContributionEnabled: Boolean(nextState?.accountContributionEnabled), }); @@ -10949,6 +10988,7 @@ function applySettingsState(state) { activeFlowId: state?.activeFlowId || state?.flowId, plusPaymentMethod: state?.plusPaymentMethod, signupMethod: stepDefinitionState.signupMethod, + phoneVerificationEnabled: Boolean(stepDefinitionState.phoneVerificationEnabled), phoneSignupReloginAfterBindEmailEnabled: Boolean(state?.phoneSignupReloginAfterBindEmailEnabled), accountContributionEnabled: Boolean(state?.accountContributionEnabled), }); @@ -16705,6 +16745,10 @@ inputPhoneVerificationEnabled?.addEventListener('change', () => { updatePhoneVerificationSettingsUI(); showToast('已切回邮箱注册', 'info', 1600); } + syncStepDefinitionsFromUiState({ + phoneVerificationEnabled: Boolean(inputPhoneVerificationEnabled.checked), + signupMethod: getSelectedSignupMethod(), + }); markSettingsDirty(true); saveSettings({ silent: true }).catch(() => { }); }); @@ -17990,6 +18034,14 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { } if (message.payload.phoneVerificationEnabled !== undefined || message.payload.signupMethod !== undefined) { updatePhoneVerificationSettingsUI(); + syncStepDefinitionsFromUiState({ + phoneVerificationEnabled: inputPhoneVerificationEnabled + ? Boolean(inputPhoneVerificationEnabled.checked) + : Boolean(latestState?.phoneVerificationEnabled), + signupMethod: typeof getSelectedSignupMethod === 'function' + ? getSelectedSignupMethod() + : latestState?.signupMethod, + }); } const activePhoneSmsProvider = normalizePhoneSmsProviderValue( message.payload.phoneSmsProvider !== undefined diff --git a/tests/background-signup-method-settings.test.js b/tests/background-signup-method-settings.test.js index 3e73e2e..1c48574 100644 --- a/tests/background-signup-method-settings.test.js +++ b/tests/background-signup-method-settings.test.js @@ -188,6 +188,7 @@ return { plusPaymentMethod: 'gopay', plusAccountAccessStrategy: 'oauth', signupMethod: 'phone', + phoneVerificationEnabled: false, phoneSignupReloginAfterBindEmailEnabled: false, }]); assert.equal(steps[0].title, '注册并输入手机号'); diff --git a/tests/flow-capabilities-module.test.js b/tests/flow-capabilities-module.test.js index ba15192..4fa2bab 100644 --- a/tests/flow-capabilities-module.test.js +++ b/tests/flow-capabilities-module.test.js @@ -28,6 +28,7 @@ test('flow capability registry keeps OpenAI phone signup available only when run assert.equal(enabledState.effectiveSignupMethod, 'phone'); assert.equal(enabledState.shouldWarnCpaPhoneSignup, true); assert.equal(enabledState.targetCapabilities.usesOauthTimeoutBudget, true); + assert.equal(enabledState.stepDefinitionOptions.phoneVerificationEnabled, true); assert.deepEqual(enabledState.effectiveSignupMethods, ['email', 'phone']); const plusLockedState = registry.resolveSidepanelCapabilities({ @@ -43,6 +44,7 @@ test('flow capability registry keeps OpenAI phone signup available only when run assert.equal(plusLockedState.canUsePhoneSignup, false); assert.equal(plusLockedState.effectiveSignupMethod, 'email'); + assert.equal(plusLockedState.stepDefinitionOptions.phoneVerificationEnabled, true); assert.equal(plusLockedState.shouldWarnCpaPhoneSignup, false); assert.equal(plusLockedState.targetCapabilities.usesOauthTimeoutBudget, false); assert.deepEqual(plusLockedState.effectiveSignupMethods, ['email']); diff --git a/tests/plus-account-access-strategy.test.js b/tests/plus-account-access-strategy.test.js index 6959779..351fe09 100644 --- a/tests/plus-account-access-strategy.test.js +++ b/tests/plus-account-access-strategy.test.js @@ -263,6 +263,7 @@ const window = { }, }; let latestState = { activeFlowId: 'openai' }; +const inputPhoneVerificationEnabled = { checked: false }; let currentPlusModeEnabled = false; let currentPlusPaymentMethod = 'paypal'; const PLUS_ACCOUNT_ACCESS_STRATEGY_OAUTH = 'oauth'; @@ -270,6 +271,7 @@ const PLUS_ACCOUNT_ACCESS_STRATEGY_SUB2API_CODEX_SESSION = 'sub2api_codex_sessio const PLUS_ACCOUNT_ACCESS_STRATEGY_CPA_CODEX_SESSION = 'cpa_codex_session'; let currentPlusAccountAccessStrategy = 'oauth'; let currentSignupMethod = 'email'; +let currentPhoneVerificationEnabled = false; let currentPhoneSignupReloginAfterBindEmailEnabled = false; let currentStepDefinitionFlowId = 'openai'; const DEFAULT_ACTIVE_FLOW_ID = 'openai'; @@ -326,6 +328,7 @@ return { plusPaymentMethod: 'paypal', plusAccountAccessStrategy: 'sub2api_codex_session', signupMethod: 'email', + phoneVerificationEnabled: false, phoneSignupReloginAfterBindEmailEnabled: false, accountContributionEnabled: false, }, @@ -338,6 +341,7 @@ return { plusPaymentMethod: 'paypal', plusAccountAccessStrategy: 'sub2api_codex_session', signupMethod: 'email', + phoneVerificationEnabled: false, phoneSignupReloginAfterBindEmailEnabled: false, accountContributionEnabled: false, }, diff --git a/tests/sidepanel-flow-source-registry.test.js b/tests/sidepanel-flow-source-registry.test.js index 4111b07..804cb74 100644 --- a/tests/sidepanel-flow-source-registry.test.js +++ b/tests/sidepanel-flow-source-registry.test.js @@ -181,6 +181,7 @@ let currentPlusModeEnabled = false; let currentPlusPaymentMethod = 'paypal'; let currentPlusAccountAccessStrategy = 'oauth'; let currentSignupMethod = 'email'; +let currentPhoneVerificationEnabled = false; let currentPhoneSignupReloginAfterBindEmailEnabled = false; let currentStepDefinitionFlowId = 'openai'; const DEFAULT_ACTIVE_FLOW_ID = 'openai'; @@ -223,6 +224,7 @@ return { plusPaymentMethod: 'paypal', plusAccountAccessStrategy: 'oauth', signupMethod: 'email', + phoneVerificationEnabled: false, phoneSignupReloginAfterBindEmailEnabled: false, accountContributionEnabled: false, }, diff --git a/tests/sidepanel-plus-payment-method.test.js b/tests/sidepanel-plus-payment-method.test.js index bdfc27d..9af3b80 100644 --- a/tests/sidepanel-plus-payment-method.test.js +++ b/tests/sidepanel-plus-payment-method.test.js @@ -89,6 +89,7 @@ const PLUS_ACCOUNT_ACCESS_STRATEGY_CPA_CODEX_SESSION = 'cpa_codex_session'; const DEFAULT_PLUS_ACCOUNT_ACCESS_STRATEGY = PLUS_ACCOUNT_ACCESS_STRATEGY_OAUTH; let currentPlusAccountAccessStrategy = DEFAULT_PLUS_ACCOUNT_ACCESS_STRATEGY; let currentSignupMethod = 'email'; +let currentPhoneVerificationEnabled = false; let currentPhoneSignupReloginAfterBindEmailEnabled = false; const DEFAULT_SIGNUP_METHOD = 'email'; let stepDefinitions = []; @@ -113,7 +114,7 @@ return { assert.deepEqual(api.getStepIds(), [7]); assert.deepEqual(api.calls[0], { type: 'getSteps', - options: { activeFlowId: 'openai', plusModeEnabled: true, plusPaymentMethod: 'gopay', plusAccountAccessStrategy: 'oauth', signupMethod: 'email', phoneSignupReloginAfterBindEmailEnabled: false, accountContributionEnabled: false }, + options: { activeFlowId: 'openai', plusModeEnabled: true, plusPaymentMethod: 'gopay', plusAccountAccessStrategy: 'oauth', signupMethod: 'email', phoneVerificationEnabled: false, phoneSignupReloginAfterBindEmailEnabled: false, accountContributionEnabled: false }, }); assert.deepEqual(api.calls[1], { type: 'render', stepIds: [7] }); }); @@ -400,6 +401,7 @@ const PLUS_ACCOUNT_ACCESS_STRATEGY_CPA_CODEX_SESSION = 'cpa_codex_session'; const DEFAULT_PLUS_ACCOUNT_ACCESS_STRATEGY = PLUS_ACCOUNT_ACCESS_STRATEGY_OAUTH; let currentPlusAccountAccessStrategy = DEFAULT_PLUS_ACCOUNT_ACCESS_STRATEGY; let currentSignupMethod = 'email'; +let currentPhoneVerificationEnabled = false; let currentPhoneSignupReloginAfterBindEmailEnabled = false; const DEFAULT_SIGNUP_METHOD = 'email'; let stepDefinitions = []; @@ -424,7 +426,7 @@ return { assert.deepEqual(api.getStepIds(), [13]); assert.deepEqual(api.calls[0], { type: 'getSteps', - options: { activeFlowId: 'openai', plusModeEnabled: true, plusPaymentMethod: 'gpc-helper', plusAccountAccessStrategy: 'oauth', signupMethod: 'email', phoneSignupReloginAfterBindEmailEnabled: false, accountContributionEnabled: false }, + options: { activeFlowId: 'openai', plusModeEnabled: true, plusPaymentMethod: 'gpc-helper', plusAccountAccessStrategy: 'oauth', signupMethod: 'email', phoneVerificationEnabled: false, phoneSignupReloginAfterBindEmailEnabled: false, accountContributionEnabled: false }, }); }); diff --git a/tests/step-definitions-module.test.js b/tests/step-definitions-module.test.js index 805e636..93d6aad 100644 --- a/tests/step-definitions-module.test.js +++ b/tests/step-definitions-module.test.js @@ -433,6 +433,34 @@ test('Plus no-payment mode removes only payment chain nodes', () => { assert.deepStrictEqual(cpaNodes.find((node) => node.nodeId === 'wait-registration-success')?.next, ['cpa-session-import']); }); +test('OpenAI OAuth workflow removes post-login phone verification when phone verification is disabled', () => { + const globalScope = {}; + const api = new Function('self', `${readStepDefinitionsBundle()}; return self.MultiPageStepDefinitions;`)(globalScope); + + [ + { label: 'normal', options: { phoneVerificationEnabled: false } }, + { label: 'plus paypal', options: { plusModeEnabled: true, phoneVerificationEnabled: false } }, + { label: 'plus gopay', options: { plusModeEnabled: true, plusPaymentMethod: 'gopay', phoneVerificationEnabled: false } }, + { label: 'phone relogin', options: { signupMethod: 'phone', phoneSignupReloginAfterBindEmailEnabled: true, phoneVerificationEnabled: false } }, + ].forEach(({ label, options }) => { + const steps = api.getSteps(options); + const nodes = api.getNodes(options); + const keys = steps.map((step) => step.key); + const nodeIds = nodes.map((node) => node.nodeId); + const expectedNextAfterLoginCode = keys.includes('bind-email') ? 'bind-email' : 'confirm-oauth'; + + assert.equal(keys.includes('post-login-phone-verification'), false, `${label} should hide post-login phone step`); + assert.equal(keys.includes('post-bound-email-phone-verification'), false, `${label} should hide bound-email phone step`); + assert.equal(nodeIds.includes('post-login-phone-verification'), false, `${label} nodes should hide post-login phone step`); + assert.equal(nodeIds.includes('post-bound-email-phone-verification'), false, `${label} nodes should hide bound-email phone step`); + assert.deepStrictEqual( + nodes.find((node) => node.nodeId === 'fetch-login-code')?.next, + [expectedNextAfterLoginCode], + `${label} fetch-login-code should link to the next non-phone node` + ); + }); +}); + test('Plus session strategy swaps the OAuth tail for a single SUB2API import node', () => { const globalScope = {}; const api = new Function('self', `${readStepDefinitionsBundle()}; return self.MultiPageStepDefinitions;`)(globalScope);