From 0260c1532d30941aa286ea747dba589d1974ff10 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Thu, 12 Feb 2026 08:10:01 -0700 Subject: [PATCH] fix ssh, undeprecate wifi (#3121) --- .../shared/src/i18n/dictionaries/de.ts | 6 +- .../shared/src/i18n/dictionaries/en.ts | 6 +- .../shared/src/i18n/dictionaries/es.ts | 6 +- .../shared/src/i18n/dictionaries/fr.ts | 6 +- .../shared/src/i18n/dictionaries/pl.ts | 6 +- .../system/routes/email/email.component.ts | 2 +- .../routes/system/routes/ssh/ssh.component.ts | 6 +- .../system/routes/wifi/table.component.ts | 159 +++++++++++++----- .../system/routes/wifi/wifi.component.ts | 36 ++-- .../portal/routes/system/system.component.ts | 11 -- .../portal/routes/system/system.const.ts | 2 +- 11 files changed, 151 insertions(+), 95 deletions(-) diff --git a/web/projects/shared/src/i18n/dictionaries/de.ts b/web/projects/shared/src/i18n/dictionaries/de.ts index 16d7b9473..88de6c3a0 100644 --- a/web/projects/shared/src/i18n/dictionaries/de.ts +++ b/web/projects/shared/src/i18n/dictionaries/de.ts @@ -5,7 +5,7 @@ export default { 2: 'Aktualisieren', 4: 'System', 5: 'Allgemein', - 6: 'E-Mail', + 6: 'SMTP', 7: 'Sicherung erstellen', 8: 'Sicherung wiederherstellen', 9: 'Zum Login gehen', @@ -385,8 +385,8 @@ export default { 405: 'Verbunden', 406: 'Vergessen', 407: 'WiFi-Zugangsdaten', - 408: 'Veraltet', - 409: 'Die WLAN-Unterstützung wird in StartOS v0.4.1 entfernt. Wenn Sie keinen Zugriff auf Ethernet haben, können Sie einen WLAN-Extender verwenden, um sich mit dem lokalen Netzwerk zu verbinden und dann Ihren Server über Ethernet an den Extender anschließen. Bitte wenden Sie sich bei Fragen an den Start9-Support.', + 408: 'Mit verstecktem Netzwerk verbinden', + 409: 'Verbinden mit', 410: 'Bekannte Netzwerke', 411: 'Weitere Netzwerke', 412: 'WiFi ist deaktiviert', diff --git a/web/projects/shared/src/i18n/dictionaries/en.ts b/web/projects/shared/src/i18n/dictionaries/en.ts index d769ded05..f7d6d8e58 100644 --- a/web/projects/shared/src/i18n/dictionaries/en.ts +++ b/web/projects/shared/src/i18n/dictionaries/en.ts @@ -4,7 +4,7 @@ export const ENGLISH: Record = { 'Update': 2, // verb 'System': 4, // as in, system preferences 'General': 5, // as in, general settings - 'Email': 6, + 'SMTP': 6, 'Create Backup': 7, // create a backup 'Restore Backup': 8, // restore from backup 'Go to login': 9, @@ -384,8 +384,8 @@ export const ENGLISH: Record = { 'Connected': 405, 'Forget': 406, // as in, delete or remove 'WiFi Credentials': 407, - 'Deprecated': 408, - 'WiFi support will be removed in StartOS v0.4.1. If you do not have access to Ethernet, you can use a WiFi extender to connect to the local network, then connect your server to the extender via Ethernet. Please contact Start9 support with any questions or concerns.': 409, + 'Connect to hidden network': 408, + 'Connect to': 409, // followed by a network name, e.g. "Connect to MyWiFi?" 'Known Networks': 410, 'Other Networks': 411, 'WiFi is disabled': 412, diff --git a/web/projects/shared/src/i18n/dictionaries/es.ts b/web/projects/shared/src/i18n/dictionaries/es.ts index 1f82b395e..7875aa1b1 100644 --- a/web/projects/shared/src/i18n/dictionaries/es.ts +++ b/web/projects/shared/src/i18n/dictionaries/es.ts @@ -5,7 +5,7 @@ export default { 2: 'Actualizar', 4: 'Sistema', 5: 'General', - 6: 'Correo electrónico', + 6: 'SMTP', 7: 'Crear copia de seguridad', 8: 'Restaurar copia de seguridad', 9: 'Ir a inicio de sesión', @@ -385,8 +385,8 @@ export default { 405: 'Conectado', 406: 'Olvidar', 407: 'Credenciales WiFi', - 408: 'Obsoleto', - 409: 'El soporte para WiFi será eliminado en StartOS v0.4.1. Si no tienes acceso a Ethernet, puedes usar un extensor WiFi para conectarte a la red local y luego conectar tu servidor al extensor por Ethernet. Por favor, contacta al soporte de Start9 si tienes dudas o inquietudes.', + 408: 'Conectar a red oculta', + 409: 'Conectar a', 410: 'Redes conocidas', 411: 'Otras redes', 412: 'WiFi está deshabilitado', diff --git a/web/projects/shared/src/i18n/dictionaries/fr.ts b/web/projects/shared/src/i18n/dictionaries/fr.ts index db13e7d97..6b0dbf1fb 100644 --- a/web/projects/shared/src/i18n/dictionaries/fr.ts +++ b/web/projects/shared/src/i18n/dictionaries/fr.ts @@ -5,7 +5,7 @@ export default { 2: 'Mettre à jour', 4: 'Système', 5: 'Général', - 6: 'Email', + 6: 'SMTP', 7: 'Créer une sauvegarde', 8: 'Restaurer une sauvegarde', 9: 'Se connecter', @@ -385,8 +385,8 @@ export default { 405: 'Connecté', 406: 'Oublier', 407: 'Identifiants WiFi', - 408: 'Obsolète', - 409: 'Le support WiFi sera supprimé dans StartOS v0.4.1. Si vous n’avez pas accès à internet via Ethernet, vous pouvez utiliser un répéteur WiFi pour vous connecter au réseau local, puis brancher votre serveur sur le répéteur en Ethernet. Contactez le support Start9 pour toute question.', + 408: 'Se connecter à un réseau masqué', + 409: 'Se connecter à', 410: 'Réseaux connus', 411: 'Autres réseaux', 412: 'Le WiFi est désactivé', diff --git a/web/projects/shared/src/i18n/dictionaries/pl.ts b/web/projects/shared/src/i18n/dictionaries/pl.ts index 13a3c4671..8bb5bee92 100644 --- a/web/projects/shared/src/i18n/dictionaries/pl.ts +++ b/web/projects/shared/src/i18n/dictionaries/pl.ts @@ -5,7 +5,7 @@ export default { 2: 'Aktualizuj', 4: 'Ustawienia', 5: 'Ogólne', - 6: 'E-mail', + 6: 'SMTP', 7: 'Utwórz kopię zapasową', 8: 'Przywróć z kopii zapasowej', 9: 'Przejdź do logowania', @@ -385,8 +385,8 @@ export default { 405: 'Połączono', 406: 'Zapomnij', 407: 'Dane logowania WiFi', - 408: 'Przestarzałe', - 409: 'Obsługa WiFi zostanie usunięta w StartOS v0.4.1. Jeśli nie masz dostępu do sieci Ethernet, możesz użyć wzmacniacza WiFi do połączenia z siecią lokalną, a następnie podłączyć serwer do wzmacniacza przez Ethernet. W razie pytań lub wątpliwości skontaktuj się z pomocą techniczną Start9.', + 408: 'Połącz z ukrytą siecią', + 409: 'Połącz z', 410: 'Znane sieci', 411: 'Inne sieci', 412: 'WiFi jest wyłączone', diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/email/email.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/email/email.component.ts index 1c2d15bdd..8d6777beb 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/email/email.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/email/email.component.ts @@ -28,7 +28,7 @@ import { configBuilderToSpec } from 'src/app/utils/configBuilderToSpec' {{ 'Back' | i18n }} - {{ 'Email' | i18n }} + {{ 'SMTP' | i18n }} @if (form$ | async; as form) {
diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/ssh/ssh.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/ssh/ssh.component.ts index d23838165..853258973 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/ssh/ssh.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/ssh/ssh.component.ts @@ -160,7 +160,11 @@ export default class SystemSSHComponent { const loader = this.loader.open('Deleting').subscribe() try { - await this.api.deleteSshKey({ fingerprint: '' }) + await Promise.all( + fingerprints.map(fingerprint => + this.api.deleteSshKey({ fingerprint }), + ), + ) this.local$.next( all.filter(s => !fingerprints.includes(s.fingerprint)), ) diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/table.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/table.component.ts index 3a4803998..279614067 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/table.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/table.component.ts @@ -5,8 +5,23 @@ import { inject, Input, } from '@angular/core' -import { ErrorService, i18nPipe, LoadingService } from '@start9labs/shared' -import { TuiButton, TuiIcon, TuiTitle } from '@taiga-ui/core' +import { NgTemplateOutlet } from '@angular/common' +import { + DialogService, + ErrorService, + i18nPipe, + LoadingService, +} from '@start9labs/shared' +import { filter } from 'rxjs' +import { IST } from '@start9labs/start-sdk' +import { + TuiButton, + TuiDataList, + TuiDropdown, + TuiIcon, + TuiTextfield, + TuiTitle, +} from '@taiga-ui/core' import { TuiBadge, TuiFade } from '@taiga-ui/kit' import { TuiCell } from '@taiga-ui/layout' import { @@ -22,50 +37,78 @@ import { wifiSpec } from './wifi.const' @Component({ selector: '[wifi]', template: ` - @for (network of wifi; track $index) { - @if (network.ssid) { + + @if (getSignal(network.strength); as signal) { + + } @else { + + } + +
+ + {{ network.ssid }} + +
+ @if (network.connected) { + + {{ 'Connected' | i18n }} + + } + @if (network.connected === false) { + - } @else { - - } - @if (getSignal(network.strength); as signal) { - - } @else { - - } + } +
+ @for (network of wifi; track $index) { + @if (network.ssid) { + @if (network.connected === undefined) { + + } @else { +
+ +
+ } + } } `, styles: ` @@ -75,8 +118,6 @@ import { wifiSpec } from './wifi.const' } [tuiCell] { - padding-inline: 1rem !important; - &:disabled > * { opacity: 1; } @@ -88,11 +129,24 @@ import { wifiSpec } from './wifi.const' } `, changeDetection: ChangeDetectionStrategy.OnPush, - imports: [TuiCell, TuiTitle, TuiBadge, TuiButton, TuiIcon, TuiFade, i18nPipe], + imports: [ + NgTemplateOutlet, + TuiCell, + TuiTitle, + TuiBadge, + TuiButton, + TuiIcon, + TuiFade, + TuiDropdown, + TuiDataList, + TuiTextfield, + i18nPipe, + ], }) export class WifiTableComponent { private readonly loader = inject(LoadingService) private readonly errorService = inject(ErrorService) + private readonly dialogs = inject(DialogService) private readonly api = inject(ApiService) private readonly formDialog = inject(FormDialogService) private readonly component = inject(SystemWifiComponent) @@ -102,6 +156,8 @@ export class WifiTableComponent { @Input() wifi: readonly Wifi[] = [] + open = false + getSignal(signal: number) { if (signal < 5) { return null @@ -141,17 +197,30 @@ export class WifiTableComponent { async prompt(network: Wifi): Promise { if (!network.security.length) { - await this.component.saveAndConnect(network.ssid) + this.dialogs + .openConfirm({ + label: `${this.i18n.transform('Connect to')} ${network.ssid}?`, + size: 's', + }) + .pipe(filter(Boolean)) + .subscribe(() => this.component.saveAndConnect(network.ssid)) } else { + const ssid = wifiSpec.spec['ssid'] as IST.ValueSpecText + const spec: IST.InputSpec = { + ...wifiSpec.spec, + ssid: { ...ssid, disabled: 'ssid', default: network.ssid }, + } + this.formDialog.open>(FormComponent, { label: 'Password needed', data: { - spec: wifiSpec.spec, + spec, + value: { ssid: network.ssid, password: '' }, buttons: [ { text: this.i18n.transform('Connect')!, - handler: async ({ ssid, password }) => - this.component.saveAndConnect(ssid, password), + handler: async ({ password }) => + this.component.saveAndConnect(network.ssid, password), }, ], }, diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/wifi.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/wifi.component.ts index e69631610..056bdbedd 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/wifi.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/wifi/wifi.component.ts @@ -8,6 +8,7 @@ import { toSignal } from '@angular/core/rxjs-interop' import { FormsModule } from '@angular/forms' import { RouterLink } from '@angular/router' import { + DocsLinkDirective, ErrorService, i18nKey, i18nPipe, @@ -19,11 +20,9 @@ import { TuiAppearance, TuiButton, TuiLoader, - TuiNotification, - TuiTitle, } from '@taiga-ui/core' import { TuiSwitch } from '@taiga-ui/kit' -import { TuiCardLarge, TuiHeader } from '@taiga-ui/layout' +import { TuiCardLarge } from '@taiga-ui/layout' import { PatchDB } from 'patch-db-client' import { catchError, defer, map, merge, Observable, of, Subject } from 'rxjs' import { @@ -47,23 +46,20 @@ import { wifiSpec } from './wifi.const' WiFi -
- -
- {{ 'Deprecated' | i18n }} -
- {{ - 'WiFi support will be removed in StartOS v0.4.1. If you do not have access to Ethernet, you can use a WiFi extender to connect to the local network, then connect your server to the extender via Ethernet. Please contact Start9 support with any questions or concerns.' - | i18n - }} -
-
-
-
@if (status()?.interface) {
Wi-Fi + + {{ 'Documentation' | i18n }} + }

-

} @else { @@ -128,10 +124,8 @@ import { wifiSpec } from './wifi.const' TitleDirective, RouterLink, PlaceholderComponent, - TuiHeader, - TuiTitle, - TuiNotification, i18nPipe, + DocsLinkDirective, ], }) export default class SystemWifiComponent { diff --git a/web/projects/ui/src/app/routes/portal/routes/system/system.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/system.component.ts index ca2384a11..af6fb2f13 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/system.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/system.component.ts @@ -1,4 +1,3 @@ -import { AsyncPipe } from '@angular/common' import { ChangeDetectionStrategy, Component, inject } from '@angular/core' import { toSignal } from '@angular/core/rxjs-interop' import { RouterModule } from '@angular/router' @@ -6,12 +5,9 @@ import { i18nPipe } from '@start9labs/shared' import { TuiIcon, TuiTitle } from '@taiga-ui/core' import { TuiBadgeNotification } from '@taiga-ui/kit' import { TuiCell } from '@taiga-ui/layout' -import { PatchDB } from 'patch-db-client' import { BadgeService } from 'src/app/services/badge.service' -import { DataModel } from 'src/app/services/patch-db/data-model' import { TitleDirective } from 'src/app/services/title.service' import { SYSTEM_MENU } from './system.const' -import { map } from 'rxjs' @Component({ template: ` @@ -26,9 +22,6 @@ import { map } from 'rxjs' tuiCell="s" routerLinkActive="active" [routerLink]="page.link" - [style.display]=" - !(wifiEnabled$ | async) && page.item === 'WiFi' ? 'none' : null - " > @@ -116,13 +109,9 @@ import { map } from 'rxjs' TitleDirective, TuiBadgeNotification, i18nPipe, - AsyncPipe, ], }) export class SystemComponent { readonly menu = SYSTEM_MENU readonly badge = toSignal(inject(BadgeService).getCount('system')) - readonly wifiEnabled$ = inject>(PatchDB) - .watch$('serverInfo', 'network', 'wifi') - .pipe(map(wifi => !!wifi.interface && wifi.enabled)) } diff --git a/web/projects/ui/src/app/routes/portal/routes/system/system.const.ts b/web/projects/ui/src/app/routes/portal/routes/system/system.const.ts index 22c4dbaa9..5b616fcca 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/system.const.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/system.const.ts @@ -28,7 +28,7 @@ export const SYSTEM_MENU = [ }, { icon: '@tui.mail', - item: 'Email', + item: 'SMTP', link: 'email', }, {