hiddifypanel 10.10.20__py3-none-any.whl → 10.11.1__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.
Files changed (68) hide show
  1. hiddifypanel/VERSION +1 -1
  2. hiddifypanel/VERSION.py +2 -2
  3. hiddifypanel/hutils/__init__.py +3 -0
  4. hiddifypanel/hutils/crypto.py +29 -0
  5. hiddifypanel/hutils/encode.py +4 -0
  6. hiddifypanel/hutils/flask.py +4 -0
  7. hiddifypanel/hutils/github_issue.py +1 -1
  8. hiddifypanel/{models/utils.py → hutils/model.py} +14 -4
  9. hiddifypanel/hutils/network/net.py +46 -2
  10. hiddifypanel/hutils/proxy/__init__.py +4 -0
  11. hiddifypanel/hutils/proxy/clash.py +161 -0
  12. hiddifypanel/hutils/proxy/shared.py +414 -0
  13. hiddifypanel/hutils/proxy/singbox.py +338 -0
  14. hiddifypanel/hutils/proxy/xray.py +561 -0
  15. hiddifypanel/models/admin.py +16 -14
  16. hiddifypanel/models/base_account.py +4 -4
  17. hiddifypanel/models/config.py +1 -1
  18. hiddifypanel/models/proxy.py +17 -17
  19. hiddifypanel/models/user.py +15 -13
  20. hiddifypanel/panel/admin/AdminstratorAdmin.py +1 -1
  21. hiddifypanel/panel/admin/DomainAdmin.py +13 -27
  22. hiddifypanel/panel/admin/ProxyAdmin.py +3 -3
  23. hiddifypanel/panel/admin/SettingAdmin.py +22 -11
  24. hiddifypanel/panel/admin/UserAdmin.py +9 -7
  25. hiddifypanel/panel/cf_api.py +1 -2
  26. hiddifypanel/panel/commercial/ProxyDetailsAdmin.py +5 -6
  27. hiddifypanel/panel/commercial/restapi/v2/user/apps_api.py +1 -1
  28. hiddifypanel/panel/commercial/restapi/v2/user/configs_api.py +4 -7
  29. hiddifypanel/panel/common.py +5 -3
  30. hiddifypanel/panel/hiddify.py +0 -90
  31. hiddifypanel/panel/init_db.py +14 -9
  32. hiddifypanel/panel/user/__init__.py +0 -1
  33. hiddifypanel/panel/user/templates/all_configs copy.txt +2 -2
  34. hiddifypanel/panel/user/templates/all_configs.txt +2 -2
  35. hiddifypanel/panel/user/templates/base_singbox_config.json.j2 +2 -1
  36. hiddifypanel/panel/user/templates/base_xray_config.json.j2 +125 -0
  37. hiddifypanel/panel/user/templates/clash_config copy.yml +1 -1
  38. hiddifypanel/panel/user/templates/clash_config.yml +4 -4
  39. hiddifypanel/panel/user/templates/clash_proxies.yml +1 -1
  40. hiddifypanel/panel/user/templates/home/all-configs.html +2 -2
  41. hiddifypanel/panel/user/templates/home/all-configs_old.html +1 -1
  42. hiddifypanel/panel/user/templates/home/ios copy.html +2 -2
  43. hiddifypanel/panel/user/user.py +50 -44
  44. hiddifypanel/templates/admin-layout.html +16 -24
  45. hiddifypanel/templates/fake.html +0 -276
  46. hiddifypanel/templates/flaskadmin-layout.html +2 -1
  47. hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
  48. hiddifypanel/translations/en/LC_MESSAGES/messages.po +16 -9
  49. hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
  50. hiddifypanel/translations/fa/LC_MESSAGES/messages.po +12 -6
  51. hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
  52. hiddifypanel/translations/pt/LC_MESSAGES/messages.po +9 -4
  53. hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
  54. hiddifypanel/translations/ru/LC_MESSAGES/messages.po +12 -7
  55. hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
  56. hiddifypanel/translations/zh/LC_MESSAGES/messages.po +9 -4
  57. hiddifypanel/translations.i18n/en.json +8 -7
  58. hiddifypanel/translations.i18n/fa.json +5 -4
  59. hiddifypanel/translations.i18n/pt.json +3 -2
  60. hiddifypanel/translations.i18n/ru.json +6 -5
  61. hiddifypanel/translations.i18n/zh.json +3 -2
  62. {hiddifypanel-10.10.20.dist-info → hiddifypanel-10.11.1.dist-info}/METADATA +1 -1
  63. {hiddifypanel-10.10.20.dist-info → hiddifypanel-10.11.1.dist-info}/RECORD +67 -61
  64. {hiddifypanel-10.10.20.dist-info → hiddifypanel-10.11.1.dist-info}/WHEEL +1 -1
  65. hiddifypanel/panel/user/link_maker.py +0 -1089
  66. {hiddifypanel-10.10.20.dist-info → hiddifypanel-10.11.1.dist-info}/LICENSE.md +0 -0
  67. {hiddifypanel-10.10.20.dist-info → hiddifypanel-10.11.1.dist-info}/entry_points.txt +0 -0
  68. {hiddifypanel-10.10.20.dist-info → hiddifypanel-10.11.1.dist-info}/top_level.txt +0 -0
