Merge branch 'dev' of https://github.com/QLHazyCoder/codex-oauth-automation-extension into dev
This commit is contained in:
+52
-15
@@ -183,6 +183,10 @@ const DEFAULT_SUB2API_URL = 'https://sub2api.hisence.fun/admin/accounts';
|
|||||||
const DEFAULT_CODEX2API_URL = 'http://localhost:8080/admin/accounts';
|
const DEFAULT_CODEX2API_URL = 'http://localhost:8080/admin/accounts';
|
||||||
const DEFAULT_SUB2API_GROUP_NAME = 'codex';
|
const DEFAULT_SUB2API_GROUP_NAME = 'codex';
|
||||||
const DEFAULT_SUB2API_PROXY_NAME = '';
|
const DEFAULT_SUB2API_PROXY_NAME = '';
|
||||||
|
const CONTRIBUTION_SOURCE_CPA = 'cpa';
|
||||||
|
const CONTRIBUTION_SOURCE_SUB2API = 'sub2api';
|
||||||
|
const CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME = 'codex号池';
|
||||||
|
const CONTRIBUTION_SUB2API_PLUS_GROUP_NAME = 'openai-plus';
|
||||||
const DEFAULT_SUB2API_REDIRECT_URI = 'http://localhost:1455/auth/callback';
|
const DEFAULT_SUB2API_REDIRECT_URI = 'http://localhost:1455/auth/callback';
|
||||||
const AUTO_RUN_TIMER_ALARM_NAME = 'auto-run-timer';
|
const AUTO_RUN_TIMER_ALARM_NAME = 'auto-run-timer';
|
||||||
const AUTO_RUN_TIMER_KIND_SCHEDULED_START = 'scheduled_start';
|
const AUTO_RUN_TIMER_KIND_SCHEDULED_START = 'scheduled_start';
|
||||||
@@ -222,6 +226,8 @@ const ACCOUNT_RUN_HISTORY_STORAGE_KEY = 'accountRunHistory';
|
|||||||
const CONTRIBUTION_RUNTIME_DEFAULTS = self.MultiPageBackgroundContributionOAuth?.RUNTIME_DEFAULTS || {
|
const CONTRIBUTION_RUNTIME_DEFAULTS = self.MultiPageBackgroundContributionOAuth?.RUNTIME_DEFAULTS || {
|
||||||
contributionMode: false,
|
contributionMode: false,
|
||||||
contributionModeExpected: false,
|
contributionModeExpected: false,
|
||||||
|
contributionSource: CONTRIBUTION_SOURCE_SUB2API,
|
||||||
|
contributionTargetGroupName: CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME,
|
||||||
contributionNickname: '',
|
contributionNickname: '',
|
||||||
contributionQq: '',
|
contributionQq: '',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
@@ -243,6 +249,40 @@ function isPlusModeState(state = {}) {
|
|||||||
return Boolean(state?.plusModeEnabled);
|
return Boolean(state?.plusModeEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeContributionModeSource(value = '') {
|
||||||
|
const normalized = String(value || '').trim().toLowerCase();
|
||||||
|
return normalized === CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
? CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
: CONTRIBUTION_SOURCE_CPA;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveContributionModeRoutingState(state = {}) {
|
||||||
|
const currentStatus = String(state?.contributionStatus || '').trim().toLowerCase();
|
||||||
|
const currentSource = normalizeContributionModeSource(state?.contributionSource);
|
||||||
|
const hasActiveSession = Boolean(
|
||||||
|
String(state?.contributionSessionId || '').trim()
|
||||||
|
&& currentStatus
|
||||||
|
&& !['auto_approved', 'auto_rejected', 'expired', 'error'].includes(currentStatus)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasActiveSession) {
|
||||||
|
return {
|
||||||
|
source: currentSource,
|
||||||
|
targetGroupName: currentSource === CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
? (String(state?.contributionTargetGroupName || '').trim() || CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME)
|
||||||
|
: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = CONTRIBUTION_SOURCE_SUB2API;
|
||||||
|
return {
|
||||||
|
source,
|
||||||
|
targetGroupName: isPlusModeState(state)
|
||||||
|
? CONTRIBUTION_SUB2API_PLUS_GROUP_NAME
|
||||||
|
: (String(state?.contributionTargetGroupName || '').trim() || CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function getStepDefinitionsForState(state = {}) {
|
function getStepDefinitionsForState(state = {}) {
|
||||||
return isPlusModeState(state) ? PLUS_STEP_DEFINITIONS : NORMAL_STEP_DEFINITIONS;
|
return isPlusModeState(state) ? PLUS_STEP_DEFINITIONS : NORMAL_STEP_DEFINITIONS;
|
||||||
}
|
}
|
||||||
@@ -1343,11 +1383,18 @@ function buildContributionModeState(enabled, persistedSettings = {}, currentStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
const routing = resolveContributionModeRoutingState({
|
||||||
|
...persistedSettings,
|
||||||
|
...currentState,
|
||||||
|
...currentContributionState,
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
...currentContributionState,
|
...currentContributionState,
|
||||||
contributionMode: true,
|
contributionMode: true,
|
||||||
contributionModeExpected: true,
|
contributionModeExpected: true,
|
||||||
panelMode: 'cpa',
|
contributionSource: routing.source,
|
||||||
|
contributionTargetGroupName: routing.targetGroupName,
|
||||||
|
panelMode: routing.source,
|
||||||
customPassword: '',
|
customPassword: '',
|
||||||
accountRunHistoryTextEnabled: false,
|
accountRunHistoryTextEnabled: false,
|
||||||
};
|
};
|
||||||
@@ -1370,14 +1417,7 @@ async function setContributionMode(enabled) {
|
|||||||
getState(),
|
getState(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (normalizedEnabled) {
|
const updates = buildContributionModeState(normalizedEnabled, persistedSettings, currentState);
|
||||||
await setPersistentSettings({ panelMode: 'cpa' });
|
|
||||||
}
|
|
||||||
|
|
||||||
const updates = buildContributionModeState(normalizedEnabled, {
|
|
||||||
...persistedSettings,
|
|
||||||
...(normalizedEnabled ? { panelMode: 'cpa' } : {}),
|
|
||||||
}, currentState);
|
|
||||||
|
|
||||||
await setState(updates);
|
await setState(updates);
|
||||||
const nextState = await getState();
|
const nextState = await getState();
|
||||||
@@ -1550,10 +1590,7 @@ async function resetState() {
|
|||||||
getPersistedSettings(),
|
getPersistedSettings(),
|
||||||
getPersistedAliasState(),
|
getPersistedAliasState(),
|
||||||
]);
|
]);
|
||||||
const contributionModeState = buildContributionModeState(Boolean(prev.contributionMode), {
|
const contributionModeState = buildContributionModeState(Boolean(prev.contributionMode), persistedSettings, prev);
|
||||||
...persistedSettings,
|
|
||||||
...(prev.contributionMode ? { panelMode: 'cpa' } : {}),
|
|
||||||
}, prev);
|
|
||||||
await chrome.storage.session.clear();
|
await chrome.storage.session.clear();
|
||||||
await chrome.storage.session.set({
|
await chrome.storage.session.set({
|
||||||
...DEFAULT_STATE,
|
...DEFAULT_STATE,
|
||||||
@@ -8261,8 +8298,8 @@ async function executeContributionStep10(state) {
|
|||||||
while (Date.now() - startedAt < timeoutMs) {
|
while (Date.now() - startedAt < timeoutMs) {
|
||||||
const status = String(latestState.contributionStatus || '').trim().toLowerCase();
|
const status = String(latestState.contributionStatus || '').trim().toLowerCase();
|
||||||
if (contributionOAuthManager?.isContributionFinalStatus?.(status)) {
|
if (contributionOAuthManager?.isContributionFinalStatus?.(status)) {
|
||||||
if (status === 'auto_approved' || status === 'manual_review_required') {
|
if (status === 'auto_approved') {
|
||||||
await addLog(`步骤 10:贡献流程已结束,最终状态:${latestState.contributionStatusMessage || status}`, status === 'auto_approved' ? 'ok' : 'warn');
|
await addLog(`步骤 10:贡献流程已结束,最终状态:${latestState.contributionStatusMessage || status}`, 'ok');
|
||||||
await completeStepFromBackground(10, {
|
await completeStepFromBackground(10, {
|
||||||
contributionStatus: status,
|
contributionStatus: status,
|
||||||
contributionStatusMessage: latestState.contributionStatusMessage || '',
|
contributionStatusMessage: latestState.contributionStatusMessage || '',
|
||||||
|
|||||||
@@ -3,13 +3,19 @@
|
|||||||
})(typeof self !== 'undefined' ? self : globalThis, function createBackgroundContributionOAuthModule() {
|
})(typeof self !== 'undefined' ? self : globalThis, function createBackgroundContributionOAuthModule() {
|
||||||
const API_BASE_URL = 'https://apikey.qzz.io/oauth/api';
|
const API_BASE_URL = 'https://apikey.qzz.io/oauth/api';
|
||||||
const ACTIVE_STATUSES = new Set(['started', 'waiting', 'processing']);
|
const ACTIVE_STATUSES = new Set(['started', 'waiting', 'processing']);
|
||||||
const FINAL_STATUSES = new Set(['auto_approved', 'auto_rejected', 'manual_review_required', 'expired', 'error']);
|
const FINAL_STATUSES = new Set(['auto_approved', 'auto_rejected', 'expired', 'error']);
|
||||||
const CALLBACK_FINAL_STATUSES = new Set(['submitted']);
|
const CALLBACK_FINAL_STATUSES = new Set(['submitted']);
|
||||||
const CALLBACK_WAITING_STATUSES = new Set(['idle', 'waiting', 'captured', 'failed', 'submitting']);
|
const CALLBACK_WAITING_STATUSES = new Set(['idle', 'waiting', 'captured', 'failed', 'submitting']);
|
||||||
|
const CONTRIBUTION_SOURCE_CPA = 'cpa';
|
||||||
|
const CONTRIBUTION_SOURCE_SUB2API = 'sub2api';
|
||||||
|
const CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME = 'codex号池';
|
||||||
|
const CONTRIBUTION_SUB2API_PLUS_GROUP_NAME = 'openai-plus';
|
||||||
|
|
||||||
const RUNTIME_DEFAULTS = {
|
const RUNTIME_DEFAULTS = {
|
||||||
contributionMode: false,
|
contributionMode: false,
|
||||||
contributionModeExpected: false,
|
contributionModeExpected: false,
|
||||||
|
contributionSource: CONTRIBUTION_SOURCE_SUB2API,
|
||||||
|
contributionTargetGroupName: CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME,
|
||||||
contributionNickname: '',
|
contributionNickname: '',
|
||||||
contributionQq: '',
|
contributionQq: '',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
@@ -64,9 +70,6 @@
|
|||||||
case 'auto_rejected':
|
case 'auto_rejected':
|
||||||
case 'rejected':
|
case 'rejected':
|
||||||
return 'auto_rejected';
|
return 'auto_rejected';
|
||||||
case 'manual_review_required':
|
|
||||||
case 'manual_review':
|
|
||||||
return 'manual_review_required';
|
|
||||||
case 'expired':
|
case 'expired':
|
||||||
case 'timeout':
|
case 'timeout':
|
||||||
return 'expired';
|
return 'expired';
|
||||||
@@ -107,6 +110,40 @@
|
|||||||
return FINAL_STATUSES.has(normalizeContributionStatus(status));
|
return FINAL_STATUSES.has(normalizeContributionStatus(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeContributionSource(value = '') {
|
||||||
|
const normalized = normalizeString(value).toLowerCase();
|
||||||
|
return normalized === CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
? CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
: CONTRIBUTION_SOURCE_CPA;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveContributionRouting(state = {}) {
|
||||||
|
const currentStatus = normalizeContributionStatus(state.contributionStatus);
|
||||||
|
const currentSource = normalizeContributionSource(state.contributionSource);
|
||||||
|
const hasActiveSession = Boolean(
|
||||||
|
normalizeString(state.contributionSessionId)
|
||||||
|
&& currentStatus
|
||||||
|
&& !FINAL_STATUSES.has(currentStatus)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasActiveSession) {
|
||||||
|
return {
|
||||||
|
source: currentSource,
|
||||||
|
targetGroupName: currentSource === CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
? (normalizeString(state.contributionTargetGroupName) || CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME)
|
||||||
|
: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const source = CONTRIBUTION_SOURCE_SUB2API;
|
||||||
|
return {
|
||||||
|
source,
|
||||||
|
targetGroupName: Boolean(state.plusModeEnabled)
|
||||||
|
? CONTRIBUTION_SUB2API_PLUS_GROUP_NAME
|
||||||
|
: (normalizeString(state.contributionTargetGroupName) || CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function getStatusLabel(status = '') {
|
function getStatusLabel(status = '') {
|
||||||
switch (normalizeContributionStatus(status)) {
|
switch (normalizeContributionStatus(status)) {
|
||||||
case 'started':
|
case 'started':
|
||||||
@@ -114,13 +151,11 @@
|
|||||||
case 'waiting':
|
case 'waiting':
|
||||||
return '等待提交回调';
|
return '等待提交回调';
|
||||||
case 'processing':
|
case 'processing':
|
||||||
return '已提交回调,等待 CPA 确认';
|
return '已提交回调,等待服务端确认';
|
||||||
case 'auto_approved':
|
case 'auto_approved':
|
||||||
return '贡献成功,CPA 已确认';
|
return '贡献成功,服务端已确认';
|
||||||
case 'auto_rejected':
|
case 'auto_rejected':
|
||||||
return '贡献未通过确认';
|
return '贡献未通过确认';
|
||||||
case 'manual_review_required':
|
|
||||||
return '已提交,等待人工处理';
|
|
||||||
case 'expired':
|
case 'expired':
|
||||||
return '贡献会话已超时';
|
return '贡献会话已超时';
|
||||||
case 'error':
|
case 'error':
|
||||||
@@ -536,6 +571,16 @@
|
|||||||
const callbackState = deriveCallbackState(mergedPayload, currentState);
|
const callbackState = deriveCallbackState(mergedPayload, currentState);
|
||||||
const updates = {
|
const updates = {
|
||||||
contributionLastPollAt: Date.now(),
|
contributionLastPollAt: Date.now(),
|
||||||
|
contributionSource: normalizeContributionSource(
|
||||||
|
mergedPayload.source
|
||||||
|
|| mergedPayload.source_kind
|
||||||
|
|| currentState.contributionSource
|
||||||
|
),
|
||||||
|
contributionTargetGroupName: normalizeString(
|
||||||
|
mergedPayload.target_group_name
|
||||||
|
|| mergedPayload.group_name
|
||||||
|
|| currentState.contributionTargetGroupName
|
||||||
|
),
|
||||||
contributionStatus: normalizedStatus,
|
contributionStatus: normalizedStatus,
|
||||||
contributionStatusMessage: buildStatusMessage(normalizedStatus, mergedPayload),
|
contributionStatusMessage: buildStatusMessage(normalizedStatus, mergedPayload),
|
||||||
contributionCallbackUrl: callbackState.callbackUrl,
|
contributionCallbackUrl: callbackState.callbackUrl,
|
||||||
@@ -577,6 +622,7 @@
|
|||||||
async function startContributionFlow(options = {}) {
|
async function startContributionFlow(options = {}) {
|
||||||
const currentState = options.stateOverride || await getState();
|
const currentState = options.stateOverride || await getState();
|
||||||
const shouldOpenAuthTab = options.openAuthTab !== false;
|
const shouldOpenAuthTab = options.openAuthTab !== false;
|
||||||
|
const routing = resolveContributionRouting(currentState);
|
||||||
if (!currentState.contributionMode) {
|
if (!currentState.contributionMode) {
|
||||||
throw new Error('请先进入贡献模式。');
|
throw new Error('请先进入贡献模式。');
|
||||||
}
|
}
|
||||||
@@ -600,7 +646,8 @@
|
|||||||
nickname: buildNickname(currentState, options.nickname),
|
nickname: buildNickname(currentState, options.nickname),
|
||||||
qq: buildContributionQq(currentState, options.qq),
|
qq: buildContributionQq(currentState, options.qq),
|
||||||
email: normalizeString(currentState.email),
|
email: normalizeString(currentState.email),
|
||||||
source: 'cpa',
|
source: routing.source,
|
||||||
|
target_group_name: routing.targetGroupName,
|
||||||
channel: 'codex-extension',
|
channel: 'codex-extension',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -613,6 +660,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
await applyRuntimeUpdates({
|
await applyRuntimeUpdates({
|
||||||
|
contributionSource: normalizeContributionSource(payload.source || routing.source),
|
||||||
|
contributionTargetGroupName: normalizeString(
|
||||||
|
payload.target_group_name
|
||||||
|
|| payload.group_name
|
||||||
|
|| routing.targetGroupName
|
||||||
|
),
|
||||||
contributionSessionId: sessionId,
|
contributionSessionId: sessionId,
|
||||||
contributionAuthUrl: authUrl,
|
contributionAuthUrl: authUrl,
|
||||||
contributionAuthState: authState,
|
contributionAuthState: authState,
|
||||||
|
|||||||
@@ -644,6 +644,9 @@
|
|||||||
stateUpdates.currentStep = 0;
|
stateUpdates.currentStep = 0;
|
||||||
}
|
}
|
||||||
await setState(stateUpdates);
|
await setState(stateUpdates);
|
||||||
|
if (Boolean(currentState?.contributionMode) && typeof setContributionMode === 'function') {
|
||||||
|
await setContributionMode(true);
|
||||||
|
}
|
||||||
if (modeChanged) {
|
if (modeChanged) {
|
||||||
await addLog(
|
await addLog(
|
||||||
Boolean(updates.plusModeEnabled)
|
Boolean(updates.plusModeEnabled)
|
||||||
|
|||||||
@@ -510,9 +510,6 @@ async function step9_submitOpenAiCallback(payload = {}) {
|
|||||||
|
|
||||||
const sessionId = String(payload.sub2apiSessionId || backgroundState.sub2apiSessionId || '').trim();
|
const sessionId = String(payload.sub2apiSessionId || backgroundState.sub2apiSessionId || '').trim();
|
||||||
const expectedState = String(payload.sub2apiOAuthState || backgroundState.sub2apiOAuthState || '').trim();
|
const expectedState = String(payload.sub2apiOAuthState || backgroundState.sub2apiOAuthState || '').trim();
|
||||||
const accountName = flowEmail
|
|
||||||
|| String(payload.sub2apiDraftName || backgroundState.sub2apiDraftName || '').trim()
|
|
||||||
|| buildDraftAccountName(payload.sub2apiGroupName || backgroundState.sub2apiGroupName || SUB2API_DEFAULT_GROUP_NAME);
|
|
||||||
|
|
||||||
const { origin, token } = await loginSub2Api(payload);
|
const { origin, token } = await loginSub2Api(payload);
|
||||||
const proxyPreference = resolveSub2ApiProxyPreference(payload, backgroundState);
|
const proxyPreference = resolveSub2ApiProxyPreference(payload, backgroundState);
|
||||||
@@ -553,10 +550,15 @@ async function step9_submitOpenAiCallback(payload = {}) {
|
|||||||
|
|
||||||
const credentials = buildOpenAiCredentials(exchangeData);
|
const credentials = buildOpenAiCredentials(exchangeData);
|
||||||
const extra = buildOpenAiExtra(exchangeData);
|
const extra = buildOpenAiExtra(exchangeData);
|
||||||
|
const resolvedEmail = String(exchangeData?.email || credentials?.email || '').trim();
|
||||||
const groupId = Number(group.id);
|
const groupId = Number(group.id);
|
||||||
if (!Number.isFinite(groupId) || groupId <= 0) {
|
if (!Number.isFinite(groupId) || groupId <= 0) {
|
||||||
throw new Error('SUB2API 返回的目标分组 ID 无效。');
|
throw new Error('SUB2API 返回的目标分组 ID 无效。');
|
||||||
}
|
}
|
||||||
|
const accountName = resolvedEmail
|
||||||
|
|| flowEmail
|
||||||
|
|| String(payload.sub2apiDraftName || backgroundState.sub2apiDraftName || '').trim()
|
||||||
|
|| buildDraftAccountName(payload.sub2apiGroupName || backgroundState.sub2apiGroupName || SUB2API_DEFAULT_GROUP_NAME);
|
||||||
const createPayload = {
|
const createPayload = {
|
||||||
name: accountName,
|
name: accountName,
|
||||||
notes: '',
|
notes: '',
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
(function attachSidepanelContributionMode(globalScope) {
|
(function attachSidepanelContributionMode(globalScope) {
|
||||||
const ACTIVE_STATUSES = new Set(['started', 'waiting', 'processing']);
|
const ACTIVE_STATUSES = new Set(['started', 'waiting', 'processing']);
|
||||||
const FINAL_STATUSES = new Set(['auto_approved', 'auto_rejected', 'manual_review_required', 'expired', 'error']);
|
const FINAL_STATUSES = new Set(['auto_approved', 'auto_rejected', 'expired', 'error']);
|
||||||
const DEFAULT_COPY = '当前账号将用于支持项目维护。扩展会自动申请贡献登录地址并持续跟踪授权状态;如检测到回调地址,会自动提交,并继续等待 CPA 最终确认。';
|
const DEFAULT_COPY = '当前账号将用于支持项目维护。扩展会自动申请贡献登录地址并持续跟踪授权状态;如检测到回调地址,会自动提交,并继续等待服务端确认。';
|
||||||
|
const CONTRIBUTION_SOURCE_CPA = 'cpa';
|
||||||
|
const CONTRIBUTION_SOURCE_SUB2API = 'sub2api';
|
||||||
|
const CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME = 'codex号池';
|
||||||
|
|
||||||
function createContributionModeManager(context = {}) {
|
function createContributionModeManager(context = {}) {
|
||||||
const {
|
const {
|
||||||
@@ -66,6 +69,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeContributionSource(value = '') {
|
||||||
|
const normalized = normalizeString(value).toLowerCase();
|
||||||
|
return normalized === CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
? CONTRIBUTION_SOURCE_SUB2API
|
||||||
|
: CONTRIBUTION_SOURCE_CPA;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContributionSource(currentState = getLatestState()) {
|
||||||
|
return normalizeContributionSource(currentState.contributionSource || currentState.panelMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContributionSourceLabel(currentState = getLatestState()) {
|
||||||
|
return getContributionSource(currentState) === CONTRIBUTION_SOURCE_SUB2API ? 'SUB2API' : 'CPA';
|
||||||
|
}
|
||||||
|
|
||||||
function isContributionModeEnabled(currentState = getLatestState()) {
|
function isContributionModeEnabled(currentState = getLatestState()) {
|
||||||
return Boolean(currentState.contributionMode);
|
return Boolean(currentState.contributionMode);
|
||||||
}
|
}
|
||||||
@@ -140,7 +158,7 @@
|
|||||||
if (status === 'waiting') {
|
if (status === 'waiting') {
|
||||||
return '等待提交回调';
|
return '等待提交回调';
|
||||||
}
|
}
|
||||||
if (status === 'processing' || status === 'auto_approved' || status === 'auto_rejected' || status === 'manual_review_required') {
|
if (status === 'processing' || status === 'auto_approved' || status === 'auto_rejected') {
|
||||||
return status === 'processing' ? '已提交回调' : '授权已结束';
|
return status === 'processing' ? '已提交回调' : '授权已结束';
|
||||||
}
|
}
|
||||||
if (status === 'expired' || status === 'error') {
|
if (status === 'expired' || status === 'error') {
|
||||||
@@ -173,7 +191,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getSummaryText(currentState = getLatestState()) {
|
function getSummaryText(currentState = getLatestState()) {
|
||||||
return normalizeString(currentState.contributionStatusMessage) || DEFAULT_COPY;
|
const statusMessage = normalizeString(currentState.contributionStatusMessage);
|
||||||
|
if (statusMessage) {
|
||||||
|
return statusMessage;
|
||||||
|
}
|
||||||
|
if (getContributionSource(currentState) === CONTRIBUTION_SOURCE_SUB2API) {
|
||||||
|
const groupName = normalizeString(currentState.contributionTargetGroupName) || CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME;
|
||||||
|
return `当前账号将用于支持项目维护。贡献会通过 SUB2API 完成,并固定写入 ${groupName} 分组;如检测到回调地址,扩展会自动提交并等待服务端确认。`;
|
||||||
|
}
|
||||||
|
return DEFAULT_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContributionPortalPageUrl() {
|
function getContributionPortalPageUrl() {
|
||||||
@@ -310,9 +336,10 @@
|
|||||||
const enabled = isContributionModeEnabled(currentState);
|
const enabled = isContributionModeEnabled(currentState);
|
||||||
const blocked = isModeSwitchBlocked();
|
const blocked = isModeSwitchBlocked();
|
||||||
const activeElement = typeof document !== 'undefined' ? document.activeElement : null;
|
const activeElement = typeof document !== 'undefined' ? document.activeElement : null;
|
||||||
|
const sourceLabel = getContributionSourceLabel(currentState);
|
||||||
|
|
||||||
if (enabled && dom.selectPanelMode) {
|
if (enabled && dom.selectPanelMode) {
|
||||||
dom.selectPanelMode.value = 'cpa';
|
dom.selectPanelMode.value = getContributionSource(currentState);
|
||||||
}
|
}
|
||||||
|
|
||||||
helpers.updatePanelModeUI?.();
|
helpers.updatePanelModeUI?.();
|
||||||
@@ -322,7 +349,13 @@
|
|||||||
dom.contributionModePanel.hidden = !enabled;
|
dom.contributionModePanel.hidden = !enabled;
|
||||||
}
|
}
|
||||||
if (dom.contributionModeText) {
|
if (dom.contributionModeText) {
|
||||||
dom.contributionModeText.textContent = DEFAULT_COPY;
|
dom.contributionModeText.textContent = getSummaryText({
|
||||||
|
contributionSource: currentState.contributionSource,
|
||||||
|
contributionTargetGroupName: currentState.contributionTargetGroupName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (dom.contributionModeBadge) {
|
||||||
|
dom.contributionModeBadge.textContent = enabled ? sourceLabel : '';
|
||||||
}
|
}
|
||||||
if (dom.inputContributionNickname && activeElement !== dom.inputContributionNickname) {
|
if (dom.inputContributionNickname && activeElement !== dom.inputContributionNickname) {
|
||||||
const nextNickname = normalizeString(currentState.contributionNickname);
|
const nextNickname = normalizeString(currentState.contributionNickname);
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
<div id="contribution-mode-panel" class="contribution-mode-panel" hidden>
|
<div id="contribution-mode-panel" class="contribution-mode-panel" hidden>
|
||||||
<div class="contribution-mode-panel-header">
|
<div class="contribution-mode-panel-header">
|
||||||
<span class="section-label">贡献模式</span>
|
<span class="section-label">贡献模式</span>
|
||||||
<span class="contribution-mode-badge">CPA</span>
|
<span id="contribution-mode-badge" class="contribution-mode-badge">CPA</span>
|
||||||
</div>
|
</div>
|
||||||
<p id="contribution-mode-text" class="contribution-mode-text">
|
<p id="contribution-mode-text" class="contribution-mode-text">
|
||||||
当前账号将用于支持项目维护。扩展会自动申请贡献登录地址并持续跟踪授权状态;如检测到回调地址,会自动提交,无需手动复制。</p>
|
当前账号将用于支持项目维护。扩展会自动申请贡献登录地址并持续跟踪授权状态;如检测到回调地址,会自动提交,无需手动复制。</p>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const updateReleaseList = document.getElementById('update-release-list');
|
|||||||
const btnOpenRelease = document.getElementById('btn-open-release');
|
const btnOpenRelease = document.getElementById('btn-open-release');
|
||||||
const settingsCard = document.getElementById('settings-card');
|
const settingsCard = document.getElementById('settings-card');
|
||||||
const contributionModePanel = document.getElementById('contribution-mode-panel');
|
const contributionModePanel = document.getElementById('contribution-mode-panel');
|
||||||
|
const contributionModeBadge = document.getElementById('contribution-mode-badge');
|
||||||
const contributionModeText = document.getElementById('contribution-mode-text');
|
const contributionModeText = document.getElementById('contribution-mode-text');
|
||||||
const inputContributionNickname = document.getElementById('input-contribution-nickname');
|
const inputContributionNickname = document.getElementById('input-contribution-nickname');
|
||||||
const inputContributionQq = document.getElementById('input-contribution-qq');
|
const inputContributionQq = document.getElementById('input-contribution-qq');
|
||||||
@@ -1733,7 +1734,9 @@ function collectSettingsPayload() {
|
|||||||
label: typeof DEFAULT_HERO_SMS_COUNTRY_LABEL !== 'undefined' ? DEFAULT_HERO_SMS_COUNTRY_LABEL : 'Thailand',
|
label: typeof DEFAULT_HERO_SMS_COUNTRY_LABEL !== 'undefined' ? DEFAULT_HERO_SMS_COUNTRY_LABEL : 'Thailand',
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
|
...(contributionModeEnabled ? {} : {
|
||||||
panelMode: selectPanelMode.value,
|
panelMode: selectPanelMode.value,
|
||||||
|
}),
|
||||||
vpsUrl: inputVpsUrl.value.trim(),
|
vpsUrl: inputVpsUrl.value.trim(),
|
||||||
vpsPassword: inputVpsPassword.value,
|
vpsPassword: inputVpsPassword.value,
|
||||||
localCpaStep9Mode: getSelectedLocalCpaStep9Mode(),
|
localCpaStep9Mode: getSelectedLocalCpaStep9Mode(),
|
||||||
@@ -4070,6 +4073,7 @@ const contributionModeManager = window.SidepanelContributionMode?.createContribu
|
|||||||
btnOpenAccountRecords,
|
btnOpenAccountRecords,
|
||||||
btnOpenContributionUpload,
|
btnOpenContributionUpload,
|
||||||
btnStartContribution,
|
btnStartContribution,
|
||||||
|
contributionModeBadge,
|
||||||
contributionModePanel,
|
contributionModePanel,
|
||||||
contributionModeSummary,
|
contributionModeSummary,
|
||||||
contributionModeText,
|
contributionModeText,
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ test('contribution oauth module exposes a factory', () => {
|
|||||||
assert.equal(Array.isArray(api?.RUNTIME_KEYS), true);
|
assert.equal(Array.isArray(api?.RUNTIME_KEYS), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('buildContributionModeState preserves active contribution runtime while forcing CPA mode', () => {
|
test('buildContributionModeState preserves active contribution runtime while keeping contribution on sub2api', () => {
|
||||||
const bundle = extractFunction(backgroundSource, 'buildContributionModeState');
|
const bundle = extractFunction(backgroundSource, 'buildContributionModeState');
|
||||||
|
|
||||||
const api = new Function(`
|
const api = new Function(`
|
||||||
@@ -92,6 +92,8 @@ const DEFAULT_STATE = { panelMode: 'cpa' };
|
|||||||
const CONTRIBUTION_RUNTIME_DEFAULTS = {
|
const CONTRIBUTION_RUNTIME_DEFAULTS = {
|
||||||
contributionMode: false,
|
contributionMode: false,
|
||||||
contributionModeExpected: false,
|
contributionModeExpected: false,
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'codex号池',
|
||||||
contributionNickname: '',
|
contributionNickname: '',
|
||||||
contributionQq: '',
|
contributionQq: '',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
@@ -107,6 +109,35 @@ const CONTRIBUTION_RUNTIME_DEFAULTS = {
|
|||||||
contributionAuthTabId: 0,
|
contributionAuthTabId: 0,
|
||||||
};
|
};
|
||||||
const CONTRIBUTION_RUNTIME_KEYS = Object.keys(CONTRIBUTION_RUNTIME_DEFAULTS);
|
const CONTRIBUTION_RUNTIME_KEYS = Object.keys(CONTRIBUTION_RUNTIME_DEFAULTS);
|
||||||
|
function isPlusModeState(state = {}) { return Boolean(state?.plusModeEnabled); }
|
||||||
|
function normalizeContributionModeSource(value = '') {
|
||||||
|
const normalized = String(value || '').trim().toLowerCase();
|
||||||
|
return normalized === 'sub2api' ? 'sub2api' : 'cpa';
|
||||||
|
}
|
||||||
|
function resolveContributionModeRoutingState(state = {}) {
|
||||||
|
const currentStatus = String(state?.contributionStatus || '').trim().toLowerCase();
|
||||||
|
const currentSource = normalizeContributionModeSource(state?.contributionSource);
|
||||||
|
const hasActiveSession = Boolean(
|
||||||
|
String(state?.contributionSessionId || '').trim()
|
||||||
|
&& currentStatus
|
||||||
|
&& !['auto_approved', 'auto_rejected', 'expired', 'error'].includes(currentStatus)
|
||||||
|
);
|
||||||
|
if (hasActiveSession) {
|
||||||
|
return {
|
||||||
|
source: currentSource,
|
||||||
|
targetGroupName: currentSource === 'sub2api'
|
||||||
|
? (String(state?.contributionTargetGroupName || '').trim() || 'codex号池')
|
||||||
|
: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const source = 'sub2api';
|
||||||
|
return {
|
||||||
|
source,
|
||||||
|
targetGroupName: isPlusModeState(state)
|
||||||
|
? 'openai-plus'
|
||||||
|
: (String(state?.contributionTargetGroupName || '').trim() || 'codex号池'),
|
||||||
|
};
|
||||||
|
}
|
||||||
${bundle}
|
${bundle}
|
||||||
return { buildContributionModeState };
|
return { buildContributionModeState };
|
||||||
`)();
|
`)();
|
||||||
@@ -125,6 +156,8 @@ return { buildContributionModeState };
|
|||||||
{
|
{
|
||||||
contributionMode: true,
|
contributionMode: true,
|
||||||
contributionModeExpected: true,
|
contributionModeExpected: true,
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'codex号池',
|
||||||
contributionNickname: '',
|
contributionNickname: '',
|
||||||
contributionQq: '',
|
contributionQq: '',
|
||||||
contributionSessionId: 'session-001',
|
contributionSessionId: 'session-001',
|
||||||
@@ -138,7 +171,7 @@ return { buildContributionModeState };
|
|||||||
contributionCallbackMessage: '',
|
contributionCallbackMessage: '',
|
||||||
contributionAuthOpenedAt: 0,
|
contributionAuthOpenedAt: 0,
|
||||||
contributionAuthTabId: 0,
|
contributionAuthTabId: 0,
|
||||||
panelMode: 'cpa',
|
panelMode: 'sub2api',
|
||||||
customPassword: '',
|
customPassword: '',
|
||||||
accountRunHistoryTextEnabled: false,
|
accountRunHistoryTextEnabled: false,
|
||||||
}
|
}
|
||||||
@@ -157,6 +190,8 @@ return { buildContributionModeState };
|
|||||||
{
|
{
|
||||||
contributionMode: false,
|
contributionMode: false,
|
||||||
contributionModeExpected: false,
|
contributionModeExpected: false,
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'codex号池',
|
||||||
contributionNickname: '',
|
contributionNickname: '',
|
||||||
contributionQq: '',
|
contributionQq: '',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
@@ -175,6 +210,37 @@ return { buildContributionModeState };
|
|||||||
accountRunHistoryTextEnabled: true,
|
accountRunHistoryTextEnabled: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
api.buildContributionModeState(true, {
|
||||||
|
panelMode: 'cpa',
|
||||||
|
plusModeEnabled: true,
|
||||||
|
customPassword: 'Secret123!',
|
||||||
|
accountRunHistoryTextEnabled: true,
|
||||||
|
}, {}),
|
||||||
|
{
|
||||||
|
contributionMode: true,
|
||||||
|
contributionModeExpected: true,
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'openai-plus',
|
||||||
|
contributionNickname: '',
|
||||||
|
contributionQq: '',
|
||||||
|
contributionSessionId: '',
|
||||||
|
contributionAuthUrl: '',
|
||||||
|
contributionAuthState: '',
|
||||||
|
contributionCallbackUrl: '',
|
||||||
|
contributionStatus: '',
|
||||||
|
contributionStatusMessage: '',
|
||||||
|
contributionLastPollAt: 0,
|
||||||
|
contributionCallbackStatus: 'idle',
|
||||||
|
contributionCallbackMessage: '',
|
||||||
|
contributionAuthOpenedAt: 0,
|
||||||
|
contributionAuthTabId: 0,
|
||||||
|
panelMode: 'sub2api',
|
||||||
|
customPassword: '',
|
||||||
|
accountRunHistoryTextEnabled: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('resetState preserves contribution runtime across reset', () => {
|
test('resetState preserves contribution runtime across reset', () => {
|
||||||
@@ -334,6 +400,8 @@ test('contribution oauth manager starts session, opens auth url, submits callbac
|
|||||||
let statusPollCount = 0;
|
let statusPollCount = 0;
|
||||||
let currentState = {
|
let currentState = {
|
||||||
contributionMode: true,
|
contributionMode: true,
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'codex号池',
|
||||||
email: 'user@example.com',
|
email: 'user@example.com',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
contributionStatus: '',
|
contributionStatus: '',
|
||||||
@@ -424,6 +492,8 @@ test('contribution oauth manager starts session, opens auth url, submits callbac
|
|||||||
assert.match(String(fetchCalls[0].options.body || ''), /"nickname":""/);
|
assert.match(String(fetchCalls[0].options.body || ''), /"nickname":""/);
|
||||||
assert.match(String(fetchCalls[0].options.body || ''), /"qq":""/);
|
assert.match(String(fetchCalls[0].options.body || ''), /"qq":""/);
|
||||||
assert.match(String(fetchCalls[0].options.body || ''), /"email":"user@example\.com"/);
|
assert.match(String(fetchCalls[0].options.body || ''), /"email":"user@example\.com"/);
|
||||||
|
assert.match(String(fetchCalls[0].options.body || ''), /"source":"sub2api"/);
|
||||||
|
assert.match(String(fetchCalls[0].options.body || ''), /"target_group_name":"codex号池"/);
|
||||||
assert.match(fetchCalls[1].url, /\/status\?/);
|
assert.match(fetchCalls[1].url, /\/status\?/);
|
||||||
|
|
||||||
const callbackState = await manager.handleCapturedCallback(
|
const callbackState = await manager.handleCapturedCallback(
|
||||||
@@ -471,6 +541,78 @@ test('contribution oauth manager accepts localhost callback urls that contain er
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('contribution oauth manager switches Plus contribution traffic to sub2api openai-plus', async () => {
|
||||||
|
const source = fs.readFileSync('background/contribution-oauth.js', 'utf8');
|
||||||
|
const globalScope = {};
|
||||||
|
const fetchCalls = [];
|
||||||
|
let currentState = {
|
||||||
|
contributionMode: true,
|
||||||
|
plusModeEnabled: true,
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'openai-plus',
|
||||||
|
contributionSessionId: '',
|
||||||
|
contributionStatus: '',
|
||||||
|
contributionCallbackStatus: 'idle',
|
||||||
|
};
|
||||||
|
|
||||||
|
const api = new Function('self', 'fetch', `${source}; return self.MultiPageBackgroundContributionOAuth;`)(
|
||||||
|
globalScope,
|
||||||
|
async (url, options = {}) => {
|
||||||
|
fetchCalls.push({ url, options });
|
||||||
|
if (String(url).endsWith('/start')) {
|
||||||
|
return createMockResponse(true, 200, {
|
||||||
|
ok: true,
|
||||||
|
session_id: 'session-plus-001',
|
||||||
|
state: 'oauth-state-plus-001',
|
||||||
|
source: 'sub2api',
|
||||||
|
target_group_name: 'openai-plus',
|
||||||
|
auth_url: 'https://auth.example.com/oauth?state=oauth-state-plus-001',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (String(url).includes('/status?')) {
|
||||||
|
return createMockResponse(true, 200, {
|
||||||
|
ok: true,
|
||||||
|
session_id: 'session-plus-001',
|
||||||
|
status: 'waiting',
|
||||||
|
source: 'sub2api',
|
||||||
|
target_group_name: 'openai-plus',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return createMockResponse(true, 200, { ok: true });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const manager = api.createContributionOAuthManager({
|
||||||
|
chrome: {
|
||||||
|
tabs: {
|
||||||
|
async create(payload) {
|
||||||
|
return { id: 91, url: payload.url };
|
||||||
|
},
|
||||||
|
async update() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
onUpdated: { addListener() {} },
|
||||||
|
},
|
||||||
|
webNavigation: {
|
||||||
|
onCommitted: { addListener() {} },
|
||||||
|
onHistoryStateUpdated: { addListener() {} },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getState: async () => currentState,
|
||||||
|
setState: async (updates) => {
|
||||||
|
currentState = { ...currentState, ...updates };
|
||||||
|
},
|
||||||
|
broadcastDataUpdate: (updates) => {
|
||||||
|
currentState = { ...currentState, ...updates };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await manager.startContributionFlow();
|
||||||
|
|
||||||
|
assert.match(String(fetchCalls[0].options.body || ''), /"source":"sub2api"/);
|
||||||
|
assert.match(String(fetchCalls[0].options.body || ''), /"target_group_name":"openai-plus"/);
|
||||||
|
});
|
||||||
|
|
||||||
test('refreshOAuthUrlBeforeStep6 uses contribution oauth session instead of panel bridge in contribution mode', async () => {
|
test('refreshOAuthUrlBeforeStep6 uses contribution oauth session instead of panel bridge in contribution mode', async () => {
|
||||||
const bundle = extractFunction(backgroundSource, 'refreshOAuthUrlBeforeStep6');
|
const bundle = extractFunction(backgroundSource, 'refreshOAuthUrlBeforeStep6');
|
||||||
const calls = [];
|
const calls = [];
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ return {
|
|||||||
`)();
|
`)();
|
||||||
|
|
||||||
const contributionPayload = api.collectSettingsPayload();
|
const contributionPayload = api.collectSettingsPayload();
|
||||||
|
assert.equal('panelMode' in contributionPayload, false);
|
||||||
assert.equal('customPassword' in contributionPayload, false);
|
assert.equal('customPassword' in contributionPayload, false);
|
||||||
assert.equal('accountRunHistoryTextEnabled' in contributionPayload, false);
|
assert.equal('accountRunHistoryTextEnabled' in contributionPayload, false);
|
||||||
assert.equal('accountRunHistoryHelperBaseUrl' in contributionPayload, false);
|
assert.equal('accountRunHistoryHelperBaseUrl' in contributionPayload, false);
|
||||||
@@ -199,6 +200,7 @@ return {
|
|||||||
|
|
||||||
api.setLatestState({ contributionMode: false });
|
api.setLatestState({ contributionMode: false });
|
||||||
const normalPayload = api.collectSettingsPayload();
|
const normalPayload = api.collectSettingsPayload();
|
||||||
|
assert.equal(normalPayload.panelMode, 'cpa');
|
||||||
assert.equal(normalPayload.customPassword, 'Secret123!');
|
assert.equal(normalPayload.customPassword, 'Secret123!');
|
||||||
assert.equal(normalPayload.accountRunHistoryTextEnabled, true);
|
assert.equal(normalPayload.accountRunHistoryTextEnabled, true);
|
||||||
assert.equal(normalPayload.accountRunHistoryHelperBaseUrl, 'http://127.0.0.1:17373');
|
assert.equal(normalPayload.accountRunHistoryHelperBaseUrl, 'http://127.0.0.1:17373');
|
||||||
@@ -231,6 +233,8 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
let latestState = {
|
let latestState = {
|
||||||
contributionMode: false,
|
contributionMode: false,
|
||||||
panelMode: 'sub2api',
|
panelMode: 'sub2api',
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'codex号池',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
contributionStatus: '',
|
contributionStatus: '',
|
||||||
contributionStatusMessage: '',
|
contributionStatusMessage: '',
|
||||||
@@ -258,6 +262,7 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
btnOpenAccountRecords: createElement(),
|
btnOpenAccountRecords: createElement(),
|
||||||
btnOpenContributionUpload: createElement(),
|
btnOpenContributionUpload: createElement(),
|
||||||
btnStartContribution: createElement(),
|
btnStartContribution: createElement(),
|
||||||
|
contributionModeBadge: createElement(),
|
||||||
inputContributionNickname: createElement({ value: '贡献者昵称' }),
|
inputContributionNickname: createElement({ value: '贡献者昵称' }),
|
||||||
inputContributionQq: createElement({ value: '123456' }),
|
inputContributionQq: createElement({ value: '123456' }),
|
||||||
contributionCallbackStatus: createElement(),
|
contributionCallbackStatus: createElement(),
|
||||||
@@ -353,7 +358,9 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
state: message.payload.enabled
|
state: message.payload.enabled
|
||||||
? {
|
? {
|
||||||
contributionMode: true,
|
contributionMode: true,
|
||||||
panelMode: 'cpa',
|
panelMode: 'sub2api',
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'codex号池',
|
||||||
contributionNickname: '',
|
contributionNickname: '',
|
||||||
contributionQq: '',
|
contributionQq: '',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
@@ -368,6 +375,8 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
: {
|
: {
|
||||||
contributionMode: false,
|
contributionMode: false,
|
||||||
panelMode: 'cpa',
|
panelMode: 'cpa',
|
||||||
|
contributionSource: 'cpa',
|
||||||
|
contributionTargetGroupName: '',
|
||||||
contributionNickname: '',
|
contributionNickname: '',
|
||||||
contributionQq: '',
|
contributionQq: '',
|
||||||
contributionSessionId: '',
|
contributionSessionId: '',
|
||||||
@@ -387,7 +396,7 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
state: {
|
state: {
|
||||||
...latestState,
|
...latestState,
|
||||||
contributionStatus: 'processing',
|
contributionStatus: 'processing',
|
||||||
contributionStatusMessage: '已提交回调,等待 CPA 确认',
|
contributionStatusMessage: '已提交回调,等待服务端确认',
|
||||||
contributionCallbackStatus: 'submitted',
|
contributionCallbackStatus: 'submitted',
|
||||||
contributionCallbackMessage: '已提交回调',
|
contributionCallbackMessage: '已提交回调',
|
||||||
},
|
},
|
||||||
@@ -414,13 +423,15 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
manager.render();
|
manager.render();
|
||||||
assert.equal(dom.contributionModePanel.hidden, true);
|
assert.equal(dom.contributionModePanel.hidden, true);
|
||||||
assert.equal(dom.btnContributionMode.disabled, false);
|
assert.equal(dom.btnContributionMode.disabled, false);
|
||||||
|
assert.equal(dom.contributionModeBadge.textContent, '');
|
||||||
|
|
||||||
manager.bindEvents();
|
manager.bindEvents();
|
||||||
await dom.btnContributionMode.listeners.click();
|
await dom.btnContributionMode.listeners.click();
|
||||||
|
|
||||||
assert.equal(dom.contributionModePanel.hidden, false);
|
assert.equal(dom.contributionModePanel.hidden, false);
|
||||||
assert.equal(dom.selectPanelMode.value, 'cpa');
|
assert.equal(dom.selectPanelMode.value, 'sub2api');
|
||||||
assert.equal(dom.selectPanelMode.disabled, true);
|
assert.equal(dom.selectPanelMode.disabled, true);
|
||||||
|
assert.equal(dom.contributionModeBadge.textContent, 'SUB2API');
|
||||||
assert.equal(dom.btnOpenAccountRecords.disabled, true);
|
assert.equal(dom.btnOpenAccountRecords.disabled, true);
|
||||||
assert.equal(dom.contributionOauthStatus.textContent, '\u672a\u751f\u6210\u767b\u5f55\u5730\u5740');
|
assert.equal(dom.contributionOauthStatus.textContent, '\u672a\u751f\u6210\u767b\u5f55\u5730\u5740');
|
||||||
assert.equal(dom.contributionCallbackStatus.textContent, '\u7b49\u5f85\u56de\u8c03');
|
assert.equal(dom.contributionCallbackStatus.textContent, '\u7b49\u5f85\u56de\u8c03');
|
||||||
@@ -453,7 +464,7 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
assert.equal(statusState.contributionStatus, 'processing');
|
assert.equal(statusState.contributionStatus, 'processing');
|
||||||
assert.equal(dom.contributionOauthStatus.textContent, '\u5df2\u63d0\u4ea4\u56de\u8c03');
|
assert.equal(dom.contributionOauthStatus.textContent, '\u5df2\u63d0\u4ea4\u56de\u8c03');
|
||||||
assert.equal(dom.contributionCallbackStatus.textContent, '\u5df2\u63d0\u4ea4\u56de\u8c03');
|
assert.equal(dom.contributionCallbackStatus.textContent, '\u5df2\u63d0\u4ea4\u56de\u8c03');
|
||||||
assert.equal(dom.contributionModeSummary.textContent, '\u5df2\u63d0\u4ea4\u56de\u8c03\uff0c\u7b49\u5f85 CPA \u786e\u8ba4');
|
assert.equal(dom.contributionModeSummary.textContent, '\u5df2\u63d0\u4ea4\u56de\u8c03\uff0c\u7b49\u5f85\u670d\u52a1\u7aef\u786e\u8ba4');
|
||||||
|
|
||||||
dom.btnOpenContributionUpload.listeners.click();
|
dom.btnOpenContributionUpload.listeners.click();
|
||||||
assert.deepStrictEqual(openedUrls, ['https://apikey.qzz.io', 'https://apikey.qzz.io/upload']);
|
assert.deepStrictEqual(openedUrls, ['https://apikey.qzz.io', 'https://apikey.qzz.io/upload']);
|
||||||
@@ -476,7 +487,9 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
blocked = true;
|
blocked = true;
|
||||||
latestState = {
|
latestState = {
|
||||||
contributionMode: true,
|
contributionMode: true,
|
||||||
panelMode: 'cpa',
|
panelMode: 'sub2api',
|
||||||
|
contributionSource: 'sub2api',
|
||||||
|
contributionTargetGroupName: 'codex号池',
|
||||||
contributionNickname: '贡献者昵称',
|
contributionNickname: '贡献者昵称',
|
||||||
contributionQq: '123456',
|
contributionQq: '123456',
|
||||||
contributionSessionId: 'session-002',
|
contributionSessionId: 'session-002',
|
||||||
@@ -487,6 +500,8 @@ test('contribution mode manager enters mode, starts main auto flow, polls contri
|
|||||||
contributionCallbackMessage: '\u7b49\u5f85\u56de\u8c03',
|
contributionCallbackMessage: '\u7b49\u5f85\u56de\u8c03',
|
||||||
};
|
};
|
||||||
manager.render();
|
manager.render();
|
||||||
|
assert.equal(dom.selectPanelMode.value, 'sub2api');
|
||||||
|
assert.equal(dom.contributionModeBadge.textContent, 'SUB2API');
|
||||||
assert.equal(dom.btnExitContributionMode.disabled, true);
|
assert.equal(dom.btnExitContributionMode.disabled, true);
|
||||||
manager.stopPolling();
|
manager.stopPolling();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user