Make SUB2API proxy defaults available across panel flows

Expose a configurable default proxy for SUB2API, resolve the proxy once,
persist the proxy_id in state, and reuse it across auth URL generation,
code exchange, and account creation so one OAuth flow stays on one proxy.

Constraint: Upstream GitHub permission is READ, so publication must use a fork PR
Rejected: Push to origin | current GitHub viewer permission does not allow upstream branch publication
Rejected: Resolve proxy independently in later steps | could drift from the proxy chosen at auth URL generation
Confidence: high
Scope-risk: moderate
Reversibility: clean
Tested: npm test passed 183/183
Not-tested: Manual browser extension flow against a live SUB2API deployment
This commit is contained in:
lizhelang
2026-04-18 06:47:24 +08:00
parent 033e76a16f
commit 81613b865a
12 changed files with 387 additions and 1 deletions
+5
View File
@@ -140,6 +140,11 @@
<span class="data-label">分组</span>
<input type="text" id="input-sub2api-group" class="data-input" placeholder="默认 codex" />
</div>
<div class="data-row" id="row-sub2api-default-proxy" style="display:none;">
<span class="data-label">默认代理</span>
<input type="text" id="input-sub2api-default-proxy" class="data-input"
placeholder="shadowrocket 或代理 ID" />
</div>
<div class="data-row">
<span class="data-label">账户密码</span>
<div class="input-with-icon">
+15
View File
@@ -74,6 +74,8 @@ const rowSub2ApiPassword = document.getElementById('row-sub2api-password');
const inputSub2ApiPassword = document.getElementById('input-sub2api-password');
const rowSub2ApiGroup = document.getElementById('row-sub2api-group');
const inputSub2ApiGroup = document.getElementById('input-sub2api-group');
const rowSub2ApiDefaultProxy = document.getElementById('row-sub2api-default-proxy');
const inputSub2ApiDefaultProxy = document.getElementById('input-sub2api-default-proxy');
const selectMailProvider = document.getElementById('select-mail-provider');
const btnMailLogin = document.getElementById('btn-mail-login');
const rowMail2925Mode = document.getElementById('row-mail-2925-mode');
@@ -202,6 +204,8 @@ const VERIFICATION_RESEND_COUNT_MIN = 0;
const VERIFICATION_RESEND_COUNT_MAX = 20;
const DEFAULT_VERIFICATION_RESEND_COUNT = 4;
const DEFAULT_LOCAL_CPA_STEP9_MODE = 'submit';
const DEFAULT_CPA_CALLBACK_MODE = 'step8';
const DEFAULT_SUB2API_PROXY_NAME = 'shadowrocket';
const MAIL_2925_MODE_PROVIDE = 'provide';
const MAIL_2925_MODE_RECEIVE = 'receive';
const DEFAULT_MAIL_2925_MODE = MAIL_2925_MODE_PROVIDE;
@@ -1306,6 +1310,7 @@ function collectSettingsPayload() {
sub2apiEmail: inputSub2ApiEmail.value.trim(),
sub2apiPassword: inputSub2ApiPassword.value,
sub2apiGroupName: inputSub2ApiGroup.value.trim(),
sub2apiDefaultProxyName: inputSub2ApiDefaultProxy.value.trim() || DEFAULT_SUB2API_PROXY_NAME,
customPassword: inputPassword.value,
mailProvider: selectMailProvider.value,
mail2925Mode: getSelectedMail2925Mode(),
@@ -1676,6 +1681,7 @@ function applySettingsState(state) {
inputSub2ApiEmail.value = state?.sub2apiEmail || '';
inputSub2ApiPassword.value = state?.sub2apiPassword || '';
inputSub2ApiGroup.value = state?.sub2apiGroupName || '';
inputSub2ApiDefaultProxy.value = state?.sub2apiDefaultProxyName || DEFAULT_SUB2API_PROXY_NAME;
const restoredMailProvider = isCustomMailProvider(state?.mailProvider)
|| [ICLOUD_PROVIDER, 'hotmail-api', GMAIL_PROVIDER, 'luckmail-api', '163', '163-vip', 'qq', 'inbucket', '2925', 'cloudflare-temp-email'].includes(String(state?.mailProvider || '').trim())
? String(state?.mailProvider || '163').trim()
@@ -2470,6 +2476,7 @@ function updatePanelModeUI() {
rowSub2ApiEmail.style.display = useSub2Api ? '' : 'none';
rowSub2ApiPassword.style.display = useSub2Api ? '' : 'none';
rowSub2ApiGroup.style.display = useSub2Api ? '' : 'none';
rowSub2ApiDefaultProxy.style.display = useSub2Api ? '' : 'none';
const step9Btn = document.querySelector('.step-btn[data-step-key="platform-verify"]');
if (step9Btn) {
@@ -3701,6 +3708,14 @@ inputSub2ApiGroup.addEventListener('blur', () => {
saveSettings({ silent: true }).catch(() => { });
});
inputSub2ApiDefaultProxy.addEventListener('input', () => {
markSettingsDirty(true);
scheduleSettingsAutoSave();
});
inputSub2ApiDefaultProxy.addEventListener('blur', () => {
saveSettings({ silent: true }).catch(() => { });
});
inputEmailPrefix.addEventListener('input', () => {
maybeClearGeneratedAliasAfterEmailPrefixChange().catch(() => { });
syncManagedAliasBaseEmailDraftFromInput();