hiddifypanel 10.80.0__py3-none-any.whl → 10.80.0.dev1__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 (69) hide show
  1. hiddifypanel/VERSION +1 -1
  2. hiddifypanel/VERSION.py +1 -1
  3. hiddifypanel/base.py +129 -43
  4. hiddifypanel/cache.py +1 -1
  5. hiddifypanel/database.py +0 -7
  6. hiddifypanel/hutils/flask.py +3 -3
  7. hiddifypanel/hutils/proxy/__init__.py +0 -1
  8. hiddifypanel/hutils/proxy/clash.py +2 -2
  9. hiddifypanel/hutils/proxy/shared.py +6 -6
  10. hiddifypanel/hutils/proxy/singbox.py +1 -1
  11. hiddifypanel/hutils/proxy/xray.py +2 -2
  12. hiddifypanel/hutils/proxy/xrayjson.py +7 -10
  13. hiddifypanel/models/config.py +1 -4
  14. hiddifypanel/models/config_enum.py +2 -2
  15. hiddifypanel/models/proxy.py +1 -1
  16. hiddifypanel/panel/__init__.py +8 -8
  17. hiddifypanel/panel/admin/AdminstratorAdmin.py +8 -7
  18. hiddifypanel/panel/admin/DomainAdmin.py +98 -132
  19. hiddifypanel/panel/admin/QuickSetup.py +8 -8
  20. hiddifypanel/panel/admin/UserAdmin.py +33 -58
  21. hiddifypanel/panel/admin/templates/index.html +4 -6
  22. hiddifypanel/panel/admin/templates/model/user_list.html +3 -11
  23. hiddifypanel/panel/cli.py +2 -11
  24. hiddifypanel/panel/commercial/restapi/v1/tgbot.py +1 -19
  25. hiddifypanel/panel/commercial/restapi/v2/admin/system_actions.py +1 -5
  26. hiddifypanel/panel/commercial/restapi/v2/admin/user_api.py +1 -2
  27. hiddifypanel/panel/common.py +1 -1
  28. hiddifypanel/panel/init_db.py +16 -19
  29. hiddifypanel/panel/usage.py +3 -13
  30. hiddifypanel/panel/user/user.py +18 -12
  31. hiddifypanel/templates/fake.html +320 -0
  32. hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
  33. hiddifypanel/translations/en/LC_MESSAGES/messages.po +13 -82
  34. hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
  35. hiddifypanel/translations/fa/LC_MESSAGES/messages.po +12 -81
  36. hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
  37. hiddifypanel/translations/pt/LC_MESSAGES/messages.po +4 -73
  38. hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
  39. hiddifypanel/translations/ru/LC_MESSAGES/messages.po +9 -79
  40. hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
  41. hiddifypanel/translations/zh/LC_MESSAGES/messages.po +4 -73
  42. hiddifypanel/translations.i18n/en.json +7 -50
  43. hiddifypanel/translations.i18n/fa.json +6 -49
  44. hiddifypanel/translations.i18n/fr.json +2 -2
  45. hiddifypanel/translations.i18n/my.json +2 -2
  46. hiddifypanel/translations.i18n/pt.json +4 -47
  47. hiddifypanel/translations.i18n/ru.json +7 -50
  48. hiddifypanel/translations.i18n/zh.json +4 -47
  49. {hiddifypanel-10.80.0.dist-info → hiddifypanel-10.80.0.dev1.dist-info}/METADATA +6 -13
  50. {hiddifypanel-10.80.0.dist-info → hiddifypanel-10.80.0.dev1.dist-info}/RECORD +53 -69
  51. hiddifypanel/apps/__init__.py +0 -0
  52. hiddifypanel/apps/asgi_app.py +0 -7
  53. hiddifypanel/apps/celery_app.py +0 -3
  54. hiddifypanel/apps/wsgi_app.py +0 -5
  55. hiddifypanel/base_setup.py +0 -82
  56. hiddifypanel/celery.py +0 -45
  57. hiddifypanel/hutils/proxy/wireguard.py +0 -34
  58. hiddifypanel/panel/hlogger.py +0 -32
  59. hiddifypanel/panel/node/__init__.py +0 -9
  60. hiddifypanel/panel/node/a.py +0 -14
  61. hiddifypanel/panel/node/hello.py +0 -14
  62. hiddifypanel/panel/node/test.proto +0 -13
  63. hiddifypanel/panel/node/test_grpc.py +0 -40
  64. hiddifypanel/panel/node/test_pb2.py +0 -40
  65. hiddifypanel/panel/node/test_pb2.pyi +0 -17
  66. hiddifypanel/panel/node/test_pb2_grpc.py +0 -97
  67. {hiddifypanel-10.80.0.dist-info → hiddifypanel-10.80.0.dev1.dist-info}/LICENSE.md +0 -0
  68. {hiddifypanel-10.80.0.dist-info → hiddifypanel-10.80.0.dev1.dist-info}/WHEEL +0 -0
  69. {hiddifypanel-10.80.0.dist-info → hiddifypanel-10.80.0.dev1.dist-info}/entry_points.txt +0 -0
