feat(hy2): add port range support for validator

This commit is contained in:
divocatt
2026-05-29 16:40:44 +03:00
parent 1543d974cc
commit 1365febaa4
8 changed files with 122 additions and 105 deletions

View File

@@ -648,56 +648,56 @@
"call": "Invalid HY2 URL: insecure must be 0 or 1", "call": "Invalid HY2 URL: insecure must be 0 or 1",
"key": "Invalid HY2 URL: insecure must be 0 or 1", "key": "Invalid HY2 URL: insecure must be 0 or 1",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:76" "src/validators/validateHysteriaUrl.ts:90"
] ]
}, },
{ {
"call": "Invalid HY2 URL: invalid port number", "call": "Invalid HY2 URL: invalid port number",
"key": "Invalid HY2 URL: invalid port number", "key": "Invalid HY2 URL: invalid port number",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:62" "src/validators/validateHysteriaUrl.ts:77"
] ]
}, },
{ {
"call": "Invalid HY2 URL: missing credentials/server", "call": "Invalid HY2 URL: missing credentials/server",
"key": "Invalid HY2 URL: missing credentials/server", "key": "Invalid HY2 URL: missing credentials/server",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:32" "src/validators/validateHysteriaUrl.ts:30"
] ]
}, },
{ {
"call": "Invalid HY2 URL: missing host", "call": "Invalid HY2 URL: missing host",
"key": "Invalid HY2 URL: missing host", "key": "Invalid HY2 URL: missing host",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:49" "src/validators/validateHysteriaUrl.ts:47"
] ]
}, },
{ {
"call": "Invalid HY2 URL: missing host & port", "call": "Invalid HY2 URL: missing host & port",
"key": "Invalid HY2 URL: missing host & port", "key": "Invalid HY2 URL: missing host & port",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:43" "src/validators/validateHysteriaUrl.ts:41"
] ]
}, },
{ {
"call": "Invalid HY2 URL: missing password", "call": "Invalid HY2 URL: missing password",
"key": "Invalid HY2 URL: missing password", "key": "Invalid HY2 URL: missing password",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:38" "src/validators/validateHysteriaUrl.ts:36"
] ]
}, },
{ {
"call": "Invalid HY2 URL: missing port", "call": "Invalid HY2 URL: missing port",
"key": "Invalid HY2 URL: missing port", "key": "Invalid HY2 URL: missing port",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:53" "src/validators/validateHysteriaUrl.ts:50"
] ]
}, },
{ {
"call": "Invalid HY2 URL: must not contain spaces", "call": "Invalid HY2 URL: must not contain spaces",
"key": "Invalid HY2 URL: must not contain spaces", "key": "Invalid HY2 URL: must not contain spaces",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:19" "src/validators/validateHysteriaUrl.ts:18"
] ]
}, },
{ {
@@ -711,28 +711,28 @@
"call": "Invalid HY2 URL: obfs-password required when obfs is set", "call": "Invalid HY2 URL: obfs-password required when obfs is set",
"key": "Invalid HY2 URL: obfs-password required when obfs is set", "key": "Invalid HY2 URL: obfs-password required when obfs is set",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:99" "src/validators/validateHysteriaUrl.ts:108"
] ]
}, },
{ {
"call": "Invalid HY2 URL: parsing failed", "call": "Invalid HY2 URL: parsing failed",
"key": "Invalid HY2 URL: parsing failed", "key": "Invalid HY2 URL: parsing failed",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:115" "src/validators/validateHysteriaUrl.ts:122"
] ]
}, },
{ {
"call": "Invalid HY2 URL: sni cannot be empty", "call": "Invalid HY2 URL: sni cannot be empty",
"key": "Invalid HY2 URL: sni cannot be empty", "key": "Invalid HY2 URL: sni cannot be empty",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:108" "src/validators/validateHysteriaUrl.ts:116"
] ]
}, },
{ {
"call": "Invalid HY2 URL: unsupported obfs type", "call": "Invalid HY2 URL: unsupported obfs type",
"key": "Invalid HY2 URL: unsupported obfs type", "key": "Invalid HY2 URL: unsupported obfs type",
"places": [ "places": [
"src/validators/validateHysteriaUrl.ts:88" "src/validators/validateHysteriaUrl.ts:98"
] ]
}, },
{ {
@@ -943,7 +943,7 @@
"call": "Latest", "call": "Latest",
"key": "Latest", "key": "Latest",
"places": [ "places": [
"src/podkop/tabs/diagnostic/initController.ts:456" "src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:48"
] ]
}, },
{ {
@@ -1075,7 +1075,7 @@
"call": "Outdated", "call": "Outdated",
"key": "Outdated", "key": "Outdated",
"places": [ "places": [
"src/podkop/tabs/diagnostic/initController.ts:446" "src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:38"
] ]
}, },
{ {
@@ -1685,7 +1685,7 @@
"src/podkop/tabs/diagnostic/initController.ts:41", "src/podkop/tabs/diagnostic/initController.ts:41",
"src/podkop/tabs/diagnostic/initController.ts:42", "src/podkop/tabs/diagnostic/initController.ts:42",
"src/podkop/tabs/diagnostic/initController.ts:43", "src/podkop/tabs/diagnostic/initController.ts:43",
"src/podkop/tabs/diagnostic/initController.ts:420" "src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:7"
] ]
}, },
{ {
@@ -1802,7 +1802,7 @@
"src/validators/validateDns.ts:18", "src/validators/validateDns.ts:18",
"src/validators/validateDomain.ts:13", "src/validators/validateDomain.ts:13",
"src/validators/validateDomain.ts:30", "src/validators/validateDomain.ts:30",
"src/validators/validateHysteriaUrl.ts:113", "src/validators/validateHysteriaUrl.ts:120",
"src/validators/validateIp.ts:8", "src/validators/validateIp.ts:8",
"src/validators/validateOutboundJson.ts:7", "src/validators/validateOutboundJson.ts:7",
"src/validators/validatePath.ts:16", "src/validators/validatePath.ts:16",

View File

@@ -1,15 +1,15 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) 2026 THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) 2026 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PODKOP package. # This file is distributed under the same license as the PODKOP package.
# romanvht <romanvht@gmail.com>, 2026. # divocatt <210179590+divocatt@users.noreply.github.com>, 2026.
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PODKOP\n" "Project-Id-Version: PODKOP\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-05-09 02:49+1000\n" "POT-Creation-Date: 2026-05-29 13:40+0300\n"
"PO-Revision-Date: 2026-05-09 02:49+1000\n" "PO-Revision-Date: 2026-05-29 13:40+0300\n"
"Last-Translator: romanvht <romanvht@gmail.com>\n" "Last-Translator: divocatt <210179590+divocatt@users.noreply.github.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n" "Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -394,35 +394,35 @@ msgstr ""
msgid "Invalid format. Use X.X.X.X or X.X.X.X/Y" msgid "Invalid format. Use X.X.X.X or X.X.X.X/Y"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:76 #: src/validators/validateHysteriaUrl.ts:90
msgid "Invalid HY2 URL: insecure must be 0 or 1" msgid "Invalid HY2 URL: insecure must be 0 or 1"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:62 #: src/validators/validateHysteriaUrl.ts:77
msgid "Invalid HY2 URL: invalid port number" msgid "Invalid HY2 URL: invalid port number"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:32 #: src/validators/validateHysteriaUrl.ts:30
msgid "Invalid HY2 URL: missing credentials/server" msgid "Invalid HY2 URL: missing credentials/server"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:49 #: src/validators/validateHysteriaUrl.ts:47
msgid "Invalid HY2 URL: missing host" msgid "Invalid HY2 URL: missing host"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:43 #: src/validators/validateHysteriaUrl.ts:41
msgid "Invalid HY2 URL: missing host & port" msgid "Invalid HY2 URL: missing host & port"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:38 #: src/validators/validateHysteriaUrl.ts:36
msgid "Invalid HY2 URL: missing password" msgid "Invalid HY2 URL: missing password"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:53 #: src/validators/validateHysteriaUrl.ts:50
msgid "Invalid HY2 URL: missing port" msgid "Invalid HY2 URL: missing port"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:19 #: src/validators/validateHysteriaUrl.ts:18
msgid "Invalid HY2 URL: must not contain spaces" msgid "Invalid HY2 URL: must not contain spaces"
msgstr "" msgstr ""
@@ -430,19 +430,19 @@ msgstr ""
msgid "Invalid HY2 URL: must start with hysteria2:// or hy2://" msgid "Invalid HY2 URL: must start with hysteria2:// or hy2://"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:99 #: src/validators/validateHysteriaUrl.ts:108
msgid "Invalid HY2 URL: obfs-password required when obfs is set" msgid "Invalid HY2 URL: obfs-password required when obfs is set"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:115 #: src/validators/validateHysteriaUrl.ts:122
msgid "Invalid HY2 URL: parsing failed" msgid "Invalid HY2 URL: parsing failed"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:108 #: src/validators/validateHysteriaUrl.ts:116
msgid "Invalid HY2 URL: sni cannot be empty" msgid "Invalid HY2 URL: sni cannot be empty"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:88 #: src/validators/validateHysteriaUrl.ts:98
msgid "Invalid HY2 URL: unsupported obfs type" msgid "Invalid HY2 URL: unsupported obfs type"
msgstr "" msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "Issues detected" msgid "Issues detected"
msgstr "" msgstr ""
#: src/podkop/tabs/diagnostic/initController.ts:456 #: src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:48
msgid "Latest" msgid "Latest"
msgstr "" msgstr ""
@@ -641,7 +641,7 @@ msgstr ""
msgid "Outbound Configuration" msgid "Outbound Configuration"
msgstr "" msgstr ""
#: src/podkop/tabs/diagnostic/initController.ts:446 #: src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:38
msgid "Outdated" msgid "Outdated"
msgstr "" msgstr ""
@@ -996,7 +996,7 @@ msgstr ""
#: src/podkop/tabs/diagnostic/initController.ts:41 #: src/podkop/tabs/diagnostic/initController.ts:41
#: src/podkop/tabs/diagnostic/initController.ts:42 #: src/podkop/tabs/diagnostic/initController.ts:42
#: src/podkop/tabs/diagnostic/initController.ts:43 #: src/podkop/tabs/diagnostic/initController.ts:43
#: src/podkop/tabs/diagnostic/initController.ts:420 #: src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:7
msgid "unknown" msgid "unknown"
msgstr "" msgstr ""
@@ -1065,7 +1065,7 @@ msgstr ""
#: src/validators/validateDns.ts:18 #: src/validators/validateDns.ts:18
#: src/validators/validateDomain.ts:13 #: src/validators/validateDomain.ts:13
#: src/validators/validateDomain.ts:30 #: src/validators/validateDomain.ts:30
#: src/validators/validateHysteriaUrl.ts:113 #: src/validators/validateHysteriaUrl.ts:120
#: src/validators/validateIp.ts:8 #: src/validators/validateIp.ts:8
#: src/validators/validateOutboundJson.ts:7 #: src/validators/validateOutboundJson.ts:7
#: src/validators/validatePath.ts:16 #: src/validators/validatePath.ts:16

