From 78e037c76340b192d94c9a17f8bcd4c6d6dc202b Mon Sep 17 00:00:00 2001 From: Bryan Gerlach Date: Sun, 11 Jan 2026 14:50:35 -0600 Subject: [PATCH] test input hiding --- .github/workflows/generator-windows.yml | 241 ++++++++++++------------ docker-compose.yml | 3 + rdgen/settings.py | 2 + rdgenerator/views.py | 103 +++++++--- requirements.txt | 2 +- setup.md | 4 + 6 files changed, 201 insertions(+), 154 deletions(-) diff --git a/.github/workflows/generator-windows.yml b/.github/workflows/generator-windows.yml index 205f65d..fa9261a 100644 --- a/.github/workflows/generator-windows.yml +++ b/.github/workflows/generator-windows.yml @@ -3,56 +3,16 @@ run-name: Custom Windows Client Generator on: workflow_dispatch: inputs: - server: - description: 'Rendezvous Server' + version: + description: 'version to buld' required: true default: '' type: string - key: - description: 'Public Key' + zip_url: + description: 'url to zip of json' required: true default: '' type: string - apiServer: - description: 'API Server' - required: true - default: '' - type: string - custom: - description: "Custom JSON" - required: true - default: '' - type: string - uuid: - description: "uuid of request" - required: true - default: '' - type: string - iconlink: - description: "icon link" - required: false - default: 'false' - type: string - logolink: - description: "logo link" - required: false - default: 'false' - type: string - appname: - description: "app name" - required: true - default: 'rustdesk' - type: string - filename: - description: "Filename" - required: true - default: 'rustdesk' - type: string - extras: - description: "extra inputs in json" - required: true - default: '{}' - type: string env: @@ -71,7 +31,7 @@ env: # vcpkg version: 2024.07.12 VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b" ARMV7_VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" - VERSION: "${{ fromJson(inputs.extras).version }}" + VERSION: "${{ inputs.version }}" NDK_VERSION: "r27c" #signing keys env variable checks ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}" @@ -85,7 +45,7 @@ jobs: generate-bridge: uses: ./.github/workflows/bridge.yml with: - version: ${{ fromJson(inputs.extras).version }} + version: ${{ inputs.version }} build-RustDeskTempTopMostWindow: uses: ./.github/workflows/third-party-RustDeskTempTopMostWindow.yml @@ -116,6 +76,37 @@ jobs: } # - { target: aarch64-pc-windows-msvc, os: windows-2022, arch: aarch64 } steps: + - name: Download ZIP + env: + ZIP_URL: ${{ github.event.inputs.zip_url }} + ZIP_PASS: ${{ secrets.ZIP_PASSWORD }} + run: | + curl -L -o secrets.zip "$ZIP_URL" + unzip -P "$ZIP_PASS" secrets.zip + + - name: Decrypt json + shell: python + run: | + import json, os + # Find the json file extracted from the zip + json_file = [f for f in os.listdir('.') if f.endswith('.json')][0] + with open(json_file) as f: + data = json.load(f) + + with open(os.environ['GITHUB_ENV'], 'a') as env_file: + for key, value in data.items(): + print(f"::add-mask::{value}") + env_file.write(f"{key}={value}\n") + + - name: Finalize and Cleanup zip/json + if: always() # Run even if previous steps fail + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ env.STATUS_URL }} + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ env.uuid }}"}' + - name: Export GitHub Actions cache environment variables uses: actions/github-script@v6 with: @@ -124,14 +115,14 @@ jobs: core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); - name: Set rdgen value - if: ${{ fromJson(inputs.extras).rdgen == 'true' }} + if: ${{ env.rdgen == 'true' }} run: | echo "STATUS_URL=${{ secrets.GENURL }}/updategh" >> $env:GITHUB_ENV - name: Set rdgen value - if: ${{ fromJson(inputs.extras).rdgen == 'false' }} + if: ${{ env.rdgen == 'false' }} run: | - echo "STATUS_URL=${{ inputs.apiServer }}/api/updategh" >> $env:GITHUB_ENV + echo "STATUS_URL=${{ env.apiServer }}/api/updategh" >> $env:GITHUB_ENV - name: Report Status uses: fjogeleit/http-request-action@v1 @@ -140,7 +131,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "5% complete"}' + data: '{"uuid": "${{ env.uuid }}", "status": "5% complete"}' - name: Checkout source code if: ${{ env.VERSION != 'master' }} @@ -175,34 +166,34 @@ jobs: sed -i -e 's|2ded7f146437a761ffe6981e2f742038f85ca68d|08a471bb8ceccdd50483c81cdfa8b81b07b14b87|' ./flutter/pubspec.yaml - name: change appname to custom - if: inputs.appname != 'rustdesk' + if: env.appname != 'rustdesk' continue-on-error: true shell: bash run: | # ./Cargo.toml - sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml - sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml - sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml - sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ env.appname }}"|' ./Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ env.appname }}"|' ./Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ env.appname }}"|' ./Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ env.appname }}.exe"|' ./Cargo.toml # ./libs/portable/Cargo.toml - sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml - sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml - sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml - sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ env.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ env.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ env.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ env.appname }}.exe"|' ./libs/portable/Cargo.toml # ./flutter/windows/runner/Runner.rc - sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc - sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc - sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc - sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"RustDesk Remote Desktop"|"${{ env.appname }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ env.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"rustdesk.exe"|"${{ env.filename }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"RustDesk"|"${{ env.appname }}"|' ./flutter/windows/runner/Runner.rc # ./src/lang/en.rs # change powered by rustdek to powered by compname - if [ ! -z "${{ fromJson(inputs.extras).compname }}" ]; then - find ./src/lang -name "*.rs" -exec sed -i '/powered_by_me/s|RustDesk|${{ fromJson(inputs.extras).compname }}|g' {} \; + if [ ! -z "${{ env.compname }}" ]; then + find ./src/lang -name "*.rs" -exec sed -i '/powered_by_me/s|RustDesk|${{ env.compname }}|g' {} \; fi - find ./src/lang -name "*.rs" -exec sed -i -e 's|RustDesk|${{ inputs.appname }}|' {} \; + find ./src/lang -name "*.rs" -exec sed -i -e 's|RustDesk|${{ env.appname }}|' {} \; - name: fix registry if appname has a space - if: contains(inputs.appname, ' ') + if: contains(env.appname, ' ') continue-on-error: true shell: bash run: | @@ -222,47 +213,47 @@ jobs: sed -i -e 's|reg delete HKEY_CLASSES_ROOT\\\\{ext} /f|reg delete \\\"HKEY_CLASSES_ROOT\\\\{ext}\\\" /f|' ./src/platform/windows.rs - name: change company name - if: fromJson(inputs.extras).compname != 'Purslane Ltd' + if: env.compname != 'Purslane Ltd' continue-on-error: true shell: bash run: | - sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./flutter/lib/desktop/pages/desktop_setting_page.dart - sed -i -e 's|PURSLANE|${{ fromJson(inputs.extras).compname }}|' ./res/msi/preprocess.py - sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./res/msi/preprocess.py - sed -i -e 's|"Copyright © 2025 Purslane Ltd. All rights reserved."|"Copyright © 2025 ${{ fromJson(inputs.extras).compname }}. All rights reserved."|' ./flutter/windows/runner/Runner.rc - sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./flutter/windows/runner/Runner.rc - sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./Cargo.toml - sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./libs/portable/Cargo.toml + sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./flutter/lib/desktop/pages/desktop_setting_page.dart + sed -i -e 's|PURSLANE|${{ env.compname }}|' ./res/msi/preprocess.py + sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./res/msi/preprocess.py + sed -i -e 's|"Copyright © 2025 Purslane Ltd. All rights reserved."|"Copyright © 2025 ${{ env.compname }}. All rights reserved."|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./Cargo.toml + sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./libs/portable/Cargo.toml - name: change url to custom - if: fromJson(inputs.extras).urlLink != 'https://rustdesk.com' + if: env.urlLink != 'https://rustdesk.com' continue-on-error: true shell: bash run: | - sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py - sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart - sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart - sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/desktop/pages/desktop_setting_page.dart - sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart - sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/mobile/pages/settings_page.dart - sed -i -e "s|https://rustdesk.com/privacy.html|${{ fromJson(inputs.extras).urlLink }}/privacy.html|" ./flutter/lib/desktop/pages/install_page.dart + sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ env.urlLink }}|' ./build.py + sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ env.urlLink }}'));|" ./flutter/lib/common.dart + sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ env.urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart + sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ env.urlLink }}/privacy.html')|" ./flutter/lib/desktop/pages/desktop_setting_page.dart + sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ env.urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart + sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ env.urlLink }}/privacy.html')|" ./flutter/lib/mobile/pages/settings_page.dart + sed -i -e "s|https://rustdesk.com/privacy.html|${{ env.urlLink }}/privacy.html|" ./flutter/lib/desktop/pages/install_page.dart - name: change download link to custom - if: fromJson(inputs.extras).downloadLink != 'https://rustdesk.com/download' + if: env.downloadLink != 'https://rustdesk.com/download' continue-on-error: true shell: bash run: | - sed -i -e 's|https://rustdesk.com/download|${{ fromJson(inputs.extras).downloadLink }}|' ./flutter/lib/desktop/pages/desktop_home_page.dart - sed -i -e 's|https://rustdesk.com/download|${{ fromJson(inputs.extras).downloadLink }}|' ./flutter/lib/mobile/pages/connection_page.dart - sed -i -e 's|https://rustdesk.com/download|${{ fromJson(inputs.extras).downloadLink }}|' ./src/ui/index.tis + sed -i -e 's|https://rustdesk.com/download|${{ env.downloadLink }}|' ./flutter/lib/desktop/pages/desktop_home_page.dart + sed -i -e 's|https://rustdesk.com/download|${{ env.downloadLink }}|' ./flutter/lib/mobile/pages/connection_page.dart + sed -i -e 's|https://rustdesk.com/download|${{ env.downloadLink }}|' ./src/ui/index.tis - name: set server, key, and apiserver continue-on-error: true shell: bash run: | - sed -i -e 's|rs-ny.rustdesk.com|${{ inputs.server }}|' ./libs/hbb_common/src/config.rs - sed -i -e 's|OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=|${{ inputs.key }}|' ./libs/hbb_common/src/config.rs - sed -i -e 's|https://admin.rustdesk.com|${{ inputs.apiServer }}|' ./src/common.rs + sed -i -e 's|rs-ny.rustdesk.com|${{ env.server }}|' ./libs/hbb_common/src/config.rs + sed -i -e 's|OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=|${{ env.key }}|' ./libs/hbb_common/src/config.rs + sed -i -e 's|https://admin.rustdesk.com|${{ env.apiServer }}|' ./src/common.rs # ./flutter/pubspec.yaml #sed -i '/intl:/a \ \ archive: ^3.6.1' ./flutter/pubspec.yaml @@ -287,7 +278,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "10% complete"}' + data: '{"uuid": "${{ env.uuid }}", "status": "10% complete"}' - name: Install flutter uses: subosito/flutter-action@v2.12.0 #https://github.com/subosito/flutter-action/issues/277 @@ -325,7 +316,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "15% complete"}' + data: '{"uuid": "${{ env.uuid }}", "status": "15% complete"}' - uses: Swatinem/rust-cache@v2 with: @@ -338,7 +329,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "20% complete"}' + data: '{"uuid": "${{ env.uuid }}", "status": "20% complete"}' - name: Setup vcpkg with Github Actions binary cache uses: lukka/run-vcpkg@v11 @@ -368,10 +359,10 @@ jobs: shell: bash - name: magick stuff - if: ${{ inputs.iconlink != 'false' }} + if: ${{ env.iconlink != 'false' }} continue-on-error: true run: | - Invoke-WebRequest -Uri ${{ fromJson(inputs.iconlink).url }}/get_png?filename=${{ fromJson(inputs.iconlink).file }}"&"uuid=${{ fromJson(inputs.iconlink).uuid }} -OutFile ./res/iconx.png + Invoke-WebRequest -Uri ${{ fromJson(env.iconlink).url }}/get_png?filename=${{ fromJson(env.iconlink).file }}"&"uuid=${{ fromJson(env.iconlink).uuid }} -OutFile ./res/iconx.png mv ./res/icon.ico ./res/icon.ico.bak mv ./res/icon.png ./res/icon.png.bak mv ./res/tray-icon.ico ./res/tray-icon.ico.bak @@ -389,7 +380,7 @@ jobs: - name: ui.rs icon - if: ${{ inputs.iconlink != 'false' }} + if: ${{ env.iconlink != 'false' }} continue-on-error: true shell: bash run: | @@ -400,28 +391,28 @@ jobs: - name: fix connection delay continue-on-error: true - if: ${{ fromJson(inputs.extras).delayFix == 'true' }} + if: ${{ env.delayFix == 'true' }} shell: bash run: | sed -i -e 's|!key.is_empty()|false|' ./src/client.rs - name: add cycle monitors to toolbar continue-on-error: true - if: fromJson(inputs.extras).cycleMonitor == 'true' + if: env.cycleMonitor == 'true' run: | Invoke-WebRequest -Uri https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/cycle_monitor.diff -OutFile cycle_monitor.diff git apply cycle_monitor.diff - name: use X for offline display instead of orange circle continue-on-error: true - if: fromJson(inputs.extras).xOffline == 'true' + if: env.xOffline == 'true' run: | Invoke-WebRequest -Uri https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/xoffline.diff -OutFile xoffline.diff git apply xoffline.diff - name: removeNewVersionNotif continue-on-error: true - if: fromJson(inputs.extras).removeNewVersionNotif == 'true' + if: env.removeNewVersionNotif == 'true' shell: bash run: | sed -i -e 's|updateUrl.isNotEmpty|false|' ./flutter/lib/desktop/pages/desktop_home_page.dart @@ -429,7 +420,7 @@ jobs: # - name: run as admin # continue-on-error: true - # if: ${{ fromJson(inputs.extras).runasadmin == 'true' }} + # if: ${{ env.runasadmin == 'true' }} # shell: bash # run: | # sed -i '/<\/compatibility>/a \ @@ -444,10 +435,10 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "25% complete"}' + data: '{"uuid": "${{ env.uuid }}", "status": "25% complete"}' - name: replace flutter icons - if: ${{ inputs.iconlink != 'false' }} + if: ${{ env.iconlink != 'false' }} continue-on-error: true run: | cd ./flutter @@ -463,7 +454,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "50% complete, this step takes about 5 minutes, be patient."}' + data: '{"uuid": "${{ env.uuid }}", "status": "50% complete, this step takes about 5 minutes, be patient."}' - name: Build rustdesk run: | @@ -506,17 +497,17 @@ jobs: } - name: icon stuff - if: ${{ inputs.iconlink != 'false' }} + if: ${{ env.iconlink != 'false' }} continue-on-error: true run: | mv ./rustdesk/data/flutter_assets/assets/icon.svg ./rustdesk/data/flutter_assets/assets/icon.svg.bak magick ./res/icon.png ./rustdesk/data/flutter_assets/assets/icon.svg - name: logo stuff - if: ${{ inputs.logolink != 'false' }} + if: ${{ env.logolink != 'false' }} continue-on-error: true run: | - Invoke-WebRequest -Uri ${{ fromJson(inputs.logolink).url }}/get_png?filename=${{ fromJson(inputs.logolink).file }}"&"uuid=${{ fromJson(inputs.logolink).uuid }} -OutFile ./rustdesk/data/flutter_assets/assets/logo.png + Invoke-WebRequest -Uri ${{ fromJson(env.logolink).url }}/get_png?filename=${{ fromJson(env.logolink).file }}"&"uuid=${{ fromJson(env.logolink).uuid }} -OutFile ./rustdesk/data/flutter_assets/assets/logo.png - name: find Runner.res # Windows: find Runner.res (compiled from ./flutter/windows/runner/Runner.rc), copy to ./Runner.res @@ -548,7 +539,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "70% complete, this step takes about 5 minutes, be patient."}' + data: '{"uuid": "${{ env.uuid }}", "status": "70% complete, this step takes about 5 minutes, be patient."}' - name: zip dlls continue-on-error: true @@ -581,17 +572,17 @@ jobs: - name: Create custom.txt file shell: bash run: | - echo -n "${{ inputs.custom }}" | cat > ./rustdesk/custom_.txt + echo -n "${{ env.custom }}" | cat > ./rustdesk/custom_.txt - name: Build self-extracted executable shell: bash if: env.UPLOAD_ARTIFACT == 'true' run: | - mv "./rustdesk/rustdesk.exe" "./rustdesk/${{ inputs.appname }}.exe" || echo "rustdesk.exe" + mv "./rustdesk/rustdesk.exe" "./rustdesk/${{ env.appname }}.exe" || echo "rustdesk.exe" sed -i '/dpiAware/d' res/manifest.xml pushd ./libs/portable pip3 install -r requirements.txt - python3 ./generate.py -f ../../rustdesk/ -o . -e "../../rustdesk/${{ inputs.appname }}.exe" + python3 ./generate.py -f ../../rustdesk/ -o . -e "../../rustdesk/${{ env.appname }}.exe" popd mkdir -p ./SignOutput mv ./target/release/rustdesk-portable-packer.exe "./SignOutput/rustdesk.exe" @@ -603,8 +594,8 @@ jobs: continue-on-error: true if: env.UPLOAD_ARTIFACT == 'true' run: | - $myappname = "${{ inputs.appname }}" -replace '\s','_' - cp "rustdesk/${{ inputs.appname }}.exe" "rustdesk/${myappname}.exe" -ErrorAction SilentlyContinue + $myappname = "${{ env.appname }}" -replace '\s','_' + cp "rustdesk/${{ env.appname }}.exe" "rustdesk/${myappname}.exe" -ErrorAction SilentlyContinue pushd ./res/msi python preprocess.py --app-name "$myappname" --arp -d ../../rustdesk nuget restore msi.sln @@ -620,7 +611,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "85% complete"}' + data: '{"uuid": "${{ env.uuid }}", "status": "85% complete"}' - name: zip exe and msi continue-on-error: true @@ -652,26 +643,26 @@ jobs: - name: rename rustdesk.exe to filename.exe run: | - mv ./SignOutput/rustdesk.exe "./SignOutput/${{ inputs.filename }}.exe" || echo "rustdesk" + mv ./SignOutput/rustdesk.exe "./SignOutput/${{ env.filename }}.exe" || echo "rustdesk" - name: rename rustdesk.msi to filename.msi continue-on-error: true run: | - mv ./SignOutput/rustdesk.msi "./SignOutput/${{ inputs.filename }}.msi" || echo "rustdesk" + mv ./SignOutput/rustdesk.msi "./SignOutput/${{ env.filename }}.msi" || echo "rustdesk" - name: send file to rdgen server - if: ${{ fromJson(inputs.extras).rdgen == 'true' }} + if: ${{ env.rdgen == 'true' }} shell: bash run: | - curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.exe" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client - curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.msi" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client || true + curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ env.token }}" -F "file=@./SignOutput/${{ env.filename }}.exe" -F "uuid=${{ env.uuid }}" ${{ secrets.GENURL }}/save_custom_client + curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ env.token }}" -F "file=@./SignOutput/${{ env.filename }}.msi" -F "uuid=${{ env.uuid }}" ${{ secrets.GENURL }}/save_custom_client || true - name: send file to api server - if: ${{ fromJson(inputs.extras).rdgen == 'false' }} + if: ${{ env.rdgen == 'false' }} shell: bash run: | - curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.exe" ${{ inputs.apiServer }}/api/save_custom_client - curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.msi" ${{ inputs.apiServer }}/api/save_custom_client || true + curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ env.token }}" -F "file=@./SignOutput/${{ env.filename }}.exe" ${{ env.apiServer }}/api/save_custom_client + curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ env.token }}" -F "file=@./SignOutput/${{ env.filename }}.msi" ${{ env.apiServer }}/api/save_custom_client || true - name: Report Status uses: fjogeleit/http-request-action@v1 @@ -679,7 +670,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}' + data: '{"uuid": "${{ env.uuid }}", "status": "Success"}' - name: failed if: failure() @@ -688,7 +679,7 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}' + data: '{"uuid": "${{ env.uuid }}", "status": "Generation failed, try again"}' - name: failed if: cancelled() @@ -697,4 +688,4 @@ jobs: url: ${{ env.STATUS_URL }} method: 'POST' customHeaders: '{"Content-Type": "application/json"}' - data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}' + data: '{"uuid": "${{ env.uuid }}", "status": "Generation cancelled, try again"}' diff --git a/docker-compose.yml b/docker-compose.yml index c55db3f..68f22f4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ services: rdgen: # use bryangerlach/rdgen:latest for the latest build + #build: . image: bryangerlach/rdgen:latest restart: unless-stopped environment: @@ -8,6 +9,8 @@ services: GHUSER: "github_username" GHBEARER: "github_access_token" GENURL: "accessible_url_of_server" + ZIP_PASSWORD: "" + GHBRANCH: "master" PROTOCOL: "https" REPONAME: "rdgen" ports: diff --git a/rdgen/settings.py b/rdgen/settings.py index 9e64ac4..9931e2f 100644 --- a/rdgen/settings.py +++ b/rdgen/settings.py @@ -24,6 +24,8 @@ SECRET_KEY = os.environ.get('SECRET_KEY','django-insecure-!(t-!f#6g#sr%yfded9(xh GHUSER = os.environ.get("GHUSER", '') GHBEARER = os.environ.get("GHBEARER", '') GENURL = os.environ.get("GENURL", '') +GHBRANCH = os.environ.get("GHBRANCH",'master') +ZIP_PASSWORD = os.environ.get("ZIP_PASSWORD",'insecure') PROTOCOL = os.environ.get("PROTOCOL", 'https') REPONAME = os.environ.get("REPONAME", 'rdgen') diff --git a/rdgenerator/views.py b/rdgenerator/views.py index 75850dc..b1567a2 100644 --- a/rdgenerator/views.py +++ b/rdgenerator/views.py @@ -9,14 +9,13 @@ import requests import base64 import json import uuid +import pyminizip from django.conf import settings as _settings from django.db.models import Q from .forms import GenerateForm from .models import GithubRun from PIL import Image from urllib.parse import quote -from cryptography.hazmat.primitives import hashes, serialization -from cryptography.hazmat.primitives.asymmetric import padding def generator_view(request): if request.method == 'POST': @@ -192,21 +191,20 @@ def generator_view(request): base64_bytes = base64.b64encode(string_bytes) encodedCustom = base64_bytes.decode("ascii") - #github limits inputs to 10, so lump extras into one with json - extras = {} - extras['genurl'] = _settings.GENURL - #extras['runasadmin'] = runasadmin - extras['urlLink'] = urlLink - extras['downloadLink'] = downloadLink - extras['delayFix'] = 'true' if delayFix else 'false' - extras['version'] = version - extras['rdgen'] = 'true' - extras['cycleMonitor'] = 'true' if cycleMonitor else 'false' - extras['xOffline'] = 'true' if xOffline else 'false' - extras['removeNewVersionNotif'] = 'true' if removeNewVersionNotif else 'false' - extras['compname'] = compname - extras['androidappid'] = androidappid - extra_input = json.dumps(extras) + # #github limits inputs to 10, so lump extras into one with json + # extras = {} + # extras['genurl'] = _settings.GENURL + # #extras['runasadmin'] = runasadmin + # extras['urlLink'] = urlLink + # extras['downloadLink'] = downloadLink + # extras['delayFix'] = 'true' if delayFix else 'false' + # extras['rdgen'] = 'true' + # extras['cycleMonitor'] = 'true' if cycleMonitor else 'false' + # extras['xOffline'] = 'true' if xOffline else 'false' + # extras['removeNewVersionNotif'] = 'true' if removeNewVersionNotif else 'false' + # extras['compname'] = compname + # extras['androidappid'] = androidappid + # extra_input = json.dumps(extras) ####from here run the github action, we need user, repo, access token. if platform == 'windows': @@ -223,19 +221,46 @@ def generator_view(request): url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-windows.yml/dispatches' #url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rustdesk/actions/workflows/test.yml/dispatches' + inputs_raw = { + "server":server, + "key":key, + "apiServer":apiServer, + "custom":encodedCustom, + "uuid":myuuid, + "iconlink":iconlink, + "logolink":logolink, + "appname":appname, + "genurl":_settings.GENURL, + "urlLink":urlLink, + "downloadLink":downloadLink, + "delayFix": 'true' if delayFix else 'false', + "rdgen":'true', + "cycleMonitor": 'true' if cycleMonitor else 'false', + "xOffline": 'true' if xOffline else 'false', + "removeNewVersionNotif": 'true' if removeNewVersionNotif else 'false', + "compname": compname, + "androidappid":androidappid, + "filename":filename + } + temp_json = f"data_{uuid.uuid4()}.json" + with open(temp_json, "w") as f: + json.dump(inputs_raw, f) + + zip_filename = f"secrets_{uuid.uuid4()}.zip" + zip_path = os.path.join(settings.MEDIA_ROOT, 'temp_zips', zip_filename) + os.makedirs(os.path.dirname(zip_path), exist_ok=True) + + pyminizip.compress(temp_json, None, zip_path, settings.ZIP_PASSWORD, 5) + + os.remove(temp_json) + + zip_url = f"{settings.PROTOCOL}://{request.get_host()}/media/temp_zips/{zip_filename}" + data = { - "ref":"master", + "ref":_settings.GHBRANCH, "inputs":{ - "server":server, - "key":key, - "apiServer":apiServer, - "custom":encodedCustom, - "uuid":myuuid, - "iconlink":iconlink, - "logolink":logolink, - "appname":appname, - "extras":extra_input, - "filename":filename + "version":version, + "zip_url":zip_url } } #print(data) @@ -417,3 +442,25 @@ def save_custom_client(request): f.write(chunk) return HttpResponse("File saved successfully!") + +def cleanup_secrets(request): + # Pass the UUID as a query param or in JSON body + my_uuid = request.GET.get('uuid') + + if not my_uuid: + return HttpResponse("Missing UUID", status=400) + + # 1. Find the files in your temp directory matching the UUID + temp_dir = os.path.join(_settings.MEDIA_ROOT, 'temp_zips') + + # We look for any file starting with 'secrets_' and containing the uuid + for filename in os.listdir(temp_dir): + if my_uuid in filename and filename.endswith('.zip'): + file_path = os.path.join(temp_dir, filename) + try: + os.remove(file_path) + print(f"Successfully deleted {file_path}") + except OSError as e: + print(f"Error deleting file: {e}") + + return HttpResponse("Cleanup successful", status=200) diff --git a/requirements.txt b/requirements.txt index 6a09b31..68892ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ django requests pillow gunicorn -cryptography>=42.0.0 \ No newline at end of file +pyminizip>=0.2.1 \ No newline at end of file diff --git a/setup.md b/setup.md index 781ee18..bc7adb7 100644 --- a/setup.md +++ b/setup.md @@ -20,10 +20,14 @@ * Now click New repository secret * Set the Name to GENURL * Set the Secret to https://rdgen.hostname.com (or whatever your server will be accessed from) + * Now click New repository secret again + * Set the Name to ZIP_PASSWORD + * Set the Secret to any password you want (use this in the next step as well) - generate a password by running: ```python3 -c 'import secrets; print(secrets.token_hex(100))'``` 4. Now download the docker-compose.yml file and fill in the environment variables: * SECRET_KEY="your secret key" - generate a secret key by running: ```python3 -c 'import secrets; print(secrets.token_hex(100))'``` * GHUSER="your github username" * GHBEARER="your fine-grained access token" + * ZIP_PASSWORD="the same password that you entered as a github secret" * PROTOCOL="https" *optional - defaults to "https", change to "http" if you need to * REPONAME="rdgen" *optional - defaults to "rdgen", change this if you renamed the repo when you forked it 5. Now just run ```docker compose up -d```