hiddifypanel/VERSION CHANGED
@@ -1 +1 @@
1
- 10.80.0
1
+ 10.80.0.dev7
hiddifypanel/VERSION.py CHANGED
@@ -2,5 +2,5 @@ import importlib.metadata
2
2
  from datetime import datetime
3
3
 
4
4
  __version__ = importlib.metadata.version(__package__ or __name__)
5
- __release_time__= datetime.strptime('2024-12-15T04:01:06','%Y-%m-%dT%H:%M:%S')
5
+ __release_time__= datetime.strptime('2024-11-10T19:45:21','%Y-%m-%dT%H:%M:%S')
6
6
  is_released_version=True
hiddifypanel/base.py CHANGED
@@ -1,7 +1,11 @@
1
1
  from flask import request, g
2
2
  # from hiddifypanel.cache import cache
3
+ from hiddifypanel.models import *
3
4
 
4
-
5
+ import flask_bootstrap
6
+ import hiddifypanel
7
+ from flask_babel import Babel
8
+ from flask_session import Session
5
9
 
6
10
  import datetime
7
11
 
@@ -9,54 +13,138 @@ from dotenv import dotenv_values
9
13
  import os
10
14
  import sys
11
15
  from apiflask import APIFlask
16
+ from werkzeug.middleware.proxy_fix import ProxyFix
12
17
  from loguru import logger
18
+ from hiddifypanel.panel.init_db import init_db
19
+
20
+
21
+ def logger_dynamic_formatter(record) -> str:
22
+ fmt = '<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>'
23
+ if record['extra']:
24
+ fmt += ' | <level>{extra}</level>'
25
+ return fmt + '\n'
13
26
 
14
27
 
15
- from dynaconf import FlaskDynaconf
28
+ def init_logger(app, cli):
29
+ # configure logger
30
+ logger.remove()
31
+ logger.add(sys.stderr if cli else sys.stdout, format=logger_dynamic_formatter, level=app.config['STDOUT_LOG_LEVEL'],
32
+ colorize=True, catch=True, enqueue=True, diagnose=False, backtrace=True)
33
+ logger.trace('Logger initiated :)')
34
+
35
+
36
+ # TODO: refactor this function
16
37
 
17
38
  def create_app(*args, cli=False, **config):
18
39
 
19
40
  app = APIFlask(__name__, static_url_path="/<proxy_path>/static/", instance_relative_config=True, version='2.2.0', title="Hiddify API",
20
41
  openapi_blueprint_url_prefix="/<proxy_path>/api", docs_ui='elements', json_errors=False, enable_openapi=not cli)
21
42
  # app = Flask(__name__, static_url_path="/<proxy_path>/static/", instance_relative_config=True)
