hiddifypanel 9.0.0.dev92__py3-none-any.whl → 10.7.0.dev94__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 (31) hide show
  1. hiddifypanel/VERSION +1 -1
  2. hiddifypanel/VERSION.py +2 -2
  3. hiddifypanel/hutils/flask.py +15 -0
  4. hiddifypanel/panel/admin/QuickSetup.py +21 -20
  5. hiddifypanel/panel/admin/SettingAdmin.py +43 -48
  6. hiddifypanel/panel/commercial/ProxyDetailsAdmin.py +1 -1
  7. hiddifypanel/panel/commercial/restapi/v1/__init__.py +1 -1
  8. hiddifypanel/panel/commercial/restapi/v1/tgbot.py +1 -1
  9. hiddifypanel/panel/hiddify.py +0 -11
  10. hiddifypanel/panel/user/link_maker.py +2 -2
  11. hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
  12. hiddifypanel/translations/en/LC_MESSAGES/messages.po +5 -5
  13. hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
  14. hiddifypanel/translations/fa/LC_MESSAGES/messages.po +3 -3
  15. hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
  16. hiddifypanel/translations/pt/LC_MESSAGES/messages.po +5 -5
  17. hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
  18. hiddifypanel/translations/ru/LC_MESSAGES/messages.po +5 -5
  19. hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
  20. hiddifypanel/translations/zh/LC_MESSAGES/messages.po +3 -3
  21. hiddifypanel/translations.i18n/en.json +1 -1
  22. hiddifypanel/translations.i18n/fa.json +1 -1
  23. hiddifypanel/translations.i18n/pt.json +1 -1
  24. hiddifypanel/translations.i18n/ru.json +1 -1
  25. hiddifypanel/translations.i18n/zh.json +1 -1
  26. {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.7.0.dev94.dist-info}/METADATA +1 -1
  27. {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.7.0.dev94.dist-info}/RECORD +31 -31
  28. {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.7.0.dev94.dist-info}/LICENSE.md +0 -0
  29. {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.7.0.dev94.dist-info}/WHEEL +0 -0
  30. {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.7.0.dev94.dist-info}/entry_points.txt +0 -0
  31. {hiddifypanel-9.0.0.dev92.dist-info → hiddifypanel-10.7.0.dev94.dist-info}/top_level.txt +0 -0
hiddifypanel/VERSION CHANGED
@@ -1 +1 @@
1
- 9.0.0.dev92
1
+ 10.7.0.dev94
hiddifypanel/VERSION.py CHANGED
@@ -1,3 +1,3 @@
1
- __version__='9.0.0.dev92'
1
+ __version__='10.7.0.dev94'
2
2
  from datetime import datetime
3
- __release_date__= datetime.strptime('2024-03-03','%Y-%m-%d')
3
+ __release_date__= datetime.strptime('2024-03-04','%Y-%m-%d')
@@ -1,5 +1,6 @@
1
1
  from typing import List
2
2
  from flask import current_app, flash as flask_flash, g, request
3
+ from wtforms.validators import ValidationError
3
4
  from apiflask import abort as apiflask_abort
4
5
  from flask_babel import lazy_gettext as _
5
6
  from flask import url_for, Markup # type: ignore
@@ -7,8 +8,10 @@ from urllib.parse import urlparse
7
8
  import user_agents
8
9
  import re
9
10
  import os
11
+
10
12
  from hiddifypanel.cache import cache
11
13
  from hiddifypanel.models import *
14
+ from hiddifypanel import hutils
12
15
 
13
16
 
14
17
  def flash(message: str, category: str = "message"):
@@ -218,6 +221,18 @@ def proxy_path_validator(proxy_path: str) -> None:
218
221
 
219
222
  def list_dir_files(dir_path: str) -> List[str]:
220
223
  return [f for f in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, f))]
224
+
225
+ def validate_domain_exist(form, field):
226
+ domain = field.data
227
+ if not domain:
228
+ return
229
+ dip = hutils.network.get_domain_ip(domain)
230
+ if dip is None:
231
+ raise ValidationError(
232
+ _("Domain can not be resolved! there is a problem in your domain")) # type: ignore
233
+
234
+
235
+
221
236
  # region not used
222
237
 
223
238
 
@@ -8,7 +8,6 @@ import wtforms as wtf
8
8
  from flask_wtf import FlaskForm
9
9
  from flask_bootstrap import SwitchField
10
10
  from hiddifypanel.panel import hiddify
11
- from wtforms.fields import *
12
11
  from flask_classful import FlaskView
13
12
  from wtforms.validators import ValidationError
14
13
  # from gettext import gettext as _
@@ -61,7 +60,7 @@ class QuickSetup(FlaskView):
61
60
  Domain.query.filter(Domain.domain == f'{hutils.network.get_ip_str(4)}.sslip.io').delete()
62
61
  db.session.add(Domain(domain=quick_form.domain.data.lower(), mode=DomainType.direct))
63
62
  set_hconfig(ConfigEnum.block_iran_sites, quick_form.block_iran_sites.data)
64
- set_hconfig(ConfigEnum.decoy_domain,quick_form.decoy_domain.data)
63
+ set_hconfig(ConfigEnum.decoy_domain, quick_form.decoy_domain.data)
65
64
  # hiddify.bulk_register_configs([
66
65
  # # {"key": ConfigEnum.telegram_enable, "value": quick_form.enable_telegram.data == True},
67
66
  # # {"key": ConfigEnum.vmess_enable, "value": quick_form.enable_vmess.data == True},
@@ -84,12 +83,16 @@ class QuickSetup(FlaskView):
84
83
 
85
84
  def get_lang_form(empty=False):
86
85
  class LangForm(FlaskForm):
87
- admin_lang = wtf.fields.SelectField(_("config.admin_lang.label"), choices=[("en", _("lang.en")), ("fa", _("lang.fa")), ("pt", _(
88
- "lang.pt")), ("zh", _("lang.zh")), ("ru", _("lang.ru"))], description=_("config.admin_lang.description"), default=hconfig(ConfigEnum.admin_lang))
89
- # lang=wtf.fields.SelectField(_("config.lang.label"),choices=[("en",_("lang.en")),("fa",_("lang.fa"))],description=_("config.lang.description"),default=hconfig(ConfigEnum.lang))
90
- country = wtf.fields.SelectField(_("config.country.label"), choices=[("ir", _("Iran")), ("zh", _(
91
- "China")), ("other", "Others")], description=_("config.country.description"), default=hconfig(ConfigEnum.country))
92
- lang_submit = wtf.fields.SubmitField(_('Submit'))
86
+ admin_lang = wtf.SelectField(
87
+ _("config.admin_lang.label"), choices=[("en", _("lang.en")), ("fa", _("lang.fa")), ("pt", _("lang.pt")), ("zh", _("lang.zh")), ("ru", _("lang.ru"))],
88
+ description=_("config.admin_lang.description"),
89
+ default=hconfig(ConfigEnum.admin_lang))
90
+ # lang=wtf.SelectField(_("config.lang.label"),choices=[("en",_("lang.en")),("fa",_("lang.fa"))],description=_("config.lang.description"),default=hconfig(ConfigEnum.lang))
91
+ country = wtf.SelectField(
92
+ _("config.country.label"), choices=[("ir", _("Iran")), ("zh", _("China")), ("other", "Others")],
93
+ description=_("config.country.description"),
94
+ default=hconfig(ConfigEnum.country))
95
+ lang_submit = wtf.SubmitField(_('Submit'))
93
96
 
