Import ban list file #4

This commit is contained in:
argenius 2024-11-13 18:00:45 +01:00
parent 594fb9f925
commit b0b1d785cc
7 changed files with 182 additions and 4 deletions

View file

@ -889,13 +889,37 @@ try {
}); });
} catch (error) { } catch (error) {
event.sender.send('download-progress', { progress: 0, status: `Error: ${error}` }); event.sender.send('download-progress', { progress: 0, status: `${error}` });
win?.setProgressBar(0, { win?.setProgressBar(0, {
mode: 'error' mode: 'error'
}); });
} }
}); });
ipcMain.handle('download-file', async (event: IpcMainInvokeEvent, url: string, destination: string) => {
try {
event.sender.send('download-file-progress', { progress: 0, status: 'Starting download' });
const fileName = await downloadFile(url, destination, (progress) => {
win?.setProgressBar(progress, {
mode: 'normal'
});
event.sender.send('download-file-progress', { progress, status: 'Downloading' });
});
win?.setProgressBar(0, {
mode: 'none'
});
event.sender.send('download-file-complete', `${destination}${separator}${fileName}`);
}
catch(error: any) {
console.error(error);
event.sender.send('download-file-error', `${error}`);
}
});
ipcMain.handle('read-file', (event: IpcMainInvokeEvent, filePath: string) => { ipcMain.handle('read-file', (event: IpcMainInvokeEvent, filePath: string) => {
fs.readFile(filePath, 'utf-8', (err, data) => { fs.readFile(filePath, 'utf-8', (err, data) => {
if (err != null) { if (err != null) {
@ -1080,6 +1104,10 @@ try {
// #endregion // #endregion
ipcMain.handle('show-error-box', (event: IpcMainInvokeEvent, title: string, content: string) => {
dialog.showErrorBox(title, content);
});
ipcMain.handle('set-tray-item-enabled', (event: IpcMainInvokeEvent, id: string, enabled: boolean) => { ipcMain.handle('set-tray-item-enabled', (event: IpcMainInvokeEvent, id: string, enabled: boolean) => {
setTrayItemEnabled(id, enabled); setTrayItemEnabled(id, enabled);
}); });
@ -1096,10 +1124,13 @@ try {
clipboard.writeText(content, "selection"); clipboard.writeText(content, "selection");
}); });
} catch (e: any) {
} catch (e) {
// Catch Error // Catch Error
console.error(e); console.error(e);
dialog.showErrorBox('', `${e}`);
app.quit();
// throw e; // throw e;
} }

View file

@ -244,5 +244,25 @@ contextBridge.exposeInMainWorld('electronAPI', {
}, },
unregisterOnIsAutoLaunched: () => { unregisterOnIsAutoLaunched: () => {
ipcRenderer.removeAllListeners('on-is-auto-launched'); ipcRenderer.removeAllListeners('on-is-auto-launched');
},
downloadFile: (url, destination) => {
ipcRenderer.invoke('download-file', url, destination);
},
onDownloadFileProgress: (callback) => {
ipcRenderer.on('download-file-progress', callback);
},
onDownloadFileError: (callback) => {
ipcRenderer.on('download-file-error', callback);
},
onDownloadFileComplete: (callback) => {
ipcRenderer.on('download-file-complete', callback);
},
unregisterOnDownloadFile: () => {
ipcRenderer.removeAllListeners('download-file-progress');
ipcRenderer.removeAllListeners('download-file-error');
ipcRenderer.removeAllListeners('download-file-complete');
},
showErrorBox: (title, content) => {
ipcRenderer.invoke('show-error-box', title, content);
} }
}); });

View file

@ -311,4 +311,25 @@ export class ElectronService {
return await promise; return await promise;
} }
public async downloadFile(url: string, destination: string, progressFunction?: (info: { progress: number, status: string }) => void): Promise<string> {
const promise = new Promise<string>((resolve, reject) => {
if (progressFunction) {
window.electronAPI.onDownloadProgress((event: any, prog: { progress: number, status: string }) => progressFunction(prog));
}
window.electronAPI.onDownloadFileError((event: any, error: string) => {
window.electronAPI.unregisterOnDownloadFile();
reject(new Error(error));
});
window.electronAPI.onDownloadFileComplete((event: any, fileName: string) => {
window.electronAPI.unregisterOnDownloadFile();
resolve(fileName);
});
});
window.electronAPI.downloadFile(url, destination);
return await promise;
}
} }

View file