22
- # app.asgi_app = WsgiToAsgi(app)
23
-
43
+
44
+ if not cli:
45
+
46
+ from hiddifypanel import auth
47
+ app.config["PREFERRED_URL_SCHEME"] = "https"
48
+ app.wsgi_app = ProxyFix(
49
+ app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1,
50
+ )
51
+ app.secret_key="asdsad"
52
+ app.servers = {
53
+ 'name': 'current',
54
+ 'url': '',
55
+ } # type: ignore
56
+ app.info = {
57
+ 'description': 'Hiddify is a free and open source software. It is as it is.',
58
+ 'termsOfService': 'https://hiddify.com',
59
+ 'contact': {
60
+ 'name': 'API Support',
61
+ 'url': 'https://www.hiddify.com/support',
62
+ 'email': 'panel@hiddify.com'
63
+ },
64
+ 'license': {
65
+ 'name': 'Creative Commons Zero v1.0 Universal',
66
+ 'url': 'https://github.com/hiddify/Hiddify-Manager/blob/main/LICENSE'
67
+ }
68
+ }
69
+ # setup flask server-side session
70
+ # app.config['APPLICATION_ROOT'] = './'
71
+ # app.config['SESSION_COOKIE_DOMAIN'] = '/'
72
+
73
+
74
+ app.jinja_env.line_statement_prefix = '%'
75
+ from hiddifypanel import hutils
76
+ app.jinja_env.filters['b64encode'] = hutils.encode.do_base_64
77
+ app.view_functions['admin.static'] = {} # fix bug in apiflask
78
+ flask_bootstrap.Bootstrap4(app)
79
+
24
80
  for c, v in dotenv_values(os.environ.get("HIDDIFY_CFG_PATH", 'app.cfg')).items():
25
81
  if v.isdecimal():
26
82
  v = int(v)
27
83
  else:
28
84
  v = True if v.lower() == "true" else (False if v.lower() == "false" else v)
29
- app.config[c] = v
30
- dyn=FlaskDynaconf(app,settings_files=[os.environ.get("HIDDIFY_CFG_PATH", 'app.cfg')])
31
-
32
- if cli:
33
- app.config['EXTENSIONS']=[
34
- # "hiddifypanel.cache:init_app",
35
- "hiddifypanel.database:init_app",
36
- "hiddifypanel.panel.hlogger:init_cli",
37
- "hiddifypanel.panel.cli:init_app",
38
- "hiddifypanel.celery:init_app",
39
- ]
40
- else:
41
- app.config['EXTENSIONS']=[
42
- # "hiddifypanel.cache:init_app",
43
- "hiddifypanel.database:init_app",
44
- "hiddifypanel.panel.hlogger:init_app",
45
- "hiddifypanel.base_setup:init_app",
46
- "hiddifypanel.panel.common:init_app",
47
- "hiddifypanel.panel.common_bp:init_app",
48
- "hiddifypanel.panel.admin:init_app",
49
- "hiddifypanel.panel.user:init_app",
50
- "hiddifypanel.panel.commercial:init_app",
51
- "hiddifypanel.panel.node:init_app",
52
- "hiddifypanel.celery:init_app",
53
- ]
54
-
55
85
 
86
+ app.config[c] = v
87
+ init_logger(app, cli)
88
+ hiddifypanel.database.init_app(app)
89
+ with app.app_context():
90
+ init_db()
91
+ logger.add(app.config['HIDDIFY_CONFIG_PATH'] + "/log/system/panel.log", format=logger_dynamic_formatter, level=hconfig(ConfigEnum.log_level),
92
+ colorize=True, catch=True, enqueue=True, diagnose=False, backtrace=True)
93
+
94
+ def get_locale():
95
+ # Put your logic here. Application can store locale in
96
+ # user profile, cookie, session, etc.
97
+ if "admin" in request.base_url:
98
+ g.locale = hconfig(ConfigEnum.admin_lang) or 'en'
99
+ else:
100
+ g.locale = auth.current_account.lang or hconfig(ConfigEnum.lang) or 'en'
101
+ return g.locale
102
+ app.jinja_env.globals['get_locale'] = get_locale
103
+ babel = Babel(app, locale_selector=get_locale)
104
+ if not cli:
105
+ app.config['SESSION_TYPE'] = 'redis'
106
+ from hiddifypanel.cache import redis_client
107
+ app.config['SESSION_REDIS'] = redis_client
108
+ app.config['SESSION_PERMANENT'] = True
109
+ app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(days=10)
110
+ app.security_schemes = { # equals to use config SECURITY_SCHEMES
111
+ 'Hiddify-API-Key': {
112
+ 'type': 'apiKey',
113
+ 'in': 'header',
114
+ 'name': 'Hiddify-API-Key',
115
+ }
116
+ }
117
+ Session(app)
118
+ hiddifypanel.panel.common.init_app(app)
119
+ hiddifypanel.panel.common_bp.init_app(app)
120
+
121
+ from hiddifypanel.panel import user, commercial, admin
122
+ admin.init_app(app)
123
+ user.init_app(app)
124
+ commercial.init_app(app)
56
125
 