@@ -13,13 +13,18 @@ from hiddifypanel.models import *
13
13
  from hiddifypanel.models import ConfigEnum, User, set_hconfig, ChildMode
14
14
  from hiddifypanel.panel import hiddify
15
15
  from hiddifypanel.database import db
16
- import hiddifypanel.models.utils as model_utils
16
+ from hiddifypanel import hutils
17
17
 
18
18
  from flask import g
19
19
 
20
20
  MAX_DB_VERSION = 80
21
21
 
22
22
 
23
+ def _v75(child_id):
24
+ for u in User.query.all():
25
+ hutils.model.gen_wg_keys(u)
26
+
27
+
23
28
  def _v74(child_id):
24
29
  set_hconfig(ConfigEnum.ws_enable, True)
25
30
  set_hconfig(ConfigEnum.grpc_enable, True)
@@ -66,12 +71,12 @@ def _v69():
66
71
  add_config_if_not_exist(ConfigEnum.wireguard_port, hutils.random.get_random_unused_port())
67
72
  add_config_if_not_exist(ConfigEnum.wireguard_ipv4, "10.90.0.1")
68
73
  add_config_if_not_exist(ConfigEnum.wireguard_ipv6, "fd42:42:90::1")
69
- wg_pk, wg_pub, _ = hiddify.get_wg_private_public_psk_pair()
74
+ wg_pk, wg_pub, _ = hutils.crypto.get_wg_private_public_psk_pair()
70
75
  add_config_if_not_exist(ConfigEnum.wireguard_private_key, wg_pk)
71
76
  add_config_if_not_exist(ConfigEnum.wireguard_public_key, wg_pub)
72
77
  add_config_if_not_exist(ConfigEnum.wireguard_noise_trick, "5-10")
73
78
  for u in User.query.all():
74
- u.wg_pk, u.wg_pub, u.wg_psk = hiddify.get_wg_private_public_psk_pair()
79
+ u.wg_pk, u.wg_pub, u.wg_psk = hutils.crypto.get_wg_private_public_psk_pair()
75
80
 
76
81
 
77
82
  def _v65():
@@ -116,13 +121,13 @@ def _v60():
116
121
  def _v59():
117
122
  # set user model username and password
118
123
  for u in User.query.all():
119
- model_utils.fill_username(u)
120
- model_utils.fill_password(u)
124
+ hutils.model.gen_username(u)
125
+ hutils.model.gen_password(u)
121
126
 
122
127
  # set admin model username and password
123
128
  for a in AdminUser.query.all():
124
- model_utils.fill_username(a)
125
- model_utils.fill_password(a)
129
+ hutils.model.gen_username(a)
130
+ hutils.model.gen_password(a)
126
131
 
127
132
 
128
133
  def _v57():
@@ -160,7 +165,7 @@ def _v50():
160
165
  def _v49():
161
166
 
162
167
  for u in User.query.all():
163
- priv, publ = hiddify.get_ed25519_private_public_pair()
168
+ priv, publ = hutils.crypto.get_ed25519_private_public_pair()
164
169
  u.ed25519_private_key = priv
165
170
  u.ed25519_public_key = publ
166
171
 
@@ -366,7 +371,7 @@ def _v7():
366
371
  Proxy.query.filter(Proxy.name == 'tls XTLSVision direct trojan').delete()
367
372
  except BaseException:
368
373
  pass
369
- add_config_if_not_exist(ConfigEnum.telegram_lib, "python")
374
+ add_config_if_not_exist(ConfigEnum.telegram_lib, "erlang")
370
375
  add_config_if_not_exist(ConfigEnum.admin_lang, hconfig(ConfigEnum.lang))
