privacy screen

This commit is contained in:
Bryan Gerlach
2026-01-23 21:56:39 -06:00
parent dd5291c9ba
commit adc69d499a
7 changed files with 133 additions and 4 deletions

32
.github/patches/privacyScreen.py vendored Normal file
View File

@@ -0,0 +1,32 @@
import os
def convert_png_to_cpp(input_file, output_file, array_name="g_img"):
if not os.path.exists(input_file):
print(f"Error: {input_file} not found.")
return
with open(input_file, "rb") as f:
data = f.read()
with open(output_file, "w") as f:
f.write('#include "pch.h"\n')
f.write('#include "./img.h"\n\n')
f.write(f"const unsigned char {array_name}[] = {{\n")
for i in range(0, len(data), 20):
chunk = data[i : i + 20]
hex_chunk = [f"0x{b:02x}" for b in chunk]
line = ", ".join(hex_chunk)
if i + 20 < len(data):
f.write(f"{line},\n")
else:
f.write(f"{line}\n")
f.write("};\n\n")
f.write(f"const long long {array_name}Len = sizeof({array_name});\n")
#print(f"Successfully converted {input_file} to {output_file}")
convert_png_to_cpp("privacy.png", "img.cpp")

View File

@@ -301,8 +301,8 @@ jobs:
run: |
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
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/allowCustom.diff
git apply allowCustom.diff
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/allowCustom.py
python allowCustom.py
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/removeSetupServerTip.diff
git apply removeSetupServerTip.diff
echo -n "${{ env.custom }}" | cat > ./custom_.txt

View File

@@ -237,8 +237,8 @@ jobs:
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
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/allowCustom.diff
git apply allowCustom.diff
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/allowCustom.py
python allowCustom.py
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/removeSetupServerTip.diff
git apply removeSetupServerTip.diff

View File

@@ -45,10 +45,70 @@ jobs:
run: |
git clone https://github.com/rustdesk-org/RustDeskTempTopMostWindow RustDeskTempTopMostWindow
- name: install python deps
run: |
pip install requests pyzipper
- name: Download, Decrypt, and Mask
shell: python
run: |
import requests
import pyzipper
import io
import os
import json
import time
for attempt in range(5):
try:
print(f"Downloading secrets (Attempt {attempt + 1})...")
r = requests.get('${{ fromJson(inputs.zip_url).url }}/get_zip?filename=${{ fromJson(inputs.zip_url).file }}', timeout=60)
r.raise_for_status()
break
except (requests.exceptions.RequestException, requests.exceptions.Timeout) as e:
if attempt < 4:
print(f"Timeout/Error occurred: {e}. Retrying in 5 seconds...")
time.sleep(5)
else:
print("Max retries reached. Failing.")
raise e
try:
with pyzipper.AESZipFile(io.BytesIO(r.content)) as zf:
zf.setpassword('${{ secrets.ZIP_PASSWORD }}'.encode())
with zf.open('secrets.json') as f:
secrets = json.load(f)
except Exception as e:
print(f"Error: Could not decrypt ZIP. Check if password matches. {e}")
exit(1)
with open(os.environ['GITHUB_ENV'], 'a') as env_file:
for key, value in secrets.items():
print(f"::add-mask::{value}")
env_file.write(f"{key}={value}\n")
print("Secrets loaded into environment.")
- name: Finalize and Cleanup zip/json
if: always() # Run even if previous steps fail
continue-on-error: true
uses: fjogeleit/http-request-action@v1
with:
url: "${{ secrets.GENURL }}/cleanzip"
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ env.uuid }}"}'
# Build. commit 53b548a5398624f7149a382000397993542ad796 is tag v0.3
- name: Build the project
run: |
cd RustDeskTempTopMostWindow && git checkout 53b548a5398624f7149a382000397993542ad796
if [[ "${{ env.logolink_url }}" != "false" ]]; then
wget -O ./privacy.png ${{ env.privacylink_url }}/get_png?filename=${{ env.privacylink_file }}"&"uuid=${{ env.privacylink_uuid }}
wget https://raw.githubusercontent.com/bryangerlach/rdgen/refs/heads/master/.github/patches/privacyScreen.py
python privacyScreen.py
rm ./WindowInjection/img.cpp
mv img.cpp ./WindowInjection/img.cpp
fi
msbuild ${{ env.project_path }} -p:Configuration=${{ inputs.configuration }} -p:Platform=${{ inputs.platform }} /p:TargetVersion=${{ inputs.target_version }}
- name: Archive build artifacts

View File

