hiddifypanel 10.70.8__py3-none-any.whl → 10.80.0__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 +5 -2
- hiddifypanel/__init__.py +5 -1
- hiddifypanel/apps/__init__.py +0 -0
- hiddifypanel/apps/asgi_app.py +7 -0
- hiddifypanel/apps/celery_app.py +3 -0
- hiddifypanel/apps/wsgi_app.py +5 -0
- hiddifypanel/auth.py +8 -3
- hiddifypanel/base.py +43 -126
- hiddifypanel/base_setup.py +82 -0
- hiddifypanel/cache.py +3 -2
- hiddifypanel/celery.py +45 -0
- hiddifypanel/database.py +7 -0
- hiddifypanel/drivers/ssh_liberty_bridge_api.py +2 -1
- hiddifypanel/drivers/wireguard_api.py +1 -1
- hiddifypanel/hutils/crypto.py +27 -0
- hiddifypanel/hutils/flask.py +5 -3
- hiddifypanel/hutils/network/cf_api.py +5 -5
- hiddifypanel/hutils/proxy/__init__.py +1 -0
- hiddifypanel/hutils/proxy/clash.py +3 -3
- hiddifypanel/hutils/proxy/shared.py +14 -18
- hiddifypanel/hutils/proxy/singbox.py +4 -2
- hiddifypanel/hutils/proxy/wireguard.py +34 -0
- hiddifypanel/hutils/proxy/xray.py +3 -3
- hiddifypanel/hutils/proxy/xrayjson.py +10 -7
- hiddifypanel/models/admin.py +1 -1
- hiddifypanel/models/base_account.py +3 -0
- hiddifypanel/models/config.py +5 -2
- hiddifypanel/models/config_enum.py +15 -2
- hiddifypanel/models/proxy.py +1 -1
- hiddifypanel/models/user.py +2 -2
- hiddifypanel/panel/__init__.py +8 -8
- hiddifypanel/panel/admin/AdminstratorAdmin.py +16 -10
- hiddifypanel/panel/admin/DomainAdmin.py +132 -98
- hiddifypanel/panel/admin/ProxyAdmin.py +4 -0
- hiddifypanel/panel/admin/QuickSetup.py +48 -17
- hiddifypanel/panel/admin/SettingAdmin.py +6 -0
- hiddifypanel/panel/admin/UserAdmin.py +63 -36
- hiddifypanel/panel/admin/adminlte.py +1 -1
- hiddifypanel/panel/admin/templates/index.html +6 -4
- hiddifypanel/panel/admin/templates/model/user_list.html +11 -3
- hiddifypanel/panel/cli.py +14 -3
- hiddifypanel/panel/commercial/restapi/v1/tgbot.py +19 -1
- hiddifypanel/panel/commercial/restapi/v2/admin/system_actions.py +5 -1
- hiddifypanel/panel/commercial/restapi/v2/admin/user_api.py +2 -1
- hiddifypanel/panel/commercial/restapi/v2/user/apps_api.py +76 -6
- hiddifypanel/panel/common.py +5 -2
- hiddifypanel/panel/common_bp/login.py +14 -8
- hiddifypanel/panel/hlogger.py +32 -0
- hiddifypanel/panel/init_db.py +157 -77
- hiddifypanel/panel/node/__init__.py +9 -0
- hiddifypanel/panel/node/a.py +14 -0
- hiddifypanel/panel/node/hello.py +14 -0
- hiddifypanel/panel/node/test.proto +13 -0
- hiddifypanel/panel/node/test_grpc.py +40 -0
- hiddifypanel/panel/node/test_pb2.py +40 -0
- hiddifypanel/panel/node/test_pb2.pyi +17 -0
- hiddifypanel/panel/node/test_pb2_grpc.py +97 -0
- hiddifypanel/panel/usage.py +13 -3
- hiddifypanel/panel/user/templates/base_singbox_config.json.j2 +16 -0
- hiddifypanel/panel/user/templates/home/home.html +1 -2
- hiddifypanel/panel/user/templates/home/multi.html +1 -2
- hiddifypanel/panel/user/user.py +13 -19
- hiddifypanel/static/apps-icon/singbox.ico +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +125 -30
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +123 -32
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +114 -22
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +129 -32
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +107 -18
- hiddifypanel/translations.i18n/en.json +73 -14
- hiddifypanel/translations.i18n/fa.json +72 -13
- hiddifypanel/translations.i18n/fr.json +28 -10
- hiddifypanel/translations.i18n/my.json +1266 -0
- hiddifypanel/translations.i18n/pt.json +68 -9
- hiddifypanel/translations.i18n/ru.json +75 -16
- hiddifypanel/translations.i18n/zh.json +67 -8
- hiddifypanel-10.80.0.dist-info/METADATA +137 -0
- {hiddifypanel-10.70.8.dist-info → hiddifypanel-10.80.0.dist-info}/RECORD +136 -119
- {hiddifypanel-10.70.8.dist-info → hiddifypanel-10.80.0.dist-info}/WHEEL +1 -2
- hiddifypanel-10.80.0.dist-info/entry_points.txt +3 -0
- hiddifypanel-10.70.8.dist-info/METADATA +0 -144
- hiddifypanel-10.70.8.dist-info/entry_points.txt +0 -2
- hiddifypanel-10.70.8.dist-info/top_level.txt +0 -1
- {hiddifypanel-10.70.8.dist-info → hiddifypanel-10.80.0.dist-info}/LICENSE.md +0 -0
@@ -11,17 +11,13 @@ from hiddifypanel.models import Proxy, ProxyProto, ProxyL3, ProxyTransport, Prox
|
|
11
11
|
from hiddifypanel import hutils
|
12
12
|
|
13
13
|
|
14
|
-
def get_ssh_hostkeys(dojson=False) -> list[str] | str:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
if len(host_key) > 2:
|
22
|
-
host_key = host_key[:2] # strip the hostname part
|
23
|
-
host_key = " ".join(host_key)
|
24
|
-
host_keys.append(host_key)
|
14
|
+
def get_ssh_hostkeys(hconfigs,dojson=False) -> list[str] | str:
|
15
|
+
host_keys = [
|
16
|
+
# hconfigs[ConfigEnum.ssh_host_dsa_pub],
|
17
|
+
hconfigs[ConfigEnum.ssh_host_ed25519_pub],
|
18
|
+
hconfigs[ConfigEnum.ssh_host_ecdsa_pub],
|
19
|
+
hconfigs[ConfigEnum.ssh_host_rsa_pub],
|
20
|
+
]
|
25
21
|
if dojson:
|
26
22
|
return json.dumps(host_keys)
|
27
23
|
return host_keys
|
@@ -138,8 +134,8 @@ def get_proxies(child_id: int = 0, only_enabled=False) -> list['Proxy']:
|
|
138
134
|
proxies = [c for c in proxies if 'trojan' not in c.proto]
|
139
135
|
if not hconfig(ConfigEnum.httpupgrade_enable, child_id):
|
140
136
|
proxies = [c for c in proxies if ProxyTransport.httpupgrade not in c.transport]
|
141
|
-
if not hconfig(ConfigEnum.
|
142
|
-
proxies = [c for c in proxies if ProxyTransport.
|
137
|
+
if not hconfig(ConfigEnum.xhttp_enable, child_id):
|
138
|
+
proxies = [c for c in proxies if ProxyTransport.xhttp not in c.transport]
|
143
139
|
if not hconfig(ConfigEnum.ws_enable, child_id):
|
144
140
|
proxies = [c for c in proxies if ProxyTransport.WS not in c.transport]
|
145
141
|
# if not hconfig(ConfigEnum.xtls_enable, child_id):
|
@@ -193,7 +189,7 @@ def get_valid_proxies(domains: list[Domain]) -> list[dict]:
|
|
193
189
|
noDomainProxies = False
|
194
190
|
if proxy.proto in [ProxyProto.ssh, ProxyProto.wireguard]:
|
195
191
|
noDomainProxies = True
|
196
|
-
if proxy.proto in [ProxyProto.ss] and proxy.transport not in [ProxyTransport.grpc, ProxyTransport.h2, ProxyTransport.WS, ProxyTransport.httpupgrade, ProxyTransport.
|
192
|
+
if proxy.proto in [ProxyProto.ss] and proxy.transport not in [ProxyTransport.grpc, ProxyTransport.h2, ProxyTransport.WS, ProxyTransport.httpupgrade, ProxyTransport.xhttp]:
|
197
193
|
noDomainProxies = True
|
198
194
|
options = []
|
199
195
|
key = f'{proxy.proto}{proxy.transport}{proxy.cdn}{proxy.l3}'
|
@@ -417,9 +413,9 @@ def make_proxy(hconfigs: dict, proxy: Proxy, domain_db: Domain, phttp=80, ptls=4
|
|
417
413
|
base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_httpupgrade]}'
|
418
414
|
base["host"] = domain
|
419
415
|
return base
|
420
|
-
if proxy.transport in [ProxyTransport.
|
421
|
-
base['transport'] = '
|
422
|
-
base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.
|
416
|
+
if proxy.transport in [ProxyTransport.xhttp]:
|
417
|
+
base['transport'] = 'xhttp'
|
418
|
+
base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_xhttp]}'
|
423
419
|
# if 0 and 'h2' in base['alpn'] or 'h3' in base['alpn']:
|
424
420
|
# base['path'] += "2"
|
425
421
|
# else:
|
@@ -441,7 +437,7 @@ def make_proxy(hconfigs: dict, proxy: Proxy, domain_db: Domain, phttp=80, ptls=4
|
|
441
437
|
return base
|
442
438
|
if ProxyProto.ssh == proxy.proto:
|
443
439
|
base['private_key'] = g.account.ed25519_private_key
|
444
|
-
base['
|
440
|
+
base['host_keys'] = hutils.proxy.get_ssh_hostkeys(hconfigs,False)
|
445
441
|
# base['ssh_port'] = hconfig(ConfigEnum.ssh_server_port)
|
446
442
|
return base
|
447
443
|
return {'name': name, 'msg': 'not valid', 'type': 'error', 'proto': proxy.proto}
|
@@ -45,7 +45,9 @@ def configs_as_json(domains: list[Domain], **kwargs) -> str:
|
|
45
45
|
|
46
46
|
|
47
47
|
def is_xray_proxy(proxy: dict):
|
48
|
-
if
|
48
|
+
if g.user_agent.get('is_hiddify_prefere_xray'):
|
49
|
+
return True
|
50
|
+
if proxy['transport'] == ProxyTransport.xhttp:
|
49
51
|
return True
|
50
52
|
return False
|
51
53
|
|
@@ -323,7 +325,7 @@ def add_ssh(all_base: list[dict], proxy: dict):
|
|
323
325
|
base["user"] = proxy['uuid']
|
324
326
|
base["private_key"] = proxy['private_key'] # .replace('\n', '\\n')
|
325
327
|
|
326
|
-
base["host_key"] = proxy.get('
|
328
|
+
base["host_key"] = proxy.get('host_keys', [])
|
327
329
|
|
328
330
|
socks_front = {
|
329
331
|
"type": "socks",
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
def generate_wireguard_config(proxy: dict) -> str:
|
3
|
+
"""
|
4
|
+
Generates a WireGuard configuration from a given proxy dictionary.
|
5
|
+
|
6
|
+
Args:
|
7
|
+
proxy (dict): Dictionary containing WireGuard and proxy details.
|
8
|
+
|
9
|
+
Returns:
|
10
|
+
str: A WireGuard configuration string.
|
11
|
+
"""
|
12
|
+
name=f'{proxy["extra_info"]} {proxy["name"]}'
|
13
|
+
addrs = f"{proxy['wg_ipv4']}/32"
|
14
|
+
if proxy['wg_ipv6']:
|
15
|
+
addrs += f", {proxy['wg_ipv6']}/128"
|
16
|
+
config = f"""[Interface]
|
17
|
+
# Name = {name}
|
18
|
+
Address= {addrs}
|
19
|
+
PrivateKey = {proxy["wg_pk"]}
|
20
|
+
MTU = {proxy.get("mtu", 1380)}
|
21
|
+
DNS = {proxy.get("dns", "1.1.1.1")}
|
22
|
+
|
23
|
+
[Peer]
|
24
|
+
# Name = Public Peer for {name}
|
25
|
+
Endpoint = {proxy["server"]}:{proxy["port"]}
|
26
|
+
PublicKey = {proxy["wg_server_pub"]}
|
27
|
+
PresharedKey = {proxy['wg_psk']}
|
28
|
+
#PersistentKeepalive = {proxy.get("keep_alive", 25)}
|
29
|
+
"""
|
30
|
+
|
31
|
+
#Address = {proxy.get("wg_ipv4", "0.0.0.0/32")}
|
32
|
+
#AllowedIPs = {proxy.get("allowed_ips", "0.0.0.0/0")}
|
33
|
+
|
34
|
+
return config
|
@@ -63,7 +63,7 @@ def to_link(proxy: dict) -> str | dict:
|
|
63
63
|
streisand_ssh = hutils.encode.do_base_64(f'{proxy["uuid"]}:0:{proxy["private_key"]}::@{proxy["server"]}:{proxy["port"]}')
|
64
64
|
baseurl += f'{streisand_ssh}#{name_link}'
|
65
65
|
else:
|
66
|
-
hk = ",".join(proxy["
|
66
|
+
hk = ",".join(proxy["host_keys"])
|
67
67
|
pk = proxy["private_key"].replace('\n', '')
|
68
68
|
baseurl += f'{proxy["uuid"]}@{proxy["server"]}:{proxy["port"]}/?file=ssh&pk={pk}&hk={hk}#{name_link}'
|
69
69
|
|
@@ -126,10 +126,10 @@ def to_link(proxy: dict) -> str | dict:
|
|
126
126
|
baseurl += "&encryption=none"
|
127
127
|
if proxy.get('fingerprint', 'none') != 'none':
|
128
128
|
baseurl += "&fp=" + proxy['fingerprint']
|
129
|
-
if proxy.get('transport') in {ProxyTransport.
|
129
|
+
if proxy.get('transport') in {ProxyTransport.xhttp}:
|
130
130
|
baseurl += "&core=xray"
|
131
131
|
if proxy['l3'] != 'quic':
|
132
|
-
if proxy.get('l3') != ProxyL3.reality and (proxy.get('transport') in {ProxyTransport.tcp, ProxyTransport.httpupgrade, ProxyTransport.
|
132
|
+
if proxy.get('l3') != ProxyL3.reality and (proxy.get('transport') in {ProxyTransport.tcp, ProxyTransport.httpupgrade, ProxyTransport.xhttp}) and proxy['proto'] in [ProxyProto.vless, ProxyProto.trojan]:
|
133
133
|
baseurl += '&headerType=http'
|
134
134
|
else:
|
135
135
|
baseurl += '&headerType=None'
|
@@ -50,10 +50,11 @@ def configs_as_json(domains: list[Domain], user: User, expire_days: int, remarks
|
|
50
50
|
unsupported_transport = {}
|
51
51
|
if g.user_agent.get('is_v2rayng'):
|
52
52
|
# TODO: ensure which protocols are not supported in v2rayng
|
53
|
-
unsupported_protos = {
|
54
|
-
ProxyProto.tuic, ProxyProto.
|
53
|
+
unsupported_protos = { ProxyProto.hysteria, ProxyProto.hysteria2,
|
54
|
+
ProxyProto.tuic, ProxyProto.ssr, ProxyProto.ssh}
|
55
55
|
if not hutils.flask.is_client_version(hutils.flask.ClientVersion.v2ryang, 1, 8, 18):
|
56
56
|
unsupported_transport = {ProxyTransport.httpupgrade}
|
57
|
+
unsupported_protos.update({ProxyProto.wireguard})
|
57
58
|
|
58
59
|
# multiple outbounds needs multiple whole base config not just one with multiple outbounds (at least for v2rayng)
|
59
60
|
# https://github.com/2dust/v2rayNG/pull/2827#issue-2127534078
|
@@ -135,7 +136,9 @@ def add_wireguard_settings(base: dict, proxy: dict):
|
|
135
136
|
base['settings']['mtu'] = 1380 # optional
|
136
137
|
base['settings']['peers'] = [{
|
137
138
|
'endpoint': f'{proxy["server"]}:{int(proxy["port"])}',
|
138
|
-
'publicKey': proxy["wg_server_pub"]
|
139
|
+
'publicKey': proxy["wg_server_pub"],
|
140
|
+
"preSharedKey": proxy['wg_psk']
|
141
|
+
|
139
142
|
# 'allowedIPs':'', 'preSharedKey':'', 'keepAlive':'' # optionals
|
140
143
|
}]
|
141
144
|
|
@@ -262,9 +265,9 @@ def add_stream_settings(base: dict, proxy: dict):
|
|
262
265
|
if proxy['transport'] == ProxyTransport.httpupgrade:
|
263
266
|
ss['network'] = proxy['transport']
|
264
267
|
add_httpupgrade_stream(ss, proxy)
|
265
|
-
if proxy['transport'] == ProxyTransport.
|
268
|
+
if proxy['transport'] == ProxyTransport.xhttp:
|
266
269
|
ss['network'] = proxy['transport']
|
267
|
-
|
270
|
+
add_xhttp_stream(ss, proxy)
|
268
271
|
if proxy['transport'] == 'ws':
|
269
272
|
ss['network'] = proxy['transport']
|
270
273
|
add_ws_stream(ss, proxy)
|
@@ -338,8 +341,8 @@ def add_httpupgrade_stream(ss: dict, proxy: dict):
|
|
338
341
|
}
|
339
342
|
|
340
343
|
|
341
|
-
def
|
342
|
-
ss['
|
344
|
+
def add_xhttp_stream(ss: dict, proxy: dict):
|
345
|
+
ss['xhttpSettings'] = {
|
343
346
|
'path': proxy['path'],
|
344
347
|
'host': proxy['host'],
|
345
348
|
"headers": {
|
hiddifypanel/models/admin.py
CHANGED
@@ -41,6 +41,9 @@ class BaseAccount(db.Model, SerializerMixin, FlaskLoginUserMixin): # type: igno
|
|
41
41
|
'telegram_id': self.telegram_id,
|
42
42
|
'lang': self.lang
|
43
43
|
}
|
44
|
+
def update_password(self,new_password):
|
45
|
+
self.password=new_password
|
46
|
+
db.session.commit()
|
44
47
|
|
45
48
|
@classmethod
|
46
49
|
def by_id(cls, id: int):
|
hiddifypanel/models/config.py
CHANGED
@@ -39,7 +39,7 @@ class StrConfig(db.Model, SerializerMixin):
|
|
39
39
|
child_id = Column(Integer, ForeignKey('child.id'), primary_key=True, default=0)
|
40
40
|
# category = db.Column(db.String(128), primary_key=True)
|
41
41
|
key = Column(Enum(ConfigEnum), primary_key=True, default=ConfigEnum.admin_secret)
|
42
|
-
value = Column(String(
|
42
|
+
value = Column(String(3072))
|
43
43
|
|
44
44
|
def to_dict(self: "StrConfig"):
|
45
45
|
return {
|
@@ -153,7 +153,10 @@ def add_or_update_config(commit: bool = True, child_id: int | None = None, overr
|
|
153
153
|
if child_id is None:
|
154
154
|
child_id = Child.current().id
|
155
155
|
c = config['key']
|
156
|
-
|
156
|
+
try:
|
157
|
+
ckey = ConfigEnum(c)
|
158
|
+
except:
|
159
|
+
return
|
157
160
|
if c == ConfigEnum.unique_id and not override_unique_id:
|
158
161
|
return
|
159
162
|
|
@@ -239,7 +239,7 @@ class ConfigEnum(metaclass=FastEnum):
|
|
239
239
|
ws_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply_config)
|
240
240
|
grpc_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply_config)
|
241
241
|
httpupgrade_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply_config)
|
242
|
-
|
242
|
+
xhttp_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply_config)
|
243
243
|
|
244
244
|
vless_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply_config)
|
245
245
|
trojan_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply_config)
|
@@ -262,7 +262,7 @@ class ConfigEnum(metaclass=FastEnum):
|
|
262
262
|
path_v2ray = _StrConfigDscr(ConfigCategory.hidden, ApplyMode.apply_config, hide_in_virtual_child=True) # deprecated
|
263
263
|
path_ss = _StrConfigDscr(ConfigCategory.hidden, ApplyMode.apply_config, hide_in_virtual_child=True)
|
264
264
|
|
265
|
-
|
265
|
+
path_xhttp = _StrConfigDscr(ConfigCategory.too_advanced, ApplyMode.apply_config, hide_in_virtual_child=True)
|
266
266
|
path_httpupgrade = _StrConfigDscr(ConfigCategory.too_advanced, ApplyMode.apply_config, hide_in_virtual_child=True)
|
267
267
|
path_ws = _StrConfigDscr(ConfigCategory.too_advanced, ApplyMode.apply_config, hide_in_virtual_child=True)
|
268
268
|
path_tcp = _StrConfigDscr(ConfigCategory.too_advanced, ApplyMode.apply_config, hide_in_virtual_child=True)
|
@@ -277,6 +277,19 @@ class ConfigEnum(metaclass=FastEnum):
|
|
277
277
|
sub_full_clash_enable = _BoolConfigDscr(ConfigCategory.hidden)
|
278
278
|
sub_full_clash_meta_enable = _BoolConfigDscr(ConfigCategory.hidden)
|
279
279
|
|
280
|
+
|
281
|
+
#ssh host keys
|
282
|
+
ssh_host_rsa_pk = _StrConfigDscr(ConfigCategory.hidden)
|
283
|
+
ssh_host_rsa_pub = _StrConfigDscr(ConfigCategory.hidden)
|
284
|
+
ssh_host_ed25519_pk = _StrConfigDscr(ConfigCategory.hidden)
|
285
|
+
ssh_host_ed25519_pub = _StrConfigDscr(ConfigCategory.hidden)
|
286
|
+
ssh_host_ecdsa_pk = _StrConfigDscr(ConfigCategory.hidden)
|
287
|
+
ssh_host_ecdsa_pub = _StrConfigDscr(ConfigCategory.hidden)
|
288
|
+
ssh_host_dsa_pk = _StrConfigDscr(ConfigCategory.hidden)
|
289
|
+
ssh_host_dsa_pub = _StrConfigDscr(ConfigCategory.hidden)
|
290
|
+
|
291
|
+
|
292
|
+
|
280
293
|
hiddifycli_enable = _BoolConfigDscr(ConfigCategory.hidden, ApplyMode.reinstall)
|
281
294
|
|
282
295
|
@classmethod
|
hiddifypanel/models/proxy.py
CHANGED
hiddifypanel/models/user.py
CHANGED
@@ -76,7 +76,7 @@ class User(BaseAccount, SerializerMixin):
|
|
76
76
|
current_usage = db.Column(db.BigInteger, default=0, nullable=False)
|
77
77
|
last_reset_time = db.Column(db.Date, default=datetime.date.today())
|
78
78
|
added_by = db.Column(db.Integer, db.ForeignKey('admin_user.id'), default=1)
|
79
|
-
max_ips = db.Column(db.Integer, default=
|
79
|
+
max_ips = db.Column(db.Integer, default=100, nullable=False)
|
80
80
|
details = db.relationship('UserDetail', cascade="all,delete", backref='user', lazy='dynamic',)
|
81
81
|
enable = db.Column(db.Boolean, default=True, nullable=False)
|
82
82
|
ed25519_private_key = db.Column(db.String(500), default="")
|
@@ -347,6 +347,6 @@ class User(BaseAccount, SerializerMixin):
|
|
347
347
|
def on_user_insert(mapper, connection, target):
|
348
348
|
from hiddifypanel import hutils
|
349
349
|
hutils.model.gen_username(target)
|
350
|
-
hutils.model.gen_password(target)
|
350
|
+
# hutils.model.gen_password(target)
|
351
351
|
hutils.model.gen_ed25519_keys(target)
|
352
352
|
hutils.model.gen_wg_keys(target)
|
hiddifypanel/panel/__init__.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
|
-
from . import user
|
3
|
-
# from . import admin
|
4
|
-
from . import cli
|
5
|
-
# from .. import database
|
6
|
-
from . import common
|
7
|
-
# from . import commercial
|
8
|
-
# from .. import auth
|
9
|
-
from . import common_bp
|
2
|
+
# from . import user
|
3
|
+
# # from . import admin
|
4
|
+
# from . import cli
|
5
|
+
# # from .. import database
|
6
|
+
# from . import common
|
7
|
+
# # from . import commercial
|
8
|
+
# # from .. import auth
|
9
|
+
# from . import common_bp
|
@@ -40,7 +40,7 @@ class SubAdminsField(SelectField):
|
|
40
40
|
class AdminstratorAdmin(AdminLTEModelView):
|
41
41
|
column_hide_backrefs = False
|
42
42
|
column_list = ["name", 'UserLinks', 'mode', 'can_add_admin', 'max_active_users', 'max_users', 'online_users', 'comment',]
|
43
|
-
form_columns = ["name", 'mode', 'can_add_admin', 'max_active_users', 'max_users', 'comment', "uuid"]
|
43
|
+
form_columns = ["name", 'mode', 'can_add_admin', 'max_active_users', 'max_users', 'comment', "uuid", "password"]
|
44
44
|
list_template = 'model/admin_list.html'
|
45
45
|
# column_editable_list = ['name']
|
46
46
|
# edit_modal = True
|
@@ -59,6 +59,7 @@ class AdminstratorAdmin(AdminLTEModelView):
|
|
59
59
|
"comment": _("Note"),
|
60
60
|
'max_active_users': _("Max Active Users"),
|
61
61
|
'max_users': _('Max Users'),
|
62
|
+
"password":_("user.password.title"),
|
62
63
|
"online_users": _("Online Users"),
|
63
64
|
'can_add_admin': _("Can add sub admin")
|
64
65
|
|
@@ -142,19 +143,18 @@ class AdminstratorAdmin(AdminLTEModelView):
|
|
142
143
|
""")
|
143
144
|
|
144
145
|
def _max_active_users_formatter(view, context, model, name):
|
145
|
-
|
146
|
-
|
147
|
-
u = len(actives)
|
146
|
+
"""Optimized user count formatter using database queries"""
|
147
|
+
active_count = model.recursive_users_query().filter(User.is_active == True).count()
|
148
148
|
if model.mode == AdminMode.super_admin:
|
149
|
-
return f"{
|
149
|
+
return f"{active_count} / ∞"
|
150
150
|
t = model.max_active_users
|
151
|
-
rate = round(
|
152
|
-
|
153
|
-
|
151
|
+
rate = round(active_count * 100 / (t + 0.000001))
|
152
|
+
color = "#ff7e7e" if active_count >= t else ('#ffc107' if rate > 80 else '#9ee150')
|
153
|
+
|
154
154
|
return Markup(f"""
|
155
155
|
<div class="progress progress-lg position-relative" style="min-width: 100px;">
|
156
156
|
<div class="progress-bar progress-bar-striped" role="progressbar" style="width: {rate}%;background-color: {color};" aria-valuenow="{rate}" aria-valuemin="0" aria-valuemax="100"></div>
|
157
|
-
<span class='badge position-absolute' style="left:auto;right:auto;width: 100%;font-size:1em">{
|
157
|
+
<span class='badge position-absolute' style="left:auto;right:auto;width: 100%;font-size:1em">{active_count} {_('user.home.usage.from')} {t}</span>
|
158
158
|
|
159
159
|
</div>
|
160
160
|
""")
|
@@ -204,6 +204,7 @@ class AdminstratorAdmin(AdminLTEModelView):
|
|
204
204
|
# else:
|
205
205
|
# model.parent_admin_id=1
|
206
206
|
# model.parent_admin=AdminUser.query.filter(AdminUser.id==1).first()
|
207
|
+
|
207
208
|
if model.id != 1 and model.parent_admin is None:
|
208
209
|
model.parent_admin_id = g.account.id
|
209
210
|
model.parent_admin = g.account
|
@@ -212,12 +213,17 @@ class AdminstratorAdmin(AdminLTEModelView):
|
|
212
213
|
raise ValidationError("Sub-Admin can not have more power!!!!")
|
213
214
|
if g.account.mode == AdminMode.agent and model.mode != AdminMode.agent:
|
214
215
|
raise ValidationError("Sub-Admin can not have more power!!!!")
|
216
|
+
|
217
|
+
if not model.password and not is_created:
|
218
|
+
model.password=AdminUser.by_id(model.id).password
|
219
|
+
|
215
220
|
|
216
221
|
def on_model_delete(self, model):
|
217
222
|
model.remove()
|
218
223
|
|
219
224
|
def on_form_prefill(self, form, id=None):
|
220
|
-
|
225
|
+
|
226
|
+
form.password.data=""
|
221
227
|
if g.account.mode != AdminMode.super_admin:
|
222
228
|
del form.mode
|
223
229
|
del form.can_add_admin
|