From 1fa59ba330abbd8d43f6c21f40ffa7c7a2d7d60f Mon Sep 17 00:00:00 2001 From: cheng zhen Date: Fri, 3 Jan 2025 18:37:44 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=B8=85=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client_decrypt.py | 73 -------- cursor_pro_keep_alive.py | 16 -- gpt-accesstoken.py | 166 ----------------- server/.dockerignore | 10 -- server/.env | 4 - server/Dockerfile | 20 --- server/README.md | 2 - server/docker-compose.yml | 33 ---- server/models/License.js | 37 ---- server/models/LicenseKey.js | 22 --- server/models/UserGeneration.js | 35 ---- server/package.json | 22 --- server/server.js | 305 -------------------------------- server/utils/date.js | 34 ---- server/utils/encryption.js | 60 ------- server/utils/validateStar.js | 30 ---- 16 files changed, 869 deletions(-) delete mode 100644 client_decrypt.py delete mode 100644 gpt-accesstoken.py delete mode 100644 server/.dockerignore delete mode 100644 server/.env delete mode 100644 server/Dockerfile delete mode 100644 server/README.md delete mode 100644 server/docker-compose.yml delete mode 100644 server/models/License.js delete mode 100644 server/models/LicenseKey.js delete mode 100644 server/models/UserGeneration.js delete mode 100644 server/package.json delete mode 100644 server/server.js delete mode 100644 server/utils/date.js delete mode 100644 server/utils/encryption.js delete mode 100644 server/utils/validateStar.js diff --git a/client_decrypt.py b/client_decrypt.py deleted file mode 100644 index 29155e2..0000000 --- a/client_decrypt.py +++ /dev/null @@ -1,73 +0,0 @@ -from Crypto.Cipher import AES -import json -import binascii - - -class ResponseDecryptor: - def __init__(self, encryption_key): - """ - 初始化解密器 - :param encryption_key: 十六进制格式的密钥字符串 - """ - # 将十六进制字符串转换为字节 - self.key = binascii.unhexlify(encryption_key) - - def decrypt_response(self, encrypted_data): - """ - 解密服务器响应的数据 - :param encrypted_data: 加密的数据字符串 (格式: "iv:encrypted") - :return: 解密后的 JSON 数据 - """ - try: - # 分离 IV 和加密数据 - iv_hex, encrypted_text = encrypted_data.split(":") - - # 将十六进制转换为字节 - iv = binascii.unhexlify(iv_hex) - encrypted_bytes = binascii.unhexlify(encrypted_text) - - # 创建解密器 - cipher = AES.new(self.key, AES.MODE_CBC, iv) - - # 解密数据 - decrypted_bytes = cipher.decrypt(encrypted_bytes) - - # 移除填充 - padding_length = decrypted_bytes[-1] - decrypted_data = decrypted_bytes[:-padding_length] - - # 转换为字符串并解析 JSON - decrypted_str = decrypted_data.decode("utf-8") - return json.loads(decrypted_str) - - except Exception as e: - raise Exception(f"解密失败: {str(e)}") - - -# 使用示例 -def main(): - # 这里填入与服务器相同的加密密钥(十六进制格式) - ENCRYPTION_KEY = "f1e2d3c4b5a6978899aabbccddeeff00112233445566778899aabbccddeeff00" # 替换为实际的密钥 - - # 创建解密器实例 - decryptor = ResponseDecryptor(ENCRYPTION_KEY) - - # 模拟服务器响应 - server_response = { - "encrypted_data": "iv_hex:encrypted_data_hex" # 这里是服务器返回的加密数据 - } - - try: - # 解密数据 - decrypted_data = decryptor.decrypt_response(server_response["encrypted_data"]) - print("解密后的数据:", decrypted_data) - - # 现在可以访问解密后的数据 - if decrypted_data.get("success"): - print("操作成功!") - # 处理其他数据... - else: - print("操作失败:", decrypted_data.get("message")) - - except Exception as e: - print("错误:", str(e)) diff --git a/cursor_pro_keep_alive.py b/cursor_pro_keep_alive.py index 23c5858..ff4441b 100644 --- a/cursor_pro_keep_alive.py +++ b/cursor_pro_keep_alive.py @@ -1,7 +1,5 @@ import os -from license_manager import LicenseManager - os.environ["PYTHONVERBOSE"] = "0" os.environ["PYINSTALLER_VERBOSE"] = "0" @@ -234,20 +232,6 @@ class EmailGenerator: if __name__ == "__main__": browser_manager = None try: - license_manager = LicenseManager() - - # 验证许可证 - is_valid, message = license_manager.verify_license() - if not is_valid: - print(f"许可证验证失败: {message}") - # 提示用户激活 - license_key = input("请输入激活码: ") - success, activate_message = license_manager.activate_license(license_key) - if not success: - print(f"激活失败: {activate_message}") - sys.exit(1) - print("激活成功!") - # 初始化浏览器 browser_manager = BrowserManager() browser = browser_manager.init_browser() diff --git a/gpt-accesstoken.py b/gpt-accesstoken.py deleted file mode 100644 index 4f8bbf8..0000000 --- a/gpt-accesstoken.py +++ /dev/null @@ -1,166 +0,0 @@ -from DrissionPage import ChromiumOptions, Chromium -import random -import time - -def handle_turnstile(tab): - """处理 Turnstile 验证""" - print("准备处理验证") - try: - while True: - if tab.ele('@id=email-input', timeout=2): - print("无需验证 - 邮箱输入框已加载") - return True - - if tab.ele('@id=password', timeout=2): - print("无需验证 - 密码输入框已加载") - return True - - try: - challenge_element = (tab.ele("@name=cf-turnstile-response", timeout=2) - .parent() - .shadow_root - .ele("tag:iframe") - .ele("tag:body") - .sr("tag:input")) - - if challenge_element: - print("验证框加载完成") - time.sleep(random.uniform(1, 3)) - challenge_element.click() - print("验证按钮已点击,等待验证完成...") - time.sleep(2) - return True - except: - pass - - time.sleep(2) - - except Exception as e: - print(f"验证处理出错: {str(e)}") - print('跳过验证') - return False - -account = 'your_chatgpt_account' -password = 'your_chatgpt_password' - -co = ChromiumOptions() -co.add_extension("turnstilePatch") -# co.headless() -co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36') -co.set_pref('credentials_enable_service', False) -co.set_argument('--hide-crash-restore-bubble') -co.auto_port() - -browser = Chromium(co) -tab = browser.latest_tab -tab.run_js("try { turnstile.reset() } catch(e) { }") - -print("\n步骤1: 开始访问网站...") - -tab.get('https://chatgpt.com') -print('等待页面加载...') - -print("\n步骤2: 开始登录...") -for _ in range(5): - try: - if tab.ele('xpath:/html/body/div[1]/div[1]/main/div[1]/div[1]/div/div[1]/div/div[3]/div/button[1]'): - signin_btn = tab.ele('xpath:/html/body/div[1]/div[1]/main/div[1]/div[1]/div/div[1]/div/div[3]/div/button[1]') - print("找到黑色登录按钮:", signin_btn.text) - break - if tab.ele('@data-testid=login-button'): - signin_btn = tab.ele('@data-testid=login-button') - print("找到蓝色登录按钮:", signin_btn.text) - break - if tab.ele("@name=cf-turnstile-response"): - print('加载页面时出现CF验证, IP 质量太差, 请更换 IP 重新尝试!') - browser.quit() - exit() - time.sleep(3) - except Exception as e: - print(f"处理登录按钮时出错: {str(e)}") - -for _ in range(5): - try: - if signin_btn: - signin_btn.click() - print("点击登录按钮") - break - except Exception as e: - print(f"处理登录按钮时出错: {str(e)}") - time.sleep(3) -else: - print("尝试点击登录按钮失败,程序退出") - exit() - -handle_turnstile(tab) - -print("\n步骤3: 输入邮箱...") -for _ in range(5): - try: - if tab.ele('@id=email-input'): - tab.actions.click('@id=email-input').type(account) - time.sleep(0.5) - tab.ele('@class=continue-btn').click() - print("输入邮箱并点击继续") - break - except Exception as e: - print(f"加载邮箱输入框时出错: {str(e)}") - time.sleep(3) -else: - print("尝试加载邮箱输入框失败,程序退出") - browser.quit() - exit() - -handle_turnstile(tab) - -print("\n步骤4: 输入密码...") -for _ in range(5): - try: - if tab.ele('@id=password'): - print("密码输入框加载完成") - tab.actions.click('@id=password').input(password) - time.sleep(2) - tab.ele('@type=submit').click('js') - # tab.actions.click('@type=submit') - print("输入密码并JS点击登录") - break - except Exception as e: - print(f"输入密码时出错: {str(e)}") - time.sleep(3) -else: - print("尝试加载密码输入框失败,程序退出") - browser.quit() - exit() - -for _ in range(5): - try: - if tab.ele('有什么可以帮忙的?'): - print('登录成功!') - break - if tab.ele('重新发送电子邮件'): - print('提示需要邮箱验证码,脚本终止,请手动获取') - exit() - except Exception as e: - print(f"登录可能遇到问题: {str(e)}") - time.sleep(3) -else: - print("登录失败,程序退出") - browser.quit() - exit() - -time.sleep(random.uniform(1,2)) -print('\n',"步骤5: 获取access_token...") -browser.new_tab('https://chatgpt.com/api/auth/session') -tab = browser.latest_tab -time.sleep(1) -response_json = tab.json -if response_json and 'accessToken' in response_json: - access_token = response_json['accessToken'] - print('\n',"请复制保存你的access_token:",'\n') - print(access_token) -else: - print("错误:未找到access token") - -# input("\n按Enter键关闭浏览器...") -browser.quit() - diff --git a/server/.dockerignore b/server/.dockerignore deleted file mode 100644 index 5832766..0000000 --- a/server/.dockerignore +++ /dev/null @@ -1,10 +0,0 @@ -node_modules -npm-debug.log -.env -.env.* -.git -.gitignore -README.md -.dockerignore -Dockerfile -docker-compose.yml \ No newline at end of file diff --git a/server/.env b/server/.env deleted file mode 100644 index be470c9..0000000 --- a/server/.env +++ /dev/null @@ -1,4 +0,0 @@ -MONGODB_URI=mongodb://mongo_3y6JyM:mongo_iNySJ5@119.8.35.41:27017/license-manager?authSource=admin&retryWrites=true&w=majority -PORT=3000 -ENCRYPTION_KEY=f1e2d3c4b5a6978899aabbccddeeff00112233445566778899aabbccddeeff00 -MAX_USAGE_COUNT=10 \ No newline at end of file diff --git a/server/Dockerfile b/server/Dockerfile deleted file mode 100644 index 58a5b19..0000000 --- a/server/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -# 使用 Node.js 18 作为基础镜像 -FROM node:18-alpine - -# 设置工作目录 -WORKDIR /usr/src/app - -# 复制 package.json 和 package-lock.json(如果存在) -COPY package*.json ./ - -# 安装依赖 -RUN npm install - -# 复制源代码 -COPY . . - -# 暴露端口 -EXPOSE 3000 - -# 启动命令 -CMD ["npm", "start"] \ No newline at end of file diff --git a/server/README.md b/server/README.md deleted file mode 100644 index 482c7c2..0000000 --- a/server/README.md +++ /dev/null @@ -1,2 +0,0 @@ -docker build --platform linux/amd64 -t ccz2/cursor-auth-server:latest . -docker push ccz2/cursor-auth-server:latest \ No newline at end of file diff --git a/server/docker-compose.yml b/server/docker-compose.yml deleted file mode 100644 index e126f1f..0000000 --- a/server/docker-compose.yml +++ /dev/null @@ -1,33 +0,0 @@ -version: '3.8' - -services: - # Node.js 应用服务 - app: - build: . - ports: - - "3000:3000" - environment: - - MONGODB_URI=${MONGODB_URI} - - PORT=3000 - - ENCRYPTION_KEY=f1e2d3c4b5a6978899aabbccddeeff00112233445566778899aabbccddeeff00 - env_file: - - .env - depends_on: - - mongo - restart: unless-stopped - - # MongoDB 服务 - mongo: - image: mongo:latest - ports: - - "27017:27017" - environment: - - MONGO_INITDB_ROOT_USERNAME=mongo_3y6JyM - - MONGO_INITDB_ROOT_PASSWORD=mongo_iNySJ5 - - MONGO_INITDB_DATABASE=license-manager - volumes: - - mongodb_data:/data/db - restart: unless-stopped - -volumes: - mongodb_data: \ No newline at end of file diff --git a/server/models/License.js b/server/models/License.js deleted file mode 100644 index 0bc050e..0000000 --- a/server/models/License.js +++ /dev/null @@ -1,37 +0,0 @@ -const mongoose = require('mongoose'); -const { getNowChinaTimeString } = require('../utils/date'); -const licenseSchema = new mongoose.Schema({ - licenseKey: { - type: String, - required: true, - unique: true - }, - machineCode: { - type: String, - required: true - }, - activationDate: { - type: String, - required: true, - default: getNowChinaTimeString - }, - expiryDate: { - type: String, - required: true - }, - isActive: { - type: Boolean, - default: true - }, - maxUsageCount: { - type: Number, - required: true, - default: process.env.MAX_USAGE_COUNT || 10 // 默认允许使用100次 - }, - currentUsageCount: { - type: Number, - default: 0 - } -}); - -module.exports = mongoose.model('License', licenseSchema); \ No newline at end of file diff --git a/server/models/LicenseKey.js b/server/models/LicenseKey.js deleted file mode 100644 index 0807635..0000000 --- a/server/models/LicenseKey.js +++ /dev/null @@ -1,22 +0,0 @@ -const mongoose = require('mongoose'); -const { getNowChinaTimeString } = require('../utils/date'); - -const licenseKeySchema = new mongoose.Schema({ - licenseKey: { - type: String, - required: true, - unique: true - }, - isUsed: { - type: Boolean, - default: false - }, - generatedAt: { - type: String, - default() { - return getNowChinaTimeString(); - } - } -}); - -module.exports = mongoose.model('LicenseKey', licenseKeySchema); \ No newline at end of file diff --git a/server/models/UserGeneration.js b/server/models/UserGeneration.js deleted file mode 100644 index 8b76f79..0000000 --- a/server/models/UserGeneration.js +++ /dev/null @@ -1,35 +0,0 @@ -const mongoose = require('mongoose'); -const { getNowChinaTimeString } = require('../utils/date'); - -const userGenerationSchema = new mongoose.Schema({ - username: { - type: String, - required: true, - unique: true, - index: true - }, - lastGenerationTime: { - type: String, - default() { - return getNowChinaTimeString(); - } - }, - generationCount: { - type: Number, - default: 0 - }, - isDisabled: { - type: Boolean, - default: false - }, - -}, { - timestamps: true // 添加 createdAt 和 updatedAt 字段 -}); - -// 创建索引以优化查询性能 -userGenerationSchema.index({ username: 1 }); - -const UserGeneration = mongoose.model('UserGeneration', userGenerationSchema); - -module.exports = UserGeneration; \ No newline at end of file diff --git a/server/package.json b/server/package.json deleted file mode 100644 index 7ec0c28..0000000 --- a/server/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "license-server", - "version": "1.0.0", - "description": "License activation server for Cursor Pro", - "main": "server.js", - "scripts": { - "start": "NODE_ENV=production node server.js", - "dev": "NODE_ENV=development nodemon server.js" - }, - "dependencies": { - "cors": "^2.8.5", - "crypto": "^1.0.1", - "dotenv": "^16.3.1", - "express": "^4.18.2", - "moment": "^2.29.4", - "moment-timezone": "^0.5.46", - "mongoose": "^8.0.3" - }, - "devDependencies": { - "nodemon": "^3.0.2" - } -} diff --git a/server/server.js b/server/server.js deleted file mode 100644 index 1b779d8..0000000 --- a/server/server.js +++ /dev/null @@ -1,305 +0,0 @@ -require('dotenv').config(); -const express = require('express'); -const mongoose = require('mongoose'); -const cors = require('cors'); -const License = require('./models/License'); -const LicenseKey = require('./models/LicenseKey'); -const { formatChinaTime, getNowChinaTime, getNowChinaTimeString, moment } = require('./utils/date'); -const { encryptLicenseKey, decryptLicenseKey, generateLicenseKey, encryptResponse } = require('./utils/encryption'); -const { validateStar } = require('./utils/validateStar'); -const UserGeneration = require('./models/UserGeneration'); -const app = express(); - -// Middleware -app.use(cors()); -app.use(express.json()); - -// 添加访问日志中间件 -app.use((req, res, next) => { - const start = Date.now(); - res.on('finish', () => { - const duration = Date.now() - start; - console.log(`[${getNowChinaTimeString()}] ${req.method} ${req.originalUrl} - ${res.statusCode} - ${duration}ms`); - }); - next(); -}); - -// Connect to MongoDB -mongoose.connect(process.env.MONGODB_URI, { - useNewUrlParser: true, - useUnifiedTopology: true, - serverSelectionTimeoutMS: 5000, // 超时时间 - socketTimeoutMS: 45000, // Socket 超时 - family: 4, // 强制使用 IPv4 -}) - .then(() => console.log('Connected to MongoDB')) - .catch(err => { - console.error('MongoDB connection error:', err); - process.exit(1); // 如果连接失败,终止程序 - }); - -// 添加连接错误处理 -mongoose.connection.on('error', err => { - console.error('MongoDB connection error:', err); -}); - -mongoose.connection.on('disconnected', () => { - console.log('MongoDB disconnected'); -}); - -// 定义一个复杂的路径,可以放在环境变量中 -const GENERATE_PATH = process.env.GENERATE_PATH || 'xx-zz-yy-dd'; - -// 在应用启动时输出生成路径(仅在控制台显示一次) -console.log('License generation path:', GENERATE_PATH); - -// Generate license key endpoint -app.get(`/${GENERATE_PATH}`, async (req, res) => { - try { - const { username } = req.query; - if (username !== 'ccj') { - const starResult = await validateStar(username); - if (starResult.code === -1 || starResult.hasStarred === false) { - return res.status(200).json({ - code: -1, - message: '不好意思,您还没有star我的项目,无法生成许可证' - }); - } - - - const userGeneration = await UserGeneration.findOne({ username: username }); - - - - if (!userGeneration) { - await UserGeneration.create({ - username: username, - generationCount: 1 - }); - } else { - // 如果这个账号已经禁用 - if (userGeneration.isDisabled) { - return res.status(200).json({ - code: -1, - message: '不好意思,您的账号已被禁用,无法生成许可证' - }); - } - - // 如果这个月已经生成过许可证,则不能再次生成 - if (getNowChinaTime().month() === moment(userGeneration.lastGenerationTime).month()) { - return res.status(200).json({ - code: -1, - message: '不好意思,这个月您已经生成过许可证,无法再次生成' - }); - } - - userGeneration.generationCount += 1; - userGeneration.lastGenerationTime = getNowChinaTimeString(); - await userGeneration.save(); - } - } - - - const licenseKey = generateLicenseKey(); - - await LicenseKey.create({ - licenseKey: licenseKey, - isUsed: false - }); - - // 加密响应数据 - const responseData = { - code: 0, - data: licenseKey - }; - - return res.json(responseData); - } catch (error) { - console.error('生成许可证错误:', error); - return res.status(500).json(encryptResponse({ - code: -1, - message: '服务器错误' - })); - } -}); - -// Activation endpoint -app.post('/activate', async (req, res) => { - try { - const { license_key, machine_code, activation_date } = req.body; - - // Validate input - if (!license_key || !machine_code) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '许可证密钥和机器码是必需的' - })); - } - - // Validate license key format - try { - decryptLicenseKey(license_key); - } catch (error) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '无效的许可证密钥' - })); - } - - // 检查许可证是否存在于生成记录中 - const licenseKeyRecord = await LicenseKey.findOne({ licenseKey: license_key }); - if (!licenseKeyRecord) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '无效的许可证密钥' - })); - } - - // 检查许可证是否已被使用 - if (licenseKeyRecord.isUsed) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '此许可证密钥已被使用,不能重复激活' - })); - } - - // 检查许可证激活状态 - const existingLicense = await License.findOne({ licenseKey: license_key }); - if (existingLicense) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '此许可证已被激活,不能重复使用' - })); - } - - // 更新过期时间计算,使用中国时区 - const expiryDate = formatChinaTime(getNowChinaTime().add(1, 'month'), 'YYYY-MM-DD'); - - await License.create([{ - licenseKey: license_key, - machineCode: machine_code, - activationDate: activation_date ? activation_date : getNowChinaTimeString(), - expiryDate: expiryDate, - isActive: true, - maxUsageCount: process.env.MAX_USAGE_COUNT || 10, - currentUsageCount: 1 - }]); - - - // 更新许可证密钥状态为已使用 - licenseKeyRecord.isUsed = true; - await licenseKeyRecord.save(); - - const responseData = { - code: 0, - message: '激活成功', - data: { - expiry_date: expiryDate - } - }; - - return res.json(encryptResponse(responseData)); - } catch (error) { - console.error('激活错误:', error); - return res.status(500).json(encryptResponse({ - code: -1, - message: '服务器错误' - })); - } -}); - -// Verification endpoint -app.post('/verify', async (req, res) => { - try { - const { license_key, machine_code } = req.body; - - // Validate input - if (!license_key || !machine_code) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '许可证密钥和机器码是必需的' - })); - } - - // Validate license key format - try { - decryptLicenseKey(license_key); - } catch (error) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '无效的许可证密钥' - })); - } - - // Find license - const license = await License.findOne({ licenseKey: license_key }); - - if (!license) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '许可证不存在' - })); - } - - // Check machine code - if (license.machineCode !== machine_code) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '硬件信息不匹配' - })); - } - - // Check if license is active - if (!license.isActive) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '许可证已被禁用' - })); - } - - // 使用中国时区检查过期时间 - if (getNowChinaTime().isAfter(license.expiryDate)) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '许可证已过期' - })); - } - - // 检查使用次数 - if (license.currentUsageCount >= license.maxUsageCount) { - return res.status(200).json(encryptResponse({ - code: -1, - message: '许可证使用次数已达到上限' - })); - } - - // 更新使用次数 - license.currentUsageCount += 1; - await license.save(); - - const responseData = { - code: 0, - data: { - message: '许可证有效', - expiry_date: formatChinaTime(license.expiryDate, 'YYYY-MM-DD'), - usage_count: { - current: license.currentUsageCount, - max: license.maxUsageCount - } - } - }; - - return res.json(encryptResponse(responseData)); - } catch (error) { - console.error('验证错误:', error); - return res.status(500).json(encryptResponse({ - code: -1, - message: '服务器错误' - })); - } -}); - -const PORT = process.env.PORT || 3000; -app.listen(PORT, () => { - console.log(`Server is running on port ${PORT}`); -}); \ No newline at end of file diff --git a/server/utils/date.js b/server/utils/date.js deleted file mode 100644 index 3e8124b..0000000 --- a/server/utils/date.js +++ /dev/null @@ -1,34 +0,0 @@ -const moment = require('moment'); -require('moment-timezone'); - -// 设置默认时区为中国时区 -moment.tz.setDefault('Asia/Shanghai'); - -/** - * 获取格式化的中国时区时间 - * @param {Date|String|Number} date - 日期输入 - * @param {String} format - 格式化模板,默认 'YYYY-MM-DD HH:mm:ss' - * @returns {String} 格式化后的时间字符串 - */ -const formatChinaTime = (date, format = 'YYYY-MM-DD HH:mm:ss') => { - return moment(date).format(format); -}; - -/** - * 获取当前中国时区的时间 - * @returns {moment} moment对象 - */ -const getNowChinaTime = () => { - return moment(); -}; - -const getNowChinaTimeString = () => { - return formatChinaTime(getNowChinaTime()); -}; - -module.exports = { - formatChinaTime, - getNowChinaTime, - getNowChinaTimeString, - moment // 导出配置好时区的 moment 实例 -}; \ No newline at end of file diff --git a/server/utils/encryption.js b/server/utils/encryption.js deleted file mode 100644 index b344011..0000000 --- a/server/utils/encryption.js +++ /dev/null @@ -1,60 +0,0 @@ -const crypto = require('crypto'); - -function getIV() { - if (process.env.ENCRYPTION_IV) { - return Buffer.from(process.env.ENCRYPTION_IV, 'hex'); - } - return crypto.randomBytes(16); -} - -function encryptLicenseKey(text) { - const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex'); - const iv = getIV(); - const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); - let encrypted = cipher.update(text, 'utf8', 'hex'); - encrypted += cipher.final('hex'); - return iv.toString('hex') + ':' + encrypted; -} - -function decryptLicenseKey(encrypted) { - const [ivHex, encryptedText] = encrypted.split(':'); - const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex'); - const iv = Buffer.from(ivHex, 'hex'); - const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); - let decrypted = decipher.update(encryptedText, 'hex', 'utf8'); - decrypted += decipher.final('utf8'); - return decrypted; -} - -function generateLicenseKey() { - const randomBytes = crypto.randomBytes(16); - const timestamp = Date.now().toString(); - const combined = randomBytes.toString('hex') + timestamp; - const encrypted = encryptLicenseKey(combined); - return encrypted; -} - -function encryptResponse(data) { - // 在开发模式下直接返回原始数据 - if (process.env.NODE_ENV === 'development') { - return data; - } - - // 生产模式下加密数据 - const jsonStr = JSON.stringify(data); - const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex'); - const iv = getIV(); - const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); - let encrypted = cipher.update(jsonStr, 'utf8', 'hex'); - encrypted += cipher.final('hex'); - return { - encrypted_data: iv.toString('hex') + ':' + encrypted - }; -} - -module.exports = { - encryptLicenseKey, - decryptLicenseKey, - generateLicenseKey, - encryptResponse -}; \ No newline at end of file diff --git a/server/utils/validateStar.js b/server/utils/validateStar.js deleted file mode 100644 index 092c9f1..0000000 --- a/server/utils/validateStar.js +++ /dev/null @@ -1,30 +0,0 @@ -async function validateStar(username) { - try { - const response = await fetch(`https://api.github.com/users/${username}/starred`); - - if (response.ok) { - const data = await response.json(); - const hasStarred = data.some(repo => repo.name === 'cursor-auto-free'); - - return { - code: 0, - hasStarred - }; - } - - return { - code: -1, - error: `验证star失败: ${response.status}` - }; - - } catch (error) { - return { - code: -1, - error: `请求出错: ${error.message}` - }; - } -} - -module.exports = { - validateStar -};