hiddifypanel 10.30.9.dev0__py3-none-any.whl → 10.30.9.dev2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hiddifypanel/VERSION +1 -1
- hiddifypanel/VERSION.py +2 -2
- hiddifypanel/cache.py +13 -3
- hiddifypanel/hutils/network/net.py +36 -7
- hiddifypanel/hutils/proxy/shared.py +1 -1
- hiddifypanel/hutils/proxy/xrayjson.py +6 -6
- hiddifypanel/models/config_enum.py +2 -2
- hiddifypanel/models/domain.py +1 -1
- hiddifypanel/panel/admin/DomainAdmin.py +45 -32
- hiddifypanel/panel/admin/ProxyAdmin.py +1 -1
- hiddifypanel/panel/admin/QuickSetup.py +138 -47
- hiddifypanel/panel/admin/SettingAdmin.py +11 -6
- hiddifypanel/panel/admin/templates/quick_setup.html +19 -13
- hiddifypanel/panel/init_db.py +6 -6
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +16 -3
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +16 -3
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +11 -2
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +11 -2
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +11 -2
- hiddifypanel/translations.i18n/en.json +11 -2
- hiddifypanel/translations.i18n/fa.json +11 -2
- hiddifypanel/translations.i18n/pt.json +10 -1
- hiddifypanel/translations.i18n/ru.json +10 -1
- hiddifypanel/translations.i18n/zh.json +10 -1
- {hiddifypanel-10.30.9.dev0.dist-info → hiddifypanel-10.30.9.dev2.dist-info}/METADATA +1 -1
- {hiddifypanel-10.30.9.dev0.dist-info → hiddifypanel-10.30.9.dev2.dist-info}/RECORD +35 -35
- {hiddifypanel-10.30.9.dev0.dist-info → hiddifypanel-10.30.9.dev2.dist-info}/LICENSE.md +0 -0
- {hiddifypanel-10.30.9.dev0.dist-info → hiddifypanel-10.30.9.dev2.dist-info}/WHEEL +0 -0
- {hiddifypanel-10.30.9.dev0.dist-info → hiddifypanel-10.30.9.dev2.dist-info}/entry_points.txt +0 -0
- {hiddifypanel-10.30.9.dev0.dist-info → hiddifypanel-10.30.9.dev2.dist-info}/top_level.txt +0 -0
hiddifypanel/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
10.30.9.
|
1
|
+
10.30.9.dev2
|
hiddifypanel/VERSION.py
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
__version__='10.30.9.
|
1
|
+
__version__='10.30.9.dev2'
|
2
2
|
from datetime import datetime
|
3
|
-
__release_date__= datetime.strptime('2024-07-
|
3
|
+
__release_date__= datetime.strptime('2024-07-13','%Y-%m-%d')
|
hiddifypanel/cache.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from redis_cache import RedisCache, chunks
|
1
|
+
from redis_cache import RedisCache, chunks, compact_dump
|
2
2
|
import redis
|
3
3
|
from pickle import dumps, loads
|
4
4
|
from loguru import logger
|
@@ -7,11 +7,21 @@ redis_client = redis.from_url('unix:///opt/hiddify-manager/other/redis/run.sock?
|
|
7
7
|
|
8
8
|
|
9
9
|
class CustomRedisCache(RedisCache):
|
10
|
+
def __init__(self, redis_client, prefix="rc", serializer=compact_dump, deserializer=loads, key_serializer=None, support_cluster=True, exception_handler=None):
|
11
|
+
super().__init__(redis_client, prefix, serializer, deserializer, key_serializer, support_cluster, exception_handler)
|
12
|
+
self.cached_functions = set()
|
13
|
+
|
14
|
+
def cache(self, ttl=0, limit=0, namespace=None, exception_handler=None):
|
15
|
+
res = super().cache(ttl, limit, namespace, exception_handler)
|
16
|
+
self.cached_functions.add(res)
|
17
|
+
return res
|
10
18
|
|
11
19
|
def invalidate_all_cached_functions(self):
|
12
20
|
try:
|
21
|
+
for f in self.cached_functions:
|
22
|
+
f.invalidate_all()
|
13
23
|
logger.trace("Invalidating all cached functions")
|
14
|
-
chunks_gen = chunks(f'{self.prefix}*',
|
24
|
+
chunks_gen = chunks(f'{self.prefix}*', 5000)
|
15
25
|
for keys in chunks_gen:
|
16
26
|
self.client.delete(*keys)
|
17
27
|
logger.trace("Successfully invalidated all cached functions")
|
@@ -22,4 +32,4 @@ class CustomRedisCache(RedisCache):
|
|
22
32
|
return False
|
23
33
|
|
24
34
|
|
25
|
-
cache = CustomRedisCache(redis_client=redis_client, prefix="h", serializer=dumps, deserializer=loads)
|
35
|
+
cache = CustomRedisCache(redis_client=redis_client, prefix="h", serializer=dumps, deserializer=loads)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import List, Literal, Union
|
1
|
+
from typing import List, Literal, Set, Union
|
2
2
|
from urllib.parse import urlparse
|
3
3
|
import urllib.request
|
4
4
|
import ipaddress
|
@@ -33,17 +33,43 @@ def get_domain_ip(domain: str, retry: int = 3, version: Literal[4, 6] | None = N
|
|
33
33
|
|
34
34
|
if not res and version != 4:
|
35
35
|
try:
|
36
|
-
res = f"
|
37
|
-
|
38
|
-
res = res[1:-1]
|
36
|
+
res = f"{socket.getaddrinfo(domain, None, socket.AF_INET6)[0][4][0]}"
|
39
37
|
|
40
38
|
except BaseException:
|
41
39
|
pass
|
42
40
|
|
43
|
-
if retry <= 0
|
41
|
+
if retry <= 0:
|
44
42
|
return None
|
43
|
+
if not res:
|
44
|
+
return get_domain_ip(domain, retry=retry - 1, version=version)
|
45
|
+
|
46
|
+
return ipaddress.ip_address(res)
|
47
|
+
|
48
|
+
|
49
|
+
def get_domain_ips(domain: str, retry: int = 3) -> Set[Union[ipaddress.IPv4Address, ipaddress.IPv6Address]]:
|
50
|
+
res = set()
|
51
|
+
if retry < 0:
|
52
|
+
return res
|
53
|
+
try:
|
54
|
+
_, _, ips = socket.gethostbyname_ex(domain)
|
55
|
+
for ip in ips:
|
56
|
+
res.add(ipaddress.ip_address(ip))
|
57
|
+
except Exception:
|
58
|
+
pass
|
59
|
+
|
60
|
+
try:
|
61
|
+
for ip in socket.getaddrinfo(domain, None, socket.AF_INET):
|
62
|
+
res.add(ipaddress.ip_address(ip[4][0]))
|
63
|
+
except BaseException:
|
64
|
+
pass
|
65
|
+
|
66
|
+
try:
|
67
|
+
for ip in socket.getaddrinfo(domain, None, socket.AF_INET6):
|
68
|
+
res.add(ipaddress.ip_address(ip[4][0]))
|
69
|
+
except BaseException:
|
70
|
+
pass
|
45
71
|
|
46
|
-
return
|
72
|
+
return res or get_domain_ips(domain, retry=retry - 1)
|
47
73
|
|
48
74
|
|
49
75
|
def get_socket_public_ip(version: Literal[4, 6]) -> Union[ipaddress.IPv4Address, ipaddress.IPv6Address, None]:
|
@@ -85,8 +111,11 @@ def get_interface_public_ip(version: Literal[4, 6]) -> List[Union[ipaddress.IPv4
|
|
85
111
|
|
86
112
|
|
87
113
|
@cache.cache(ttl=600)
|
88
|
-
def get_ips(version: Literal[4, 6]) -> List[Union[ipaddress.IPv4Address, ipaddress.IPv6Address]]:
|
114
|
+
def get_ips(version: Literal[4, 6] | None = None) -> List[Union[ipaddress.IPv4Address, ipaddress.IPv6Address]]:
|
115
|
+
if not version:
|
116
|
+
return [*get_ips(4), *get_ips(6)]
|
89
117
|
addrs = []
|
118
|
+
|
90
119
|
i_ips = get_interface_public_ip(version)
|
91
120
|
if i_ips:
|
92
121
|
addrs = i_ips
|
@@ -130,7 +130,7 @@ def get_proxies(child_id: int = 0, only_enabled=False) -> list['Proxy']:
|
|
130
130
|
if not hconfig(ConfigEnum.vmess_enable, child_id):
|
131
131
|
proxies = [c for c in proxies if 'vmess' not in c.proto]
|
132
132
|
if not hconfig(ConfigEnum.vless_enable, child_id):
|
133
|
-
proxies = [c for c in proxies if 'vless' not in c.proto]
|
133
|
+
proxies = [c for c in proxies if 'vless' not in c.proto or 'reality' in c.l3]
|
134
134
|
if not hconfig(ConfigEnum.trojan_enable, child_id):
|
135
135
|
proxies = [c for c in proxies if 'trojan' not in c.proto]
|
136
136
|
if not hconfig(ConfigEnum.httpupgrade_enable, child_id):
|
@@ -223,8 +223,10 @@ def add_stream_settings(base: dict, proxy: dict):
|
|
223
223
|
# THE CURRENT CODE WORKS BUT THE CORRECT CONDITINO SHOULD BE THIS:
|
224
224
|
# ss['security'] == 'tls' or 'xtls' -----> ss['security'] in ['tls','xtls']
|
225
225
|
# TODO: FIX THE CONDITION AND TEST CONFIGS ON THE CLIENT SIDE
|
226
|
-
|
227
|
-
|
226
|
+
if ss['security'] == 'reality':
|
227
|
+
ss['network'] = proxy['transport']
|
228
|
+
add_reality_stream(ss, proxy)
|
229
|
+
elif ss['security'] == 'tls' or 'xtls' and proxy['proto'] != ProxyProto.ss:
|
228
230
|
ss['tlsSettings'] = {
|
229
231
|
'serverName': proxy['sni'],
|
230
232
|
'allowInsecure': proxy['allow_insecure'],
|
@@ -239,9 +241,7 @@ def add_stream_settings(base: dict, proxy: dict):
|
|
239
241
|
# 'cipherSuites': '', # Go lang sets
|
240
242
|
# 'rejectUnknownSni': '', # default is false
|
241
243
|
}
|
242
|
-
|
243
|
-
ss['network'] = proxy['transport']
|
244
|
-
add_reality_stream(ss, proxy)
|
244
|
+
|
245
245
|
if proxy['l3'] == ProxyL3.kcp:
|
246
246
|
ss['network'] = 'kcp'
|
247
247
|
add_kcp_stream(ss, proxy)
|
@@ -249,7 +249,7 @@ def add_stream_settings(base: dict, proxy: dict):
|
|
249
249
|
if proxy['l3'] == ProxyL3.h3_quic:
|
250
250
|
add_quic_stream(ss, proxy)
|
251
251
|
|
252
|
-
if proxy['transport'] == 'tcp'
|
252
|
+
if (proxy['transport'] == 'tcp' and ss['security'] != 'reality') or (ss['security'] == 'none' and proxy['transport'] not in [ProxyTransport.httpupgrade, ProxyTransport.WS] and proxy['proto'] != ProxyProto.ss):
|
253
253
|
ss['network'] = proxy['transport']
|
254
254
|
add_tcp_stream(ss, proxy)
|
255
255
|
if proxy['transport'] == ProxyTransport.h2 and ss['security'] == 'none' and ss['security'] != 'reality':
|
@@ -243,8 +243,8 @@ class ConfigEnum(metaclass=FastEnum):
|
|
243
243
|
trojan_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
|
244
244
|
reality_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
|
245
245
|
tcp_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
|
246
|
-
quic_enable = _BoolConfigDscr(ConfigCategory.
|
247
|
-
xtls_enable = _BoolConfigDscr(ConfigCategory.
|
246
|
+
quic_enable = _BoolConfigDscr(ConfigCategory.hidden, ApplyMode.apply)
|
247
|
+
xtls_enable = _BoolConfigDscr(ConfigCategory.hidden, ApplyMode.apply)
|
248
248
|
h2_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
|
249
249
|
|
250
250
|
db_version = _StrConfigDscr(ConfigCategory.hidden, ApplyMode.apply)
|
hiddifypanel/models/domain.py
CHANGED
@@ -38,7 +38,7 @@ ShowDomain = db.Table('show_domain',
|
|
38
38
|
class Domain(db.Model, SerializerMixin):
|
39
39
|
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
40
40
|
child_id = db.Column(db.Integer, db.ForeignKey('child.id'), default=0)
|
41
|
-
domain = db.Column(db.String(200), nullable=
|
41
|
+
domain = db.Column(db.String(200), nullable=True, unique=False)
|
42
42
|
alias = db.Column(db.String(200))
|
43
43
|
sub_link_only = db.Column(db.Boolean, nullable=False, default=False)
|
44
44
|
mode = db.Column(db.Enum(DomainType), nullable=False, default=DomainType.direct)
|
@@ -65,7 +65,7 @@ class DomainAdmin(AdminLTEModelView):
|
|
65
65
|
'domain': {
|
66
66
|
'validators': [
|
67
67
|
Regexp(
|
68
|
-
r'^(\*\.)?([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,})
|
68
|
+
r'^(\*\.)?([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,})$|^$',
|
69
69
|
message=__("Should be a valid domain"))]},
|
70
70
|
"cdn_ip": {
|
71
71
|
'validators': [
|
@@ -109,21 +109,24 @@ class DomainAdmin(AdminLTEModelView):
|
|
109
109
|
f'</a><a href="{admin_link}" class="btn btn-xs btn-info ltr" target="_blank">{model.domain}</a></div>')
|
110
110
|
|
111
111
|
def _domain_ip(view, context, model, name):
|
112
|
-
|
112
|
+
dips = hutils.network.get_domain_ips(model.domain)
|
113
113
|
# The get_domain_ip function uses the socket library, which relies on the system DNS resolver. So it may sometimes use cached data, which is not desirable
|
114
|
-
if not
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
res
|
126
|
-
|
114
|
+
# if not dips:
|
115
|
+
# dip = hutils.network.resolve_domain_with_api(model.domain)
|
116
|
+
myips = set(hutils.network.get_ips())
|
117
|
+
all_res = ""
|
118
|
+
for dip in dips:
|
119
|
+
if dip in myips and model.mode in [DomainType.direct, DomainType.sub_link_only]:
|
120
|
+
badge_type = ''
|
121
|
+
elif dip and dip not in myips and model.mode != DomainType.direct:
|
122
|
+
badge_type = 'warning'
|
123
|
+
else:
|
124
|
+
badge_type = 'danger'
|
125
|
+
res = f'<span class="badge badge-{badge_type}">{dip}</span>'
|
126
|
+
if model.sub_link_only:
|
127
|
+
res += f'<span class="badge badge-success">{_("SubLink")}</span>'
|
128
|
+
all_res += res
|
129
|
+
return Markup(all_res)
|
127
130
|
|
128
131
|
def _show_domains_formater(view, context, model, name):
|
129
132
|
if not len(model.show_domains):
|
@@ -149,8 +152,9 @@ class DomainAdmin(AdminLTEModelView):
|
|
149
152
|
|
150
153
|
# TODO: refactor this function
|
151
154
|
def on_model_change(self, form, model, is_created):
|
152
|
-
model.domain = model.domain.lower()
|
153
|
-
|
155
|
+
model.domain = (model.domain or '').lower()
|
156
|
+
if model.domain == '' and model.mode != DomainType.fake:
|
157
|
+
raise ValidationError(_("domain.empty.allowed_for_fake_only"))
|
154
158
|
configs = get_hconfigs()
|
155
159
|
for c in configs:
|
156
160
|
if "domain" in c and c not in [ConfigEnum.decoy_domain, ConfigEnum.reality_fallback_domain] and c.category != 'hidden':
|
@@ -174,7 +178,7 @@ class DomainAdmin(AdminLTEModelView):
|
|
174
178
|
if "*" in model.domain and model.mode not in [DomainType.cdn, DomainType.auto_cdn_ip]:
|
175
179
|
raise ValidationError(_("Domain can not be resolved! there is a problem in your domain"))
|
176
180
|
|
177
|
-
skip_check = "*" in model.domain
|
181
|
+
skip_check = "*" in model.domain or model.domain == ""
|
178
182
|
if hconfig(ConfigEnum.cloudflare) and model.mode not in [DomainType.fake, DomainType.relay, DomainType.reality]:
|
179
183
|
try:
|
180
184
|
proxied = model.mode in [DomainType.cdn, DomainType.auto_cdn_ip]
|
@@ -190,28 +194,30 @@ class DomainAdmin(AdminLTEModelView):
|
|
190
194
|
# hutils.flask.flash(__("Using alias with special charachters may cause problem in some clients like FairVPN."), 'warning')
|
191
195
|
# raise ValidationError(_("You have to add your cloudflare api key to use this feature: "))
|
192
196
|
|
193
|
-
|
197
|
+
dips = hutils.network.get_domain_ips(model.domain)
|
194
198
|
if model.sub_link_only:
|
195
|
-
if
|
199
|
+
if not dips:
|
196
200
|
raise ValidationError(_("Domain can not be resolved! there is a problem in your domain")) # type: ignore
|
197
201
|
elif not skip_check:
|
198
|
-
if
|
202
|
+
if not dips:
|
199
203
|
raise ValidationError(_("Domain can not be resolved! there is a problem in your domain")) # type: ignore
|
200
204
|
|
201
205
|
domain_ip_is_same_as_panel = False
|
202
|
-
|
203
|
-
for
|
204
|
-
domain_ip_is_same_as_panel |=
|
206
|
+
server_ips = [*ipv4_list, *ipv6_list]
|
207
|
+
for mip in server_ips:
|
208
|
+
domain_ip_is_same_as_panel |= mip in dips
|
209
|
+
server_ips_str = ', '.join(list(map(str, server_ips)))
|
210
|
+
dips_str = ', '.join(list(map(str, dips)))
|
205
211
|
|
206
212
|
if model.mode == DomainType.direct and not domain_ip_is_same_as_panel:
|
207
213
|
# hutils.flask.flash(__(f"Domain IP={dip} is not matched with your ip={', '.join(list(map(str, ipv4_list)))} which is required in direct mode"),category='error')
|
208
214
|
raise ValidationError(
|
209
|
-
__("Domain IP=%(domain_ip)s is not matched with your ip=%(server_ip)s which is required in direct mode", server_ip=
|
215
|
+
__("Domain IP=%(domain_ip)s is not matched with your ip=%(server_ip)s which is required in direct mode", server_ip=server_ips_str, domain_ip=dips_str)) # type: ignore
|
210
216
|
|
211
217
|
if domain_ip_is_same_as_panel and model.mode in [DomainType.cdn, DomainType.relay, DomainType.fake, DomainType.auto_cdn_ip]:
|
212
218
|
# # hutils.flask.flash(__(f"In CDN mode, Domain IP={dip} should be different to your ip={', '.join(list(map(str, ipv4_list)))}"), 'warning')
|
213
219
|
raise ValidationError(__("In CDN mode, Domain IP=%(domain_ip)s should be different to your ip=%(server_ip)s",
|
214
|
-
server_ip=
|
220
|
+
server_ip=server_ips_str, domain_ip=dips_str)) # type: ignore
|
215
221
|
|
216
222
|
# if model.mode in [DomainType.ss_faketls, DomainType.telegram_faketls]:
|
217
223
|
# if len(Domain.query.filter(Domain.mode==model.mode and Domain.id!=model.id).all())>0:
|
@@ -219,10 +225,11 @@ class DomainAdmin(AdminLTEModelView):
|
|
219
225
|
|
220
226
|
model.domain = model.domain.lower()
|
221
227
|
if model.mode == DomainType.direct and model.cdn_ip:
|
228
|
+
model.cdn_ip = ""
|
222
229
|
raise ValidationError(f"Specifying CDN IP is only valid for CDN mode")
|
223
230
|
|
224
231
|
if model.mode == DomainType.fake and not model.cdn_ip:
|
225
|
-
model.cdn_ip = str(
|
232
|
+
model.cdn_ip = str(server_ips[0])
|
226
233
|
|
227
234
|
# if model.mode==DomainType.fake and model.cdn_ip!=myip:
|
228
235
|
# raise ValidationError(f"Specifying CDN IP is only valid for CDN mode")
|
@@ -230,8 +237,14 @@ class DomainAdmin(AdminLTEModelView):
|
|
230
237
|
# # Update the many-to-many relationship
|
231
238
|
if len(model.show_domains) == Domain.query.count():
|
232
239
|
model.show_domains = []
|
233
|
-
|
234
|
-
|
240
|
+
if model.mode == DomainType.old_xtls_direct:
|
241
|
+
if not hconfig(ConfigEnum.xtls_enable):
|
242
|
+
set_hconfig(ConfigEnum.xtls_enable, True)
|
243
|
+
hutils.proxy.get_proxies().invalidate_all()
|
244
|
+
elif model.mode == DomainType.reality:
|
245
|
+
if not hconfig(ConfigEnum.reality_enable):
|
246
|
+
set_hconfig(ConfigEnum.reality_enable, True)
|
247
|
+
hutils.proxy.get_proxies().invalidate_all()
|
235
248
|
model.servernames = (model.servernames or model.domain).lower()
|
236
249
|
for v in set([model.domain, model.servernames]):
|
237
250
|
for d in v.split(","):
|
@@ -240,9 +253,9 @@ class DomainAdmin(AdminLTEModelView):
|
|
240
253
|
if not hutils.network.is_domain_reality_friendly(d): # the minimum requirement for the REALITY protocol is to have tls1.3 and h2
|
241
254
|
raise ValidationError(_("Domain is not REALITY friendly!") + f' {d}')
|
242
255
|
|
243
|
-
if not hutils.network.is_in_same_asn(d,
|
244
|
-
server_asn = hutils.network.get_ip_asn(
|
245
|
-
domain_asn = hutils.network.get_ip_asn(
|
256
|
+
if not hutils.network.is_in_same_asn(d, server_ips[0]):
|
257
|
+
server_asn = hutils.network.get_ip_asn(server_ips[0])
|
258
|
+
domain_asn = hutils.network.get_ip_asn(dips[0]) # type: ignore
|
246
259
|
msg = _("domain.reality.asn_issue") + \
|
247
260
|
(f"<br> Server ASN={server_asn}<br>{d}_ASN={domain_asn}" if server_asn or domain_asn else "")
|
248
261
|
hutils.flask.flash(msg, 'warning')
|
@@ -4,6 +4,7 @@ import uuid
|
|
4
4
|
# from flask_babelex import lazy_gettext as _
|
5
5
|
from flask import render_template, g, request
|
6
6
|
from flask_babel import gettext as _
|
7
|
+
from markupsafe import Markup
|
7
8
|
import wtforms as wtf
|
8
9
|
from flask_wtf import FlaskForm
|
9
10
|
from flask_bootstrap import SwitchField
|
@@ -22,67 +23,46 @@ from hiddifypanel.models import *
|
|
22
23
|
class QuickSetup(FlaskView):
|
23
24
|
decorators = [login_required({Role.super_admin})]
|
24
25
|
|
26
|
+
def current_form(self, step=None, empty=False, next=False):
|
27
|
+
step = int(step or request.form.get("step") or request.args.get('step', "1"))
|
28
|
+
if next:
|
29
|
+
step = step + 1
|
30
|
+
form = {1: get_lang_form,
|
31
|
+
2: get_quick_setup_form,
|
32
|
+
3: get_proxy_form}
|
33
|
+
|
34
|
+
return form[step](empty=empty or next)
|
35
|
+
|
25
36
|
def index(self):
|
26
37
|
return render_template(
|
27
|
-
'quick_setup.html',
|
28
|
-
form=
|
29
|
-
ipv4=hutils.network.get_ip_str(4),
|
30
|
-
ipv6=hutils.network.get_ip_str(6),
|
38
|
+
'quick_setup.html',
|
39
|
+
form=self.current_form(),
|
40
|
+
# ipv4=hutils.network.get_ip_str(4),
|
41
|
+
# ipv6=hutils.network.get_ip_str(6),
|
31
42
|
admin_link=admin_link(),
|
32
43
|
show_domain_info=True)
|
33
44
|
|
34
45
|
def post(self):
|
35
46
|
if request.args.get('changepw') == "true":
|
36
47
|
AdminUser.current_admin_or_owner().uuid = str(uuid.uuid4())
|
37
|
-
|
38
|
-
quick_form = get_quick_setup_form()
|
39
|
-
lang_form = get_lang_form()
|
40
|
-
if lang_form.lang_submit.data:
|
41
|
-
if lang_form.validate_on_submit():
|
42
|
-
set_hconfig(ConfigEnum.lang, lang_form.admin_lang.data)
|
43
|
-
set_hconfig(ConfigEnum.admin_lang, lang_form.admin_lang.data)
|
44
|
-
set_hconfig(ConfigEnum.country, lang_form.country.data)
|
45
|
-
|
46
|
-
flask_babel.refresh()
|
47
|
-
hutils.flask.flash((_('quicksetup.setlang.success')), 'success')
|
48
|
-
else:
|
49
|
-
hutils.flask.flash((_('quicksetup.setlang.error')), 'danger')
|
48
|
+
db.session.commit()
|
50
49
|
|
50
|
+
set_hconfig(ConfigEnum.first_setup, False)
|
51
|
+
form = self.current_form()
|
52
|
+
if not form.validate_on_submit() or form.step.data not in ["1", "2", "3"]:
|
53
|
+
hutils.flask.flash(_('config.validation-error'), 'danger')
|
51
54
|
return render_template(
|
52
|
-
'quick_setup.html', form=
|
53
|
-
lang_form=get_lang_form(),
|
55
|
+
'quick_setup.html', form=form,
|
54
56
|
admin_link=admin_link(),
|
55
57
|
ipv4=hutils.network.get_ip_str(4),
|
56
58
|
ipv6=hutils.network.get_ip_str(6),
|
57
59
|
show_domain_info=False)
|
58
|
-
|
59
|
-
if quick_form.validate_on_submit():
|
60
|
-
Domain.query.filter(Domain.domain == f'{hutils.network.get_ip_str(4)}.sslip.io').delete()
|
61
|
-
db.session.add(Domain(domain=quick_form.domain.data.lower(), mode=DomainType.direct))
|
62
|
-
set_hconfig(ConfigEnum.block_iran_sites, quick_form.block_iran_sites.data)
|
63
|
-
set_hconfig(ConfigEnum.decoy_domain, quick_form.decoy_domain.data)
|
64
|
-
# hiddify.bulk_register_configs([
|
65
|
-
# # {"key": ConfigEnum.telegram_enable, "value": quick_form.enable_telegram.data == True},
|
66
|
-
# # {"key": ConfigEnum.vmess_enable, "value": quick_form.enable_vmess.data == True},
|
67
|
-
# # {"key": ConfigEnum.firewall, "value": quick_form.enable_firewall.data == True},
|
68
|
-
# {"key": ConfigEnum.block_iran_sites, "value": quick_form.block_iran_sites.data == True},
|
69
|
-
# # {"key":ConfigEnum.decoy_domain,"value":quick_form.decoy_domain.data}
|
70
|
-
# ])
|
71
|
-
|
72
|
-
from .Actions import Actions
|
73
|
-
return Actions().reinstall(domain_changed=True)
|
74
|
-
else:
|
75
|
-
hutils.flask.flash(_('config.validation-error'), 'danger')
|
76
|
-
return render_template(
|
77
|
-
'quick_setup.html', form=quick_form, lang_form=get_lang_form(True),
|
78
|
-
ipv4=hutils.network.get_ip_str(4),
|
79
|
-
ipv6=hutils.network.get_ip_str(6),
|
80
|
-
admin_link=admin_link(),
|
81
|
-
show_domain_info=False)
|
60
|
+
return form.post(self)
|
82
61
|
|
83
62
|
|
84
63
|
def get_lang_form(empty=False):
|
85
64
|
class LangForm(FlaskForm):
|
65
|
+
step = wtf.HiddenField(default="1")
|
86
66
|
admin_lang = wtf.SelectField(
|
87
67
|
_("config.admin_lang.label"), choices=[("en", _("lang.en")), ("fa", _("lang.fa")), ("pt", _("lang.pt")), ("zh", _("lang.zh")), ("ru", _("lang.ru"))],
|
88
68
|
description=_("config.admin_lang.description"),
|
@@ -94,7 +74,61 @@ def get_lang_form(empty=False):
|
|
94
74
|
default=hconfig(ConfigEnum.country))
|
95
75
|
lang_submit = wtf.SubmitField(_('Submit'))
|
96
76
|
|
97
|
-
|
77
|
+
def post(self, view):
|
78
|
+
set_hconfig(ConfigEnum.lang, self.admin_lang.data)
|
79
|
+
set_hconfig(ConfigEnum.admin_lang, self.admin_lang.data)
|
80
|
+
set_hconfig(ConfigEnum.country, self.country.data)
|
81
|
+
|
82
|
+
flask_babel.refresh()
|
83
|
+
hutils.flask.flash((_('quicksetup.setlang.success')), 'success')
|
84
|
+
|
85
|
+
return render_template(
|
86
|
+
'quick_setup.html', form=view.current_form(next=True),
|
87
|
+
admin_link=admin_link(),
|
88
|
+
ipv4=hutils.network.get_ip_str(4),
|
89
|
+
ipv6=hutils.network.get_ip_str(6),
|
90
|
+
show_domain_info=False)
|
91
|
+
|
92
|
+
form = LangForm(None)if empty else LangForm()
|
93
|
+
form.step.data = "1"
|
94
|
+
return form
|
95
|
+
|
96
|
+
|
97
|
+
def get_proxy_form(empty=False):
|
98
|
+
class ProxyForm(FlaskForm):
|
99
|
+
step = wtf.HiddenField(default="3")
|
100
|
+
description_for_fieldset = wtf.TextAreaField("", description=_(f'quicksetup.proxy_cat.description'), render_kw={"class": "d-none"})
|
101
|
+
|
102
|
+
def post(self, view):
|
103
|
+
|
104
|
+
for k, vs in self.data.items():
|
105
|
+
ek = ConfigEnum[k]
|
106
|
+
if ek != ConfigEnum.not_found:
|
107
|
+
set_hconfig(ek, vs, commit=False)
|
108
|
+
|
109
|
+
db.session.commit()
|
110
|
+
# print(cat,vs)
|
111
|
+
hutils.proxy.get_proxies.invalidate_all()
|
112
|
+
if hutils.node.is_child():
|
113
|
+
hutils.node.run_node_op_in_bg(hutils.node.child.sync_with_parent, *[hutils.node.child.SyncFields.hconfigs])
|
114
|
+
|
115
|
+
from .Actions import Actions
|
116
|
+
return Actions().reinstall(domain_changed=True)
|
117
|
+
boolconfigs = BoolConfig.query.filter(BoolConfig.child_id == Child.current().id).all()
|
118
|
+
|
119
|
+
for cf in boolconfigs:
|
120
|
+
if cf.key.category == 'hidden':
|
121
|
+
continue
|
122
|
+
if cf.key.startswith("sub_") or cf.key.startswith("mux_"):
|
123
|
+
continue
|
124
|
+
if not cf.key.endswith("_enable") or cf.key in [ConfigEnum.hysteria_obfs_enable, ConfigEnum.tls_padding_enable]:
|
125
|
+
continue
|
126
|
+
field = SwitchField(_(f'config.{cf.key}.label'), default=cf.value, description=_(f'config.{cf.key}.description'))
|
127
|
+
setattr(ProxyForm, f'{cf.key}', field)
|
128
|
+
setattr(ProxyForm, "submit_global", wtf.fields.SubmitField(_('Submit')))
|
129
|
+
form = ProxyForm(None) if empty else ProxyForm()
|
130
|
+
form.step.data = "3"
|
131
|
+
return form
|
98
132
|
|
99
133
|
|
100
134
|
def get_quick_setup_form(empty=False):
|
@@ -108,7 +142,9 @@ def get_quick_setup_form(empty=False):
|
|
108
142
|
domains.append(d.domain)
|
109
143
|
return domains
|
110
144
|
|
111
|
-
class
|
145
|
+
class BasicConfigs(FlaskForm):
|
146
|
+
step = wtf.HiddenField(default="2")
|
147
|
+
description_for_fieldset = wtf.TextAreaField("", description=_(f'quicksetup.proxy_cat.description'), render_kw={"class": "d-none"})
|
112
148
|
domain_regex = "^([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})$"
|
113
149
|
|
114
150
|
domain_validators = [
|
@@ -116,6 +152,12 @@ def get_quick_setup_form(empty=False):
|
|
116
152
|
validate_domain,
|
117
153
|
wtf.validators.NoneOf([d.domain.lower() for d in Domain.query.all()], _("config.Domain_already_used")),
|
118
154
|
wtf.validators.NoneOf([c.value.lower() for c in StrConfig.query.all() if "fakedomain" in c.key and c.key != ConfigEnum.decoy_domain], _("config.Domain_already_used"))]
|
155
|
+
|
156
|
+
cdn_domain_validators = [
|
157
|
+
wtf.validators.Regexp(f'({domain_regex})|(^$)', re.IGNORECASE, _("config.Invalid_domain")),
|
158
|
+
validate_domain_cdn,
|
159
|
+
wtf.validators.NoneOf([d.domain.lower() for d in Domain.query.all()], _("config.Domain_already_used")),
|
160
|
+
wtf.validators.NoneOf([c.value.lower() for c in StrConfig.query.all() if "fakedomain" in c.key and c.key != ConfigEnum.decoy_domain], _("config.Domain_already_used"))]
|
119
161
|
domain = wtf.StringField(
|
120
162
|
_("domain.domain"),
|
121
163
|
domain_validators,
|
@@ -126,6 +168,16 @@ def get_quick_setup_form(empty=False):
|
|
126
168
|
"title": domain_validators[0].message,
|
127
169
|
"required": "",
|
128
170
|
"placeholder": "sub.domain.com"})
|
171
|
+
|
172
|
+
cdn_domain = wtf.StringField(
|
173
|
+
_("quicksetup.cdn_domain.label"),
|
174
|
+
cdn_domain_validators,
|
175
|
+
description=_("quicksetup.cdn_domain.description"),
|
176
|
+
render_kw={
|
177
|
+
"class": "ltr",
|
178
|
+
"pattern": domain_validators[0].regex.pattern,
|
179
|
+
"title": domain_validators[0].message,
|
180
|
+
"placeholder": "sub.domain.com"})
|
129
181
|
# enable_telegram = SwitchField(_("config.telegram_enable.label"), description=_("config.telegram_enable.description"), default=hconfig(ConfigEnum.telegram_enable))
|
130
182
|
# enable_firewall = SwitchField(_("config.firewall.label"), description=_("config.firewall.description"), default=hconfig(ConfigEnum.firewall))
|
131
183
|
block_iran_sites = SwitchField(_("config.block_iran_sites.label"), description=_(
|
@@ -135,7 +187,31 @@ def get_quick_setup_form(empty=False):
|
|
135
187
|
ConfigEnum.decoy_domain), validators=[wtf.validators.Regexp(domain_regex, re.IGNORECASE, _("config.Invalid_domain")), hutils.flask.validate_domain_exist])
|
136
188
|
submit = wtf.SubmitField(_('Submit'))
|
137
189
|
|
138
|
-
|
190
|
+
def post(self, view):
|
191
|
+
Domain.query.filter(Domain.domain == f'{hutils.network.get_ip_str(4)}.sslip.io').delete()
|
192
|
+
db.session.add(Domain(domain=self.domain.data.lower(), mode=DomainType.direct))
|
193
|
+
if self.cdn_domain.data:
|
194
|
+
db.session.add(Domain(domain=self.cdn_domain.data.lower(), mode=DomainType.cdn))
|
195
|
+
set_hconfig(ConfigEnum.block_iran_sites, self.block_iran_sites.data)
|
196
|
+
set_hconfig(ConfigEnum.decoy_domain, self.decoy_domain.data)
|
197
|
+
# hiddify.bulk_register_configs([
|
198
|
+
# # {"key": ConfigEnum.telegram_enable, "value": quick_form.enable_telegram.data == True},
|
199
|
+
# # {"key": ConfigEnum.vmess_enable, "value": quick_form.enable_vmess.data == True},
|
200
|
+
# # {"key": ConfigEnum.firewall, "value": quick_form.enable_firewall.data == True},
|
201
|
+
# {"key": ConfigEnum.block_iran_sites, "value": quick_form.block_iran_sites.data == True},
|
202
|
+
# # {"key":ConfigEnum.decoy_domain,"value":quick_form.decoy_domain.data}
|
203
|
+
# ])
|
204
|
+
|
205
|
+
return render_template(
|
206
|
+
'quick_setup.html', form=view.current_form(next=True),
|
207
|
+
# ipv4=hutils.network.get_ip_str(4),
|
208
|
+
# ipv6=hutils.network.get_ip_str(6),
|
209
|
+
admin_link=admin_link(),
|
210
|
+
show_domain_info=False)
|
211
|
+
|
212
|
+
form = BasicConfigs(None) if empty else BasicConfigs()
|
213
|
+
form.step.data = "2"
|
214
|
+
return form
|
139
215
|
|
140
216
|
|
141
217
|
def validate_domain(form, field):
|
@@ -145,11 +221,26 @@ def validate_domain(form, field):
|
|
145
221
|
raise ValidationError(_("Domain can not be resolved! there is a problem in your domain"))
|
146
222
|
|
147
223
|
myip = hutils.network.get_ip(4)
|
148
|
-
|
224
|
+
myip6 = hutils.network.get_ip(4)
|
225
|
+
if dip and myip != dip and (not myip6 or myip6 != dip):
|
149
226
|
raise ValidationError(_("Domain (%(domain)s)-> IP=%(domain_ip)s is not matched with your ip=%(server_ip)s which is required in direct mode",
|
150
227
|
server_ip=myip, domain_ip=dip, domain=domain))
|
151
228
|
|
152
229
|
|
230
|
+
def validate_domain_cdn(form, field):
|
231
|
+
domain = field.data
|
232
|
+
if not domain:
|
233
|
+
return
|
234
|
+
dip = hutils.network.get_domain_ip(domain)
|
235
|
+
if dip is None:
|
236
|
+
raise ValidationError(_("Domain can not be resolved! there is a problem in your domain"))
|
237
|
+
|
238
|
+
myip = hutils.network.get_ip(4)
|
239
|
+
if myip == dip:
|
240
|
+
raise ValidationError(_("In CDN mode, Domain IP=%(domain_ip)s should be different to your ip=%(server_ip)s",
|
241
|
+
server_ip=myip, domain_ip=dip, domain=domain))
|
242
|
+
|
243
|
+
|
153
244
|
def admin_link():
|
154
245
|
domains = Domain.get_domains()
|
155
246
|
return hiddify.get_account_panel_link(g.account, domains[0] if len(domains)else hutils.network.get_ip_str(4))
|
@@ -24,6 +24,7 @@ from hiddifypanel.models import *
|
|
24
24
|
from hiddifypanel.database import db
|
25
25
|
from hiddifypanel.panel import hiddify, custom_widgets
|
26
26
|
from hiddifypanel import __version__
|
27
|
+
from hiddifypanel.cache import cache
|
27
28
|
|
28
29
|
|
29
30
|
class SettingAdmin(FlaskView):
|
@@ -111,6 +112,8 @@ class SettingAdmin(FlaskView):
|
|
111
112
|
if p_mode != PanelMode.standalone:
|
112
113
|
set_hconfig(ConfigEnum.panel_mode, PanelMode.standalone)
|
113
114
|
|
115
|
+
cache.invalidate_all_cached_functions()
|
116
|
+
# hutils.proxy.get_proxies.invalidate_all()
|
114
117
|
from hiddifypanel.panel.commercial.telegrambot import register_bot
|
115
118
|
register_bot(set_hook=True)
|
116
119
|
|
@@ -194,13 +197,15 @@ def get_config_form():
|
|
194
197
|
if c.key in bool_types:
|
195
198
|
field = SwitchField(_(f'config.{c.key}.label'), default=c.value, description=_(f'config.{c.key}.description'))
|
196
199
|
elif c.key == ConfigEnum.core_type:
|
197
|
-
field = wtf.SelectField(_(f"config.{c.key}.label"),
|
198
|
-
|
200
|
+
field = wtf.SelectField(_(f"config.{c.key}.label"),
|
201
|
+
choices=[("xray", _("Xray")), ("singbox", _("SingBox"))],
|
202
|
+
description=_(f"config.{c.key}.description"),
|
203
|
+
default=hconfig(c.key))
|
199
204
|
elif c.key == ConfigEnum.warp_mode:
|
200
|
-
field = wtf.SelectField(
|
201
|
-
|
202
|
-
|
203
|
-
|
205
|
+
field = wtf.SelectField(_(f"config.{c.key}.label"),
|
206
|
+
choices=[("disable", _("Disable")), ("all", _("All")), ("custom", _("Only Blocked and Local websites"))],
|
207
|
+
description=_(f"config.{c.key}.description"),
|
208
|
+
default=hconfig(c.key))
|
204
209
|
|
205
210
|
elif c.key == ConfigEnum.lang or c.key == ConfigEnum.admin_lang:
|
206
211
|
field = wtf.SelectField(
|
@@ -43,26 +43,17 @@
|
|
43
43
|
|
44
44
|
|
45
45
|
<div class="row">
|
46
|
-
<div class="card col-12">
|
47
|
-
<div class="card-header">{{_("config.lang.label")}}</div>
|
48
|
-
<div class="card-body">
|
49
46
|
|
50
|
-
<div class="row">
|
51
|
-
<div class="col-12">
|
52
47
|
|
53
|
-
|
54
|
-
</div>
|
55
|
-
</div>
|
56
|
-
</div>
|
57
|
-
</div>
|
58
|
-
|
59
|
-
<div class="card">
|
48
|
+
<div class="card col-12">
|
60
49
|
<div class="card-header">{{_("admin.quicksetup.title")}}</div>
|
61
50
|
<div class="card-body">
|
62
51
|
|
63
52
|
<div class="row">
|
64
53
|
<div class="card-columns">
|
54
|
+
{% if ipv4 or ipv6 %}
|
65
55
|
{{_('admin.quicksetup_intro',ipv4=ip_btn(ipv4),ipv6=ip_btn(ipv6))}}
|
56
|
+
{%endif%}
|
66
57
|
{{render_form(form,form_type="",extra_classes="card-columns1")}}
|
67
58
|
</div>
|
68
59
|
</div>
|
@@ -71,9 +62,24 @@
|
|
71
62
|
</div>
|
72
63
|
|
73
64
|
<style>
|
65
|
+
.form-group {
|
66
|
+
display: inline-block;
|
67
|
+
width: 100%;
|
68
|
+
}
|
69
|
+
|
70
|
+
fieldset {
|
71
|
+
margin: 20px 0;
|
72
|
+
}
|
73
|
+
|
74
|
+
legend {
|
75
|
+
background: transparent;
|
76
|
+
margin-bottom: 20px;
|
77
|
+
|
78
|
+
}
|
79
|
+
|
74
80
|
@media (min-width: 576px) {
|
75
81
|
.card-columns {
|
76
|
-
column-count:
|
82
|
+
column-count: 2;
|
77
83
|
}
|
78
84
|
}
|
79
85
|
|
hiddifypanel/panel/init_db.py
CHANGED
@@ -14,7 +14,7 @@ from hiddifypanel.database import db, db_execute
|
|
14
14
|
from flask import g
|
15
15
|
from sqlalchemy import text
|
16
16
|
from loguru import logger
|
17
|
-
MAX_DB_VERSION =
|
17
|
+
MAX_DB_VERSION = 100
|
18
18
|
|
19
19
|
|
20
20
|
def _v88(child_id):
|
@@ -47,11 +47,11 @@ def _v83(child_id):
|
|
47
47
|
|
48
48
|
def _v82(child_id):
|
49
49
|
set_hconfig(ConfigEnum.vless_enable, True)
|
50
|
-
set_hconfig(ConfigEnum.trojan_enable,
|
51
|
-
set_hconfig(ConfigEnum.reality_enable,
|
50
|
+
set_hconfig(ConfigEnum.trojan_enable, False)
|
51
|
+
set_hconfig(ConfigEnum.reality_enable, False)
|
52
52
|
set_hconfig(ConfigEnum.tcp_enable, True)
|
53
|
-
set_hconfig(ConfigEnum.quic_enable,
|
54
|
-
set_hconfig(ConfigEnum.xtls_enable,
|
53
|
+
set_hconfig(ConfigEnum.quic_enable, False)
|
54
|
+
set_hconfig(ConfigEnum.xtls_enable, False)
|
55
55
|
set_hconfig(ConfigEnum.h2_enable, True)
|
56
56
|
|
57
57
|
|
@@ -80,7 +80,7 @@ def _v75(child_id):
|
|
80
80
|
|
81
81
|
|
82
82
|
def _v74(child_id):
|
83
|
-
set_hconfig(ConfigEnum.ws_enable,
|
83
|
+
set_hconfig(ConfigEnum.ws_enable, False)
|
84
84
|
set_hconfig(ConfigEnum.grpc_enable, True)
|
85
85
|
set_hconfig(ConfigEnum.httpupgrade_enable, True)
|
86
86
|
set_hconfig(ConfigEnum.shadowsocks2022_port, hutils.random.get_random_unused_port())
|
Binary file
|
@@ -965,7 +965,7 @@ msgstr ""
|
|
965
965
|
"%(default_link)s"
|
966
966
|
|
967
967
|
msgid "admin.proxy.detailed_config"
|
968
|
-
msgstr "⚙️ Detailed Configs"
|
968
|
+
msgstr "⚙️ Detailed Configs: Only enabled configs are shown."
|
969
969
|
|
970
970
|
msgid "admin.proxy.global_config"
|
971
971
|
msgstr "⚙️ Global Configs"
|
@@ -2340,6 +2340,9 @@ msgstr ""
|
|
2340
2340
|
msgid "domain.domain_fronting.label"
|
2341
2341
|
msgstr "🔒 TLS Domain Fronting"
|
2342
2342
|
|
2343
|
+
msgid "domain.empty.allowed_for_fake_only"
|
2344
|
+
msgstr "domain.empty.allowed_for_fake_only"
|
2345
|
+
|
2343
2346
|
msgid "domain.intro"
|
2344
2347
|
msgstr ""
|
2345
2348
|
"1️⃣ In this section, you can add your Domain. \n"
|
@@ -2488,8 +2491,18 @@ msgstr "parent.sync-req-failed"
|
|
2488
2491
|
msgid "previous"
|
2489
2492
|
msgstr "Previous"
|
2490
2493
|
|
2491
|
-
msgid "quicksetup.
|
2492
|
-
msgstr "
|
2494
|
+
msgid "quicksetup.cdn_domain.description"
|
2495
|
+
msgstr ""
|
2496
|
+
"Setting CDN domain is optional. Only use it if you have already config a "
|
2497
|
+
"CDN."
|
2498
|
+
|
2499
|
+
msgid "quicksetup.cdn_domain.label"
|
2500
|
+
msgstr "CDN Domain"
|
2501
|
+
|
2502
|
+
msgid "quicksetup.proxy_cat.description"
|
2503
|
+
msgstr ""
|
2504
|
+
"Final Step: Please select the proxies you want. Please choose minimum as "
|
2505
|
+
"possible."
|
2493
2506
|
|
2494
2507
|
msgid "quicksetup.setlang.success"
|
2495
2508
|
msgstr "Changing the Language was Successful."
|
Binary file
|
@@ -953,7 +953,7 @@ msgstr ""
|
|
953
953
|
"%(default_link)s"
|
954
954
|
|
955
955
|
msgid "admin.proxy.detailed_config"
|
956
|
-
msgstr "⚙️ تنظیمات
|
956
|
+
msgstr "⚙️ تنظیمات دقیق: فقط کانفیگ های فعال نمایش داده میشود."
|
957
957
|
|
958
958
|
msgid "admin.proxy.global_config"
|
959
959
|
msgstr "⚙️ تنظیمات عمومی"
|
@@ -2345,6 +2345,9 @@ msgstr ""
|
|
2345
2345
|
msgid "domain.domain_fronting.label"
|
2346
2346
|
msgstr "🔒 فعال کردن دامین فرانتینگ در اتصال TLS"
|
2347
2347
|
|
2348
|
+
msgid "domain.empty.allowed_for_fake_only"
|
2349
|
+
msgstr ""
|
2350
|
+
|
2348
2351
|
msgid "domain.intro"
|
2349
2352
|
msgstr ""
|
2350
2353
|
|
@@ -2486,8 +2489,18 @@ msgstr ""
|
|
2486
2489
|
msgid "previous"
|
2487
2490
|
msgstr "قبلی"
|
2488
2491
|
|
2489
|
-
msgid "quicksetup.
|
2490
|
-
msgstr "
|
2492
|
+
msgid "quicksetup.cdn_domain.description"
|
2493
|
+
msgstr ""
|
2494
|
+
"تنظیم دامنه CDN اختیاری است. فقط در صورتی از آن استفاده کنید که قبلاً یک CDN"
|
2495
|
+
" را پیکربندی کرده باشید."
|
2496
|
+
|
2497
|
+
msgid "quicksetup.cdn_domain.label"
|
2498
|
+
msgstr "دامنه CDN"
|
2499
|
+
|
2500
|
+
msgid "quicksetup.proxy_cat.description"
|
2501
|
+
msgstr ""
|
2502
|
+
"مرحله آخر: لطفا پراکسی های مورد نظر خود را انتخاب کنید. لطفا حداقل تا حد "
|
2503
|
+
"امکان را انتخاب کنید."
|
2491
2504
|
|
2492
2505
|
msgid "quicksetup.setlang.success"
|
2493
2506
|
msgstr "تغییر زبان با موفقیت انجام شد"
|
Binary file
|
@@ -2251,6 +2251,9 @@ msgstr ""
|
|
2251
2251
|
msgid "domain.domain_fronting.label"
|
2252
2252
|
msgstr "🔒 Habilitar fronting de domínio TLS"
|
2253
2253
|
|
2254
|
+
msgid "domain.empty.allowed_for_fake_only"
|
2255
|
+
msgstr ""
|
2256
|
+
|
2254
2257
|
msgid "domain.intro"
|
2255
2258
|
msgstr ""
|
2256
2259
|
|
@@ -2394,8 +2397,14 @@ msgstr ""
|
|
2394
2397
|
msgid "previous"
|
2395
2398
|
msgstr "Anterior"
|
2396
2399
|
|
2397
|
-
msgid "quicksetup.
|
2398
|
-
msgstr "
|
2400
|
+
msgid "quicksetup.cdn_domain.description"
|
2401
|
+
msgstr ""
|
2402
|
+
|
2403
|
+
msgid "quicksetup.cdn_domain.label"
|
2404
|
+
msgstr ""
|
2405
|
+
|
2406
|
+
msgid "quicksetup.proxy_cat.description"
|
2407
|
+
msgstr ""
|
2399
2408
|
|
2400
2409
|
msgid "quicksetup.setlang.success"
|
2401
2410
|
msgstr "A alteração do idioma foi bem-sucedida."
|
Binary file
|
@@ -2358,6 +2358,9 @@ msgstr ""
|
|
2358
2358
|
msgid "domain.domain_fronting.label"
|
2359
2359
|
msgstr "🔒 Включить подключение к домену TLS"
|
2360
2360
|
|
2361
|
+
msgid "domain.empty.allowed_for_fake_only"
|
2362
|
+
msgstr ""
|
2363
|
+
|
2361
2364
|
msgid "domain.intro"
|
2362
2365
|
msgstr ""
|
2363
2366
|
|
@@ -2504,8 +2507,14 @@ msgstr ""
|
|
2504
2507
|
msgid "previous"
|
2505
2508
|
msgstr "Предыдущий"
|
2506
2509
|
|
2507
|
-
msgid "quicksetup.
|
2508
|
-
msgstr "
|
2510
|
+
msgid "quicksetup.cdn_domain.description"
|
2511
|
+
msgstr ""
|
2512
|
+
|
2513
|
+
msgid "quicksetup.cdn_domain.label"
|
2514
|
+
msgstr ""
|
2515
|
+
|
2516
|
+
msgid "quicksetup.proxy_cat.description"
|
2517
|
+
msgstr ""
|
2509
2518
|
|
2510
2519
|
msgid "quicksetup.setlang.success"
|
2511
2520
|
msgstr "Изменение языка прошло успешно."
|
Binary file
|
@@ -2176,6 +2176,9 @@ msgstr ""
|
|
2176
2176
|
msgid "domain.domain_fronting.label"
|
2177
2177
|
msgstr "🔒 启用 TLS 域前置"
|
2178
2178
|
|
2179
|
+
msgid "domain.empty.allowed_for_fake_only"
|
2180
|
+
msgstr ""
|
2181
|
+
|
2179
2182
|
msgid "domain.intro"
|
2180
2183
|
msgstr ""
|
2181
2184
|
|
@@ -2314,8 +2317,14 @@ msgstr ""
|
|
2314
2317
|
msgid "previous"
|
2315
2318
|
msgstr "以前的"
|
2316
2319
|
|
2317
|
-
msgid "quicksetup.
|
2318
|
-
msgstr "
|
2320
|
+
msgid "quicksetup.cdn_domain.description"
|
2321
|
+
msgstr ""
|
2322
|
+
|
2323
|
+
msgid "quicksetup.cdn_domain.label"
|
2324
|
+
msgstr ""
|
2325
|
+
|
2326
|
+
msgid "quicksetup.proxy_cat.description"
|
2327
|
+
msgstr ""
|
2319
2328
|
|
2320
2329
|
msgid "quicksetup.setlang.success"
|
2321
2330
|
msgstr "更改语言成功。"
|
@@ -260,7 +260,7 @@
|
|
260
260
|
},
|
261
261
|
"no_user_warning": "It seems that you have not created any users yet. default user link: %(default_link)s",
|
262
262
|
"proxy": {
|
263
|
-
"detailed_config": "⚙️ Detailed Configs",
|
263
|
+
"detailed_config": "⚙️ Detailed Configs: Only enabled configs are shown.",
|
264
264
|
"global_config": "⚙️ Global Configs"
|
265
265
|
},
|
266
266
|
"quicksetup": {
|
@@ -1026,6 +1026,9 @@
|
|
1026
1026
|
"description": "It is used to simulate another website instead of your website in SNI. therefore, GFW can not filter your Domain\n<a href='https://github.com/hiddify/hiddify-config/wiki/Guide-for-domain-fronting'>Guide</a>. ⚠️CloudFlare does not support Domain Fronting.",
|
1027
1027
|
"label": "🔒 TLS Domain Fronting"
|
1028
1028
|
},
|
1029
|
+
"empty": {
|
1030
|
+
"allowed_for_fake_only": "domain.empty.allowed_for_fake_only"
|
1031
|
+
},
|
1029
1032
|
"intro": "1️⃣ In this section, you can add your Domain. \n<br>\n2️⃣ If you want to lessen the probability of having dirty IP, you can add Multiple Relay Server <a href='https://github.com/hiddify/hiddify-config/discussions/129'>Read More</a>.\n<br>\n3️⃣ If you have Multiple IPv4 or IPv6 in your Panel you have to add the domain pointed to them as Relay.",
|
1030
1033
|
"ip": "IP",
|
1031
1034
|
"mode": "Mode",
|
@@ -1099,8 +1102,14 @@
|
|
1099
1102
|
},
|
1100
1103
|
"previous": "Previous",
|
1101
1104
|
"quicksetup": {
|
1105
|
+
"cdn_domain": {
|
1106
|
+
"description": "Setting CDN domain is optional. Only use it if you have already config a CDN.",
|
1107
|
+
"label": "CDN Domain"
|
1108
|
+
},
|
1109
|
+
"proxy_cat": {
|
1110
|
+
"description": "Final Step: Please select the proxies you want. Please choose minimum as possible."
|
1111
|
+
},
|
1102
1112
|
"setlang": {
|
1103
|
-
"error": "An error occurred while changing language.",
|
1104
1113
|
"success": "Changing the Language was Successful."
|
1105
1114
|
}
|
1106
1115
|
},
|
@@ -260,7 +260,7 @@
|
|
260
260
|
},
|
261
261
|
"no_user_warning": "شما هنوز هیچ کاربری ایجاد نکرده اید. لینک صفحه کاربری پیشفرض: %(default_link)s",
|
262
262
|
"proxy": {
|
263
|
-
"detailed_config": "⚙️ تنظیمات
|
263
|
+
"detailed_config": "⚙️ تنظیمات دقیق: فقط کانفیگ های فعال نمایش داده میشود.",
|
264
264
|
"global_config": "⚙️ تنظیمات عمومی"
|
265
265
|
},
|
266
266
|
"quicksetup": {
|
@@ -1026,6 +1026,9 @@
|
|
1026
1026
|
"description": "برای شبیه سازی وب سایت دیگری به جای وب سایت شما در SNI استفاده می شود. بنابراین، فیلترچی نمی تواند دامنه شما را فیلتر کند. \n<a href='https://github.com/hiddify/hiddify-config/wiki/استفاده-از-دامین-فرانتینگ'>آموزش ثبت </a>\n\n⚠️CloudFlare از دامین فرانتینگ پشتیبانی نمی کند.",
|
1027
1027
|
"label": "🔒 فعال کردن دامین فرانتینگ در اتصال TLS"
|
1028
1028
|
},
|
1029
|
+
"empty": {
|
1030
|
+
"allowed_for_fake_only": ""
|
1031
|
+
},
|
1029
1032
|
"intro": "",
|
1030
1033
|
"ip": "آیپی",
|
1031
1034
|
"mode": "حالت",
|
@@ -1099,8 +1102,14 @@
|
|
1099
1102
|
},
|
1100
1103
|
"previous": "قبلی",
|
1101
1104
|
"quicksetup": {
|
1105
|
+
"cdn_domain": {
|
1106
|
+
"description": "تنظیم دامنه CDN اختیاری است. فقط در صورتی از آن استفاده کنید که قبلاً یک CDN را پیکربندی کرده باشید.",
|
1107
|
+
"label": "دامنه CDN"
|
1108
|
+
},
|
1109
|
+
"proxy_cat": {
|
1110
|
+
"description": "مرحله آخر: لطفا پراکسی های مورد نظر خود را انتخاب کنید. لطفا حداقل تا حد امکان را انتخاب کنید."
|
1111
|
+
},
|
1102
1112
|
"setlang": {
|
1103
|
-
"error": "خطایی در تغییر زبان رخ داد",
|
1104
1113
|
"success": "تغییر زبان با موفقیت انجام شد"
|
1105
1114
|
}
|
1106
1115
|
},
|
@@ -1026,6 +1026,9 @@
|
|
1026
1026
|
"description": "É usado para simular outro site em vez do seu site no SNI. portanto, o GFW não pode filtrar seu domínio\n<a href='https://github.com/hiddify/hiddify-config/wiki/Guide-for-domain-fronting'>Guia</a>. ⚠️CloudFlare não suporta fronting de domínio.",
|
1027
1027
|
"label": "🔒 Habilitar fronting de domínio TLS"
|
1028
1028
|
},
|
1029
|
+
"empty": {
|
1030
|
+
"allowed_for_fake_only": ""
|
1031
|
+
},
|
1029
1032
|
"intro": "",
|
1030
1033
|
"ip": "IP",
|
1031
1034
|
"mode": "Modo",
|
@@ -1099,8 +1102,14 @@
|
|
1099
1102
|
},
|
1100
1103
|
"previous": "Anterior",
|
1101
1104
|
"quicksetup": {
|
1105
|
+
"cdn_domain": {
|
1106
|
+
"description": "",
|
1107
|
+
"label": ""
|
1108
|
+
},
|
1109
|
+
"proxy_cat": {
|
1110
|
+
"description": ""
|
1111
|
+
},
|
1102
1112
|
"setlang": {
|
1103
|
-
"error": "Ocorreu um erro ao alterar o idioma.",
|
1104
1113
|
"success": "A alteração do idioma foi bem-sucedida."
|
1105
1114
|
}
|
1106
1115
|
},
|
@@ -1026,6 +1026,9 @@
|
|
1026
1026
|
"description": "Он используется для имитации другого веб-сайта вместо вашего веб-сайта в SNI следовательно, GTW не может отфильтровать ваш домен\n<<a href='https://github.com/hibbity/hibbity-config/wiki/Guide-for-domain-fronting '>Руководство</a>. ⚠CloudFlare не поддерживает подключение к домену.",
|
1027
1027
|
"label": "🔒 Включить подключение к домену TLS"
|
1028
1028
|
},
|
1029
|
+
"empty": {
|
1030
|
+
"allowed_for_fake_only": ""
|
1031
|
+
},
|
1029
1032
|
"intro": "",
|
1030
1033
|
"ip": "IP",
|
1031
1034
|
"mode": "Режим",
|
@@ -1099,8 +1102,14 @@
|
|
1099
1102
|
},
|
1100
1103
|
"previous": "Предыдущий",
|
1101
1104
|
"quicksetup": {
|
1105
|
+
"cdn_domain": {
|
1106
|
+
"description": "",
|
1107
|
+
"label": ""
|
1108
|
+
},
|
1109
|
+
"proxy_cat": {
|
1110
|
+
"description": ""
|
1111
|
+
},
|
1102
1112
|
"setlang": {
|
1103
|
-
"error": "Произошла ошибка при смене языка.",
|
1104
1113
|
"success": "Изменение языка прошло успешно."
|
1105
1114
|
}
|
1106
1115
|
},
|
@@ -1026,6 +1026,9 @@
|
|
1026
1026
|
"description": "它用于在 SNI 中模拟另一个网站而不是您的网站。因此,GFW 无法过滤您的域名\n<a href='https://github.com/hiddify/hiddify-config/wiki/Guide-for-domain-fronting'>指南</a>。 ⚠️CloudFlare 不支持域前置。",
|
1027
1027
|
"label": "🔒 启用 TLS 域前置"
|
1028
1028
|
},
|
1029
|
+
"empty": {
|
1030
|
+
"allowed_for_fake_only": ""
|
1031
|
+
},
|
1029
1032
|
"intro": "",
|
1030
1033
|
"ip": "知识产权",
|
1031
1034
|
"mode": "模式",
|
@@ -1099,8 +1102,14 @@
|
|
1099
1102
|
},
|
1100
1103
|
"previous": "以前的",
|
1101
1104
|
"quicksetup": {
|
1105
|
+
"cdn_domain": {
|
1106
|
+
"description": "",
|
1107
|
+
"label": ""
|
1108
|
+
},
|
1109
|
+
"proxy_cat": {
|
1110
|
+
"description": ""
|
1111
|
+
},
|
1102
1112
|
"setlang": {
|
1103
|
-
"error": "更改语言时发生错误。",
|
1104
1113
|
"success": "更改语言成功。"
|
1105
1114
|
}
|
1106
1115
|
},
|
@@ -1,11 +1,11 @@
|
|
1
1
|
hiddifypanel/Events.py,sha256=AlnRdjVul0jP-NCT4-zoaQgowoOo-JhdQB4ytetAFKA,723
|
2
|
-
hiddifypanel/VERSION,sha256=
|
3
|
-
hiddifypanel/VERSION.py,sha256=
|
2
|
+
hiddifypanel/VERSION,sha256=Y6IENmPdjXKcyFlyeQEdpnopW1VkZD3KlHmAS1UFMyo,13
|
3
|
+
hiddifypanel/VERSION.py,sha256=PCPEWTyKxxkXM5tojvD0a2up6INqf7ZCIxDtdstpnc4,118
|
4
4
|
hiddifypanel/__init__.py,sha256=aLukp3ORszdcH4G9J-MlxhjHN6yFlOuOE6mm-L3aG_g,266
|
5
5
|
hiddifypanel/__main__.py,sha256=IVchnXpK6bm8T3N--mN17HBQNLMeLAjyP7iwzULexB4,218
|
6
6
|
hiddifypanel/auth.py,sha256=Xq0UwiFTRFmQpxnOehQGwPDlJqoelwGhPQbYZ0Xn5c0,7850
|
7
7
|
hiddifypanel/base.py,sha256=vnN0o7KFNZIQSix_TmYTRYVMRHioQ2TDCAV6LV20XWI,6079
|
8
|
-
hiddifypanel/cache.py,sha256=
|
8
|
+
hiddifypanel/cache.py,sha256=H-QhHbQbz0Avh_ntjPntzhnFJOKdLTJyIaovtOYH1GE,1507
|
9
9
|
hiddifypanel/database.py,sha256=14sfbGEG-NCqkfUtyLvcO2JbkQ3-Fzs-MezPNkNbvgk,717
|
10
10
|
hiddifypanel/drivers/abstract_driver.py,sha256=HpWkgbWVWF8n3WhDe0BlxsIF1WTWO57AQEAEb2ZVCPM,223
|
11
11
|
hiddifypanel/drivers/singbox_api.py,sha256=gdP_RM8b7qvDpN9RzUyJJ9i_MtMOpATx0LVDLEmDMjs,2270
|
@@ -29,7 +29,7 @@ hiddifypanel/hutils/importer/xui.py,sha256=TtmF4KJ263k3ByUvOeVKPlsGfj0tHLdlSdUQs
|
|
29
29
|
hiddifypanel/hutils/network/__init__.py,sha256=wQ1atebA98SC0agNc_Tbe4ct1aIIKaXOniSEyTE2PKo,348
|
30
30
|
hiddifypanel/hutils/network/auto_ip_selector.py,sha256=uSQjxnqI7NdJ6N_jCNtHAGLwjRjHagBG4GeR0lhD-HM,5667
|
31
31
|
hiddifypanel/hutils/network/cf_api.py,sha256=RgOGhx936VcMq_WpDc_xCtMhanMkh9zKdeBpSij5rcM,2611
|
32
|
-
hiddifypanel/hutils/network/net.py,sha256=
|
32
|
+
hiddifypanel/hutils/network/net.py,sha256=IaoLd8p4GNrMRkKtoiXFqRHWxdnwgPAOkAkr5CcwU9s,12043
|
33
33
|
hiddifypanel/hutils/node/__init__.py,sha256=p9-nse5h2p3SX6XdU33GOqOX-8OfvmdkDRmIq3cWDWM,63
|
34
34
|
hiddifypanel/hutils/node/api_client.py,sha256=Gr2532czQEE3YBh3sbeK036QI5gXDigUFlrMdJuO2sE,3684
|
35
35
|
hiddifypanel/hutils/node/child.py,sha256=oAyKlEHHn9FHcpZ9jBi3nYH-GHs8H7Gi2hzkmtO5IA8,6714
|
@@ -37,17 +37,17 @@ hiddifypanel/hutils/node/parent.py,sha256=UbyfvfP4fTSn6HN9oZDjYsKYIejiqW6eApKIfP
|
|
37
37
|
hiddifypanel/hutils/node/shared.py,sha256=FDSj3e-i3pb3mEv5vcUeX0Km1nxYg1CeAruIq7RwFmU,2540
|
38
38
|
hiddifypanel/hutils/proxy/__init__.py,sha256=xXBa83kjYT_b-BNseEykfQYyJBQHTq1ZosfR8ZrQHkI,106
|
39
39
|
hiddifypanel/hutils/proxy/clash.py,sha256=t57ywMo2TPpnAIuOn9v5gMD2os7zqS9b4NQtFX-Do5s,5813
|
40
|
-
hiddifypanel/hutils/proxy/shared.py,sha256=
|
40
|
+
hiddifypanel/hutils/proxy/shared.py,sha256=O7lVTUlNo-kbI0P2DMG9ZdmPypsrm8eoWUJeGIGEK3A,21832
|
41
41
|
hiddifypanel/hutils/proxy/singbox.py,sha256=WBSsGF7QeNvDPg0SbfWitV2_CP6UQ0gcV5-Gpy4AlkY,10786
|
42
42
|
hiddifypanel/hutils/proxy/xray.py,sha256=LFHjgQhebN4Kw1XzMDRk7F_K-2DSL93wkad12XijzBA,10694
|
43
|
-
hiddifypanel/hutils/proxy/xrayjson.py,sha256=
|
43
|
+
hiddifypanel/hutils/proxy/xrayjson.py,sha256=Ph1m_ZKINZ57XyWcnhp5mjASWL4ahj8ObVu3Kd7O8ZI,14452
|
44
44
|
hiddifypanel/models/__init__.py,sha256=PngFjQL9WvQP4EioNHRz1tTeyIgLoNvZ7WpmAhwKHnU,677
|
45
45
|
hiddifypanel/models/admin.py,sha256=qZ-BRJ_Gn6hJNWz35SQQSds1CoeDslU9B0MDBRhjPSM,7596
|
46
46
|
hiddifypanel/models/base_account.py,sha256=TUGDGHt3q3GWqWBdWwqaZl75KXTt7bw6pxnzOWAbkjI,3454
|
47
47
|
hiddifypanel/models/child.py,sha256=ZFJaH-GWTKAGD0BGMH0iKEMipi37_cAk59OeJKt2IKA,3039
|
48
48
|
hiddifypanel/models/config.py,sha256=-KKYqMkSEn2DabRxqBogSyA6xOU4ons6sa5CxxHAlAk,6373
|
49
|
-
hiddifypanel/models/config_enum.py,sha256=
|
50
|
-
hiddifypanel/models/domain.py,sha256=
|
49
|
+
hiddifypanel/models/config_enum.py,sha256=KDDXdYfNKjY3SUvmmhAJqLQ5cshFAsQjtqgZ8jbrjo8,15364
|
50
|
+
hiddifypanel/models/domain.py,sha256=szrSdqGZBZ4lS_D_K-XO8OUjU4ojKrxnYzXy5MgU2QA,8016
|
51
51
|
hiddifypanel/models/parent_domain.py,sha256=bs5F1neOAQu9XHEk3QQTBM4p2iuebM4cnAQqwfNjCtg,2291
|
52
52
|
hiddifypanel/models/proxy.py,sha256=9cm5Q0ZUEPeRDWdm1lQGom0SM_Q32NCDFTNFh36OzaQ,3304
|
53
53
|
hiddifypanel/models/report.py,sha256=33h9k12SAEWkwZsc3-jUdIIpFL66cEOTHQqVXd07NWY,1001
|
@@ -63,7 +63,7 @@ hiddifypanel/panel/cli.py,sha256=GNK-lqoedepG6hfpLHTPLxBaMsdjbQHZAw-qKjdRxnQ,859
|
|
63
63
|
hiddifypanel/panel/common.py,sha256=3jMmdoMk-qvdT8mSmIXEBh9y54P81EsWUKmGeK9qQKg,7593
|
64
64
|
hiddifypanel/panel/custom_widgets.py,sha256=9qI_fNX8NKqB1r8ljgcaisGZaDM89_PM_rOBZbGaTYs,2506
|
65
65
|
hiddifypanel/panel/hiddify.py,sha256=Tj2WSjNrlRJ3yahFINCTQSn36ygBgFB3SQRr9MegLuE,15572
|
66
|
-
hiddifypanel/panel/init_db.py,sha256=
|
66
|
+
hiddifypanel/panel/init_db.py,sha256=wewSjqu9LwvD9UiTtrAe4Y6BVl6EjzxwZ7ONUxwaWes,33397
|
67
67
|
hiddifypanel/panel/run_commander.py,sha256=D9y-My0xSe2adHWXKV5UPYGl-9WwKURzniq55MRu6tE,3259
|
68
68
|
hiddifypanel/panel/usage.py,sha256=LBmM5pKPbCxBxFozPjrXIypNVMlBn4ZyO46t5VBCNKg,6137
|
69
69
|
hiddifypanel/panel/admin/Actions.py,sha256=yRMKuCZ7J8F8KLlIfFUTYhdL19zVC_tujzZUWmTmCOA,8573
|
@@ -71,11 +71,11 @@ hiddifypanel/panel/admin/AdminstratorAdmin.py,sha256=eUUe5b8bGPj2nZstKkwK3lhqBhM
|
|
71
71
|
hiddifypanel/panel/admin/Backup.py,sha256=BKSoAZgw1j16P1Jh9vMqGj7ZfB2m-WafDK0C5vil5FY,3634
|
72
72
|
hiddifypanel/panel/admin/ConfigAdmin.py,sha256=0hnLY-8BxrpVnrAcQaedWjHnRUq1X_Styi_ZCZ2ivds,2876
|
73
73
|
hiddifypanel/panel/admin/Dashboard.py,sha256=JOqZLHxPOYKQYQVJ7AtHAkilH-anJZQyK1rQrgCJUeA,3798
|
74
|
-
hiddifypanel/panel/admin/DomainAdmin.py,sha256=
|
74
|
+
hiddifypanel/panel/admin/DomainAdmin.py,sha256=rAtLUgVHXarbqAsfskW-77oSpulWZ6bI4Gb0hHW79aU,15747
|
75
75
|
hiddifypanel/panel/admin/NodeAdmin.py,sha256=QAHQjF7e7F4KqsWNWpMt7SoLANlFEborVtWQV9OXJ2E,3102
|
76
|
-
hiddifypanel/panel/admin/ProxyAdmin.py,sha256=
|
77
|
-
hiddifypanel/panel/admin/QuickSetup.py,sha256=
|
78
|
-
hiddifypanel/panel/admin/SettingAdmin.py,sha256=
|
76
|
+
hiddifypanel/panel/admin/ProxyAdmin.py,sha256=jiay6e9Eyi_-VgWORBLgCAyzxLRYCAyJnlG7DtFaQIc,5243
|
77
|
+
hiddifypanel/panel/admin/QuickSetup.py,sha256=EDa_ombxF3vWDsj7JEmDnw8Kf0bKwdXU-IdISDi2hj0,11448
|
78
|
+
hiddifypanel/panel/admin/SettingAdmin.py,sha256=EMBAW4v4F4dFpz3ApfT2HiXMtqSnQA1DfaUj4oAMuwU,19553
|
79
79
|
hiddifypanel/panel/admin/Terminal.py,sha256=rzZWRjMhjVnAvC65rfE3HJT3boUDznI6fl-htzKp7sI,1712
|
80
80
|
hiddifypanel/panel/admin/UserAdmin.py,sha256=UPPg92NGxclBKE-inYas58Lz2bc06oFibSMdygQaC2M,18020
|
81
81
|
hiddifypanel/panel/admin/__init__.py,sha256=hb0A2HuK_nBZRCNPumwahXX-25FMxODKYlNbk2ItF08,3015
|
@@ -93,7 +93,7 @@ hiddifypanel/panel/admin/templates/index.html,sha256=4QPq8ATHmzaEpMjLkxCRpTTaZZ1
|
|
93
93
|
hiddifypanel/panel/admin/templates/ltemaster.html,sha256=KE_HsUOIR__BG1fW8DZ05rhgckQ8ls0a-ho6dWtmuX4,1080
|
94
94
|
hiddifypanel/panel/admin/templates/parent_dash.html,sha256=kAVBwv287oaQFfNmvTxBqgaZOaAf1Nz6jPXfEZMfTXQ,1814
|
95
95
|
hiddifypanel/panel/admin/templates/proxy.html,sha256=Q-Flp_O1LuuJnwWbodte2yr96MGzDoqgU50kB4dcsf0,1777
|
96
|
-
hiddifypanel/panel/admin/templates/quick_setup.html,sha256=
|
96
|
+
hiddifypanel/panel/admin/templates/quick_setup.html,sha256=tYZnRBH682eThl6lQcnLNKIdCQDTWRZWccIZSiNxSlA,2101
|
97
97
|
hiddifypanel/panel/admin/templates/redirect_to_admin.html,sha256=ivXFEUOv-3sKCJYPlJGjIrALxTaqq9SkjW5NLDKB3DI,139
|
98
98
|
hiddifypanel/panel/admin/templates/result.html,sha256=q8mZDl0Wmzxy23TP9YZBOZ2Gsklvuzfewd1ce0FogFc,6786
|
99
99
|
hiddifypanel/panel/admin/templates/view_logs.html,sha256=cemHWjYifbPVgaa9CuHf2nKOwTnYuBura9oZ7NKCBW0,771
|
@@ -822,24 +822,24 @@ hiddifypanel/templates/redirect.html,sha256=K9x_O4P96vEkqBhOXIhoGrWw1KIqd2bL0BjI
|
|
822
822
|
hiddifypanel/templates/static.html,sha256=jp6q4wtx-k2A_cjqJoNiMS7Ee30arE45qI3ev4d5ky4,165
|
823
823
|
hiddifypanel/templates/hiddify-flask-admin/actions.html,sha256=2NeITe2e-lPKCk_o511tCIqVtrPu8LYHE1wTCtrFUrI,1331
|
824
824
|
hiddifypanel/templates/hiddify-flask-admin/list.html,sha256=MBGrTqZpzNLe4sZy0RozvXNr8seFUQc2C6v88BJtNWc,11095
|
825
|
-
hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=
|
826
|
-
hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=
|
827
|
-
hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=
|
828
|
-
hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=
|
829
|
-
hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=
|
830
|
-
hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256
|
831
|
-
hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=
|
832
|
-
hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=
|
833
|
-
hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=
|
834
|
-
hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=
|
835
|
-
hiddifypanel/translations.i18n/en.json,sha256=
|
836
|
-
hiddifypanel/translations.i18n/fa.json,sha256=
|
837
|
-
hiddifypanel/translations.i18n/pt.json,sha256=
|
838
|
-
hiddifypanel/translations.i18n/ru.json,sha256=
|
839
|
-
hiddifypanel/translations.i18n/zh.json,sha256=
|
840
|
-
hiddifypanel-10.30.9.
|
841
|
-
hiddifypanel-10.30.9.
|
842
|
-
hiddifypanel-10.30.9.
|
843
|
-
hiddifypanel-10.30.9.
|
844
|
-
hiddifypanel-10.30.9.
|
845
|
-
hiddifypanel-10.30.9.
|
825
|
+
hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=iMDqnzl1z2iGaY_NJmCoRKOltuFXcklHm86Z7Kg9FC0,75756
|
826
|
+
hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=96O8XWX3UEb8OCw0WL9cGTOkzyU51UupXSKt4dBMs14,78920
|
827
|
+
hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=ak3v2PQgdDMyWF00RkKwGneDWdIxGj4M6_qb3msndN4,96092
|
828
|
+
hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=JdZQhrLwzFDngs0Wu3qDJaCxSoh7UJn09zwPTMKupyg,101469
|
829
|
+
hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=n5yiUZy_2I8OwE1kq5m5gHquM6KGpYSHl1ltFktCXoM,58649
|
830
|
+
hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256=tEWo_g0gJAm1wlmRWfV7rKjt1w87GglPwv504K7hPyI,69401
|
831
|
+
hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=MFrKhsX-nKtqj8-cqL1FdpI47YpO2Z0FqbF8khpqVKU,97620
|
832
|
+
hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=7gdyumMtKwmL2KtbdE6aVSZ31N5VM51GuyHhS__41ds,104624
|
833
|
+
hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=vlgjN9lFxAnZwVx9qJu4SE17oELs0oYiXr7aGcs0vWs,58966
|
834
|
+
hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=8aP7TqaDZjDEHwiL0t8_eu5yP5PH8OrgouOND9ExH88,68629
|
835
|
+
hiddifypanel/translations.i18n/en.json,sha256=IukyU5kkY_FRkFx_xT1APP7A5PASazjFOzMzDg5aZy0,68563
|
836
|
+
hiddifypanel/translations.i18n/fa.json,sha256=ebTs9S5L4F_rFYfQxuJ8pMr6fz2PG8i8fkl4Soyxhzc,91103
|
837
|
+
hiddifypanel/translations.i18n/pt.json,sha256=YQseQvgHDlCy3HHVJo-yAvepMl_y-zCU0qPLARybDmA,59407
|
838
|
+
hiddifypanel/translations.i18n/ru.json,sha256=dCp5BI_15WoiMpV2u9_6M6feS_yL_lf22gXeyMqJDB4,94231
|
839
|
+
hiddifypanel/translations.i18n/zh.json,sha256=8iFoOhmXeoPJHWop7Fa8FMs1Ix-5jvn09gq8N9w1iUs,58875
|
840
|
+
hiddifypanel-10.30.9.dev2.dist-info/LICENSE.md,sha256=oDrt-cUsyiDGnRPjEJh-3dH2ddAuK_bIVBD8ntkOtZw,19807
|
841
|
+
hiddifypanel-10.30.9.dev2.dist-info/METADATA,sha256=Z4jbG1XjsMbwtM5kF_qH05ZEyV2WngsuIy4aQv6D_Bo,4044
|
842
|
+
hiddifypanel-10.30.9.dev2.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
843
|
+
hiddifypanel-10.30.9.dev2.dist-info/entry_points.txt,sha256=Xzpqlh3nwBtZhoV9AANJykano056VJvYzaujxPztJaM,60
|
844
|
+
hiddifypanel-10.30.9.dev2.dist-info/top_level.txt,sha256=rv-b3qFWUZQTBy0kyBfsr7L6tPpeO7AaQlLHXn-HI5M,13
|
845
|
+
hiddifypanel-10.30.9.dev2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{hiddifypanel-10.30.9.dev0.dist-info → hiddifypanel-10.30.9.dev2.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|