Browse Source

feat(cursor): 增强设备标识符管理与配置更新

- 新增 serviceMachineId、firstSessionDate 等多个标识符生成与配置项
- 支持修改 machineid 和 .updaterId 文件并设置只读保护
- 替换 someValue.firstSessionDate 以确保会话追踪准确性
- 提升配置更新原子性与备份机制可靠性
- 优化日志输出与错误处理提示信息
- 统一跨平台(Linux/macOS/Windows)标识符管理逻辑
煎饼果子卷鲨鱼辣椒 1 month ago
parent
commit
8bd3afc320
  1. 86
      scripts/run/cursor_linux_id_modifier.sh
  2. 67
      scripts/run/cursor_mac_id_modifier.sh
  3. 80
      scripts/run/cursor_win_id_modifier.ps1

86
scripts/run/cursor_linux_id_modifier.sh

@ -539,17 +539,84 @@ generate_new_config() {
# 生成并设置新的设备ID
local new_device_id=$(generate_uuid)
local new_machine_id=$(generate_uuid) # 使用 UUID 作为 Machine ID 更常见
# 🔧 新增: serviceMachineId (用于 storage.serviceMachineId)
local new_service_machine_id=$(generate_uuid)
# 🔧 新增: firstSessionDate (重置首次会话日期)
local new_first_session_date=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
# 🔧 新增: macMachineId 和 sqmId
local new_mac_machine_id=$(openssl rand -hex 32 2>/dev/null || head -c 32 /dev/urandom | xxd -p | tr -d '\n')
local new_sqm_id="{$(generate_uuid | tr '[:lower:]' '[:upper:]')}"
log_info "正在设置新的设备和机器ID..."
log_debug "新设备ID: $new_device_id"
log_debug "新机器ID: $new_machine_id"
log_debug "新serviceMachineId: $new_service_machine_id"
log_debug "新firstSessionDate: $new_first_session_date"
# 修改配置文件
if modify_or_add_config "deviceId" "$new_device_id" "$STORAGE_FILE" && \
modify_or_add_config "machineId" "$new_machine_id" "$STORAGE_FILE"; then
log_info "配置文件中的 deviceId 和 machineId 修改成功"
# 🔧 修复: 添加 storage.serviceMachineId, telemetry.firstSessionDate, telemetry.macMachineId, telemetry.sqmId
local config_success=true
modify_or_add_config "deviceId" "$new_device_id" "$STORAGE_FILE" || config_success=false
modify_or_add_config "machineId" "$new_machine_id" "$STORAGE_FILE" || config_success=false
modify_or_add_config "telemetry.machineId" "$new_machine_id" "$STORAGE_FILE" || config_success=false
modify_or_add_config "telemetry.macMachineId" "$new_mac_machine_id" "$STORAGE_FILE" || config_success=false
modify_or_add_config "telemetry.devDeviceId" "$new_device_id" "$STORAGE_FILE" || config_success=false
modify_or_add_config "telemetry.sqmId" "$new_sqm_id" "$STORAGE_FILE" || config_success=false
modify_or_add_config "storage.serviceMachineId" "$new_service_machine_id" "$STORAGE_FILE" || config_success=false
modify_or_add_config "telemetry.firstSessionDate" "$new_first_session_date" "$STORAGE_FILE" || config_success=false
if [ "$config_success" = true ]; then
log_info "配置文件中的所有标识符修改成功"
log_info "📋 [详情] 已更新以下标识符:"
echo " 🔹 deviceId: ${new_device_id:0:16}..."
echo " 🔹 machineId: ${new_machine_id:0:16}..."
echo " 🔹 macMachineId: ${new_mac_machine_id:0:16}..."
echo " 🔹 sqmId: $new_sqm_id"
echo " 🔹 serviceMachineId: $new_service_machine_id"
echo " 🔹 firstSessionDate: $new_first_session_date"
# 🔧 新增: 修改 machineid 文件
log_info "🔧 [machineid] 正在修改 machineid 文件..."
local machineid_file_path="$HOME/.config/Cursor/machineid"
if [ -f "$machineid_file_path" ]; then
# 备份原始 machineid 文件
local machineid_backup="$BACKUP_DIR/machineid.backup_$(date +%Y%m%d_%H%M%S)"
cp "$machineid_file_path" "$machineid_backup" 2>/dev/null && \
log_info "💾 [备份] machineid 文件已备份: $machineid_backup"
fi
# 写入新的 serviceMachineId 到 machineid 文件
if echo -n "$new_service_machine_id" > "$machineid_file_path" 2>/dev/null; then
log_info "✅ [machineid] machineid 文件修改成功: $new_service_machine_id"
# 设置 machineid 文件为只读
chmod 444 "$machineid_file_path" 2>/dev/null && \
log_info "🔒 [保护] machineid 文件已设置为只读"
else
log_warn "⚠️ [machineid] machineid 文件修改失败"
log_info "💡 [提示] 可手动修改文件: $machineid_file_path"
fi
# 🔧 新增: 修改 .updaterId 文件(更新器设备标识符)
log_info "🔧 [updaterId] 正在修改 .updaterId 文件..."
local updater_id_file_path="$HOME/.config/Cursor/.updaterId"
if [ -f "$updater_id_file_path" ]; then
# 备份原始 .updaterId 文件
local updater_id_backup="$BACKUP_DIR/.updaterId.backup_$(date +%Y%m%d_%H%M%S)"
cp "$updater_id_file_path" "$updater_id_backup" 2>/dev/null && \
log_info "💾 [备份] .updaterId 文件已备份: $updater_id_backup"
fi
# 生成新的 updaterId(UUID格式)
local new_updater_id=$(generate_uuid)
if echo -n "$new_updater_id" > "$updater_id_file_path" 2>/dev/null; then
log_info "✅ [updaterId] .updaterId 文件修改成功: $new_updater_id"
# 设置 .updaterId 文件为只读
chmod 444 "$updater_id_file_path" 2>/dev/null && \
log_info "🔒 [保护] .updaterId 文件已设置为只读"
else
log_warn "⚠️ [updaterId] .updaterId 文件修改失败"
log_info "💡 [提示] 可手动修改文件: $updater_id_file_path"
fi
else
log_error "配置文件中的 deviceId 或 machineId 修改失败"
log_error "配置文件中的部分标识符修改失败"
# 注意:即使失败,备份仍在,但配置文件可能已部分修改
return 1 # 返回错误状态
fi
@ -675,6 +742,8 @@ modify_cursor_js_files() {
local mac_machine_id=$(openssl rand -hex 32)
local sqm_id=$(generate_uuid)
local session_id=$(generate_uuid)
# 🔧 新增: 生成 firstSessionDate 用于替换 someValue.firstSessionDate
local first_session_date=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
log_info "🔑 [生成] 已生成新的设备标识符"
log_info " machineId: ${machine_id:0:16}..."
@ -782,6 +851,13 @@ modify_cursor_js_files() {
replaced=true
fi
# 🔧 新增: 替换 someValue.firstSessionDate(首次会话日期)
if grep -q 'someValue\.firstSessionDate' "$file"; then
sed -i "s/someValue\.firstSessionDate/${first_session_date}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.firstSessionDate"
replaced=true
fi
# ========== 方法B: IIFE运行时劫持(crypto.randomUUID) ==========
# 使用IIFE包装,兼容webpack打包的bundle文件
# 在支持 require 的环境中劫持 crypto.randomUUID;在 ESM 环境中安全降级为 no-op,避免 require 抛错

67
scripts/run/cursor_mac_id_modifier.sh

@ -445,6 +445,10 @@ except Exception as e:
local UUID=$(uuidgen | tr '[:upper:]' '[:lower:]')
local MACHINE_ID="auth0|user_$(openssl rand -hex 32)"
local SQM_ID="{$(uuidgen | tr '[:lower:]' '[:upper:]')}"
# 🔧 新增: serviceMachineId (用于 storage.serviceMachineId)
local SERVICE_MACHINE_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
# 🔧 新增: firstSessionDate (重置首次会话日期)
local FIRST_SESSION_DATE=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
log_info "✅ [进度] 1/5 - 设备标识符生成完成"
@ -492,11 +496,14 @@ try:
config = json.load(f)
# 安全更新配置,确保属性存在
# 🔧 修复: 添加 storage.serviceMachineId 和 telemetry.firstSessionDate
properties_to_update = {
'telemetry.machineId': '$MACHINE_ID',
'telemetry.macMachineId': '$MAC_MACHINE_ID',
'telemetry.devDeviceId': '$UUID',
'telemetry.sqmId': '$SQM_ID'
'telemetry.sqmId': '$SQM_ID',
'storage.serviceMachineId': '$SERVICE_MACHINE_ID',
'telemetry.firstSessionDate': '$FIRST_SESSION_DATE'
}
for key, value in properties_to_update.items():
@ -549,11 +556,14 @@ try:
with open('$config_path', 'r', encoding='utf-8') as f:
config = json.load(f)
# 🔧 修复: 添加 storage.serviceMachineId 和 telemetry.firstSessionDate 验证
properties_to_check = {
'telemetry.machineId': '$MACHINE_ID',
'telemetry.macMachineId': '$MAC_MACHINE_ID',
'telemetry.devDeviceId': '$UUID',
'telemetry.sqmId': '$SQM_ID'
'telemetry.sqmId': '$SQM_ID',
'storage.serviceMachineId': '$SERVICE_MACHINE_ID',
'telemetry.firstSessionDate': '$FIRST_SESSION_DATE'
}
verification_passed = True
@ -594,8 +604,52 @@ except Exception as e:
echo " 🔹 macMachineId: $MAC_MACHINE_ID"
echo " 🔹 devDeviceId: $UUID"
echo " 🔹 sqmId: $SQM_ID"
echo " 🔹 serviceMachineId: $SERVICE_MACHINE_ID"
echo " 🔹 firstSessionDate: $FIRST_SESSION_DATE"
echo
log_info "💾 [备份] 原配置已备份至: $backup_name"
# 🔧 新增: 修改 machineid 文件
log_info "🔧 [machineid] 正在修改 machineid 文件..."
local machineid_file_path="$HOME/Library/Application Support/Cursor/machineid"
if [ -f "$machineid_file_path" ]; then
# 备份原始 machineid 文件
local machineid_backup="$backup_dir/machineid.backup_$(date +%Y%m%d_%H%M%S)"
cp "$machineid_file_path" "$machineid_backup" 2>/dev/null && \
log_info "💾 [备份] machineid 文件已备份: $machineid_backup"
fi
# 写入新的 serviceMachineId 到 machineid 文件
if echo -n "$SERVICE_MACHINE_ID" > "$machineid_file_path" 2>/dev/null; then
log_info "✅ [machineid] machineid 文件修改成功: $SERVICE_MACHINE_ID"
# 设置 machineid 文件为只读
chmod 444 "$machineid_file_path" 2>/dev/null && \
log_info "🔒 [保护] machineid 文件已设置为只读"
else
log_warn "⚠️ [machineid] machineid 文件修改失败"
log_info "💡 [提示] 可手动修改文件: $machineid_file_path"
fi
# 🔧 新增: 修改 .updaterId 文件(更新器设备标识符)
log_info "🔧 [updaterId] 正在修改 .updaterId 文件..."
local updater_id_file_path="$HOME/Library/Application Support/Cursor/.updaterId"
if [ -f "$updater_id_file_path" ]; then
# 备份原始 .updaterId 文件
local updater_id_backup="$backup_dir/.updaterId.backup_$(date +%Y%m%d_%H%M%S)"
cp "$updater_id_file_path" "$updater_id_backup" 2>/dev/null && \
log_info "💾 [备份] .updaterId 文件已备份: $updater_id_backup"
fi
# 生成新的 updaterId(UUID格式)
local new_updater_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
if echo -n "$new_updater_id" > "$updater_id_file_path" 2>/dev/null; then
log_info "✅ [updaterId] .updaterId 文件修改成功: $new_updater_id"
# 设置 .updaterId 文件为只读
chmod 444 "$updater_id_file_path" 2>/dev/null && \
log_info "🔒 [保护] .updaterId 文件已设置为只读"
else
log_warn "⚠️ [updaterId] .updaterId 文件修改失败"
log_info "💡 [提示] 可手动修改文件: $updater_id_file_path"
fi
return 0
else
log_error "❌ [错误] 修改验证失败"
@ -1442,6 +1496,8 @@ modify_cursor_js_files() {
local sqm_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
# 生成一个固定的session_id用于替换someValue.sessionId
local session_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
# 🔧 新增: 生成 firstSessionDate 用于替换 someValue.firstSessionDate
local first_session_date=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
log_info "🔑 [生成] 已生成新的设备标识符"
log_info " machineId: ${machine_id:0:16}..."
@ -1554,6 +1610,13 @@ modify_cursor_js_files() {
replaced=true
fi
# 🔧 新增: 替换 someValue.firstSessionDate(首次会话日期)
if grep -q 'someValue\.firstSessionDate' "$file"; then
sed -i.tmp "s/someValue\.firstSessionDate/${first_session_date}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.firstSessionDate"
replaced=true
fi
# ========== 方法B: IIFE运行时劫持(crypto.randomUUID) ==========
# 使用IIFE包装,兼容webpack打包的bundle文件
# 在支持 require 的环境中劫持 crypto.randomUUID;在 ESM 环境中安全降级为 no-op,避免 require 抛错

80
scripts/run/cursor_win_id_modifier.ps1

@ -196,6 +196,14 @@ function Modify-CursorJSFiles {
$replaced = $true
}
# 🔧 新增: 替换 someValue.firstSessionDate
$firstSessionDateValue = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
if ($content -match 'someValue\.firstSessionDate') {
$content = $content -replace 'someValue\.firstSessionDate', $firstSessionDateValue
Write-Host " $GREEN✓$NC [方案A] 替换 someValue.firstSessionDate"
$replaced = $true
}
# ========== 方法B: IIFE运行时劫持(crypto.randomUUID) ==========
# 使用IIFE包装,兼容webpack打包的bundle文件
# 在支持 require 的环境中劫持 crypto.randomUUID;在 ESM 环境中安全降级为 no-op,避免 require 抛错
@ -880,10 +888,14 @@ function Modify-MachineCodeConfig {
$rng.Dispose()
$MACHINE_ID = "${prefixHex}${randomPart}"
$SQM_ID = "{$([System.Guid]::NewGuid().ToString().ToUpper())}"
# 🔧 新增: serviceMachineId (用于 storage.serviceMachineId)
$SERVICE_MACHINE_ID = [System.Guid]::NewGuid().ToString()
# 🔧 新增: firstSessionDate (重置首次会话日期)
$FIRST_SESSION_DATE = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
Write-Host "$GREEN✅ [进度]$NC 1/6 - 设备标识符生成完成"
Write-Host "$GREEN✅ [进度]$NC 1/7 - 设备标识符生成完成"
Write-Host "$BLUE⏳ [进度]$NC 2/6 - 创建备份目录..."
Write-Host "$BLUE⏳ [进度]$NC 2/7 - 创建备份目录..."
# 备份原始值(增强版)
$backupDir = "$env:APPDATA\Cursor\User\globalStorage\backups"
@ -894,7 +906,7 @@ function Modify-MachineCodeConfig {
$backupName = "storage.json.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')_retry$retryCount"
$backupPath = "$backupDir\$backupName"
Write-Host "$BLUE⏳ [进度]$NC 3/6 - 备份原始配置..."
Write-Host "$BLUE⏳ [进度]$NC 3/7 - 备份原始配置..."
Copy-Item $configPath $backupPath -ErrorAction Stop
# 验证备份是否成功
@ -902,7 +914,7 @@ function Modify-MachineCodeConfig {
$backupSize = (Get-Item $backupPath).Length
$originalSize = (Get-Item $configPath).Length
if ($backupSize -eq $originalSize) {
Write-Host "$GREEN✅ [进度]$NC 3/6 - 配置备份成功: $backupName"
Write-Host "$GREEN✅ [进度]$NC 3/7 - 配置备份成功: $backupName"
} else {
Write-Host "$YELLOW⚠️ [警告]$NC 备份文件大小不匹配,但继续执行"
}
@ -910,20 +922,23 @@ function Modify-MachineCodeConfig {
throw "备份文件创建失败"
}
Write-Host "$BLUE⏳ [进度]$NC 4/6 - 读取原始配置到内存..."
Write-Host "$BLUE⏳ [进度]$NC 4/7 - 读取原始配置到内存..."
# 原子性操作:读取原始内容到内存
$originalContent = Get-Content $configPath -Raw -Encoding UTF8 -ErrorAction Stop
$config = $originalContent | ConvertFrom-Json -ErrorAction Stop
Write-Host "$BLUE⏳ [进度]$NC 5/6 - 在内存中更新配置..."
Write-Host "$BLUE⏳ [进度]$NC 5/7 - 在内存中更新配置..."
# 更新配置值(安全方式,确保属性存在)
# 🔧 修复: 添加 storage.serviceMachineId 和 telemetry.firstSessionDate
$propertiesToUpdate = @{
'telemetry.machineId' = $MACHINE_ID
'telemetry.macMachineId' = $MAC_MACHINE_ID
'telemetry.devDeviceId' = $UUID
'telemetry.sqmId' = $SQM_ID
'storage.serviceMachineId' = $SERVICE_MACHINE_ID
'telemetry.firstSessionDate' = $FIRST_SESSION_DATE
}
foreach ($property in $propertiesToUpdate.GetEnumerator()) {
@ -942,7 +957,7 @@ function Modify-MachineCodeConfig {
}
}
Write-Host "$BLUE⏳ [进度]$NC 6/6 - 原子性写入新配置文件..."
Write-Host "$BLUE⏳ [进度]$NC 6/7 - 原子性写入新配置文件..."
# 原子性操作:删除原文件,写入新文件
$tempPath = "$configPath.tmp"
@ -983,7 +998,7 @@ function Modify-MachineCodeConfig {
$file.IsReadOnly = $false # 保持可写,便于后续修改
# 最终验证修改结果
Write-Host "$BLUE🔍 [最终验证]$NC 验证新配置文件..."
Write-Host "$BLUE⏳ [进度]$NC 7/7 - 验证新配置文件..."
$verifyContent = Get-Content $configPath -Raw -Encoding UTF8
$verifyConfig = $verifyContent | ConvertFrom-Json
@ -1020,9 +1035,58 @@ function Modify-MachineCodeConfig {
Write-Host " 🔹 macMachineId: $MAC_MACHINE_ID"
Write-Host " 🔹 devDeviceId: $UUID"
Write-Host " 🔹 sqmId: $SQM_ID"
Write-Host " 🔹 serviceMachineId: $SERVICE_MACHINE_ID"
Write-Host " 🔹 firstSessionDate: $FIRST_SESSION_DATE"
Write-Host ""
Write-Host "$GREEN💾 [备份]$NC 原配置已备份至: $backupName"
# 🔧 新增: 修改 machineid 文件
Write-Host "$BLUE🔧 [machineid]$NC 正在修改 machineid 文件..."
$machineIdFilePath = "$env:APPDATA\Cursor\machineid"
try {
if (Test-Path $machineIdFilePath) {
# 备份原始 machineid 文件
$machineIdBackup = "$backupDir\machineid.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
Copy-Item $machineIdFilePath $machineIdBackup -Force
Write-Host "$GREEN💾 [备份]$NC machineid 文件已备份: $machineIdBackup"
}
# 写入新的 serviceMachineId 到 machineid 文件
[System.IO.File]::WriteAllText($machineIdFilePath, $SERVICE_MACHINE_ID, [System.Text.Encoding]::UTF8)
Write-Host "$GREEN✅ [machineid]$NC machineid 文件修改成功: $SERVICE_MACHINE_ID"
# 设置 machineid 文件为只读
$machineIdFile = Get-Item $machineIdFilePath
$machineIdFile.IsReadOnly = $true
Write-Host "$GREEN🔒 [保护]$NC machineid 文件已设置为只读"
} catch {
Write-Host "$YELLOW⚠️ [machineid]$NC machineid 文件修改失败: $($_.Exception.Message)"
Write-Host "$BLUE💡 [提示]$NC 可手动修改文件: $machineIdFilePath"
}
# 🔧 新增: 修改 .updaterId 文件(更新器设备标识符)
Write-Host "$BLUE🔧 [updaterId]$NC 正在修改 .updaterId 文件..."
$updaterIdFilePath = "$env:APPDATA\Cursor\.updaterId"
try {
if (Test-Path $updaterIdFilePath) {
# 备份原始 .updaterId 文件
$updaterIdBackup = "$backupDir\.updaterId.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
Copy-Item $updaterIdFilePath $updaterIdBackup -Force
Write-Host "$GREEN💾 [备份]$NC .updaterId 文件已备份: $updaterIdBackup"
}
# 生成新的 updaterId(UUID格式)
$newUpdaterId = [System.Guid]::NewGuid().ToString()
[System.IO.File]::WriteAllText($updaterIdFilePath, $newUpdaterId, [System.Text.Encoding]::UTF8)
Write-Host "$GREEN✅ [updaterId]$NC .updaterId 文件修改成功: $newUpdaterId"
# 设置 .updaterId 文件为只读
$updaterIdFile = Get-Item $updaterIdFilePath
$updaterIdFile.IsReadOnly = $true
Write-Host "$GREEN🔒 [保护]$NC .updaterId 文件已设置为只读"
} catch {
Write-Host "$YELLOW⚠️ [updaterId]$NC .updaterId 文件修改失败: $($_.Exception.Message)"
Write-Host "$BLUE💡 [提示]$NC 可手动修改文件: $updaterIdFilePath"
}
# 🔒 添加配置文件保护机制
Write-Host "$BLUE🔒 [保护]$NC 正在设置配置文件保护..."
try {

Loading…
Cancel
Save