@ -65,6 +65,40 @@
</div> </div>
<hr class="my-4">
<h4 class="mb-3">Ban</h4>
<div class="col-md-12">
<div class="form-check form-switch col-md-6">
<label for="general-remote-ban-list" class="form-check-label">Remote ban list</label>
<input class="form-control form-check-input" type="checkbox" role="switch" id="general-remote-ban-list" [checked]="currentSettings.remoteBanList" [(ngModel)]="currentSettings.remoteBanList" [ngModelOptions]="{standalone: true}">
<br>
<small class="text-body-secondary">Specify a remote URL for download ban list</small>
</div>
</div>
<br>
<div *ngIf="!currentSettings.remoteBanList" class="col-md-12">
<label for="general-ban-list-file" class="form-label">Ban list file</label>
<div class="input-group mb-3">
<input id="general-ban-list-file" type="text" class="form-control form-control-sm" placeholder="" aria-label="Ban list file path" aria-describedby="basic-addon3" [value]="currentSettings.banList" readonly>
<span class="input-group-text" id="basic-addon3"><button type="button" class="btn btn-secondary btn-sm" (click)="chooseBanListFile()"><i class="bi bi-filetype-txt"></i> Choose File</button></span>
<span class="input-group-text" id="basic-addon3"><button type="button" class="btn btn-secondary btn-sm" (click)="removeBanListFile()" [disabled]="currentSettings.banList === ''"><i class="bi bi-file-x"></i> Remove</button></span>
</div>
<small class="text-body-secondary">Specify ban list file, one IP address per line. It is <strong>not recommended</strong> to statically ban any IP addresses unless you absolutely need to. Banning IPs often excludes the most vulnerable users who are forced to operate entirely behind Tor or other anonymity networks</small>
</div>
<div *ngIf="currentSettings.remoteBanList" class="col-md-12">
<label for="general-ban-list-url" class="form-label">Ban list URL</label>
<div class="input-group mb-3">
<input id="general-ban-list-url" type="text" class="form-control form-control-sm" placeholder="https://gui.xmr.pm/files/block.txt" aria-label="Ban list file url" aria-describedby="basic-addon3" [(ngModel)]="banListUrl" [ngModelOptions]="{standalone: true}">
<span class="input-group-text" id="basic-addon3"><button type="button" class="btn btn-secondary btn-sm" (click)="downloadBanListFile()" [disabled]="!validBanListUrl"><i class="bi bi-filetype-txt"></i> Download</button></span>
</div>
<small class="text-body-secondary">Specify ban list file, one IP address per line. It is <strong>not recommended</strong> to statically ban any IP addresses unless you absolutely need to. Banning IPs often excludes the most vulnerable users who are forced to operate entirely behind Tor or other anonymity networks</small>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -545,7 +579,6 @@
<div class="tab-pane fade" id="pills-blockchain" role="tabpanel" aria-labelledby="pills-blockchain-tab" tabindex="0"> <div class="tab-pane fade" id="pills-blockchain" role="tabpanel" aria-labelledby="pills-blockchain-tab" tabindex="0">
<div class="row g-5 p-2"> <div class="row g-5 p-2">
<div class="col-md-7 col-lg-12"> <div class="col-md-7 col-lg-12">
<form class="needs-validation" novalidate=""> <form class="needs-validation" novalidate="">

View file

@ -16,6 +16,22 @@ export class SettingsComponent {
private originalSettings: DaemonSettings; private originalSettings: DaemonSettings;
public currentSettings: DaemonSettings; public currentSettings: DaemonSettings;
public banListUrl: string = '';
public get validBanListUrl(): boolean {
if (this.banListUrl == '') {
return false;
}
try {
new URL(this.banListUrl);
return true;
}
catch {
return false;
}
}
public savingChanges: boolean = false; public savingChanges: boolean = false;
public savingChangesError = ``; public savingChangesError = ``;
public savingChangesSuccess: boolean = false; public savingChangesSuccess: boolean = false;
@ -339,6 +355,50 @@ export class SettingsComponent {
}); });
} }
public async chooseBanListFile(): Promise<void> {
const file = await this.electronService.selectFile(['txt']);
if (file == '') {
return;
}
this.ngZone.run(() => {
this.currentSettings.banList = file;
});
}
public removeBanListFile(): void {
this.currentSettings.banList = '';
}
public downloadingBanListFile: boolean = false;
public async downloadBanListFile(): Promise<void> {
if (!this.currentSettings.remoteBanList) {
return;
}
this.downloadingBanListFile = true;
try {
const destination = await this.electronService.selectFolder();
const filePath = await this.electronService.downloadFile(this.banListUrl, destination);
if (!filePath.endsWith('.txt')) {
throw new Error("Downloaded file doesn't seem to be a valid ban list txt file");
}
this.currentSettings.banList = filePath;
this.currentSettings.remoteBanList = false;
}
catch (error: any) {
console.error(error);
window.electronAPI.showErrorBox('', `${error}`.replace('Error:', ''));
}
this.downloadingBanListFile = false;
}
private async choosePemFile(): Promise<string> { private async choosePemFile(): Promise<string> {
return await this.electronService.selectFile(['pem', 'PEM']); return await this.electronService.selectFile(['pem', 'PEM']);
} }

View file

@ -98,6 +98,7 @@ export class DaemonSettings {
public anonymousInbound: string = ''; public anonymousInbound: string = '';
public banList: string = ''; public banList: string = '';
public remoteBanList: boolean = false;
public hideMyPort: boolean = false; public hideMyPort: boolean = false;
public noSync: boolean = false; public noSync: boolean = false;
@ -146,6 +147,10 @@ export class DaemonSettings {
public rpcPaymentAllowFreeLoopback: boolean = false; public rpcPaymentAllowFreeLoopback: boolean = false;
public disableRpcBan: boolean = false; public disableRpcBan: boolean = false;
public get banListArray(): string[] {
return this.banList.split('\n');
}
public equals(settings: DaemonSettings): boolean { public equals(settings: DaemonSettings): boolean {
//return this.toCommandOptions().join('') == settings.toCommandOptions().join(''); //return this.toCommandOptions().join('') == settings.toCommandOptions().join('');
return this.deepEqual(this, settings); return this.deepEqual(this, settings);

View file

@ -161,6 +161,14 @@ declare global {
unregisterOnIsOnBatteryPower: () => void; unregisterOnIsOnBatteryPower: () => void;
onBattery: (callback: (event: any) => void) => void; onBattery: (callback: (event: any) => void) => void;
onAc: (callback: (event: any) => void) => void; onAc: (callback: (event: any) => void) => void;
downloadFile: (url: string, destination: string) => void;
onDownloadFileProgress: (callback: (event: any, info: { progress: number, status: string }) => void) => void;
onDownloadFileError: (callback: (event: any, error: string) => void) => void;
onDownloadFileComplete: (callback: (event: any, fileName: string) => void) => void;
unregisterOnDownloadFile: () => void;
showErrorBox: (title: string, content: string) => void;
}; };
} }
} }