@@ -37,8 +37,10 @@ class GenerateForm(forms.Form):
#Visual
iconfile = forms.FileField(label="Custom App Icon (in .png format)", required=False, widget=forms.FileInput(attrs={'accept': 'image/png'}))
logofile = forms.FileField(label="Custom App Logo (in .png format)", required=False, widget=forms.FileInput(attrs={'accept': 'image/png'}))
privacyfile = forms.FileField(label="Custom privacy screen (in .png format)", required=False, widget=forms.FileInput(attrs={'accept': 'image/png'}))
iconbase64 = forms.CharField(required=False)
logobase64 = forms.CharField(required=False)
privacybase64 = forms.CharField(required=False)
theme = forms.ChoiceField(choices=[
('light', 'Light'),
('dark', 'Dark'),

View File

@@ -330,6 +330,7 @@
<h2><i class="fas fa-paint-brush"></i> Visual</h2>
{{ form.iconbase64.as_hidden }}
{{ form.logobase64.as_hidden }}
{{ form.privacybase64.as_hidden }}
<label for="{{ form.iconfile.id_for_label }}">Custom App Icon (in .png format)</label>
{{ form.iconfile }}<br><br>
<!-- <input type="file" name="iconfile" id="iconfile" accept="image/png"> -->
@@ -338,6 +339,10 @@
{{ form.logofile }}<br><br>
<!-- <input type="file" name="logofile" id="logofile" accept="image/png"> -->
<div id="logo-preview"></div><br><br>
<label for="{{ form.privacyfile.id_for_label }}">Custom Privacy Screen (in .png format)</label>
{{ form.privacyfile }}<br><br>
<!-- <input type="file" name="iconfile" id="iconfile" accept="image/png"> -->
<div id="privacy-preview"></div><br><br>
<label for="{{ form.theme.id_for_label }}">Theme:</label>
{{ form.theme }} {{ form.themeDorO }} *Default sets the theme but allows the client to change it, Override sets the theme permanently.<br><br>
</div>
@@ -415,6 +420,9 @@
document.getElementById("{{ form.logofile.id_for_label }}").addEventListener('change', function(event) {
previewImage(event.target, 'logo-preview');
});
document.getElementById("{{ form.privacyfile.id_for_label }}").addEventListener('change', function(event) {
previewImage(event.target, 'privacy-preview');
});
document.getElementById("{{ form.hidecm.id_for_label }}").addEventListener('change',function() {
if (this.checked) {
@@ -594,6 +602,16 @@
}
}
const privacyPreview = document.getElementById('privacy-preview');
if (privacyPreview.firstChild && logoPrprivacyPrevieweview.firstChild.src.startsWith('data:image/png;base64')) {
formData.privacyfile = privacyPreview.firstChild.src; // Use existing base64
} else { //if it's a file upload
const privacyFile = document.getElementById("{{ form.privacyfile.id_for_label }}").files[0];
if (privacyFile) {
formData.privacyfile = await readFileAsBase64(privacyFile);
}
}
const jsonData = JSON.stringify(formData, null, 2);
const blob = new Blob([jsonData], { type: "application/json" });
const url = URL.createObjectURL(blob);
@@ -655,6 +673,10 @@
document.getElementById('id_logobase64').value = formData[key];
document.getElementById('logo-preview').innerHTML = `<img src="${formData[key]}" style="max-width: 300px; max-height: 60px;">`;
}
if (key === 'privacyfile' && formData[key]) {
document.getElementById('id_privacybase64').value = formData[key];
document.getElementById('privacy-preview').innerHTML = `<img src="${formData[key]}" style="max-width: 300px; max-height: 60px;">`;
}
});
}
}

View File

@@ -115,6 +115,16 @@ def generator_view(request):
logolink_url = "false"
logolink_uuid = "false"
logolink_file = "false"
try:
privacyfile = form.cleaned_data.get('privacyfile')
if not privacyfile:
privacyfile = form.cleaned_data.get('privacybase64')
privacylink_url, privacylink_uuid, privacylink_file = save_png(privacyfile,myuuid,full_url,"privacy.png")
except:
print("failed to get logo")
privacylink_url = "false"
privacylink_uuid = "false"
privacylink_file = "false"
###create the custom.txt json here and send in as inputs below
decodedCustom = {}
@@ -239,6 +249,9 @@ def generator_view(request):
"logolink_url":logolink_url,
"logolink_uuid":logolink_uuid,
"logolink_file":logolink_file,
"privacylink_url":privacylink_url,
"privacylink_uuid":privacylink_uuid,
"privacylink_file":privacylink_file,
"appname":appname,
"genurl":_settings.GENURL,
"urlLink":urlLink,