feat: implement validateProxyUrl validation

This commit is contained in:
divocat
2025-10-03 21:44:42 +03:00
parent 3f4a0cf094
commit eb52d52eb4
5 changed files with 63 additions and 31 deletions

View File

@@ -104,4 +104,4 @@ export const COMMAND_SCHEDULING = {
P8_PRIORITY: 1500, // Background execution
P9_PRIORITY: 1700, // Idle mode execution
P10_PRIORITY: 1900, // Lowest priority
};
} as const;

View File

@@ -9,3 +9,4 @@ export * from './validateShadowsocksUrl';
export * from './validateVlessUrl';
export * from './validateOutboundJson';
export * from './validateTrojanUrl';
export * from './validateProxyUrl';

View File

@@ -0,0 +1,24 @@
import { ValidationResult } from './types';
import { validateShadowsocksUrl } from './validateShadowsocksUrl';
import { validateVlessUrl } from './validateVlessUrl';
import { validateTrojanUrl } from './validateTrojanUrl';
// TODO refactor current validation and add tests
export function validateProxyUrl(url: string): ValidationResult {
if (url.startsWith('ss://')) {
return validateShadowsocksUrl(url);
}
if (url.startsWith('vless://')) {
return validateVlessUrl(url);
}
if (url.startsWith('trojan://')) {
return validateTrojanUrl(url);
}
return {
valid: false,
message: 'URL must start with vless:// or ss:// or trojan://',
};
}

View File

@@ -92,38 +92,13 @@ function createConfigSection(section) {
return _('No active configuration found. At least one non-commented line is required.');
}
if (activeConfig.startsWith('ss://')) {
const validation = main.validateShadowsocksUrl(activeConfig);
const validation = main.validateProxyUrl(activeConfig);
if (validation.valid) {
return true;
}
return _(validation.message)
}
if (activeConfig.startsWith('vless://')) {
const validation = main.validateVlessUrl(activeConfig);
if (validation.valid) {
return true;
}
return _(validation.message)
}
if (activeConfig.startsWith('trojan://')) {
const validation = main.validateTrojanUrl(activeConfig);
if (validation.valid) {
return true;
}
return _(validation.message)
}
return _('URL must start with vless:// or ss:// or trojan://')
} catch (e) {
return `${_('Invalid URL format:')} ${e?.message}`;
}
@@ -150,11 +125,25 @@ function createConfigSection(section) {
o = s.taboption('basic', form.DynamicList, 'urltest_proxy_links', _('URLTest Proxy Links'));
o.depends('proxy_config_type', 'urltest');
o.placeholder = 'vless:// or ss:// link';
o.placeholder = 'vless://, ss://, trojan:// links';
o.rmempty = false;
o.textarea = true;
o.rows = 3;
o.wrap = 'soft';
o.validate = function (section_id, value) {
// Optional
if (!value || value.length === 0) {
return true
}
const validation = main.validateProxyUrl(value);
if (validation.valid) {
return true;
}
return _(validation.message)
};
o = s.taboption('basic', form.Flag, 'ss_uot', _('Shadowsocks UDP over TCP'), _('Apply for SS2022'));
o.default = '0';

View File

@@ -299,6 +299,23 @@ function validateTrojanUrl(url) {
return { valid: true, message: "Valid" };
}
// src/validators/validateProxyUrl.ts
function validateProxyUrl(url) {
if (url.startsWith("ss://")) {
return validateShadowsocksUrl(url);
}
if (url.startsWith("vless://")) {
return validateVlessUrl(url);
}
if (url.startsWith("trojan://")) {
return validateTrojanUrl(url);
}
return {
valid: false,
message: "URL must start with vless:// or ss:// or trojan://"
};
}
// src/helpers/getBaseUrl.ts
function getBaseUrl() {
const { protocol, hostname } = window.location;
@@ -485,6 +502,7 @@ return baseclass.extend({
validateIPV4,
validateOutboundJson,
validatePath,
validateProxyUrl,
validateShadowsocksUrl,
validateSubnet,
validateTrojanUrl,