hiddifypanel 9.0.0.dev31__py3-none-any.whl → 9.0.0.dev33__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 +1 -1
- hiddifypanel/models/__init__.py +4 -3
- hiddifypanel/models/config.py +5 -5
- hiddifypanel/models/parent_domain.py +27 -27
- hiddifypanel/models/proxy.py +32 -30
- hiddifypanel/models/usage.py +71 -71
- hiddifypanel/panel/admin/Actions.py +5 -6
- hiddifypanel/panel/admin/AdminstratorAdmin.py +6 -6
- hiddifypanel/panel/admin/Backup.py +5 -5
- hiddifypanel/panel/admin/ChildAdmin.py +1 -2
- hiddifypanel/panel/admin/Dashboard.py +4 -5
- hiddifypanel/panel/admin/DomainAdmin.py +1 -1
- hiddifypanel/panel/admin/QuickSetup.py +1 -9
- hiddifypanel/panel/admin/UserAdmin.py +5 -5
- hiddifypanel/panel/admin/templates/parent_dash.html +1 -2
- hiddifypanel/panel/admin/templates/result.html +5 -3
- hiddifypanel/panel/cli.py +10 -32
- hiddifypanel/panel/commercial/ParentDomainAdmin.py +1 -1
- hiddifypanel/panel/commercial/restapi/v2/admin/server_status_api.py +5 -5
- hiddifypanel/panel/commercial/restapi/v2/user/info_api.py +2 -3
- hiddifypanel/panel/commercial/restapi/v2/user/short_api.py +2 -3
- hiddifypanel/panel/commercial/telegrambot/Usage.py +1 -1
- hiddifypanel/panel/commercial/templates/parent_dash.html +1 -1
- hiddifypanel/panel/common.py +3 -3
- hiddifypanel/panel/hiddify.py +37 -33
- hiddifypanel/panel/user/templates/new.html +2 -3
- hiddifypanel/panel/user/user.py +5 -193
- hiddifypanel/static/css/custom.css +5 -0
- hiddifypanel/static/new/assets/index-c4c80da4.js +1 -1
- hiddifypanel/templates/master.html +3 -2
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +90 -94
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +97 -94
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +103 -99
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +102 -98
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +91 -93
- {hiddifypanel-9.0.0.dev31.dist-info → hiddifypanel-9.0.0.dev33.dist-info}/METADATA +1 -1
- {hiddifypanel-9.0.0.dev31.dist-info → hiddifypanel-9.0.0.dev33.dist-info}/RECORD +47 -47
- {hiddifypanel-9.0.0.dev31.dist-info → hiddifypanel-9.0.0.dev33.dist-info}/LICENSE.md +0 -0
- {hiddifypanel-9.0.0.dev31.dist-info → hiddifypanel-9.0.0.dev33.dist-info}/WHEEL +0 -0
- {hiddifypanel-9.0.0.dev31.dist-info → hiddifypanel-9.0.0.dev33.dist-info}/entry_points.txt +0 -0
- {hiddifypanel-9.0.0.dev31.dist-info → hiddifypanel-9.0.0.dev33.dist-info}/top_level.txt +0 -0
hiddifypanel/panel/cli.py
CHANGED
@@ -55,34 +55,23 @@ def all_configs():
|
|
55
55
|
# "parent_domains": [hiddify.parent_domain_dict(u) for u in ParentDomain.query.all()],
|
56
56
|
"hconfigs": get_hconfigs()
|
57
57
|
}
|
58
|
-
# for d in configs['domains']:
|
59
|
-
|
60
|
-
# # del d['domain']['show_domains']
|
61
58
|
|
62
59
|
def_user = None if len(User.query.all()) > 1 else User.query.filter(User.name == 'default').first()
|
63
60
|
domains = Domain.query.all()
|
64
61
|
sslip_domains = [d.domain for d in domains if "sslip.io" in d.domain]
|
65
62
|
|
66
63
|
configs['hconfigs']['first_setup'] = def_user != None and len(sslip_domains) > 0
|
67
|
-
|
68
|
-
# path = f'/{hconfig(ConfigEnum.proxy_path_admin)}/l'
|
69
|
-
path = f'/{hconfig(ConfigEnum.proxy_path_admin)}/{AdminUser.get_super_admin_uuid()}/'
|
70
|
-
|
71
64
|
server_ip = hutils.ip.get_ip(4)
|
72
|
-
configs['admin_path'] = path
|
73
65
|
owner = AdminUser.get_super_admin()
|
66
|
+
|
67
|
+
configs['admin_path'] = hiddify.get_account_panel_link(owner, server_ip, is_https=False, prefere_path_only=True)
|
74
68
|
configs['panel_links'] = []
|
75
|
-
|
76
|
-
configs['panel_links'].append(
|
77
|
-
# configs['panel_links'].append(hutils.utils.add_basic_auth_to_url(f'https://{server_ip}{path}', owner.username, owner.password))
|
78
|
-
configs['panel_links'].append(f'https://{server_ip}{path}')
|
69
|
+
configs['panel_links'].append(hiddify.get_account_panel_link(owner, server_ip, is_https=False))
|
70
|
+
configs['panel_links'].append(hiddify.get_account_panel_link(owner, server_ip))
|
79
71
|
domains = get_panel_domains()
|
80
|
-
# if not any([d for d in domains if 'sslip.io' not in d.domain]):
|
81
|
-
# configs['panel_links'].append(f"https://{server_ip}{path}")
|
82
72
|
|
83
73
|
for d in domains:
|
84
|
-
|
85
|
-
configs['panel_links'].append(f'https://{d.domain}{path}')
|
74
|
+
configs['panel_links'].append(hiddify.get_account_panel_link(owner, d.domain))
|
86
75
|
|
87
76
|
print(json.dumps(configs, indent=4))
|
88
77
|
|
@@ -100,34 +89,23 @@ def admin_links():
|
|
100
89
|
server_ip = hutils.ip.get_ip(4)
|
101
90
|
owner = AdminUser.get_super_admin()
|
102
91
|
|
103
|
-
|
104
|
-
# admin_links = f"Not Secure (do not use it - only if others not work):\n {hutils.utils.add_basic_auth_to_url(f'http://{server_ip}/{proxy_path}/', owner.username, owner.password)}\n"
|
105
|
-
admin_links = f"Not Secure (do not use it - only if others not work):\n http://{server_ip}/{proxy_path}/{owner.uuid}/'\n"
|
92
|
+
admin_links = f"Not Secure (do not use it - only if others not work):\n {hiddify.get_account_panel_link(owner, server_ip,is_https=True)}'\n"
|
106
93
|
|
107
94
|
domains = get_panel_domains()
|
108
95
|
admin_links += f"Secure:\n"
|
109
96
|
if not any([d for d in domains if 'sslip.io' not in d.domain]):
|
110
|
-
|
111
|
-
admin_links += f" (not signed) https://{server_ip}/{proxy_path}/{owner.uuid}\n"
|
97
|
+
admin_links += f" (not signed) {hiddify.get_account_panel_link(owner, server_ip)}\n"
|
112
98
|
|
113
|
-
# domains=[*domains,f'{server_ip}.sslip.io']
|
114
99
|
for d in domains:
|
115
|
-
|
116
|
-
admin_links += f" https://{d.domain}/{proxy_path}/{owner.uuid}/\n"
|
100
|
+
admin_links += f" {hiddify.get_account_panel_link(owner, d.domain)}\n"
|
117
101
|
|
118
102
|
print(admin_links)
|
119
103
|
return admin_links
|
120
104
|
|
121
105
|
|
122
106
|
def admin_path():
|
123
|
-
|
124
|
-
|
125
|
-
if not admin:
|
126
|
-
db.session.add(AdminUser(mode=AdminMode.super_admin))
|
127
|
-
db.session.commit()
|
128
|
-
admin = AdminUser.query.filter(AdminUser.mode == AdminMode.super_admin).first()
|
129
|
-
|
130
|
-
print(f"/{proxy_path}/admin/")
|
107
|
+
admin = AdminUser.get_super_admin()
|
108
|
+
print(hiddify.get_account_panel_link(owner, server_ip, prefere_path_only=True))
|
131
109
|
|
132
110
|
|
133
111
|
def hysteria_domain_port():
|
@@ -64,7 +64,7 @@ class ParentDomainAdmin(AdminLTEModelView):
|
|
64
64
|
form_columns = ['domain', "alias", 'show_domains']
|
65
65
|
|
66
66
|
def _domain_admin_link(view, context, model, name):
|
67
|
-
admin_link =
|
67
|
+
admin_link = hiddify.get_account_panel_link(g.account,model.domain)
|
68
68
|
return Markup(f'<div class="btn-group"><a href="{admin_link}" class="btn btn-xs btn-secondary">' + _("admin link") +
|
69
69
|
f'</a><a href="{admin_link}" class="btn btn-xs btn-info ltr" target="_blank">{model.domain}</a></div>')
|
70
70
|
|
@@ -3,10 +3,10 @@ from flask import g
|
|
3
3
|
from flask.views import MethodView
|
4
4
|
from apiflask.fields import Dict
|
5
5
|
from apiflask import Schema
|
6
|
+
from hiddifypanel.models.usage import DailyUsage
|
6
7
|
from hiddifypanel.panel.auth import login_required
|
7
|
-
from hiddifypanel.models
|
8
|
+
from hiddifypanel.models import Role, DailyUsage
|
8
9
|
from hiddifypanel.panel import hiddify
|
9
|
-
from hiddifypanel.models import get_daily_usage_stats
|
10
10
|
|
11
11
|
|
12
12
|
class ServerStatus(Schema):
|
@@ -17,13 +17,13 @@ class ServerStatus(Schema):
|
|
17
17
|
class AdminServerStatusApi(MethodView):
|
18
18
|
decorators = [login_required({Role.super_admin, Role.admin, Role.agent})]
|
19
19
|
|
20
|
-
@app.output(ServerStatus)
|
20
|
+
@app.output(ServerStatus) # type: ignore
|
21
21
|
def get(self):
|
22
22
|
dto = ServerStatus()
|
23
|
-
dto.stats = {
|
23
|
+
dto.stats = { # type: ignore
|
24
24
|
'system': hiddify.system_stats(),
|
25
25
|
'top5': hiddify.top_processes()
|
26
26
|
}
|
27
27
|
admin_id = request.args.get("admin_id") or g.account.id
|
28
|
-
dto.usage_history = get_daily_usage_stats(admin_id)
|
28
|
+
dto.usage_history = DailyUsage.get_daily_usage_stats(admin_id) # type: ignore
|
29
29
|
return dto
|
@@ -47,8 +47,7 @@ class InfoAPI(MethodView):
|
|
47
47
|
dto = ProfileSchema()
|
48
48
|
# user is exist for sure
|
49
49
|
dto.profile_title = c['user'].name
|
50
|
-
|
51
|
-
dto.profile_url = f"https://{urlparse(request.base_url).hostname}/{g.proxy_path}/{g.account.uuid}/"
|
50
|
+
dto.profile_url = c['profile_url']
|
52
51
|
dto.profile_usage_current = g.account.current_usage_GB
|
53
52
|
dto.profile_usage_total = g.account.usage_limit_GB
|
54
53
|
dto.profile_remaining_days = g.account.remaining_days()
|
@@ -59,7 +58,7 @@ class InfoAPI(MethodView):
|
|
59
58
|
dto.admin_message_url = hconfig(ConfigEnum.branding_site)
|
60
59
|
dto.brand_title = hconfig(ConfigEnum.branding_title)
|
61
60
|
dto.brand_icon_url = ""
|
62
|
-
dto.doh = f"https://{
|
61
|
+
dto.doh = f"https://{request.host}/{g.proxy_path}/dns/dns-query"
|
63
62
|
dto.lang = c['user'].lang
|
64
63
|
return dto
|
65
64
|
|
@@ -23,9 +23,8 @@ class ShortAPI(MethodView):
|
|
23
23
|
|
24
24
|
@app.output(ShortSchema)
|
25
25
|
def get(self):
|
26
|
-
short, expire_in = hiddify.add_short_link(
|
27
|
-
|
28
|
-
full_url = f"https://{urlparse(request.base_url).hostname}/{short}"
|
26
|
+
short, expire_in = hiddify.add_short_link(hiddify.get_account_panel_link(g.account, request.host))
|
27
|
+
full_url = f"https://{request.host}/{short}"
|
29
28
|
dto = ShortSchema()
|
30
29
|
dto.full_url = full_url
|
31
30
|
dto.short = short
|
@@ -52,7 +52,7 @@ def get_usage_msg(uuid, domain=None):
|
|
52
52
|
reset_day = user_data['reset_day']
|
53
53
|
|
54
54
|
domain = domain or get_panel_domains()[0]
|
55
|
-
user_link =
|
55
|
+
user_link = hiddify.get_account_panel_link(user,domain.domain)
|
56
56
|
msg = f"""{_('<a href="%(user_link)s"> %(user)s</a>',user_link=user_link ,user=user.name if user.name != "default" else "")}\n\n"""
|
57
57
|
|
58
58
|
msg += f"""{_('user.home.usage.title')} {round(user.current_usage_GB, 3)}GB <b>{_('user.home.usage.from')}</b> {user.usage_limit_GB}GB {_('user.home.usage.monthly') if user.monthly else ''}\n"""
|
@@ -8,7 +8,7 @@
|
|
8
8
|
{% macro admin_btn(child,domain) -%}
|
9
9
|
<div class="btn-group">
|
10
10
|
|
11
|
-
<a href="
|
11
|
+
<a href="{hiddify.get_account_panel_link(g.account,domain,child_id=child.id)}" class="btn btn-xs btn-{{" success" if child.is_active else "warning" }} orig-link ltr" target="_blank">{{domain}}</a>
|
12
12
|
</div>
|
13
13
|
{%- endmacro -%}
|
14
14
|
|
hiddifypanel/panel/common.py
CHANGED
@@ -104,10 +104,10 @@ def init_app(app: APIFlask):
|
|
104
104
|
if hasattr(g, 'account') and isinstance(g.account, AdminUser):
|
105
105
|
values['proxy_path'] = hconfig(ConfigEnum.proxy_path_admin)
|
106
106
|
# elif 'static' in endpoint:
|
107
|
-
|
107
|
+
# values['proxy_path'] = hconfig(ConfigEnum.proxy_path)
|
108
108
|
elif hiddify.is_user_panel_call():
|
109
109
|
values['proxy_path'] = hconfig(ConfigEnum.proxy_path_client)
|
110
|
-
|
110
|
+
elif g.is_admin:
|
111
111
|
values['proxy_path'] = hconfig(ConfigEnum.proxy_path_admin)
|
112
112
|
|
113
113
|
if hiddify.is_api_v1_call(endpoint=endpoint) and 'admin_uuid' not in values:
|
@@ -184,7 +184,7 @@ def init_app(app: APIFlask):
|
|
184
184
|
|
185
185
|
# validate proxy path
|
186
186
|
|
187
|
-
g.proxy_path = hutils.utils.get_proxy_path_from_url(request.url)
|
187
|
+
# g.proxy_path = hutils.utils.get_proxy_path_from_url(request.url)
|
188
188
|
hiddify.proxy_path_validator(g.proxy_path)
|
189
189
|
|
190
190
|
# if g.proxy_path != hconfig(ConfigEnum.proxy_path):
|
hiddifypanel/panel/hiddify.py
CHANGED
@@ -27,15 +27,15 @@ from hiddifypanel.panel.run_commander import commander, Command
|
|
27
27
|
to_gig_d = 1000*1000*1000
|
28
28
|
|
29
29
|
|
30
|
-
def add_temporary_access():
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
# def add_temporary_access():
|
31
|
+
# random_port = random.randint(30000, 50000)
|
32
|
+
# # exec_command(
|
33
|
+
# # f'sudo /opt/hiddify-manager/hiddify-panel/temporary_access.sh {random_port} &')
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
# # run temporary_access.sh
|
36
|
+
# commander(Command.temporary_access, port=random_port)
|
37
|
+
# temp_admin_link = f"http://{hutils.ip.get_ip(4)}:{random_port}{get_admin_path()}"
|
38
|
+
# g.temp_admin_link = temp_admin_link
|
39
39
|
|
40
40
|
|
41
41
|
# with user panel url format we don't really need this function
|
@@ -65,12 +65,6 @@ def add_short_link_imp(link: str, period_min: int = 5) -> Tuple[str, datetime]:
|
|
65
65
|
return short_code, datetime.now() + timedelta(minutes=period_min)
|
66
66
|
|
67
67
|
|
68
|
-
def get_admin_path():
|
69
|
-
proxy_path = hconfig(ConfigEnum.proxy_path_admin)
|
70
|
-
# admin_secret = g.account.uuid or get_super_admin_secret()
|
71
|
-
return (f"/{proxy_path}/admin/")
|
72
|
-
|
73
|
-
|
74
68
|
def exec_command(cmd, cwd=None):
|
75
69
|
try:
|
76
70
|
subprocess.Popen(cmd.split(" ")) # run in background
|
@@ -206,13 +200,7 @@ def is_admin_home_call() -> bool:
|
|
206
200
|
|
207
201
|
|
208
202
|
def is_login_call() -> bool:
|
209
|
-
# print(request.blueprint)
|
210
203
|
return request.blueprint == 'common_bp'
|
211
|
-
# base_path = f'{request.host}'
|
212
|
-
# requested_url = f'{request.host}{request.path}'
|
213
|
-
# if requested_url == f'{base_path}/{hconfig(ConfigEnum.proxy_path_admin)}/' or requested_url == f'{base_path}/{hconfig(ConfigEnum.proxy_path_client)}/':
|
214
|
-
# return True
|
215
|
-
# return False
|
216
204
|
|
217
205
|
|
218
206
|
def is_admin_role(role: Role):
|
@@ -372,21 +360,15 @@ def check_connection_for_domain(domain):
|
|
372
360
|
return True
|
373
361
|
|
374
362
|
|
375
|
-
def
|
363
|
+
def get_html_user_link(model: BaseAccount, domain: Domain):
|
376
364
|
is_cdn = domain.mode == DomainType.cdn if type(domain) == Domain else False
|
377
365
|
res = ""
|
378
|
-
if mode == "multi":
|
379
|
-
res += "<div class='btn-group'>"
|
380
366
|
d = domain.domain
|
381
367
|
if "*" in d:
|
382
368
|
d = d.replace("*", get_random_string(5, 15))
|
383
|
-
proxy_path = hconfig(ConfigEnum.proxy_path_admin) if mode == 'admin' else hconfig(ConfigEnum.proxy_path_client)
|
384
|
-
# account = AdminUser.query.filter(AdminUser.uuid == uuid).first() if mode == 'admin' else User.query.filter(User.uuid == uuid).first()
|
385
|
-
# link = f"https://{account.username}:{account.password}@{d}/{proxy_path}/admin/#{username}" if mode == 'admin' else f"https://{account.username}:{account.password}@{d}/{proxy_path}/#{username}"
|
386
|
-
link = f"https://{d}/{proxy_path}/{uuid}/#{username}"
|
387
369
|
|
388
|
-
|
389
|
-
|
370
|
+
link = get_account_panel_link(model, d)+f"#{model.name}"
|
371
|
+
|
390
372
|
text = domain.alias or domain.domain
|
391
373
|
color_cls = 'info'
|
392
374
|
|
@@ -395,7 +377,7 @@ def get_user_link(uuid, domain, mode='', username=''):
|
|
395
377
|
color_cls = "success" if auto_cdn else 'warning'
|
396
378
|
text = f'<span class="badge badge-secondary" >{"Auto" if auto_cdn else "CDN"}</span> '+text
|
397
379
|
|
398
|
-
res += f"<a target='_blank' data-copy='{link}' href='{link}' class='btn btn-xs btn-{color_cls} ltr
|
380
|
+
res += f"<a target='_blank' data-copy='{link}' href='{link}' class='btn btn-xs btn-{color_cls} ltr share-link' ><i class='fa-solid fa-arrow-up-right-from-square d-none'></i> {text}</a>"
|
399
381
|
|
400
382
|
return res
|
401
383
|
|
@@ -538,11 +520,11 @@ def set_db_from_json(json_data, override_child_id=None, set_users=True, set_doma
|
|
538
520
|
if set_domains and 'domains' in json_data:
|
539
521
|
bulk_register_domains(json_data['domains'], commit=False, remove=remove_domains, override_child_id=override_child_id)
|
540
522
|
if set_domains and 'parent_domains' in json_data:
|
541
|
-
|
523
|
+
ParentDomain.bulk_register(json_data['parent_domains'], commit=False, remove=remove_domains)
|
542
524
|
if set_settings and 'hconfigs' in json_data:
|
543
525
|
bulk_register_configs(json_data["hconfigs"], commit=True, override_child_id=override_child_id, override_unique_id=override_unique_id)
|
544
526
|
if 'proxies' in json_data:
|
545
|
-
|
527
|
+
Proxy.bulk_register(json_data['proxies'], commit=False, override_child_id=override_child_id)
|
546
528
|
|
547
529
|
ids_without_parent = get_ids_without_parent({u.id: u.to_dict() for u in AdminUser.query.all()})
|
548
530
|
owner = AdminUser.get_super_admin()
|
@@ -846,7 +828,13 @@ def do_base_64(str):
|
|
846
828
|
|
847
829
|
|
848
830
|
def get_user_agent():
|
849
|
-
|
831
|
+
ua = __parse_user_agent(request.user_agent.string)
|
832
|
+
|
833
|
+
if 'is_bot' not in ua:
|
834
|
+
__parse_user_agent.invalidate_all()
|
835
|
+
ua = __parse_user_agent(request.user_agent.string)
|
836
|
+
|
837
|
+
return ua
|
850
838
|
|
851
839
|
|
852
840
|
@cache.cache()
|
@@ -909,3 +897,19 @@ def get_direct_host_or_ip(prefer_version: int):
|
|
909
897
|
if not direct:
|
910
898
|
direct = hutils.ip.get_ip(socket.AF_INET if prefer_version == socket.AF_INET6 else socket.AF_INET6)
|
911
899
|
return direct
|
900
|
+
|
901
|
+
|
902
|
+
def get_account_panel_link(account: BaseAccount, host: str, is_https: bool = True, prefere_path_only: bool = False, child_id=0):
|
903
|
+
basic_auth = False
|
904
|
+
|
905
|
+
link = ""
|
906
|
+
if basic_auth or not prefere_path_only:
|
907
|
+
link = "https://" if is_https else "http://"
|
908
|
+
if basic_auth:
|
909
|
+
link += f'{account.uuid}@'
|
910
|
+
link += host
|
911
|
+
proxy_path = hconfig(ConfigEnum.proxy_path_admin, child_id) if isinstance(account, AdminUser) else hconfig(ConfigEnum.proxy_path_client, child_id)
|
912
|
+
link += f'/{proxy_path}/'
|
913
|
+
if not basic_auth:
|
914
|
+
link += f'{account.uuid}/'
|
915
|
+
return link
|
@@ -2,8 +2,7 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<meta charset="UTF-8" />
|
5
|
-
|
6
|
-
<meta name="apple-itunes-app" content="app-id=6450534064, app-argument=streisand://import/{{base}}">
|
5
|
+
<meta name="apple-itunes-app" content="app-id=6450534064, app-argument=streisand://import/{{profile_url}}">
|
7
6
|
|
8
7
|
<link rel="icon" type="image/png" href="../static/new/assets/hiddify-logo-7617d937.png" />
|
9
8
|
<link rel="stylesheet" href="node_modules/smartbanner.js/dist/smartbanner.min.css">
|
@@ -20,7 +19,7 @@
|
|
20
19
|
<script src="node_modules/smartbanner.js/dist/smartbanner.min.js"></script>
|
21
20
|
<script>
|
22
21
|
window.appVersion = '{{version}}';
|
23
|
-
window.deepLink = "hiddify://import/{{
|
22
|
+
window.deepLink = "hiddify://import/{{profile_url}}"
|
24
23
|
</script>
|
25
24
|
</body>
|
26
25
|
</html>
|
hiddifypanel/panel/user/user.py
CHANGED
@@ -27,187 +27,11 @@ class UserView(FlaskView):
|
|
27
27
|
|
28
28
|
return f"<div style='direction:ltr'>https://{urlparse(request.base_url).hostname}/{short}/</a><br><br>"+_("This link will expire in 5 minutes")
|
29
29
|
|
30
|
-
@route('/
|
31
|
-
@route('/info')
|
32
|
-
# TODO: delete this function and use /me/ api instead
|
33
|
-
def info(self):
|
34
|
-
c = get_common_data(g.account.uuid, 'new')
|
35
|
-
data = {
|
36
|
-
'profile_title': c['profile_title'],
|
37
|
-
'profile_url': f"https://{g.account.username}:{g.account.password}{urlparse(request.base_url).hostname}/{g.proxy_path}/#{g.account.name}",
|
38
|
-
'profile_usage_current': g.account.current_usage_GB,
|
39
|
-
'profile_usage_total': g.account.usage_limit_GB,
|
40
|
-
'profile_remaining_days': g.account.remaining_days(),
|
41
|
-
'profile_reset_days': g.account.days_to_reset(),
|
42
|
-
'telegram_bot_url': f"https://t.me/{c['bot'].username}?start={g.account.uuid}" if c['bot'] else "",
|
43
|
-
'admin_message_html': hconfig(ConfigEnum.branding_freetext),
|
44
|
-
'admin_message_url': hconfig(ConfigEnum.branding_site),
|
45
|
-
'brand_title': hconfig(ConfigEnum.branding_title),
|
46
|
-
'brand_icon_url': "",
|
47
|
-
'doh': f"https://{urlparse(request.base_url).hostname}/{g.proxy_path}/dns/dns-query",
|
48
|
-
'def_lang': hconfig(ConfigEnum.lang)
|
49
|
-
}
|
50
|
-
|
51
|
-
return jsonify(data)
|
52
|
-
|
53
|
-
@route('/mtproxies/')
|
54
|
-
@route('/mtproxies')
|
55
|
-
def mtproxies(self):
|
56
|
-
# get domains
|
57
|
-
c = get_common_data(g.account.uuid, 'new')
|
58
|
-
mtproxies = []
|
59
|
-
# TODO: Remove duplicated domains mapped to a same ipv4 and v6
|
60
|
-
for d in c['domains']:
|
61
|
-
if d.mode not in [DomainType.direct, DomainType.relay]:
|
62
|
-
continue
|
63
|
-
hexuuid = hconfig(ConfigEnum.shared_secret, d.child_id).replace('-', '')
|
64
|
-
telegram_faketls_domain_hex = hconfig(ConfigEnum.telegram_fakedomain, d.child_id).encode('utf-8').hex()
|
65
|
-
server_link = f'tg://proxy?server={d.domain}&port=443&secret=ee{hexuuid}{telegram_faketls_domain_hex}'
|
66
|
-
mtproxies.append({'title': d.alias or d.domain, 'link': server_link})
|
67
|
-
|
68
|
-
return jsonify(mtproxies)
|
69
|
-
|
70
|
-
@route('/all-configs/')
|
71
|
-
@route('/all-configs')
|
72
|
-
def configs(self):
|
73
|
-
def create_item(name, type, domain, protocol, transport, security, link):
|
74
|
-
return {
|
75
|
-
'name': name,
|
76
|
-
'domain': domain,
|
77
|
-
'link': link,
|
78
|
-
# 'tags': set(type, protocol, transport, security),
|
79
|
-
'type': type,
|
80
|
-
'protocol': protocol,
|
81
|
-
'transport': transport,
|
82
|
-
'security': security,
|
83
|
-
}
|
84
|
-
|
85
|
-
items = []
|
86
|
-
base_url = f"https://{g.account.username}:{g.account.password}{urlparse(request.base_url).hostname}/{g.proxy_path}/"
|
87
|
-
c = get_common_data(g.account.uuid, 'new')
|
88
|
-
|
89
|
-
# Add Auto
|
90
|
-
items.append(
|
91
|
-
create_item(
|
92
|
-
"Auto", "All", "All", "All", "All", "All",
|
93
|
-
f"{base_url}sub/?asn={c['asn']}")
|
94
|
-
)
|
95
|
-
|
96
|
-
# Add Full Singbox
|
97
|
-
items.append(
|
98
|
-
create_item(
|
99
|
-
"Full Singbox", "All", "All", "All", "All", "All",
|
100
|
-
f"{base_url}full-singbox.json?asn={c['asn']}"
|
101
|
-
)
|
102
|
-
)
|
103
|
-
|
104
|
-
# Add Clash Meta
|
105
|
-
items.append(
|
106
|
-
create_item(
|
107
|
-
"Clash Meta", "All", "All", "All", "All", "All",
|
108
|
-
f"clashmeta://install-config?url={base_url}clash/meta/all.yml&name=mnormal_{c['db_domain'].alias or c['db_domain'].domain}-{c['asn']}-{c['mode']}&asn={c['asn']}&mode={c['mode']}"
|
109
|
-
)
|
110
|
-
)
|
111
|
-
|
112
|
-
# Add Clash
|
113
|
-
items.append(
|
114
|
-
create_item(
|
115
|
-
"Clash", "All", "All", "Except VLess", "All", "All",
|
116
|
-
f"clash://install-config?url={base_url}clash/all.yml&name=new_normal_{c['db_domain'].alias or c['db_domain'].domain}-{c['asn']}-{c['mode']}&asn={c['asn']}&mode={c['mode']}"
|
117
|
-
)
|
118
|
-
)
|
119
|
-
|
120
|
-
# Add Singbox: SSh
|
121
|
-
if hconfig(ConfigEnum.ssh_server_enable):
|
122
|
-
items.append(
|
123
|
-
create_item(
|
124
|
-
"Singbox: SSH", "SSH", "SSH", "SSH", "SSH", "SSH",
|
125
|
-
f"{base_url}singbox.json?name={c['db_domain'].alias or c['db_domain'].domain}-{c['asn']}&asn={c['asn']}&mode={c['mode']}"
|
126
|
-
)
|
127
|
-
)
|
128
|
-
|
129
|
-
# Add Subscription link
|
130
|
-
items.append(
|
131
|
-
create_item(
|
132
|
-
"Subscription link", "All", "All", "All", "All", "All",
|
133
|
-
f"{base_url}all.txt?name={c['db_domain'].alias or c['db_domain'].domain}-{c['asn']}&asn={c['asn']}&mode={c['mode']}"
|
134
|
-
)
|
135
|
-
)
|
136
|
-
|
137
|
-
# Add Subscription link base64
|
138
|
-
items.append(
|
139
|
-
create_item(
|
140
|
-
"Subscription link b64", "All", "All", "All", "All", "All",
|
141
|
-
f"{base_url}all.txt?name=new_link_{c['db_domain'].alias or c['db_domain'].domain}-{c['asn']}-{c['mode']}&asn={c['asn']}&mode={c['mode']}&base64=True"
|
142
|
-
)
|
143
|
-
)
|
144
|
-
|
145
|
-
for pinfo in link_maker.get_all_validated_proxies(c['domains']):
|
146
|
-
items.append(
|
147
|
-
create_item(
|
148
|
-
pinfo["name"].replace("_", " "),
|
149
|
-
f"{'Auto ' if pinfo['dbdomain'].has_auto_ip else ''}{pinfo['mode']}",
|
150
|
-
pinfo['server'],
|
151
|
-
pinfo['proto'],
|
152
|
-
pinfo['transport'],
|
153
|
-
pinfo['l3'],
|
154
|
-
f"{link_maker.to_link(pinfo)}"
|
155
|
-
)
|
156
|
-
)
|
157
|
-
|
158
|
-
return jsonify(items)
|
159
|
-
|
160
|
-
# endregion
|
161
|
-
|
162
|
-
@route('/test/')
|
30
|
+
@route('/useragent/')
|
163
31
|
@login_required(roles={Role.user})
|
164
32
|
def test(self):
|
165
33
|
ua = request.user_agent.string
|
166
|
-
|
167
|
-
return "Please do not open here"
|
168
|
-
conf = self.get_proper_config()
|
169
|
-
|
170
|
-
import json
|
171
|
-
ua = request.user_agent.string
|
172
|
-
uaa = user_agents.parse(request.user_agent.string)
|
173
|
-
with open('ua.txt', 'a') as f:
|
174
|
-
f.write("\n".join([
|
175
|
-
f'\n{datetime.datetime.now()} '+("Ok" if conf else "ERROR"),
|
176
|
-
ua,
|
177
|
-
f'os={uaa.os.family}-{uaa.os.version}({uaa.os.version_string}) br={uaa.browser.family} v={uaa.browser.version} vs={uaa.browser.version_string} dev={uaa.device.family}-{uaa.device.brand}-{uaa.device.model}',
|
178
|
-
'\n'
|
179
|
-
]))
|
180
|
-
if conf:
|
181
|
-
return conf
|
182
|
-
abort(500)
|
183
|
-
# @route('/old')
|
184
|
-
# @route('/old/')
|
185
|
-
# def index(self):
|
186
|
-
|
187
|
-
# c=get_common_data(g.account_uuid,mode="")
|
188
|
-
# user_agent = user_agents.parse(request.user_agent.string)
|
189
|
-
|
190
|
-
# return render_template('home/index.html',**c,ua=user_agent)
|
191
|
-
# @route('/multi/')
|
192
|
-
# @route('/multi')
|
193
|
-
# def multi(self):
|
194
|
-
|
195
|
-
# c=get_common_data(g.account_uuid,mode="multi")
|
196
|
-
|
197
|
-
# user_agent = user_agents.parse(request.user_agent.string)
|
198
|
-
|
199
|
-
# return render_template('home/multi.html',**c,ua=user_agent)
|
200
|
-
|
201
|
-
# @route('/')
|
202
|
-
# # @login_required()
|
203
|
-
# # login
|
204
|
-
# def login(self):
|
205
|
-
# return ""
|
206
|
-
# # redirect based on authenticated account
|
207
|
-
# if hiddify.is_admin_proxy_path() and g.account.role in {Role.super_admin, Role.admin, Role.agent}:
|
208
|
-
# return redirect(url_for('admin.Dashboard:index'))
|
209
|
-
# elif hiddify.is_client_proxy_path():
|
210
|
-
# return self.auto_sub()
|
34
|
+
return ua
|
211
35
|
|
212
36
|
def index(self):
|
213
37
|
return self.auto_sub()
|
@@ -241,14 +65,6 @@ class UserView(FlaskView):
|
|
241
65
|
if re.match('^(Hiddify|FoXray|Fair|v2rayNG|SagerNet|Shadowrocket|V2Box|Loon|Liberty)', ua, re.IGNORECASE):
|
242
66
|
return self.all_configs(base64=True)
|
243
67
|
|
244
|
-
@ route('/auto')
|
245
|
-
@login_required(roles={Role.user})
|
246
|
-
def auto_select(self):
|
247
|
-
c = get_common_data(g.account.uuid, mode="new")
|
248
|
-
user_agent = user_agents.parse(request.user_agent.string)
|
249
|
-
# return render_template('home/handle_smart.html', **c)
|
250
|
-
return render_template('home/auto_page.html', **c, ua=user_agent)
|
251
|
-
|
252
68
|
@ route('/new/')
|
253
69
|
@ route('/new')
|
254
70
|
@login_required(roles={Role.user})
|
@@ -371,11 +187,6 @@ class UserView(FlaskView):
|
|
371
187
|
# render_template('all_configs.txt', **c, base64=do_base_64)
|
372
188
|
resp = link_maker.make_v2ray_configs(**c)
|
373
189
|
|
374
|
-
# res = ""
|
375
|
-
# for line in resp.split("\n"):
|
376
|
-
# if "vmess://" in line:
|
377
|
-
# line = "vmess://"+do_base_64(line.replace("vmess://", ""))
|
378
|
-
# res += line+"\n"
|
379
190
|
if base64:
|
380
191
|
resp = do_base_64(resp)
|
381
192
|
return add_headers(resp, c)
|
@@ -383,7 +194,7 @@ class UserView(FlaskView):
|
|
383
194
|
@login_required(roles={Role.user})
|
384
195
|
@ route("/offline.html")
|
385
196
|
def offline():
|
386
|
-
return f"Not Connected <a href='
|
197
|
+
return f"Not Connected <a href='{hiddify.get_account_panel_link(g.account, request.host)}'>click for reload</a>"
|
387
198
|
|
388
199
|
# backward compatiblity
|
389
200
|
@route("/admin/<path:path>")
|
@@ -509,7 +320,8 @@ def get_common_data(user_uuid, mode, no_domain=False, filter_domain=None):
|
|
509
320
|
"ip_debug": auto_ip_selector.get_real_user_ip_debug(user_ip),
|
510
321
|
"asn": asn,
|
511
322
|
"country": auto_ip_selector.get_country(user_ip),
|
512
|
-
'has_auto_cdn': has_auto_cdn
|
323
|
+
'has_auto_cdn': has_auto_cdn,
|
324
|
+
'profile_url': hiddify.get_account_panel_link(g.account, domain)
|
513
325
|
}
|
514
326
|
|
515
327
|
|