mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
limit adding gateway to StartTunnel, better copy around Tor SSL (#3033)
* limit adding gateway to StartTunnel, better copy around Tor SSL * properly differentiate ssl * exclude disconnected gateways * better error handling --------- Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
@@ -135,11 +135,12 @@ impl BindInfo {
|
||||
}
|
||||
impl InterfaceFilter for NetInfo {
|
||||
fn filter(&self, id: &GatewayId, info: &NetworkInterfaceInfo) -> bool {
|
||||
if info.public() {
|
||||
self.public_enabled.contains(id)
|
||||
} else {
|
||||
!self.private_disabled.contains(id)
|
||||
}
|
||||
info.ip_info.is_some()
|
||||
&& if info.public() {
|
||||
self.public_enabled.contains(id)
|
||||
} else {
|
||||
!self.private_disabled.contains(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,10 @@ type FormatReturnTy<
|
||||
export type Filled = {
|
||||
hostnames: HostnameInfo[]
|
||||
|
||||
toUrl: (h: HostnameInfo) => UrlString[]
|
||||
toUrls: (h: HostnameInfo) => {
|
||||
url: UrlString | null
|
||||
sslUrl: UrlString | null
|
||||
}
|
||||
|
||||
filter: <F extends Filter, Format extends Formats = "urlstring">(
|
||||
filter: F,
|
||||
@@ -139,7 +142,7 @@ const unique = <A>(values: A[]) => Array.from(new Set(values))
|
||||
export const addressHostToUrl = (
|
||||
{ scheme, sslScheme, username, suffix }: AddressInfo,
|
||||
hostname: HostnameInfo,
|
||||
): UrlString[] => {
|
||||
): { url: UrlString | null; sslUrl: UrlString | null } => {
|
||||
const res = []
|
||||
const fmt = (scheme: string | null, host: HostnameInfo, port: number) => {
|
||||
const excludePort =
|
||||
@@ -164,14 +167,16 @@ export const addressHostToUrl = (
|
||||
username ? `${username}@` : ""
|
||||
}${hostname}${excludePort ? "" : `:${port}`}${suffix}`
|
||||
}
|
||||
let url = null
|
||||
if (hostname.hostname.sslPort !== null) {
|
||||
res.push(fmt(sslScheme, hostname, hostname.hostname.sslPort))
|
||||
url = fmt(sslScheme, hostname, hostname.hostname.sslPort)
|
||||
}
|
||||
let sslUrl = null
|
||||
if (hostname.hostname.port !== null) {
|
||||
res.push(fmt(scheme, hostname, hostname.hostname.port))
|
||||
sslUrl = fmt(scheme, hostname, hostname.hostname.port)
|
||||
}
|
||||
|
||||
return res
|
||||
return { url, sslUrl }
|
||||
}
|
||||
|
||||
function filterRec(
|
||||
@@ -223,13 +228,17 @@ export const filledAddress = (
|
||||
host: Host,
|
||||
addressInfo: AddressInfo,
|
||||
): FilledAddressInfo => {
|
||||
const toUrl = addressHostToUrl.bind(null, addressInfo)
|
||||
const toUrls = addressHostToUrl.bind(null, addressInfo)
|
||||
const toUrlArray = (h: HostnameInfo) => {
|
||||
const u = toUrls(h)
|
||||
return [u.url, u.sslUrl].filter((u) => u !== null)
|
||||
}
|
||||
const hostnames = host.hostnameInfo[addressInfo.internalPort] ?? []
|
||||
|
||||
return {
|
||||
...addressInfo,
|
||||
hostnames,
|
||||
toUrl,
|
||||
toUrls,
|
||||
filter: <F extends Filter, Format extends Formats = "urlstring">(
|
||||
filter: F,
|
||||
format?: Format,
|
||||
@@ -237,7 +246,7 @@ export const filledAddress = (
|
||||
const filtered = filterRec(hostnames, filter, false)
|
||||
let res: FormatReturnTy<F, Format>[] = filtered as any
|
||||
if (format === "hostname-info") return res
|
||||
const urls = filtered.flatMap(toUrl)
|
||||
const urls = filtered.flatMap(toUrlArray)
|
||||
if (format === "url") res = urls.map((u) => new URL(u)) as any
|
||||
else res = urls as any
|
||||
return res
|
||||
@@ -279,28 +288,28 @@ export const filledAddress = (
|
||||
)
|
||||
},
|
||||
get urls() {
|
||||
return this.hostnames.flatMap(toUrl)
|
||||
return this.hostnames.flatMap(toUrlArray)
|
||||
},
|
||||
get publicUrls() {
|
||||
return this.publicHostnames.flatMap(toUrl)
|
||||
return this.publicHostnames.flatMap(toUrlArray)
|
||||
},
|
||||
get onionUrls() {
|
||||
return this.onionHostnames.flatMap(toUrl)
|
||||
return this.onionHostnames.flatMap(toUrlArray)
|
||||
},
|
||||
get localUrls() {
|
||||
return this.localHostnames.flatMap(toUrl)
|
||||
return this.localHostnames.flatMap(toUrlArray)
|
||||
},
|
||||
get ipUrls() {
|
||||
return this.ipHostnames.flatMap(toUrl)
|
||||
return this.ipHostnames.flatMap(toUrlArray)
|
||||
},
|
||||
get ipv4Urls() {
|
||||
return this.ipv4Hostnames.flatMap(toUrl)
|
||||
return this.ipv4Hostnames.flatMap(toUrlArray)
|
||||
},
|
||||
get ipv6Urls() {
|
||||
return this.ipv6Hostnames.flatMap(toUrl)
|
||||
return this.ipv6Hostnames.flatMap(toUrlArray)
|
||||
},
|
||||
get nonIpUrls() {
|
||||
return this.nonIpHostnames.flatMap(toUrl)
|
||||
return this.nonIpHostnames.flatMap(toUrlArray)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ export default {
|
||||
531: 'Fehler beim Initialisieren des Servers',
|
||||
532: 'Abgeschlossen',
|
||||
533: 'Gateways',
|
||||
535: 'Gateway hinzufügen',
|
||||
535: 'StartTunnel-Gateway hinzufügen',
|
||||
536: 'Umbenennen',
|
||||
537: 'Zugriff',
|
||||
538: 'Öffentliche Domains',
|
||||
@@ -535,10 +535,8 @@ export default {
|
||||
569: 'Wählen Sie eine Zertifizierungsstelle aus, um SSL/TLS-Zertifikate für diese Domain auszustellen.',
|
||||
570: 'Andere',
|
||||
571: 'Ein Name zur einfachen Identifizierung des Gateways',
|
||||
572: 'Wählen Sie diese Option, wenn das Gateway für den privaten Zugriff nur für autorisierte Clients konfiguriert ist. StartTunnel ist ein privates Gateway.',
|
||||
573: 'Wählen Sie diese Option, wenn das Gateway für uneingeschränkten öffentlichen Zugriff konfiguriert ist.',
|
||||
574: 'Datei',
|
||||
575: 'Wireguard-Konfigurationsdatei',
|
||||
575: 'StartTunnel-Konfigurationsdatei',
|
||||
576: 'Kopieren/Einfügen',
|
||||
577: 'Dateiinhalt',
|
||||
578: 'Öffentlicher Schlüssel',
|
||||
@@ -550,7 +548,7 @@ export default {
|
||||
584: 'Verbindungen können manchmal langsam oder unzuverlässig sein',
|
||||
585: 'Öffentlich, wenn Sie die Adresse öffentlich teilen, andernfalls privat',
|
||||
586: 'Erfordert ein Tor-fähiges Gerät oder einen Browser',
|
||||
587: 'Nur nützlich für Clients, die HTTPS erzwingen',
|
||||
587: 'Nur nützlich für Clients, die SSL erzwingen',
|
||||
588: 'Ideal für anonyme, zensurresistente Bereitstellung und Fernzugriff',
|
||||
589: 'Ideal für lokalen Zugriff',
|
||||
590: 'Erfordert die Verbindung mit demselben lokalen Netzwerk (LAN) wie Ihr Server, entweder physisch oder über VPN',
|
||||
@@ -589,4 +587,5 @@ export default {
|
||||
623: 'Alternative Implementierungen',
|
||||
624: 'Versionen',
|
||||
625: 'Eine andere Version auswählen',
|
||||
626: 'Hochladen',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -501,7 +501,7 @@ export const ENGLISH = {
|
||||
'Error initializing server': 531,
|
||||
'Finished': 532, // an in, complete
|
||||
'Gateways': 533, // as in, a device or software that connects two different networks
|
||||
'Add gateway': 535, // as in, add a new network gateway to StartOS
|
||||
'Add StartTunnel Gateway': 535, // as in, add a new StartTunnel network gateway to StartOS
|
||||
'Rename': 536,
|
||||
'Access': 537, // as in, public or private access, almost "permission"
|
||||
'Public Domains': 538, // as in, internet domains
|
||||
@@ -534,10 +534,8 @@ export const ENGLISH = {
|
||||
'Select a Certificate Authority to issue SSL/TLS certificates for this domain': 569,
|
||||
'Other': 570, // as in, a list option to indicate none of the options listed
|
||||
'A name to easily identify the gateway': 571,
|
||||
'select this option if the gateway is configured for private access to authorized clients only. StartTunnel is a private gateway.': 572,
|
||||
'select this option if the gateway is configured for unfettered public access.': 573,
|
||||
'File': 574, // as in, a computer file
|
||||
'Wireguard Config File': 575,
|
||||
'StartTunnel Config File': 575,
|
||||
'Copy/Paste': 576,
|
||||
'File Contents': 577,
|
||||
'Public Key': 578, // as in, a cryptographic public key
|
||||
@@ -549,7 +547,7 @@ export const ENGLISH = {
|
||||
'Connections can be slow or unreliable at times': 584,
|
||||
'Public if you share the address publicly, otherwise private': 585,
|
||||
'Requires using a Tor-enabled device or browser': 586,
|
||||
'Only useful for clients that enforce HTTPS': 587,
|
||||
'Only useful for clients that require SSL': 587,
|
||||
'Ideal for anonymous, censorship-resistant hosting and remote access': 588,
|
||||
'Ideal for local access': 589,
|
||||
'Requires being connected to the same Local Area Network (LAN) as your server, either physically or via VPN': 590,
|
||||
@@ -588,4 +586,5 @@ export const ENGLISH = {
|
||||
'Alternative Implementations': 623,
|
||||
'Versions': 624,
|
||||
'Select another version': 625,
|
||||
'Upload': 626, // as in, upload a file
|
||||
} as const
|
||||
|
||||
@@ -502,7 +502,7 @@ export default {
|
||||
531: 'Error al inicializar el servidor',
|
||||
532: 'Finalizado',
|
||||
533: 'Puertas de enlace',
|
||||
535: 'Agregar puerta de enlace',
|
||||
535: 'Agregar puerta de enlace StartTunnel',
|
||||
536: 'Renombrar',
|
||||
537: 'Acceso',
|
||||
538: 'Dominios públicos',
|
||||
@@ -535,10 +535,8 @@ export default {
|
||||
569: 'Selecciona una Autoridad Certificadora para emitir certificados SSL/TLS para este dominio.',
|
||||
570: 'Otro',
|
||||
571: 'Un nombre para identificar fácilmente la puerta de enlace',
|
||||
572: 'Selecciona esta opción si la puerta de enlace está configurada para acceso privado solo a clientes autorizados. StartTunnel es una puerta de enlace privada.',
|
||||
573: 'Selecciona esta opción si la puerta de enlace está configurada para acceso público sin restricciones.',
|
||||
574: 'Archivo',
|
||||
575: 'Archivo de configuración de Wireguard',
|
||||
575: 'Archivo de configuración de StartTunnel',
|
||||
576: 'Copiar/Pegar',
|
||||
577: 'Contenido del archivo',
|
||||
578: 'Clave pública',
|
||||
@@ -550,7 +548,7 @@ export default {
|
||||
584: 'Las conexiones pueden ser lentas o poco confiables a veces',
|
||||
585: 'Público si compartes la dirección públicamente, de lo contrario privado',
|
||||
586: 'Requiere un dispositivo o navegador habilitado para Tor',
|
||||
587: 'Solo útil para clientes que imponen HTTPS',
|
||||
587: 'Solo útil para clientes que imponen SSL',
|
||||
588: 'Ideal para alojamiento y acceso remoto anónimo y resistente a la censura',
|
||||
589: 'Ideal para acceso local',
|
||||
590: 'Requiere estar conectado a la misma red de área local (LAN) que tu servidor, ya sea físicamente o mediante VPN',
|
||||
@@ -589,4 +587,5 @@ export default {
|
||||
623: 'Implementaciones alternativas',
|
||||
624: 'Versiones',
|
||||
625: 'Seleccionar otra versión',
|
||||
626: 'Subir',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -502,7 +502,7 @@ export default {
|
||||
531: "Erreur lors de l'initialisation du serveur",
|
||||
532: 'Terminé',
|
||||
533: 'Passerelles',
|
||||
535: 'Ajouter une passerelle',
|
||||
535: 'Ajouter une passerelle StartTunnel',
|
||||
536: 'Renommer',
|
||||
537: 'Accès',
|
||||
538: 'Domaines publics',
|
||||
@@ -535,10 +535,8 @@ export default {
|
||||
569: 'Sélectionnez une Autorité de Certification pour émettre des certificats SSL/TLS pour ce domaine.',
|
||||
570: 'Autre',
|
||||
571: 'Un nom pour identifier facilement la passerelle',
|
||||
572: 'Sélectionnez cette option si la passerelle est configurée pour un accès privé uniquement aux clients autorisés. StartTunnel est une passerelle privée.',
|
||||
573: 'Sélectionnez cette option si la passerelle est configurée pour un accès public illimité.',
|
||||
574: 'Fichier',
|
||||
575: 'Fichier de configuration Wireguard',
|
||||
575: 'Fichier de configuration StartTunnel',
|
||||
576: 'Copier/Coller',
|
||||
577: 'Contenu du fichier',
|
||||
578: 'Clé publique',
|
||||
@@ -550,7 +548,7 @@ export default {
|
||||
584: 'Les connexions peuvent parfois être lentes ou peu fiables',
|
||||
585: 'Public si vous partagez l’adresse publiquement, sinon privé',
|
||||
586: 'Nécessite un appareil ou un navigateur compatible Tor',
|
||||
587: 'Utile uniquement pour les clients qui imposent HTTPS',
|
||||
587: 'Utile uniquement pour les clients qui imposent SSL',
|
||||
588: 'Idéal pour l’hébergement et l’accès à distance anonymes et résistants à la censure',
|
||||
589: 'Idéal pour un accès local',
|
||||
590: 'Nécessite d’être connecté au même réseau local (LAN) que votre serveur, soit physiquement, soit via VPN',
|
||||
@@ -589,4 +587,5 @@ export default {
|
||||
623: 'Implémentations alternatives',
|
||||
624: 'Versions',
|
||||
625: 'Sélectionner une autre version',
|
||||
626: 'Téléverser',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -502,7 +502,7 @@ export default {
|
||||
531: 'Błąd inicjalizacji serwera',
|
||||
532: 'Zakończono',
|
||||
533: 'Bramy sieciowe',
|
||||
535: 'Dodaj bramę',
|
||||
535: 'Dodaj bramę StartTunnel',
|
||||
536: 'Zmień nazwę',
|
||||
537: 'Dostęp',
|
||||
538: 'Domeny publiczne',
|
||||
@@ -535,10 +535,8 @@ export default {
|
||||
569: 'Wybierz Urząd Certyfikacji, aby wystawić certyfikaty SSL/TLS dla tej domeny.',
|
||||
570: 'Inne',
|
||||
571: 'Nazwa ułatwiająca identyfikację bramy',
|
||||
572: 'Wybierz tę opcję, jeśli brama jest skonfigurowana do prywatnego dostępu tylko dla autoryzowanych klientów. StartTunnel to prywatna brama.',
|
||||
573: 'Wybierz tę opcję, jeśli brama jest skonfigurowana do nieograniczonego publicznego dostępu.',
|
||||
574: 'Plik',
|
||||
575: 'Plik konfiguracyjny Wireguard',
|
||||
575: 'Plik konfiguracyjny StartTunnel',
|
||||
576: 'Kopiuj/Wklej',
|
||||
577: 'Zawartość pliku',
|
||||
578: 'Klucz publiczny',
|
||||
@@ -550,7 +548,7 @@ export default {
|
||||
584: 'Połączenia mogą być czasami wolne lub niestabilne',
|
||||
585: 'Publiczne, jeśli udostępniasz adres publicznie, w przeciwnym razie prywatne',
|
||||
586: 'Wymaga urządzenia lub przeglądarki obsługującej Tor',
|
||||
587: 'Przydatne tylko dla klientów wymuszających HTTPS',
|
||||
587: 'Przydatne tylko dla klientów wymuszających SSL',
|
||||
588: 'Idealne do anonimowego, odpornego na cenzurę hostingu i zdalnego dostępu',
|
||||
589: 'Idealne do dostępu lokalnego',
|
||||
590: 'Wymaga połączenia z tą samą siecią lokalną (LAN) co serwer, fizycznie lub przez VPN',
|
||||
@@ -589,4 +587,5 @@ export default {
|
||||
623: 'Alternatywne implementacje',
|
||||
624: 'Wersje',
|
||||
625: 'Wybierz inną wersję',
|
||||
626: 'Prześlij',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -7,6 +7,7 @@ import { i18nKey, i18nPipe } from '@start9labs/shared'
|
||||
|
||||
type AddressWithInfo = {
|
||||
url: string
|
||||
ssl: boolean
|
||||
info: T.HostnameInfo
|
||||
gateway?: GatewayPlus
|
||||
}
|
||||
@@ -132,12 +133,26 @@ export class InterfaceService {
|
||||
|
||||
if (!hostnamesInfos.length) return addresses
|
||||
|
||||
const allAddressesWithInfo: AddressWithInfo[] = hostnamesInfos.flatMap(h =>
|
||||
utils.addressHostToUrl(serviceInterface.addressInfo, h).map(url => ({
|
||||
url,
|
||||
info: h,
|
||||
gateway: gateways.find(g => h.kind === 'ip' && h.gateway.id === g.id),
|
||||
})),
|
||||
const allAddressesWithInfo: AddressWithInfo[] = hostnamesInfos.flatMap(
|
||||
h => {
|
||||
const { url, sslUrl } = utils.addressHostToUrl(
|
||||
serviceInterface.addressInfo,
|
||||
h,
|
||||
)
|
||||
const info = h
|
||||
const gateway =
|
||||
h.kind === 'ip'
|
||||
? gateways.find(g => h.gateway.id === g.id)
|
||||
: undefined
|
||||
const res = []
|
||||
if (url) {
|
||||
res.push({ url, ssl: false, info, gateway })
|
||||
}
|
||||
if (sslUrl) {
|
||||
res.push({ url: sslUrl, ssl: true, info, gateway })
|
||||
}
|
||||
return res
|
||||
},
|
||||
)
|
||||
|
||||
const torAddrs = allAddressesWithInfo.filter(filterTor).sort(cmpTor)
|
||||
@@ -311,7 +326,7 @@ export class InterfaceService {
|
||||
}
|
||||
|
||||
private toDisplayAddress(
|
||||
{ info, url, gateway }: AddressWithInfo,
|
||||
{ info, ssl, url, gateway }: AddressWithInfo,
|
||||
publicDomains: Record<string, T.PublicDomainConfig>,
|
||||
): DisplayAddress {
|
||||
let access: DisplayAddress['access']
|
||||
@@ -335,33 +350,29 @@ export class InterfaceService {
|
||||
),
|
||||
this.i18n.transform('Requires using a Tor-enabled device or browser'),
|
||||
]
|
||||
// Tor (HTTPS)
|
||||
if (url.startsWith('https:')) {
|
||||
type = `${type} (HTTPS)`
|
||||
// Tor (SSL)
|
||||
if (ssl) {
|
||||
type = `${type} (SSL)`
|
||||
bullets = [
|
||||
this.i18n.transform('Only useful for clients that enforce HTTPS'),
|
||||
this.i18n.transform('Only useful for clients that require SSL'),
|
||||
rootCaRequired,
|
||||
...bullets,
|
||||
]
|
||||
// Tor (HTTP)
|
||||
// Tor (NON-SSL)
|
||||
} else {
|
||||
bullets.unshift(
|
||||
this.i18n.transform(
|
||||
'Ideal for anonymous, censorship-resistant hosting and remote access',
|
||||
),
|
||||
)
|
||||
if (url.startsWith('http:')) {
|
||||
type = `${type} (HTTP)`
|
||||
}
|
||||
}
|
||||
// ** Not Tor **
|
||||
} else {
|
||||
const port = info.hostname.sslPort || info.hostname.port
|
||||
const g = gateway!
|
||||
gatewayName = g.name
|
||||
gatewayName = info.gateway.name
|
||||
|
||||
const gatewayLanIpv4 = g.lanIpv4[0]
|
||||
const isWireguard = g.ipInfo.deviceType === 'wireguard'
|
||||
const gatewayLanIpv4 = gateway?.lanIpv4[0]
|
||||
const isWireguard = gateway?.ipInfo.deviceType === 'wireguard'
|
||||
|
||||
const localIdeal = this.i18n.transform('Ideal for local access')
|
||||
const lanRequired = this.i18n.transform(
|
||||
@@ -402,9 +413,9 @@ export class InterfaceService {
|
||||
),
|
||||
rootCaRequired,
|
||||
]
|
||||
if (!g.public) {
|
||||
if (!info.gateway.public) {
|
||||
bullets.push(
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${g.subnets.find(s => s.isIpv4())?.address}:${port}`,
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${gateway?.subnets.find(s => s.isIpv4())?.address}:${port}`,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@@ -436,12 +447,12 @@ export class InterfaceService {
|
||||
if (info.public) {
|
||||
access = 'public'
|
||||
bullets = [
|
||||
`${dnsFor} ${info.hostname.value} ${resolvesTo} ${g.ipInfo.wanIp}`,
|
||||
`${dnsFor} ${info.hostname.value} ${resolvesTo} ${gateway?.ipInfo.wanIp}`,
|
||||
]
|
||||
|
||||
if (!g.public) {
|
||||
if (!info.gateway.public) {
|
||||
bullets.push(
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${g.subnets.find(s => s.isIpv4())?.address}:${port === 443 ? 5443 : port}`,
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${gateway?.subnets.find(s => s.isIpv4())?.address}:${port === 443 ? 5443 : port}`,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -83,18 +83,10 @@ export default class GatewaysComponent {
|
||||
),
|
||||
required: true,
|
||||
default: null,
|
||||
}),
|
||||
type: ISB.Value.select({
|
||||
name: this.i18n.transform('Type'),
|
||||
description: `-**${this.i18n.transform('private')}**: ${this.i18n.transform('select this option if the gateway is configured for private access to authorized clients only. StartTunnel is a private gateway.')}\n-**${this.i18n.transform('public')}**: ${this.i18n.transform('select this option if the gateway is configured for unfettered public access.')}`,
|
||||
default: 'private',
|
||||
values: {
|
||||
private: this.i18n.transform('private'),
|
||||
public: this.i18n.transform('public'),
|
||||
},
|
||||
placeholder: 'StartTunnel 1',
|
||||
}),
|
||||
config: ISB.Value.union({
|
||||
name: this.i18n.transform('Wireguard Config File'),
|
||||
name: this.i18n.transform('StartTunnel Config File'),
|
||||
default: 'paste',
|
||||
variants: ISB.Variants.of({
|
||||
paste: {
|
||||
@@ -108,7 +100,7 @@ export default class GatewaysComponent {
|
||||
}),
|
||||
},
|
||||
select: {
|
||||
name: this.i18n.transform('Select'),
|
||||
name: this.i18n.transform('Upload'),
|
||||
spec: ISB.InputSpec.of({
|
||||
file: ISB.Value.file({
|
||||
name: this.i18n.transform('File'),
|
||||
@@ -122,7 +114,7 @@ export default class GatewaysComponent {
|
||||
})
|
||||
|
||||
this.formDialog.open(FormComponent, {
|
||||
label: 'Add gateway',
|
||||
label: 'Add StartTunnel Gateway',
|
||||
data: {
|
||||
spec: await configBuilderToSpec(spec),
|
||||
buttons: [
|
||||
@@ -138,7 +130,7 @@ export default class GatewaysComponent {
|
||||
input.config.selection === 'paste'
|
||||
? input.config.value.file
|
||||
: await (input.config.value.file as any as File).text(),
|
||||
public: input.type === 'public',
|
||||
public: false,
|
||||
})
|
||||
return true
|
||||
} catch (e: any) {
|
||||
|
||||
Reference in New Issue
Block a user