57
126
  app.config.update(config) # Override with passed config
58
-
59
- app.config.load_extensions("EXTENSIONS")
127
+ # app.config['WTF_CSRF_CHECK_DEFAULT'] = False
128
+ # app.config['WTF_CSRF_ENABLED'] = False
129
+ # app.config['BABEL_TRANSLATION_DIRECTORIES'] = '/workspace/Hiddify-Server/hiddify-panel/src/translations.i18n'
130
+
131
+ # from flask_wtf.csrf import CSRFProtect
132
+
133
+ # csrf = CSRFProtect(app)
134
+
135
+ # @app.before_request
136
+ # def check_csrf():
137
+ # # if "/admin/user/" in request.base_url:
138
+ # # return
139
+ # # if "/admin/domain/" in request.base_url:
140
+ # # return
141
+ # # if "/admin/actions/" in request.base_url:
142
+ # # return
143
+ # # if "/api/" in request.base_url:
144
+ # # return
145
+ # csrf.protect()
146
+
147
+ hiddifypanel.panel.cli.init_app(app)
60
148
  return app
61
149
 
62
150
 
@@ -65,18 +153,16 @@ def create_app_wsgi(*args, **kwargs):
65
153
  # that doesn't allow **config
66
154
  # to be passed to create_app
67
155
  # https://github.com/pallets/flask/issues/4170
68
- cli = ("hiddifypanel" in sys.argv[0] ) or (sys.argv[1] in ["update-usage", "all-configs", "admin_links", "admin_path"])
69
-
156
+ cli = ("hiddifypanel" in sys.argv[0]) or (sys.argv[1] in ["update-usage", "all-configs", "admin_links", "admin_path"])
70
157
  app = create_app(cli=cli)
71
158
  return app
72
159
 
73
160
 
74
-
75
- def create_celery_app():
76
- # # workaround for Flask issue
77
- # # that doesn't allow **config
78
- # # to be passed to create_app
79
- # # https://github.com/pallets/flask/issues/4170
80
- # print(kwargs)
81
- app = create_app(cli=True)
82
- return app.extensions["celery"]
161
+ # def create_cli_app(*args, **kwargs):
162
+ # # # workaround for Flask issue
163
+ # # # that doesn't allow **config
164
+ # # # to be passed to create_app
165
+ # # # https://github.com/pallets/flask/issues/4170
166
+ # # print(kwargs)
167
+ # app = create_app(*args, cli=True, **kwargs)
168
+ # return app
hiddifypanel/cache.py CHANGED
@@ -5,7 +5,7 @@ from pickle import dumps, loads
5
5
  from loguru import logger
6
6
 
7
7
  redis_client = redis.from_url(os.environ["REDIS_URI_MAIN"])
8
- # print(os.environ["REDIS_URI_MAIN"])
8
+
9
9
 
10
10
  class CustomRedisCache(RedisCache):
11
11
  def __init__(self, redis_client, prefix="rc", serializer=compact_dump, deserializer=loads, key_serializer=None, support_cluster=True, exception_handler=None):
hiddifypanel/database.py CHANGED
@@ -6,9 +6,6 @@ import os
6
6
  from sqlalchemy import Row, text, Sequence
7
7
 
8
8
 
9
-
10
-
11
-
12
9
  db: SQLAlchemy = SQLAlchemy()
13
10
  db.UUID = UUIDType # type: ignore
14
11
 
@@ -16,10 +13,6 @@ db.UUID = UUIDType # type: ignore
16
13
  def init_app(app):
17
14
  app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
18
15
  db.init_app(app)
