hiddifypanel 9.0.0.dev54__py3-none-any.whl → 9.0.0.dev61__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/base.py +5 -4
- hiddifypanel/hutils/__init__.py +8 -1
- hiddifypanel/hutils/auth.py +94 -0
- hiddifypanel/hutils/auto_ip_selector.py +1 -1
- hiddifypanel/hutils/convert.py +14 -0
- hiddifypanel/hutils/encode.py +11 -0
- hiddifypanel/hutils/flask.py +24 -0
- hiddifypanel/{panel/github_issue_generator.py → hutils/github_issue.py} +104 -14
- hiddifypanel/hutils/json.py +24 -0
- hiddifypanel/hutils/random.py +19 -0
- hiddifypanel/hutils/utils.py +0 -161
- hiddifypanel/models/__init__.py +1 -0
- hiddifypanel/models/admin.py +53 -8
- hiddifypanel/models/base_account.py +31 -169
- hiddifypanel/models/config_enum.py +23 -1
- hiddifypanel/models/domain.py +2 -2
- hiddifypanel/models/parent_domain.py +1 -0
- hiddifypanel/models/user.py +105 -33
- hiddifypanel/models/utils.py +3 -3
- hiddifypanel/panel/admin/Actions.py +5 -6
- hiddifypanel/panel/admin/AdminstratorAdmin.py +1 -1
- hiddifypanel/panel/admin/Backup.py +5 -5
- hiddifypanel/panel/admin/ChildAdmin.py +3 -3
- hiddifypanel/panel/admin/Dashboard.py +12 -10
- hiddifypanel/panel/admin/DomainAdmin.py +10 -9
- hiddifypanel/panel/admin/ProxyAdmin.py +4 -6
- hiddifypanel/panel/admin/QuickSetup.py +11 -13
- hiddifypanel/panel/admin/SettingAdmin.py +20 -10
- hiddifypanel/panel/admin/UserAdmin.py +14 -12
- hiddifypanel/panel/auth.py +43 -10
- hiddifypanel/panel/auth_back2.py +5 -5
- hiddifypanel/panel/cli.py +1 -0
- hiddifypanel/panel/commercial/ParentDomainAdmin.py +3 -3
- hiddifypanel/panel/commercial/ProxyDetailsAdmin.py +1 -0
- hiddifypanel/panel/commercial/restapi/v1/tgbot.py +1 -2
- hiddifypanel/panel/commercial/restapi/v1/tgmsg.py +37 -29
- hiddifypanel/panel/commercial/restapi/v2/user/apps_api.py +5 -4
- hiddifypanel/panel/commercial/restapi/v2/user/configs_api.py +15 -7
- hiddifypanel/panel/commercial/restapi/v2/user/info_api.py +7 -11
- hiddifypanel/panel/commercial/telegrambot/Usage.py +2 -1
- hiddifypanel/panel/commercial/telegrambot/admin.py +1 -0
- hiddifypanel/panel/common.py +12 -89
- hiddifypanel/panel/common_bp/login.py +12 -12
- hiddifypanel/panel/database.py +22 -21
- hiddifypanel/panel/hiddify.py +27 -29
- hiddifypanel/panel/importer/xui.py +2 -2
- hiddifypanel/panel/init_db.py +32 -13
- hiddifypanel/panel/usage.py +2 -1
- hiddifypanel/panel/user/link_maker.py +118 -15
- hiddifypanel/panel/user/templates/new.html +4 -2
- hiddifypanel/panel/user/user.py +83 -38
- hiddifypanel/static/new/assets/{index-bd9ba5e9.js → index-2cd90979.js} +1 -1
- hiddifypanel/templates/fake.html +2 -2
- hiddifypanel/templates/master.html +1 -1
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +317 -189
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +346 -206
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +315 -195
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +315 -195
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +866 -2739
- {hiddifypanel-9.0.0.dev54.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/METADATA +2 -1
- {hiddifypanel-9.0.0.dev54.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/RECORD +72 -66
- {hiddifypanel-9.0.0.dev54.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/LICENSE.md +0 -0
- {hiddifypanel-9.0.0.dev54.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/WHEEL +0 -0
- {hiddifypanel-9.0.0.dev54.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/entry_points.txt +0 -0
- {hiddifypanel-9.0.0.dev54.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/top_level.txt +0 -0
hiddifypanel/panel/hiddify.py
CHANGED
@@ -1,17 +1,22 @@
|
|
1
1
|
import glob
|
2
|
+
import random
|
3
|
+
import socket
|
4
|
+
import ssl
|
5
|
+
import time
|
6
|
+
import uuid
|
2
7
|
import user_agents
|
3
8
|
import json
|
4
9
|
import subprocess
|
5
10
|
import psutil
|
11
|
+
from datetime import datetime
|
6
12
|
from typing import Tuple
|
7
13
|
from cryptography.hazmat.primitives import serialization
|
8
14
|
from cryptography.hazmat.primitives.asymmetric import x25519
|
9
|
-
from flask import current_app, g,
|
15
|
+
from flask import current_app, g, request, Markup # type: ignore
|
10
16
|
from flask_babelex import gettext as __
|
11
17
|
from flask_babelex import lazy_gettext as _
|
12
18
|
from wtforms.validators import ValidationError
|
13
19
|
from apiflask import abort as apiflask_abort
|
14
|
-
from apiflask import abort
|
15
20
|
|
16
21
|
from datetime import timedelta
|
17
22
|
from babel.dates import format_timedelta as babel_format_timedelta
|
@@ -56,7 +61,7 @@ def add_short_link_imp(link: str, period_min: int = 5) -> Tuple[str, datetime]:
|
|
56
61
|
if link in line:
|
57
62
|
return re.search(pattern, line).group(1), datetime.now() + timedelta(minutes=period_min)
|
58
63
|
|
59
|
-
short_code = get_random_string(6, 10).lower()
|
64
|
+
short_code = hutils.random.get_random_string(6, 10).lower()
|
60
65
|
# exec_command(
|
61
66
|
# f'sudo /opt/hiddify-manager/nginx/add2shortlink.sh {link} {short_code} {period_min} &')
|
62
67
|
|
@@ -171,6 +176,8 @@ def is_login_call() -> bool:
|
|
171
176
|
|
172
177
|
|
173
178
|
def is_admin_role(role: Role):
|
179
|
+
if not role:
|
180
|
+
return False
|
174
181
|
if role in {Role.super_admin, Role.admin, Role.agent}:
|
175
182
|
return True
|
176
183
|
return False
|
@@ -201,18 +208,18 @@ def proxy_path_validator(proxy_path):
|
|
201
208
|
return
|
202
209
|
|
203
210
|
if proxy_path not in [admin_proxy_path, deprecated_path, client_proxy_path]:
|
204
|
-
|
211
|
+
apiflask_abort(400, 'invalid request')
|
205
212
|
|
206
213
|
if is_admin_panel_call() and proxy_path != admin_proxy_path:
|
207
|
-
|
214
|
+
apiflask_abort(400, 'invalid request')
|
208
215
|
if is_user_panel_call() and proxy_path != client_proxy_path:
|
209
|
-
|
216
|
+
apiflask_abort(400, 'invalid request')
|
210
217
|
|
211
218
|
if is_api_call(request.path):
|
212
219
|
if is_admin_api_call() and proxy_path != admin_proxy_path:
|
213
|
-
return apiflask_abort(400, Markup(f"Invalid Proxy Path <a href=/{admin_proxy_path}/admin>Admin Panel</a>")) if dbg_mode else
|
220
|
+
return apiflask_abort(400, Markup(f"Invalid Proxy Path <a href=/{admin_proxy_path}/admin>Admin Panel</a>")) if dbg_mode else apiflask_abort(400, 'invalid request')
|
214
221
|
if is_user_api_call() and proxy_path != client_proxy_path:
|
215
|
-
return apiflask_abort(400, Markup(f"Invalid Proxy Path <a href=/{client_proxy_path}/admin>User Panel</a>")) if dbg_mode else
|
222
|
+
return apiflask_abort(400, Markup(f"Invalid Proxy Path <a href=/{client_proxy_path}/admin>User Panel</a>")) if dbg_mode else apiflask_abort(400, 'invalid request')
|
216
223
|
|
217
224
|
|
218
225
|
def asset_url(path) -> str:
|
@@ -270,17 +277,6 @@ def quick_apply_users():
|
|
270
277
|
return {"status": 'success'}
|
271
278
|
|
272
279
|
|
273
|
-
def flash_config_success(restart_mode='', domain_changed=True):
|
274
|
-
if restart_mode:
|
275
|
-
url = url_for('admin.Actions:reinstall', complete_install=restart_mode ==
|
276
|
-
'reinstall', domain_changed=domain_changed)
|
277
|
-
apply_btn = f"<a href='{url}' class='btn btn-primary form_post'>" + \
|
278
|
-
_("admin.config.apply_configs")+"</a>"
|
279
|
-
flash((_('config.validation-success', link=apply_btn)), 'success')
|
280
|
-
else:
|
281
|
-
flash((_('config.validation-success-no-reset')), 'success')
|
282
|
-
|
283
|
-
|
284
280
|
# Importing socket library
|
285
281
|
|
286
282
|
# Function to display hostname and
|
@@ -332,7 +328,7 @@ def get_html_user_link(model: BaseAccount, domain: Domain):
|
|
332
328
|
res = ""
|
333
329
|
d = domain.domain
|
334
330
|
if "*" in d:
|
335
|
-
d = d.replace("*", get_random_string(5, 15))
|
331
|
+
d = d.replace("*", hutils.random.get_random_string(5, 15))
|
336
332
|
|
337
333
|
link = get_account_panel_link(model, d)+f"#{model.name}"
|
338
334
|
|
@@ -379,7 +375,7 @@ def check_need_reset(old_configs, do=False):
|
|
379
375
|
if old_configs[ConfigEnum.package_mode] != hconfig(ConfigEnum.package_mode):
|
380
376
|
return reinstall_action(do_update=True)
|
381
377
|
if not (do and restart_mode == 'reinstall'):
|
382
|
-
return flash_config_success(restart_mode=restart_mode, domain_changed=False)
|
378
|
+
return hutils.flask.flash_config_success(restart_mode=restart_mode, domain_changed=False)
|
383
379
|
|
384
380
|
return reinstall_action(complete_install=True, domain_changed=domain_changed)
|
385
381
|
|
@@ -648,9 +644,12 @@ def get_random_domains(count=1, retry=3):
|
|
648
644
|
return random.sample(defdomains, count)
|
649
645
|
return get_random_domains(count, retry-1)
|
650
646
|
|
647
|
+
# not used
|
648
|
+
|
651
649
|
|
652
650
|
def is_domain_support_tls_13(domain):
|
653
651
|
context = ssl.create_default_context()
|
652
|
+
port = 433
|
654
653
|
with socket.create_connection((domain, port)) as sock:
|
655
654
|
with context.wrap_socket(sock, server_hostname=domain) as ssock:
|
656
655
|
return ssock.version() == "TLSv1.3"
|
@@ -693,8 +692,8 @@ def debug_flash_if_not_in_the_same_asn(domain):
|
|
693
692
|
# country_ipv4= ipcountry.get(ipv4)
|
694
693
|
# country_dip= ipcountry.get(dip)
|
695
694
|
if asn_ipv4.get('autonomous_system_organization') != asn_dip.get('autonomous_system_organization'):
|
696
|
-
flash(_("selected domain for REALITY is not in the same ASN. To better use of the protocol, it is better to find a domain in the same ASN.") +
|
697
|
-
|
695
|
+
hutils.flask.flash(_("selected domain for REALITY is not in the same ASN. To better use of the protocol, it is better to find a domain in the same ASN.") +
|
696
|
+
f"<br> Server ASN={asn_ipv4.get('autonomous_system_organization','unknown')}<br>{domain}_ASN={asn_dip.get('autonomous_system_organization','unknown')}", "warning")
|
698
697
|
except:
|
699
698
|
pass
|
700
699
|
|
@@ -788,10 +787,10 @@ def get_ed25519_private_public_pair():
|
|
788
787
|
return priv_bytes.decode(), pub_bytes.decode()
|
789
788
|
|
790
789
|
|
791
|
-
def do_base_64(str):
|
792
|
-
|
793
|
-
|
794
|
-
|
790
|
+
# def do_base_64(str):
|
791
|
+
# import base64
|
792
|
+
# resp = base64.b64encode(f'{str}'.encode("utf-8"))
|
793
|
+
# return resp.decode()
|
795
794
|
|
796
795
|
|
797
796
|
def get_user_agent():
|
@@ -854,7 +853,6 @@ def __parse_user_agent(ua):
|
|
854
853
|
|
855
854
|
def is_ssh_password_authentication_enabled():
|
856
855
|
if os.path.isfile('/etc/ssh/sshd_config'):
|
857
|
-
content = ''
|
858
856
|
with open('/etc/ssh/sshd_config', 'r') as f:
|
859
857
|
for line in f.readlines():
|
860
858
|
line = line.strip()
|
@@ -876,7 +874,7 @@ def get_direct_host_or_ip(prefer_version: int):
|
|
876
874
|
else:
|
877
875
|
direct = hutils.ip.get_ip(prefer_version)
|
878
876
|
if not direct:
|
879
|
-
direct = hutils.ip.get_ip(
|
877
|
+
direct = hutils.ip.get_ip(4 if prefer_version == 6 else 6)
|
880
878
|
return direct
|
881
879
|
|
882
880
|
|
@@ -4,7 +4,7 @@ from typing import Any, Dict, List, Tuple
|
|
4
4
|
import uuid as uuid_mod
|
5
5
|
from datetime import datetime
|
6
6
|
from dateutil.relativedelta import relativedelta
|
7
|
-
|
7
|
+
from hiddifypanel import hutils
|
8
8
|
from hiddifypanel.models.admin import AdminUser
|
9
9
|
from hiddifypanel.models.user import User, UserMode
|
10
10
|
from hiddifypanel.models.domain import Domain, DomainType
|
@@ -63,7 +63,7 @@ def __get_users(db, x_ui_inbounds):
|
|
63
63
|
def __create_hiddify_user_from_xui_values(id: str, values: Dict[str, Any]) -> User:
|
64
64
|
user = User()
|
65
65
|
user.name = values['name']
|
66
|
-
user.uuid = id if
|
66
|
+
user.uuid = id if hutils.auth.is_uuid_valid(id, 4) else uuid_mod.uuid4()
|
67
67
|
|
68
68
|
if str(values['expiry_time']) == '0':
|
69
69
|
user.expiry_time = datetime.now() + relativedelta(years=10)
|
hiddifypanel/panel/init_db.py
CHANGED
@@ -12,7 +12,7 @@ from hiddifypanel import Events, hutils
|
|
12
12
|
from hiddifypanel.models import *
|
13
13
|
from hiddifypanel.panel import hiddify
|
14
14
|
from hiddifypanel.panel.database import db
|
15
|
-
from hiddifypanel.panel.hiddify import get_random_domains
|
15
|
+
from hiddifypanel.panel.hiddify import get_random_domains
|
16
16
|
import hiddifypanel.models.utils as model_utils
|
17
17
|
|
18
18
|
MAX_DB_VERSION = 70
|
@@ -26,7 +26,12 @@ def init_db():
|
|
26
26
|
hconfig.invalidate_all()
|
27
27
|
get_hconfigs.invalidate_all()
|
28
28
|
db_version = int(hconfig(ConfigEnum.db_version) or 0)
|
29
|
+
if db_version == latest_db_version():
|
30
|
+
return
|
31
|
+
execute("alter table user alter column telegram_id int;")
|
32
|
+
execute("alter table admin_user alter column telegram_id int;")
|
29
33
|
add_column(User.lang)
|
34
|
+
add_column(AdminUser.lang)
|
30
35
|
add_column(User.username)
|
31
36
|
add_column(User.password)
|
32
37
|
add_column(AdminUser.username)
|
@@ -34,8 +39,6 @@ def init_db():
|
|
34
39
|
|
35
40
|
add_column(Domain.extra_params)
|
36
41
|
|
37
|
-
if db_version == latest_db_version():
|
38
|
-
return
|
39
42
|
Events.db_prehook.notify()
|
40
43
|
if db_version < 52:
|
41
44
|
execute(f'update domain set mode="sub_link_only", sub_link_only=false where sub_link_only = true or mode=1 or mode="1"')
|
@@ -148,6 +151,22 @@ def init_db():
|
|
148
151
|
# add_config_if_not_exist(ConfigEnum.hysteria_enable, True)
|
149
152
|
# add_config_if_not_exist(ConfigEnum.hysteria_port, random.randint(5000, 20000))
|
150
153
|
|
154
|
+
def _v67():
|
155
|
+
pass
|
156
|
+
|
157
|
+
|
158
|
+
def _v65():
|
159
|
+
add_config_if_not_exist(ConfigEnum.mux_enable, False)
|
160
|
+
add_config_if_not_exist(ConfigEnum.mux_protocol, 'smux')
|
161
|
+
add_config_if_not_exist(ConfigEnum.mux_max_connections, '4')
|
162
|
+
add_config_if_not_exist(ConfigEnum.mux_min_streams, '4')
|
163
|
+
add_config_if_not_exist(ConfigEnum.mux_max_streams, '0')
|
164
|
+
add_config_if_not_exist(ConfigEnum.mux_padding_enable, False)
|
165
|
+
add_config_if_not_exist(ConfigEnum.mux_brutal_enable, True)
|
166
|
+
add_config_if_not_exist(ConfigEnum.mux_brutal_up_mbps, '100')
|
167
|
+
add_config_if_not_exist(ConfigEnum.mux_brutal_down_mbps, '100')
|
168
|
+
|
169
|
+
|
151
170
|
def _v64():
|
152
171
|
set_hconfig(ConfigEnum.ssh_server_redis_url, "unix:///opt/hiddify-manager/other/redis/run.sock?db=1")
|
153
172
|
|
@@ -175,8 +194,8 @@ def _v61():
|
|
175
194
|
|
176
195
|
|
177
196
|
def _v60():
|
178
|
-
add_config_if_not_exist(ConfigEnum.proxy_path_admin, get_random_string())
|
179
|
-
add_config_if_not_exist(ConfigEnum.proxy_path_client, get_random_string())
|
197
|
+
add_config_if_not_exist(ConfigEnum.proxy_path_admin, hutils.random.get_random_string())
|
198
|
+
add_config_if_not_exist(ConfigEnum.proxy_path_client, hutils.random.get_random_string())
|
180
199
|
|
181
200
|
|
182
201
|
def _v59():
|
@@ -342,13 +361,13 @@ def _v20():
|
|
342
361
|
|
343
362
|
|
344
363
|
def _v19():
|
345
|
-
set_hconfig(ConfigEnum.path_trojan, get_random_string(7, 15))
|
346
|
-
set_hconfig(ConfigEnum.path_vless, get_random_string(7, 15))
|
347
|
-
set_hconfig(ConfigEnum.path_vmess, get_random_string(7, 15))
|
348
|
-
set_hconfig(ConfigEnum.path_ss, get_random_string(7, 15))
|
349
|
-
set_hconfig(ConfigEnum.path_grpc, get_random_string(7, 15))
|
350
|
-
set_hconfig(ConfigEnum.path_tcp, get_random_string(7, 15))
|
351
|
-
set_hconfig(ConfigEnum.path_ws, get_random_string(7, 15))
|
364
|
+
set_hconfig(ConfigEnum.path_trojan, hutils.random.get_random_string(7, 15))
|
365
|
+
set_hconfig(ConfigEnum.path_vless, hutils.random.get_random_string(7, 15))
|
366
|
+
set_hconfig(ConfigEnum.path_vmess, hutils.random.get_random_string(7, 15))
|
367
|
+
set_hconfig(ConfigEnum.path_ss, hutils.random.get_random_string(7, 15))
|
368
|
+
set_hconfig(ConfigEnum.path_grpc, hutils.random.get_random_string(7, 15))
|
369
|
+
set_hconfig(ConfigEnum.path_tcp, hutils.random.get_random_string(7, 15))
|
370
|
+
set_hconfig(ConfigEnum.path_ws, hutils.random.get_random_string(7, 15))
|
352
371
|
add_config_if_not_exist(ConfigEnum.tuic_enable, False)
|
353
372
|
add_config_if_not_exist(ConfigEnum.shadowtls_enable, False)
|
354
373
|
add_config_if_not_exist(ConfigEnum.shadowtls_fakedomain, "en.wikipedia.org")
|
@@ -383,7 +402,7 @@ def _v1():
|
|
383
402
|
StrConfig(key=ConfigEnum.tls_ports, value="443"),
|
384
403
|
BoolConfig(key=ConfigEnum.first_setup, value=True),
|
385
404
|
StrConfig(key=ConfigEnum.decoy_domain, value=hiddify.get_random_decoy_domain()),
|
386
|
-
StrConfig(key=ConfigEnum.proxy_path, value=get_random_string()),
|
405
|
+
StrConfig(key=ConfigEnum.proxy_path, value=hutils.random.get_random_string()),
|
387
406
|
BoolConfig(key=ConfigEnum.firewall, value=False),
|
388
407
|
BoolConfig(key=ConfigEnum.netdata, value=True),
|
389
408
|
StrConfig(key=ConfigEnum.lang, value='en'),
|
hiddifypanel/panel/usage.py
CHANGED
@@ -19,6 +19,7 @@ def update_local_usage():
|
|
19
19
|
|
20
20
|
|
21
21
|
def add_users_usage_uuid(uuids_bytes, child_id):
|
22
|
+
# WHAT IS THE "keys" function WHY ?????
|
22
23
|
users = User.query.filter(User.uuid.in_(keys(uuids_bytes)))
|
23
24
|
dbusers_bytes = {u: uuids_bytes.get(u.uuid, 0) for u in users}
|
24
25
|
add_users_usage(dbusers_bytes, child_id)
|
@@ -100,6 +101,6 @@ def send_bot_message(user):
|
|
100
101
|
try:
|
101
102
|
msg = Usage.get_usage_msg(user.uuid)
|
102
103
|
msg = _("User activated!") if user.is_active else _("Package ended!")+"\n"+msg
|
103
|
-
bot.send_message(user.telegram_id, msg, reply_markup=Usage.user_keyboard(uuid))
|
104
|
+
bot.send_message(user.telegram_id, msg, reply_markup=Usage.user_keyboard(user.uuid))
|
104
105
|
except:
|
105
106
|
pass
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from flask import g, request, render_template
|
2
|
-
from ipaddress import IPv4Address,
|
2
|
+
from ipaddress import IPv4Address, IPv6Address
|
3
3
|
import enum
|
4
4
|
from hiddifypanel import hutils
|
5
5
|
from hiddifypanel.models import *
|
@@ -235,7 +235,7 @@ def to_link(proxy):
|
|
235
235
|
if 'error' in proxy:
|
236
236
|
return proxy
|
237
237
|
orig_name_link = (proxy['extra_info'] + " " + proxy["name"]).strip()
|
238
|
-
name_link =
|
238
|
+
name_link = hutils.encode.url_encode(orig_name_link)
|
239
239
|
if proxy['proto'] == 'vmess':
|
240
240
|
# print(proxy)
|
241
241
|
vmess_type = None
|
@@ -264,12 +264,18 @@ def to_link(proxy):
|
|
264
264
|
vmess_data['pbk'] = proxy['reality_pbk']
|
265
265
|
vmess_data['sid'] = proxy['reality_short_id']
|
266
266
|
|
267
|
-
|
267
|
+
if proxy['cdn'] and g.user_agent.get('is_hiddify'):
|
268
|
+
add_tls_tricks_to_dict(vmess_data)
|
269
|
+
add_mux_to_dict(vmess_data)
|
270
|
+
|
271
|
+
return "vmess://" + hutils.encode.do_base_64(f'{json.dumps(vmess_data,cls=CustomEncoder)}')
|
268
272
|
# return pbase64(f'vmess://{json.dumps(vmess_data)}')
|
269
273
|
if proxy['proto'] == 'ssh':
|
270
|
-
strenssh =
|
274
|
+
strenssh = hutils.encode.do_base_64(f'{proxy["uuid"]}:0:{proxy["private_key"]}::@{proxy["server"]}:{proxy["port"]}')
|
271
275
|
baseurl = f'ssh://{strenssh}#{name_link}'
|
272
|
-
|
276
|
+
hk = hutils.encode.do_base_64(",".join(proxy["host_key"]))
|
277
|
+
pk = hutils.encode.do_base_64(proxy["private_key"])
|
278
|
+
baseurl += f'\nssh://{proxy["uuid"]}@{proxy["server"]}:{proxy["port"]}/?pk={pk}&hk={hk}#{name_link}'
|
273
279
|
|
274
280
|
return baseurl
|
275
281
|
if proxy['proto'] == "ssr":
|
@@ -298,6 +304,14 @@ def to_link(proxy):
|
|
298
304
|
baseurl += f'&sni={proxy["sni"]}&type={proxy["transport"]}'
|
299
305
|
baseurl += f"&alpn={proxy['alpn']}"
|
300
306
|
|
307
|
+
# the ray2sing supports vless, vmess and trojan tls tricks and mux
|
308
|
+
# the vmess handled already
|
309
|
+
|
310
|
+
if proxy['proto'] in {'vless', 'trojan'}:
|
311
|
+
baseurl = add_mux_to_link(baseurl)
|
312
|
+
if proxy['cdn'] and g.user_agent.get('is_hiddify'):
|
313
|
+
baseurl = add_tls_tricks_to_link(baseurl)
|
314
|
+
|
301
315
|
# infos+=f'&alpn={proxy["alpn"]}'
|
302
316
|
baseurl += f'&path={proxy["path"]}' if "path" in proxy else ""
|
303
317
|
baseurl += f'&host={proxy["host"]}' if "host" in proxy else ""
|
@@ -329,6 +343,54 @@ def to_link(proxy):
|
|
329
343
|
return f'{baseurl}&security=none{infos}'
|
330
344
|
return proxy
|
331
345
|
|
346
|
+
# region tls tricks & mux
|
347
|
+
# notice: combining the functions into two function would make code less readable and difficult to maintain
|
348
|
+
|
349
|
+
|
350
|
+
def add_tls_tricks_to_link(link: str) -> str:
|
351
|
+
if hconfig(ConfigEnum.tls_fragment_enable):
|
352
|
+
link += f'&fgsize={hconfig(ConfigEnum.tls_fragment_size)}&fgsleep={hconfig(ConfigEnum.tls_fragment_sleep)}'
|
353
|
+
if hconfig(ConfigEnum.tls_mixed_case):
|
354
|
+
link += '&mc=1'
|
355
|
+
if hconfig(ConfigEnum.tls_padding_enable):
|
356
|
+
link += f'&padsize={hconfig(ConfigEnum.tls_padding_length)}'
|
357
|
+
return link
|
358
|
+
|
359
|
+
|
360
|
+
def add_mux_to_link(link: str) -> str:
|
361
|
+
if hconfig(ConfigEnum.mux_enable):
|
362
|
+
link += f'&mux={hconfig(ConfigEnum.mux_protocol)}&mux_max={hconfig(ConfigEnum.mux_max_connections)}&mux_min={hconfig(ConfigEnum.mux_min_streams)}&mux_pad={hconfig(ConfigEnum.mux_padding_enable)}'
|
363
|
+
if hconfig(ConfigEnum.mux_brutal_enable):
|
364
|
+
link += f'&mux_up={hconfig(ConfigEnum.mux_brutal_up_mbps)}&mux_down={hconfig(ConfigEnum.mux_brutal_down_mbps)}'
|
365
|
+
return link
|
366
|
+
|
367
|
+
|
368
|
+
def add_tls_tricks_to_dict(d: dict):
|
369
|
+
if hconfig(ConfigEnum.tls_fragment_enable):
|
370
|
+
d['fgsize'] = hconfig(ConfigEnum.tls_fragment_size)
|
371
|
+
d['fgsleep'] = hconfig(ConfigEnum.tls_fragment_sleep)
|
372
|
+
if hconfig(ConfigEnum.tls_mixed_case):
|
373
|
+
d['mc'] = 1
|
374
|
+
if hconfig(ConfigEnum.tls_padding_enable):
|
375
|
+
d['padsize'] = hconfig(ConfigEnum.tls_padding_length)
|
376
|
+
|
377
|
+
|
378
|
+
def add_mux_to_dict(d: dict):
|
379
|
+
if hconfig(ConfigEnum.mux_enable):
|
380
|
+
d['mux'] = hconfig(ConfigEnum.mux_protocol)
|
381
|
+
d['mux_max'] = hconfig(ConfigEnum.mux_max_connections)
|
382
|
+
d['mux_min'] = hconfig(ConfigEnum.mux_min_streams)
|
383
|
+
d['mux_pad'] = hconfig(ConfigEnum.mux_padding_enable)
|
384
|
+
# the hiddify next client doesn't support mux max streams
|
385
|
+
# vmess_data['mux_max_streams'] = hconfig(ConfigEnum.mux_max_streams)
|
386
|
+
|
387
|
+
# handle brutal tcp
|
388
|
+
if hconfig(ConfigEnum.mux_brutal_enable):
|
389
|
+
d['mux_up'] = hconfig(ConfigEnum.mux_brutal_up_mbps)
|
390
|
+
d['mux_down'] = hconfig(ConfigEnum.mux_brutal_down_mbps)
|
391
|
+
|
392
|
+
# endregion
|
393
|
+
|
332
394
|
|
333
395
|
def to_clash_yml(proxy):
|
334
396
|
return yaml.dump(to_clash(proxy))
|
@@ -523,6 +585,9 @@ def to_singbox(proxy):
|
|
523
585
|
|
524
586
|
add_singbox_tls(base, proxy)
|
525
587
|
|
588
|
+
if proxy['cdn'] and g.user_agent.get('is_hiddify') and proxy["proto"] in ['vmess', 'vless', 'trojan']:
|
589
|
+
add_singbox_tls_tricks(base)
|
590
|
+
|
526
591
|
if proxy.get('flow'):
|
527
592
|
base["flow"] = proxy['flow']
|
528
593
|
# base["flow-show"] = True
|
@@ -567,15 +632,31 @@ def add_hysteria(base, proxy):
|
|
567
632
|
|
568
633
|
|
569
634
|
def add_singbox_multiplex(base):
|
570
|
-
|
635
|
+
if not hconfig(ConfigEnum.mux_enable):
|
636
|
+
return
|
571
637
|
base['multiplex'] = {
|
572
638
|
"enabled": True,
|
573
|
-
"protocol":
|
574
|
-
"
|
575
|
-
"min_streams": 4,
|
576
|
-
"max_streams": 0,
|
577
|
-
"padding": false
|
639
|
+
"protocol": hconfig(ConfigEnum.mux_protocol),
|
640
|
+
"padding": hconfig(ConfigEnum.mux_padding_enable)
|
578
641
|
}
|
642
|
+
# Conflicts: max_streams with max_connections and min_streams
|
643
|
+
mux_max_streams = int(hconfig(ConfigEnum.mux_max_streams))
|
644
|
+
if mux_max_streams and mux_max_streams != 0:
|
645
|
+
base['multiplex']['max_streams'] = mux_max_streams
|
646
|
+
else:
|
647
|
+
base['multiplex']['max_connections'] = int(hconfig(ConfigEnum.mux_max_connections))
|
648
|
+
base['multiplex']['min_streams'] = int(hconfig(ConfigEnum.mux_min_streams))
|
649
|
+
|
650
|
+
add_singbox_tcp_brutal(base)
|
651
|
+
|
652
|
+
|
653
|
+
def add_singbox_tcp_brutal(base):
|
654
|
+
if 'multiplex' in base:
|
655
|
+
base['multiplex']['brutal'] = {
|
656
|
+
"enabled": hconfig(ConfigEnum.mux_brutal_enable),
|
657
|
+
"up_mbps": int(hconfig(ConfigEnum.mux_brutal_up_mbps)),
|
658
|
+
"down_mbps": int(hconfig(ConfigEnum.mux_brutal_down_mbps))
|
659
|
+
}
|
579
660
|
|
580
661
|
|
581
662
|
def add_singbox_udp_over_tcp(base):
|
@@ -611,6 +692,28 @@ def add_singbox_tls(base, proxy):
|
|
611
692
|
# }
|
612
693
|
|
613
694
|
|
695
|
+
def add_singbox_tls_tricks(base):
|
696
|
+
if hconfig(ConfigEnum.tls_fragment_enable):
|
697
|
+
base['tls_fragment'] = {
|
698
|
+
# 'enable': True,
|
699
|
+
'size': hconfig(ConfigEnum.tls_fragment_size),
|
700
|
+
'sleep': hconfig(ConfigEnum.tls_fragment_sleep)
|
701
|
+
}
|
702
|
+
|
703
|
+
tls_padding_enable = hconfig(ConfigEnum.tls_padding_enable)
|
704
|
+
tls_mixed_case = hconfig(ConfigEnum.tls_mixed_case)
|
705
|
+
if (tls_padding_enable or tls_mixed_case) and 'tls' not in base:
|
706
|
+
base['tls'] = {
|
707
|
+
'tls_tricks': {}
|
708
|
+
}
|
709
|
+
if hconfig(ConfigEnum.tls_padding_enable):
|
710
|
+
base['tls']['tls_tricks'] = {
|
711
|
+
'padding_size': hconfig(ConfigEnum.tls_padding_length)
|
712
|
+
}
|
713
|
+
if hconfig(ConfigEnum.tls_mixed_case):
|
714
|
+
base['tls']['tls_tricks']['mixedcase_sni'] = True
|
715
|
+
|
716
|
+
|
614
717
|
def add_singbox_transport(base, proxy):
|
615
718
|
if proxy['l3'] == 'reality' and proxy['transport'] not in ["grpc"]:
|
616
719
|
return
|
@@ -769,7 +872,7 @@ def make_v2ray_configs(user, user_activate, domains, expire_days, ip_debug, db_d
|
|
769
872
|
# res.append(f'trojan://1@{fake_ip_for_sub_link}?sni=fake_ip_for_sub_link&security=tls#{round(user.current_usage_GB,3)}/{user.usage_limit_GB}GB_Remain:{expire_days}days')
|
770
873
|
# else:
|
771
874
|
|
772
|
-
# res.append(f'trojan://1@{fake_ip_for_sub_link}?sni=fake_ip_for_sub_link&security=tls#{
|
875
|
+
# res.append(f'trojan://1@{fake_ip_for_sub_link}?sni=fake_ip_for_sub_link&security=tls#{hutils.encode.url_encode(profile_title)}')
|
773
876
|
|
774
877
|
name = '⏳' if user_activate else '✖'
|
775
878
|
if user.usage_limit_GB < 1000:
|
@@ -785,7 +888,7 @@ def make_v2ray_configs(user, user_activate, domains, expire_days, ip_debug, db_d
|
|
785
888
|
|
786
889
|
name = name.strip()
|
787
890
|
if len(name) > 3:
|
788
|
-
res.append(f'trojan://1@{fake_ip_for_sub_link}?sni=fake_ip_for_sub_link&security=tls#{
|
891
|
+
res.append(f'trojan://1@{fake_ip_for_sub_link}?sni=fake_ip_for_sub_link&security=tls#{hutils.encode.url_encode(name)}')
|
789
892
|
|
790
893
|
if ua['is_browser']:
|
791
894
|
res.append(f'#Hiddify auto ip: {ip_debug}')
|
@@ -793,9 +896,9 @@ def make_v2ray_configs(user, user_activate, domains, expire_days, ip_debug, db_d
|
|
793
896
|
if not user_activate:
|
794
897
|
|
795
898
|
if hconfig(ConfigEnum.lang) == 'fa':
|
796
|
-
res.append('trojan://1@1.1.1.1#'+
|
899
|
+
res.append('trojan://1@1.1.1.1#'+hutils.encode.url_encode('✖بسته شما به پایان رسید'))
|
797
900
|
else:
|
798
|
-
res.append('trojan://1@1.1.1.1#'+
|
901
|
+
res.append('trojan://1@1.1.1.1#'+hutils.encode.url_encode('✖Package_Ended'))
|
799
902
|
return "\n".join(res)
|
800
903
|
|
801
904
|
for pinfo in get_all_validated_proxies(domains):
|
@@ -9,9 +9,11 @@
|
|
9
9
|
<link rel="stylesheet" href="node_modules/smartbanner.js/dist/smartbanner.min.css">
|
10
10
|
<link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet" type="text/css" />
|
11
11
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
12
|
-
|
12
|
+
<link rel="icon" type="image/x-icon" href="{{ static_url_for( filename='images/favicon.ico')}}">
|
13
|
+
<link rel="manifest" href="{{ url_for('common_bp.LoginView:create_pwa_manifest',secret_uuid=g.account.uuid or '')}}">
|
14
|
+
|
13
15
|
<title>Hiddify | Panel</title>
|
14
|
-
<script type="module" crossorigin src="../static/new/assets/index-
|
16
|
+
<script type="module" crossorigin src="../static/new/assets/index-2cd90979.js"></script>
|
15
17
|
<link rel="stylesheet" href="../static/new/assets/index-d9bbf489.css">
|
16
18
|
</head>
|
17
19
|
<body>
|