功能: - 激活码管理 (Pro/Auto 两种类型) - 账号池管理 - 设备绑定记录 - 使用日志 - 搜索/筛选功能 - 禁用/启用功能 (支持退款参考) - 全局设置 (换号间隔、额度消耗等) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
258 lines
5.9 KiB
JavaScript
258 lines
5.9 KiB
JavaScript
'use strict';
|
|
|
|
// ============================================
|
|
// CursorPro API Client - 反混淆版本
|
|
// ============================================
|
|
|
|
const vscode = require('vscode');
|
|
|
|
// 默认 API 地址 (原代码中被混淆)
|
|
const DEFAULT_API_URL = 'https://api.cursorpro.com';
|
|
const REQUEST_TIMEOUT = 15000; // 15秒超时
|
|
|
|
let isOnline = true;
|
|
let onlineStatusCallbacks = [];
|
|
|
|
/**
|
|
* 获取 API URL (从配置或使用默认值)
|
|
*/
|
|
function getApiUrl() {
|
|
const config = vscode.workspace.getConfiguration('cursorpro');
|
|
return config.get('apiUrl') || DEFAULT_API_URL;
|
|
}
|
|
exports.getApiUrl = getApiUrl;
|
|
|
|
/**
|
|
* 获取在线状态
|
|
*/
|
|
function getOnlineStatus() {
|
|
return isOnline;
|
|
}
|
|
exports.getOnlineStatus = getOnlineStatus;
|
|
|
|
/**
|
|
* 监听在线状态变化
|
|
*/
|
|
function onOnlineStatusChange(callback) {
|
|
onlineStatusCallbacks.push(callback);
|
|
return () => {
|
|
onlineStatusCallbacks = onlineStatusCallbacks.filter(cb => cb !== callback);
|
|
};
|
|
}
|
|
exports.onOnlineStatusChange = onOnlineStatusChange;
|
|
|
|
/**
|
|
* 设置在线状态
|
|
*/
|
|
function setOnlineStatus(status) {
|
|
if (isOnline !== status) {
|
|
isOnline = status;
|
|
onlineStatusCallbacks.forEach(callback => callback(status));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 带超时的 fetch
|
|
*/
|
|
async function fetchWithTimeout(url, options, timeout) {
|
|
const controller = new AbortController();
|
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
...options,
|
|
signal: controller.signal
|
|
});
|
|
clearTimeout(timeoutId);
|
|
return response;
|
|
} catch (error) {
|
|
clearTimeout(timeoutId);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 通用请求函数
|
|
*/
|
|
async function request(endpoint, method = 'GET', body) {
|
|
const url = `${getApiUrl()}${endpoint}`;
|
|
const options = {
|
|
method: method,
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
};
|
|
|
|
if (body) {
|
|
options.body = JSON.stringify(body);
|
|
}
|
|
|
|
try {
|
|
const response = await fetchWithTimeout(url, options, REQUEST_TIMEOUT);
|
|
const data = await response.json();
|
|
|
|
setOnlineStatus(true);
|
|
|
|
if (!response.ok && data.error) {
|
|
data.success = false;
|
|
data.message = data.error;
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
// 检查是否是网络错误
|
|
const isNetworkError = error.name === 'AbortError' ||
|
|
error.name === 'fetch' ||
|
|
error.message?.includes('network') ||
|
|
error.message?.includes('fetch') ||
|
|
error.message?.includes('ENOTFOUND') ||
|
|
error.message?.includes('ETIMEDOUT') ||
|
|
error.message?.includes('ECONNREFUSED');
|
|
|
|
if (isNetworkError) {
|
|
setOnlineStatus(false);
|
|
return {
|
|
success: false,
|
|
error: '网络连接失败,请检查网络',
|
|
isOffline: true
|
|
};
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 验证 Key
|
|
*/
|
|
async function verifyKey(key) {
|
|
return request('/api/verify', 'POST', { key });
|
|
}
|
|
exports.verifyKey = verifyKey;
|
|
|
|
/**
|
|
* 切换账号
|
|
*/
|
|
async function switchAccount(key) {
|
|
return request('/api/switch', 'POST', { key });
|
|
}
|
|
exports.switchAccount = switchAccount;
|
|
|
|
/**
|
|
* 获取代理配置
|
|
*/
|
|
async function getProxyConfig() {
|
|
return request('/api/proxy-config', 'GET');
|
|
}
|
|
exports.getProxyConfig = getProxyConfig;
|
|
|
|
/**
|
|
* 更新代理配置
|
|
*/
|
|
async function updateProxyConfig(isEnabled, proxyUrl) {
|
|
return request('/api/proxy-config', 'POST', {
|
|
is_enabled: isEnabled,
|
|
proxy_url: proxyUrl
|
|
});
|
|
}
|
|
exports.updateProxyConfig = updateProxyConfig;
|
|
|
|
// ============================================
|
|
// 无感换号 (Seamless Mode) API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取无缝模式状态
|
|
* 检查用户是否有权使用无感换号功能
|
|
*/
|
|
async function getSeamlessStatus() {
|
|
return request('/api/seamless/status');
|
|
}
|
|
exports.getSeamlessStatus = getSeamlessStatus;
|
|
|
|
/**
|
|
* 获取用户切换状态
|
|
*/
|
|
async function getUserSwitchStatus(userKey) {
|
|
return request('/api/seamless/user-status?key=' + encodeURIComponent(userKey));
|
|
}
|
|
exports.getUserSwitchStatus = getUserSwitchStatus;
|
|
|
|
/**
|
|
* 获取无缝配置
|
|
*/
|
|
async function getSeamlessConfig() {
|
|
return request('/api/seamless/config');
|
|
}
|
|
exports.getSeamlessConfig = getSeamlessConfig;
|
|
|
|
/**
|
|
* 更新无缝配置
|
|
*/
|
|
async function updateSeamlessConfig(config) {
|
|
return request('/api/seamless/config', 'POST', config);
|
|
}
|
|
exports.updateSeamlessConfig = updateSeamlessConfig;
|
|
|
|
/**
|
|
* 注入无缝模式
|
|
*/
|
|
async function injectSeamless(apiUrl, userKey) {
|
|
return request('/api/seamless/inject', 'POST', {
|
|
api_url: apiUrl,
|
|
user_key: userKey
|
|
});
|
|
}
|
|
exports.injectSeamless = injectSeamless;
|
|
|
|
/**
|
|
* 恢复无缝模式
|
|
*/
|
|
async function restoreSeamless() {
|
|
return request('/api/seamless/restore', 'POST');
|
|
}
|
|
exports.restoreSeamless = restoreSeamless;
|
|
|
|
/**
|
|
* 获取无缝账号列表
|
|
*/
|
|
async function getSeamlessAccounts() {
|
|
return request('/api/seamless/accounts');
|
|
}
|
|
exports.getSeamlessAccounts = getSeamlessAccounts;
|
|
|
|
/**
|
|
* 同步无缝账号
|
|
*/
|
|
async function syncSeamlessAccounts(accounts) {
|
|
return request('/api/seamless/accounts', 'POST', { accounts });
|
|
}
|
|
exports.syncSeamlessAccounts = syncSeamlessAccounts;
|
|
|
|
/**
|
|
* 获取无缝 Token
|
|
*/
|
|
async function getSeamlessToken(userKey) {
|
|
return request('/api/seamless/token?key=' + encodeURIComponent(userKey));
|
|
}
|
|
exports.getSeamlessToken = getSeamlessToken;
|
|
|
|
/**
|
|
* 切换无缝 Token
|
|
*/
|
|
async function switchSeamlessToken(userKey) {
|
|
return request('/api/seamless/switch', 'POST', {
|
|
mode: 'seamless',
|
|
userKey: userKey
|
|
});
|
|
}
|
|
exports.switchSeamlessToken = switchSeamlessToken;
|
|
|
|
/**
|
|
* 获取最新版本
|
|
*/
|
|
async function getLatestVersion() {
|
|
return request('/api/version');
|
|
}
|
|
exports.getLatestVersion = getLatestVersion;
|