mirror of
https://github.com/itdoginfo/podkop.git
synced 2026-01-31 06:40:46 +03:00
feat: migrate validatePath to modular
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
export const STATUS_COLORS = {
|
||||
SUCCESS: '#4caf50',
|
||||
ERROR: '#f44336',
|
||||
WARNING: '#ff9800'
|
||||
WARNING: '#ff9800',
|
||||
};
|
||||
|
||||
export const FAKEIP_CHECK_DOMAIN = 'fakeip.podkop.fyi';
|
||||
export const IP_CHECK_DOMAIN = 'ip.podkop.fyi';
|
||||
|
||||
export const REGIONAL_OPTIONS = ['russia_inside', 'russia_outside', 'ukraine_inside'];
|
||||
export const REGIONAL_OPTIONS = [
|
||||
'russia_inside',
|
||||
'russia_outside',
|
||||
'ukraine_inside',
|
||||
];
|
||||
|
||||
export const ALLOWED_WITH_RUSSIA_INSIDE = [
|
||||
'russia_inside',
|
||||
'meta',
|
||||
@@ -21,7 +26,7 @@ export const ALLOWED_WITH_RUSSIA_INSIDE = [
|
||||
'ovh',
|
||||
'hodca',
|
||||
'digitalocean',
|
||||
'cloudfront'
|
||||
'cloudfront',
|
||||
];
|
||||
|
||||
export const DOMAIN_LIST_OPTIONS = {
|
||||
@@ -47,7 +52,7 @@ export const DOMAIN_LIST_OPTIONS = {
|
||||
hetzner: 'Hetzner ASN',
|
||||
ovh: 'OVH ASN',
|
||||
digitalocean: 'Digital Ocean ASN',
|
||||
cloudfront: 'CloudFront ASN'
|
||||
cloudfront: 'CloudFront ASN',
|
||||
};
|
||||
|
||||
export const UPDATE_INTERVAL_OPTIONS = {
|
||||
@@ -55,7 +60,7 @@ export const UPDATE_INTERVAL_OPTIONS = {
|
||||
'3h': 'Every 3 hours',
|
||||
'12h': 'Every 12 hours',
|
||||
'1d': 'Every day',
|
||||
'3d': 'Every 3 days'
|
||||
'3d': 'Every 3 days',
|
||||
};
|
||||
|
||||
export const DNS_SERVER_OPTIONS = {
|
||||
@@ -63,8 +68,9 @@ export const DNS_SERVER_OPTIONS = {
|
||||
'8.8.8.8': '8.8.8.8 (Google)',
|
||||
'9.9.9.9': '9.9.9.9 (Quad9)',
|
||||
'dns.adguard-dns.com': 'dns.adguard-dns.com (AdGuard Default)',
|
||||
'unfiltered.adguard-dns.com': 'unfiltered.adguard-dns.com (AdGuard Unfiltered)',
|
||||
'family.adguard-dns.com': 'family.adguard-dns.com (AdGuard Family)'
|
||||
'unfiltered.adguard-dns.com':
|
||||
'unfiltered.adguard-dns.com (AdGuard Unfiltered)',
|
||||
'family.adguard-dns.com': 'family.adguard-dns.com (AdGuard Family)',
|
||||
};
|
||||
|
||||
export const DIAGNOSTICS_UPDATE_INTERVAL = 10000; // 10 seconds
|
||||
@@ -87,5 +93,5 @@ export const COMMAND_SCHEDULING = {
|
||||
P7_PRIORITY: 1300, // Very low priority
|
||||
P8_PRIORITY: 1500, // Background execution
|
||||
P9_PRIORITY: 1700, // Idle mode execution
|
||||
P10_PRIORITY: 1900 // Lowest priority
|
||||
P10_PRIORITY: 1900, // Lowest priority
|
||||
};
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
'require baseclass';
|
||||
|
||||
export * from './validators';
|
||||
export * from './constants'
|
||||
export * from './constants';
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from './validateIp';
|
||||
export * from './validateDomain';
|
||||
export * from './validateDns';
|
||||
export * from './validateUrl';
|
||||
export * from './validatePath';
|
||||
|
||||
39
fe-app-podkop/src/validators/tests/validatePath.test.js
Normal file
39
fe-app-podkop/src/validators/tests/validatePath.test.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { validatePath } from '../validatePath';
|
||||
|
||||
export const validPaths = [
|
||||
['Single level', '/etc'],
|
||||
['Nested path', '/usr/local/bin'],
|
||||
['With dash', '/var/log/nginx-access'],
|
||||
['With underscore', '/opt/my_app/config'],
|
||||
['With numbers', '/data123/files'],
|
||||
['With dots', '/home/user/.config'],
|
||||
['Deep nested', '/a/b/c/d/e/f/g'],
|
||||
];
|
||||
|
||||
export const invalidPaths = [
|
||||
['Empty string', ''],
|
||||
['Missing starting slash', 'usr/local'],
|
||||
['Only dot', '.'],
|
||||
['Space inside', '/path with space'],
|
||||
['Illegal char', '/path$'],
|
||||
['Backslash not allowed', '\\windows\\path'],
|
||||
['Relative path ./', './relative'],
|
||||
['Relative path ../', '../parent'],
|
||||
];
|
||||
|
||||
describe('validatePath', () => {
|
||||
describe.each(validPaths)('Valid path: %s', (_desc, path) => {
|
||||
it(`returns valid=true for "${path}"`, () => {
|
||||
const res = validatePath(path);
|
||||
expect(res.valid).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe.each(invalidPaths)('Invalid path: %s', (_desc, path) => {
|
||||
it(`returns valid=false for "${path}"`, () => {
|
||||
const res = validatePath(path);
|
||||
expect(res.valid).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
25
fe-app-podkop/src/validators/validatePath.ts
Normal file
25
fe-app-podkop/src/validators/validatePath.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ValidationResult } from './types';
|
||||
|
||||
export function validatePath(value: string): ValidationResult {
|
||||
if (!value) {
|
||||
return {
|
||||
valid: false,
|
||||
message: 'Path cannot be empty',
|
||||
};
|
||||
}
|
||||
|
||||
const pathRegex = /^\/[a-zA-Z0-9_\-/.]+$/;
|
||||
|
||||
if (pathRegex.test(value)) {
|
||||
return {
|
||||
valid: true,
|
||||
message: 'Valid',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
valid: false,
|
||||
message:
|
||||
'Invalid path format. Path must start with "/" and contain valid characters',
|
||||
};
|
||||
}
|
||||
@@ -409,12 +409,18 @@ function createConfigSection(section, map, network) {
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value || value.length === 0) return true;
|
||||
const pathRegex = /^\/[a-zA-Z0-9_\-\/\.]+$/;
|
||||
if (!pathRegex.test(value)) {
|
||||
return _('Invalid path format. Path must start with "/" and contain valid characters');
|
||||
// Optional
|
||||
if (!value || value.length === 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
const validation = main.validatePath(value);
|
||||
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return _(validation.message)
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'remote_domain_lists_enabled', _('Remote Domain Lists'), _('Download and use domain lists from remote URLs'));
|
||||
@@ -453,12 +459,18 @@ function createConfigSection(section, map, network) {
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
if (!value || value.length === 0) return true;
|
||||
const pathRegex = /^\/[a-zA-Z0-9_\-\/\.]+$/;
|
||||
if (!pathRegex.test(value)) {
|
||||
return _('Invalid path format. Path must start with "/" and contain valid characters');
|
||||
// Optional
|
||||
if (!value || value.length === 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
const validation = main.validatePath(value);
|
||||
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return _(validation.message)
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'user_subnet_list_type', _('User Subnet List Type'), _('Select how to add your custom subnets'));
|
||||
|
||||
@@ -59,6 +59,27 @@ function validateUrl(url, protocols = ["http:", "https:"]) {
|
||||
}
|
||||
}
|
||||
|
||||
// src/validators/validatePath.ts
|
||||
function validatePath(value) {
|
||||
if (!value) {
|
||||
return {
|
||||
valid: false,
|
||||
message: "Path cannot be empty"
|
||||
};
|
||||
}
|
||||
const pathRegex = /^\/[a-zA-Z0-9_\-/.]+$/;
|
||||
if (pathRegex.test(value)) {
|
||||
return {
|
||||
valid: true,
|
||||
message: "Valid"
|
||||
};
|
||||
}
|
||||
return {
|
||||
valid: false,
|
||||
message: 'Invalid path format. Path must start with "/" and contain valid characters'
|
||||
};
|
||||
}
|
||||
|
||||
// src/constants.ts
|
||||
var STATUS_COLORS = {
|
||||
SUCCESS: "#4caf50",
|
||||
@@ -67,7 +88,11 @@ var STATUS_COLORS = {
|
||||
};
|
||||
var FAKEIP_CHECK_DOMAIN = "fakeip.podkop.fyi";
|
||||
var IP_CHECK_DOMAIN = "ip.podkop.fyi";
|
||||
var REGIONAL_OPTIONS = ["russia_inside", "russia_outside", "ukraine_inside"];
|
||||
var REGIONAL_OPTIONS = [
|
||||
"russia_inside",
|
||||
"russia_outside",
|
||||
"ukraine_inside"
|
||||
];
|
||||
var ALLOWED_WITH_RUSSIA_INSIDE = [
|
||||
"russia_inside",
|
||||
"meta",
|
||||
@@ -174,5 +199,6 @@ return baseclass.extend({
|
||||
validateDNS,
|
||||
validateDomain,
|
||||
validateIPV4,
|
||||
validatePath,
|
||||
validateUrl
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user