371
376
  add_config_if_not_exist(ConfigEnum.branding_title, "")
372
377
  add_config_if_not_exist(ConfigEnum.branding_site, "")
@@ -1,6 +1,5 @@
1
1
  from .user import UserView
2
2
  from flask import send_from_directory
3
- from . import link_maker
4
3
  from flask import Blueprint
5
4
  from hiddifypanel.database import db
6
5
 
@@ -1,4 +1,4 @@
1
- {% for type in link_maker.all_proxies(d.child_id) %}
1
+ {% for type in link_maker.get_all_proxies(d.child_id,only_enabled=True) %}
2
2
  {% set pinfo=link_maker.proxy_info(type) %}
3
3
  # {{type}} {{domain}}
4
4
  {{pinfo['url']}}
@@ -16,7 +16,7 @@
16
16
  # HTTP Not Secure
17
17
  # HTTP Not Secure
18
18
 
19
- {% for type in link_maker.all_proxies(d.child_id) %}
19
+ {% for type in link_maker.get_all_proxies(d.child_id,only_enabled=True) %}
20
20
  {% set pinfo=link_maker.proxy_info(type,port=80,security="http") %}
21
21
  {% if pinfo!=None %}
22
22
  # HTTP {{type}} {{domain}}
@@ -14,10 +14,10 @@ trojan://1@{{fake_ip_for_sub_link}}?sni=fake_ip_for_sub_link&security=tls#{{user
14
14
  ####################################
15
15
  ## {% if d.has_auto_ip %}Auto {%endif%} {{d.mode}} {{d.alias or d.domain}} {{t}}:{{port}}
16
16
  ####################################
17
- {% for type in link_maker.all_proxies(d.child_id) %}
17
+ {% for type in link_maker.get_all_proxies(d.child_id, only_enabled=True) %}
18
18
  {% set pinfo=link_maker.make_proxy(type,d,phttp=phttp,ptls=ptls) %}
19
19
  {% if 'msg' not in pinfo %}
20
- {% set link=link_maker.to_link(pinfo) %}
20
+ {% set link=link_maker.xray.to_link(pinfo) %}
21
21
  {% if 'msg' not in link %}
22
22
  {{''}}
23
23
  # {{pinfo["name"]}} {{d.alias or d.domain}}
@@ -170,6 +170,7 @@
170
170
  "domain": [
171
171
  "github.com",
172
172
  "githubusercontent.com",
173
+ "raw.githubusercontent.com",
173
174
  "1.1.1.1"
174
175
  ],
175
176
  "server": "dns-local"
@@ -225,4 +226,4 @@
225
226
  "type": "mixed"
226
227
  }
227
228
  ]
