Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to configure the vpn apps from the manager UI #479

Merged
merged 1 commit into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Input, OnDestroy } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Observable, Subscription } from 'rxjs';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';

import { Application } from '../../../../../app.datatypes';
import { AppsService } from '../../../../../services/apps.service';
Expand All @@ -16,7 +17,6 @@ import { SkysocksSettingsComponent } from '../node-apps/skysocks-settings/skysoc
import { processServiceError } from 'src/app/utils/errors';
import { OperationError } from 'src/app/utils/operation-error';
import { SkysocksClientSettingsComponent } from '../node-apps/skysocks-client-settings/skysocks-client-settings.component';
import { TranslateService } from '@ngx-translate/core';
import { FilterProperties, FilterFieldTypes } from 'src/app/utils/filters';
import { SortingColumn, SortingModes, DataSorter } from 'src/app/utils/lists/data-sorter';
import { DataFilterer } from 'src/app/utils/lists/data-filterer';
Expand Down Expand Up @@ -70,6 +70,8 @@ export class NodeAppsListComponent implements OnDestroy {
appsWithConfig = new Map<string, boolean>([
['skysocks', true],
['skysocks-client', true],
['vpn-client', true],
['vpn-server', true],
]);

allApps: Application[];
Expand Down Expand Up @@ -411,9 +413,9 @@ export class NodeAppsListComponent implements OnDestroy {
* Shows the appropriate modal window for configuring the app.
*/
config(app: Application): void {
if (app.name === 'skysocks') {
if (app.name === 'skysocks' || app.name === 'vpn-server') {
SkysocksSettingsComponent.openDialog(this.dialog, app);
} else if (app.name === 'skysocks-client') {
} else if (app.name === 'skysocks-client' || app.name === 'vpn-client') {
SkysocksClientSettingsComponent.openDialog(this.dialog, app);
} else {
this.snackbarService.showError('apps.error');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<app-dialog [headline]="'apps.skysocks-client-settings.change-note-dialog.title' | translate">
<app-dialog [headline]="'apps.vpn-socks-client-settings.change-note-dialog.title' | translate">
<form [formGroup]="form">
<mat-form-field>
<input #firstInput [placeholder]="'apps.skysocks-client-settings.change-note-dialog.note' | translate" formControlName="note" maxlength="100" matInput>
<input #firstInput [placeholder]="'apps.vpn-socks-client-settings.change-note-dialog.note' | translate" formControlName="note" maxlength="100" matInput>
</mat-form-field>
<app-button class="float-right" color="primary" type="mat-raised-button" (action)="finish()">{{ 'common.save' | translate }}</app-button>
</form>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
<app-dialog [headline]="'apps.skysocks-client-settings.filter-dialog.title' | translate">
<app-dialog [headline]="'apps.vpn-socks-client-settings.filter-dialog.title' | translate">
<form [formGroup]="form">

<!-- Country. -->
<mat-form-field *ngIf="data.availableCountries.length > 0">
<mat-select formControlName="country" id="country" [placeholder]="'apps.vpn-socks-client-settings.filter-dialog.country' | translate">
<mat-option [value]="'-'">{{ 'apps.vpn-socks-client-settings.filter-dialog.any-country' | translate }}</mat-option>
<mat-option *ngFor="let country of data.availableCountries" [value]="country.toUpperCase()">
<div class="flag-container">
<div [style]="'background-image: url(\'assets/img/flags/' + country.toLocaleLowerCase() + '.png\');'"></div>
</div>
<ng-container *ngIf="completeCountriesList[country.toUpperCase()]">{{ completeCountriesList[country.toUpperCase()] }}</ng-container>
<ng-container *ngIf="!completeCountriesList[country.toUpperCase()]">{{ country.toUpperCase() }}</ng-container>
</mat-option>
<mat-select-trigger>
<ng-container *ngIf="form.get('country').value === '-'">
{{ 'apps.vpn-socks-client-settings.filter-dialog.any-country' | translate }}
</ng-container>
<ng-container *ngIf="form.get('country').value !== '-'">
<div class="flag-container">
<div [style]="'background-image: url(\'assets/img/flags/' + form.get('country').value.toLocaleLowerCase() + '.png\');'"></div>
</div>
<ng-container *ngIf="completeCountriesList[form.get('country').value]">{{ completeCountriesList[form.get('country').value] }}</ng-container>
<ng-container *ngIf="!completeCountriesList[form.get('country').value]">{{ form.get('country').value }}</ng-container>
</ng-container>
</mat-select-trigger>
</mat-select>
</mat-form-field>

<!-- Location. -->
<mat-form-field>
<input
formControlName="location-text"
maxlength="100"
[placeholder]="'apps.skysocks-client-settings.filter-dialog.location' | translate"
[placeholder]="'apps.vpn-socks-client-settings.filter-dialog.location' | translate"
matInput
>
</mat-form-field>
Expand All @@ -14,7 +41,7 @@
<input
formControlName="key-text"
maxlength="66"
[placeholder]="'apps.skysocks-client-settings.filter-dialog.pub-key' | translate"
[placeholder]="'apps.vpn-socks-client-settings.filter-dialog.pub-key' | translate"
matInput
>
</mat-form-field>
Expand All @@ -27,7 +54,7 @@
color="primary"
class="float-right"
>
{{ 'apps.skysocks-client-settings.filter-dialog.apply' | translate }}
{{ 'apps.vpn-socks-client-settings.filter-dialog.apply' | translate }}
</app-button>
</form>
</app-dialog>
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@ import { FormBuilder, FormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog';

import { AppConfig } from 'src/app/app.config';
import { countriesList } from 'src/app/utils/countries-list';

/**
* Filters the user selected using SkysocksClientFilterComponent. It is prepopulated with default
* data which indicates that no filter has been selected.
*/
export class SkysocksClientFilters {
country = '';
location = '';
key = '';
}

/**
* Modal window for selecting the filters for the proxy list shown by
* Data for SkysocksClientFilterComponent.
*/
export interface FilterWindowData {
currentFilters: SkysocksClientFilters;
availableCountries: string[];
}

/**
* Modal window for selecting the filters for the elements list shown by
* SkysocksClientSettingsComponent. If the user accepts the changes, the modal window is closed
* and an instance of SkysocksClientFilters is returned in the "afterClosed" envent, with the
* selected filters.
Expand All @@ -27,35 +37,47 @@ export class SkysocksClientFilters {
export class SkysocksClientFilterComponent implements OnInit {
form: FormGroup;

completeCountriesList = countriesList;

/**
* Opens the modal window. Please use this function instead of opening the window "by hand".
*/
public static openDialog(dialog: MatDialog, currentFilters: SkysocksClientFilters): MatDialogRef<SkysocksClientFilterComponent, any> {
public static openDialog(dialog: MatDialog, data: FilterWindowData): MatDialogRef<SkysocksClientFilterComponent, any> {
const config = new MatDialogConfig();
config.data = currentFilters;
config.data = data;
config.autoFocus = false;
config.width = AppConfig.smallModalWidth;

return dialog.open(SkysocksClientFilterComponent, config);
}

constructor(
@Inject(MAT_DIALOG_DATA) private data: SkysocksClientFilters,
@Inject(MAT_DIALOG_DATA) public data: FilterWindowData,
private dialogRef: MatDialogRef<SkysocksClientFilterComponent>,
private formBuilder: FormBuilder,
) { }

ngOnInit() {
// The '-' value is used when the country field is empty, to be able to show the "any" label,
// due to the way in which Angular works.
this.form = this.formBuilder.group({
'location-text': [this.data.location],
'key-text': [this.data.key],
'country': [this.data.currentFilters.country ? this.data.currentFilters.country : '-'],
'location-text': [this.data.currentFilters.location],
'key-text': [this.data.currentFilters.key],
});
}

// Closes the modal window and returns the selected filters.
apply() {
const response = new SkysocksClientFilters();

// If the value of the country field is '-', it means that no country was selected.
let country = (this.form.get('country').value as string).trim();
if (country === '-') {
country = '';
}

response.country = country;
response.location = (this.form.get('location-text').value as string).trim();
response.key = (this.form.get('key-text').value as string).trim();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
<app-dialog [headline]="'apps.skysocks-client-settings.title' | translate">
<app-dialog [headline]="('apps.vpn-socks-client-settings.' + ( configuringVpn ? 'vpn-title' : 'socks-title')) | translate">
<mat-tab-group>
<!-- Form. -->
<mat-tab [label]="'apps.skysocks-client-settings.remote-visor-tab' | translate">
<mat-tab [label]="'apps.vpn-socks-client-settings.remote-visor-tab' | translate">
<form [formGroup]="form">
<mat-form-field>
<input
id="pk"
formControlName="pk"
maxlength="66"
[placeholder]="'apps.skysocks-client-settings.public-key' | translate"
[placeholder]="'apps.vpn-socks-client-settings.public-key' | translate"
#firstInput
matInput
>
<mat-error>
<ng-container *ngIf="!this.form.get('pk').hasError('pattern');else hexError">
{{ 'apps.skysocks-client-settings.remote-key-length-error' | translate }}
{{ 'apps.vpn-socks-client-settings.remote-key-length-error' | translate }}
</ng-container>
</mat-error>
<ng-template #hexError>
{{ 'apps.skysocks-client-settings.remote-key-chars-error' | translate }}
{{ 'apps.vpn-socks-client-settings.remote-key-chars-error' | translate }}
</ng-template>
</mat-form-field>

Expand All @@ -29,18 +29,18 @@
color="primary"
class="float-right"
>
{{ 'apps.skysocks-client-settings.save' | translate }}
{{ 'apps.vpn-socks-client-settings.save' | translate }}
</app-button>
</form>
</mat-tab>
<!-- Discovery. -->
<mat-tab [label]="'apps.skysocks-client-settings.discovery-tab' | translate">
<mat-tab [label]="'apps.vpn-socks-client-settings.discovery-tab' | translate">
<app-loading-indicator class="loading-indicator" [showWhite]="false" *ngIf="loadingFromDiscovery"></app-loading-indicator>

<!-- No proxies in the discovery service msg. -->
<div class="info-text" *ngIf="!loadingFromDiscovery && proxiesFromDiscovery.length === 0">
<mat-icon [inline]="true">error</mat-icon>
{{ 'apps.skysocks-client-settings.no-elements' | translate }}
{{ 'apps.vpn-socks-client-settings.no-elements' | translate }}
</div>

<!-- Filters button. -->
Expand All @@ -56,22 +56,22 @@
</div>
<div>
<div class="item" *ngIf="currentFiltersTexts.length === 0">
{{ 'apps.skysocks-client-settings.no-filter' | translate }}
{{ 'apps.vpn-socks-client-settings.no-filter' | translate }}
</div>
<div *ngFor="let filterTexts of currentFiltersTexts" class="item">
<span>{{ filterTexts[0] | translate }} </span>
<ng-container *ngIf="filterTexts[1]">{{ filterTexts[1] | translate }}</ng-container>
<ng-container *ngIf="filterTexts[2]">{{ filterTexts[2] }}</ng-container>
</div>
<div class="item" class="blue-part">{{ 'apps.skysocks-client-settings.click-to-change' | translate }}</div>
<div class="item" class="blue-part">{{ 'apps.vpn-socks-client-settings.click-to-change' | translate }}</div>
</div>
</div>
</button>

<!-- No proxies with the current filters msg. -->
<div class="info-text" *ngIf="filteredProxiesFromDiscovery.length === 0">
<mat-icon [inline]="true">error</mat-icon>
{{ 'apps.skysocks-client-settings.no-elements-for-filters' | translate }}
{{ 'apps.vpn-socks-client-settings.no-elements-for-filters' | translate }}
</div>

<!-- Proxies list. -->
Expand All @@ -83,16 +83,23 @@
>
<div class="button-content">
<div class="item">
<span>{{ 'apps.skysocks-client-settings.key' | translate }}</span>
<span>{{ 'apps.vpn-socks-client-settings.key' | translate }}</span>
<span>&nbsp;<ng-container *ngFor="let part of getHighlightedTextParts(proxy.pk, currentFilters.key); let i = index">
<span [ngClass]="{ highlighted: i % 2 !== 0 }">{{ part }}</span>
</ng-container></span>
</div>
<div class="item" *ngIf="proxy.location">
<span>{{ 'apps.skysocks-client-settings.location' | translate }}</span>
<span>&nbsp;<ng-container *ngFor="let part of getHighlightedTextParts(proxy.location, currentFilters.location); let i = index">
<span [ngClass]="{ highlighted: i % 2 !== 0 }">{{ part }}</span>
</ng-container></span>
<span>{{ 'apps.vpn-socks-client-settings.location' | translate }}</span>
<span>&nbsp;
<ng-container *ngIf="proxy.country">
<div class="flag-container">
<div [style]="'background-image: url(\'assets/img/flags/' + proxy.country.toLocaleLowerCase() + '.png\');'"></div>
</div>
</ng-container>
<ng-container *ngFor="let part of getHighlightedTextParts(proxy.location, currentFilters.location); let i = index">
<span [ngClass]="{ highlighted: i % 2 !== 0 }">{{ part }}</span>
</ng-container>
</span>
</div>
</div>
</button>
Expand All @@ -101,7 +108,7 @@

<!-- Paginator. -->
<div class="paginator" *ngIf="numberOfPages > 1">
<span>{{ 'apps.skysocks-client-settings.pagination-info' | translate:{currentElementsRange: currentRange, totalElements: filteredProxiesFromDiscovery.length} }}</span>
<span>{{ 'apps.vpn-socks-client-settings.pagination-info' | translate:{currentElementsRange: currentRange, totalElements: filteredProxiesFromDiscovery.length} }}</span>

<button (click)="goToPreviousPage()" mat-icon-button class="hard-grey-button-background">
<mat-icon>chevron_left</mat-icon>
Expand All @@ -112,12 +119,12 @@
</div>
</mat-tab>
<!-- History. -->
<mat-tab [label]="'apps.skysocks-client-settings.history-tab' | translate">
<mat-tab [label]="'apps.vpn-socks-client-settings.history-tab' | translate">
<!-- Msg shown if there is no history. -->
<div *ngIf="history.length === 0">
<div class="info-text">
<mat-icon [inline]="true">error</mat-icon>
{{ 'apps.skysocks-client-settings.no-history' | translate:{number: maxHistoryElements} }}
{{ 'apps.vpn-socks-client-settings.no-history' | translate:{number: maxHistoryElements} }}
</div>
</div>

Expand Down Expand Up @@ -146,20 +153,20 @@
<!-- Info. -->
<div class="full-size-area">
<div class="item">
<span>{{ 'apps.skysocks-client-settings.key' | translate }}</span>
<span>{{ 'apps.vpn-socks-client-settings.key' | translate }}</span>
<span> {{ entry.key }}</span>
</div>
<div class="item">
<span>{{ 'apps.skysocks-client-settings.note' | translate }}</span>
<span>{{ 'apps.vpn-socks-client-settings.note' | translate }}</span>
<ng-container *ngIf="entry.note">
<span> {{ entry.note }}</span>
</ng-container>
<ng-container *ngIf="!entry.note">
<ng-container *ngIf="entry.enteredManually">
<span> {{ 'apps.skysocks-client-settings.note-entered-manually' | translate }}</span>
<span> {{ 'apps.vpn-socks-client-settings.note-entered-manually' | translate }}</span>
</ng-container>
<ng-container *ngIf="!entry.enteredManually">
<span> {{ 'apps.skysocks-client-settings.note-obtained' | translate }}</span>
<span> {{ 'apps.vpn-socks-client-settings.note-obtained' | translate }}</span>
<ng-container *ngIf="entry.location">
<span> ({{ entry.location }})</span>
</ng-container>
Expand All @@ -172,15 +179,15 @@
<button
(click)="$event.stopPropagation(); changeNote(entry)"
mat-icon-button
[matTooltip]="'apps.skysocks-client-settings.change-note' | translate"
[matTooltip]="'apps.vpn-socks-client-settings.change-note' | translate"
class="small-button hard-grey-button-background d-none d-md-inline"
>
<mat-icon [inline]="true">edit</mat-icon>
</button>
<button
(click)="$event.stopPropagation(); removeFromHistory(entry.key)"
mat-icon-button
[matTooltip]="'apps.skysocks-client-settings.remove-entry' | translate"
[matTooltip]="'apps.vpn-socks-client-settings.remove-entry' | translate"
class="small-button hard-grey-button-background d-none d-md-inline"
>
<mat-icon [inline]="true">close</mat-icon>
Expand Down
Loading