19
- with app.app_context():
20
- from hiddifypanel.panel.init_db import init_db
21
- init_db()
22
-
23
16
 
24
17
 
25
18
  def db_execute(query: str, return_val: bool = False, commit: bool = False, **params: dict):
@@ -51,7 +51,7 @@ def hurl_for(endpoint, **values):
51
51
  def get_user_agent() -> dict:
52
52
  ua = __parse_user_agent(request.user_agent.string)
53
53
 
54
- if ua.get('v', 1) < 9:
54
+ if ua.get('v', 1) < 8:
55
55
  __parse_user_agent.invalidate_all() # type:ignore
56
56
  ua = __parse_user_agent(request.user_agent.string)
57
57
  return ua
@@ -66,13 +66,13 @@ def __parse_user_agent(ua: str) -> dict:
66
66
  # Example: SFA/1.7.0 (239; sing-box 1.7.0)
67
67
  # Example: HiddifyNext/0.13.6 (android) like ClashMeta v2ray sing-box
68
68
  if ua=="v2rayNG/1.8.23": #temporary fix for xray sub in hiddifynext
69
- ua="HiddifyNextX/3.0.0 (android) like ClashMeta v2ray sing-box"
69
+ ua="HiddifyNextX/0.13.6 (android) like ClashMeta v2ray sing-box"
70
70
  uaa = user_agents.parse(ua)
71
71
 
72
72
  match = re.search(ua_version_pattern, ua)
73
73
  generic_version = list(map(int, match.group(1).split('.'))) if match else [0, 0, 0]
74
74
  res = {}
75
- res['v'] = 9
75
+ res['v'] = 8
76
76
  res["is_bot"] = uaa.is_bot
77
77
  res["is_browser"] = re.match('^Mozilla', ua, re.IGNORECASE) and True
78
78
  res['os'] = uaa.os.family
@@ -3,4 +3,3 @@ from . import xray
3
3
  from . import xrayjson
4
4
  from . import singbox
5
5
  from . import clash
6
- from . import wireguard
@@ -33,7 +33,7 @@ def to_clash(proxy, meta_or_normal):
33
33
 
34
34
  if proxy['l3'] in ["kcp", ProxyL3.h3_quic]:
35
35
  return {'name': name, 'msg': f"clash does not support {proxy['l3']}", 'type': 'debug'}
36
- if proxy['transport'] in [ProxyTransport.xhttp, ProxyTransport.httpupgrade]:
36
+ if proxy['transport'] in [ProxyTransport.splithttp, ProxyTransport.httpupgrade]:
37
37
  return {'name': name, 'msg': f"clash does not support {proxy['transport']}", 'type': 'debug'}
38
38
  # if proxy['proto'] in [Proxy.shado]:
39
39
 
@@ -44,7 +44,7 @@ def to_clash(proxy, meta_or_normal):
44
44
  return {'name': name, 'msg': f"clash does not support {proxy['proto']}", 'type': 'debug'}
45
45
  if proxy['proto'] in ["vless", 'tuic', 'hysteria2']:
46
46
  return {'name': name, 'msg': f"{proxy['proto']} not supported in clash", 'type': 'debug'}
47
- if proxy['transport'] in ["shadowtls", "xhttp"]:
47
+ if proxy['transport'] in ["shadowtls", "splithttp"]:
48
48
  return {'name': name, 'msg': f"{proxy['transport']} not supported in clash", 'type': 'debug'}
49
49
  if proxy['l3'] == ProxyL3.tls_h2 and proxy['proto'] in [ProxyProto.vmess, ProxyProto.vless] and proxy['dbe'].cdn == ProxyCDN.direct:
50
50
  return {'name': name, 'msg': "bug tls_h2 vmess and vless in clash meta", 'type': 'warning'}
@@ -134,8 +134,8 @@ def get_proxies(child_id: int = 0, only_enabled=False) -> list['Proxy']:
134
134
  proxies = [c for c in proxies if 'trojan' not in c.proto]
135
135
  if not hconfig(ConfigEnum.httpupgrade_enable, child_id):
136
136
  proxies = [c for c in proxies if ProxyTransport.httpupgrade not in c.transport]