228
- }
229
+ }
@@ -0,0 +1,125 @@
1
+ {
2
+ "remarks": "{{remarks}}",
3
+ "log": {
4
+ "access": "",
5
+ "error": "",
6
+ "loglevel": "warning"
7
+ },
8
+ "inbounds": [
9
+ {
10
+ "tag": "socks",
11
+ "port": 10808,
12
+ "listen": "127.0.0.1",
13
+ "protocol": "socks",
14
+ "sniffing": {
15
+ "enabled": true,
16
+ "destOverride": [
17
+ "http",
18
+ "tls"
19
+ ],
20
+ "routeOnly": false
21
+ },
22
+ "settings": {
23
+ "auth": "noauth",
24
+ "udp": true,
25
+ "allowTransparent": false
26
+ }
27
+ },
28
+ {
29
+ "tag": "http",
30
+ "port": 10809,
31
+ "listen": "127.0.0.1",
32
+ "protocol": "http",
33
+ "sniffing": {
34
+ "enabled": true,
35
+ "destOverride": [
36
+ "http",
37
+ "tls"
38
+ ],
39
+ "routeOnly": false
40
+ },
41
+ "settings": {
42
+ "auth": "noauth",
43
+ "udp": true,
44
+ "allowTransparent": false
45
+ }
46
+ }
47
+ ],
48
+ "outbounds": [
49
+ {
50
+ "tag": "fragment",
51
+ "protocol": "freedom",
52
+ "settings": {
53
+ "domainStrategy": "AsIs",
54
+ {% if hconfig(ConfigEnum.tls_fragment_enable) %}
55
+ "fragment": {
56
+ "packets": "tlshello",
57
+ "length": "{{ hconfig(ConfigEnum.tls_fragment_size) }}",
58
+ "interval": "{{ hconfig(ConfigEnum.tls_fragment_sleep) }}"
59
+ }
60
+ {% endif %}
61
+ },
62
+ "streamSettings": {
63
+ "sockopt": {
64
+ "tcpNoDelay": true,
65
+ "tcpKeepAliveIdle": 100
66
+ }
67
+ }
68
+ },
69
+ {
70
+ "tag": "direct",
71
+ "protocol": "freedom",
72
+ "settings": {}
73
+ },
74
+ {
75
+ "tag": "block",
76
+ "protocol": "blackhole",
77
+ "settings": {
78
+ "response": {
79
+ "type": "http"
80
+ }
81
+ }
82
+ }
83
+ ],
84
+ "routing": {
85
+ "domainStrategy": "AsIs",
86
+ "rules": [
87
+ {
88
+ "type": "field",
89
+ "inboundTag": [
90
+ "api"
91
+ ],
92
+ "outboundTag": "api",
93
+ "enabled": true
94
+ },
95
+ {
96
+ "id": "5465425548310166497",
97
+ "type": "field",
98
+ "outboundTag": "direct",
99
+ "domain": [
100
+ "domain:ir",
101
+ "geosite:cn"
102
+ ],
103
+ "enabled": true
104
+ },
105
+ {
106
+ "id": "5425034033205580637",
107
+ "type": "field",
108
+ "outboundTag": "direct",
109
+ "ip": [
110
+ "geoip:private",
111
+ "geoip:cn",
112
+ "geoip:ir"
113
+ ],
114
+ "enabled": true
115
+ },
116
+ {
117
+ "id": "5627785659655799759",
118
+ "type": "field",
119
+ "port": "0-65535",
120
+ "outboundTag": "proxy",
121
+ "enabled": true
122
+ }
123
+ ]
124
+ }
125
+ }
@@ -180,7 +180,7 @@ proxy-groups:
180
180
 
181
181
 
182
182
 
