mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-17 19:16:32 +02:00
Add new ssh config for private resources
This commit is contained in:
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Метод",
|
"editInternalResourceDialogScheme": "Метод",
|
||||||
"editInternalResourceDialogEnableSsl": "Активирайте TLS",
|
"editInternalResourceDialogEnableSsl": "Активирайте TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Активирайте SSL/TLS криптиране за сигурни HTTPS връзки към целта.",
|
"editInternalResourceDialogEnableSslDescription": "Активирайте SSL/TLS криптиране за сигурни HTTPS връзки към целта.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Метод",
|
"scheme": "Метод",
|
||||||
"createInternalResourceDialogScheme": "Метод",
|
"createInternalResourceDialogScheme": "Метод",
|
||||||
"createInternalResourceDialogEnableSsl": "Активирайте TLS",
|
"createInternalResourceDialogEnableSsl": "Активирайте TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Schéma",
|
"editInternalResourceDialogScheme": "Schéma",
|
||||||
"editInternalResourceDialogEnableSsl": "Povolit SSL",
|
"editInternalResourceDialogEnableSsl": "Povolit SSL",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Povolit šifrování SSL/TLS pro zabezpečené HTTPS připojení k cíli.",
|
"editInternalResourceDialogEnableSslDescription": "Povolit šifrování SSL/TLS pro zabezpečené HTTPS připojení k cíli.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Schéma",
|
"scheme": "Schéma",
|
||||||
"createInternalResourceDialogScheme": "Schéma",
|
"createInternalResourceDialogScheme": "Schéma",
|
||||||
"createInternalResourceDialogEnableSsl": "Povolit SSL",
|
"createInternalResourceDialogEnableSsl": "Povolit SSL",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Schema",
|
"editInternalResourceDialogScheme": "Schema",
|
||||||
"editInternalResourceDialogEnableSsl": "TLS aktivieren",
|
"editInternalResourceDialogEnableSsl": "TLS aktivieren",
|
||||||
"editInternalResourceDialogEnableSslDescription": "SSL/TLS-Verschlüsselung für sichere HTTPS-Verbindungen zum Ziel aktivieren.",
|
"editInternalResourceDialogEnableSslDescription": "SSL/TLS-Verschlüsselung für sichere HTTPS-Verbindungen zum Ziel aktivieren.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Schema",
|
"scheme": "Schema",
|
||||||
"createInternalResourceDialogScheme": "Schema",
|
"createInternalResourceDialogScheme": "Schema",
|
||||||
"createInternalResourceDialogEnableSsl": "TLS aktivieren",
|
"createInternalResourceDialogEnableSsl": "TLS aktivieren",
|
||||||
|
|||||||
@@ -2110,6 +2110,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Scheme",
|
"editInternalResourceDialogScheme": "Scheme",
|
||||||
"editInternalResourceDialogEnableSsl": "Enable TLS",
|
"editInternalResourceDialogEnableSsl": "Enable TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Enable SSL/TLS encryption for secure HTTPS connections to the destination.",
|
"editInternalResourceDialogEnableSslDescription": "Enable SSL/TLS encryption for secure HTTPS connections to the destination.",
|
||||||
@@ -2159,6 +2160,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Scheme",
|
"scheme": "Scheme",
|
||||||
"createInternalResourceDialogScheme": "Scheme",
|
"createInternalResourceDialogScheme": "Scheme",
|
||||||
"createInternalResourceDialogEnableSsl": "Enable TLS",
|
"createInternalResourceDialogEnableSsl": "Enable TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Esquema",
|
"editInternalResourceDialogScheme": "Esquema",
|
||||||
"editInternalResourceDialogEnableSsl": "Activar TLS",
|
"editInternalResourceDialogEnableSsl": "Activar TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Habilitar cifrado SSL/TLS para conexiones HTTPS seguras al destino.",
|
"editInternalResourceDialogEnableSslDescription": "Habilitar cifrado SSL/TLS para conexiones HTTPS seguras al destino.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Esquema",
|
"scheme": "Esquema",
|
||||||
"createInternalResourceDialogScheme": "Esquema",
|
"createInternalResourceDialogScheme": "Esquema",
|
||||||
"createInternalResourceDialogEnableSsl": "Activar TLS",
|
"createInternalResourceDialogEnableSsl": "Activar TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Méthode HTTP",
|
"editInternalResourceDialogScheme": "Méthode HTTP",
|
||||||
"editInternalResourceDialogEnableSsl": "Activer TLS",
|
"editInternalResourceDialogEnableSsl": "Activer TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Activer le cryptage SSL/TLS pour des connexions HTTPS sécurisées vers la destination.",
|
"editInternalResourceDialogEnableSslDescription": "Activer le cryptage SSL/TLS pour des connexions HTTPS sécurisées vers la destination.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Méthode HTTP",
|
"scheme": "Méthode HTTP",
|
||||||
"createInternalResourceDialogScheme": "Méthode HTTP",
|
"createInternalResourceDialogScheme": "Méthode HTTP",
|
||||||
"createInternalResourceDialogEnableSsl": "Activer TLS",
|
"createInternalResourceDialogEnableSsl": "Activer TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Metodo HTTP",
|
"editInternalResourceDialogScheme": "Metodo HTTP",
|
||||||
"editInternalResourceDialogEnableSsl": "Abilitare TLS",
|
"editInternalResourceDialogEnableSsl": "Abilitare TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Abilita la crittografia SSL/TLS per connessioni HTTPS sicure alla destinazione.",
|
"editInternalResourceDialogEnableSslDescription": "Abilita la crittografia SSL/TLS per connessioni HTTPS sicure alla destinazione.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Metodo HTTP",
|
"scheme": "Metodo HTTP",
|
||||||
"createInternalResourceDialogScheme": "Metodo HTTP",
|
"createInternalResourceDialogScheme": "Metodo HTTP",
|
||||||
"createInternalResourceDialogEnableSsl": "Abilitare TLS",
|
"createInternalResourceDialogEnableSsl": "Abilitare TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "스킴",
|
"editInternalResourceDialogScheme": "스킴",
|
||||||
"editInternalResourceDialogEnableSsl": "TLS 활성화",
|
"editInternalResourceDialogEnableSsl": "TLS 활성화",
|
||||||
"editInternalResourceDialogEnableSslDescription": "목적지로의 안전한 HTTPS 연결을 위한 SSL/TLS 암호화 활성화.",
|
"editInternalResourceDialogEnableSslDescription": "목적지로의 안전한 HTTPS 연결을 위한 SSL/TLS 암호화 활성화.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "스킴",
|
"scheme": "스킴",
|
||||||
"createInternalResourceDialogScheme": "스킴",
|
"createInternalResourceDialogScheme": "스킴",
|
||||||
"createInternalResourceDialogEnableSsl": "TLS 활성화",
|
"createInternalResourceDialogEnableSsl": "TLS 활성화",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Skjema",
|
"editInternalResourceDialogScheme": "Skjema",
|
||||||
"editInternalResourceDialogEnableSsl": "Aktiver TLS",
|
"editInternalResourceDialogEnableSsl": "Aktiver TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Aktiver SSL/TLS-kryptering for sikre HTTPS-tilkoblinger til destinasjonen.",
|
"editInternalResourceDialogEnableSslDescription": "Aktiver SSL/TLS-kryptering for sikre HTTPS-tilkoblinger til destinasjonen.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Skjema",
|
"scheme": "Skjema",
|
||||||
"createInternalResourceDialogScheme": "Skjema",
|
"createInternalResourceDialogScheme": "Skjema",
|
||||||
"createInternalResourceDialogEnableSsl": "Aktiver TLS",
|
"createInternalResourceDialogEnableSsl": "Aktiver TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Schema",
|
"editInternalResourceDialogScheme": "Schema",
|
||||||
"editInternalResourceDialogEnableSsl": "TLS inschakelen",
|
"editInternalResourceDialogEnableSsl": "TLS inschakelen",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Schakel SSL/TLS-encryptie in voor beveiligde HTTPS-verbindingen met de bestemming.",
|
"editInternalResourceDialogEnableSslDescription": "Schakel SSL/TLS-encryptie in voor beveiligde HTTPS-verbindingen met de bestemming.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Schema",
|
"scheme": "Schema",
|
||||||
"createInternalResourceDialogScheme": "Schema",
|
"createInternalResourceDialogScheme": "Schema",
|
||||||
"createInternalResourceDialogEnableSsl": "TLS inschakelen",
|
"createInternalResourceDialogEnableSsl": "TLS inschakelen",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Schemat",
|
"editInternalResourceDialogScheme": "Schemat",
|
||||||
"editInternalResourceDialogEnableSsl": "Włącz TLS",
|
"editInternalResourceDialogEnableSsl": "Włącz TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Włącz szyfrowanie SSL/TLS dla bezpiecznych połączeń HTTPS z miejscem docelowym.",
|
"editInternalResourceDialogEnableSslDescription": "Włącz szyfrowanie SSL/TLS dla bezpiecznych połączeń HTTPS z miejscem docelowym.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Schemat",
|
"scheme": "Schemat",
|
||||||
"createInternalResourceDialogScheme": "Schemat",
|
"createInternalResourceDialogScheme": "Schemat",
|
||||||
"createInternalResourceDialogEnableSsl": "Włącz TLS",
|
"createInternalResourceDialogEnableSsl": "Włącz TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Esquema",
|
"editInternalResourceDialogScheme": "Esquema",
|
||||||
"editInternalResourceDialogEnableSsl": "Ativar TLS",
|
"editInternalResourceDialogEnableSsl": "Ativar TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Ativar criptografia SSL/TLS para conexões HTTPS seguras com o destino.",
|
"editInternalResourceDialogEnableSslDescription": "Ativar criptografia SSL/TLS para conexões HTTPS seguras com o destino.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Esquema",
|
"scheme": "Esquema",
|
||||||
"createInternalResourceDialogScheme": "Esquema",
|
"createInternalResourceDialogScheme": "Esquema",
|
||||||
"createInternalResourceDialogEnableSsl": "Ativar TLS",
|
"createInternalResourceDialogEnableSsl": "Ativar TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "СИДР",
|
"editInternalResourceDialogModeCidr": "СИДР",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Схема",
|
"editInternalResourceDialogScheme": "Схема",
|
||||||
"editInternalResourceDialogEnableSsl": "Включить TLS",
|
"editInternalResourceDialogEnableSsl": "Включить TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Включите шифрование SSL/TLS для защищенных HTTPS соединений с конечной точкой.",
|
"editInternalResourceDialogEnableSslDescription": "Включите шифрование SSL/TLS для защищенных HTTPS соединений с конечной точкой.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "СИДР",
|
"createInternalResourceDialogModeCidr": "СИДР",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Схема",
|
"scheme": "Схема",
|
||||||
"createInternalResourceDialogScheme": "Схема",
|
"createInternalResourceDialogScheme": "Схема",
|
||||||
"createInternalResourceDialogEnableSsl": "Включить TLS",
|
"createInternalResourceDialogEnableSsl": "Включить TLS",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "Şema",
|
"editInternalResourceDialogScheme": "Şema",
|
||||||
"editInternalResourceDialogEnableSsl": "TLS Etkinleştir",
|
"editInternalResourceDialogEnableSsl": "TLS Etkinleştir",
|
||||||
"editInternalResourceDialogEnableSslDescription": "Hedefe güvenli HTTPS bağlantıları için SSL/TLS şifrelemeyi etkinleştirin.",
|
"editInternalResourceDialogEnableSslDescription": "Hedefe güvenli HTTPS bağlantıları için SSL/TLS şifrelemeyi etkinleştirin.",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "Şema",
|
"scheme": "Şema",
|
||||||
"createInternalResourceDialogScheme": "Şema",
|
"createInternalResourceDialogScheme": "Şema",
|
||||||
"createInternalResourceDialogEnableSsl": "TLS'yi Etkinleştir",
|
"createInternalResourceDialogEnableSsl": "TLS'yi Etkinleştir",
|
||||||
|
|||||||
@@ -2049,6 +2049,7 @@
|
|||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
"editInternalResourceDialogModeHttp": "HTTP",
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
"editInternalResourceDialogModeHttps": "HTTPS",
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"editInternalResourceDialogModeSsh": "SSH",
|
||||||
"editInternalResourceDialogScheme": "方案",
|
"editInternalResourceDialogScheme": "方案",
|
||||||
"editInternalResourceDialogEnableSsl": "启用 TLS",
|
"editInternalResourceDialogEnableSsl": "启用 TLS",
|
||||||
"editInternalResourceDialogEnableSslDescription": "为目标的安全 HTTPS 连接启用 SSL/TLS 加密。",
|
"editInternalResourceDialogEnableSslDescription": "为目标的安全 HTTPS 连接启用 SSL/TLS 加密。",
|
||||||
@@ -2098,6 +2099,7 @@
|
|||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
"createInternalResourceDialogModeHttp": "HTTP",
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
"createInternalResourceDialogModeHttps": "HTTPS",
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
|
"createInternalResourceDialogModeSsh": "SSH",
|
||||||
"scheme": "方案",
|
"scheme": "方案",
|
||||||
"createInternalResourceDialogScheme": "方案",
|
"createInternalResourceDialogScheme": "方案",
|
||||||
"createInternalResourceDialogEnableSsl": "启用 TLS",
|
"createInternalResourceDialogEnableSsl": "启用 TLS",
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const createSiteResourceSchema = z
|
|||||||
udpPortRangeString: portRangeStringSchema,
|
udpPortRangeString: portRangeStringSchema,
|
||||||
disableIcmp: z.boolean().optional(),
|
disableIcmp: z.boolean().optional(),
|
||||||
authDaemonPort: z.int().positive().optional(),
|
authDaemonPort: z.int().positive().optional(),
|
||||||
authDaemonMode: z.enum(["site", "remote"]).optional(),
|
authDaemonMode: z.enum(["site", "remote", "native"]).optional(),
|
||||||
pamMode: z.enum(["passthrough", "push"]).optional(),
|
pamMode: z.enum(["passthrough", "push"]).optional(),
|
||||||
domainId: z.string().optional(), // only used for http mode, we need this to verify the alias is unique within the org
|
domainId: z.string().optional(), // only used for http mode, we need this to verify the alias is unique within the org
|
||||||
subdomain: z.string().optional() // only used for http mode, we need this to verify the alias is unique within the org
|
subdomain: z.string().optional() // only used for http mode, we need this to verify the alias is unique within the org
|
||||||
@@ -213,6 +213,7 @@ export async function createSiteResource(
|
|||||||
disableIcmp,
|
disableIcmp,
|
||||||
authDaemonPort,
|
authDaemonPort,
|
||||||
authDaemonMode,
|
authDaemonMode,
|
||||||
|
pamMode,
|
||||||
domainId,
|
domainId,
|
||||||
subdomain
|
subdomain
|
||||||
} = parsedBody.data;
|
} = parsedBody.data;
|
||||||
@@ -417,6 +418,7 @@ export async function createSiteResource(
|
|||||||
insertValues.authDaemonPort = authDaemonPort;
|
insertValues.authDaemonPort = authDaemonPort;
|
||||||
if (authDaemonMode !== undefined)
|
if (authDaemonMode !== undefined)
|
||||||
insertValues.authDaemonMode = authDaemonMode;
|
insertValues.authDaemonMode = authDaemonMode;
|
||||||
|
if (pamMode !== undefined) insertValues.pamMode = pamMode;
|
||||||
}
|
}
|
||||||
[newSiteResource] = await trx
|
[newSiteResource] = await trx
|
||||||
.insert(siteResources)
|
.insert(siteResources)
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ const updateSiteResourceSchema = z
|
|||||||
udpPortRangeString: portRangeStringSchema,
|
udpPortRangeString: portRangeStringSchema,
|
||||||
disableIcmp: z.boolean().optional(),
|
disableIcmp: z.boolean().optional(),
|
||||||
authDaemonPort: z.int().positive().nullish(),
|
authDaemonPort: z.int().positive().nullish(),
|
||||||
authDaemonMode: z.enum(["site", "remote"]).optional(),
|
authDaemonMode: z.enum(["site", "remote", "native"]).optional(),
|
||||||
|
pamMode: z.enum(["passthrough", "push"]).optional(),
|
||||||
domainId: z.string().optional(),
|
domainId: z.string().optional(),
|
||||||
subdomain: z.string().optional()
|
subdomain: z.string().optional()
|
||||||
})
|
})
|
||||||
@@ -222,6 +223,7 @@ export async function updateSiteResource(
|
|||||||
disableIcmp,
|
disableIcmp,
|
||||||
authDaemonPort,
|
authDaemonPort,
|
||||||
authDaemonMode,
|
authDaemonMode,
|
||||||
|
pamMode,
|
||||||
domainId,
|
domainId,
|
||||||
subdomain
|
subdomain
|
||||||
} = parsedBody.data;
|
} = parsedBody.data;
|
||||||
@@ -430,13 +432,17 @@ export async function updateSiteResource(
|
|||||||
const sshPamSet =
|
const sshPamSet =
|
||||||
isLicensedSshPam &&
|
isLicensedSshPam &&
|
||||||
(authDaemonPort !== undefined ||
|
(authDaemonPort !== undefined ||
|
||||||
authDaemonMode !== undefined)
|
authDaemonMode !== undefined ||
|
||||||
|
pamMode !== undefined)
|
||||||
? {
|
? {
|
||||||
...(authDaemonPort !== undefined && {
|
...(authDaemonPort !== undefined && {
|
||||||
authDaemonPort
|
authDaemonPort
|
||||||
}),
|
}),
|
||||||
...(authDaemonMode !== undefined && {
|
...(authDaemonMode !== undefined && {
|
||||||
authDaemonMode
|
authDaemonMode
|
||||||
|
}),
|
||||||
|
...(pamMode !== undefined && {
|
||||||
|
pamMode
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
@@ -554,13 +560,17 @@ export async function updateSiteResource(
|
|||||||
const sshPamSet =
|
const sshPamSet =
|
||||||
isLicensedSshPam &&
|
isLicensedSshPam &&
|
||||||
(authDaemonPort !== undefined ||
|
(authDaemonPort !== undefined ||
|
||||||
authDaemonMode !== undefined)
|
authDaemonMode !== undefined ||
|
||||||
|
pamMode !== undefined)
|
||||||
? {
|
? {
|
||||||
...(authDaemonPort !== undefined && {
|
...(authDaemonPort !== undefined && {
|
||||||
authDaemonPort
|
authDaemonPort
|
||||||
}),
|
}),
|
||||||
...(authDaemonMode !== undefined && {
|
...(authDaemonMode !== undefined && {
|
||||||
authDaemonMode
|
authDaemonMode
|
||||||
|
}),
|
||||||
|
...(pamMode !== undefined && {
|
||||||
|
pamMode
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ export default async function ClientResourcesPage(
|
|||||||
pagination = responseData.pagination;
|
pagination = responseData.pagination;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
const siteIdParam = parsePositiveInt(searchParams.get("siteId") ?? undefined);
|
const siteIdParam = parsePositiveInt(
|
||||||
|
searchParams.get("siteId") ?? undefined
|
||||||
|
);
|
||||||
|
|
||||||
let initialFilterSite: {
|
let initialFilterSite: {
|
||||||
siteId: number;
|
siteId: number;
|
||||||
@@ -106,7 +108,10 @@ export default async function ClientResourcesPage(
|
|||||||
siteNiceId: siteResource.siteNiceIds[idx],
|
siteNiceId: siteResource.siteNiceIds[idx],
|
||||||
online: siteResource.siteOnlines[idx]
|
online: siteResource.siteOnlines[idx]
|
||||||
})),
|
})),
|
||||||
mode: siteResource.mode,
|
mode:
|
||||||
|
siteResource.pamMode && siteResource.mode === "host"
|
||||||
|
? "ssh"
|
||||||
|
: siteResource.mode,
|
||||||
scheme: siteResource.scheme,
|
scheme: siteResource.scheme,
|
||||||
ssl: siteResource.ssl,
|
ssl: siteResource.ssl,
|
||||||
siteNames: siteResource.siteNames,
|
siteNames: siteResource.siteNames,
|
||||||
@@ -125,6 +130,7 @@ export default async function ClientResourcesPage(
|
|||||||
disableIcmp: siteResource.disableIcmp || false,
|
disableIcmp: siteResource.disableIcmp || false,
|
||||||
authDaemonMode: siteResource.authDaemonMode ?? null,
|
authDaemonMode: siteResource.authDaemonMode ?? null,
|
||||||
authDaemonPort: siteResource.authDaemonPort ?? null,
|
authDaemonPort: siteResource.authDaemonPort ?? null,
|
||||||
|
pamMode: siteResource.pamMode ?? null,
|
||||||
subdomain: siteResource.subdomain ?? null,
|
subdomain: siteResource.subdomain ?? null,
|
||||||
domainId: siteResource.domainId ?? null,
|
domainId: siteResource.domainId ?? null,
|
||||||
fullDomain: siteResource.fullDomain ?? null,
|
fullDomain: siteResource.fullDomain ?? null,
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export type InternalResourceRow = {
|
|||||||
siteIds: number[];
|
siteIds: number[];
|
||||||
siteNiceIds: string[];
|
siteNiceIds: string[];
|
||||||
// mode: "host" | "cidr" | "port";
|
// mode: "host" | "cidr" | "port";
|
||||||
mode: "host" | "cidr" | "http";
|
mode: "host" | "cidr" | "http" | "ssh";
|
||||||
scheme: "http" | "https" | null;
|
scheme: "http" | "https" | null;
|
||||||
ssl: boolean;
|
ssl: boolean;
|
||||||
// protocol: string | null;
|
// protocol: string | null;
|
||||||
@@ -90,8 +90,9 @@ export type InternalResourceRow = {
|
|||||||
tcpPortRangeString: string | null;
|
tcpPortRangeString: string | null;
|
||||||
udpPortRangeString: string | null;
|
udpPortRangeString: string | null;
|
||||||
disableIcmp: boolean;
|
disableIcmp: boolean;
|
||||||
authDaemonMode?: "site" | "remote" | null;
|
authDaemonMode?: "site" | "remote" | "native" | null;
|
||||||
authDaemonPort?: number | null;
|
authDaemonPort?: number | null;
|
||||||
|
pamMode?: "passthrough" | "push" | null;
|
||||||
subdomain?: string | null;
|
subdomain?: string | null;
|
||||||
domainId?: string | null;
|
domainId?: string | null;
|
||||||
fullDomain?: string | null;
|
fullDomain?: string | null;
|
||||||
@@ -410,6 +411,10 @@ export default function ClientResourcesTable({
|
|||||||
{
|
{
|
||||||
value: "http",
|
value: "http",
|
||||||
label: t("editInternalResourceDialogModeHttp")
|
label: t("editInternalResourceDialogModeHttp")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "ssh",
|
||||||
|
label: t("editInternalResourceDialogModeSsh")
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
selectedValue={searchParams.get("mode") ?? undefined}
|
selectedValue={searchParams.get("mode") ?? undefined}
|
||||||
@@ -425,13 +430,14 @@ export default function ClientResourcesTable({
|
|||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const resourceRow = row.original;
|
const resourceRow = row.original;
|
||||||
const modeLabels: Record<
|
const modeLabels: Record<
|
||||||
"host" | "cidr" | "port" | "http",
|
"host" | "cidr" | "port" | "http" | "ssh",
|
||||||
string
|
string
|
||||||
> = {
|
> = {
|
||||||
host: t("editInternalResourceDialogModeHost"),
|
host: t("editInternalResourceDialogModeHost"),
|
||||||
cidr: t("editInternalResourceDialogModeCidr"),
|
cidr: t("editInternalResourceDialogModeCidr"),
|
||||||
port: t("editInternalResourceDialogModePort"),
|
port: t("editInternalResourceDialogModePort"),
|
||||||
http: t("editInternalResourceDialogModeHttp")
|
http: t("editInternalResourceDialogModeHttp"),
|
||||||
|
ssh: t("editInternalResourceDialogModeSsh")
|
||||||
};
|
};
|
||||||
return <span>{modeLabels[resourceRow.mode]}</span>;
|
return <span>{modeLabels[resourceRow.mode]}</span>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ export default function CreateInternalResourceDialog({
|
|||||||
try {
|
try {
|
||||||
let data = { ...values };
|
let data = { ...values };
|
||||||
if (
|
if (
|
||||||
(data.mode === "host" || data.mode === "http") &&
|
(data.mode === "host" ||
|
||||||
|
data.mode === "http" ||
|
||||||
|
data.mode === "ssh") &&
|
||||||
isHostname(data.destination)
|
isHostname(data.destination)
|
||||||
) {
|
) {
|
||||||
const currentAlias = data.alias?.trim() || "";
|
const currentAlias = data.alias?.trim() || "";
|
||||||
@@ -60,12 +62,15 @@ export default function CreateInternalResourceDialog({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "ssh" mode maps to "host" in the backend with SSH settings
|
||||||
|
const backendMode = data.mode === "ssh" ? "host" : data.mode;
|
||||||
|
|
||||||
await api.put<
|
await api.put<
|
||||||
AxiosResponse<{ data: { siteResourceId: number } }>
|
AxiosResponse<{ data: { siteResourceId: number } }>
|
||||||
>(`/org/${orgId}/site-resource`, {
|
>(`/org/${orgId}/site-resource`, {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
siteIds: data.siteIds,
|
siteIds: data.siteIds,
|
||||||
mode: data.mode,
|
mode: backendMode,
|
||||||
destination: data.destination,
|
destination: data.destination,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
...(data.mode === "http" && {
|
...(data.mode === "http" && {
|
||||||
@@ -94,7 +99,25 @@ export default function CreateInternalResourceDialog({
|
|||||||
authDaemonPort: data.authDaemonPort
|
authDaemonPort: data.authDaemonPort
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
...((data.mode === "host" || data.mode == "cidr") && {
|
...(data.mode === "ssh" && {
|
||||||
|
alias:
|
||||||
|
data.alias &&
|
||||||
|
typeof data.alias === "string" &&
|
||||||
|
data.alias.trim()
|
||||||
|
? data.alias
|
||||||
|
: undefined,
|
||||||
|
pamMode: data.pamMode ?? undefined,
|
||||||
|
...(data.authDaemonMode != null && {
|
||||||
|
authDaemonMode: data.authDaemonMode
|
||||||
|
}),
|
||||||
|
...(data.authDaemonMode === "remote" &&
|
||||||
|
data.authDaemonPort != null && {
|
||||||
|
authDaemonPort: data.authDaemonPort
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
...((data.mode === "host" ||
|
||||||
|
data.mode === "ssh" ||
|
||||||
|
data.mode === "cidr") && {
|
||||||
tcpPortRangeString: data.tcpPortRangeString,
|
tcpPortRangeString: data.tcpPortRangeString,
|
||||||
udpPortRangeString: data.udpPortRangeString,
|
udpPortRangeString: data.udpPortRangeString,
|
||||||
disableIcmp: data.disableIcmp ?? false
|
disableIcmp: data.disableIcmp ?? false
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ export default function EditInternalResourceDialog({
|
|||||||
try {
|
try {
|
||||||
let data = { ...values };
|
let data = { ...values };
|
||||||
if (
|
if (
|
||||||
(data.mode === "host" || data.mode === "http") &&
|
(data.mode === "host" ||
|
||||||
|
data.mode === "http" ||
|
||||||
|
data.mode === "ssh") &&
|
||||||
isHostname(data.destination)
|
isHostname(data.destination)
|
||||||
) {
|
) {
|
||||||
const currentAlias = data.alias?.trim() || "";
|
const currentAlias = data.alias?.trim() || "";
|
||||||
@@ -64,10 +66,13 @@ export default function EditInternalResourceDialog({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "ssh" mode maps to "host" in the backend with SSH settings
|
||||||
|
const backendMode = data.mode === "ssh" ? "host" : data.mode;
|
||||||
|
|
||||||
await api.post(`/site-resource/${resource.id}`, {
|
await api.post(`/site-resource/${resource.id}`, {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
siteIds: data.siteIds,
|
siteIds: data.siteIds,
|
||||||
mode: data.mode,
|
mode: backendMode,
|
||||||
niceId: data.niceId,
|
niceId: data.niceId,
|
||||||
destination: data.destination,
|
destination: data.destination,
|
||||||
...(data.mode === "http" && {
|
...(data.mode === "http" && {
|
||||||
@@ -95,7 +100,24 @@ export default function EditInternalResourceDialog({
|
|||||||
authDaemonPort: data.authDaemonPort || null
|
authDaemonPort: data.authDaemonPort || null
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
...((data.mode === "host" || data.mode === "cidr") && {
|
...(data.mode === "ssh" && {
|
||||||
|
alias:
|
||||||
|
data.alias &&
|
||||||
|
typeof data.alias === "string" &&
|
||||||
|
data.alias.trim()
|
||||||
|
? data.alias
|
||||||
|
: null,
|
||||||
|
pamMode: data.pamMode ?? undefined,
|
||||||
|
...(data.authDaemonMode != null && {
|
||||||
|
authDaemonMode: data.authDaemonMode
|
||||||
|
}),
|
||||||
|
...(data.authDaemonMode === "remote" && {
|
||||||
|
authDaemonPort: data.authDaemonPort || null
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
...((data.mode === "host" ||
|
||||||
|
data.mode === "ssh" ||
|
||||||
|
data.mode === "cidr") && {
|
||||||
tcpPortRangeString: data.tcpPortRangeString,
|
tcpPortRangeString: data.tcpPortRangeString,
|
||||||
udpPortRangeString: data.udpPortRangeString,
|
udpPortRangeString: data.udpPortRangeString,
|
||||||
disableIcmp: data.disableIcmp ?? false
|
disableIcmp: data.disableIcmp ?? false
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export const cleanForFQDN = (name: string): string =>
|
|||||||
|
|
||||||
// --- Types ---
|
// --- Types ---
|
||||||
|
|
||||||
export type InternalResourceMode = "host" | "cidr" | "http";
|
export type InternalResourceMode = "host" | "cidr" | "http" | "ssh";
|
||||||
|
|
||||||
export type InternalResourceData = {
|
export type InternalResourceData = {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -151,8 +151,9 @@ export type InternalResourceData = {
|
|||||||
tcpPortRangeString?: string | null;
|
tcpPortRangeString?: string | null;
|
||||||
udpPortRangeString?: string | null;
|
udpPortRangeString?: string | null;
|
||||||
disableIcmp?: boolean;
|
disableIcmp?: boolean;
|
||||||
authDaemonMode?: "site" | "remote" | null;
|
authDaemonMode?: "site" | "remote" | "native" | null;
|
||||||
authDaemonPort?: number | null;
|
authDaemonPort?: number | null;
|
||||||
|
pamMode?: "passthrough" | "push" | null;
|
||||||
httpHttpsPort?: number | null;
|
httpHttpsPort?: number | null;
|
||||||
scheme?: "http" | "https" | null;
|
scheme?: "http" | "https" | null;
|
||||||
ssl?: boolean;
|
ssl?: boolean;
|
||||||
@@ -183,8 +184,9 @@ export type InternalResourceFormValues = {
|
|||||||
tcpPortRangeString?: string | null;
|
tcpPortRangeString?: string | null;
|
||||||
udpPortRangeString?: string | null;
|
udpPortRangeString?: string | null;
|
||||||
disableIcmp?: boolean;
|
disableIcmp?: boolean;
|
||||||
authDaemonMode?: "site" | "remote" | null;
|
authDaemonMode?: "site" | "remote" | "native" | null;
|
||||||
authDaemonPort?: number | null;
|
authDaemonPort?: number | null;
|
||||||
|
pamMode?: "passthrough" | "push" | null;
|
||||||
httpHttpsPort?: number | null;
|
httpHttpsPort?: number | null;
|
||||||
scheme?: "http" | "https";
|
scheme?: "http" | "https";
|
||||||
ssl?: boolean;
|
ssl?: boolean;
|
||||||
@@ -256,6 +258,10 @@ export function InternalResourceForm({
|
|||||||
variant === "create"
|
variant === "create"
|
||||||
? "createInternalResourceDialogModeHttp"
|
? "createInternalResourceDialogModeHttp"
|
||||||
: "editInternalResourceDialogModeHttp";
|
: "editInternalResourceDialogModeHttp";
|
||||||
|
const modeSshKey =
|
||||||
|
variant === "create"
|
||||||
|
? "createInternalResourceDialogModeSsh"
|
||||||
|
: "editInternalResourceDialogModeSsh";
|
||||||
const schemeLabelKey =
|
const schemeLabelKey =
|
||||||
variant === "create"
|
variant === "create"
|
||||||
? "createInternalResourceDialogScheme"
|
? "createInternalResourceDialogScheme"
|
||||||
@@ -301,7 +307,7 @@ export function InternalResourceForm({
|
|||||||
.object({
|
.object({
|
||||||
name: z.string().min(1, t(nameRequiredKey)).max(255, t(nameMaxKey)),
|
name: z.string().min(1, t(nameRequiredKey)).max(255, t(nameMaxKey)),
|
||||||
siteIds: siteIdsSchema,
|
siteIds: siteIdsSchema,
|
||||||
mode: z.enum(["host", "cidr", "http"]),
|
mode: z.enum(["host", "cidr", "http", "ssh"]),
|
||||||
destination: z
|
destination: z
|
||||||
.string()
|
.string()
|
||||||
.min(
|
.min(
|
||||||
@@ -332,8 +338,12 @@ export function InternalResourceForm({
|
|||||||
tcpPortRangeString: createPortRangeStringSchema(t),
|
tcpPortRangeString: createPortRangeStringSchema(t),
|
||||||
udpPortRangeString: createPortRangeStringSchema(t),
|
udpPortRangeString: createPortRangeStringSchema(t),
|
||||||
disableIcmp: z.boolean().optional(),
|
disableIcmp: z.boolean().optional(),
|
||||||
authDaemonMode: z.enum(["site", "remote"]).optional().nullable(),
|
authDaemonMode: z
|
||||||
|
.enum(["site", "remote", "native"])
|
||||||
|
.optional()
|
||||||
|
.nullable(),
|
||||||
authDaemonPort: z.number().int().positive().optional().nullable(),
|
authDaemonPort: z.number().int().positive().optional().nullable(),
|
||||||
|
pamMode: z.enum(["passthrough", "push"]).optional().nullable(),
|
||||||
roles: z.array(tagSchema).optional(),
|
roles: z.array(tagSchema).optional(),
|
||||||
users: z.array(tagSchema).optional(),
|
users: z.array(tagSchema).optional(),
|
||||||
clients: z
|
clients: z
|
||||||
@@ -456,6 +466,19 @@ export function InternalResourceForm({
|
|||||||
number | null
|
number | null
|
||||||
>(null);
|
>(null);
|
||||||
|
|
||||||
|
const [sshServerMode, setSshServerMode] = useState<"standard" | "native">(
|
||||||
|
() => {
|
||||||
|
if (
|
||||||
|
variant === "edit" &&
|
||||||
|
resource &&
|
||||||
|
resource.authDaemonMode === "native"
|
||||||
|
) {
|
||||||
|
return "native";
|
||||||
|
}
|
||||||
|
return "standard";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const [tcpPortMode, setTcpPortMode] = useState<PortMode>(() =>
|
const [tcpPortMode, setTcpPortMode] = useState<PortMode>(() =>
|
||||||
variant === "edit" && resource
|
variant === "edit" && resource
|
||||||
? getPortModeFromString(resource.tcpPortRangeString)
|
? getPortModeFromString(resource.tcpPortRangeString)
|
||||||
@@ -494,8 +517,12 @@ export function InternalResourceForm({
|
|||||||
tcpPortRangeString: resource.tcpPortRangeString ?? "*",
|
tcpPortRangeString: resource.tcpPortRangeString ?? "*",
|
||||||
udpPortRangeString: resource.udpPortRangeString ?? "*",
|
udpPortRangeString: resource.udpPortRangeString ?? "*",
|
||||||
disableIcmp: resource.disableIcmp ?? false,
|
disableIcmp: resource.disableIcmp ?? false,
|
||||||
authDaemonMode: resource.authDaemonMode ?? "site",
|
authDaemonMode:
|
||||||
|
resource.authDaemonMode === "native"
|
||||||
|
? "native"
|
||||||
|
: (resource.authDaemonMode ?? "site"),
|
||||||
authDaemonPort: resource.authDaemonPort ?? null,
|
authDaemonPort: resource.authDaemonPort ?? null,
|
||||||
|
pamMode: resource.pamMode ?? "passthrough",
|
||||||
httpHttpsPort: resource.httpHttpsPort ?? null,
|
httpHttpsPort: resource.httpHttpsPort ?? null,
|
||||||
scheme: resource.scheme ?? "http",
|
scheme: resource.scheme ?? "http",
|
||||||
ssl: resource.ssl ?? false,
|
ssl: resource.ssl ?? false,
|
||||||
@@ -524,6 +551,7 @@ export function InternalResourceForm({
|
|||||||
disableIcmp: false,
|
disableIcmp: false,
|
||||||
authDaemonMode: "site",
|
authDaemonMode: "site",
|
||||||
authDaemonPort: null,
|
authDaemonPort: null,
|
||||||
|
pamMode: "passthrough",
|
||||||
roles: [],
|
roles: [],
|
||||||
users: [],
|
users: [],
|
||||||
clients: []
|
clients: []
|
||||||
@@ -546,6 +574,15 @@ export function InternalResourceForm({
|
|||||||
const httpConfigFullDomain = form.watch("httpConfigFullDomain");
|
const httpConfigFullDomain = form.watch("httpConfigFullDomain");
|
||||||
const isHttpMode = mode === "http";
|
const isHttpMode = mode === "http";
|
||||||
const authDaemonMode = form.watch("authDaemonMode") ?? "site";
|
const authDaemonMode = form.watch("authDaemonMode") ?? "site";
|
||||||
|
const pamMode = form.watch("pamMode") ?? "passthrough";
|
||||||
|
const isNative = sshServerMode === "native";
|
||||||
|
const showDaemonLocation =
|
||||||
|
mode === "ssh" && !isNative && pamMode === "push";
|
||||||
|
const showDaemonPort =
|
||||||
|
mode === "ssh" &&
|
||||||
|
!isNative &&
|
||||||
|
pamMode === "push" &&
|
||||||
|
authDaemonMode === "remote";
|
||||||
const hasInitialized = useRef(false);
|
const hasInitialized = useRef(false);
|
||||||
const previousResourceId = useRef<number | null>(null);
|
const previousResourceId = useRef<number | null>(null);
|
||||||
|
|
||||||
@@ -579,11 +616,13 @@ export function InternalResourceForm({
|
|||||||
disableIcmp: false,
|
disableIcmp: false,
|
||||||
authDaemonMode: "site",
|
authDaemonMode: "site",
|
||||||
authDaemonPort: null,
|
authDaemonPort: null,
|
||||||
|
pamMode: "passthrough",
|
||||||
roles: [],
|
roles: [],
|
||||||
users: [],
|
users: [],
|
||||||
clients: []
|
clients: []
|
||||||
});
|
});
|
||||||
setSelectedSites([]);
|
setSelectedSites([]);
|
||||||
|
setSshServerMode("standard");
|
||||||
setTcpPortMode("all");
|
setTcpPortMode("all");
|
||||||
setUdpPortMode("all");
|
setUdpPortMode("all");
|
||||||
setTcpCustomPorts("");
|
setTcpCustomPorts("");
|
||||||
@@ -611,12 +650,19 @@ export function InternalResourceForm({
|
|||||||
tcpPortRangeString: resource.tcpPortRangeString ?? "*",
|
tcpPortRangeString: resource.tcpPortRangeString ?? "*",
|
||||||
udpPortRangeString: resource.udpPortRangeString ?? "*",
|
udpPortRangeString: resource.udpPortRangeString ?? "*",
|
||||||
disableIcmp: resource.disableIcmp ?? false,
|
disableIcmp: resource.disableIcmp ?? false,
|
||||||
authDaemonMode: resource.authDaemonMode ?? "site",
|
authDaemonMode:
|
||||||
|
resource.authDaemonMode === "native"
|
||||||
|
? "native"
|
||||||
|
: (resource.authDaemonMode ?? "site"),
|
||||||
authDaemonPort: resource.authDaemonPort ?? null,
|
authDaemonPort: resource.authDaemonPort ?? null,
|
||||||
|
pamMode: resource.pamMode ?? "passthrough",
|
||||||
roles: [],
|
roles: [],
|
||||||
users: [],
|
users: [],
|
||||||
clients: []
|
clients: []
|
||||||
});
|
});
|
||||||
|
setSshServerMode(
|
||||||
|
resource.authDaemonMode === "native" ? "native" : "standard"
|
||||||
|
);
|
||||||
setSelectedSites(buildSelectedSitesForResource(resource));
|
setSelectedSites(buildSelectedSitesForResource(resource));
|
||||||
setTcpPortMode(
|
setTcpPortMode(
|
||||||
getPortModeFromString(resource.tcpPortRangeString)
|
getPortModeFromString(resource.tcpPortRangeString)
|
||||||
@@ -736,7 +782,7 @@ export function InternalResourceForm({
|
|||||||
title: t("editInternalResourceDialogAccessPolicy"),
|
title: t("editInternalResourceDialogAccessPolicy"),
|
||||||
href: "#"
|
href: "#"
|
||||||
},
|
},
|
||||||
...(disableEnterpriseFeatures || mode !== "host"
|
...(disableEnterpriseFeatures || mode !== "ssh"
|
||||||
? []
|
? []
|
||||||
: [{ title: t("sshAccess"), href: "#" }])
|
: [{ title: t("sshAccess"), href: "#" }])
|
||||||
]}
|
]}
|
||||||
@@ -847,6 +893,12 @@ export function InternalResourceForm({
|
|||||||
label: t(
|
label: t(
|
||||||
modeHttpKey
|
modeHttpKey
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "ssh" as const,
|
||||||
|
label: t(
|
||||||
|
modeSshKey
|
||||||
|
)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: [])
|
: [])
|
||||||
@@ -1574,152 +1626,256 @@ export function InternalResourceForm({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* SSH Access tab (host mode only) */}
|
{/* SSH Access tab (ssh mode only) */}
|
||||||
{!disableEnterpriseFeatures && mode === "host" && (
|
{!disableEnterpriseFeatures && mode === "ssh" && (
|
||||||
<div className="space-y-4 mt-4 p-1">
|
<div className="space-y-4 mt-4 p-1">
|
||||||
<PaidFeaturesAlert tiers={tierMatrix.sshPam} />
|
<PaidFeaturesAlert tiers={tierMatrix.sshPam} />
|
||||||
<div className="mb-8">
|
|
||||||
<label className="font-medium block">
|
{/* Mode */}
|
||||||
{t("internalResourceAuthDaemonStrategy")}
|
<div className="space-y-3">
|
||||||
</label>
|
<p className="text-sm font-semibold">
|
||||||
<div className="text-sm text-muted-foreground">
|
{t("sshServerMode")}
|
||||||
{t.rich(
|
</p>
|
||||||
"internalResourceAuthDaemonDescription",
|
<StrategySelect<"standard" | "native">
|
||||||
|
value={sshServerMode}
|
||||||
|
options={[
|
||||||
{
|
{
|
||||||
docsLink: (chunks) => (
|
id: "native",
|
||||||
<a
|
title: t("sshServerModePangolin"),
|
||||||
href={
|
description: t(
|
||||||
"https://docs.pangolin.net/manage/ssh#setup-choose-your-architecture"
|
"sshServerModeNativeDescription"
|
||||||
}
|
),
|
||||||
target="_blank"
|
disabled: sshSectionDisabled
|
||||||
rel="noopener noreferrer"
|
},
|
||||||
className={
|
{
|
||||||
"text-primary inline-flex items-center gap-1"
|
id: "standard",
|
||||||
}
|
title: t("sshServerModeStandard"),
|
||||||
>
|
description: t(
|
||||||
{chunks}
|
"sshServerModeStandardDescription"
|
||||||
<ExternalLink className="size-3.5 shrink-0" />
|
),
|
||||||
</a>
|
disabled: sshSectionDisabled
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)}
|
]}
|
||||||
</div>
|
onChange={(v) => {
|
||||||
</div>
|
if (sshSectionDisabled) return;
|
||||||
<div className="space-y-4">
|
setSshServerMode(v);
|
||||||
<FormField
|
if (v === "native") {
|
||||||
control={form.control}
|
form.setValue(
|
||||||
name="authDaemonMode"
|
"authDaemonMode",
|
||||||
render={({ field }) => (
|
"native"
|
||||||
<FormItem>
|
);
|
||||||
<FormLabel>
|
form.setValue(
|
||||||
{t(
|
"authDaemonPort",
|
||||||
"internalResourceAuthDaemonStrategyLabel"
|
null
|
||||||
)}
|
);
|
||||||
</FormLabel>
|
} else {
|
||||||
<FormControl>
|
form.setValue(
|
||||||
<StrategySelect<
|
"authDaemonMode",
|
||||||
"site" | "remote"
|
"site"
|
||||||
>
|
);
|
||||||
value={
|
}
|
||||||
field.value ?? undefined
|
}}
|
||||||
}
|
cols={2}
|
||||||
options={[
|
|
||||||
{
|
|
||||||
id: "site",
|
|
||||||
title: t(
|
|
||||||
"internalResourceAuthDaemonSite"
|
|
||||||
),
|
|
||||||
description: t(
|
|
||||||
"internalResourceAuthDaemonSiteDescription"
|
|
||||||
),
|
|
||||||
disabled:
|
|
||||||
sshSectionDisabled
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "remote",
|
|
||||||
title: t(
|
|
||||||
"internalResourceAuthDaemonRemote"
|
|
||||||
),
|
|
||||||
description: t(
|
|
||||||
"internalResourceAuthDaemonRemoteDescription"
|
|
||||||
),
|
|
||||||
disabled:
|
|
||||||
sshSectionDisabled
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
onChange={(v) => {
|
|
||||||
if (sshSectionDisabled)
|
|
||||||
return;
|
|
||||||
field.onChange(v);
|
|
||||||
if (v === "site") {
|
|
||||||
form.setValue(
|
|
||||||
"authDaemonPort",
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
cols={2}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
{authDaemonMode === "remote" && (
|
</div>
|
||||||
|
|
||||||
|
{/* Auth Method (standard only) */}
|
||||||
|
{!isNative && (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<p className="text-sm font-semibold">
|
||||||
|
{t("sshAuthenticationMethod")}
|
||||||
|
</p>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="authDaemonPort"
|
name="pamMode"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>
|
|
||||||
{t(
|
|
||||||
"internalResourceAuthDaemonPort"
|
|
||||||
)}
|
|
||||||
</FormLabel>
|
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<StrategySelect<
|
||||||
type="number"
|
"passthrough" | "push"
|
||||||
min={1}
|
>
|
||||||
max={65535}
|
|
||||||
placeholder="22123"
|
|
||||||
{...field}
|
|
||||||
disabled={
|
|
||||||
sshSectionDisabled
|
|
||||||
}
|
|
||||||
value={
|
value={
|
||||||
field.value ?? ""
|
field.value ??
|
||||||
|
"passthrough"
|
||||||
}
|
}
|
||||||
onChange={(e) => {
|
options={[
|
||||||
|
{
|
||||||
|
id: "passthrough",
|
||||||
|
title: t(
|
||||||
|
"sshAuthMethodManual"
|
||||||
|
),
|
||||||
|
description: t(
|
||||||
|
"sshAuthMethodManualDescription"
|
||||||
|
),
|
||||||
|
disabled:
|
||||||
|
sshSectionDisabled
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "push",
|
||||||
|
title: t(
|
||||||
|
"sshAuthMethodAutomated"
|
||||||
|
),
|
||||||
|
description: t(
|
||||||
|
"sshAuthMethodAutomatedDescription"
|
||||||
|
),
|
||||||
|
disabled:
|
||||||
|
sshSectionDisabled
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={(v) => {
|
||||||
if (
|
if (
|
||||||
sshSectionDisabled
|
sshSectionDisabled
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
const v =
|
field.onChange(v);
|
||||||
e.target.value;
|
if (
|
||||||
if (v === "") {
|
v ===
|
||||||
field.onChange(
|
"passthrough"
|
||||||
|
) {
|
||||||
|
form.setValue(
|
||||||
|
"authDaemonPort",
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const num =
|
|
||||||
parseInt(v, 10);
|
|
||||||
field.onChange(
|
|
||||||
Number.isNaN(
|
|
||||||
num
|
|
||||||
)
|
|
||||||
? null
|
|
||||||
: num
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
|
cols={2}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
|
{/* Daemon Location (standard + push) */}
|
||||||
|
{showDaemonLocation && (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<p className="text-sm font-semibold">
|
||||||
|
{t("sshAuthDaemonLocation")}
|
||||||
|
</p>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="authDaemonMode"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormControl>
|
||||||
|
<StrategySelect<
|
||||||
|
"site" | "remote"
|
||||||
|
>
|
||||||
|
value={
|
||||||
|
(field.value as
|
||||||
|
| "site"
|
||||||
|
| "remote") ??
|
||||||
|
"site"
|
||||||
|
}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
id: "site",
|
||||||
|
title: t(
|
||||||
|
"internalResourceAuthDaemonSite"
|
||||||
|
),
|
||||||
|
description: t(
|
||||||
|
"sshDaemonLocationSiteDescription"
|
||||||
|
),
|
||||||
|
disabled:
|
||||||
|
sshSectionDisabled
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "remote",
|
||||||
|
title: t(
|
||||||
|
"sshDaemonLocationRemote"
|
||||||
|
),
|
||||||
|
description: t(
|
||||||
|
"sshDaemonLocationRemoteDescription"
|
||||||
|
),
|
||||||
|
disabled:
|
||||||
|
sshSectionDisabled
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={(v) => {
|
||||||
|
if (
|
||||||
|
sshSectionDisabled
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
field.onChange(v);
|
||||||
|
if (v === "site") {
|
||||||
|
form.setValue(
|
||||||
|
"authDaemonPort",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
cols={2}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
{t("sshDaemonDisclaimer")}{" "}
|
||||||
|
<a
|
||||||
|
href="https://docs.pangolin.net/manage/resources/private/ssh"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-primary hover:underline inline-flex items-center gap-1"
|
||||||
|
>
|
||||||
|
{t("learnMore")}
|
||||||
|
<ExternalLink className="size-3.5 shrink-0" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Daemon Port (standard + push + remote) */}
|
||||||
|
{showDaemonPort && (
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="authDaemonPort"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>
|
||||||
|
{t("sshDaemonPort")}
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
max={65535}
|
||||||
|
placeholder="22123"
|
||||||
|
disabled={
|
||||||
|
sshSectionDisabled
|
||||||
|
}
|
||||||
|
value={field.value ?? ""}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (sshSectionDisabled)
|
||||||
|
return;
|
||||||
|
const v =
|
||||||
|
e.target.value;
|
||||||
|
if (v === "") {
|
||||||
|
field.onChange(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const num = parseInt(
|
||||||
|
v,
|
||||||
|
10
|
||||||
|
);
|
||||||
|
field.onChange(
|
||||||
|
Number.isNaN(num)
|
||||||
|
? null
|
||||||
|
: num
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</HorizontalTabs>
|
</HorizontalTabs>
|
||||||
|
|||||||
Reference in New Issue
Block a user