94
97
  return LangForm(None)if empty else LangForm()
95
98
 
@@ -108,13 +111,12 @@ def get_quick_setup_form(empty=False):
108
111
  class QuickSetupForm(FlaskForm):
109
112
  domain_regex = "^([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})$"
110
113
 
111
- domain_validators = [wtf.validators.Regexp(domain_regex, re.IGNORECASE, _("config.Invalid domain")),
112
- validate_domain,
113
- wtf.validators.NoneOf([d.domain.lower() for d in Domain.query.all()], _("config.Domain already used")),
114
- wtf.validators.NoneOf([c.value.lower() for c in StrConfig.query.all() if "fakedomain" in c.key and c.key !=
115
- ConfigEnum.decoy_domain], _("config.Domain already used"))
116
- ]
117
- domain = wtf.fields.StringField(
114
+ domain_validators = [
115
+ wtf.validators.Regexp(domain_regex, re.IGNORECASE, _("config.Invalid domain")),
116
+ validate_domain,
117
+ wtf.validators.NoneOf([d.domain.lower() for d in Domain.query.all()], _("config.Domain already used")),
118
+ wtf.validators.NoneOf([c.value.lower() for c in StrConfig.query.all() if "fakedomain" in c.key and c.key != ConfigEnum.decoy_domain], _("config.Domain already used"))]
119
+ domain = wtf.StringField(
118
120
  _("domain.domain"),
119
121
  domain_validators,
120
122
  description=_("domain.description"),
@@ -129,9 +131,9 @@ def get_quick_setup_form(empty=False):
129
131
  block_iran_sites = SwitchField(_("config.block_iran_sites.label"), description=_(
130
132
  "config.block_iran_sites.description"), default=hconfig(ConfigEnum.block_iran_sites))
131
133
  # enable_vmess = SwitchField(_("config.vmess_enable.label"), description=_("config.vmess_enable.description"), default=hconfig(ConfigEnum.vmess_enable))
132
- decoy_domain = wtf.fields.StringField(_("config.decoy_domain.label"), description=_("config.decoy_domain.description"), default=hconfig(
133
- ConfigEnum.decoy_domain), validators=[wtf.validators.Regexp(domain_regex, re.IGNORECASE, _("config.Invalid domain")), hiddify.validate_domain_exist])
134
- submit = wtf.fields.SubmitField(_('Submit'))
134
+ decoy_domain = wtf.StringField(_("config.decoy_domain.label"), description=_("config.decoy_domain.description"), default=hconfig(
135
+ ConfigEnum.decoy_domain), validators=[wtf.validators.Regexp(domain_regex, re.IGNORECASE, _("config.Invalid domain")), hutils.flask.validate_domain_exist])
136
+ submit = wtf.SubmitField(_('Submit'))
135
137
 
136
138
  return QuickSetupForm(None) if empty else QuickSetupForm()
137
139
 
@@ -144,8 +146,7 @@ def validate_domain(form, field):
144
146
 
145
147
  myip = hutils.network.get_ip(4)
146
148
  if dip and myip != dip:
147
- raise ValidationError(_("Domain (%(domain)s)-> IP=%(domain_ip)s is not matched with your ip=%(server_ip)s which is required in direct mode",
148
- server_ip=myip, domain_ip=dip, domain=domain))
149
+ raise ValidationError(_("Domain (%(domain)s)-> IP=%(domain_ip)s is not matched with your ip=%(server_ip)s which is required in direct mode", server_ip=myip, domain_ip=dip, domain=domain))
149
150
 
150
151
 
151
152
  def admin_link():
@@ -13,7 +13,6 @@ from flask_bootstrap import SwitchField
13
13
 
14
14
  # from gettext import gettext as _
15
15
  from flask_classful import FlaskView
16
- from wtforms.fields import *
17
16
  from flask_wtf import FlaskForm
18
17
 
19
18
 
@@ -81,7 +80,7 @@ class SettingAdmin(FlaskView):
81
80
  flask_babel.refresh()
82
81
 
83
82
  from hiddifypanel.panel.commercial.telegrambot import register_bot
84
- register_bot()
83
+ register_bot(set_hook=True)
85
84
  # if hconfig(ConfigEnum.parent_panel):
86
85
  # hiddify_api.sync_child_to_parent()
87
86
  reset_action = hiddify.check_need_reset(old_configs)
@@ -146,7 +145,7 @@ def get_config_form():
146
145
  continue
147
146
 
148
147
  class CategoryForm(FlaskForm):
149
- description_for_fieldset = wtf.fields.TextAreaField("", description=_(f'config.{cat}.description'), render_kw={"class": "d-none"})
148
+ description_for_fieldset = wtf.TextAreaField("", description=_(f'config.{cat}.description'), render_kw={"class": "d-none"})
150
149
  for c2 in cat_configs:
151
150
  if not (c2 in configs_key):
152
151
  continue
@@ -155,102 +154,96 @@ def get_config_form():
155
154
  if c.key in bool_types:
156
155
  field = SwitchField(_(f'config.{c.key}.label'), default=c.value, description=_(f'config.{c.key}.description'))
157
156
  elif c.key == ConfigEnum.core_type:
158
- field = wtf.fields.SelectField(_(f"config.{c.key}.label"), choices=[("xray", _("Xray")), ("singbox", _(
159
- "SingBox"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
157
+ field = wtf.SelectField(_(f"config.{c.key}.label"), choices=[("xray", _("Xray")), ("singbox", _("SingBox"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
160
158
  elif c.key == ConfigEnum.warp_mode:
161
- field = wtf.fields.SelectField(_(f"config.{c.key}.label"), choices=[("disable", _("Disable")), ("all", _("All")), ("custom", _(
162
- "Only Blocked and Local websites"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
159
+ field = wtf.SelectField(
160
+ _(f"config.{c.key}.label"), choices=[("disable", _("Disable")), ("all", _("All")), ("custom", _("Only Blocked and Local websites"))],
161
+ description=_(f"config.{c.key}.description"),
162
+ default=hconfig(c.key))
163
163
 
164
164
  elif c.key == ConfigEnum.lang or c.key == ConfigEnum.admin_lang:
165
- field = wtf.fields.SelectField(_(f"config.{c.key}.label"), choices=[("en", _("lang.en")), ("fa", Markup(_("lang.fa"))), ("zh", _(
166
- "lang.zh")), ("pt", _("lang.pt")), ("ru", _("lang.ru"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
165
+ field = wtf.SelectField(
166
+ _(f"config.{c.key}.label"),
167
+ choices=[("en", _("lang.en")), ("fa", Markup(_("lang.fa"))), ("zh", _("lang.zh")), ("pt", _("lang.pt")), ("ru", _("lang.ru"))],
168
+ description=_(f"config.{c.key}.description"),
169
+ default=hconfig(c.key))
167
170
  elif c.key == ConfigEnum.country:
168
- field = wtf.fields.SelectField(_(f"config.{c.key}.label"), choices=[("ir", _("Iran")), ("zh", _(
169
- "China")), ("other", _("Others"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
171
+ field = wtf.SelectField(_(f"config.{c.key}.label"), choices=[("ir", _("Iran")), ("zh", _("China")), ("other", _("Others"))], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
170
172
  elif c.key == ConfigEnum.package_mode:
171
173
  package_modes = [("release", _("Release")), ("beta", _("Beta"))]
172
174
  if hconfig(c.key) == "develop":
173
175
  package_modes.append(("develop", _("Develop")))
174
- field = wtf.fields.SelectField(_(f"config.{c.key}.label"), choices=package_modes,
175
- description=_(f"config.{c.key}.description"), default=hconfig(c.key))
176
+ field = wtf.SelectField(_(f"config.{c.key}.label"), choices=package_modes, description=_(f"config.{c.key}.description"), default=hconfig(c.key))
176
177
 
177
178
  elif c.key == ConfigEnum.shadowsocks2022_method:
178
- field = wtf.fields.SelectField(_(f"config.{c.key}.label"), choices=[
179
- ("2022-blake3-aes-256-gcm", "2022-blake3-aes-256-gcm"),
180
- ("2022-blake3-chacha20-poly1305", "2022-blake3-chacha20-poly1305"),
181
- ], description=_(f"config.{c.key}.description"), default=hconfig(c.key))
179
+ field = wtf.SelectField(
180
+ _(f"config.{c.key}.label"),
181
+ choices=[("2022-blake3-aes-256-gcm", "2022-blake3-aes-256-gcm"), ("2022-blake3-chacha20-poly1305", "2022-blake3-chacha20-poly1305"),],
182
+ description=_(f"config.{c.key}.description"), default=hconfig(c.key))
182
183
 
183
184
  elif c.key == ConfigEnum.utls:
184
- field = wtf.fields.SelectField(
185
+ field = wtf.SelectField(
185
186
  _(f"config.{c.key}.label"),
186
- choices=[("none", "None"),
187
- ("chrome", "Chrome"),
188
- ("edge", "Edge"),
189
- ("ios", "iOS"),
190
- ("android", "Android"),
191
- ("safari", "Safari"),
192
- ("firefox", "Firefox"),
193
- ('random', 'random'),
194
- ('randomized', 'randomized')],
187
+ choices=[
188
+ ("none", "None"), ("chrome", "Chrome"), ("edge", "Edge"), ("ios", "iOS"), ("android", "Android"),
189
+ ("safari", "Safari"), ("firefox", "Firefox"), ('random', 'random'), ('randomized', 'randomized')],
195
190
  description=_(f"config.{c.key}.description"),
196
- default=hconfig(c.key))
191
+ default=hconfig(c.key)
192
+ )
197
193
  elif c.key == ConfigEnum.telegram_lib:
198
194
  # if hconfig(ConfigEnum.telegram_lib)=='python':
199
195
  # continue6
200
196
  libs = [("python", _("lib.telegram.python")), ("tgo", _("lib.telegram.go")),
201
197
  ("orig", _("lib.telegram.orignal")), ("erlang", _("lib.telegram.erlang"))]
202
- field = wtf.fields.SelectField(_("config.telegram_lib.label"), choices=libs, description=_(
203
- "config.telegram_lib.description"), default=hconfig(ConfigEnum.telegram_lib))
198
+ field = wtf.SelectField(_("config.telegram_lib.label"), choices=libs, description=_("config.telegram_lib.description"), default=hconfig(ConfigEnum.telegram_lib))
204
199
  elif c.key == ConfigEnum.mux_protocol:
205
200
  choices = [("smux", 'smux'), ("yamux", "yamux"), ("h2mux", "h2mux")]
206
- field = wtf.fields.SelectField(_(f"config.{c.key}.label"), choices=choices,
207
- description=_(f"config.{c.key}.description"), default=hconfig(c.key))
201
+ field = wtf.SelectField(_(f"config.{c.key}.label"), choices=choices, description=_(f"config.{c.key}.description"), default=hconfig(c.key))
208
202
 
209
203
  elif c.key == ConfigEnum.warp_sites:
210
204
  validators = [wtf.validators.Length(max=2048)]
211
205
  render_kw = {'class': "ltr", 'maxlength': 2048}
212
- field = wtf.fields.TextAreaField(_(f'config.{c.key}.label'), validators, default=c.value,
213
- description=_(f'config.{c.key}.description'), render_kw=render_kw)
206
+ field = wtf.TextAreaField(_(f'config.{c.key}.label'), validators, default=c.value, description=_(f'config.{c.key}.description'), render_kw=render_kw)
214
207
  elif c.key == ConfigEnum.branding_freetext:
215
208
  validators = [wtf.validators.Length(max=2048)]
216
209
  render_kw = {'class': "ltr", 'maxlength': 2048}
217
- field = custom_widgets.CKTextAreaField(_(f'config.{c.key}.label'), validators, default=c.value,
218
- description=_(f'config.{c.key}.description'), render_kw=render_kw)
210
+ field = custom_widgets.CKTextAreaField(_(f'config.{c.key}.label'), validators, default=c.value, description=_(f'config.{c.key}.description'), render_kw=render_kw)
219
211
  else:
220
212
  render_kw = {'class': "ltr"}
221
213
  validators = []
222
214
  if c.key == ConfigEnum.domain_fronting_domain:
223
215
  validators.append(wtf.validators.Regexp("^([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})|$", re.IGNORECASE, _("config.Invalid domain")))
224
- validators.append(hiddify.validate_domain_exist)
216
+ validators.append(hutils.flask.validate_domain_exist)
225
217
  elif '_domain' in c.key or "_fakedomain" in c.key:
226
218
  validators.append(wtf.validators.Regexp("^([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})$", re.IGNORECASE, _("config.Invalid domain")))
227
- validators.append(hiddify.validate_domain_exist)
219
+ validators.append(hutils.flask.validate_domain_exist)
228
220
 
229
221
  if c.key != ConfigEnum.decoy_domain:
230
222
  validators.append(wtf.validators.NoneOf([d.domain.lower() for d in Domain.query.all()], _("config.Domain already used")))
231
- validators.append(wtf.validators.NoneOf([cc.value.lower() for cc in StrConfig.query.filter(StrConfig.child_id == Child.current.id).all(
232
- ) if cc.key != c.key and "fakedomain" in cc.key and cc.key != ConfigEnum.decoy_domain], _("config.Domain already used")))
223
+ validators.append(wtf.validators.NoneOf(
224
+ [cc.value.lower() for cc in StrConfig.query.filter(StrConfig.child_id == Child.current.id).all() if cc.key != c.key and "fakedomain" in cc.key and cc.key != ConfigEnum.decoy_domain], _("config.Domain already used")))
225
+
233
226
  render_kw['required'] = ""
234
227
  if len(c.value) < 3:
235
228
  c.value = hutils.network.get_random_domains(1)[0]
229
+
236
230
  # if c.key ==ConfigEnum.reality_short_ids:
237
231
  # extra_info=f" <a target='_blank' href='{hurl_for('admin.Actions:get_some_random_reality_friendly_domain',test_domain=c.value)}'>"+_('Example Domains')+"</a>"
238
232
  # if c.key ==ConfigEnum.reality_server_names:
239
233
  # validators.append(wtf.validators.Regexp("^([\w-]+\.)+[\w-]+(,\s*([\w-]+\.)+[\w-]+)*$",re.IGNORECASE,_("Invalid REALITY hostnames")))
240
234
  # gauge width gate lamp weasel jaguar minute enough few attitude endorse situate usdt trc20 doge bep20 trx doge ltc bnb eth btc bnb
241
235
  # enjoy control list debris chronic few door broken way negative daring life season recipe profit switch bitter casual frame aunt plate brush aerobic display
236
+
242
237
  if c.key == ConfigEnum.parent_panel:
243
238
  validators.append(wtf.validators.Regexp("()|(http(s|)://([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})/.*)", re.IGNORECASE, _("Invalid admin link")))
244
239
  if c.key == ConfigEnum.telegram_bot_token:
245
240
  validators.append(wtf.validators.Regexp("()|^([0-9]{8,12}:[a-zA-Z0-9_-]{30,40})|$", re.IGNORECASE, _("config.Invalid telegram bot token")))
246
241
  if c.key == ConfigEnum.branding_site:
247
- validators.append(wtf.validators.Regexp(
248
- "()|(http(s|)://([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})/?.*)", re.IGNORECASE, _("config.Invalid brand link")))
242
+ validators.append(wtf.validators.Regexp("()|(http(s|)://([A-Za-z0-9\\-\\.]+\\.[a-zA-Z]{2,})/?.*)", re.IGNORECASE, _("config.Invalid brand link")))
249
243
  # render_kw['required']=""
250
244
 
251
245
  if 'secret' in c.key:
252
- validators.append(wtf.validators.Regexp(
253
- "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", re.IGNORECASE, _('config.invalid uuid')))
246
+ validators.append(wtf.validators.Regexp("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", re.IGNORECASE, _('config.invalid uuid')))
254
247
  render_kw['required'] = ""
255
248
 
256
249
  if c.key == ConfigEnum.proxy_path:
@@ -272,20 +265,22 @@ def get_config_form():
272
265
  if c.key in [ConfigEnum.hysteria_up_mbps, ConfigEnum.hysteria_down_mbps, ConfigEnum.mux_max_connections, ConfigEnum.mux_min_streams, ConfigEnum.mux_max_streams,
273
266
  ConfigEnum.mux_brutal_down_mbps, ConfigEnum.mux_brutal_up_mbps]:
274
267
  validators.append(wtf.validators.Regexp("^\\d+$", re.IGNORECASE, _("config.Invalid! it should be a number only") + f' {c.key}'))
268
+
275
269
  for val in validators:
276
270
  if hasattr(val, "regex"):
277
271
  render_kw['pattern'] = val.regex.pattern
278
272
  render_kw['title'] = val.message
273
+
279
274
  if c.key == ConfigEnum.reality_public_key and g.account.mode in [AdminMode.super_admin]:
280
275
  extra_info = f" <a href='{hurl_for('admin.Actions:change_reality_keys')}'>{_('Change')}</a>"
281
- field = wtf.fields.StringField(_(f'config.{c.key}.label'), validators, default=c.value,
282
- description=_(f'config.{c.key}.description') + extra_info, render_kw=render_kw)
276
+
277
+ field = wtf.StringField(_(f'config.{c.key}.label'), validators, default=c.value, description=_(f'config.{c.key}.description') + extra_info, render_kw=render_kw)
283
278
  setattr(CategoryForm, f'{c.key}', field)
284
279
 
285
- multifield = wtf.fields.FormField(CategoryForm, Markup('<i class="fa-solid fa-plus"></i>&nbsp' + _(f'config.{cat}.label')))
280
+ multifield = wtf.FormField(CategoryForm, Markup('<i class="fa-solid fa-plus"></i>&nbsp' + _(f'config.{cat}.label')))
286
281
 
287
282
  setattr(DynamicForm, cat, multifield)
288
283
 
289
- setattr(DynamicForm, "submit", wtf.fields.SubmitField(_('Submit')))
284
+ setattr(DynamicForm, "submit", wtf.SubmitField(_('Submit')))
290
285
 
291
286
  return DynamicForm()
@@ -18,7 +18,7 @@ class ProxyDetailsAdmin(AdminLTEModelView):
18
18
 
19
19
  column_hide_backrefs = True
20
20
  can_create = False
21
- form_excluded_columns = ['child']
21
+ form_excluded_columns = ['child', 'proto', 'transport', 'l3', 'cdn']
22
22
  column_exclude_list = ['child']
23
23
  column_searchable_list = ['name', 'proto', 'transport', 'l3', 'cdn']
24
24
  column_editable_list = ['name']
@@ -10,7 +10,7 @@ from . import tgbot
10
10
  from .tgmsg import SendMsgResource
11
11
  from .resources import *
12
12
  bp = APIBlueprint("api_v1", __name__, url_prefix="/<proxy_path>/api/v1/", tag="api_v1", enable_openapi=False)
13
- bp_uuid = APIBlueprint("api_v1_uuid", __name__, url_prefix="/<proxy_path>/<uuid:secret_uuid>/api/v1", template_folder="templates", enable_openapi=False)
13
+ bp_uuid = APIBlueprint("api_v1_uuid", __name__, url_prefix="/<proxy_path>/<uuid:secret_uuid>/api/v1/", template_folder="templates", enable_openapi=False)
14
14
  api = Api(bp)
15
15
  api_uuid = Api(bp_uuid)
16
16
 
@@ -34,7 +34,7 @@ def register_bot(set_hook=False):
34
34
 
35
35
  user_secret = AdminUser.get_super_admin_uuid()
36
36
  if set_hook:
37
- bot.set_webhook(url=f"https://{domain}/{admin_proxy_path}/{user_secret}/api/v1/tgbot/",)
37
+ bot.set_webhook(url=f"https://{domain}/{admin_proxy_path}/{user_secret}/api/v1/tgbot/")
38
38
  except Exception as e:
39
39
  print(e)
40
40
  import traceback
@@ -8,7 +8,6 @@ from typing import Tuple
8
8
  from cryptography.hazmat.primitives import serialization
9
9
  from cryptography.hazmat.primitives.asymmetric import x25519
10
10
  from flask import current_app, g
11
- from wtforms.validators import ValidationError
12
11
  from flask_babel import lazy_gettext as _
13
12
  from flask_babel import gettext as __
14
13
  from datetime import timedelta
@@ -164,16 +163,6 @@ def get_html_user_link(model: BaseAccount, domain: Domain):
164
163
  return res
165
164
 
166
165
 
167
- def validate_domain_exist(form, field):
168
- domain = field.data
169
- if not domain:
170
- return
171
- dip = hutils.network.get_domain_ip(domain)
172
- if dip is None:
173
- raise ValidationError(
174
- _("Domain can not be resolved! there is a problem in your domain"))
175
-
176
-
177
166
  def reinstall_action(complete_install=False, domain_changed=False, do_update=False):
178
167
  from hiddifypanel.panel.admin.Actions import Actions
179
168
  action = Actions()
@@ -978,9 +978,9 @@ def make_v2ray_configs(user, user_activate, domains, expire_days, ip_debug, db_d
978
978
 
979
979
  name = '⏳' if user_activate else '✖'
980
980
  if user.usage_limit_GB < 1000:
981
- name += f'{round(user.current_usage_GB,3)}/{str(user.usage_limit_GB).rstrip(".0")}GB'
981
+ name += f'{round(user.current_usage_GB,3)}/{str(user.usage_limit_GB).replace(".0","")}GB'
982
982
  elif user.usage_limit_GB < 100000:
983
- name += f'{round(user.current_usage_GB/1000,3)}/{str(round(user.usage_limit_GB/1000,1)).rstrip(".0")}TB'
983
+ name += f'{round(user.current_usage_GB/1000,3)}/{str(round(user.usage_limit_GB/1000,1)).replace(".0","")}TB'
984
984
  else:
985
985
  res.append("#No Usage Limit")
986
986
  if expire_days < 1000:
@@ -1089,6 +1089,11 @@ msgstr "Shadowsocks"
1089
1089
  msgid "config.shadowsocks.description"
1090
1090
  msgstr "Shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
1091
1091
 
1092
+ msgid "Domain can not be resolved! there is a problem in your domain"
1093
+ msgstr ""
1094
+ "Domain can not be resolved! There is a problem in your domain. Please check "
1095
+ "your Domain configurations."
1096
+
1092
1097
  msgid "Error! auto cdn ip can not be find, please contact admin."
1093
1098
  msgstr "Error In Auto CDN IP! It Can Not Be Find, Please Contact Admin"
1094
1099
 
@@ -1098,11 +1103,6 @@ msgstr "Owner can not be deleted!"
1098
1103
  msgid "This domain does not exist in the panel!"
1099
1104
  msgstr "This Domain does not exist in the Panel !"
1100
1105
 
1101
- msgid "Domain can not be resolved! there is a problem in your domain"
1102
- msgstr ""
1103
- "Domain can not be resolved! There is a problem in your domain. Please check "
1104
- "your Domain configurations."
1105
-
1106
1106
  msgid ""
1107
1107
  "selected domain for REALITY is not in the same ASN. To better use of the "
1108
1108
  "protocol, it is better to find a domain in the same ASN."
@@ -1095,6 +1095,9 @@ msgstr ""
1095
1095
  "Shadowsocks یک پروکسی تونل سریع است که به شما کمک می کند فایروال ها را دور "
1096
1096
  "بزنید."
1097
1097
 
1098
+ msgid "Domain can not be resolved! there is a problem in your domain"
1099
+ msgstr "دامنه قابل دسترسی نیست! در دامنه شما مشکلی وجود دارد."
1100
+
1098
1101
  msgid "Error! auto cdn ip can not be find, please contact admin."
1099
1102
  msgstr "خطا! آی پی اتوماتیک نتوانست پیدا شود. لطفا با مدیر تماس بگیرید"
1100
1103
 
@@ -1104,9 +1107,6 @@ msgstr ""
1104
1107
  msgid "This domain does not exist in the panel!"
1105
1108
  msgstr "این دامنه در پنل وجود ندارد!"
1106
1109
 
1107
- msgid "Domain can not be resolved! there is a problem in your domain"
1108
- msgstr "دامنه قابل دسترسی نیست! در دامنه شما مشکلی وجود دارد."
1109
-
1110
1110
  msgid ""
1111
1111
  "selected domain for REALITY is not in the same ASN. To better use of the "
1112
1112
  "protocol, it is better to find a domain in the same ASN."
@@ -1109,6 +1109,11 @@ msgid "config.shadowsocks.description"
1109
1109
  msgstr ""
1110
1110
  "Shadowsocks é um proxy de túnel rápido que ajuda a contornar firewalls."
1111
1111
 
1112
+ msgid "Domain can not be resolved! there is a problem in your domain"
1113
+ msgstr ""
1114
+ "O domínio não pode ser resolvido! Há um problema em seu domínio. Verifique "
1115
+ "as configurações do seu Domínio."
1116
+
1112
1117
  msgid "Error! auto cdn ip can not be find, please contact admin."
1113
1118
  msgstr ""
1114
1119
  "Erro no Auto CDN IP! Não pode ser encontrado, entre em contato com o "
@@ -1120,11 +1125,6 @@ msgstr ""
1120
1125
  msgid "This domain does not exist in the panel!"
1121
1126
  msgstr "Este Domínio não existe no Painel!"
1122
1127
 
1123
- msgid "Domain can not be resolved! there is a problem in your domain"
1124
- msgstr ""
1125
- "O domínio não pode ser resolvido! Há um problema em seu domínio. Verifique "
1126
- "as configurações do seu Domínio."
1127
-
1128
1128
  msgid ""
1129
1129
  "selected domain for REALITY is not in the same ASN. To better use of the "
1130
1130
  "protocol, it is better to find a domain in the same ASN."
@@ -1114,6 +1114,11 @@ msgstr ""
1114
1114
  "Shadowsocks — это быстрый туннельный прокси, который помогает обходить "
1115
1115
  "брандмауэры."
1116
1116
 
1117
+ msgid "Domain can not be resolved! there is a problem in your domain"
1118
+ msgstr ""
1119
+ "Не возможно определить IP адрес для домена! В вашем домене возникла "
1120
+ "проблема. Пожалуйста, проверьте настройки."
1121
+
1117
1122
  msgid "Error! auto cdn ip can not be find, please contact admin."
1118
1123
  msgstr ""
1119
1124
  "Ошибка в IP-адресе Auto CDN! Невозможно найти, обратитесь к администратору"
@@ -1124,11 +1129,6 @@ msgstr ""
1124
1129
  msgid "This domain does not exist in the panel!"
1125
1130
  msgstr "Этого домена не существует в панели управления!"
1126
1131
 
1127
- msgid "Domain can not be resolved! there is a problem in your domain"
1128
- msgstr ""
1129
- "Не возможно определить IP адрес для домена! В вашем домене возникла "
1130
- "проблема. Пожалуйста, проверьте настройки."
1131
-
1132
1132
  msgid ""
1133
1133
  "selected domain for REALITY is not in the same ASN. To better use of the "
1134
1134
  "protocol, it is better to find a domain in the same ASN."
@@ -996,6 +996,9 @@ msgstr "影袜"
996
996
  msgid "config.shadowsocks.description"
997
997
  msgstr "Shadowsocks 是一种快速隧道代理,可帮助您绕过防火墙。"
998
998
 
999
+ msgid "Domain can not be resolved! there is a problem in your domain"
1000
+ msgstr "域名无法解析!您的域有问题。请检查您的域配置。"
1001
+
999
1002
  msgid "Error! auto cdn ip can not be find, please contact admin."
1000
1003
  msgstr "自动 CDN IP 错误!找不到,请联系管理员"
1001
1004
 
@@ -1005,9 +1008,6 @@ msgstr ""
1005
1008
  msgid "This domain does not exist in the panel!"
1006
1009
  msgstr "该域名在面板中不存在!"
1007
1010
 
1008
- msgid "Domain can not be resolved! there is a problem in your domain"
1009
- msgstr "域名无法解析!您的域有问题。请检查您的域配置。"
1010
-
1011
1011
  msgid ""
1012
1012
  "selected domain for REALITY is not in the same ASN. To better use of the "
1013
1013
  "protocol, it is better to find a domain in the same ASN."
@@ -607,10 +607,10 @@
607
607
  "description": "Shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
608
608
  }
609
609
  },
610
+ "Domain can not be resolved! there is a problem in your domain": "Domain can not be resolved! There is a problem in your domain. Please check your Domain configurations.",
610
611
  "Error! auto cdn ip can not be find, please contact admin.": "Error In Auto CDN IP! It Can Not Be Find, Please Contact Admin",
611
612
  "Owner can not be deleted!": "Owner can not be deleted!",
612
613
  "This domain does not exist in the panel!": "This Domain does not exist in the Panel !",
613
- "Domain can not be resolved! there is a problem in your domain": "Domain can not be resolved! There is a problem in your domain. Please check your Domain configurations.",
614
614
  "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.": "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",
615
615
  "User activated!": "User Activated",
616
616
  "Package ended!": "Package Ended",
@@ -607,10 +607,10 @@
607
607
  "description": "Shadowsocks یک پروکسی تونل سریع است که به شما کمک می کند فایروال ها را دور بزنید."
608
608
  }
609
609
  },
610
+ "Domain can not be resolved! there is a problem in your domain": "دامنه قابل دسترسی نیست! در دامنه شما مشکلی وجود دارد.",
610
611
  "Error! auto cdn ip can not be find, please contact admin.": "خطا! آی پی اتوماتیک نتوانست پیدا شود. لطفا با مدیر تماس بگیرید",
611
612
  "Owner can not be deleted!": "",
612
613
  "This domain does not exist in the panel!": "این دامنه در پنل وجود ندارد!",
613
- "Domain can not be resolved! there is a problem in your domain": "دامنه قابل دسترسی نیست! در دامنه شما مشکلی وجود دارد.",
614
614
  "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.": "دامنه انتخاب شده برای REALITY در همان ASN نیست. برای استفاده بهتر از این پروتکل، بهتر است یک دامنه در همان ASN پیدا کنید.",
615
615
  "User activated!": "یوزر شما فعال شد",
616
616
  "Package ended!": "پکیج شما به پایان رسید",
@@ -607,10 +607,10 @@
607
607
  "description": "Shadowsocks é um proxy de túnel rápido que ajuda a contornar firewalls."
608
608
  }
609
609
  },
610
+ "Domain can not be resolved! there is a problem in your domain": "O domínio não pode ser resolvido! Há um problema em seu domínio. Verifique as configurações do seu Domínio.",
610
611
  "Error! auto cdn ip can not be find, please contact admin.": "Erro no Auto CDN IP! Não pode ser encontrado, entre em contato com o administrador",
611
612
  "Owner can not be deleted!": "",
612
613
  "This domain does not exist in the panel!": "Este Domínio não existe no Painel!",
613
- "Domain can not be resolved! there is a problem in your domain": "O domínio não pode ser resolvido! Há um problema em seu domínio. Verifique as configurações do seu Domínio.",
614
614
  "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.": "O domínio selecionado para REALITY não está no mesmo ASN.\nPara melhor aproveitamento do Protocolo, é melhor encontrar um Domínio com o mesmo ASN",
615
615
  "User activated!": "Usuário ativado",
616
616
  "Package ended!": "Package encerrado",
@@ -607,10 +607,10 @@
607
607
  "description": "Shadowsocks — это быстрый туннельный прокси, который помогает обходить брандмауэры."
608
608
  }
609
609
  },
610
+ "Domain can not be resolved! there is a problem in your domain": "Не возможно определить IP адрес для домена! В вашем домене возникла проблема. Пожалуйста, проверьте настройки.",
610
611
  "Error! auto cdn ip can not be find, please contact admin.": "Ошибка в IP-адресе Auto CDN! Невозможно найти, обратитесь к администратору",
611
612
  "Owner can not be deleted!": "",
612
613
  "This domain does not exist in the panel!": "Этого домена не существует в панели управления!",
613
- "Domain can not be resolved! there is a problem in your domain": "Не возможно определить IP адрес для домена! В вашем домене возникла проблема. Пожалуйста, проверьте настройки.",
614
614
  "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.": "Выбранный домен для REALITY не находится в том же ASN. Для более эффективного использования протокола лучше найти Домен в том же ASN",
615
615
  "User activated!": "Пользователь активирован",
616
616
  "Package ended!": "Пакет закончился",
@@ -607,10 +607,10 @@
607
607
  "description": "Shadowsocks 是一种快速隧道代理,可帮助您绕过防火墙。"
608
608
  }
609
609
  },
610
+ "Domain can not be resolved! there is a problem in your domain": "域名无法解析!您的域有问题。请检查您的域配置。",
610
611
  "Error! auto cdn ip can not be find, please contact admin.": "自动 CDN IP 错误!找不到,请联系管理员",
611
612
  "Owner can not be deleted!": "",
612
613
  "This domain does not exist in the panel!": "该域名在面板中不存在!",
613
- "Domain can not be resolved! there is a problem in your domain": "域名无法解析!您的域有问题。请检查您的域配置。",
614
614
  "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.": "REALITY 的所选域不在同一 ASN 中。为了更好地使用该协议,最好在同一 ASN 中找到一个域",
615
615
  "User activated!": "用户激活",
616
616
  "Package ended!": "套餐已结束",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hiddifypanel
3
- Version: 9.0.0.dev92
3
+ Version: 10.7.0.dev94
4
4
  Summary: hiddifypanel multi proxy panel
5
5
  Home-page: https://github.com/hiddify/hiddify-manager/
6
6
  Author: hiddify
@@ -1,6 +1,6 @@
1
1
  hiddifypanel/Events.py,sha256=AlnRdjVul0jP-NCT4-zoaQgowoOo-JhdQB4ytetAFKA,723
2
- hiddifypanel/VERSION,sha256=KTbWwCeSQxulaRvw1ounuOOfeMlaeMylsANf_6VbW14,12
3
- hiddifypanel/VERSION.py,sha256=bj4_-wqgBFZBLVPsFNoNZScPWgcWFBlF5rFSzbCkFJE,117
2
+ hiddifypanel/VERSION,sha256=2FkiNHntl0isrdA8kJvzSAW-6X6gotQHT-yUzMVXe7k,13
3
+ hiddifypanel/VERSION.py,sha256=jfF2cqaHHoQqTveCUWbFBFKsnSkplFbn8RNIxppwT2A,118
4
4
  hiddifypanel/__init__.py,sha256=aLukp3ORszdcH4G9J-MlxhjHN6yFlOuOE6mm-L3aG_g,266
5
5
  hiddifypanel/__main__.py,sha256=IVchnXpK6bm8T3N--mN17HBQNLMeLAjyP7iwzULexB4,218
6
6
  hiddifypanel/auth.py,sha256=ouAFprxAfsbeuC-YFGkMyA1Z4dtWzixv8DqB7nQXrtA,6640
@@ -17,7 +17,7 @@ hiddifypanel/hutils/__init__.py,sha256=WmKsyIqxQNoWpme7szk8j8PCT6TODGiXSU16pxDeg
17
17
  hiddifypanel/hutils/auth.py,sha256=CoT25nrneWaAnRtx7qDE0v4WkdCeV3ra78VqEN48jeE,3031
18
18
  hiddifypanel/hutils/convert.py,sha256=8GDlewbeRWGjXONxEk-M7fUwlYZ2-D0vi-UHf0XRLmE,1764
19
19
  hiddifypanel/hutils/encode.py,sha256=IEjD8iiX-CYQ60Bi4wUsn7d-T5pbdz20oJUZlmanzXY,729
20
- hiddifypanel/hutils/flask.py,sha256=fjD7lPHykL2zUdBKYKdzhLzNa85juGNfgM42ap38vZs,9568
20
+ hiddifypanel/hutils/flask.py,sha256=3pR5We_AQVPGq1KtuwD62f_zOqP7XY-H0OW3uxa19Og,9943
21
21
  hiddifypanel/hutils/github_issue.py,sha256=8YMFDa4pgFeFCYXM3Tqp1WB9nxkpECno8_udvrEC0gg,6496
22
22
  hiddifypanel/hutils/random.py,sha256=BFDzAZSnf26eyzHRdA_qGQzT2H8jmzMFopaJSUlHsMU,1685
23
23
  hiddifypanel/hutils/system.py,sha256=nX7ZvmXKfHu6_cFVOGZRG-7ch2glqgzQL2iWraQc4S0,4350
@@ -50,7 +50,7 @@ hiddifypanel/panel/cf_api.py,sha256=lkkKb4ozSEfOXXcYrTMj9RsRfrI-xSd6ui0npFZfzYg,
50
50
  hiddifypanel/panel/cli.py,sha256=stf6kNsfMGHFKrgeNeI9CqoFfSW_fGJZjIn6GcrRYjM,9410
51
51
  hiddifypanel/panel/common.py,sha256=7_wlBe55dgb5whbo1RqSLZsJ6qbRdF4hNQbebcqKg1E,7385
52
52
  hiddifypanel/panel/custom_widgets.py,sha256=9qI_fNX8NKqB1r8ljgcaisGZaDM89_PM_rOBZbGaTYs,2506
53
- hiddifypanel/panel/hiddify.py,sha256=8LgTHI9ZOSEbRdp_fiZlGMZomfZqlAR4EOKWwdDY30Q,21723
53
+ hiddifypanel/panel/hiddify.py,sha256=xn0fHfMBb9zcWP_2Czle746_Z2wY90bKzQ39phf13bU,21398
54
54
  hiddifypanel/panel/init_db.py,sha256=jyCWw6zmvsoMrkCDIMPaUtd2SWnO4F_5ciioYnnd-as,31387
55
55
  hiddifypanel/panel/run_commander.py,sha256=D9y-My0xSe2adHWXKV5UPYGl-9WwKURzniq55MRu6tE,3259
56
56
  hiddifypanel/panel/usage.py,sha256=RBEuN4kDMbePFWRlRvFblAlFyLizdZhDHlW_AyxzXQ0,4141
@@ -62,8 +62,8 @@ hiddifypanel/panel/admin/Dashboard.py,sha256=i-k6bK9mTViN1iApMGR4AqwPr3pO14QXf4L
62
62
  hiddifypanel/panel/admin/DomainAdmin.py,sha256=ihmb_1ckRum6jJzIGLFdR2M_d2NvOaDnA_W9W1-BRzc,14625
63
63
  hiddifypanel/panel/admin/NodeAdmin.py,sha256=utJsYrZiK3hA1q3R0GMsEX03u-mxywsMr9z89_1bXjE,2995
64
64
  hiddifypanel/panel/admin/ProxyAdmin.py,sha256=m2hfQcDXf8MOQ7BsP1dk2zoxlndAfzRLPnCJ4OADA80,5247
65
- hiddifypanel/panel/admin/QuickSetup.py,sha256=fkBNdSQhwUMZcslnymCGkwIbCYu2xJAvAQWPTM9XYW0,7733
66
- hiddifypanel/panel/admin/SettingAdmin.py,sha256=G82-BIcA_QrtVBZIgSPv6XgRCaXJaa9lC32zTgjutOg,16418
65
+ hiddifypanel/panel/admin/QuickSetup.py,sha256=X8d492PLQu8vNtabh-X2R2IDZVs_5pmWeyn-Qz5_qXk,7560
66
+ hiddifypanel/panel/admin/SettingAdmin.py,sha256=Sb3cbpKre9SPQu5KoC88rK8utHDpccI3AGzYOcGxDig,15903
67
67
  hiddifypanel/panel/admin/Terminal.py,sha256=fjLVLspXYHOwZGyMU_KbytWe1zf-m6KbmvBPEDps45w,1737
68
68
  hiddifypanel/panel/admin/UserAdmin.py,sha256=NwxSVrm8Sz6wIh-fcSNth6atHb0QzXVA0B6oLYmdZy8,17091
69
69
  hiddifypanel/panel/admin/__init__.py,sha256=hb0A2HuK_nBZRCNPumwahXX-25FMxODKYlNbk2ItF08,3015
@@ -115,12 +115,12 @@ hiddifypanel/panel/admin/templates/model/admin_list.html,sha256=lpjiAl7kR5xb0fLp
115
115
  hiddifypanel/panel/admin/templates/model/domain_list.html,sha256=rrPYKISPXcwYreMp2MrJb-sEL9-6dCZF_dk6ejObrm8,414
116
116
  hiddifypanel/panel/admin/templates/model/user_list.html,sha256=n46ymDd1FwYclN0MKmsjGEw9BBOI-jd0PMQjTy3aNSo,4898
117
117
  hiddifypanel/panel/commercial/ParentDomainAdmin.py,sha256=n3X7_PuQBr2zlP6K5A0EHmtRdI9Vy49YORim_9L2QFA,4886
118
- hiddifypanel/panel/commercial/ProxyDetailsAdmin.py,sha256=ZAl78L1xbuYFGhL_z6j0plVeRu8sG_Mn9FzgiFL_YV8,2774
118
+ hiddifypanel/panel/commercial/ProxyDetailsAdmin.py,sha256=_j3oeRlLWgHDlFmxaGYaYYCPhugOJE9c84yo7flTuQ4,2809
119
119
  hiddifypanel/panel/commercial/__init__.py,sha256=YF5r5nSOCMof9NTPRtWbkHbRXfSBroOdwvyjdMCqXbo,2245
120
120
  hiddifypanel/panel/commercial/restapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
- hiddifypanel/panel/commercial/restapi/v1/__init__.py,sha256=YYdI5ayZ9wnCh2eOTs03xsJf8lCNmde0GRfHmkYz40w,1207
121
+ hiddifypanel/panel/commercial/restapi/v1/__init__.py,sha256=PKpT6Jdh37udexOnOdsvA681nqStGY-jqalEBB9_utU,1208
122
122
  hiddifypanel/panel/commercial/restapi/v1/resources.py,sha256=D7HTLAW-KA_Ikm9VArN2FSARfyCPKHxr3WEs_y4_HTM,4691
123
- hiddifypanel/panel/commercial/restapi/v1/tgbot.py,sha256=-8bZBtk6eHCpB99kK-zOqVOgY974CWU8VHfEpnavs_w,2070
123
+ hiddifypanel/panel/commercial/restapi/v1/tgbot.py,sha256=jgbLuwH9vvDOi4T1LeowqBsEUI3V4mgmR24s0RkMO14,2069
124
124
  hiddifypanel/panel/commercial/restapi/v1/tgmsg.py,sha256=alqwRD_kfG0tUzxvzR9fgfgeW7flgJPBXOvzzsYCj6g,2873
125
125
  hiddifypanel/panel/commercial/restapi/v2/DTO.py,sha256=X4UqDY0EiWMECuiNVmCYuzZUi6yY0dXwnkXSCEdeV84,244
126
126
  hiddifypanel/panel/commercial/restapi/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -152,7 +152,7 @@ hiddifypanel/panel/common_bp/login.py,sha256=wNfH7rzYtmanrIityKQhhVvUJooC658QhSE
152
152
  hiddifypanel/panel/common_bp/templates/login.html,sha256=jDl9-Nh2qMuCsLQmXm7e5jvSaRAlBxReVVCbNSTTHJw,1312
153
153
  hiddifypanel/panel/user/__init__.py,sha256=n-BkHg0CtVfJyQtrBW6Rve98CVI9MmqbrpLsdm7DY48,1884
154
154
  hiddifypanel/panel/user/link_maker.html,sha256=g420NAm_fUI8asYjyfCiXyUOIwEQfDPonZA9xh3p0-8,177
155
- hiddifypanel/panel/user/link_maker.py,sha256=Lj4m2tixva2QD4tAV-05do6DvjoczI8NOiXkaFKEHjI,43670
155
+ hiddifypanel/panel/user/link_maker.py,sha256=14LLR4tcLHPKB6FXzqaoBwN0ECGfQtde5FwmuCXWJwk,43678
156
156
  hiddifypanel/panel/user/user.py,sha256=KBRhVTIqNjkbO4lXv4MxHH4jOf8Pymnju-5DhFD1LFU,13582
157
157
  hiddifypanel/panel/user/templates/all_configs copy.txt,sha256=o3Re6RYpNzbJp_BHWy9u4ArZfZXxalEpmXbyLdZGUw0,520
158
158
  hiddifypanel/panel/user/templates/all_configs.txt,sha256=VG-3kcr8XnxgNtnsdiUIbJH4j8oeYi4giLemPOHb_d4,1232
@@ -793,24 +793,24 @@ hiddifypanel/templates/redirect.html,sha256=K9x_O4P96vEkqBhOXIhoGrWw1KIqd2bL0BjI
793
793
  hiddifypanel/templates/static.html,sha256=jp6q4wtx-k2A_cjqJoNiMS7Ee30arE45qI3ev4d5ky4,165
794
794
  hiddifypanel/templates/hiddify-flask-admin/actions.html,sha256=2NeITe2e-lPKCk_o511tCIqVtrPu8LYHE1wTCtrFUrI,1331
795
795
  hiddifypanel/templates/hiddify-flask-admin/list.html,sha256=MBGrTqZpzNLe4sZy0RozvXNr8seFUQc2C6v88BJtNWc,11095
796
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=GvSNdPw_-k-Gqtokw8QPt0HXFQwXHdN8oUArfJ4QvHo,71212
797
- hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=nMhJR9hiN-8QkiLcXq9VXIDVs2afqos3gKOv7UH-oIk,74257
798
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=-qWeoxcylSF5tf2T9Znn8oPl0a0XWHyYqyBuqrpo7JU,93735
799
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=pKvNLAsLMFxIgriEhk3kXiSh4zjxZEi_3eYrIc14Icg,97666
800
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=WRwl1piWQ2nI54ftZzefKVbJR29EYJqzymMWN1HE4hg,67756
801
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256=3D1SIYbMDe6E0YXnn8l8-LSxBc0C8Ku6BmU8ulzRa7g,72252
802
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=CR0_e8bKJrA7y5XCb-l0pGCbx-8honY7YN4biZ1jtsE,92168
803
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=W1l03ywkXGd-Nx6OOVxH7BfgT84sqeV35BmPOwyDJEw,97319
804
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=BRiTTjADKhYX13RjxFQG3x_SWC9mZ0NljEOlIE0FRTc,63409
805
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=MSUGsBKq-6sAoR1G2dNbsEkd0bODfVfoUW3g3iHsK5U,67321
806
- hiddifypanel/translations.i18n/en.json,sha256=-S-bgJraurABhHWzSUcZR1ro-DNblumvOXedrhQm6oI,64654
807
- hiddifypanel/translations.i18n/fa.json,sha256=MtmxBNf7TpxJMLdtRQYOh7U_4wN4cm6DvedzJTlAJCE,88072
808
- hiddifypanel/translations.i18n/pt.json,sha256=YTHc_nFDUBtsr-OHZzBuZ_Uoeb0MbCCwf3ctcVeM7dA,62820
809
- hiddifypanel/translations.i18n/ru.json,sha256=Av1hw-2GcUE8JIbdLe5RZj5R3GHh5VWVHUY0_c5WSsE,87812
810
- hiddifypanel/translations.i18n/zh.json,sha256=-kwcMrAxAFIn1uXU72sbLR9sEOdXrxk9YnZpdL02VAE,58339
811
- hiddifypanel-9.0.0.dev92.dist-info/LICENSE.md,sha256=oDrt-cUsyiDGnRPjEJh-3dH2ddAuK_bIVBD8ntkOtZw,19807
812
- hiddifypanel-9.0.0.dev92.dist-info/METADATA,sha256=jZA7yRZXbmJieCLbL4SH9cG4y39IEnlHS2LkcMh-CqI,3983
813
- hiddifypanel-9.0.0.dev92.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
814
- hiddifypanel-9.0.0.dev92.dist-info/entry_points.txt,sha256=Xzpqlh3nwBtZhoV9AANJykano056VJvYzaujxPztJaM,60
815
- hiddifypanel-9.0.0.dev92.dist-info/top_level.txt,sha256=rv-b3qFWUZQTBy0kyBfsr7L6tPpeO7AaQlLHXn-HI5M,13
816
- hiddifypanel-9.0.0.dev92.dist-info/RECORD,,
796
+ hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=_Z8Ka5_gsgGEkkv2Sx7F3kS-TdgamxKzvR5ka-L59gc,71212
797
+ hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=PdqmjhczZKb-eKYLvsO-e8SaUuSG83Gq8KjseBzwg0A,74257
798
+ hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=j6gdBlPC60-R-iixHizy8gFi9fDZtsFCZSE5a4V8H5Y,93735
799
+ hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=unE7BZLDXl8-APVYi-9nkx-OKTU3UKq88p_K7bgqc2Y,97666
800
+ hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=TAbz6pXtRNHKVG4KvggoJ17l3-AOfwwms9b7AW-iUJo,67756
801
+ hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256=00DzSudMS8G05nqiGd2yttopZi5DrwxfnpKEpfUJCp4,72252
802
+ hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=qVW2y4t8Q0r8F4MO7lcZjlREyYC4kA4LE4Rl8D9gqf0,92168
803
+ hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=1aWEKxonc3m_CtBuUpmDiRTnrwmkj7-k5lSRSSUt-Ek,97319
804
+ hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=LRGqx_HbdaWG9_NNwAP1cPxIVKYhfq0QoS9ZoLcu-oU,63409
805
+ hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=T-FPBVi1eXsx7CvoH5Zt5OY8kYQ2AKt62GRQJPT1WQs,67321
806
+ hiddifypanel/translations.i18n/en.json,sha256=_LZ0fZ-mSyehDNPKelnT7OrXG-sMzaLmjIqkLy3FMjA,64654
807
+ hiddifypanel/translations.i18n/fa.json,sha256=vJPdvuT_X_i0l2hoGn5-wMbROBp89TE_FLdGeqb1-j4,88072
808
+ hiddifypanel/translations.i18n/pt.json,sha256=HfcDQfH6cXtzEkfTTcS9Ds47Gw1-LUv4yTywu3RcbFk,62820
809
+ hiddifypanel/translations.i18n/ru.json,sha256=tTUB5k6vRR6jG2MMqmkgct6njUpndS5aE7WF3mMCxfw,87812
810
+ hiddifypanel/translations.i18n/zh.json,sha256=Px8w8IVT-MSMgfiWGRPDEgTh4g0qjEZF8OMHxXKtawY,58339
811
+ hiddifypanel-10.7.0.dev94.dist-info/LICENSE.md,sha256=oDrt-cUsyiDGnRPjEJh-3dH2ddAuK_bIVBD8ntkOtZw,19807
812
+ hiddifypanel-10.7.0.dev94.dist-info/METADATA,sha256=oepvqVnyT8Uipyj_MKbYIf4zRgB9myRB0CZJkIlSV4A,3984
813
+ hiddifypanel-10.7.0.dev94.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
814
+ hiddifypanel-10.7.0.dev94.dist-info/entry_points.txt,sha256=Xzpqlh3nwBtZhoV9AANJykano056VJvYzaujxPztJaM,60
815
+ hiddifypanel-10.7.0.dev94.dist-info/top_level.txt,sha256=rv-b3qFWUZQTBy0kyBfsr7L6tPpeO7AaQlLHXn-HI5M,13
816
+ hiddifypanel-10.7.0.dev94.dist-info/RECORD,,