183
- {#link_maker.get_all_clash_configs(meta_or_normal,domains)#}
183
+ {#link_maker.clash.get_all_clash_configs(meta_or_normal,domains)#}
184
184
 
185
185
  proxy-providers:
186
186
  all_proxies:
@@ -51,7 +51,7 @@ proxy-groups:
51
51
  proxies:
52
52
  - automatic
53
53
  - sequential
54
- {{link_maker.get_clash_config_names(meta_or_normal,domains)|indent(6)}}
54
+ {{link_maker.clash.get_clash_config_names(meta_or_normal,domains)|indent(6)}}
55
55
 
56
56
  # use:
57
57
  # %for phttp in hconfigs[ConfigEnum.http_ports].split(',')
@@ -88,7 +88,7 @@ proxy-groups:
88
88
  url: "http://cp.cloudflare.com"
89
89
  interval: 300
90
90
  proxies:
91
- {{link_maker.get_clash_config_names(meta_or_normal,domains)|indent(6)}}
91
+ {{link_maker.clash.get_clash_config_names(meta_or_normal,domains)|indent(6)}}
92
92
  # use:
93
93
  # %for phttp in hconfigs[ConfigEnum.http_ports].split(',')
94
94
  # - all_proxies_{{phttp}}
@@ -99,7 +99,7 @@ proxy-groups:
99
99
 
100
100
  - name: auto
101
101
  proxies:
102
- {{link_maker.get_clash_config_names(meta_or_normal,domains)|indent(6)}}
102
+ {{link_maker.clash.get_clash_config_names(meta_or_normal,domains)|indent(6)}}
103
103
  # use:
104
104
  # %for phttp in hconfigs[ConfigEnum.http_ports].split(',')
105
105
  # - all_proxies_{{phttp}}
@@ -116,7 +116,7 @@ proxy-groups:
116
116
 
117
117
 
118
118
 
119
- {{link_maker.get_all_clash_configs(meta_or_normal,domains)}}
119
+ {{link_maker.clash.get_all_clash_configs(meta_or_normal,domains)}}
120
120
 
121
121
  # proxy-providers:
122
122
  # %for t in (['http','tls'] if hconfigs[ConfigEnum.http_proxy_enable] else ['tls'])
@@ -1,5 +1,5 @@
1
1
 
2
- {{link_maker.get_all_clash_configs(meta_or_normal,domains)}}
2
+ {{link_maker.clash.get_all_clash_configs(meta_or_normal,domains)}}
3
3
 
4
4
 
5
5
  {% if False %}
@@ -108,10 +108,10 @@
108
108
  <td><span class="badge badge-success">{{_('all')}}</span></td>
109
109
  </tr>
110
110
 
111
- {% for pinfo in link_maker.get_all_validated_proxies(domains) %}
111
+ {% for pinfo in link_maker.get_valid_proxies(domains) %}
112
112
  <tr>
113
113
  <td>
114
- <div class="btn-group"><a href='{{link_maker.to_link(pinfo)}}' class="btn btn-light orig-link">{{pinfo["name"].replace("_", " ")}}</a></div>
114
+ <div class="btn-group"><a href='{{link_maker.xray.to_link(pinfo)}}' class="btn btn-light orig-link">{{pinfo["name"].replace("_", " ")}}</a></div>
115
115
  </td>
116
116
  <td><span class="badge badge-danger"> {% if pinfo['dbdomain'].has_auto_ip %}Auto {%endif%}{{pinfo["mode"]}}</span></td>
117
117
  <td><span class="badge ltr">{{pinfo['server']}}</span></td>
@@ -48,7 +48,7 @@
48
48
  <td><span class="badge badge-success">{{_('all')}}</span></td>
49
49
  </tr>
50
50
 
51
- {% for type in link_maker.all_proxies() %}
51
+ {% for type in link_maker.get_all_proxies(only_enabled=True) %}
52
52
  {% for mode in ["tls","http"] %}
53
53
  {% set pinfo=link_maker.proxy_info(type,mode=mode) %}
54
54
  {% if pinfo!=None %}
@@ -51,7 +51,7 @@
51
51
  سپس کانفیگ مورد نظر را انتخاب و اجرا نمایید.
52
52
  <br>
53
53
 
54
- {% for type in link_maker.all_proxies() %}
54
+ {% for type in link_maker.get_all_proxies(only_enabled=True) %}
55
55
  {% set pinfo=link_maker.proxy_info(type) %}
56
56
  {% if pinfo!=None %}
57
57
  <div class="btn-group"><a href='{{pinfo["url"]}}' class="btn btn-primary orig-link">{{type}}</a></div>
@@ -107,7 +107,7 @@
107
107
  <br />
108
108
  سپس کانفیگ مورد نظر خود را اعمال کنید:
109
109
  <br />
110
- {% for type in link_maker.all_proxies() %}
110
+ {% for type in link_maker.get_all_proxies(only_enabled=True) %}
111
111
  {% set pinfo=link_maker.proxy_info(type) %}
112
112
  {% if pinfo!=None %}
113
113
  <div class="btn-group"><a href='{{pinfo["url"]}}' class="btn btn-primary orig-link">{{type}}</a></div>
@@ -5,7 +5,6 @@ import re
5
5
 
6
6
  from flask import render_template, request, Response, g
7
7
  from apiflask import abort
8
- from . import link_maker
9
8
  from flask_classful import FlaskView, route
10
9
  from urllib.parse import urlparse
11
10
  from flask_babel import gettext as _
@@ -16,7 +15,6 @@ from hiddifypanel.database import db
16
15
  from hiddifypanel.panel import hiddify
17
16
  from hiddifypanel.models import *
18
17
  from hiddifypanel import hutils
19
- from hiddifypanel import cache
20
18
 
21
19
 
22
20
  class UserView(FlaskView):
@@ -56,6 +54,14 @@ class UserView(FlaskView):
56
54
  def sub64(self):
57
55
  return self.all_configs(base64=True)
58
56
 
57
+ @route("/xray/")
58
+ @route("/xray")
59
+ @login_required(roles={Role.user})
60
+ def xray(self):
61
+ c = c = get_common_data(g.account.uuid, mode="new")
62
+ configs = hutils.proxy.xray.configs_as_json(c['domains'], c['profile_title'])
63
+ return add_headers(configs, c, 'application/json')
64
+
59
65
  @route("/singbox/")
60
66
  @route("/singbox")
61
67
  @login_required(roles={Role.user})
@@ -127,43 +133,43 @@ class UserView(FlaskView):
127
133
 
128
134
  return resp
129
135
 
130
- @ route('/report', methods=["POST"])
131
- @login_required(roles={Role.user})
132
- def report(self):
133
-
134
- # THE REPORT MODEL IS NOT COMPLETED YET.
135
-
136
- data = request.get_json()
137
- user_ip = hutils.network.auto_ip_selector.get_real_user_ip()
138
- report = Report()
139
- report.asn_id = hutils.network.auto_ip_selector.get_asn_id(user_ip)
140
- report.country = hutils.network.auto_ip_selector.get_country(user_ip)
141
-
142
- city_info = hutils.network.auto_ip_selector.get_city(user_ip)
143
- report.city = city_info['name']
144
- report.latitude = city_info['latitude']
145
- report.longitude = city_info['longitude']
146
- report.accuracy_radius = city_info['accuracy_radius']
147
-
148
- report.date = datetime.datetime.now()
149
- sub_update_time = data['sub_update_time']
150
- sub_url = data['sub_url']
151
-
152
- db.session.add(report)
153
- db.session.commit()
154
- proxy_map = {p.name: p.id for p in Proxy.query.all()}
155
-
156
- for name, ping in data['pings']:
157
- detail = ReportDetail()
158
- detail.report_id = report.id
159
- detail.proxy_id = proxy_map.get(name, -1)
160
- del proxy_map[name]
161
- if detail.proxy_id < 0:
162
- print("Error. Proxy not found!")
163
- continue
164
- detail.ping = ping
165
- db.session.add(detail)
166
- db.session.commit()
136
+ # @ route('/report', methods=["POST"])
137
+ # @login_required(roles={Role.user})
138
+ # def report(self):
139
+
140
+ # # THE REPORT MODEL IS NOT COMPLETED YET.
141
+
142
+ # data = request.get_json()
143
+ # user_ip = hutils.network.auto_ip_selector.get_real_user_ip()
144
+ # report = Report()
145
+ # report.asn_id = hutils.network.auto_ip_selector.get_asn_id(user_ip)
146
+ # report.country = hutils.network.auto_ip_selector.get_country(user_ip)
147
+
148
+ # city_info = hutils.network.auto_ip_selector.get_city(user_ip)
149
+ # report.city = city_info['name']
150
+ # report.latitude = city_info['latitude']
151
+ # report.longitude = city_info['longitude']
152
+ # report.accuracy_radius = city_info['accuracy_radius']
153
+
154
+ # report.date = datetime.datetime.now()
155
+ # sub_update_time = data['sub_update_time']
156
+ # sub_url = data['sub_url']
157
+
158
+ # db.session.add(report)
159
+ # db.session.commit()
160
+ # proxy_map = {p.name: p.id for p in Proxy.query.all()}
161
+
162
+ # for name, ping in data['pings']:
163
+ # detail = ReportDetail()
164
+ # detail.report_id = report.id
165
+ # detail.proxy_id = proxy_map.get(name, -1)
166
+ # del proxy_map[name]
167
+ # if detail.proxy_id < 0:
168
+ # print("Error. Proxy not found!")
169
+ # continue
170
+ # detail.ping = ping
171
+ # db.session.add(detail)
172
+ # db.session.commit()
167
173
 
168
174
  @ route('/clash/<typ>.yml', methods=["GET", "HEAD"])
169
175
  @ route('/clash/<meta_or_normal>/<typ>.yml', methods=["GET", "HEAD"])
@@ -191,7 +197,7 @@ class UserView(FlaskView):
191
197
  if request.method == 'HEAD':
192
198
  resp = ""
193
199
  else:
194
- resp = link_maker.make_full_singbox_config(**c)
200
+ resp = hutils.proxy.singbox.configs_as_json(**c)
195
201
 
196
202
  return add_headers(resp, c, 'application/json')
197
203
 
@@ -206,7 +212,7 @@ class UserView(FlaskView):
206
212
  if request.method == 'HEAD':
207
213
  resp = ""
208
214
  else:
209
- resp = render_template('singbox_config.json', **c, host_keys=hiddify.get_hostkeys(True),
215
+ resp = render_template('singbox_config.json', **c, host_keys=hutils.proxy.get_ssh_hostkeys(True),
210
216
  ssh_client_version=hiddify.get_ssh_client_version(user), ssh_ip=hutils.network.get_direct_host_or_ip(4), base64=False)
211
217
 
212
218
  return add_headers(resp, c)
@@ -222,7 +228,7 @@ class UserView(FlaskView):
222
228
  resp = ""
223
229
  else:
224
230
  # render_template('all_configs.txt', **c, base64=hutils.encode.do_base_64)
225
- resp = link_maker.make_v2ray_configs(**c)
231
+ resp = hutils.proxy.xray.make_v2ray_configs(**c)
226
232
 
227
233
  if base64:
228
234
  resp = hutils.encode.do_base_64(resp)
@@ -249,7 +255,7 @@ class UserView(FlaskView):
249
255
  # @cache.cache(ttl=300)
250
256
  def get_domain_information(no_domain=False, filter_domain=None, alternative=None):
251
257
  domains = []
252
- default_asn = request.args.get("asn")
258
+ default_asn = request.args.get("asn", '')
253
259
  if filter_domain:
254
260
  domain = filter_domain
255
261
  db_domain = Domain.query.filter(Domain.domain == domain).first() or Domain(
@@ -340,7 +346,7 @@ def get_common_data(user_uuid, mode, no_domain=False, filter_domain=None):
340
346
  'hconfigs': get_hconfigs(),
341
347
  'hdomains': get_hdomains(),
342
348
  'ConfigEnum': ConfigEnum,
343
- 'link_maker': link_maker,
349
+ 'link_maker': hutils.proxy,
344
350
  'domains': domains,
345
351
  "bot": g.get('bot', None),
346
352
  "db_domain": db_domain,
@@ -9,15 +9,13 @@
9
9
  {% block nav_bar %}
10
10
  {% include "donation.html" %}
11
11
  <!-- Navbar -->
12
- <nav class="main-header hold-transition sidebar-mini-md navbar navbar-expand {{" navbar-dark" if g.darkmode
13
- else "bg-white navbar-light" }} border-bottom">
12
+ <nav class="main-header hold-transition sidebar-mini-md navbar navbar-expand {{" navbar-dark" if g.darkmode else "bg-white navbar-light" }} border-bottom">
14
13
  <!-- Left navbar links -->
15
14
 
16
15
 
17
16
 
18
17
  <div class="navbar-nav">
19
- <a class="nav-link" data-widget="pushmenu" href="#"><i class="fa fa-bars"></i> <span
20
- class="brand-text font-weight-light">{{_("master.page-title")}}
18
+ <a class="nav-link" data-widget="pushmenu" href="#"><i class="fa fa-bars"></i> <span class="brand-text font-weight-light">{{_("master.page-title")}}
21
19
  <!-- <span class="badge d-none d-sm-inline-block">{{version}}</span> -->
22
20
  {% if hconfig(ConfigEnum.is_parent) %}
23
21
  {{_("Parent Panel")}}
@@ -26,8 +24,7 @@
26
24
  {% endif %}
27
25
  </a>
28
26
  <a class="nav-link" href="https://github.com/hiddify/Hiddify-Manager/" target="_blank">
29
- <img alt="GitHub Repo stars"
30
- src="https://img.shields.io/github/stars/hiddify/hiddify-manager?style=social&logo=star&label=%E2%AD%90">
27
+ <img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/hiddify/hiddify-manager?style=social&logo=star&label=%E2%AD%90">
31
28
 
32
29
  </a>
33
30
  </div>
@@ -44,8 +41,7 @@
44
41
  {% if 0 and not hconfig(ConfigEnum.is_parent) %}
45
42
 
46
43
 
47
- <a class="nav-link btn btn-outline-secondary form_post d-none d-md-flex"
48
- href="{{hurl_for('admin.Actions:apply_configs')}}">
44
+ <a class="nav-link btn btn-outline-secondary form_post d-none d-md-flex" href="{{hurl_for('admin.Actions:apply_configs')}}">
49
45
  {{icon('solid','bolt','nav-icon')}} {{_('admin.Actions:apply_configs')}}
50
46
  </a>
51
47
 
@@ -62,10 +58,8 @@
62
58
  <aside id="main-sidebar" class="main-sidebar {{ " sidebar-dark-primary"}} elevation-4">
63
59
  <!-- Brand Logo -->
64
60
 
65
- <a href="https://github.com/hiddify/hiddify-manager/wiki" class=""
66
- style="text-align: center; color: white;display: block;">
67
- <img src="{{static_url_for(filename='images/WhiteLogo.png')}}" class=" "
68
- style="width: 50%;opacity: .8;margin: auto;display:block" />
61
+ <a href="https://github.com/hiddify/hiddify-manager/wiki" class="" style="text-align: center; color: white;display: block;">
62
+ <img src="{{static_url_for(filename='images/WhiteLogo.png')}}" class=" " style="width: 50%;opacity: .8;margin: auto;display:block" />
69
63
  <div class="ltr" style="font-size: 8pt;">{{version}}</div>
70
64
  {% if False and hconfig(ConfigEnum.is_parent) %}
71
65
  <br>
@@ -113,8 +107,7 @@
113
107
  request.endpoint or "Dashboard" in request.endpoint) else True %}
