mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-09 13:06:52 +03:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2074ccecce | ||
|
|
06f9bee038 | ||
|
|
891b8f713d | ||
|
|
b96552fb49 |
@@ -100,6 +100,7 @@ Luci: Services/podkop
|
|||||||
```
|
```
|
||||||
- [x] Только кастомный remote list не создаёт секцию в route-rules-rule-set и dns-rules-ruleset
|
- [x] Только кастомный remote list не создаёт секцию в route-rules-rule-set и dns-rules-ruleset
|
||||||
- [ ] Не отрабатывает service podkop stop, если podkop запущен и не может, к пример, зарезолвить домен с сломанным DNS
|
- [ ] Не отрабатывает service podkop stop, если podkop запущен и не может, к пример, зарезолвить домен с сломанным DNS
|
||||||
|
- [ ] Длинный label ломает sing-box
|
||||||
|
|
||||||
# ToDo
|
# ToDo
|
||||||
Этот раздел не означает задачи, которые нужно брать и делать. Это общий список хотелок. Если вы хотите помочь, пожалуйста, спросите сначала в телеграмме.
|
Этот раздел не означает задачи, которые нужно брать и делать. Это общий список хотелок. Если вы хотите помочь, пожалуйста, спросите сначала в телеграмме.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-podkop
|
PKG_NAME:=luci-app-podkop
|
||||||
PKG_VERSION:=0.3.14
|
PKG_VERSION:=0.3.15
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI podkop app
|
LUCI_TITLE:=LuCI podkop app
|
||||||
|
|||||||
@@ -13,6 +13,23 @@ function formatDiagnosticOutput(output) {
|
|||||||
.replace(/\r/g, '\n');
|
.replace(/\r/g, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNetworkInterfaces(o) {
|
||||||
|
const excludeInterfaces = ['br-lan', 'eth0', 'eth1', 'wan', 'phy0-ap0', 'phy1-ap0', 'pppoe-wan'];
|
||||||
|
|
||||||
|
return network.getDevices().then(devices => {
|
||||||
|
devices.forEach(device => {
|
||||||
|
if (device.dev && device.dev.name) {
|
||||||
|
const deviceName = device.dev.name;
|
||||||
|
if (!excludeInterfaces.includes(deviceName) && !/^lan\d+$/.test(deviceName)) {
|
||||||
|
o.value(deviceName, deviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Failed to get network devices:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Общая функция для создания конфигурационных секций
|
// Общая функция для создания конфигурационных секций
|
||||||
function createConfigSection(section, map, network) {
|
function createConfigSection(section, map, network) {
|
||||||
const s = section;
|
const s = section;
|
||||||
@@ -168,21 +185,7 @@ function createConfigSection(section, map, network) {
|
|||||||
o = s.taboption('basic', form.ListValue, 'interface', _('Network Interface'), _('Select network interface for VPN connection'));
|
o = s.taboption('basic', form.ListValue, 'interface', _('Network Interface'), _('Select network interface for VPN connection'));
|
||||||
o.depends('mode', 'vpn');
|
o.depends('mode', 'vpn');
|
||||||
o.ucisection = s.section;
|
o.ucisection = s.section;
|
||||||
|
getNetworkInterfaces(o);
|
||||||
try {
|
|
||||||
const devices = network.getDevicesSync ? network.getDevicesSync() : network.getDevices();
|
|
||||||
const excludeInterfaces = ['br-lan', 'eth0', 'eth1', 'wan', 'phy0-ap0', 'phy1-ap0'];
|
|
||||||
devices.forEach(device => {
|
|
||||||
if (device.dev && device.dev.name) {
|
|
||||||
const deviceName = device.dev.name;
|
|
||||||
if (!excludeInterfaces.includes(deviceName) && !/^lan\d+$/.test(deviceName)) {
|
|
||||||
o.value(deviceName, deviceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching devices:', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
o = s.taboption('basic', form.Flag, 'domain_list_enabled', _('Community Lists'));
|
o = s.taboption('basic', form.Flag, 'domain_list_enabled', _('Community Lists'));
|
||||||
o.default = '0';
|
o.default = '0';
|
||||||
@@ -503,25 +506,34 @@ return view.extend({
|
|||||||
o.value('1.1.1.1', 'Cloudflare (1.1.1.1)');
|
o.value('1.1.1.1', 'Cloudflare (1.1.1.1)');
|
||||||
o.value('8.8.8.8', 'Google (8.8.8.8)');
|
o.value('8.8.8.8', 'Google (8.8.8.8)');
|
||||||
o.value('9.9.9.9', 'Quad9 (9.9.9.9)');
|
o.value('9.9.9.9', 'Quad9 (9.9.9.9)');
|
||||||
o.value('dns.adguard-dns.com', 'AdGuard Default');
|
o.value('dns.adguard-dns.com', 'AdGuard Default (dns.adguard-dns.com)');
|
||||||
o.value('unfiltered.adguard-dns.com', 'AdGuard Unfiltered');
|
o.value('unfiltered.adguard-dns.com', 'AdGuard Unfiltered (unfiltered.adguard-dns.com)');
|
||||||
o.value('family.adguard-dns.com', 'AdGuard Family');
|
o.value('family.adguard-dns.com', 'AdGuard Family (family.adguard-dns.com)');
|
||||||
o.default = '1.1.1.1';
|
o.default = '1.1.1.1';
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.ucisection = 'main';
|
o.ucisection = 'main';
|
||||||
o.validate = function (section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
if (!value) return _('DNS server address cannot be empty');
|
if (!value) {
|
||||||
|
return _('DNS server address cannot be empty');
|
||||||
|
}
|
||||||
|
|
||||||
const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
|
const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
|
||||||
if (ipRegex.test(value)) {
|
if (ipRegex.test(value)) {
|
||||||
const parts = value.split('.');
|
const parts = value.split('.');
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
const num = parseInt(part);
|
const num = parseInt(part);
|
||||||
if (num < 0 || num > 255) return _('IP address parts must be between 0 and 255');
|
if (num < 0 || num > 255) {
|
||||||
|
return _('IP address parts must be between 0 and 255');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const domainRegex = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$/;
|
const domainRegex = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$/;
|
||||||
if (!domainRegex.test(value)) return _('Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com');
|
if (!domainRegex.test(value)) {
|
||||||
|
return _('Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com');
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -628,10 +640,6 @@ return view.extend({
|
|||||||
'class': 'btn cbi-button-apply',
|
'class': 'btn cbi-button-apply',
|
||||||
'click': () => fs.exec('/etc/init.d/podkop', ['restart']).then(() => location.reload())
|
'click': () => fs.exec('/etc/init.d/podkop', ['restart']).then(() => location.reload())
|
||||||
}, _('Restart Podkop')),
|
}, _('Restart Podkop')),
|
||||||
E('button', {
|
|
||||||
'class': 'btn cbi-button-' + (podkopStatus.enabled ? 'remove' : 'apply'),
|
|
||||||
'click': () => fs.exec('/etc/init.d/podkop', [podkopStatus.enabled ? 'disable' : 'enable']).then(() => location.reload())
|
|
||||||
}, podkopStatus.enabled ? _('Disable Podkop') : _('Enable Podkop')),
|
|
||||||
E('button', {
|
E('button', {
|
||||||
'class': 'btn',
|
'class': 'btn',
|
||||||
'click': () => fs.exec('/etc/init.d/podkop', ['show_config']).then(res => {
|
'click': () => fs.exec('/etc/init.d/podkop', ['show_config']).then(res => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=podkop
|
PKG_NAME:=podkop
|
||||||
PKG_VERSION:=0.3.14
|
PKG_VERSION:=0.3.15
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_MAINTAINER:=ITDog <podkop@itdog.info>
|
PKG_MAINTAINER:=ITDog <podkop@itdog.info>
|
||||||
|
|||||||
Reference in New Issue
Block a user