feat: upgrade multi-flow account contributions
This commit is contained in:
@@ -431,7 +431,7 @@
|
||||
source,
|
||||
autoRunContext: source === 'auto' ? autoRunContext : null,
|
||||
plusModeEnabled: Boolean(record.plusModeEnabled),
|
||||
contributionMode: Boolean(record.contributionMode),
|
||||
accountContributionEnabled: Boolean(record.accountContributionEnabled),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -526,7 +526,7 @@
|
||||
source,
|
||||
autoRunContext,
|
||||
plusModeEnabled: Boolean(state.plusModeEnabled),
|
||||
contributionMode: Boolean(state.contributionMode),
|
||||
accountContributionEnabled: Boolean(state.accountContributionEnabled),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -637,7 +637,7 @@
|
||||
}
|
||||
|
||||
function shouldSyncAccountRunHistorySnapshot(state = {}) {
|
||||
if (Boolean(state.contributionMode)) {
|
||||
if (Boolean(state.accountContributionEnabled)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
const CALLBACK_WAITING_STATUSES = new Set(['idle', 'waiting', 'captured', 'failed', 'submitting']);
|
||||
|
||||
const RUNTIME_DEFAULTS = {
|
||||
contributionMode: false,
|
||||
contributionModeExpected: false,
|
||||
accountContributionEnabled: false,
|
||||
accountContributionExpected: false,
|
||||
contributionAdapterId: '',
|
||||
flowContributionRuntime: {},
|
||||
contributionSource: 'sub2api',
|
||||
contributionTargetGroupName: 'codex号池',
|
||||
contributionNickname: '',
|
||||
@@ -265,14 +267,14 @@
|
||||
return Boolean(state?.plusModeEnabled);
|
||||
}
|
||||
|
||||
function normalizeContributionModeSource(value = '') {
|
||||
function normalizeOpenAiContributionSource(value = '') {
|
||||
const normalized = normalizeString(value).toLowerCase();
|
||||
return normalized === 'sub2api' ? 'sub2api' : 'cpa';
|
||||
}
|
||||
|
||||
function resolveContributionModeRoutingState(state = {}) {
|
||||
function resolveOpenAiContributionRoutingState(state = {}) {
|
||||
const currentStatus = normalizeString(state?.contributionStatus).toLowerCase();
|
||||
const currentSource = normalizeContributionModeSource(state?.contributionSource);
|
||||
const currentSource = normalizeOpenAiContributionSource(state?.contributionSource);
|
||||
const hasActiveSession = Boolean(
|
||||
normalizeString(state?.contributionSessionId)
|
||||
&& currentStatus
|
||||
@@ -533,7 +535,7 @@
|
||||
|
||||
async function handleCapturedCallback(rawUrl, metadata = {}) {
|
||||
const currentState = await getState();
|
||||
if (!normalizeString(currentState.contributionSessionId) || !currentState.contributionMode) {
|
||||
if (!normalizeString(currentState.contributionSessionId) || !currentState.accountContributionEnabled) {
|
||||
return currentState;
|
||||
}
|
||||
if (!isContributionCallbackUrl(rawUrl, currentState)) {
|
||||
@@ -642,10 +644,10 @@
|
||||
return nextState;
|
||||
}
|
||||
|
||||
async function startContributionFlow(options = {}) {
|
||||
async function startFlowContribution(options = {}) {
|
||||
const currentState = options.stateOverride || await getState();
|
||||
const shouldOpenAuthTab = options.openAuthTab !== false;
|
||||
if (!currentState.contributionMode) {
|
||||
if (!currentState.accountContributionEnabled) {
|
||||
throw new Error('请先进入贡献模式。');
|
||||
}
|
||||
|
||||
@@ -662,7 +664,7 @@
|
||||
return pollContributionStatus({ reason: 'resume_existing' });
|
||||
}
|
||||
|
||||
const routingState = resolveContributionModeRoutingState(currentState);
|
||||
const routingState = resolveOpenAiContributionRoutingState(currentState);
|
||||
const payload = await fetchContributionJson('/start', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
@@ -744,7 +746,7 @@
|
||||
isContributionCallbackUrl,
|
||||
isContributionFinalStatus,
|
||||
pollContributionStatus,
|
||||
startContributionFlow,
|
||||
startFlowContribution,
|
||||
submitContributionCallback,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
(function attachBackgroundKiroBuilderIdContributionAdapter(root, factory) {
|
||||
root.MultiPageBackgroundKiroBuilderIdContributionAdapter = factory(root);
|
||||
})(typeof self !== 'undefined' ? self : globalThis, function createBackgroundKiroBuilderIdContributionAdapterModule(root) {
|
||||
const artifactApi = root?.MultiPageBackgroundKiroCredentialArtifact || {};
|
||||
const FLOW_ID = artifactApi.FLOW_ID || 'kiro';
|
||||
const ADAPTER_ID = artifactApi.ADAPTER_ID || 'kiro-builder-id';
|
||||
const ARTIFACT_KIND = artifactApi.ARTIFACT_KIND || 'kiro-builder-id';
|
||||
const DEFAULT_CONTRIBUTION_API_URL = 'https://flowpilot.qlhazycoder.top/api/contributions';
|
||||
|
||||
function isPlainObject(value) {
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
||||
}
|
||||
|
||||
function cleanString(value = '') {
|
||||
return String(value ?? '').trim();
|
||||
}
|
||||
|
||||
function getErrorMessage(error) {
|
||||
return error instanceof Error ? error.message : String(error ?? '未知错误');
|
||||
}
|
||||
|
||||
function normalizeFlowId(state = {}) {
|
||||
return cleanString(state.activeFlowId || state.flowId).toLowerCase() || 'openai';
|
||||
}
|
||||
|
||||
function normalizeAdapterId(state = {}) {
|
||||
return cleanString(state.contributionAdapterId || ADAPTER_ID).toLowerCase() || ADAPTER_ID;
|
||||
}
|
||||
|
||||
function shouldSubmitKiroBuilderIdContribution(state = {}) {
|
||||
return Boolean(state?.accountContributionEnabled)
|
||||
&& normalizeFlowId(state) === FLOW_ID
|
||||
&& normalizeAdapterId(state) === ADAPTER_ID;
|
||||
}
|
||||
|
||||
function normalizeContributionApiUrl(value = '') {
|
||||
const normalized = cleanString(value).replace(/\/+$/, '');
|
||||
if (!normalized) {
|
||||
return DEFAULT_CONTRIBUTION_API_URL;
|
||||
}
|
||||
if (/\/api\/contributions$/i.test(normalized)) {
|
||||
return normalized;
|
||||
}
|
||||
return `${normalized}/api/contributions`;
|
||||
}
|
||||
|
||||
function mergeFlowContributionRuntime(currentRuntime = {}, flowId = FLOW_ID, patch = {}) {
|
||||
const runtime = isPlainObject(currentRuntime) ? currentRuntime : {};
|
||||
const currentFlowRuntime = isPlainObject(runtime[flowId]) ? runtime[flowId] : {};
|
||||
return {
|
||||
...runtime,
|
||||
[flowId]: {
|
||||
...currentFlowRuntime,
|
||||
...patch,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function redactKnownArtifactSecrets(message = '', artifact = {}) {
|
||||
let result = cleanString(message);
|
||||
const secrets = [
|
||||
artifact?.credentials?.refreshToken,
|
||||
artifact?.credentials?.clientSecret,
|
||||
]
|
||||
.map((value) => cleanString(value))
|
||||
.filter(Boolean);
|
||||
secrets.forEach((secret) => {
|
||||
result = result.split(secret).join(artifactApi.redactSecret?.(secret) || '[redacted]');
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
async function readJsonResponse(response) {
|
||||
const text = await response.text();
|
||||
try {
|
||||
return text ? JSON.parse(text) : {};
|
||||
} catch (_error) {
|
||||
return { message: text };
|
||||
}
|
||||
}
|
||||
|
||||
async function submitContributionArtifact(artifact = {}, options = {}) {
|
||||
const fetchImpl = options.fetchImpl;
|
||||
if (typeof fetchImpl !== 'function') {
|
||||
throw new Error('账号贡献提交能力缺少 fetch。');
|
||||
}
|
||||
const endpoint = normalizeContributionApiUrl(options.apiUrl);
|
||||
const payload = {
|
||||
flow: FLOW_ID,
|
||||
adapter_id: ADAPTER_ID,
|
||||
artifact_kind: ARTIFACT_KIND,
|
||||
source: 'flowpilot-extension',
|
||||
contributor: {
|
||||
nickname: cleanString(options.nickname),
|
||||
qq: cleanString(options.qq),
|
||||
},
|
||||
artifact,
|
||||
};
|
||||
const response = await fetchImpl(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
const body = await readJsonResponse(response);
|
||||
if (!response.ok || body?.ok === false) {
|
||||
throw new Error(cleanString(body?.message || body?.detail || body?.error) || `贡献服务请求失败(HTTP ${response.status})。`);
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
status: response.status,
|
||||
contributionId: cleanString(body?.contribution_id || body?.contributionId || body?.id),
|
||||
message: cleanString(body?.message) || '贡献提交成功',
|
||||
raw: body,
|
||||
};
|
||||
}
|
||||
|
||||
function createKiroBuilderIdContributionAdapter(deps = {}) {
|
||||
const {
|
||||
addLog = async () => {},
|
||||
contributionApiUrl = DEFAULT_CONTRIBUTION_API_URL,
|
||||
fetchImpl = typeof fetch === 'function' ? fetch.bind(globalThis) : null,
|
||||
getState = async () => ({}),
|
||||
setState = async () => {},
|
||||
} = deps;
|
||||
|
||||
async function updateFlowContributionRuntime(currentState = {}, patch = {}) {
|
||||
const runtime = mergeFlowContributionRuntime(currentState.flowContributionRuntime, FLOW_ID, {
|
||||
adapterId: ADAPTER_ID,
|
||||
...patch,
|
||||
});
|
||||
await setState({
|
||||
flowContributionRuntime: runtime,
|
||||
});
|
||||
return runtime;
|
||||
}
|
||||
|
||||
async function log(message, level = 'info', nodeId = '') {
|
||||
await addLog(message, level, nodeId ? { nodeId } : {});
|
||||
}
|
||||
|
||||
async function maybeSubmitFlowContribution(state = {}, options = {}) {
|
||||
const currentState = Object.keys(state || {}).length ? state : await getState();
|
||||
const nodeId = cleanString(options.nodeId || 'kiro-complete-desktop-authorize');
|
||||
if (!shouldSubmitKiroBuilderIdContribution(currentState)) {
|
||||
return {
|
||||
ok: true,
|
||||
skipped: true,
|
||||
reason: 'not_enabled_for_kiro_builder_id',
|
||||
};
|
||||
}
|
||||
|
||||
let artifact = null;
|
||||
try {
|
||||
artifact = artifactApi.buildKiroBuilderIdArtifact(currentState);
|
||||
} catch (error) {
|
||||
const message = redactKnownArtifactSecrets(getErrorMessage(error), artifact);
|
||||
await updateFlowContributionRuntime(currentState, {
|
||||
enabled: true,
|
||||
status: 'skipped',
|
||||
error: message,
|
||||
lastMessage: message,
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
await log(`Kiro 账号贡献已跳过:${message}`, 'warn', nodeId);
|
||||
return {
|
||||
ok: false,
|
||||
skipped: true,
|
||||
reason: error?.code || 'artifact_invalid',
|
||||
message,
|
||||
};
|
||||
}
|
||||
|
||||
await updateFlowContributionRuntime(currentState, {
|
||||
enabled: true,
|
||||
status: 'submitting',
|
||||
error: '',
|
||||
lastMessage: '正在提交 Kiro Builder ID 贡献',
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
|
||||
const safeSummary = artifactApi.buildSafeArtifactSummary?.(artifact) || {};
|
||||
await log(`Kiro 账号贡献:正在提交 Builder ID,邮箱 ${safeSummary.email || '未知'}。`, 'info', nodeId);
|
||||
|
||||
try {
|
||||
const result = await submitContributionArtifact(artifact, {
|
||||
apiUrl: options.contributionApiUrl || contributionApiUrl,
|
||||
fetchImpl,
|
||||
nickname: currentState.contributionNickname,
|
||||
qq: currentState.contributionQq,
|
||||
});
|
||||
await updateFlowContributionRuntime(currentState, {
|
||||
enabled: true,
|
||||
status: 'submitted',
|
||||
error: '',
|
||||
contributionId: result.contributionId,
|
||||
lastMessage: result.message,
|
||||
submittedAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
await log(`Kiro 账号贡献:提交完成,${result.message}。`, 'ok', nodeId);
|
||||
return result;
|
||||
} catch (error) {
|
||||
const message = redactKnownArtifactSecrets(getErrorMessage(error), artifact);
|
||||
await updateFlowContributionRuntime(currentState, {
|
||||
enabled: true,
|
||||
status: 'error',
|
||||
error: message,
|
||||
lastMessage: message,
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
await log(`Kiro 账号贡献提交失败:${message}`, 'warn', nodeId);
|
||||
return {
|
||||
ok: false,
|
||||
skipped: false,
|
||||
reason: 'submit_failed',
|
||||
message,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
maybeSubmitFlowContribution,
|
||||
shouldSubmitKiroBuilderIdContribution,
|
||||
submitContributionArtifact: (artifact, options = {}) => submitContributionArtifact(artifact, {
|
||||
...options,
|
||||
apiUrl: options.apiUrl || contributionApiUrl,
|
||||
fetchImpl: options.fetchImpl || fetchImpl,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
ADAPTER_ID,
|
||||
ARTIFACT_KIND,
|
||||
DEFAULT_CONTRIBUTION_API_URL,
|
||||
FLOW_ID,
|
||||
createKiroBuilderIdContributionAdapter,
|
||||
normalizeContributionApiUrl,
|
||||
shouldSubmitKiroBuilderIdContribution,
|
||||
submitContributionArtifact,
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,138 @@
|
||||
(function attachBackgroundKiroCredentialArtifact(root, factory) {
|
||||
root.MultiPageBackgroundKiroCredentialArtifact = factory(root);
|
||||
})(typeof self !== 'undefined' ? self : globalThis, function createBackgroundKiroCredentialArtifactModule(root) {
|
||||
const kiroStateApi = root?.MultiPageBackgroundKiroState || null;
|
||||
const FLOW_ID = 'kiro';
|
||||
const ADAPTER_ID = 'kiro-builder-id';
|
||||
const ARTIFACT_KIND = 'kiro-builder-id';
|
||||
const DEFAULT_REGION = kiroStateApi?.DEFAULT_REGION || 'us-east-1';
|
||||
const DEFAULT_TARGET_ID = kiroStateApi?.DEFAULT_TARGET_ID || 'kiro-rs';
|
||||
const BUILDER_ID_PROFILE_ARN = 'arn:aws:codewhisperer:us-east-1:638616132270:profile/AAAACCCCXXXX';
|
||||
|
||||
function isPlainObject(value) {
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
||||
}
|
||||
|
||||
function cleanString(value = '') {
|
||||
return String(value ?? '').trim();
|
||||
}
|
||||
|
||||
function readKiroRuntime(state = {}) {
|
||||
return kiroStateApi?.ensureRuntimeState
|
||||
? kiroStateApi.ensureRuntimeState(state)
|
||||
: (isPlainObject(state?.kiroRuntime) ? state.kiroRuntime : {});
|
||||
}
|
||||
|
||||
function resolveKiroTargetId(state = {}, runtimeState = readKiroRuntime(state)) {
|
||||
return cleanString(
|
||||
state?.settingsState?.flows?.kiro?.targetId
|
||||
|| state?.flows?.kiro?.targetId
|
||||
|| state?.kiroTargetId
|
||||
|| runtimeState?.upload?.targetId
|
||||
|| DEFAULT_TARGET_ID
|
||||
) || DEFAULT_TARGET_ID;
|
||||
}
|
||||
|
||||
function resolveEmail(state = {}, runtimeState = readKiroRuntime(state)) {
|
||||
return cleanString(
|
||||
runtimeState?.register?.email
|
||||
|| state?.email
|
||||
|| state?.registrationEmailState?.current
|
||||
|| state?.accountIdentifier
|
||||
);
|
||||
}
|
||||
|
||||
function resolveRegion(state = {}, runtimeState = readKiroRuntime(state), targetId = DEFAULT_TARGET_ID) {
|
||||
return cleanString(
|
||||
runtimeState?.desktopAuth?.region
|
||||
|| state?.settingsState?.flows?.kiro?.targets?.[targetId]?.region
|
||||
|| state?.flows?.kiro?.targets?.[targetId]?.region
|
||||
|| DEFAULT_REGION
|
||||
) || DEFAULT_REGION;
|
||||
}
|
||||
|
||||
function assertRequiredField(name, value, message) {
|
||||
if (!cleanString(value)) {
|
||||
const error = new Error(message);
|
||||
error.code = `missing_${name}`;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function redactSecret(value = '') {
|
||||
const normalized = cleanString(value);
|
||||
if (!normalized) {
|
||||
return '';
|
||||
}
|
||||
if (normalized.length <= 10) {
|
||||
return `${normalized.slice(0, 2)}***`;
|
||||
}
|
||||
return `${normalized.slice(0, 6)}...${normalized.slice(-4)}`;
|
||||
}
|
||||
|
||||
function buildKiroBuilderIdArtifact(state = {}, options = {}) {
|
||||
const runtimeState = readKiroRuntime(state);
|
||||
const desktopAuth = runtimeState?.desktopAuth || {};
|
||||
const targetId = resolveKiroTargetId(state, runtimeState);
|
||||
const region = resolveRegion(state, runtimeState, targetId);
|
||||
const email = resolveEmail(state, runtimeState);
|
||||
const refreshToken = String(desktopAuth.refreshToken || '');
|
||||
const clientId = cleanString(desktopAuth.clientId);
|
||||
const clientSecret = String(desktopAuth.clientSecret || '');
|
||||
|
||||
assertRequiredField('refreshToken', refreshToken, '缺少桌面授权 refreshToken,无法提交 Kiro Builder ID 贡献。');
|
||||
assertRequiredField('clientId', clientId, '缺少桌面授权 clientId,无法提交 Kiro Builder ID 贡献。');
|
||||
assertRequiredField('clientSecret', clientSecret, '缺少桌面授权 clientSecret,无法提交 Kiro Builder ID 贡献。');
|
||||
assertRequiredField('email', email, '缺少注册邮箱,无法提交 Kiro Builder ID 贡献。');
|
||||
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
flow: FLOW_ID,
|
||||
adapter: ADAPTER_ID,
|
||||
artifact: ARTIFACT_KIND,
|
||||
account: {
|
||||
email,
|
||||
},
|
||||
credentials: {
|
||||
refreshToken,
|
||||
clientId,
|
||||
clientSecret,
|
||||
profileArn: cleanString(options.profileArn) || BUILDER_ID_PROFILE_ARN,
|
||||
authMethod: 'idc',
|
||||
region,
|
||||
authRegion: region,
|
||||
apiRegion: region,
|
||||
tokenSource: cleanString(desktopAuth.tokenSource) || 'desktop_authorization_code_pkce',
|
||||
},
|
||||
metadata: {
|
||||
targetId,
|
||||
authorizedAt: Math.max(0, Number(desktopAuth.authorizedAt) || 0),
|
||||
generatedAt: new Date().toISOString(),
|
||||
source: 'flowpilot-extension',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function buildSafeArtifactSummary(artifact = {}) {
|
||||
return {
|
||||
flow: cleanString(artifact.flow),
|
||||
adapter: cleanString(artifact.adapter),
|
||||
artifact: cleanString(artifact.artifact),
|
||||
email: cleanString(artifact.account?.email),
|
||||
clientId: cleanString(artifact.credentials?.clientId),
|
||||
refreshToken: redactSecret(artifact.credentials?.refreshToken),
|
||||
clientSecret: redactSecret(artifact.credentials?.clientSecret),
|
||||
region: cleanString(artifact.credentials?.region),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
ADAPTER_ID,
|
||||
ARTIFACT_KIND,
|
||||
BUILDER_ID_PROFILE_ARN,
|
||||
FLOW_ID,
|
||||
buildKiroBuilderIdArtifact,
|
||||
buildSafeArtifactSummary,
|
||||
redactSecret,
|
||||
};
|
||||
});
|
||||
@@ -365,6 +365,7 @@
|
||||
MAIL_2925_VERIFICATION_INTERVAL_MS = 15000,
|
||||
MAIL_2925_VERIFICATION_MAX_ATTEMPTS = 15,
|
||||
isTabAlive = async () => false,
|
||||
maybeSubmitFlowContribution = async () => null,
|
||||
KIRO_REGISTER_INJECT_FILES = null,
|
||||
KIRO_DESKTOP_AUTHORIZE_INJECT_FILES = null,
|
||||
pollCloudflareTempEmailVerificationCode = null,
|
||||
@@ -477,6 +478,15 @@
|
||||
},
|
||||
});
|
||||
await log('步骤 8:桌面授权回调已捕获,Token 换取成功。', 'ok', nodeId);
|
||||
await maybeSubmitFlowContribution({
|
||||
...currentState,
|
||||
...payload,
|
||||
}, {
|
||||
nodeId,
|
||||
trigger: 'kiro-step-8',
|
||||
}).catch(async (error) => {
|
||||
await log(`步骤 8:Kiro 公共贡献提交异常,已保留桌面授权结果:${getErrorMessage(error)}`, 'warn', nodeId);
|
||||
});
|
||||
await completeNodeFromBackground(nodeId, payload);
|
||||
return payload;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
}
|
||||
return Boolean(state?.phoneVerificationEnabled)
|
||||
&& !Boolean(state?.plusModeEnabled)
|
||||
&& !Boolean(state?.contributionMode);
|
||||
&& !Boolean(state?.accountContributionEnabled);
|
||||
},
|
||||
resolveSignupMethod = (state = {}) => {
|
||||
const method = normalizeSignupMethod(state?.signupMethod);
|
||||
@@ -149,6 +149,7 @@
|
||||
patchMail2925Account,
|
||||
patchHotmailAccount,
|
||||
pollContributionStatus,
|
||||
submitFlowContribution,
|
||||
registerTab,
|
||||
requestStop,
|
||||
probeIpProxyExit,
|
||||
@@ -162,7 +163,7 @@
|
||||
setCurrentPayPalAccount,
|
||||
setCurrentMail2925Account,
|
||||
setCurrentHotmailAccount,
|
||||
setContributionMode,
|
||||
setAccountContributionMode,
|
||||
setEmailState,
|
||||
setEmailStateSilently,
|
||||
persistRegistrationEmailState,
|
||||
@@ -179,7 +180,7 @@
|
||||
setNodeStatus,
|
||||
skipAutoRunCountdown,
|
||||
skipNode,
|
||||
startContributionFlow,
|
||||
startFlowContribution,
|
||||
startAutoRunLoop,
|
||||
deleteMail2925Account,
|
||||
deleteMail2925Accounts,
|
||||
@@ -1154,59 +1155,61 @@
|
||||
return await setFreeReusablePhoneActivation(message.payload || {});
|
||||
}
|
||||
|
||||
case 'SET_CONTRIBUTION_MODE': {
|
||||
case 'SET_ACCOUNT_CONTRIBUTION_MODE': {
|
||||
const enabled = Boolean(message.payload?.enabled);
|
||||
const state = await ensureManualInteractionAllowed(enabled ? '进入贡献模式' : '退出贡献模式');
|
||||
const state = await ensureManualInteractionAllowed(enabled ? '进入账号贡献' : '退出账号贡献');
|
||||
if (Object.values(state.nodeStatuses || {}).some((status) => status === 'running')) {
|
||||
throw new Error(enabled ? '当前有步骤正在执行,无法进入贡献模式。' : '当前有步骤正在执行,无法退出贡献模式。');
|
||||
throw new Error(enabled ? '当前有步骤正在执行,无法进入账号贡献。' : '当前有步骤正在执行,无法退出账号贡献。');
|
||||
}
|
||||
if (typeof setContributionMode !== 'function') {
|
||||
throw new Error('贡献模式切换能力未接入。');
|
||||
if (typeof setAccountContributionMode !== 'function') {
|
||||
throw new Error('账号贡献切换能力未接入。');
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
state: await setContributionMode(enabled),
|
||||
state: await setAccountContributionMode(enabled, {
|
||||
adapterId: message.payload?.adapterId,
|
||||
flowId: message.payload?.flowId || state?.activeFlowId || state?.flowId,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
case 'START_CONTRIBUTION_FLOW': {
|
||||
case 'START_FLOW_CONTRIBUTION': {
|
||||
const state = await ensureManualInteractionAllowed('开始贡献');
|
||||
if (Object.values(state.nodeStatuses || {}).some((status) => status === 'running')) {
|
||||
throw new Error('当前有步骤正在执行,无法开始贡献流程。');
|
||||
}
|
||||
if (typeof startContributionFlow !== 'function') {
|
||||
if (!state?.accountContributionEnabled) {
|
||||
throw new Error('请先进入账号贡献。');
|
||||
}
|
||||
if (typeof startFlowContribution !== 'function') {
|
||||
throw new Error('贡献 OAuth 流程尚未接入。');
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
state: await startContributionFlow({
|
||||
state: await startFlowContribution({
|
||||
nickname: message.payload?.nickname,
|
||||
qq: message.payload?.qq,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
case 'SET_CONTRIBUTION_PROFILE': {
|
||||
case 'SUBMIT_FLOW_CONTRIBUTION': {
|
||||
const state = await getState();
|
||||
if (!state?.contributionMode) {
|
||||
throw new Error('请先进入贡献模式。');
|
||||
if (!state?.accountContributionEnabled) {
|
||||
throw new Error('请先进入账号贡献。');
|
||||
}
|
||||
const nickname = String(message.payload?.nickname || '').trim();
|
||||
const qq = String(message.payload?.qq || '').trim();
|
||||
if (qq && !/^\d{1,20}$/.test(qq)) {
|
||||
throw new Error('QQ 只能填写数字,且长度不能超过 20 位。');
|
||||
if (typeof submitFlowContribution !== 'function') {
|
||||
throw new Error('贡献提交能力尚未接入。');
|
||||
}
|
||||
await setState({
|
||||
contributionNickname: nickname,
|
||||
contributionQq: qq,
|
||||
});
|
||||
return {
|
||||
ok: true,
|
||||
state: await getState(),
|
||||
state: await submitFlowContribution(message.payload?.callbackUrl, {
|
||||
reason: message.payload?.reason || 'sidepanel_submit',
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
case 'POLL_CONTRIBUTION_STATUS': {
|
||||
case 'POLL_FLOW_CONTRIBUTION_STATUS': {
|
||||
if (typeof pollContributionStatus !== 'function') {
|
||||
throw new Error('贡献状态轮询能力尚未接入。');
|
||||
}
|
||||
@@ -1285,8 +1288,11 @@
|
||||
if (message.source === 'sidepanel') {
|
||||
await lockAutomationWindowFromMessage(message, sender);
|
||||
}
|
||||
if (Boolean(message.payload?.contributionMode) && typeof setContributionMode === 'function') {
|
||||
await setContributionMode(true);
|
||||
if (Boolean(message.payload?.accountContributionEnabled) && typeof setAccountContributionMode === 'function') {
|
||||
await setAccountContributionMode(true, {
|
||||
adapterId: message.payload?.contributionAdapterId,
|
||||
flowId: message.payload?.activeFlowId || message.payload?.flowId,
|
||||
});
|
||||
if (typeof setState === 'function') {
|
||||
const contributionNickname = String(message.payload?.contributionNickname || '').trim();
|
||||
const contributionQq = String(message.payload?.contributionQq || '').trim();
|
||||
@@ -1325,8 +1331,11 @@
|
||||
if (message.source === 'sidepanel') {
|
||||
await lockAutomationWindowFromMessage(message, sender);
|
||||
}
|
||||
if (Boolean(message.payload?.contributionMode) && typeof setContributionMode === 'function') {
|
||||
await setContributionMode(true);
|
||||
if (Boolean(message.payload?.accountContributionEnabled) && typeof setAccountContributionMode === 'function') {
|
||||
await setAccountContributionMode(true, {
|
||||
adapterId: message.payload?.contributionAdapterId,
|
||||
flowId: message.payload?.activeFlowId || message.payload?.flowId,
|
||||
});
|
||||
if (typeof setState === 'function') {
|
||||
const contributionNickname = String(message.payload?.contributionNickname || '').trim();
|
||||
const contributionQq = String(message.payload?.contributionQq || '').trim();
|
||||
@@ -1444,7 +1453,7 @@
|
||||
|| Object.prototype.hasOwnProperty.call(updates, 'signupMethod')
|
||||
|| Object.prototype.hasOwnProperty.call(updates, 'panelMode')
|
||||
|| Object.prototype.hasOwnProperty.call(updates, 'activeFlowId')
|
||||
|| Object.prototype.hasOwnProperty.call(updates, 'contributionMode')
|
||||
|| Object.prototype.hasOwnProperty.call(updates, 'accountContributionEnabled')
|
||||
) {
|
||||
updates.signupMethod = resolveSignupMethod(nextSignupState);
|
||||
}
|
||||
@@ -1576,8 +1585,11 @@
|
||||
error: error?.message || String(error || '代理应用失败'),
|
||||
}));
|
||||
}
|
||||
if (Boolean(currentState?.contributionMode) && typeof setContributionMode === 'function') {
|
||||
await setContributionMode(true);
|
||||
if (Boolean(currentState?.accountContributionEnabled) && typeof setAccountContributionMode === 'function') {
|
||||
await setAccountContributionMode(true, {
|
||||
adapterId: currentState?.contributionAdapterId,
|
||||
flowId: currentState?.activeFlowId || currentState?.flowId,
|
||||
});
|
||||
}
|
||||
if (Object.keys(stateUpdates).length > 0 && typeof broadcastDataUpdate === 'function') {
|
||||
broadcastDataUpdate(stateUpdates);
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
return normalizeStep7SignupMethod(state?.signupMethod) === 'phone'
|
||||
&& Boolean(state?.phoneVerificationEnabled)
|
||||
&& !Boolean(state?.plusModeEnabled)
|
||||
&& !Boolean(state?.contributionMode);
|
||||
&& !Boolean(state?.accountContributionEnabled);
|
||||
}
|
||||
|
||||
function hasStep7PhoneSignupIdentity(state = {}) {
|
||||
|
||||
Reference in New Issue
Block a user