137
- if not hconfig(ConfigEnum.xhttp_enable, child_id):
138
- proxies = [c for c in proxies if ProxyTransport.xhttp not in c.transport]
137
+ if not hconfig(ConfigEnum.splithttp_enable, child_id):
138
+ proxies = [c for c in proxies if ProxyTransport.splithttp not in c.transport]
139
139
  if not hconfig(ConfigEnum.ws_enable, child_id):
140
140
  proxies = [c for c in proxies if ProxyTransport.WS not in c.transport]
141
141
  # if not hconfig(ConfigEnum.xtls_enable, child_id):
@@ -189,7 +189,7 @@ def get_valid_proxies(domains: list[Domain]) -> list[dict]:
189
189
  noDomainProxies = False
190
190
  if proxy.proto in [ProxyProto.ssh, ProxyProto.wireguard]:
191
191
  noDomainProxies = True
192
- if proxy.proto in [ProxyProto.ss] and proxy.transport not in [ProxyTransport.grpc, ProxyTransport.h2, ProxyTransport.WS, ProxyTransport.httpupgrade, ProxyTransport.xhttp]:
192
+ if proxy.proto in [ProxyProto.ss] and proxy.transport not in [ProxyTransport.grpc, ProxyTransport.h2, ProxyTransport.WS, ProxyTransport.httpupgrade, ProxyTransport.splithttp]:
193
193
  noDomainProxies = True
194
194
  options = []
195
195
  key = f'{proxy.proto}{proxy.transport}{proxy.cdn}{proxy.l3}'
@@ -413,9 +413,9 @@ def make_proxy(hconfigs: dict, proxy: Proxy, domain_db: Domain, phttp=80, ptls=4
413
413
  base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_httpupgrade]}'
414
414
  base["host"] = domain
415
415
  return base
416
- if proxy.transport in [ProxyTransport.xhttp]:
417
- base['transport'] = 'xhttp'
418
- base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_xhttp]}'
416
+ if proxy.transport in [ProxyTransport.splithttp]:
417
+ base['transport'] = 'splithttp'
418
+ base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_splithttp]}'
419
419
  # if 0 and 'h2' in base['alpn'] or 'h3' in base['alpn']:
420
420
  # base['path'] += "2"
421
421
  # else:
@@ -47,7 +47,7 @@ def configs_as_json(domains: list[Domain], **kwargs) -> str:
47
47
  def is_xray_proxy(proxy: dict):
48
48
  if g.user_agent.get('is_hiddify_prefere_xray'):
49
49
  return True
50
- if proxy['transport'] == ProxyTransport.xhttp:
50
+ if proxy['transport'] == ProxyTransport.splithttp:
51
51
  return True
52
52
  return False
53
53
 
@@ -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.xhttp}:
129
+ if proxy.get('transport') in {ProxyTransport.splithttp}:
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.xhttp}) and proxy['proto'] in [ProxyProto.vless, ProxyProto.trojan]:
132
+ if proxy.get('l3') != ProxyL3.reality and (proxy.get('transport') in {ProxyTransport.tcp, ProxyTransport.httpupgrade, ProxyTransport.splithttp}) and proxy['proto'] in [ProxyProto.vless, ProxyProto.trojan]:
133
133
  baseurl += '&headerType=http'
134
134
  else:
135
135
  baseurl += '&headerType=None'
@@ -50,11 +50,10 @@ 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 = { ProxyProto.hysteria, ProxyProto.hysteria2,
54
- ProxyProto.tuic, ProxyProto.ssr, ProxyProto.ssh}
53
+ unsupported_protos = {ProxyProto.wireguard, ProxyProto.hysteria, ProxyProto.hysteria2,
54
+ ProxyProto.tuic, ProxyProto.ss, 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})
58
57
 
59
58
  # multiple outbounds needs multiple whole base config not just one with multiple outbounds (at least for v2rayng)
60
59
  # https://github.com/2dust/v2rayNG/pull/2827#issue-2127534078
@@ -136,9 +135,7 @@ def add_wireguard_settings(base: dict, proxy: dict):
136
135
  base['settings']['mtu'] = 1380 # optional