114
108
  <li class="nav-item {{'menu-open' if settings_active else ''}}">
115
109
 
116
- <a id=href="#" data-target="#setting-sidebar"
117
- class="nav-link">{{icon('solid','gear','nav-icon')+_('admin.menu.config')}}</a>
110
+ <a id=href="#" data-target="#setting-sidebar" class="nav-link">{{icon('solid','gear','nav-icon')+_('admin.menu.config')}}</a>
118
111
 
119
112
  </li>
120
113
  {% endif %}
@@ -129,21 +122,17 @@
129
122
  {% if g.account.mode=="super_admin" %}
130
123
  <li class="nav-item {{'menu-open' if action_active else ''}}">
131
124
 
132
- <a id=href="#" data-target="#action-sidebar"
133
- class="nav-link">{{icon('solid','suitcase','nav-icon')+_('admin.actions.title')}} <i
134
- class="right fas fa-angle-left"></i></a>
125
+ <a id=href="#" data-target="#action-sidebar" class="nav-link">{{icon('solid','suitcase','nav-icon')+_('admin.actions.title')}} <i class="right fas fa-angle-left"></i></a>
135
126
 
136
127
  </li>
137
128
  {% endif %}
138
129
 
139
130
  <li class="nav-item">
140
131
  <a href="https://github.com/hiddify/hiddify-manager/wiki/{{'%D9%87%D9%85%D9%87-%D8%A2%D9%85%D9%88%D8%B2%D8%B4%E2%80%8C%D9%87%D8%A7-%D9%88-%D9%88%DB%8C%D8%AF%D8%A6%D9%88%D9%87%D8%A7' if get_locale()=='fa' else 'All-tutorials-and-videos'}}"
