hiddifypanel 9.0.0.dev60__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 -169
- hiddifypanel/models/__init__.py +1 -0
- hiddifypanel/models/admin.py +53 -8
- hiddifypanel/models/base_account.py +31 -169
- 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/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 +13 -11
- hiddifypanel/panel/admin/UserAdmin.py +13 -12
- hiddifypanel/panel/auth.py +42 -9
- 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/tgmsg.py +1 -1
- hiddifypanel/panel/commercial/restapi/v2/user/apps_api.py +5 -4
- hiddifypanel/panel/commercial/restapi/v2/user/info_api.py +7 -11
- hiddifypanel/panel/commercial/telegrambot/admin.py +1 -0
- hiddifypanel/panel/common.py +10 -86
- hiddifypanel/panel/common_bp/login.py +9 -8
- hiddifypanel/panel/database.py +22 -21
- hiddifypanel/panel/hiddify.py +25 -28
- hiddifypanel/panel/importer/xui.py +2 -2
- hiddifypanel/panel/init_db.py +20 -13
- hiddifypanel/panel/usage.py +2 -1
- hiddifypanel/panel/user/link_maker.py +118 -15
- hiddifypanel/panel/user/user.py +25 -19
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +252 -234
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +280 -228
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +240 -207
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +240 -207
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +779 -2740
- {hiddifypanel-9.0.0.dev60.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/METADATA +2 -1
- {hiddifypanel-9.0.0.dev60.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/RECORD +63 -57
- {hiddifypanel-9.0.0.dev60.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/LICENSE.md +0 -0
- {hiddifypanel-9.0.0.dev60.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/WHEEL +0 -0
- {hiddifypanel-9.0.0.dev60.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/entry_points.txt +0 -0
- {hiddifypanel-9.0.0.dev60.dist-info → hiddifypanel-9.0.0.dev61.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@ from apiflask import Schema
|
|
4
4
|
from apiflask.fields import Integer, String, Float, URL, Enum
|
5
5
|
from flask import g, request
|
6
6
|
from flask import current_app as app
|
7
|
+
from hiddifypanel import hutils
|
7
8
|
from hiddifypanel.panel.auth import login_required
|
8
9
|
import hiddifypanel.panel.auth as auth
|
9
10
|
from flask_babelex import gettext as _
|
@@ -55,11 +56,11 @@ class InfoAPI(MethodView):
|
|
55
56
|
dto.profile_remaining_days = g.account.remaining_days()
|
56
57
|
dto.profile_reset_days = g.account.days_to_reset()
|
57
58
|
dto.telegram_bot_url = f"https://t.me/{c['bot'].username}?start={g.account.uuid}" if c['bot'] else ""
|
58
|
-
dto.telegram_id = c['user'].telegram_id
|
59
|
+
dto.telegram_id = c['user'].telegram_id
|
59
60
|
|
60
61
|
dto.doh = f"https://{request.host}/{g.proxy_path}/dns/dns-query"
|
61
62
|
dto.lang = (c['user'].lang) or Lang(hconfig(ConfigEnum.lang))
|
62
|
-
dto.brand_icon_url = "" if hconfig(ConfigEnum.branding_title) else
|
63
|
+
dto.brand_icon_url = "" if hconfig(ConfigEnum.branding_title) else hutils.flask.static_url_for(filename="images/hiddify.png")
|
63
64
|
# with force_locale("fa"):
|
64
65
|
dto.admin_message_html = hconfig(ConfigEnum.branding_freetext) or _("Join our Hiddify Telegram channel to get the latest updates on Hiddify.")
|
65
66
|
if not hconfig(ConfigEnum.branding_freetext) and auth.admin_session_is_exist():
|
@@ -69,16 +70,11 @@ class InfoAPI(MethodView):
|
|
69
70
|
return dto
|
70
71
|
|
71
72
|
@app.input(UserInfoChangableSchema, arg_name='data')
|
72
|
-
def patch(self, data):
|
73
|
-
if data['telegram_id']:
|
74
|
-
try:
|
75
|
-
tg_id = int(data['telegram_id'])
|
76
|
-
except:
|
77
|
-
return {'message': 'The telegram id field is invalid'}
|
78
|
-
|
73
|
+
def patch(self, data: UserInfoChangableSchema):
|
74
|
+
if data['telegram_id'] and hutils.convert.is_int(data['telegram_id']):
|
79
75
|
user = User.by_uuid(g.account.uuid)
|
80
|
-
if user.telegram_id !=
|
81
|
-
user.telegram_id =
|
76
|
+
if user.telegram_id != data['telegram_id']:
|
77
|
+
user.telegram_id = data['telegram_id']
|
82
78
|
db.session.commit()
|
83
79
|
|
84
80
|
if data['language']:
|
hiddifypanel/panel/common.py
CHANGED
@@ -6,11 +6,10 @@ from flask import g, send_from_directory, session
|
|
6
6
|
from flask_babelex import gettext as _
|
7
7
|
import hiddifypanel
|
8
8
|
from hiddifypanel.models import *
|
9
|
-
from hiddifypanel.panel import hiddify
|
10
|
-
from
|
11
|
-
from platform import platform
|
12
|
-
import hiddifypanel.hutils as hutils
|
9
|
+
from hiddifypanel.panel import hiddify
|
10
|
+
from hiddifypanel import hutils
|
13
11
|
import hiddifypanel.panel.auth as auth
|
12
|
+
from hiddifypanel.panel.auth import current_account
|
14
13
|
from apiflask import APIFlask, HTTPError, abort
|
15
14
|
|
16
15
|
|
@@ -48,7 +47,7 @@ def init_app(app: APIFlask):
|
|
48
47
|
trace = traceback.format_exc()
|
49
48
|
|
50
49
|
# Create github issue link
|
51
|
-
issue_link = generate_github_issue_link_for_500_error(e, trace)
|
50
|
+
issue_link = hutils.github_issue.generate_github_issue_link_for_500_error(e, trace)
|
52
51
|
|
53
52
|
return render_template('500.html', error=e, trace=trace, has_update=has_update, last_version=last_version, issue_link=issue_link), 500
|
54
53
|
|
@@ -61,7 +60,7 @@ def init_app(app: APIFlask):
|
|
61
60
|
trace = traceback.format_exc()
|
62
61
|
|
63
62
|
# Create github issue link
|
64
|
-
issue_link = generate_github_issue_link_for_500_error(e, trace)
|
63
|
+
issue_link = hutils.github_issue.generate_github_issue_link_for_500_error(e, trace)
|
65
64
|
|
66
65
|
last_version = hiddify.get_latest_release_version('hiddify-panel') # TODO: add dev update check
|
67
66
|
if "T" in hiddifypanel.__version__:
|
@@ -75,16 +74,6 @@ def init_app(app: APIFlask):
|
|
75
74
|
|
76
75
|
return render_template('error.html', error=e), e.status_code
|
77
76
|
|
78
|
-
def generate_github_issue_link(title, issue_body):
|
79
|
-
opts = {
|
80
|
-
"user": 'hiddify',
|
81
|
-
"repo": 'Hiddify-Manager',
|
82
|
-
"title": title,
|
83
|
-
"body": issue_body,
|
84
|
-
}
|
85
|
-
issue_link = str(github_issue_generator.IssueUrl(opts).get_url())
|
86
|
-
return issue_link
|
87
|
-
|
88
77
|
# @app.spec_processor
|
89
78
|
# def set_default_path_values(spec):
|
90
79
|
# # for path in spec['paths'].values():
|
@@ -100,7 +89,7 @@ def init_app(app: APIFlask):
|
|
100
89
|
@app.url_defaults
|
101
90
|
def add_proxy_path_user(endpoint, values):
|
102
91
|
if 'proxy_path' not in values:
|
103
|
-
if
|
92
|
+
if hiddify.is_admin_role(g.account):
|
104
93
|
values['proxy_path'] = hconfig(ConfigEnum.proxy_path_admin)
|
105
94
|
# elif 'static' in endpoint:
|
106
95
|
# values['proxy_path'] = hconfig(ConfigEnum.proxy_path)
|
@@ -144,7 +133,7 @@ def init_app(app: APIFlask):
|
|
144
133
|
# if user_agent.is_bot:
|
145
134
|
# abort(400, "invalid")
|
146
135
|
|
147
|
-
# uuid = hutils.
|
136
|
+
# uuid = hutils.auth.get_uuid_from_url_path(request.path)
|
148
137
|
# account = User.by_uuid(uuid) or AdminUser.by_uuid(uuid) or abort(400, 'invalid request2')
|
149
138
|
|
150
139
|
# admin_proxy_path = hconfig(ConfigEnum.proxy_path_admin)
|
@@ -161,7 +150,7 @@ def init_app(app: APIFlask):
|
|
161
150
|
# else:
|
162
151
|
# return abort(400, 'invalid request 1')
|
163
152
|
|
164
|
-
# new_link = hutils.
|
153
|
+
# new_link = hutils.auth.add_basic_auth_to_url(new_link, account.username, account.password)
|
165
154
|
|
166
155
|
# if user_agent.browser:
|
167
156
|
# return render_template('redirect_to_new_format.html', new_link=new_link)
|
@@ -171,6 +160,7 @@ def init_app(app: APIFlask):
|
|
171
160
|
# return redirect(new_link, 302)
|
172
161
|
@app.before_request
|
173
162
|
def set_default_values():
|
163
|
+
g.account = current_account
|
174
164
|
g.user_agent = hiddify.get_user_agent()
|
175
165
|
|
176
166
|
@app.before_request
|
@@ -216,70 +206,4 @@ def init_app(app: APIFlask):
|
|
216
206
|
else:
|
217
207
|
g.bot = None
|
218
208
|
|
219
|
-
|
220
|
-
details = {
|
221
|
-
'hiddify_version': f'{hiddifypanel.__version__}',
|
222
|
-
'python_version': f'{python_version}',
|
223
|
-
'os_details': f'{platform()}',
|
224
|
-
'user_agent': request.user_agent
|
225
|
-
}
|
226
|
-
return details
|
227
|
-
|
228
|
-
def generate_github_issue_link_for_500_error(error, traceback, remove_sensetive_data=True, remove_unrelated_traceback_datails=True):
|
229
|
-
|
230
|
-
def remove_sensetive_data_from_github_issue_link(issue_link):
|
231
|
-
if hasattr(g, 'account') and hasattr(g.account, 'uuid') and g.account.uuid:
|
232
|
-
issue_link.replace(f'{g.account.uuid}', '*******************')
|
233
|
-
|
234
|
-
issue_link.replace(request.host, '**********')
|
235
|
-
issue_link.replace(hconfig(ConfigEnum.proxy_path), '**********')
|
236
|
-
issue_link.replace(hconfig(ConfigEnum.proxy_path_admin), '**********')
|
237
|
-
issue_link.replace(hconfig(ConfigEnum.proxy_path_client), '**********')
|
238
|
-
|
239
|
-
def remove_unrelated_traceback_details(stacktrace: str):
|
240
|
-
lines = stacktrace.splitlines()
|
241
|
-
if len(lines) < 1:
|
242
|
-
return ""
|
243
|
-
|
244
|
-
output = ''
|
245
|
-
skip_next_line = False
|
246
|
-
for i, line in enumerate(lines):
|
247
|
-
if i == 0:
|
248
|
-
output += line + '\n'
|
249
|
-
continue
|
250
|
-
if skip_next_line == True:
|
251
|
-
skip_next_line = False
|
252
|
-
continue
|
253
|
-
if line.strip().startswith('File'):
|
254
|
-
if 'hiddify' in line.lower():
|
255
|
-
output += line + '\n'
|
256
|
-
if len(lines) > i+1:
|
257
|
-
output += lines[i + 1] + '\n'
|
258
|
-
skip_next_line = True
|
259
|
-
|
260
|
-
return output
|
261
|
-
|
262
|
-
if remove_unrelated_traceback_datails:
|
263
|
-
traceback = remove_unrelated_traceback_details(traceback)
|
264
|
-
|
265
|
-
issue_details = github_issue_details()
|
266
|
-
|
267
|
-
issue_body = render_template('github_issue_body.j2', issue_details=issue_details, error=error, traceback=traceback)
|
268
|
-
|
269
|
-
# Create github issue link
|
270
|
-
issue_link = generate_github_issue_link(f"Internal server error: {error.name if hasattr(error,'name') and error.name != None and error.name else 'Unknown'}", issue_body)
|
271
|
-
|
272
|
-
if remove_sensetive_data:
|
273
|
-
remove_sensetive_data_from_github_issue_link(issue_link)
|
274
|
-
|
275
|
-
return issue_link
|
276
|
-
|
277
|
-
def generate_github_issue_link_for_admin_sidebar():
|
278
|
-
|
279
|
-
issue_body = render_template('github_issue_body.j2', issue_details=github_issue_details())
|
280
|
-
|
281
|
-
# Create github issue link
|
282
|
-
issue_link = generate_github_issue_link('Please fill the title properly', issue_body)
|
283
|
-
return issue_link
|
284
|
-
|
285
|
-
app.jinja_env.globals['generate_github_issue_link_for_admin_sidebar'] = generate_github_issue_link_for_admin_sidebar
|
209
|
+
app.jinja_env.globals['generate_github_issue_link_for_admin_sidebar'] = hutils.github_issue.generate_github_issue_link_for_admin_sidebar
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from flask_classful import FlaskView, route
|
2
|
+
from hiddifypanel import hutils
|
2
3
|
from hiddifypanel.panel.auth import login_required, current_account, login_user, logout_user, login_by_uuid
|
3
4
|
from flask import redirect, request, g, url_for, render_template, flash, jsonify
|
4
5
|
from flask import current_app as app
|
@@ -54,7 +55,7 @@ class LoginView(FlaskView):
|
|
54
55
|
uuid = form.secret_textbox.data.strip()
|
55
56
|
if login_by_uuid(uuid, hiddify.is_admin_proxy_path()):
|
56
57
|
return redirect(f'/{g.proxy_path}/')
|
57
|
-
flash(_('config.validation-error'), 'danger')
|
58
|
+
hutils.flask.flash(_('config.validation-error'), 'danger') # type: ignore
|
58
59
|
return render_template('login.html', form=LoginForm())
|
59
60
|
|
60
61
|
@route("/l/")
|
@@ -66,10 +67,10 @@ class LoginView(FlaskView):
|
|
66
67
|
|
67
68
|
loginurl = url_for('common_bp.LoginView:index', next=redirect_arg, user=username)
|
68
69
|
if g.user_agent['is_browser'] and request.headers.get('Authorization') or (current_account and len(username) > 0 and current_account.username != username):
|
69
|
-
flash(_('Incorrect Password'), 'error')
|
70
|
+
hutils.flask.flash(_('Incorrect Password'), 'error') # type: ignore
|
70
71
|
logout_user()
|
71
|
-
g.
|
72
|
-
# flash(request.authorization.username, 'error')
|
72
|
+
g.__account_store = None
|
73
|
+
# hutils.flask.flash(request.authorization.username, 'error')
|
73
74
|
return redirect(loginurl)
|
74
75
|
|
75
76
|
return render_template("redirect.html", url=loginurl), 401
|
@@ -90,13 +91,13 @@ class LoginView(FlaskView):
|
|
90
91
|
|
91
92
|
# def uuid(self, uuid, path=''):
|
92
93
|
# proxy_path = hiddify.get_proxy_path_from_url(request.url)
|
93
|
-
# g.
|
94
|
+
# g.__account_store = None
|
94
95
|
# uuid = str(uuid)
|
95
96
|
# if proxy_path == hconfig(ConfigEnum.proxy_path_client):
|
96
|
-
# g.
|
97
|
+
# g.__account_store = User.by_uuid(uuid)
|
97
98
|
# path = f'client/{path}'
|
98
99
|
# elif proxy_path == hconfig(ConfigEnum.proxy_path_admin):
|
99
|
-
# g.
|
100
|
+
# g.__account_store = AdminUser.by_uuid(uuid)
|
100
101
|
# if not g.account:
|
101
102
|
# abort(403)
|
102
103
|
# if not g.user_agent['is_browser'] and proxy_path == hconfig(ConfigEnum.proxy_path_client):
|
@@ -134,7 +135,7 @@ class LoginView(FlaskView):
|
|
134
135
|
"orientation": "any",
|
135
136
|
"icons": [
|
136
137
|
{
|
137
|
-
"src":
|
138
|
+
"src": hutils.flask.static_url_for(filename='images/hiddify-dark.png'),
|
138
139
|
"sizes": "512x512",
|
139
140
|
"type": "image/png",
|
140
141
|
"purpose": "maskable any"
|
hiddifypanel/panel/database.py
CHANGED
@@ -6,7 +6,8 @@ import re
|
|
6
6
|
import os
|
7
7
|
|
8
8
|
db = SQLAlchemy()
|
9
|
-
db.UUID = UUIDType
|
9
|
+
db.UUID = UUIDType # type: ignore
|
10
|
+
|
10
11
|
|
11
12
|
def init_app(app):
|
12
13
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
|
@@ -14,23 +15,23 @@ def init_app(app):
|
|
14
15
|
|
15
16
|
# db.create_all(app)
|
16
17
|
# app.jinja_env.globals['get_locale'] = get_locale
|
17
|
-
def init_migration(app):
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def migrate():
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
18
|
+
# def init_migration(app):
|
19
|
+
# migrate = flask_migrate.Migrate(app,db)
|
20
|
+
# if os.path.isdir(migrate.directory):
|
21
|
+
# return
|
22
|
+
# flask_migrate.init()
|
23
|
+
# def migrate():
|
24
|
+
# try_again = False
|
25
|
+
# try:
|
26
|
+
# # run flask_migrate.migrate function without its decorator to catch function error in try statement
|
27
|
+
# flask_migrate.migrate.__wrapped__()
|
28
|
+
# except Exception as err:
|
29
|
+
# err_str = str(err)
|
30
|
+
# if err_str == 'Target database is not up to date.':
|
31
|
+
# flask_migrate.stamp()
|
32
|
+
# elif err_str.startswith("Can't locate revision identified by"):
|
33
|
+
# rev_id = re.findall(" '(.*)'$",err_str)[0].replace("'","'").strip()
|
34
|
+
# flask_migrate.revision(rev_id=rev_id)
|
35
|
+
# finally:
|
36
|
+
# if try_again:
|
37
|
+
# flask_migrate.migrate()
|
hiddifypanel/panel/hiddify.py
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
import glob
|
2
|
+
import random
|
3
|
+
import socket
|
4
|
+
import ssl
|
5
|
+
import time
|
2
6
|
import uuid
|
3
7
|
import user_agents
|
4
8
|
import json
|
5
9
|
import subprocess
|
6
10
|
import psutil
|
11
|
+
from datetime import datetime
|
7
12
|
from typing import Tuple
|
8
13
|
from cryptography.hazmat.primitives import serialization
|
9
14
|
from cryptography.hazmat.primitives.asymmetric import x25519
|
10
|
-
from flask import current_app, g,
|
15
|
+
from flask import current_app, g, request, Markup # type: ignore
|
11
16
|
from flask_babelex import gettext as __
|
12
17
|
from flask_babelex import lazy_gettext as _
|
13
18
|
from wtforms.validators import ValidationError
|
14
19
|
from apiflask import abort as apiflask_abort
|
15
|
-
from apiflask import abort
|
16
20
|
|
17
21
|
from datetime import timedelta
|
18
22
|
from babel.dates import format_timedelta as babel_format_timedelta
|
@@ -57,7 +61,7 @@ def add_short_link_imp(link: str, period_min: int = 5) -> Tuple[str, datetime]:
|
|
57
61
|
if link in line:
|
58
62
|
return re.search(pattern, line).group(1), datetime.now() + timedelta(minutes=period_min)
|
59
63
|
|
60
|
-
short_code = get_random_string(6, 10).lower()
|
64
|
+
short_code = hutils.random.get_random_string(6, 10).lower()
|
61
65
|
# exec_command(
|
62
66
|
# f'sudo /opt/hiddify-manager/nginx/add2shortlink.sh {link} {short_code} {period_min} &')
|
63
67
|
|
@@ -172,6 +176,8 @@ def is_login_call() -> bool:
|
|
172
176
|
|
173
177
|
|
174
178
|
def is_admin_role(role: Role):
|
179
|
+
if not role:
|
180
|
+
return False
|
175
181
|
if role in {Role.super_admin, Role.admin, Role.agent}:
|
176
182
|
return True
|
177
183
|
return False
|
@@ -202,18 +208,18 @@ def proxy_path_validator(proxy_path):
|
|
202
208
|
return
|
203
209
|
|
204
210
|
if proxy_path not in [admin_proxy_path, deprecated_path, client_proxy_path]:
|
205
|
-
|
211
|
+
apiflask_abort(400, 'invalid request')
|
206
212
|
|
207
213
|
if is_admin_panel_call() and proxy_path != admin_proxy_path:
|
208
|
-
|
214
|
+
apiflask_abort(400, 'invalid request')
|
209
215
|
if is_user_panel_call() and proxy_path != client_proxy_path:
|
210
|
-
|
216
|
+
apiflask_abort(400, 'invalid request')
|
211
217
|
|
212
218
|
if is_api_call(request.path):
|
213
219
|
if is_admin_api_call() and proxy_path != admin_proxy_path:
|
214
|
-
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')
|
215
221
|
if is_user_api_call() and proxy_path != client_proxy_path:
|
216
|
-
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')
|
217
223
|
|
218
224
|
|
219
225
|
def asset_url(path) -> str:
|
@@ -271,17 +277,6 @@ def quick_apply_users():
|
|
271
277
|
return {"status": 'success'}
|
272
278
|
|
273
279
|
|
274
|
-
def flash_config_success(restart_mode='', domain_changed=True):
|
275
|
-
if restart_mode:
|
276
|
-
url = url_for('admin.Actions:reinstall', complete_install=restart_mode ==
|
277
|
-
'reinstall', domain_changed=domain_changed)
|
278
|
-
apply_btn = f"<a href='{url}' class='btn btn-primary form_post'>" + \
|
279
|
-
_("admin.config.apply_configs")+"</a>"
|
280
|
-
flash((_('config.validation-success', link=apply_btn)), 'success')
|
281
|
-
else:
|
282
|
-
flash((_('config.validation-success-no-reset')), 'success')
|
283
|
-
|
284
|
-
|
285
280
|
# Importing socket library
|
286
281
|
|
287
282
|
# Function to display hostname and
|
@@ -333,7 +328,7 @@ def get_html_user_link(model: BaseAccount, domain: Domain):
|
|
333
328
|
res = ""
|
334
329
|
d = domain.domain
|
335
330
|
if "*" in d:
|
336
|
-
d = d.replace("*", get_random_string(5, 15))
|
331
|
+
d = d.replace("*", hutils.random.get_random_string(5, 15))
|
337
332
|
|
338
333
|
link = get_account_panel_link(model, d)+f"#{model.name}"
|
339
334
|
|
@@ -380,7 +375,7 @@ def check_need_reset(old_configs, do=False):
|
|
380
375
|
if old_configs[ConfigEnum.package_mode] != hconfig(ConfigEnum.package_mode):
|
381
376
|
return reinstall_action(do_update=True)
|
382
377
|
if not (do and restart_mode == 'reinstall'):
|
383
|
-
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)
|
384
379
|
|
385
380
|
return reinstall_action(complete_install=True, domain_changed=domain_changed)
|
386
381
|
|
@@ -649,9 +644,12 @@ def get_random_domains(count=1, retry=3):
|
|
649
644
|
return random.sample(defdomains, count)
|
650
645
|
return get_random_domains(count, retry-1)
|
651
646
|
|
647
|
+
# not used
|
648
|
+
|
652
649
|
|
653
650
|
def is_domain_support_tls_13(domain):
|
654
651
|
context = ssl.create_default_context()
|
652
|
+
port = 433
|
655
653
|
with socket.create_connection((domain, port)) as sock:
|
656
654
|
with context.wrap_socket(sock, server_hostname=domain) as ssock:
|
657
655
|
return ssock.version() == "TLSv1.3"
|
@@ -694,8 +692,8 @@ def debug_flash_if_not_in_the_same_asn(domain):
|
|
694
692
|
# country_ipv4= ipcountry.get(ipv4)
|
695
693
|
# country_dip= ipcountry.get(dip)
|
696
694
|
if asn_ipv4.get('autonomous_system_organization') != asn_dip.get('autonomous_system_organization'):
|
697
|
-
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.") +
|
698
|
-
|
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")
|
699
697
|
except:
|
700
698
|
pass
|
701
699
|
|
@@ -789,10 +787,10 @@ def get_ed25519_private_public_pair():
|
|
789
787
|
return priv_bytes.decode(), pub_bytes.decode()
|
790
788
|
|
791
789
|
|
792
|
-
def do_base_64(str):
|
793
|
-
|
794
|
-
|
795
|
-
|
790
|
+
# def do_base_64(str):
|
791
|
+
# import base64
|
792
|
+
# resp = base64.b64encode(f'{str}'.encode("utf-8"))
|
793
|
+
# return resp.decode()
|
796
794
|
|
797
795
|
|
798
796
|
def get_user_agent():
|
@@ -855,7 +853,6 @@ def __parse_user_agent(ua):
|
|
855
853
|
|
856
854
|
def is_ssh_password_authentication_enabled():
|
857
855
|
if os.path.isfile('/etc/ssh/sshd_config'):
|
858
|
-
content = ''
|
859
856
|
with open('/etc/ssh/sshd_config', 'r') as f:
|
860
857
|
for line in f.readlines():
|
861
858
|
line = line.strip()
|
@@ -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,10 @@ 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
|
+
|
151
158
|
def _v65():
|
152
159
|
add_config_if_not_exist(ConfigEnum.mux_enable, False)
|
153
160
|
add_config_if_not_exist(ConfigEnum.mux_protocol, 'smux')
|
@@ -187,8 +194,8 @@ def _v61():
|
|
187
194
|
|
188
195
|
|
189
196
|
def _v60():
|
190
|
-
add_config_if_not_exist(ConfigEnum.proxy_path_admin, get_random_string())
|
191
|
-
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())
|
192
199
|
|
193
200
|
|
194
201
|
def _v59():
|
@@ -354,13 +361,13 @@ def _v20():
|
|
354
361
|
|
355
362
|
|
356
363
|
def _v19():
|
357
|
-
set_hconfig(ConfigEnum.path_trojan, get_random_string(7, 15))
|
358
|
-
set_hconfig(ConfigEnum.path_vless, get_random_string(7, 15))
|
359
|
-
set_hconfig(ConfigEnum.path_vmess, get_random_string(7, 15))
|
360
|
-
set_hconfig(ConfigEnum.path_ss, get_random_string(7, 15))
|
361
|
-
set_hconfig(ConfigEnum.path_grpc, get_random_string(7, 15))
|
362
|
-
set_hconfig(ConfigEnum.path_tcp, get_random_string(7, 15))
|
363
|
-
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))
|
364
371
|
add_config_if_not_exist(ConfigEnum.tuic_enable, False)
|
365
372
|
add_config_if_not_exist(ConfigEnum.shadowtls_enable, False)
|
366
373
|
add_config_if_not_exist(ConfigEnum.shadowtls_fakedomain, "en.wikipedia.org")
|
@@ -395,7 +402,7 @@ def _v1():
|
|
395
402
|
StrConfig(key=ConfigEnum.tls_ports, value="443"),
|
396
403
|
BoolConfig(key=ConfigEnum.first_setup, value=True),
|
397
404
|
StrConfig(key=ConfigEnum.decoy_domain, value=hiddify.get_random_decoy_domain()),
|
398
|
-
StrConfig(key=ConfigEnum.proxy_path, value=get_random_string()),
|
405
|
+
StrConfig(key=ConfigEnum.proxy_path, value=hutils.random.get_random_string()),
|
399
406
|
BoolConfig(key=ConfigEnum.firewall, value=False),
|
400
407
|
BoolConfig(key=ConfigEnum.netdata, value=True),
|
401
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
|