137
136
  base['settings']['peers'] = [{
138
137
  'endpoint': f'{proxy["server"]}:{int(proxy["port"])}',
139
- 'publicKey': proxy["wg_server_pub"],
140
- "preSharedKey": proxy['wg_psk']
141
-
138
+ 'publicKey': proxy["wg_server_pub"]
142
139
  # 'allowedIPs':'', 'preSharedKey':'', 'keepAlive':'' # optionals
143
140
  }]
144
141
 
@@ -265,9 +262,9 @@ def add_stream_settings(base: dict, proxy: dict):
265
262
  if proxy['transport'] == ProxyTransport.httpupgrade:
266
263
  ss['network'] = proxy['transport']
267
264
  add_httpupgrade_stream(ss, proxy)
268
- if proxy['transport'] == ProxyTransport.xhttp:
265
+ if proxy['transport'] == ProxyTransport.splithttp:
269
266
  ss['network'] = proxy['transport']
270
- add_xhttp_stream(ss, proxy)
267
+ add_splithttp_stream(ss, proxy)
271
268
  if proxy['transport'] == 'ws':
272
269
  ss['network'] = proxy['transport']
273
270
  add_ws_stream(ss, proxy)
@@ -341,8 +338,8 @@ def add_httpupgrade_stream(ss: dict, proxy: dict):
341
338
  }
342
339
 
343
340
 
344
- def add_xhttp_stream(ss: dict, proxy: dict):
345
- ss['xhttpSettings'] = {
341
+ def add_splithttp_stream(ss: dict, proxy: dict):
342
+ ss['splithttpSettings'] = {
346
343
  'path': proxy['path'],
347
344
  'host': proxy['host'],
348
345
  "headers": {
@@ -153,10 +153,7 @@ 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
- try:
157
- ckey = ConfigEnum(c)
158
- except:
159
- return
156
+ ckey = ConfigEnum(c)
160
157
  if c == ConfigEnum.unique_id and not override_unique_id:
161
158
  return
162
159
 
@@ -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
- xhttp_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply_config)
242
+ splithttp_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
- path_xhttp = _StrConfigDscr(ConfigCategory.too_advanced, ApplyMode.apply_config, hide_in_virtual_child=True)
265
+ path_splithttp = _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)
@@ -20,7 +20,7 @@ class ProxyTransport(StrEnum):
20
20
  tcp = auto()
21
21
  ssh = auto()
22
22
  httpupgrade = auto()
23
- xhttp = auto()
23
+ splithttp = auto()
24
24
  custom = auto()
25
25
  shadowsocks = auto()
26
26
 
@@ -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
@@ -143,18 +143,19 @@ class AdminstratorAdmin(AdminLTEModelView):
143
143
  """)
144
144
 
145
145
  def _max_active_users_formatter(view, context, model, name):
146
- """Optimized user count formatter using database queries"""
147
- active_count = model.recursive_users_query().filter(User.is_active == True).count()
146
+
147
+ actives = [u for u in model.recursive_users_query().all() if u.is_active]
148
+ u = len(actives)
148
149
  if model.mode == AdminMode.super_admin:
149
- return f"{active_count} / ∞"
150
+ return f"{u} / ∞"
150
151
  t = model.max_active_users
151
- rate = round(active_count * 100 / (t + 0.000001))
152
- color = "#ff7e7e" if active_count >= t else ('#ffc107' if rate > 80 else '#9ee150')
153
-
152
+ rate = round(u * 100 / (t + 0.000001))
153
+ state = "danger" if u >= t else ('warning' if rate > 80 else 'success')
154
+ color = "#ff7e7e" if u >= t else ('#ffc107' if rate > 80 else '#9ee150')
154
155
  return Markup(f"""
155
156
  <div class="progress progress-lg position-relative" style="min-width: 100px;">
156
157
  <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">{active_count} {_('user.home.usage.from')} {t}</span>
158
+ <span class='badge position-absolute' style="left:auto;right:auto;width: 100%;font-size:1em">{u} {_('user.home.usage.from')} {t}</span>
158
159
 
159
160
  </div>
160
161
  """)