From 2e1734f5eaf79428564492c6910bdec39acad061 Mon Sep 17 00:00:00 2001 From: "Satur@it-depot.ru" Date: Tue, 11 Mar 2025 11:10:52 +0300 Subject: [PATCH] unmovable.fix --- app.py | 628 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 384 insertions(+), 244 deletions(-) diff --git a/app.py b/app.py index 3537b19..ccde2f8 100644 --- a/app.py +++ b/app.py @@ -1,266 +1,406 @@ -$ErrorActionPreference = 'silentlycontinue' +from fastapi import FastAPI, HTTPException, File, UploadFile, Form, Query, WebSocket, WebSocketDisconnect +from pydantic import BaseModel +import sqlite3 +import datetime +import csv +import markdown +from fastapi.staticfiles import StaticFiles +from fastapi.responses import FileResponse, StreamingResponse +import io +import os +from fastapi.middleware.cors import CORSMiddleware +from werkzeug.utils import secure_filename +import json -# Формируем пароль из зашифрованных частей -$p1 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("cDk4")) -$p2 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("Nng=")) -$p3 = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("Yjc4")) -$rustdesk_pw = $p1 + $p2 + $p3 +# Создаем два экземпляра FastAPI +web_app = FastAPI(title="Web Interface") # Для веб-интерфейса (порт 8001) +api_app = FastAPI(title="API Endpoints") # Для API (порт 8002) -# Get your config string from your Web portal and Fill Below -$rustdesk_cfg = "0nI1JnL09GclRWL0lmL0NXdy9yL6MHc0RHaiojIpBXYiwiI9gjYwBjbXVERFRXZiNEVYBjRGdHUZhUUvBVRx52dWlmenlTY6t0U1IlMLhlI6ISeltmIsISdy5CdvBXZk1Cdp5CdzVnciojI5FGblJnIsISdy5CdvBXZk1Cdp5CdzVnciojI0N3boJye" +# Общий код для подключения к базе данных +conn = sqlite3.connect("/db/rustdesk.db", check_same_thread=False) +cursor = conn.cursor() -################################### Please Do Not Edit Below This Line ######################################### +# Проверяем и обновляем структуру таблицы installs +cursor.execute("PRAGMA table_info(installs)") +columns = [row[1] for row in cursor.fetchall()] +if 'protocol' not in columns: + cursor.execute("ALTER TABLE installs ADD COLUMN protocol TEXT DEFAULT 'rustdesk'") + conn.commit() +if 'note' not in columns: + cursor.execute("ALTER TABLE installs ADD COLUMN note TEXT DEFAULT ''") + conn.commit() +if 'last_seen' not in columns: + cursor.execute("ALTER TABLE installs ADD COLUMN last_seen TEXT DEFAULT NULL") + conn.commit() -# Run as administrator and stays in the current directory -if (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { - if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) { - Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`""; - Exit; +# Создаем таблицы +cursor.execute(""" +CREATE TABLE IF NOT EXISTS folders ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + parent_id INTEGER, + FOREIGN KEY (parent_id) REFERENCES folders(id) +) +""") +cursor.execute(""" +CREATE TABLE IF NOT EXISTS installs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + rust_id TEXT, + computer_name TEXT, + install_time TEXT, + folder_id INTEGER, + protocol TEXT DEFAULT 'rustdesk', + note TEXT DEFAULT '', + last_seen TEXT DEFAULT NULL, + FOREIGN KEY (folder_id) REFERENCES folders(id) +) +""") +conn.commit() + +# Проверяем/создаем папку "Несортированные" и получаем её ID +cursor.execute("SELECT id FROM folders WHERE name = 'Несортированные'") +unsorted_folder = cursor.fetchone() +if not unsorted_folder: + cursor.execute("INSERT INTO folders (name) VALUES ('Несортированные')") + conn.commit() + unsorted_folder_id = cursor.lastrowid +else: + unsorted_folder_id = unsorted_folder[0] + +# Папка для загрузки изображений +UPLOAD_FOLDER = "/app/uploads" +if not os.path.exists(UPLOAD_FOLDER): + os.makedirs(UPLOAD_FOLDER) + +# Монтируем папку uploads для доступа к изображениям +api_app.mount("/uploads", StaticFiles(directory=UPLOAD_FOLDER), name="uploads") +web_app.mount("/uploads", StaticFiles(directory=UPLOAD_FOLDER), name="uploads") + +# Модели данных +class Folder(BaseModel): + name: str + parent_id: int | None = None + +class FolderUpdate(BaseModel): + name: str + +class InstallData(BaseModel): + rust_id: str | None = None + computer_name: str | None = None + install_time: str | None = None + folder_id: int | None = None + protocol: str | None = 'rustdesk' + note: str | None = '' + last_seen: str | None = None + +# Функция форматирования времени +def format_time(time_str): + if not time_str: + return None + try: + dt = datetime.datetime.strptime(time_str, "%Y-%m-%dT%H:%M:%S.%fZ") + return dt.strftime("%Y-%m-%d %H:%M:%S") + except ValueError: + try: + dt = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S") + return dt.strftime("%Y-%m-%d %H:%M:%S") + except ValueError: + return time_str + +# Монтируем папки templates и icons +web_app.mount("/templates", StaticFiles(directory="templates"), name="templates") +web_app.mount("/icons", StaticFiles(directory="templates/icons"), name="icons") + +# Веб-интерфейс +@web_app.get("/") +async def root(): + return FileResponse("templates/index.html") + +# WebSocket для отправки обновлений статуса +class ConnectionManager: + def __init__(self): + self.active_connections: list[WebSocket] = [] + self.max_connections = 100 # Ограничение числа подключений + + async def connect(self, websocket: WebSocket): + if len(self.active_connections) >= self.max_connections: + await websocket.close(code=1008, reason="Too many connections") + return + await websocket.accept() + self.active_connections.append(websocket) + + def disconnect(self, websocket: WebSocket): + self.active_connections.remove(websocket) + + async def broadcast(self, message: str): + for connection in self.active_connections[:]: # Копируем список для безопасного удаления + await connection.send_text(message) + +manager = ConnectionManager() + +@api_app.websocket("/ws") +async def websocket_endpoint(websocket: WebSocket): + await manager.connect(websocket) + try: + while True: + data = await websocket.receive_text() + except WebSocketDisconnect: + manager.disconnect(websocket) + +# API-эндпоинты +@api_app.get("/api/folders") +def get_folders(): + cursor.execute("SELECT * FROM folders") + rows = cursor.fetchall() + return [{"id": row[0], "name": row[1], "parent_id": row[2]} for row in rows] + +@api_app.post("/api/folders") +def add_folder(folder: Folder): + cursor.execute("INSERT INTO folders (name, parent_id) VALUES (?, ?)", + (folder.name, folder.parent_id)) + conn.commit() + return {"status": "success", "id": cursor.lastrowid} + +@api_app.put("/api/folders/{folder_id}") +def update_folder(folder_id: int, folder: FolderUpdate): + cursor.execute("UPDATE folders SET name = ? WHERE id = ?", (folder.name, folder_id)) + conn.commit() + if cursor.rowcount == 0: + raise HTTPException(status_code=404, detail="Папка не найдена") + return {"status": "success"} + +@api_app.delete("/api/folders/{folder_id}") +def delete_folder(folder_id: int): + cursor.execute("SELECT name FROM folders WHERE id = ?", (folder_id,)) + folder_name = cursor.fetchone() + if folder_name and folder_name[0] == 'Несортированные': + raise HTTPException(status_code=403, detail="Папка 'Несортированные' не может быть удалена") + + cursor.execute("DELETE FROM folders WHERE id = ?", (folder_id,)) + conn.commit() + if cursor.rowcount == 0: + raise HTTPException(status_code=404, detail="Папка не найдена") + return {"status": "success"} + +@api_app.get("/api/installs") +def get_installs(): + cursor.execute(""" + SELECT i.id, i.rust_id, i.computer_name, i.install_time, i.folder_id, f.name as folder_name, i.protocol, i.note, i.last_seen + FROM installs i + LEFT JOIN folders f ON i.folder_id = f.id + """) + rows = cursor.fetchall() + return [{"id": row[0], "rust_id": row[1], "computer_name": row[2], + "install_time": format_time(row[3]), + "folder_id": row[4], "folder_name": row[5], "protocol": row[6], "note": row[7], "last_seen": row[8]} + for row in rows] + +@api_app.post("/api/install") +async def add_install(data: InstallData): + rust_id = data.rust_id + computer_name = data.computer_name or f"PC_{rust_id}" + install_time = data.install_time or datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + protocol = data.protocol or 'rustdesk' + note = data.note or '' + last_seen = data.last_seen or datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + # Проверяем, существует ли запись с таким rust_id + cursor.execute("SELECT id, folder_id, protocol, note FROM installs WHERE rust_id = ?", (rust_id,)) + existing = cursor.fetchone() + + if existing: + # Если запись существует, используем текущий folder_id из базы данных + current_folder_id = existing[1] # Текущий folder_id + current_protocol = existing[2] # Текущий protocol + current_note = existing[3] # Текущая заметка + + # Обновляем запись, сохраняя существующий folder_id + cursor.execute(""" + UPDATE installs + SET computer_name = ?, install_time = ?, protocol = ?, note = ?, last_seen = ? + WHERE rust_id = ? + """, (computer_name, install_time, current_protocol, current_note, last_seen, rust_id)) + else: + # Если записи нет, создаем новую, используя folder_id из запроса или "Несортированные" + folder_id = data.folder_id if data.folder_id is not None else unsorted_folder_id + cursor.execute(""" + INSERT INTO installs (rust_id, computer_name, install_time, folder_id, protocol, note, last_seen) + VALUES (?, ?, ?, ?, ?, ?, ?) + """, (rust_id, computer_name, install_time, folder_id, protocol, note, last_seen)) + + conn.commit() + + # Получаем обновленную запись для отправки через WebSocket + cursor.execute(""" + SELECT id, rust_id, computer_name, install_time, folder_id, protocol, note, last_seen + FROM installs WHERE rust_id = ? + """, (rust_id,)) + updated_install = cursor.fetchone() + install_data = { + "id": updated_install[0], + "rust_id": updated_install[1], + "computer_name": updated_install[2], + "install_time": format_time(updated_install[3]), + "folder_id": updated_install[4], # Используем folder_id из базы + "protocol": updated_install[5], + "note": updated_install[6], + "last_seen": updated_install[7] } -} + # Отправляем обновленную запись через WebSocket + await manager.broadcast(json.dumps({"type": "update", "data": install_data})) -# Проверка наличия установленного RustDesk -$rustdeskInstalled = Test-Path "$env:ProgramFiles\RustDesk\rustdesk.exe" -$rdver = ((Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RustDesk\" -ErrorAction SilentlyContinue).Version) + return {"status": "success"} -if ($rustdeskInstalled -and $rdver) { - echo "RustDesk $rdver is already installed. Importing configuration..." - cd $env:ProgramFiles\RustDesk - .\rustdesk.exe --config $rustdesk_cfg - .\rustdesk.exe --password $rustdesk_pw -} else { - $localRustDesk = Join-Path $PSScriptRoot "rustdesk.exe" - $rustdeskExistsLocally = Test-Path $localRustDesk +@api_app.put("/api/install/{install_id}") +def update_install(install_id: int, data: InstallData): + cursor.execute("SELECT rust_id, computer_name, install_time, folder_id, protocol, note FROM installs WHERE id = ?", (install_id,)) + current = cursor.fetchone() + if not current: + raise HTTPException(status_code=404, detail="Запись не найдена") + + new_rust_id = data.rust_id if data.rust_id is not None else current[0] + new_computer_name = data.computer_name if data.computer_name is not None else current[1] + new_install_time = data.install_time if data.install_time is not None else current[2] + new_folder_id = data.folder_id if data.folder_id is not None else current[3] + new_protocol = data.protocol if data.protocol is not None else current[4] + new_note = data.note if data.note is not None else current[5] - if (-not $rustdeskExistsLocally) { - $url = 'https://www.github.com//rustdesk/rustdesk/releases/latest' - $request = [System.Net.WebRequest]::Create($url) - $response = $request.GetResponse() - $realTagUrl = $response.ResponseUri.OriginalString - $RDLATEST = $realTagUrl.split('/')[-1].Trim('v') - echo "RustDesk $RDLATEST is the latest version." - } else { - $RDLATEST = "local" + if new_install_time: + try: + datetime.datetime.strptime(new_install_time, "%Y-%m-%d %H:%M:%S") + except ValueError: + raise HTTPException(status_code=400, detail="Неверный формат времени. Используйте YYYY-MM-DD HH:MM:SS") + else: + new_install_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + cursor.execute(""" + UPDATE installs + SET rust_id = ?, computer_name = ?, install_time = ?, folder_id = ?, protocol = ?, note = ? + WHERE id = ? + """, (new_rust_id, new_computer_name, new_install_time, new_folder_id, new_protocol, new_note, install_id)) + conn.commit() + return {"status": "success"} + +@api_app.delete("/api/install/{install_id}") +def delete_install(install_id: int): + cursor.execute("DELETE FROM installs WHERE id = ?", (install_id,)) + conn.commit() + if cursor.rowcount == 0: + raise HTTPException(status_code=404, detail="Запись не найдена") + return {"status": "success"} + +@api_app.get("/api/export/csv") +async def export_csv(folder_id: int | None = Query(None, description="ID папки для экспорта, если None - экспортировать все папки")): + if folder_id: + cursor.execute(""" + SELECT i.rust_id, i.computer_name, i.install_time, f.name as folder_name, i.protocol, i.note, i.last_seen + FROM installs i + LEFT JOIN folders f ON i.folder_id = f.id + WHERE i.folder_id = ? + """, (folder_id,)) + else: + cursor.execute(""" + SELECT i.rust_id, i.computer_name, i.install_time, f.name as folder_name, i.protocol, i.note, i.last_seen + FROM installs i + LEFT JOIN folders f ON i.folder_id = f.id + """) + rows = cursor.fetchall() + + output = io.StringIO() + writer = csv.writer(output, lineterminator='\n') + writer.writerow(['ID подключения', 'Имя компьютера', 'Время установки', 'Папка', 'Протокол', 'Заметка', 'Последнее подключение']) + for row in rows: + install_time = format_time(row[2]) if row[2] else "" + last_seen = format_time(row[6]) if row[6] else "" + writer.writerow([row[0], row[1], install_time, row[3], row[4], row[5], last_seen]) + + headers = { + 'Content-Disposition': 'attachment; filename="rustdesk_data.csv"', + 'Content-Type': 'text/csv' } + return StreamingResponse(iter([output.getvalue()]), headers=headers) - if (!(Test-Path C:\ProgramData\RustDesk)) { - New-Item -ItemType Directory -Force -Path C:\ProgramData\RustDesk > null - } +@api_app.post("/api/import/csv") +async def import_csv(file: UploadFile = File(...), folder_id: int | None = Query(None, description="ID папки для импорта, если None - использовать 'Несортированные'")): + try: + contents = await file.read() + csv_data = io.StringIO(contents.decode('utf-8')) + reader = csv.DictReader(csv_data) - cd C:\ProgramData\RustDesk + target_folder_id = folder_id if folder_id is not None else unsorted_folder_id - if ($rustdeskExistsLocally) { - echo "Found local rustdesk.exe, using it for installation." - Copy-Item -Path $localRustDesk -Destination ".\rustdesk.exe" -Force - } else { - echo "Downloading RustDesk version $RDLATEST." - powershell Invoke-WebRequest "https://github.com/rustdesk/rustdesk/releases/download/$RDLATEST/rustdesk-$RDLATEST-x86_64.exe" -Outfile "rustdesk.exe" - } + for row in reader: + rust_id = row['ID подключения'] + computer_name = row['Имя компьютера'] + install_time = row['Время установки'] + folder_name = row.get('Папка', None) + protocol = row.get('Протокол', 'rustdesk') + note = row.get('Заметка', '') - echo "Installing RustDesk." - Start-Process .\rustdesk.exe --silent-install - Start-Sleep -Seconds 10 + cursor.execute("SELECT id FROM installs WHERE rust_id = ?", (rust_id,)) + if cursor.fetchone(): + continue - $ServiceName = 'rustdesk' - $arrService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue + if install_time: + try: + dt = datetime.datetime.strptime(install_time, "%Y-%m-%d %H:%M:%S") + install_time = dt.strftime("%Y-%m-%d %H:%M:%S") + except ValueError: + try: + dt = datetime.datetime.strptime(install_time, "%Y-%m-%dT%H:%M:%S.%fZ") + install_time = dt.strftime("%Y-%m-%d %H:%M:%S") + except ValueError: + raise HTTPException(status_code=400, detail=f"Неверный формат времени для записи с ID {rust_id}. Используйте YYYY-MM-DD HH:MM:SS или ISO 8601") - if ($arrService -eq $null) { - echo "Installing service." - cd $env:ProgramFiles\RustDesk - Start-Process .\rustdesk.exe --install-service -wait -Verbose - Start-Sleep -Seconds 20 - } + if folder_name: + cursor.execute("SELECT id FROM folders WHERE name = ?", (folder_name,)) + folder = cursor.fetchone() + folder_id = folder[0] if folder else unsorted_folder_id + else: + folder_id = target_folder_id - while ($arrService.Status -ne 'Running') { - Start-Service $ServiceName - Start-Sleep -seconds 5 - $arrService.Refresh() - } + cursor.execute(""" + INSERT INTO installs (rust_id, computer_name, install_time, folder_id, protocol, note) + VALUES (?, ?, ?, ?, ?, ?) + """, (rust_id, computer_name, install_time, folder_id, protocol, note)) + + conn.commit() + return {"status": "success", "message": "Данные успешно импортированы"} + except Exception as e: + raise HTTPException(status_code=400, detail=f"Ошибка импорта: {str(e)}") - echo "Please wait a few seconds." - Start-Sleep -Seconds 10 - Remove-Item -Path "C:\ProgramData\RustDesk\rustdesk.exe" -Force - echo "Temporary installation files have been cleaned up." - cd $env:ProgramFiles\RustDesk - echo "Inputting configuration now." - .\rustdesk.exe --config $rustdesk_cfg - .\rustdesk.exe --password $rustdesk_pw -} +@api_app.post("/api/upload-image") +async def upload_image(install_id: int = Form(...), file: UploadFile = File(...)): + if not file.filename: + raise HTTPException(status_code=400, detail="No file provided") + + allowed_extensions = {'png', 'jpg', 'jpeg', 'gif'} + if not secure_filename(file.filename).rsplit('.', 1)[1].lower() in allowed_extensions: + raise HTTPException(status_code=400, detail="Invalid file format. Use png, jpg, jpeg, or gif") -# Добавляем папку RustDesk в исключения Windows Defender -$defenderPath = "C:\Program Files\RustDesk" -try { - Add-MpPreference -ExclusionPath $defenderPath -ErrorAction Stop - echo "Added $defenderPath to Windows Defender exclusions." -} catch { - echo "Failed to add $defenderPath to Windows Defender exclusions: $_" -} + filename = secure_filename(f"{install_id}_{file.filename}") + file_path = os.path.join(UPLOAD_FOLDER, filename) -# Удаляем ярлык с общего рабочего стола -$publicDesktop = "C:\Users\Public\Desktop\RustDesk.lnk" -if (Test-Path $publicDesktop) { - Remove-Item -Path $publicDesktop -Force - echo "Removed RustDesk shortcut from Public Desktop." -} + with open(file_path, "wb") as buffer: + buffer.write(await file.read()) -# Создаем папку RustDesk в меню Пуск под Critical Fixes -$startMenuPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Critical Fixes\RustDesk" -if (!(Test-Path $startMenuPath)) { - New-Item -ItemType Directory -Force -Path $startMenuPath -} + url = f"/uploads/{filename}" + return {"url": url} -$shortcutPath = "$startMenuPath\RustDesk.lnk" -$shell = New-Object -ComObject WScript.Shell -$shortcut = $shell.CreateShortcut($shortcutPath) -$shortcut.TargetPath = "$env:ProgramFiles\RustDesk\rustdesk.exe" -$shortcut.Save() -echo "Created RustDesk shortcut in Start Menu under Critical Fixes\RustDesk." +# CORS для API +api_app.add_middleware( + CORSMiddleware, + allow_origins=["https://rd.it-depot.ru"], # Обновлено для HTTPS + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) -# Удаляем папку RustDesk из корня Programs -$rustDeskStartMenu = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\RustDesk" -if (Test-Path $rustDeskStartMenu) { - Remove-Item -Path $rustDeskStartMenu -Recurse -Force - echo "Removed RustDesk folder from Start Menu Programs." -} - -# Добавляем параметры в конфигурационные файлы -$configPath = "$env:USERPROFILE\AppData\Roaming\RustDesk\config" -$config2Path = "$configPath\RustDesk2.toml" -$configLocalPath = "$configPath\RustDesk_local.toml" - -if (!(Test-Path $configPath)) { - New-Item -ItemType Directory -Force -Path $configPath -} - -if (!(Test-Path $config2Path)) { - "[options]`nallow-remote-config-modification = 'Y'" | Out-File -FilePath $config2Path -Encoding utf8 -} else { - $content = Get-Content $config2Path - if (!($content -match "allow-remote-config-modification")) { - if ($content -match "\[options\]") { - $content = $content -replace "\[options\]", "[options]`nallow-remote-config-modification = 'Y'" - } else { - $content += "`n[options]`nallow-remote-config-modification = 'Y'" - } - $content | Out-File -FilePath $config2Path -Encoding utf8 - } -} - -if (!(Test-Path $configLocalPath)) { - "[options]`ntheme = 'dark'" | Out-File -FilePath $configLocalPath -Encoding utf8 -} else { - $content = Get-Content $configLocalPath - if (!($content -match "theme")) { - if ($content -match "\[options\]") { - $content = $content -replace "\[options\]", "[options]`ntheme = 'dark'" - } else { - $content += "`n[options]`ntheme = 'dark'" - } - $content | Out-File -FilePath $configLocalPath -Encoding utf8 - } -} - -# Создание BAT-файла для удаления -$uninstallBatPath = "$env:ProgramFiles\RustDesk\Uninstall RustDesk.bat" -$uninstallBatContent = @" -@echo off -echo Stopping RustDeskOnlineCheck task... -schtasks /End /TN "RustDeskOnlineCheck" -timeout /t 2 >nul -echo Deleting RustDeskOnlineCheck task... -schtasks /Delete /TN "RustDeskOnlineCheck" /F -echo Stopping RustDesk service... -sc stop rustdesk -timeout /t 2 >nul -echo Uninstalling RustDesk... -"C:\Program Files\RustDesk\rustdesk.exe" --uninstall -echo Cleaning up files... -rd /s /q "C:\ProgramData\RustDesk" -rd /s /q "%appdata%\RustDesk" -rd /s /q "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Critical Fixes\RustDesk" -echo Removing Windows Defender exclusion... -powershell -Command "Remove-MpPreference -ExclusionPath 'C:\Program Files\RustDesk'" 2>nul -echo RustDesk has been completely removed. -pause -"@ - -# Удаляем существующий ярлык Uninstall RustDesk, если он есть -$uninstallLnkPath = "$env:ProgramFiles\RustDesk\Uninstall RustDesk.lnk" -if (Test-Path $uninstallLnkPath) { - Remove-Item -Path $uninstallLnkPath -Force - echo "Removed original Uninstall RustDesk shortcut." -} - -# Создаем BAT-файл в папке RustDesk -$uninstallBatContent | Out-File -FilePath $uninstallBatPath -Encoding ASCII -echo "Created Uninstall RustDesk.bat in $env:ProgramFiles\RustDesk" - -# Копируем BAT-файл в Critical Fixes\RustDesk -Copy-Item -Path $uninstallBatPath -Destination "$startMenuPath\Uninstall RustDesk.bat" -Force -echo "Copied Uninstall RustDesk.bat to $startMenuPath" - -$rustdesk_id = .\rustdesk.exe --get-id | Write-Output -OutVariable rustdesk_id -echo "All done! Please double check the Network settings tab in RustDesk." -echo "" -echo "..............................................." -echo "RustDesk ID: $rustdesk_id" -$RustID = $rustdesk_id -$ComputerName = $env:COMPUTERNAME -$InstallTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss" - -$ServerURL = "https://rd.it-depot.ru/api/install" -$Body = @{ - "rust_id" = $RustID - "computer_name" = $ComputerName - "install_time" = $InstallTime -} | ConvertTo-Json -Compress - -Invoke-RestMethod -Uri $ServerURL -Method Post -Body $Body -ContentType "application/json" -echo "Initial entry added to address book." -echo "..............................................." -echo "" - -# Создание скрипта для проверки онлайн-статуса -$checkScriptPath = "C:\ProgramData\RustDesk\RustDeskOnlineCheck.ps1" -$checkScriptContent = @" -`$ErrorActionPreference = 'SilentlyContinue' -`$RustID = "$RustID" -`$ComputerName = "$ComputerName" -`$InstallTime = "$InstallTime" -`$ServerURL = "https://rd.it-depot.ru/api/install" - -while (`$true) { - `$Body = @{ - `"rust_id`" = `$RustID - `"computer_name`" = `$ComputerName - `"install_time`" = `$InstallTime - `"last_seen`" = (Get-Date -Format `"yyyy-MM-dd HH:mm:ss`") - } | ConvertTo-Json -Compress - try { - Invoke-RestMethod -Uri `$ServerURL -Method Post -Body `$Body -ContentType `"application/json`" -ErrorAction Stop - Write-Host "Online ping sent for ID `$RustID at `(Get-Date -Format 'HH:mm:ss')" -ForegroundColor Green - } - catch { - Write-Host "Error sending online ping: `$_" -ForegroundColor Red - } - Start-Sleep -Seconds 30 -} -"@ -$checkScriptContent | Out-File -FilePath $checkScriptPath -Encoding UTF8 -echo "Created online check script at $checkScriptPath" - -# Создание задания в Планировщике задач -$taskName = "RustDeskOnlineCheck" -$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$checkScriptPath`"" -$trigger = New-ScheduledTaskTrigger -AtStartup -$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable - -Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -User "SYSTEM" -RunLevel Highest -Force -echo "Scheduled task '$taskName' created to check online status at system startup." - -Start-ScheduledTask -TaskName $taskName -echo "Scheduled task '$taskName' has been started." - -echo "Press Enter to open RustDesk." -pause -.\rustdesk.exe \ No newline at end of file +# CORS для веб-интерфейса +web_app.add_middleware( + CORSMiddleware, + allow_origins=["https://rd.it-depot.ru"], # Обновлено для HTTPS + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) \ No newline at end of file