View File

@@ -1,15 +1,15 @@
# RU translations for PODKOP package. # RU translations for PODKOP package.
# Copyright (C) 2026 THE PODKOP'S COPYRIGHT HOLDER # Copyright (C) 2026 THE PODKOP'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PODKOP package. # This file is distributed under the same license as the PODKOP package.
# romanvht, 2026. # divocatt, 2026.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PODKOP\n" "Project-Id-Version: PODKOP\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-05-09 12:50+1000\n" "POT-Creation-Date: 2026-05-29 16:40+0300\n"
"PO-Revision-Date: 2026-05-09 12:50+1000\n" "PO-Revision-Date: 2026-05-29 16:40+0300\n"
"Last-Translator: romanvht\n" "Last-Translator: divocatt\n"
"Language-Team: none\n" "Language-Team: none\n"
"Language: ru\n" "Language: ru\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

View File

@@ -28,6 +28,11 @@ const validUrls = [
// Explicit obfs=none (valid) // Explicit obfs=none (valid)
['obfs none = ok', 'hysteria2://pw@example.com:443/?obfs=none#hy2-none'], ['obfs none = ok', 'hysteria2://pw@example.com:443/?obfs=none#hy2-none'],
[
'port range 5000-6000',
'hysteria2://letmein@example.com:123,5000-6000/?insecure=1&obfs=salamander&obfs-password=gawrgura&pinSHA256=deadbeef&sni=real.example.com',
],
]; ];
const invalidUrls = [ const invalidUrls = [

View File

@@ -6,19 +6,17 @@ export function validateHysteria2Url(url: string): ValidationResult {
const isHY2 = url.startsWith('hysteria2://'); const isHY2 = url.startsWith('hysteria2://');
const isHY2Short = url.startsWith('hy2://'); const isHY2Short = url.startsWith('hy2://');
if (!isHY2 && !isHY2Short) { if (!isHY2 && !isHY2Short)
return { return {
valid: false, valid: false,
message: _('Invalid HY2 URL: must start with hysteria2:// or hy2://'), message: _('Invalid HY2 URL: must start with hysteria2:// or hy2://'),
}; };
}
if (/\s/.test(url)) { if (/\s/.test(url))
return { return {
valid: false, valid: false,
message: _('Invalid HY2 URL: must not contain spaces'), message: _('Invalid HY2 URL: must not contain spaces'),
}; };
}
const prefix = isHY2 ? 'hysteria2://' : 'hy2://'; const prefix = isHY2 ? 'hysteria2://' : 'hy2://';
const body = url.slice(prefix.length); const body = url.slice(prefix.length);
@@ -45,23 +43,39 @@ export function validateHysteria2Url(url: string): ValidationResult {
const [host, port] = hostPortPart.split(':'); const [host, port] = hostPortPart.split(':');
if (!host) { if (!host)
return { valid: false, message: _('Invalid HY2 URL: missing host') }; return { valid: false, message: _('Invalid HY2 URL: missing host') };
}
if (!port) { if (!port)
return { valid: false, message: _('Invalid HY2 URL: missing port') }; return { valid: false, message: _('Invalid HY2 URL: missing port') };
}
const cleanedPort = port.replace('/', ''); const cleanedPort = port.replace('/', '');
const portNum = Number(cleanedPort); const portEntries = cleanedPort.split(',');
if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) { const isValidPortNumber = (value: string) => {
if (!/^\d+$/.test(value)) return false;
const num = Number(value);
return num >= 1 && num <= 65535;
};
const isValidPortEntry = (entry: string) => {
if (!entry) return false;
if (!entry.includes('-')) return isValidPortNumber(entry);
const rangeParts = entry.split('-');
if (rangeParts.length !== 2) return false;
const [start, end] = rangeParts;
if (!isValidPortNumber(start) || !isValidPortNumber(end)) return false;
return Number(start) <= Number(end);
};
if (!portEntries.every(isValidPortEntry))
return { return {
valid: false, valid: false,
message: _('Invalid HY2 URL: invalid port number'), message: _('Invalid HY2 URL: invalid port number'),
}; };
}
if (queryString) { if (queryString) {
const params = parseQueryString(queryString); const params = parseQueryString(queryString);
@@ -70,44 +84,37 @@ export function validateHysteria2Url(url: string): ValidationResult {
if ( if (
paramsKeys.includes('insecure') && paramsKeys.includes('insecure') &&
!['0', '1'].includes(params.insecure) !['0', '1'].includes(params.insecure)
) { )
return { return {
valid: false, valid: false,
message: _('Invalid HY2 URL: insecure must be 0 or 1'), message: _('Invalid HY2 URL: insecure must be 0 or 1'),
}; };
}
const validObfsTypes = ['none', 'salamander']; const validObfsTypes = ['none', 'salamander'];
if ( if (paramsKeys.includes('obfs') && !validObfsTypes.includes(params.obfs))
paramsKeys.includes('obfs') &&
!validObfsTypes.includes(params.obfs)
) {
return { return {
valid: false, valid: false,
message: _('Invalid HY2 URL: unsupported obfs type'), message: _('Invalid HY2 URL: unsupported obfs type'),
}; };
}
if ( if (
paramsKeys.includes('obfs') && paramsKeys.includes('obfs') &&
params.obfs !== 'none' && params.obfs !== 'none' &&
!params['obfs-password'] !params['obfs-password']
) { )
return { return {
valid: false, valid: false,
message: _( message: _(
'Invalid HY2 URL: obfs-password required when obfs is set', 'Invalid HY2 URL: obfs-password required when obfs is set',
), ),
}; };
}
if (paramsKeys.includes('sni') && !params.sni) { if (paramsKeys.includes('sni') && !params.sni)
return { return {
valid: false, valid: false,
message: _('Invalid HY2 URL: sni cannot be empty'), message: _('Invalid HY2 URL: sni cannot be empty'),
}; };
}
} }
return { valid: true, message: _('Valid') }; return { valid: true, message: _('Valid') };

View File

@@ -453,18 +453,16 @@ function validateHysteria2Url(url) {
try { try {
const isHY2 = url.startsWith("hysteria2://"); const isHY2 = url.startsWith("hysteria2://");
const isHY2Short = url.startsWith("hy2://"); const isHY2Short = url.startsWith("hy2://");
if (!isHY2 && !isHY2Short) { if (!isHY2 && !isHY2Short)
return { return {
valid: false, valid: false,
message: _("Invalid HY2 URL: must start with hysteria2:// or hy2://") message: _("Invalid HY2 URL: must start with hysteria2:// or hy2://")
}; };
} if (/\s/.test(url))
if (/\s/.test(url)) {
return { return {
valid: false, valid: false,
message: _("Invalid HY2 URL: must not contain spaces") message: _("Invalid HY2 URL: must not contain spaces")
}; };
}
const prefix = isHY2 ? "hysteria2://" : "hy2://"; const prefix = isHY2 ? "hysteria2://" : "hy2://";
const body = url.slice(prefix.length); const body = url.slice(prefix.length);
const [mainPart] = body.split("#"); const [mainPart] = body.split("#");
@@ -483,50 +481,57 @@ function validateHysteria2Url(url) {
message: _("Invalid HY2 URL: missing host & port") message: _("Invalid HY2 URL: missing host & port")
}; };
const [host, port] = hostPortPart.split(":"); const [host, port] = hostPortPart.split(":");
if (!host) { if (!host)
return { valid: false, message: _("Invalid HY2 URL: missing host") }; return { valid: false, message: _("Invalid HY2 URL: missing host") };
} if (!port)
if (!port) {
return { valid: false, message: _("Invalid HY2 URL: missing port") }; return { valid: false, message: _("Invalid HY2 URL: missing port") };
}
const cleanedPort = port.replace("/", ""); const cleanedPort = port.replace("/", "");
const portNum = Number(cleanedPort); const portEntries = cleanedPort.split(",");
if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) { const isValidPortNumber = (value) => {
if (!/^\d+$/.test(value)) return false;
const num = Number(value);
return num >= 1 && num <= 65535;
};
const isValidPortEntry = (entry) => {
if (!entry) return false;
if (!entry.includes("-")) return isValidPortNumber(entry);
const rangeParts = entry.split("-");
if (rangeParts.length !== 2) return false;
const [start, end] = rangeParts;
if (!isValidPortNumber(start) || !isValidPortNumber(end)) return false;
return Number(start) <= Number(end);
};
if (!portEntries.every(isValidPortEntry))
return { return {
valid: false, valid: false,
message: _("Invalid HY2 URL: invalid port number") message: _("Invalid HY2 URL: invalid port number")
}; };
}
if (queryString) { if (queryString) {
const params = parseQueryString(queryString); const params = parseQueryString(queryString);
const paramsKeys = Object.keys(params); const paramsKeys = Object.keys(params);
if (paramsKeys.includes("insecure") && !["0", "1"].includes(params.insecure)) { if (paramsKeys.includes("insecure") && !["0", "1"].includes(params.insecure))
return { return {
valid: false, valid: false,
message: _("Invalid HY2 URL: insecure must be 0 or 1") message: _("Invalid HY2 URL: insecure must be 0 or 1")
}; };
}
const validObfsTypes = ["none", "salamander"]; const validObfsTypes = ["none", "salamander"];
if (paramsKeys.includes("obfs") && !validObfsTypes.includes(params.obfs)) { if (paramsKeys.includes("obfs") && !validObfsTypes.includes(params.obfs))
return { return {
valid: false, valid: false,
message: _("Invalid HY2 URL: unsupported obfs type") message: _("Invalid HY2 URL: unsupported obfs type")
}; };
} if (paramsKeys.includes("obfs") && params.obfs !== "none" && !params["obfs-password"])
if (paramsKeys.includes("obfs") && params.obfs !== "none" && !params["obfs-password"]) {
return { return {
valid: false, valid: false,
message: _( message: _(
"Invalid HY2 URL: obfs-password required when obfs is set" "Invalid HY2 URL: obfs-password required when obfs is set"
) )
}; };
} if (paramsKeys.includes("sni") && !params.sni)
if (paramsKeys.includes("sni") && !params.sni) {
return { return {
valid: false, valid: false,
message: _("Invalid HY2 URL: sni cannot be empty") message: _("Invalid HY2 URL: sni cannot be empty")
}; };
}
} }
return { valid: true, message: _("Valid") }; return { valid: true, message: _("Valid") };
} catch (_e) { } catch (_e) {

View File

@@ -1,15 +1,15 @@
# RU translations for PODKOP package. # RU translations for PODKOP package.
# Copyright (C) 2026 THE PODKOP'S COPYRIGHT HOLDER # Copyright (C) 2026 THE PODKOP'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PODKOP package. # This file is distributed under the same license as the PODKOP package.
# romanvht, 2026. # divocatt, 2026.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PODKOP\n" "Project-Id-Version: PODKOP\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-05-09 12:50+1000\n" "POT-Creation-Date: 2026-05-29 16:40+0300\n"
"PO-Revision-Date: 2026-05-09 12:50+1000\n" "PO-Revision-Date: 2026-05-29 16:40+0300\n"
"Last-Translator: romanvht\n" "Last-Translator: divocatt\n"
"Language-Team: none\n" "Language-Team: none\n"
"Language: ru\n" "Language: ru\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

View File

@@ -1,15 +1,15 @@
# SOME DESCRIPTIVE TITLE. # SOME DESCRIPTIVE TITLE.
# Copyright (C) 2026 THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) 2026 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PODKOP package. # This file is distributed under the same license as the PODKOP package.
# romanvht <romanvht@gmail.com>, 2026. # divocatt <210179590+divocatt@users.noreply.github.com>, 2026.
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PODKOP\n" "Project-Id-Version: PODKOP\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-05-09 02:49+1000\n" "POT-Creation-Date: 2026-05-29 13:40+0300\n"
"PO-Revision-Date: 2026-05-09 02:49+1000\n" "PO-Revision-Date: 2026-05-29 13:40+0300\n"
"Last-Translator: romanvht <romanvht@gmail.com>\n" "Last-Translator: divocatt <210179590+divocatt@users.noreply.github.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n" "Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -394,35 +394,35 @@ msgstr ""
msgid "Invalid format. Use X.X.X.X or X.X.X.X/Y" msgid "Invalid format. Use X.X.X.X or X.X.X.X/Y"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:76 #: src/validators/validateHysteriaUrl.ts:90
msgid "Invalid HY2 URL: insecure must be 0 or 1" msgid "Invalid HY2 URL: insecure must be 0 or 1"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:62 #: src/validators/validateHysteriaUrl.ts:77
msgid "Invalid HY2 URL: invalid port number" msgid "Invalid HY2 URL: invalid port number"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:32 #: src/validators/validateHysteriaUrl.ts:30
msgid "Invalid HY2 URL: missing credentials/server" msgid "Invalid HY2 URL: missing credentials/server"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:49 #: src/validators/validateHysteriaUrl.ts:47
msgid "Invalid HY2 URL: missing host" msgid "Invalid HY2 URL: missing host"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:43 #: src/validators/validateHysteriaUrl.ts:41
msgid "Invalid HY2 URL: missing host & port" msgid "Invalid HY2 URL: missing host & port"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:38 #: src/validators/validateHysteriaUrl.ts:36
msgid "Invalid HY2 URL: missing password" msgid "Invalid HY2 URL: missing password"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:53 #: src/validators/validateHysteriaUrl.ts:50
msgid "Invalid HY2 URL: missing port" msgid "Invalid HY2 URL: missing port"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:19 #: src/validators/validateHysteriaUrl.ts:18
msgid "Invalid HY2 URL: must not contain spaces" msgid "Invalid HY2 URL: must not contain spaces"
msgstr "" msgstr ""
@@ -430,19 +430,19 @@ msgstr ""
msgid "Invalid HY2 URL: must start with hysteria2:// or hy2://" msgid "Invalid HY2 URL: must start with hysteria2:// or hy2://"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:99 #: src/validators/validateHysteriaUrl.ts:108
msgid "Invalid HY2 URL: obfs-password required when obfs is set" msgid "Invalid HY2 URL: obfs-password required when obfs is set"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:115 #: src/validators/validateHysteriaUrl.ts:122
msgid "Invalid HY2 URL: parsing failed" msgid "Invalid HY2 URL: parsing failed"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:108 #: src/validators/validateHysteriaUrl.ts:116
msgid "Invalid HY2 URL: sni cannot be empty" msgid "Invalid HY2 URL: sni cannot be empty"
msgstr "" msgstr ""
#: src/validators/validateHysteriaUrl.ts:88 #: src/validators/validateHysteriaUrl.ts:98
msgid "Invalid HY2 URL: unsupported obfs type" msgid "Invalid HY2 URL: unsupported obfs type"
msgstr "" msgstr ""
@@ -563,7 +563,7 @@ msgstr ""
msgid "Issues detected" msgid "Issues detected"
msgstr "" msgstr ""
#: src/podkop/tabs/diagnostic/initController.ts:456 #: src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:48
msgid "Latest" msgid "Latest"
msgstr "" msgstr ""
@@ -641,7 +641,7 @@ msgstr ""
msgid "Outbound Configuration" msgid "Outbound Configuration"
msgstr "" msgstr ""
#: src/podkop/tabs/diagnostic/initController.ts:446 #: src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:38
msgid "Outdated" msgid "Outdated"
msgstr "" msgstr ""
@@ -996,7 +996,7 @@ msgstr ""
#: src/podkop/tabs/diagnostic/initController.ts:41 #: src/podkop/tabs/diagnostic/initController.ts:41
#: src/podkop/tabs/diagnostic/initController.ts:42 #: src/podkop/tabs/diagnostic/initController.ts:42
#: src/podkop/tabs/diagnostic/initController.ts:43 #: src/podkop/tabs/diagnostic/initController.ts:43
#: src/podkop/tabs/diagnostic/initController.ts:420 #: src/podkop/tabs/diagnostic/helpers/getPodkopVersionRow.ts:7
msgid "unknown" msgid "unknown"
msgstr "" msgstr ""
@@ -1065,7 +1065,7 @@ msgstr ""
#: src/validators/validateDns.ts:18 #: src/validators/validateDns.ts:18
#: src/validators/validateDomain.ts:13 #: src/validators/validateDomain.ts:13
#: src/validators/validateDomain.ts:30 #: src/validators/validateDomain.ts:30
#: src/validators/validateHysteriaUrl.ts:113 #: src/validators/validateHysteriaUrl.ts:120
#: src/validators/validateIp.ts:8 #: src/validators/validateIp.ts:8
#: src/validators/validateOutboundJson.ts:7 #: src/validators/validateOutboundJson.ts:7
#: src/validators/validatePath.ts:16 #: src/validators/validatePath.ts:16