141
- target="_blank"
142
- class=" nav-link">{{icon('solid','circle-question','nav-icon')+_('admin.menu.support')}}</a>
132
+ target="_blank" class=" nav-link">{{icon('solid','circle-question','nav-icon')+_('admin.menu.support')}}</a>
143
133
  </li>
144
134
  <li class="nav-item d-none">
145
- <a href="https://t.me/hiddify" target="_blank"
146
- class="nav-link">{{icon('brands','telegram','nav-icon')+_('admin.menu.telegram')}}</a>
135
+ <a href="https://t.me/hiddify" target="_blank" class="nav-link">{{icon('brands','telegram','nav-icon')+_('admin.menu.telegram')}}</a>
147
136
  </li>
148
137
  <li class="nav-item">
149
138
  {% set issue_link = generate_github_issue_link_for_admin_sidebar() %}
@@ -202,12 +191,11 @@
202
191
  {{ render_nav_item('admin.ProxyAdmin:index',
203
192
  icon('solid','arrow-down-up-lock','nav-icon')+_('admin.menu.proxy'),_use_li=True) }}
204
193
  {% if g.account.mode=='super_admin' %}
205
- {{ render_nav_item('admin.SettingAdmin:index',icon('solid','gear','nav-icon')+
194
+ {{ render_nav_item('admin.SettingAdmin:index',icon('solid','gears','nav-icon')+
206
195
  _('admin.menu.config'),_use_li=True) }}
207
-
208
-
209
196
  {{ render_nav_item('admin.Backup:index',icon('solid','floppy-disk','nav-icon')+ _('Backup'), _use_li=True) }}
210
197
  {% endif %}
198
+
211
199
  {% if hconfig(ConfigEnum.telegram_bot_token) and g.bot %}
212
200
  {{ render_nav_item("tg://resolve?domain="+g.bot.username+"&start=admin_"+g.account.uuid,
213
201
  icon('brands','telegram','nav-icon')+_('Telegram Bot'),_use_li=True) }}
@@ -217,6 +205,10 @@
217
205
  {{ render_nav_item('openapi.docs', icon('solid','code','nav-icon')+_('admin.menu.api'),_use_li=True) }}
218
206
  {% endif %}
219
207
 
208
+ {% if g.account.mode=="super_admin" %}
209
+ {{ render_nav_item(proxy_stats_url()+"#/proxies", icon('solid','feed','nav-icon')+_('admin.menu.proxy_stats'),_use_li=True) }}
210
+ {% endif %}
211
+
220
212
  </div>
221
213
  </ul>
222
214
  </nav>