mirror of
https://github.com/yeongpin/cursor-free-vip.git
synced 2025-08-02 20:47:35 +08:00
chore: Bump version to 1.5.04 and improve system compatibility
- Update version in .env file to 1.5.04 - Add Mac-specific run_venv script to .gitignore - Enhance Cursor Auth platform detection with more precise sys.platform checks - Add maximum retry mechanism for email creation - Improve error handling and platform support in cursor_auth.py
This commit is contained in:
parent
005aa2cd95
commit
4aabe2e403
3
.gitignore
vendored
3
.gitignore
vendored
@ -45,3 +45,6 @@ Thumbs.db
|
|||||||
*.log
|
*.log
|
||||||
*.db
|
*.db
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
|
|
||||||
|
# Mac
|
||||||
|
run_venv.mac.command
|
@ -1,5 +1,11 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v1.6.01
|
||||||
|
1. Fix: Cursor Auth | 修復Cursor Auth
|
||||||
|
2. Add: Create Account Maximum Retry | 增加創建賬號最大重試次數
|
||||||
|
3. Fix: Cursor Auth Error | 修復Cursor Auth錯誤
|
||||||
|
4. Fix: Update Curl Faild | 修復更新Curl失敗
|
||||||
|
|
||||||
## v1.5.03
|
## v1.5.03
|
||||||
1. HOTFIX: Stuck on starting browser | 修復啟動瀏覽器卡住問題
|
1. HOTFIX: Stuck on starting browser | 修復啟動瀏覽器卡住問題
|
||||||
2. Small Fix: Error Handling | 小修錯誤處理
|
2. Small Fix: Error Handling | 小修錯誤處理
|
||||||
|
@ -22,18 +22,21 @@ class CursorAuth:
|
|||||||
def __init__(self, translator=None):
|
def __init__(self, translator=None):
|
||||||
self.translator = translator
|
self.translator = translator
|
||||||
# 判断操作系统
|
# 判断操作系统
|
||||||
if os.name == "nt": # Windows
|
if sys.platform == "win32": # Windows
|
||||||
self.db_path = os.path.join(
|
self.db_path = os.path.join(
|
||||||
os.getenv("APPDATA"), "Cursor", "User", "globalStorage", "state.vscdb"
|
os.getenv("APPDATA"), "Cursor", "User", "globalStorage", "state.vscdb"
|
||||||
)
|
)
|
||||||
elif os.name =='posix':
|
elif sys.platform == 'linux':
|
||||||
self.db_path = os.path.expanduser(
|
self.db_path = os.path.expanduser(
|
||||||
"~/.config/Cursor/User/globalStorage/state.vscdb"
|
"~/.config/Cursor/User/globalStorage/state.vscdb"
|
||||||
)
|
)
|
||||||
else: # macOS
|
elif sys.platform == 'darwin': # macOS
|
||||||
self.db_path = os.path.expanduser(
|
self.db_path = os.path.expanduser(
|
||||||
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
|
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.unsupported_platform')}{Style.RESET_ALL}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# 检查数据库文件是否存在
|
# 检查数据库文件是否存在
|
||||||
if not os.path.exists(self.db_path):
|
if not os.path.exists(self.db_path):
|
||||||
@ -87,13 +90,16 @@ class CursorAuth:
|
|||||||
|
|
||||||
# 设置要更新的键值对
|
# 设置要更新的键值对
|
||||||
updates = []
|
updates = []
|
||||||
|
|
||||||
|
updates.append(("cursorAuth/cachedSignUpType", "Auth_0"))
|
||||||
|
|
||||||
if email is not None:
|
if email is not None:
|
||||||
updates.append(("cursorAuth/cachedEmail", email))
|
updates.append(("cursorAuth/cachedEmail", email))
|
||||||
if access_token is not None:
|
if access_token is not None:
|
||||||
updates.append(("cursorAuth/accessToken", access_token))
|
updates.append(("cursorAuth/accessToken", access_token))
|
||||||
if refresh_token is not None:
|
if refresh_token is not None:
|
||||||
updates.append(("cursorAuth/refreshToken", refresh_token))
|
updates.append(("cursorAuth/refreshToken", refresh_token))
|
||||||
updates.append(("cursorAuth/cachedSignUpType", "Auth_0"))
|
|
||||||
|
|
||||||
# 使用事务来确保数据完整性
|
# 使用事务来确保数据完整性
|
||||||
cursor.execute("BEGIN TRANSACTION")
|
cursor.execute("BEGIN TRANSACTION")
|
||||||
@ -131,5 +137,3 @@ class CursorAuth:
|
|||||||
if conn:
|
if conn:
|
||||||
conn.close()
|
conn.close()
|
||||||
print(f"{EMOJI['DB']} {Fore.CYAN} {self.translator.get('auth.database_connection_closed')}{Style.RESET_ALL}")
|
print(f"{EMOJI['DB']} {Fore.CYAN} {self.translator.get('auth.database_connection_closed')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
|
||||||
|
256
new_tempemail.py
256
new_tempemail.py
@ -73,149 +73,157 @@ class NewTempEmail:
|
|||||||
|
|
||||||
def create_email(self):
|
def create_email(self):
|
||||||
"""create temporary email"""
|
"""create temporary email"""
|
||||||
try:
|
max_retries = 3 # Maximum number of retries
|
||||||
if self.translator:
|
attempt = 0 # Current attempt count
|
||||||
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.visiting_site').replace('mail.tm', self.selected_service['name'])}{Style.RESET_ALL}")
|
|
||||||
else:
|
|
||||||
print(f"{Fore.CYAN}ℹ️ 正在访问 {self.selected_service['name']}...{Style.RESET_ALL}")
|
|
||||||
|
|
||||||
# 获取可用域名列表
|
while attempt < max_retries:
|
||||||
|
attempt += 1
|
||||||
try:
|
try:
|
||||||
domains_response = requests.get(f"{self.api_url}/domains", timeout=10)
|
|
||||||
if domains_response.status_code != 200:
|
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.domains_list_error', error=domains_response.status_code)}{Style.RESET_ALL}")
|
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.domains_list_error', error=domains_response.text)}{Style.RESET_ALL}")
|
|
||||||
raise Exception(f"{self.translator.get('email.failed_to_get_available_domains') if self.translator else 'Failed to get available domains'}")
|
|
||||||
|
|
||||||
domains = domains_response.json()["hydra:member"]
|
|
||||||
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.available_domains_loaded', count=len(domains))}{Style.RESET_ALL}")
|
|
||||||
|
|
||||||
if not domains:
|
|
||||||
raise Exception(f"{self.translator.get('email.no_available_domains') if self.translator else '没有可用域名'}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Fore.RED}❌ 获取域名列表时出错: {str(e)}{Style.RESET_ALL}")
|
|
||||||
raise
|
|
||||||
|
|
||||||
# 排除被屏蔽的域名
|
|
||||||
try:
|
|
||||||
filtered_domains = self.exclude_blocked_domains(domains)
|
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.domains_filtered', count=len(filtered_domains))}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.visiting_site').replace('mail.tm', self.selected_service['name'])}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"{Fore.CYAN}ℹ️ 过滤后剩余 {len(filtered_domains)} 个可用域名{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}ℹ️ 正在访问 {self.selected_service['name']}...{Style.RESET_ALL}")
|
||||||
|
|
||||||
if not filtered_domains:
|
# 获取可用域名列表
|
||||||
|
try:
|
||||||
|
domains_response = requests.get(f"{self.api_url}/domains", timeout=10)
|
||||||
|
if domains_response.status_code != 200:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.domains_list_error', error=domains_response.status_code)}{Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.domains_list_error', error=domains_response.text)}{Style.RESET_ALL}")
|
||||||
|
raise Exception(f"{self.translator.get('email.failed_to_get_available_domains') if self.translator else 'Failed to get available domains'}")
|
||||||
|
|
||||||
|
domains = domains_response.json()["hydra:member"]
|
||||||
|
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.available_domains_loaded', count=len(domains))}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
if not domains:
|
||||||
|
raise Exception(f"{self.translator.get('email.no_available_domains') if self.translator else '没有可用域名'}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}❌ 获取域名列表时出错: {str(e)}{Style.RESET_ALL}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# 排除被屏蔽的域名
|
||||||
|
try:
|
||||||
|
filtered_domains = self.exclude_blocked_domains(domains)
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.all_domains_blocked')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.domains_filtered', count=len(filtered_domains))}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"{Fore.RED}❌ 所有域名都被屏蔽了,尝试切换服务{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}ℹ️ 过滤后剩余 {len(filtered_domains)} 个可用域名{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 切换到另一个服务
|
if not filtered_domains:
|
||||||
for service in self.services:
|
if self.translator:
|
||||||
if service["api_url"] != self.api_url:
|
print(f"{Fore.RED}❌ {self.translator.get('email.all_domains_blocked')}{Style.RESET_ALL}")
|
||||||
self.selected_service = service
|
else:
|
||||||
self.api_url = service["api_url"]
|
print(f"{Fore.RED}❌ 所有域名都被屏蔽了,尝试切换服务{Style.RESET_ALL}")
|
||||||
if self.translator:
|
|
||||||
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.switching_service', service=service['name'])}{Style.RESET_ALL}")
|
|
||||||
else:
|
|
||||||
print(f"{Fore.CYAN}ℹ️ 切换到 {service['name']} 服务{Style.RESET_ALL}")
|
|
||||||
return self.create_email() # 递归调用
|
|
||||||
|
|
||||||
raise Exception(f"{self.translator.get('email.no_available_domains_after_filtering') if self.translator else '过滤后没有可用域名'}")
|
# 切换到另一个服务
|
||||||
except Exception as e:
|
for service in self.services:
|
||||||
print(f"{Fore.RED}❌ 过滤域名时出错: {str(e)}{Style.RESET_ALL}")
|
if service["api_url"] != self.api_url:
|
||||||
raise
|
self.selected_service = service
|
||||||
|
self.api_url = service["api_url"]
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.switching_service', service=service['name'])}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"{Fore.CYAN}ℹ️ 切换到 {service['name']} 服务{Style.RESET_ALL}")
|
||||||
|
return self.create_email() # 递归调用
|
||||||
|
|
||||||
# 生成随机用户名和密码
|
raise Exception(f"{self.translator.get('email.no_available_domains_after_filtering') if self.translator else '过滤后没有可用域名'}")
|
||||||
try:
|
except Exception as e:
|
||||||
username, password = self._generate_credentials()
|
print(f"{Fore.RED}❌ 过滤域名时出错: {str(e)}{Style.RESET_ALL}")
|
||||||
self.password = password
|
raise
|
||||||
|
|
||||||
# 创建邮箱账户
|
# 生成随机用户名和密码
|
||||||
selected_domain = filtered_domains[0]['domain']
|
try:
|
||||||
email = f"{username}@{selected_domain}"
|
username, password = self._generate_credentials()
|
||||||
|
self.password = password
|
||||||
|
|
||||||
|
# 创建邮箱账户
|
||||||
|
selected_domain = filtered_domains[0]['domain']
|
||||||
|
email = f"{username}@{selected_domain}"
|
||||||
|
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.trying_to_create_email', email=email)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"{Fore.CYAN}ℹ️ 尝试创建邮箱: {email}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
account_data = {
|
||||||
|
"address": email,
|
||||||
|
"password": password
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}❌ 生成凭据时出错: {str(e)}{Style.RESET_ALL}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# 创建账户
|
||||||
|
try:
|
||||||
|
create_response = requests.post(f"{self.api_url}/accounts", json=account_data, timeout=15)
|
||||||
|
|
||||||
|
if create_response.status_code != 201:
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=create_response.status_code)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}❌ 创建账户失败: 状态码 {create_response.status_code}{Style.RESET_ALL}")
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=create_response.text)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}❌ 响应内容: {create_response.text}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# 如果是域名问题,尝试下一个域名
|
||||||
|
if len(filtered_domains) > 1 and ("domain" in create_response.text.lower() or "address" in create_response.text.lower()):
|
||||||
|
print(f"{Fore.YELLOW}⚠️ 尝试使用下一个可用域名...{Style.RESET_ALL}")
|
||||||
|
# 将当前域名添加到屏蔽列表
|
||||||
|
if selected_domain not in self.blocked_domains:
|
||||||
|
self.blocked_domains.append(selected_domain)
|
||||||
|
# 递归调用自己
|
||||||
|
return self.create_email()
|
||||||
|
|
||||||
|
raise Exception(f"{self.translator.get('email.failed_to_create_account') if self.translator else '创建账户失败'}")
|
||||||
|
except Exception as e:
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=str(e))}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}❌ 创建账户时出错: {str(e)}{Style.RESET_ALL}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# 获取访问令牌
|
||||||
|
try:
|
||||||
|
token_data = {
|
||||||
|
"address": email,
|
||||||
|
"password": password
|
||||||
|
}
|
||||||
|
|
||||||
|
token_response = requests.post(f"{self.api_url}/token", json=token_data, timeout=10)
|
||||||
|
if token_response.status_code != 200:
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_get_access_token', error=token_response.status_code)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}❌ 获取令牌失败: 状态码 {token_response.status_code}{Style.RESET_ALL}")
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_get_access_token', error=token_response.text)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}❌ 响应内容: {token_response.text}{Style.RESET_ALL}")
|
||||||
|
raise Exception(f"{self.translator.get('email.failed_to_get_access_token') if self.translator else '获取访问令牌失败'}")
|
||||||
|
|
||||||
|
self.token = token_response.json()["token"]
|
||||||
|
self.email = email
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}❌ 获取令牌时出错: {str(e)}{Style.RESET_ALL}")
|
||||||
|
raise
|
||||||
|
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.trying_to_create_email', email=email)}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {self.translator.get('email.create_success')}: {email}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"{Fore.CYAN}ℹ️ 尝试创建邮箱: {email}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ 创建邮箱成功: {email}{Style.RESET_ALL}")
|
||||||
|
return email
|
||||||
|
|
||||||
account_data = {
|
|
||||||
"address": email,
|
|
||||||
"password": password
|
|
||||||
}
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.RED}❌ 生成凭据时出错: {str(e)}{Style.RESET_ALL}")
|
if attempt < max_retries:
|
||||||
raise
|
print(f"{Fore.YELLOW}⚠️ 尝试重新创建邮箱... (尝试 {attempt}/{max_retries}){Style.RESET_ALL}")
|
||||||
|
|
||||||
# 创建账户
|
|
||||||
try:
|
|
||||||
create_response = requests.post(f"{self.api_url}/accounts", json=account_data, timeout=15)
|
|
||||||
|
|
||||||
if create_response.status_code != 201:
|
|
||||||
if self.translator:
|
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=create_response.status_code)}{Style.RESET_ALL}")
|
|
||||||
else:
|
|
||||||
print(f"{Fore.RED}❌ 创建账户失败: 状态码 {create_response.status_code}{Style.RESET_ALL}")
|
|
||||||
if self.translator:
|
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=create_response.text)}{Style.RESET_ALL}")
|
|
||||||
else:
|
|
||||||
print(f"{Fore.RED}❌ 响应内容: {create_response.text}{Style.RESET_ALL}")
|
|
||||||
|
|
||||||
# 如果是域名问题,尝试下一个域名
|
|
||||||
if len(filtered_domains) > 1 and ("domain" in create_response.text.lower() or "address" in create_response.text.lower()):
|
|
||||||
print(f"{Fore.YELLOW}⚠️ 尝试使用下一个可用域名...{Style.RESET_ALL}")
|
|
||||||
# 将当前域名添加到屏蔽列表
|
|
||||||
if selected_domain not in self.blocked_domains:
|
|
||||||
self.blocked_domains.append(selected_domain)
|
|
||||||
# 递归调用自己
|
|
||||||
return self.create_email()
|
|
||||||
|
|
||||||
raise Exception(f"{self.translator.get('email.failed_to_create_account') if self.translator else '创建账户失败'}")
|
|
||||||
except Exception as e:
|
|
||||||
if self.translator:
|
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=str(e))}{Style.RESET_ALL}")
|
|
||||||
else:
|
else:
|
||||||
print(f"{Fore.RED}❌ 创建账户时出错: {str(e)}{Style.RESET_ALL}")
|
|
||||||
raise
|
|
||||||
|
|
||||||
# 获取访问令牌
|
|
||||||
try:
|
|
||||||
token_data = {
|
|
||||||
"address": email,
|
|
||||||
"password": password
|
|
||||||
}
|
|
||||||
|
|
||||||
token_response = requests.post(f"{self.api_url}/token", json=token_data, timeout=10)
|
|
||||||
if token_response.status_code != 200:
|
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_get_access_token', error=token_response.status_code)}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {self.translator.get('email.create_error')}: {str(e)}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"{Fore.RED}❌ 获取令牌失败: 状态码 {token_response.status_code}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ 创建邮箱出错: {str(e)}{Style.RESET_ALL}")
|
||||||
if self.translator:
|
return None
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_get_access_token', error=token_response.text)}{Style.RESET_ALL}")
|
|
||||||
else:
|
|
||||||
print(f"{Fore.RED}❌ 响应内容: {token_response.text}{Style.RESET_ALL}")
|
|
||||||
raise Exception(f"{self.translator.get('email.failed_to_get_access_token') if self.translator else '获取访问令牌失败'}")
|
|
||||||
|
|
||||||
self.token = token_response.json()["token"]
|
|
||||||
self.email = email
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Fore.RED}❌ 获取令牌时出错: {str(e)}{Style.RESET_ALL}")
|
|
||||||
raise
|
|
||||||
|
|
||||||
if self.translator:
|
|
||||||
print(f"{Fore.GREEN}✅ {self.translator.get('email.create_success')}: {email}{Style.RESET_ALL}")
|
|
||||||
else:
|
|
||||||
print(f"{Fore.GREEN}✅ 创建邮箱成功: {email}{Style.RESET_ALL}")
|
|
||||||
return email
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
if self.translator:
|
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.create_error')}: {str(e)}{Style.RESET_ALL}")
|
|
||||||
else:
|
|
||||||
print(f"{Fore.RED}❌ 创建邮箱出错: {str(e)}{Style.RESET_ALL}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""close browser"""
|
"""close browser"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user