Add new ssh config for private resources

This commit is contained in:
Owen
2026-05-26 17:50:46 -07:00
parent eca87b66f0
commit aa7004b2ff
22 changed files with 399 additions and 144 deletions
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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 활성화",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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,
+10 -4
View File
@@ -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
+25 -3
View File
@@ -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
+284 -128
View File
@@ -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>