modoboa 2.4.10__py3-none-any.whl → 2.4.11__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.
- modoboa/admin/api/v1/serializers.py +1 -0
- modoboa/admin/api/v2/serializers.py +1 -1
- modoboa/admin/api/v2/tests.py +11 -1
- modoboa/admin/lib.py +1 -1
- modoboa/admin/models/mailbox.py +15 -13
- modoboa/admin/models/mxrecord.py +4 -0
- modoboa/admin/tests/test_import_.py +11 -11
- modoboa/core/api/v2/serializers.py +9 -0
- modoboa/core/api/v2/tests.py +18 -0
- modoboa/core/api/v2/urls.py +5 -0
- modoboa/core/api/v2/views.py +20 -1
- modoboa/core/app_settings.py +11 -0
- modoboa/core/fido2_auth.py +1 -2
- modoboa/core/management/commands/cleanlogs.py +9 -0
- modoboa/core/tests/test_core.py +5 -0
- modoboa/core/utils.py +3 -0
- modoboa/dnstools/api/v2/serializers.py +9 -11
- modoboa/frontend_dist/assets/{AccountAliasForm-DVXatAhB.js → AccountAliasForm-BV6KvTu6.js} +1 -1
- modoboa/frontend_dist/assets/{AccountEditView-DmvQjxpx.js → AccountEditView-DDOFyfBD.js} +1 -1
- modoboa/frontend_dist/assets/AccountLayout-rX51xgxT.js +1 -0
- modoboa/frontend_dist/assets/{AccountPasswordSubForm-g3IEGrgM.js → AccountPasswordSubForm-D9S6LaeH.js} +1 -1
- modoboa/frontend_dist/assets/AccountView-cmvaZNq3.js +1 -0
- modoboa/frontend_dist/assets/{AddressBook-3RoKiKon.js → AddressBook-DCJxL8SU.js} +1 -1
- modoboa/frontend_dist/assets/AdminLayout-r0wfG2lO.js +1 -0
- modoboa/frontend_dist/assets/{AlarmsView-D3Mh8ntf.js → AlarmsView-C0bqC4PA.js} +1 -1
- modoboa/frontend_dist/assets/{AliasEditView-C15eUZ11.js → AliasEditView-DVoWoCGY.js} +1 -1
- modoboa/frontend_dist/assets/{AliasRecipientForm-DVZXWaUX.js → AliasRecipientForm-IOae6sjF.js} +1 -1
- modoboa/frontend_dist/assets/{AliasView-Cyvc5vMb.js → AliasView-DrONZXOh.js} +1 -1
- modoboa/frontend_dist/assets/{AuditTrailView-LI2XuLLn.js → AuditTrailView-OTkoZaMU.js} +1 -1
- modoboa/frontend_dist/assets/{CalendarView-BpOlPh3f.js → CalendarView-CqF4_Ui9.js} +1 -1
- modoboa/frontend_dist/assets/{ChoiceField-7eU7c_rI.js → ChoiceField-DJ_c78Cm.js} +1 -1
- modoboa/frontend_dist/assets/{ComposeEmailForm-CNfI7ept.js → ComposeEmailForm-DO5_GB3e.js} +1 -1
- modoboa/frontend_dist/assets/ComposeEmailView-A91HCBsN.js +1 -0
- modoboa/frontend_dist/assets/{ConfirmDialog-BvqxQsD1.js → ConfirmDialog-BBcgdAnO.js} +1 -1
- modoboa/frontend_dist/assets/ConnectedLayout-1oRW-Rql.js +1 -0
- modoboa/frontend_dist/assets/{ConnectedLayout-BaJZ3BeR.css → ConnectedLayout-Dvwmicnc.css} +1 -1
- modoboa/frontend_dist/assets/CreationForm-71YJbjsA.js +1 -0
- modoboa/frontend_dist/assets/DashboardView-CdLpSfUl.js +1 -0
- modoboa/frontend_dist/assets/{DashboardView-BLlMi6Qb.css → DashboardView-gwwVAPvt.css} +1 -1
- modoboa/frontend_dist/assets/DomainAdminList-BjC4KsqI.js +1 -0
- modoboa/frontend_dist/assets/{DomainEditView-DocxeOeW.js → DomainEditView-CQjKwYxl.js} +1 -1
- modoboa/frontend_dist/assets/{DomainTransportForm-DPnPGBOp.js → DomainTransportForm-C2xo0Yd7.js} +1 -1
- modoboa/frontend_dist/assets/DomainView-BhhuZI_N.js +5 -0
- modoboa/frontend_dist/assets/DomainsView-Cft4BP8Z.js +1 -0
- modoboa/frontend_dist/assets/{EmailField-BEKxuYni.js → EmailField-C8umy0EU.js} +1 -1
- modoboa/frontend_dist/assets/{EmailView-BsR1Wes5.js → EmailView-ki7uEQPD.js} +1 -1
- modoboa/frontend_dist/assets/EmptyLayout-DaA1XH9n.js +1 -0
- modoboa/frontend_dist/assets/{FiltersView-5rmpC5cC.js → FiltersView-FYFZxG4B.js} +1 -1
- modoboa/frontend_dist/assets/ForwardEmailView-cUbnSYCF.js +1 -0
- modoboa/frontend_dist/assets/{HtmlEditor-uM4AtIGi.js → HtmlEditor-CJ9umKeO.js} +1 -1
- modoboa/frontend_dist/assets/{IdentitiesView-jmuItyMZ.css → IdentitiesView-0ziuQ5s-.css} +1 -1
- modoboa/frontend_dist/assets/IdentitiesView-njNo8N5n.js +1 -0
- modoboa/frontend_dist/assets/{InformationView-CghcvPn2.js → InformationView-D1h38POt.js} +1 -1
- modoboa/frontend_dist/assets/{LoadingData-CVD2Aen8.js → LoadingData-CYwX3Jpn.js} +1 -1
- modoboa/frontend_dist/assets/{LoginCallbackView-sWzBke1g.js → LoginCallbackView-E01qkKn0.js} +1 -1
- modoboa/frontend_dist/assets/{LoginView-wmN73W0f.js → LoginView-Cy4uFV9h.js} +1 -1
- modoboa/frontend_dist/assets/{MailboxView-T_p-_ZtJ.js → MailboxView-IlrLWm_H.js} +1 -1
- modoboa/frontend_dist/assets/{MenuItems-kHCMzR5E.js → MenuItems-BAtHWzAE.js} +1 -1
- modoboa/frontend_dist/assets/MessagesView-OSpjixFq.js +1 -0
- modoboa/frontend_dist/assets/{MigrationsView-7kjqPyYU.js → MigrationsView-DKNOsVzF.js} +1 -1
- modoboa/frontend_dist/assets/{ParametersForm-BCeQljir.js → ParametersForm-BZM0QSvg.js} +1 -1
- modoboa/frontend_dist/assets/ParametersView-C4bXASiq.js +1 -0
- modoboa/frontend_dist/assets/ParametersView-CYXgNmc1.js +1 -0
- modoboa/frontend_dist/assets/{ProviderEditView-DDLMOylC.js → ProviderEditView-CyxCWTST.js} +1 -1
- modoboa/frontend_dist/assets/{ProviderGeneralForm-BwOSKNHK.js → ProviderGeneralForm-BYPjNHqB.js} +1 -1
- modoboa/frontend_dist/assets/ProvidersView-CxrMkRyk.js +1 -0
- modoboa/frontend_dist/assets/ReplyEmailView-Dkw9-N26.js +1 -0
- modoboa/frontend_dist/assets/{ResourcesForm-D87PHeH0.js → ResourcesForm-CuUvrOdY.js} +1 -1
- modoboa/frontend_dist/assets/SettingsView-BxLJBFY0.js +6 -0
- modoboa/frontend_dist/assets/{StatisticsView-CM__Eqku.js → StatisticsView-BN7QsZMT.js} +1 -1
- modoboa/frontend_dist/assets/{TimeSerieChart-C6j0uYR_.js → TimeSerieChart-BMN8BeFZ.js} +1 -1
- modoboa/frontend_dist/assets/UserLayout-B6-JQg4F.js +1 -0
- modoboa/frontend_dist/assets/{VAlert-B7mzOJIO.js → VAlert-DIQTrRif.js} +1 -1
- modoboa/frontend_dist/assets/{VApp-BKxnjOoi.js → VApp-CpkYA7js.js} +1 -1
- modoboa/frontend_dist/assets/{VAutocomplete-Cc4_tcl1.js → VAutocomplete-C4IpXyl8.js} +1 -1
- modoboa/frontend_dist/assets/{VAvatar-BAgTUIvX.js → VAvatar-Lpb-Dion.js} +1 -1
- modoboa/frontend_dist/assets/{VCard-DFWiFORP.js → VCard-er_isjE_.js} +1 -1
- modoboa/frontend_dist/assets/{VCheckbox-CKsH_vq3.js → VCheckbox-D-u8JXP1.js} +1 -1
- modoboa/frontend_dist/assets/{VCheckboxBtn-j7di4leN.js → VCheckboxBtn-Dt810gWf.js} +1 -1
- modoboa/frontend_dist/assets/{VChip-nZ0uhY7t.js → VChip-B4iSpj8_.js} +1 -1
- modoboa/frontend_dist/assets/{VColorPicker-Os2aeP6J.js → VColorPicker-BAjGDsXv.js} +1 -1
- modoboa/frontend_dist/assets/VContainer-DvTbsotR.js +1 -0
- modoboa/frontend_dist/assets/{VDataTable-D_0_xJTl.js → VDataTable-4JRjbtgF.js} +1 -1
- modoboa/frontend_dist/assets/{VDataTableServer-BWTt4Mzi.js → VDataTableServer-tIDT1m3-.js} +1 -1
- modoboa/frontend_dist/assets/{VDataTableVirtual-BwVmkt4u.js → VDataTableVirtual-BlnO18u_.js} +1 -1
- modoboa/frontend_dist/assets/{VDialog-CZqM2Ofu.js → VDialog-Bk6EWNhz.js} +1 -1
- modoboa/frontend_dist/assets/{VExpansionPanels-B5D6GOa3.js → VExpansionPanels-CwGtXDhr.js} +1 -1
- modoboa/frontend_dist/assets/{VFileInput-Cv9DIPki.js → VFileInput-D1_7ZkO_.js} +1 -1
- modoboa/frontend_dist/assets/{VForm-CpoZf60D.js → VForm-DAkW4nfy.js} +1 -1
- modoboa/frontend_dist/assets/{VMenu-B_dVqOmo.js → VMenu-BPFJwj2f.js} +1 -1
- modoboa/frontend_dist/assets/{VPicker-CXkIGEze.js → VPicker-CfT82M8N.js} +1 -1
- modoboa/frontend_dist/assets/{VProgressCircular-CrEXxs7k.js → VProgressCircular-w75-3ogi.js} +1 -1
- modoboa/frontend_dist/assets/{VRadioGroup-D8ypjYOO.js → VRadioGroup-0j6DNC_k.js} +1 -1
- modoboa/frontend_dist/assets/{VRow-C_Ydf6yr.js → VRow-BF35mT1S.js} +1 -1
- modoboa/frontend_dist/assets/{VSelect-CS51PDEt.js → VSelect-Cs4ARbAS.js} +1 -1
- modoboa/frontend_dist/assets/{VSelectionControl-DiOqtY38.js → VSelectionControl-Dg-XyRRS.js} +1 -1
- modoboa/frontend_dist/assets/VSheet-Btq_Mu4s.js +1 -0
- modoboa/frontend_dist/assets/VSpacer-C7xukQmu.js +1 -0
- modoboa/frontend_dist/assets/{VSwitch-Chg5o-Cp.js → VSwitch-Cs1NQrmk.js} +1 -1
- modoboa/frontend_dist/assets/{VTable-KsiZ3cBz.js → VTable-CNz2SGk4.js} +1 -1
- modoboa/frontend_dist/assets/{VTabs-tNrJIYO0.js → VTabs-B1fyVn4M.js} +1 -1
- modoboa/frontend_dist/assets/{VTextField-CLwRV0Cb.js → VTextField-BdyvgvkG.js} +1 -1
- modoboa/frontend_dist/assets/{VTextarea-Di8jbl8m.js → VTextarea-DnOMpe0Q.js} +1 -1
- modoboa/frontend_dist/assets/{VToolbar-CGwhgdmI.js → VToolbar-BiCiBxBJ.js} +1 -1
- modoboa/frontend_dist/assets/{VWindowItem-wWSFAGI-.js → VWindowItem-ChWm_kz3.js} +1 -1
- modoboa/frontend_dist/assets/WebmailLayout-o4uEkp9e.js +1 -0
- modoboa/frontend_dist/assets/admin-o-HRGnmT.js +1 -0
- modoboa/frontend_dist/assets/{aliases-c3n-dCV_.js → aliases-DDVeehyg.js} +1 -1
- modoboa/frontend_dist/assets/{contacts-Bqckz8sr.js → contacts-C84DY-Q1.js} +1 -1
- modoboa/frontend_dist/assets/{domains-nBMR-fRf.js → domains-Bgn4ixHL.js} +1 -1
- modoboa/frontend_dist/assets/{domains.store-ChZgLcqP.js → domains.store-DTE-V7Y1.js} +1 -1
- modoboa/frontend_dist/assets/{filter-D7NrAf6a.js → filter-CnffiQAW.js} +1 -1
- modoboa/frontend_dist/assets/{forwardRefs-Cpc3YYl6.js → forwardRefs-Dvjn_Xq4.js} +1 -1
- modoboa/frontend_dist/assets/{global.store-DUP26-A5.js → global.store-BaiD63EN.js} +1 -1
- modoboa/frontend_dist/assets/{importExport-Dn9vYw7T.js → importExport-BlQYb0NO.js} +1 -1
- modoboa/frontend_dist/assets/index-DuzUMVLM.js +1 -0
- modoboa/frontend_dist/assets/index-I1VDlN4g.js +984 -0
- modoboa/frontend_dist/assets/layout-D8ZJPiJ_.js +1 -0
- modoboa/frontend_dist/assets/{layout.store-BxBoBlgf.js → layout.store-DkjrAoXt.js} +1 -1
- modoboa/frontend_dist/assets/logos-q8SEyAa4.js +1 -0
- modoboa/frontend_dist/assets/{logs-DrTzylW7.js → logs-B7IJ7LBa.js} +1 -1
- modoboa/frontend_dist/assets/{parameters-Lgiqp7aw.js → parameters-A6iBEYQq.js} +1 -1
- modoboa/frontend_dist/assets/{parameters.store-C9k9DuTj.js → parameters.store-BiXS4_6w.js} +1 -1
- modoboa/frontend_dist/assets/{permissions-mL5hLHcW.js → permissions-CITHLHVg.js} +1 -1
- modoboa/frontend_dist/assets/{ssrBoot-BsxW6uW4.js → ssrBoot-AzTdjPjk.js} +1 -1
- modoboa/frontend_dist/assets/{tag-CFK9dzMJ.js → tag-BnSYRTcD.js} +1 -1
- modoboa/frontend_dist/assets/transports-Dz7c6kIy.js +1 -0
- modoboa/frontend_dist/assets/{webmail-KrD8ZhNM.js → webmail-CSH_3l6R.js} +1 -1
- modoboa/frontend_dist/index.html +1 -1
- modoboa/lib/redis.py +1 -5
- modoboa/locale/ja_JP/LC_MESSAGES/django.mo +0 -0
- modoboa/locale/ja_JP/LC_MESSAGES/django.po +122 -263
- {modoboa-2.4.10.dist-info → modoboa-2.4.11.dist-info}/METADATA +1 -1
- {modoboa-2.4.10.dist-info → modoboa-2.4.11.dist-info}/RECORD +139 -138
- modoboa/frontend_dist/assets/AccountLayout-OGtZvlHR.js +0 -1
- modoboa/frontend_dist/assets/AccountView-DsxYqr3k.js +0 -1
- modoboa/frontend_dist/assets/AdminLayout-CWfn8zaQ.js +0 -1
- modoboa/frontend_dist/assets/ComposeEmailView-B866Xsrc.js +0 -1
- modoboa/frontend_dist/assets/ConnectedLayout-BQ3ug6Jh.js +0 -1
- modoboa/frontend_dist/assets/CreationForm-C9Kh05ax.js +0 -1
- modoboa/frontend_dist/assets/DashboardView-Cw-gIcuB.js +0 -1
- modoboa/frontend_dist/assets/DomainAdminList-CsWUNKVk.js +0 -1
- modoboa/frontend_dist/assets/DomainView-Djc_0PsF.js +0 -5
- modoboa/frontend_dist/assets/DomainsView-B-Lxru7P.js +0 -1
- modoboa/frontend_dist/assets/EmptyLayout-BzPFOeLU.js +0 -1
- modoboa/frontend_dist/assets/ForwardEmailView-D7MbetcT.js +0 -1
- modoboa/frontend_dist/assets/IdentitiesView-BqjD9Lue.js +0 -1
- modoboa/frontend_dist/assets/MessagesView-Cerv3xsy.js +0 -1
- modoboa/frontend_dist/assets/ParametersView-DspBxVMV.js +0 -1
- modoboa/frontend_dist/assets/ParametersView-Dy0H5ep1.js +0 -1
- modoboa/frontend_dist/assets/ProvidersView-C99UD0WB.js +0 -1
- modoboa/frontend_dist/assets/ReplyEmailView-DAPBHldd.js +0 -1
- modoboa/frontend_dist/assets/SettingsView-OxDo9wNd.js +0 -6
- modoboa/frontend_dist/assets/UserLayout-CckCGnPS.js +0 -1
- modoboa/frontend_dist/assets/VContainer-Btam4lk2.js +0 -1
- modoboa/frontend_dist/assets/VSheet-5VVWtHvs.js +0 -1
- modoboa/frontend_dist/assets/VSpacer-C6PZ3X24.js +0 -1
- modoboa/frontend_dist/assets/WebmailLayout-DsYThBrz.js +0 -1
- modoboa/frontend_dist/assets/admin-CJVLMHh9.js +0 -1
- modoboa/frontend_dist/assets/index-DV9Li2cg.js +0 -852
- modoboa/frontend_dist/assets/index-DzL89N4E.js +0 -1
- modoboa/frontend_dist/assets/layout-CHO37cA6.js +0 -1
- modoboa/frontend_dist/assets/transports-TO08iTXJ.js +0 -1
- {modoboa-2.4.10.data → modoboa-2.4.11.data}/scripts/modoboa-admin.py +0 -0
- {modoboa-2.4.10.dist-info → modoboa-2.4.11.dist-info}/WHEEL +0 -0
- {modoboa-2.4.10.dist-info → modoboa-2.4.11.dist-info}/entry_points.txt +0 -0
- {modoboa-2.4.10.dist-info → modoboa-2.4.11.dist-info}/licenses/LICENSE +0 -0
- {modoboa-2.4.10.dist-info → modoboa-2.4.11.dist-info}/top_level.txt +0 -0
|
@@ -731,7 +731,7 @@ class CSVImportSerializer(serializers.Serializer):
|
|
|
731
731
|
class CSVIdentityImportSerializer(CSVImportSerializer):
|
|
732
732
|
"""Custom serializer for identity import."""
|
|
733
733
|
|
|
734
|
-
|
|
734
|
+
crypt_passwords = serializers.BooleanField()
|
|
735
735
|
|
|
736
736
|
|
|
737
737
|
class AlarmSerializer(serializers.ModelSerializer):
|
modoboa/admin/api/v2/tests.py
CHANGED
|
@@ -331,6 +331,16 @@ class AccountViewSetTestCase(ModoAPITestCase):
|
|
|
331
331
|
resp = self.client.patch(url, data, format="json")
|
|
332
332
|
self.assertEqual(resp.status_code, 200)
|
|
333
333
|
|
|
334
|
+
def test_update_quota(self):
|
|
335
|
+
account = core_models.User.objects.get(username="user@test.com")
|
|
336
|
+
url = reverse("v2:account-detail", args=[account.pk])
|
|
337
|
+
data = {
|
|
338
|
+
"mailbox": {"quota": 1},
|
|
339
|
+
}
|
|
340
|
+
resp = self.client.patch(url, data, format="json")
|
|
341
|
+
self.assertEqual(resp.status_code, 200)
|
|
342
|
+
self.assertEqual(account.mailbox.quota, data["mailbox"]["quota"])
|
|
343
|
+
|
|
334
344
|
def test_user_updates_password(self):
|
|
335
345
|
account = core_models.User.objects.get(username="user@test.com")
|
|
336
346
|
self.authenticate_user(account)
|
|
@@ -583,7 +593,7 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com
|
|
|
583
593
|
) # NOQA:E501
|
|
584
594
|
self.client.post(
|
|
585
595
|
reverse("v2:identities-import-from-csv"),
|
|
586
|
-
{"sourcefile": f, "
|
|
596
|
+
{"sourcefile": f, "crypt_passwords": True},
|
|
587
597
|
)
|
|
588
598
|
admin = core_models.User.objects.get(username="admin")
|
|
589
599
|
u1 = core_models.User.objects.get(username="user1@test.com")
|
modoboa/admin/lib.py
CHANGED
|
@@ -138,7 +138,7 @@ def import_domainalias(user, row, formopts):
|
|
|
138
138
|
def import_account(user, row, formopts):
|
|
139
139
|
"""Specific code for accounts import"""
|
|
140
140
|
account = User()
|
|
141
|
-
account.from_csv(user, row, formopts["
|
|
141
|
+
account.from_csv(user, row, formopts["crypt_passwords"])
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
def _import_alias(user, row, **kwargs):
|
modoboa/admin/models/mailbox.py
CHANGED
|
@@ -295,19 +295,21 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject):
|
|
|
295
295
|
def update_from_dict(self, user, values):
|
|
296
296
|
"""Update mailbox from a dictionary."""
|
|
297
297
|
newaddress = None
|
|
298
|
-
if
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
298
|
+
if "email" in values:
|
|
299
|
+
if values["email"] != self.full_address:
|
|
300
|
+
newaddress = values["email"]
|
|
301
|
+
elif (
|
|
302
|
+
self.user.role == "SimpleUsers"
|
|
303
|
+
and self.user.username != self.full_address
|
|
304
|
+
):
|
|
305
|
+
newaddress = self.user.username
|
|
306
|
+
if newaddress is not None:
|
|
307
|
+
local_part, domname = split_mailbox(newaddress)
|
|
308
|
+
domain = Domain.objects.filter(name=domname).first()
|
|
309
|
+
if domain is None:
|
|
310
|
+
raise lib_exceptions.NotFound(_("Domain does not exist"))
|
|
311
|
+
if not user.can_access(domain):
|
|
312
|
+
raise lib_exceptions.PermDeniedException
|
|
311
313
|
if "use_domain_quota" in values:
|
|
312
314
|
self.use_domain_quota = values["use_domain_quota"]
|
|
313
315
|
if "use_domain_quota" in values or "quota" in values:
|
modoboa/admin/models/mxrecord.py
CHANGED
|
@@ -71,6 +71,10 @@ class MXRecord(models.Model):
|
|
|
71
71
|
def __str__(self):
|
|
72
72
|
return f"{self.name} ({self.address}) for {self.domain} "
|
|
73
73
|
|
|
74
|
+
@property
|
|
75
|
+
def active_dnsbl_results(self):
|
|
76
|
+
return self.dnsblresult_set.exclude(status="")
|
|
77
|
+
|
|
74
78
|
|
|
75
79
|
class DNSBLQuerySet(models.QuerySet):
|
|
76
80
|
"""Custom manager for DNSBLResultManager."""
|
|
@@ -88,7 +88,7 @@ account; user1@nonlocal.com; toto; User; One; True; SimpleUsers; user1@nonlocal.
|
|
|
88
88
|
name="identities.csv",
|
|
89
89
|
) # NOQA:E501
|
|
90
90
|
url = reverse("v2:identities-import-from-csv")
|
|
91
|
-
self.client.post(url, {"sourcefile": f, "
|
|
91
|
+
self.client.post(url, {"sourcefile": f, "crypt_passwords": True})
|
|
92
92
|
self.assertFalse(User.objects.filter(username="user1@nonlocal.com").exists())
|
|
93
93
|
|
|
94
94
|
def test_import_invalid_quota(self):
|
|
@@ -99,7 +99,7 @@ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; ; t
|
|
|
99
99
|
name="identities.csv",
|
|
100
100
|
) # NOQA:E501
|
|
101
101
|
url = reverse("v2:identities-import-from-csv")
|
|
102
|
-
resp = self.client.post(url, {"sourcefile": f, "
|
|
102
|
+
resp = self.client.post(url, {"sourcefile": f, "crypt_passwords": True})
|
|
103
103
|
self.assertIn("wrong quota value", resp.content.decode())
|
|
104
104
|
|
|
105
105
|
def test_import_domain_by_domainadmin(self):
|
|
@@ -114,7 +114,7 @@ domain; domain2.com; 1000; 200; False
|
|
|
114
114
|
name="identities.csv",
|
|
115
115
|
)
|
|
116
116
|
url = reverse("v2:identities-import-from-csv")
|
|
117
|
-
resp = self.client.post(url, {"sourcefile": f, "
|
|
117
|
+
resp = self.client.post(url, {"sourcefile": f, "crypt_passwords": True})
|
|
118
118
|
self.assertIn("You are not allowed to import domains", resp.content.decode())
|
|
119
119
|
f = ContentFile(
|
|
120
120
|
b"""
|
|
@@ -122,7 +122,7 @@ domainalias; domalias1.com; test.com; True
|
|
|
122
122
|
""",
|
|
123
123
|
name="identities.csv",
|
|
124
124
|
)
|
|
125
|
-
resp = self.client.post(url, {"sourcefile": f, "
|
|
125
|
+
resp = self.client.post(url, {"sourcefile": f, "crypt_passwords": True})
|
|
126
126
|
self.assertIn(
|
|
127
127
|
"You are not allowed to import domain aliases", resp.content.decode()
|
|
128
128
|
)
|
|
@@ -138,7 +138,7 @@ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 40
|
|
|
138
138
|
)
|
|
139
139
|
resp = self.client.post(
|
|
140
140
|
reverse("v2:identities-import-from-csv"),
|
|
141
|
-
{"sourcefile": f, "
|
|
141
|
+
{"sourcefile": f, "crypt_passwords": True},
|
|
142
142
|
)
|
|
143
143
|
self.assertIn("test.com: domain quota exceeded", resp.content.decode())
|
|
144
144
|
|
|
@@ -151,7 +151,7 @@ account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com
|
|
|
151
151
|
)
|
|
152
152
|
self.client.post(
|
|
153
153
|
reverse("v2:identities-import-from-csv"),
|
|
154
|
-
{"sourcefile": f, "
|
|
154
|
+
{"sourcefile": f, "crypt_passwords": True},
|
|
155
155
|
)
|
|
156
156
|
account = User.objects.get(username="user1@test.com")
|
|
157
157
|
self.assertEqual(
|
|
@@ -168,7 +168,7 @@ account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 0;
|
|
|
168
168
|
) # NOQA:E501
|
|
169
169
|
self.client.post(
|
|
170
170
|
reverse("v2:identities-import-from-csv"),
|
|
171
|
-
{"sourcefile": f, "
|
|
171
|
+
{"sourcefile": f, "crypt_passwords": True, "continue_if_exists": True},
|
|
172
172
|
)
|
|
173
173
|
admin = User.objects.get(username="admin")
|
|
174
174
|
u1 = User.objects.get(username="truc@test.com")
|
|
@@ -189,7 +189,7 @@ account; sa@test.com; toto; Super; Admin; True; SuperAdmins; superadmin@test.com
|
|
|
189
189
|
) # NOQA:E501
|
|
190
190
|
self.client.post(
|
|
191
191
|
reverse("v2:identities-import-from-csv"),
|
|
192
|
-
{"sourcefile": f, "
|
|
192
|
+
{"sourcefile": f, "crypt_passwords": True, "continue_if_exists": True},
|
|
193
193
|
)
|
|
194
194
|
with self.assertRaises(User.DoesNotExist):
|
|
195
195
|
User.objects.get(username="sa@test.com")
|
|
@@ -203,7 +203,7 @@ alias;user.alias@test.com;True;user@test.com;;;;;;;;;;;;;;;;
|
|
|
203
203
|
)
|
|
204
204
|
self.client.post(
|
|
205
205
|
reverse("v2:identities-import-from-csv"),
|
|
206
|
-
{"sourcefile": f, "
|
|
206
|
+
{"sourcefile": f, "crypt_passwords": True, "continue_if_exists": True},
|
|
207
207
|
)
|
|
208
208
|
alias = Alias.objects.get(address="user.alias@test.com")
|
|
209
209
|
self.assertEqual(alias.type, "alias")
|
|
@@ -218,7 +218,7 @@ alias;user@test.com;True;admin@test.com
|
|
|
218
218
|
)
|
|
219
219
|
self.client.post(
|
|
220
220
|
reverse("v2:identities-import-from-csv"),
|
|
221
|
-
{"sourcefile": f, "
|
|
221
|
+
{"sourcefile": f, "crypt_passwords": True},
|
|
222
222
|
)
|
|
223
223
|
self.assertTrue(
|
|
224
224
|
Alias.objects.filter(address="user@test.com", internal=False).exists()
|
|
@@ -315,7 +315,7 @@ alias; alias1@test.com; True; user1@test.com
|
|
|
315
315
|
) # NOQA:E501
|
|
316
316
|
resp = self.client.post(
|
|
317
317
|
reverse("v2:identities-import-from-csv"),
|
|
318
|
-
{"sourcefile": f, "
|
|
318
|
+
{"sourcefile": f, "crypt_passwords": True},
|
|
319
319
|
)
|
|
320
320
|
self.assertEqual(resp.status_code, 200)
|
|
321
321
|
|
|
@@ -188,6 +188,7 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
|
|
|
188
188
|
inactive_account_threshold = serializers.IntegerField(default=30)
|
|
189
189
|
top_notifications_check_interval = serializers.IntegerField(default=30)
|
|
190
190
|
log_maximum_age = serializers.IntegerField(default=365)
|
|
191
|
+
message_history_maximum_age = serializers.IntegerField(default=180)
|
|
191
192
|
items_per_page = serializers.IntegerField(default=30)
|
|
192
193
|
default_top_redirection = serializers.ChoiceField(
|
|
193
194
|
default="user", choices=[("user", _("User profile"))], required=False
|
|
@@ -691,3 +692,11 @@ class ThemeSerializer(serializers.Serializer):
|
|
|
691
692
|
theme_primary_color_light = serializers.CharField(default="#3688F9")
|
|
692
693
|
theme_secondary_color = serializers.CharField(default="#F18429")
|
|
693
694
|
theme_label_color = serializers.CharField(default="#616161")
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
class StatisticsSerializer(serializers.Serializer):
|
|
698
|
+
|
|
699
|
+
domain_count = serializers.IntegerField()
|
|
700
|
+
domain_alias_count = serializers.IntegerField()
|
|
701
|
+
account_count = serializers.IntegerField()
|
|
702
|
+
alias_count = serializers.IntegerField()
|
modoboa/core/api/v2/tests.py
CHANGED
|
@@ -658,3 +658,21 @@ class NewsFeedAPIViewTestCase(ModoAPITestCase):
|
|
|
658
658
|
response = self.client.get(url)
|
|
659
659
|
self.assertEqual(response.status_code, 200)
|
|
660
660
|
self.assertIn("modoboa", response.json()[0]["link"])
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
class StatisticsAPIViewTestCase(ModoAPITestCase):
|
|
664
|
+
|
|
665
|
+
@classmethod
|
|
666
|
+
def setUpTestData(cls):
|
|
667
|
+
"""Create test data."""
|
|
668
|
+
super().setUpTestData()
|
|
669
|
+
factories.populate_database()
|
|
670
|
+
|
|
671
|
+
def test_get_statistics(self):
|
|
672
|
+
url = reverse("v2:statistics")
|
|
673
|
+
response = self.client.get(url)
|
|
674
|
+
self.assertEqual(response.status_code, 200)
|
|
675
|
+
stats = response.json()
|
|
676
|
+
self.assertEqual(stats["domain_count"], 2)
|
|
677
|
+
self.assertEqual(stats["account_count"], 5)
|
|
678
|
+
self.assertEqual(stats["alias_count"], 3)
|
modoboa/core/api/v2/urls.py
CHANGED
|
@@ -42,6 +42,11 @@ urlpatterns += [
|
|
|
42
42
|
views.NewsFeedAPIView.as_view(),
|
|
43
43
|
name="news-feed",
|
|
44
44
|
),
|
|
45
|
+
path(
|
|
46
|
+
"admin/statistics/",
|
|
47
|
+
views.StatisticsAPIView.as_view(),
|
|
48
|
+
name="statistics",
|
|
49
|
+
),
|
|
45
50
|
path("capabilities/", views.CapabilitiesAPIView.as_view(), name="capabilities"),
|
|
46
51
|
path("theme/", views.ThemeAPIView.as_view(), name="theme"),
|
|
47
52
|
]
|
modoboa/core/api/v2/views.py
CHANGED
|
@@ -14,7 +14,8 @@ from drf_spectacular.utils import extend_schema
|
|
|
14
14
|
from rest_framework import permissions, response
|
|
15
15
|
from rest_framework.views import APIView
|
|
16
16
|
|
|
17
|
-
from modoboa.
|
|
17
|
+
from modoboa.admin import models as admin_models
|
|
18
|
+
from modoboa.core import models, signals
|
|
18
19
|
from modoboa.core.utils import check_for_updates, get_capabilities
|
|
19
20
|
from modoboa.lib.permissions import IsSuperUser, IsPrivilegedUser
|
|
20
21
|
from modoboa.lib.throttle import (
|
|
@@ -226,3 +227,21 @@ class NewsFeedAPIView(APIView):
|
|
|
226
227
|
|
|
227
228
|
serializer = serializers.NewsFeedEntrySerializer(entries, many=True)
|
|
228
229
|
return response.Response(serializer.data)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
class StatisticsAPIView(APIView):
|
|
233
|
+
"""Return some statistics about this modoboa instance."""
|
|
234
|
+
|
|
235
|
+
permission_classes = [permissions.IsAuthenticated, IsSuperUser]
|
|
236
|
+
throttle_classes = [UserLesserDdosUser]
|
|
237
|
+
|
|
238
|
+
@extend_schema(responses=serializers.StatisticsSerializer())
|
|
239
|
+
def get(self, request, *args, **kwargs):
|
|
240
|
+
data = {
|
|
241
|
+
"domain_count": admin_models.Domain.objects.count(),
|
|
242
|
+
"domain_alias_count": admin_models.DomainAlias.objects.count(),
|
|
243
|
+
"account_count": models.User.objects.count(),
|
|
244
|
+
"alias_count": admin_models.Alias.objects.filter(internal=False).count(),
|
|
245
|
+
}
|
|
246
|
+
serializer = serializers.StatisticsSerializer(data)
|
|
247
|
+
return response.Response(serializer.data)
|
modoboa/core/app_settings.py
CHANGED
|
@@ -720,6 +720,17 @@ GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict(
|
|
|
720
720
|
),
|
|
721
721
|
},
|
|
722
722
|
),
|
|
723
|
+
(
|
|
724
|
+
"message_history_maximum_age",
|
|
725
|
+
{
|
|
726
|
+
"label": gettext_lazy(
|
|
727
|
+
"Retention time in message history"
|
|
728
|
+
),
|
|
729
|
+
"help_text": gettext_lazy(
|
|
730
|
+
"Retention time (in days) of a message in the message history section"
|
|
731
|
+
),
|
|
732
|
+
},
|
|
733
|
+
),
|
|
723
734
|
(
|
|
724
735
|
"items_per_page",
|
|
725
736
|
{
|
modoboa/core/fido2_auth.py
CHANGED
|
@@ -34,10 +34,9 @@ def begin_registration(request):
|
|
|
34
34
|
),
|
|
35
35
|
list(get_creds_from_user(request.user.pk).values()),
|
|
36
36
|
user_verification=UserVerificationRequirement.DISCOURAGED,
|
|
37
|
-
extensions={"credentialProtectionPolicy": "userVerificationOptional"},
|
|
38
37
|
)
|
|
39
38
|
request.session["fido2_state"] = state
|
|
40
|
-
return options
|
|
39
|
+
return dict(options)
|
|
41
40
|
|
|
42
41
|
|
|
43
42
|
def end_registration(request):
|
|
@@ -5,6 +5,7 @@ from django.core.management.base import BaseCommand
|
|
|
5
5
|
from django.utils import timezone
|
|
6
6
|
|
|
7
7
|
from modoboa.core.models import Log
|
|
8
|
+
from modoboa.maillog.models import Maillog
|
|
8
9
|
from modoboa.parameters import tools as param_tools
|
|
9
10
|
|
|
10
11
|
|
|
@@ -41,4 +42,12 @@ class Command(BaseCommand):
|
|
|
41
42
|
self.__vprint(f"Deleting logs older than {log_maximum_age} days...")
|
|
42
43
|
limit = timezone.now() - datetime.timedelta(log_maximum_age)
|
|
43
44
|
Log.objects.filter(date_created__lt=limit).delete()
|
|
45
|
+
message_history_maximum_age = param_tools.get_global_parameter(
|
|
46
|
+
"message_history_maximum_age"
|
|
47
|
+
)
|
|
48
|
+
self.__vprint(
|
|
49
|
+
f"Deleting messages in history older than {message_history_maximum_age} days..."
|
|
50
|
+
)
|
|
51
|
+
limit = timezone.now() - datetime.timedelta(message_history_maximum_age)
|
|
52
|
+
Maillog.objects.filter(date__lt=limit).delete()
|
|
44
53
|
self.__vprint("Done.")
|
modoboa/core/tests/test_core.py
CHANGED
|
@@ -16,6 +16,7 @@ from django.urls import reverse
|
|
|
16
16
|
from django.utils import timezone
|
|
17
17
|
|
|
18
18
|
from modoboa.lib.tests import ModoTestCase, SimpleModoTestCase
|
|
19
|
+
from modoboa.maillog import factories as maillog_factories, models as maillog_models
|
|
19
20
|
from .. import factories, mocks, models
|
|
20
21
|
|
|
21
22
|
|
|
@@ -60,12 +61,16 @@ class ManagementCommandsTestCase(SimpleModoTestCase):
|
|
|
60
61
|
|
|
61
62
|
def test_clean_logs(self):
|
|
62
63
|
"""Run cleanlogs command."""
|
|
64
|
+
management.call_command("load_initial_data", "--no-frontend")
|
|
63
65
|
log1 = factories.LogFactory()
|
|
64
66
|
factories.LogFactory()
|
|
65
67
|
log1.date_created -= relativedelta(years=2)
|
|
66
68
|
log1.save(update_fields=["date_created"])
|
|
69
|
+
maillog_factories.MaillogFactory(date=timezone.now() - relativedelta(days=190))
|
|
70
|
+
maillog_factories.MaillogFactory()
|
|
67
71
|
management.call_command("cleanlogs")
|
|
68
72
|
self.assertEqual(models.Log.objects.count(), 1)
|
|
73
|
+
self.assertEqual(maillog_models.Maillog.objects.count(), 1)
|
|
69
74
|
|
|
70
75
|
def test_init_data_non_duplicate_client_creation(self):
|
|
71
76
|
"""Test that the load_initial_data command does not create duplicates
|
modoboa/core/utils.py
CHANGED
|
@@ -111,4 +111,7 @@ def get_capabilities():
|
|
|
111
111
|
if is_rspamd_installed:
|
|
112
112
|
rspamd_options = get_rspamd_options()
|
|
113
113
|
capabilities.update({"rspamd": rspamd_options})
|
|
114
|
+
# IMAP migration
|
|
115
|
+
if "modoboa.imap_migration" in settings.MODOBOA_APPS:
|
|
116
|
+
capabilities.update({"imap_migration": {}})
|
|
114
117
|
return capabilities
|
|
@@ -7,22 +7,22 @@ from modoboa.admin import models as admin_models
|
|
|
7
7
|
from ... import models
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class
|
|
11
|
-
"""Serializer for
|
|
10
|
+
class DNSBLResultSerializer(serializers.ModelSerializer):
|
|
11
|
+
"""Serializer for DNSBLResult."""
|
|
12
12
|
|
|
13
13
|
class Meta:
|
|
14
|
-
model = admin_models.
|
|
15
|
-
fields = ("
|
|
14
|
+
model = admin_models.DNSBLResult
|
|
15
|
+
fields = ("provider", "status")
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
class
|
|
19
|
-
"""Serializer for
|
|
18
|
+
class MXRecordSerializer(serializers.ModelSerializer):
|
|
19
|
+
"""Serializer for MXRecord."""
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
dnsbl_results = DNSBLResultSerializer(many=True, source="active_dnsbl_results")
|
|
22
22
|
|
|
23
23
|
class Meta:
|
|
24
|
-
model = admin_models.
|
|
25
|
-
fields = ("
|
|
24
|
+
model = admin_models.MXRecord
|
|
25
|
+
fields = ("name", "address", "dnsbl_results", "updated")
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class DNSRecordSerializer(serializers.ModelSerializer):
|
|
@@ -41,13 +41,11 @@ class DNSDetailSerializer(serializers.ModelSerializer):
|
|
|
41
41
|
spf_record = DNSRecordSerializer()
|
|
42
42
|
dkim_record = DNSRecordSerializer()
|
|
43
43
|
dmarc_record = DNSRecordSerializer()
|
|
44
|
-
dnsbl_results = DNSBLResultSerializer(many=True, source="dnsblresult_set")
|
|
45
44
|
|
|
46
45
|
class Meta:
|
|
47
46
|
model = admin_models.Domain
|
|
48
47
|
fields = (
|
|
49
48
|
"mx_records",
|
|
50
|
-
"dnsbl_results",
|
|
51
49
|
"autoconfig_record",
|
|
52
50
|
"autodiscover_record",
|
|
53
51
|
"spf_record",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as
|
|
1
|
+
import{C as q}from"./ChoiceField-DJ_c78Cm.js";import{u as N,b as S,g as V,h as f,i as _,c as R,o as y,w as h,a as d,f as s,e as U,t as x,l as M,k as C,L as D,n as j,m as Q,F as G,G as T,N as H}from"./index-I1VDlN4g.js";import{V as P,a as L}from"./VRow-BF35mT1S.js";import{V as B}from"./VAlert-DIQTrRif.js";import{d as z}from"./VAvatar-Lpb-Dion.js";import{V as k,r as F}from"./VForm-DAkW4nfy.js";import{_ as K}from"./AccountPasswordSubForm-D9S6LaeH.js";import{E as I}from"./EmailField-C8umy0EU.js";import{V as E}from"./VTextField-BdyvgvkG.js";import{V as $}from"./VSwitch-Cs1NQrmk.js";import{u as Y}from"./domains.store-DTE-V7Y1.js";import{V as J}from"./VChip-B4iSpj8_.js";const W={class:"headline"},X={class:"mt-4"},_e={__name:"AccountRoleForm",props:{modelValue:{type:Object,default:null}},setup(g,{expose:w}){const i=N(),{$gettext:a}=S(),v=g,m=V(),c=f(()=>v.modelValue),l=f(()=>i.authUser),p=f(()=>{const n=b.value.find(r=>r.value===c.value.role);return n!==void 0?n.label:""}),e=f(()=>{const n=b.value.find(r=>r.value===c.value.role);return n!==void 0?n.help:""}),b=f(()=>l.value.role===_.SUPER_ADMIN?[...A,...o,...u,...t]:l.value.role===_.DOMAIN_ADMIN?[...A]:l.value.role===_.RESELLER?[...o,...A]:[]),A=[{label:a("Simple user"),value:_.USER,help:a("A user with no privileges but with a mailbox. He will be allowed to use all end-user features: webmail, calendar, contacts, filters.")}],o=[{label:a("Domain administrator"),value:_.DOMAIN_ADMIN,help:a("A user with privileges on one or more domain. He will be allowed to administer mailboxes and he can also have a mailbox.")}],u=[{label:a("Reseller"),value:_.RESELLER,help:a("An intermediate user who has the same privileges than a Domain administrator, plus the possibility to create domains and to assign resources.")}],t=[{label:a("Super administrator"),value:_.SUPER_ADMIN,help:a("A user with all privileges, can do anything. By default, such a user does not have a mailbox so he can't access end-user features.")}];return w({vFormRef:m,roleLabel:p}),(n,r)=>(y(),R(k,{ref_key:"vFormRef",ref:m},{default:h(()=>[d(P,null,{default:h(()=>[d(L,{cols:"7"},{default:h(()=>[d(s(q),{modelValue:c.value.role,"onUpdate:modelValue":r[0]||(r[0]=O=>c.value.role=O),label:s(a)("Choose a role"),choices:b.value,"choices-per-line":2},null,8,["modelValue","label","choices"])]),_:1}),d(L,{cols:"5"},{default:h(()=>[d(B,{color:"primary",class:"mt-11 ml-4 rounded-lg"},{default:h(()=>[U("h3",W,x(p.value),1),U("p",X,x(e.value),1),d(z,{color:"white",class:"float-right",size:"large",icon:"mdi-help-circle-outline"})]),_:1})]),_:1})]),_:1})]),_:1},512))}},Z={class:"m-label"},ee={class:"m-label"},le={class:"m-label"},Ve={__name:"AccountGeneralForm",props:{modelValue:{type:Object,default:null},editing:{type:Boolean,default:!1}},setup(g,{expose:w}){const{$gettext:i}=S(),a=N(),v=g,m=V(),c=V({}),l=f(()=>v.modelValue),p=f(()=>l.value.role===_.USER?i("Enter an email address"):i("Enter a simple username or an email address")),e=f(()=>l.value.role===_.USER?"email":"text");function b(){l.value.username.indexOf("@")!==-1&&(l.value.mailbox.full_address=l.value.username,l.value.mailbox.message_limit=null)}return w({vFormRef:m,formErrors:c}),(A,o)=>(y(),R(k,{ref_key:"vFormRef",ref:m},{default:h(()=>[U("label",Z,x(s(i)("Username")),1),d(I,{ref:"username",modelValue:l.value.username,"onUpdate:modelValue":[o[0]||(o[0]=u=>l.value.username=u),b],placeholder:p.value,type:e.value,rules:e.value==="email"?[s(F).required,s(F).email]:[s(F).required],role:l.value.role,"error-msg":c.value.value?c.value.value.username:[]},null,8,["modelValue","placeholder","type","rules","role","error-msg"]),U("label",ee,x(s(i)("First name")),1),d(E,{modelValue:l.value.first_name,"onUpdate:modelValue":o[1]||(o[1]=u=>l.value.first_name=u),autocomplete:"new-password",variant:"outlined",density:"compact"},null,8,["modelValue"]),U("label",le,x(s(i)("Last name")),1),d(E,{modelValue:l.value.last_name,"onUpdate:modelValue":o[2]||(o[2]=u=>l.value.last_name=u),autocomplete:"new-password",variant:"outlined",density:"compact"},null,8,["modelValue"]),s(a).authUser.pk!==l.value.pk?(y(),R(K,{key:0,ref:"passwordForm",modelValue:l.value,"onUpdate:modelValue":o[3]||(o[3]=u=>l.value=u),editing:g.editing,"form-errors":c.value},null,8,["modelValue","editing","form-errors"])):(y(),R(B,{key:1,type:"info",variant:"tonal",class:"py-2"},{default:h(()=>[M(x(s(i)("You can update your password from the Account section")),1)]),_:1})),d($,{modelValue:l.value.is_active,"onUpdate:modelValue":o[4]||(o[4]=u=>l.value.is_active=u),label:s(i)("Enabled"),density:"compact",color:"primary"},null,8,["modelValue","label"])]),_:1},512))}},ae={class:"m-label"},oe={class:"m-label"},te={__name:"AccountMailboxForm",props:{modelValue:{type:Object,default:null}},emits:["update:modelValue"],setup(g,{expose:w,emit:i}){const{$gettext:a}=S(),v=i,m=g,c=Y(),l=f(()=>c.domains),p=V(),e=V({mailbox:{}});D(m.modelValue,t=>{t?(e.value={...t},e.value.role===_.USER&&(e.value.mailbox||(e.value.mailbox={}),e.value.mailbox.full_address=e.value.username),e.value.mailbox.message_limit===""&&(e.value.mailbox.message_limit=null)):e.value={mailbox:{}}},{immediate:!0}),D(e,t=>{v("update:modelValue",t)},{deep:!0});const b=f(()=>{const t=e.value.mailbox.full_address;if(t&&t.indexOf("@")!==-1){const n=l.value.find(r=>r.name===t.split("@")[1]);if(n)return parseInt(n.default_mailbox_quota)}}),A=f(()=>{let t=a("Use domain default value");return b.value!==void 0&&(b.value===0?t+=` (${a("unlimited")})`:t+=` (${b.value} MB)`),t});function o(t){t&&delete e.value.mailbox.quota}function u(t){t===""&&(e.value.mailbox.message_limit=null)}return w({vFormRef:p}),(t,n)=>(y(),R(k,{ref_key:"vFormRef",ref:p},{default:h(()=>[U("label",ae,x(s(a)("Quota")),1),d($,{modelValue:e.value.mailbox.use_domain_quota,"onUpdate:modelValue":[n[0]||(n[0]=r=>e.value.mailbox.use_domain_quota=r),o],label:A.value,color:"primary"},null,8,["modelValue","label"]),e.value.mailbox.use_domain_quota?j("",!0):(y(),R(E,{key:0,modelValue:e.value.mailbox.quota,"onUpdate:modelValue":n[1]||(n[1]=r=>e.value.mailbox.quota=r),placeholder:s(a)("Ex: 10MB. Leave empty for no limit"),hint:s(a)("Quota for this mailbox, can be expressed in KB, MB (default) or GB. Define a custom value or use domain's default one. Leave empty to define an unlimited value (not allowed for domain administrators)."),"persistent-hint":"",variant:"outlined",density:"compact"},null,8,["modelValue","placeholder","hint"])),U("label",oe,x(s(a)("Daily message sending limit")),1),d(E,{modelValue:e.value.mailbox.message_limit,"onUpdate:modelValue":[n[2]||(n[2]=r=>e.value.mailbox.message_limit=r),u],placeholder:s(a)("Leave empty for no limit"),hint:s(a)("Number of messages this mailbox can send per day. Leave empty for no limit."),"persistent-hint":"",variant:"outlined",density:"compact",rules:[s(F).numericOrNull]},null,8,["modelValue","placeholder","hint","rules"]),d($,{modelValue:e.value.mailbox.is_send_only,"onUpdate:modelValue":n[3]||(n[3]=r=>e.value.mailbox.is_send_only=r),label:s(a)("Send only account"),density:"compact",color:"primary"},null,8,["modelValue","label"])]),_:1},512))}},he=C(te,[["__scopeId","data-v-41714779"]]),xe={__name:"AccountAliasForm",props:{modelValue:{type:Object,default:null}},setup(g,{expose:w}){const{$gettext:i}=S(),a=g,v=f(()=>a.modelValue),m=V(""),c=V(),l=V(),p=V(!1),e=V([]);async function b(){if(e.value=[],p.value=!0,v.value.aliases.indexOf(m.value)!==-1){e.value=[i("Alias already added")],m.value="",p.value=!1;return}try{await H.validate({aliases:[m.value],mailbox:v.value.mailbox}),v.value.aliases.push(m.value),m.value="",l.value.resetValidation()}catch(o){o.response.data.aliases?o.response.data.aliases:o.response.data.non_field_errors&&o.response.data.non_field_errors}finally{p.value=!1}}function A(o){v.value.aliases.splice(o,1)}return w({vFormRef:l}),(o,u)=>(y(),R(k,{ref_key:"vFormRef",ref:l},{default:h(()=>[d(s(I),{ref_key:"aliasField",ref:c,modelValue:m.value,"onUpdate:modelValue":u[0]||(u[0]=t=>m.value=t),placeholder:s(i)("Start typing a name here..."),hint:s(i)("Alias(es) of this mailbox. To create a catchall alias, just enter the domain name (@domain.tld)."),"persistent-hint":"",loading:p.value,"error-msg":e.value,onDomainSelected:b},null,8,["modelValue","placeholder","hint","loading","error-msg"]),(y(!0),Q(G,null,T(v.value.aliases,(t,n)=>(y(),R(J,{key:n,class:"mr-2 mt-2",closable:"","onClick:close":r=>A(n)},{default:h(()=>[M(x(t),1)]),_:2},1032,["onClick:close"]))),128))]),_:1},512))}};export{he as A,xe as _,Ve as a,_e as b};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as
|
|
1
|
+
import{b as q,u as H,M as J,s as K,g as c,h as P,i as T,d as W,N as L,L as X,c as d,m as p,o,a,e as v,w as e,n as k,f as m,l as f,t as r,F as M,k as Y}from"./index-I1VDlN4g.js";import{b as Z,a as ee,A as ae,_ as le}from"./AccountAliasForm-BV6KvTu6.js";import{_ as te}from"./ResourcesForm-CuUvrOdY.js";import{L as oe}from"./LoadingData-CYwX3Jpn.js";import{p as se}from"./parameters-A6iBEYQq.js";import{u as ue}from"./permissions-CITHLHVg.js";import{g,d as U,V as j}from"./VAvatar-Lpb-Dion.js";import{V,c as b,a as x,b as re}from"./VExpansionPanels-CwGtXDhr.js";import{V as _,a as n}from"./VRow-BF35mT1S.js";import{V as ne,a as ie}from"./VToolbar-BiCiBxBJ.js";import"./ChoiceField-DJ_c78Cm.js";import"./VAlert-DIQTrRif.js";import"./VProgressCircular-w75-3ogi.js";import"./tag-BnSYRTcD.js";import"./VForm-DAkW4nfy.js";import"./VTextField-BdyvgvkG.js";import"./forwardRefs-Dvjn_Xq4.js";import"./ssrBoot-AzTdjPjk.js";import"./AccountPasswordSubForm-D9S6LaeH.js";import"./VSwitch-Cs1NQrmk.js";import"./VSelectionControl-Dg-XyRRS.js";import"./EmailField-C8umy0EU.js";import"./domains.store-DTE-V7Y1.js";import"./domains-Bgn4ixHL.js";import"./VChip-B4iSpj8_.js";import"./VContainer-DvTbsotR.js";/* empty css */const de={key:1},me={key:0},fe={key:0},ce={class:"mr-2"},_e={class:"mr-2"},ve={key:0},pe={class:"mr-2"},ke={class:"mr-2"},ye={class:"mr-2"},ge={key:0},Ve={class:"mr-2"},be={key:0},xe={class:"mr-2"},Fe={class:"mr-2"},we={class:"mt-4 d-flex justify-end"},he={__name:"AccountEditForm",setup(G){const{$gettext:i}=q(),N=H(),F=J(),O=K(),{canSetRole:S}=ue(),l=c({pk:F.params.id}),w=P(()=>l.value.username&&l.value.username.indexOf("@")!==-1),$=P(()=>{const t=C.value.params&&C.value.params.enable_admin_limits&&l.value.role!==T.USER&&l.value.role!==T.SUPER_ADMIN;return t===void 0?!1:t}),C=c({}),h=c(0),y=c(!1),E=c(!1),A=c(),B=c(),I=c(),D=c(),R=c(),Q=P(()=>{const t={roleForm:A,generalForm:B};return w.value&&(t.aliasForm=D,t.mailboxForm=I),$.value&&(t.resourcesForm=R),t});async function z(){E.value=!1,h.value=[];for(const[t,s]of Object.entries(Q.value))if(s.value!=null){const{valid:u}=await s.value.vFormRef.validate();u||(E.value=!0,h.value.push(t))}if(!E.value){y.value=!0;try{const t={...l.value};w.value?t.mailbox.full_address=t.username:t.mailbox&&delete t.mailbox.full_address,t.new_password&&(t.password=t.new_password,delete t.new_password,delete t.password_confirmation),$.value&&R.value!==null&&(t.resources=R.value.getPayload()),t.aliases===null&&delete t.aliases,S.value||(l.value.pk===N.authUser.pk?t.role=N.authUser.role:t.role=T.USER),await L.patch(l.value.pk,t),O.push({name:"AccountDetail",params:{id:F.params.id}})}finally{y.value=!1}}}return W(()=>{L.get(F.params.id).then(t=>{l.value=t.data,y.value=!1}),S.value&&se.getGlobalApplication("limits").then(t=>{C.value=t.data})}),X(l,()=>{delete l.value.domains,l.value.mailbox===null&&delete l.value.mailbox},{deep:!0}),(t,s)=>y.value?(o(),d(oe,{key:0})):(o(),p("div",de,[a(re,{modelValue:h.value,"onUpdate:modelValue":s[5]||(s[5]=u=>h.value=u),multiple:E.value},{default:e(()=>[m(S)?(o(),d(V,{key:0,eager:"",value:"roleForm"},{default:e(()=>[a(b,null,{default:e(({expanded:u})=>[a(_,{"no-gutters":""},{default:e(()=>[a(n,{cols:"4"},{default:e(()=>[f(r(m(i)("Role")),1)]),_:1}),a(n,{cols:"8",class:"text-medium-emphasis"},{default:e(()=>[a(g,{"leave-absolute":""},{default:e(()=>[u?(o(),p("span",me)):(o(),d(_,{key:1,"no-gutters":"",style:{width:"100%"}},{default:e(()=>[A.value?(o(),d(n,{key:0,cols:"6"},{default:e(()=>[f(r(A.value.roleLabel),1)]),_:1})):k("",!0)]),_:1}))]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:1}),a(x,null,{default:e(()=>[a(Z,{ref_key:"roleForm",ref:A,modelValue:l.value,"onUpdate:modelValue":s[0]||(s[0]=u=>l.value=u)},null,8,["modelValue"])]),_:1})]),_:1})):k("",!0),a(V,{eager:"",value:"generalForm"},{default:e(()=>[a(b,null,{default:e(({expanded:u})=>[a(_,{"no-gutters":""},{default:e(()=>[a(n,{cols:"4"},{default:e(()=>[f(r(m(i)("Identification")),1)]),_:1}),a(n,{cols:"8",class:""},{default:e(()=>[a(g,{"leave-absolute":""},{default:e(()=>[u?(o(),p("span",fe)):(o(),d(_,{key:1,"no-gutters":"",style:{width:"100%"}},{default:e(()=>[a(n,{cols:"6"},{default:e(()=>[v("div",ce,r(m(i)("Username:"))+" "+r(l.value.username),1)]),_:1}),a(n,{cols:"6"},{default:e(()=>[v("div",_e,[f(r(m(i)("Enabled"))+" ",1),l.value.is_active?(o(),d(U,{key:0,color:"success"},{default:e(()=>s[7]||(s[7]=[f("mdi-check-circle-outline")])),_:1,__:[7]})):(o(),d(U,{key:1},{default:e(()=>s[8]||(s[8]=[f("mdi-close-circle-outline")])),_:1,__:[8]}))])]),_:1})]),_:1}))]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:1}),a(x,null,{default:e(()=>[a(ee,{ref_key:"generalForm",ref:B,modelValue:l.value,"onUpdate:modelValue":s[1]||(s[1]=u=>l.value=u),editing:""},null,8,["modelValue"])]),_:1})]),_:1}),w.value?(o(),d(V,{key:1,eager:"",value:"mailboxForm"},{default:e(()=>[a(b,null,{default:e(({expanded:u})=>[a(_,{"no-gutters":""},{default:e(()=>[a(n,{cols:"4"},{default:e(()=>[f(r(m(i)("Mailbox")),1)]),_:1}),a(n,{cols:"8",class:""},{default:e(()=>[a(g,{"leave-absolute":""},{default:e(()=>[u?(o(),p("span",ve)):(o(),d(_,{key:1,"no-gutters":"",style:{width:"100%"}},{default:e(()=>[l.value.mailbox?(o(),p(M,{key:0},[l.value.mailbox.use_domain_quota?(o(),d(n,{key:0,cols:"6"},{default:e(()=>[v("div",pe,r(m(i)("Quota: "))+" "+r(m(i)("domain's default value")),1)]),_:1})):(o(),d(n,{key:1,cols:"6"},{default:e(()=>[v("div",ke,r(m(i)("Quota: "))+" "+r(l.value.mailbox.quota),1)]),_:1})),a(n,{cols:"6"},{default:e(()=>[v("div",ye,[f(r(m(i)("Send only"))+" ",1),l.value.mailbox.is_send_only?(o(),d(U,{key:0,color:"success"},{default:e(()=>s[9]||(s[9]=[f("mdi-check-circle-outline")])),_:1,__:[9]})):(o(),d(U,{key:1},{default:e(()=>s[10]||(s[10]=[f("mdi-close-circle-outline")])),_:1,__:[10]}))])]),_:1})],64)):k("",!0)]),_:1}))]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:1}),a(x,null,{default:e(()=>[a(ae,{ref_key:"mailboxForm",ref:I,modelValue:l.value,"onUpdate:modelValue":s[2]||(s[2]=u=>l.value=u)},null,8,["modelValue"])]),_:1})]),_:1})):k("",!0),w.value?(o(),d(V,{key:2,eager:"",value:"aliasForm"},{default:e(()=>[a(b,null,{default:e(({expanded:u})=>[a(_,{"no-gutters":""},{default:e(()=>[a(n,{cols:"4"},{default:e(()=>[f(r(m(i)("Alias")),1)]),_:1}),a(n,{cols:"8",class:""},{default:e(()=>[a(g,{"leave-absolute":""},{default:e(()=>[u?(o(),p("span",ge)):(o(),d(_,{key:1,"no-gutters":"",style:{width:"100%"}},{default:e(()=>[l.value.aliases?(o(),d(n,{key:0,cols:"6"},{default:e(()=>[v("div",Ve,r(m(i)("Number of associated alias:"))+" "+r(l.value.aliases.length),1)]),_:1})):k("",!0)]),_:1}))]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:1}),a(x,null,{default:e(()=>[a(le,{ref_key:"aliasForm",ref:D,modelValue:l.value,"onUpdate:modelValue":s[3]||(s[3]=u=>l.value=u)},null,8,["modelValue"])]),_:1})]),_:1})):k("",!0),$.value?(o(),d(V,{key:3,eager:"",value:"resourcesForm"},{default:e(()=>[a(b,null,{default:e(({expanded:u})=>[a(_,{"no-gutters":""},{default:e(()=>[a(n,{cols:"4"},{default:e(()=>[f(r(m(i)("Resources")),1)]),_:1}),a(n,{cols:"8",class:""},{default:e(()=>[a(g,{"leave-absolute":""},{default:e(()=>[u?(o(),p("span",be)):(o(),d(_,{key:1,"no-gutters":"",style:{width:"100%"}},{default:e(()=>[l.value.resources!=null&&l.value.resources.length==2?(o(),p(M,{key:0},[a(n,{cols:"6"},{default:e(()=>[v("div",xe,r(m(i)("Number of allowed mailboxes:"))+" "+r(l.value.resources[0].max_value),1)]),_:1}),a(n,{cols:"6"},{default:e(()=>[v("div",Fe,r(m(i)("Number of allowed mailbox aliases:"))+" "+r(l.value.resources[1].max_value),1)]),_:1})],64)):k("",!0)]),_:1}))]),_:2},1024)]),_:2},1024)]),_:2},1024)]),_:1}),a(x,null,{default:e(()=>[a(te,{ref_key:"resourcesForm",ref:R,modelValue:l.value.resources,"onUpdate:modelValue":s[4]||(s[4]=u=>l.value.resources=u)},null,8,["modelValue"])]),_:1})]),_:1})):k("",!0)]),_:1},8,["modelValue","multiple"]),v("div",we,[a(j,{loading:y.value,variant:"outlined",onClick:s[6]||(s[6]=u=>t.$router.go(-1))},{default:e(()=>[f(r(m(i)("Cancel")),1)]),_:1},8,["loading"]),a(j,{class:"ml-4",color:"primary darken-1",variant:"outlined",loading:y.value,onClick:z},{default:e(()=>[f(r(m(i)("Save")),1)]),_:1},8,["loading"])])]))}},Ee={__name:"AccountEditView",setup(G){const{$gettext:i}=q();return(N,F)=>(o(),p(M,null,[a(ne,{flat:""},{default:e(()=>[a(ie,null,{default:e(()=>[f(r(m(i)("Edit account")),1)]),_:1})]),_:1}),a(he)],64))}},ea=Y(Ee,[["__scopeId","data-v-4019c7f8"]]);export{ea as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{u as n,b as c,g as u,h as s,c as l,o as f}from"./index-I1VDlN4g.js";import{_}from"./ConnectedLayout-1oRW-Rql.js";import{p as h}from"./parameters-A6iBEYQq.js";import"./VContainer-DvTbsotR.js";/* empty css */import"./tag-BnSYRTcD.js";import"./VApp-CpkYA7js.js";import"./layout-D8ZJPiJ_.js";import"./ssrBoot-AzTdjPjk.js";import"./logos-q8SEyAa4.js";import"./global.store-BaiD63EN.js";import"./admin-o-HRGnmT.js";import"./layout.store-DkjrAoXt.js";import"./VAvatar-Lpb-Dion.js";import"./VProgressCircular-w75-3ogi.js";import"./forwardRefs-Dvjn_Xq4.js";import"./VMenu-BPFJwj2f.js";import"./VCard-er_isjE_.js";import"./VRow-BF35mT1S.js";import"./VSheet-Btq_Mu4s.js";const q={__name:"AccountLayout",setup(d){const i=n(),{$gettext:e}=c(),r=u([]),m=s(()=>i.authUser),p=s(()=>{const t=[],a={contacts:"mdi-contacts-outline",webmail:"mdi-at"};if(t.push({text:e("Settings"),to:{name:"AccountSettings"},icon:"mdi-cog"}),m.value.mailbox){t.push({text:e("Filters"),to:{name:"AccountFilters"},icon:"mdi-filter"});for(const o of r.value)t.push({icon:a[o.name],text:o.label,to:{name:"AccountParametersEdit",params:{app:o.name}}})}return t});return h.getUserApplications().then(t=>{r.value=t.data}),(t,a)=>(f(),l(_,{color:"grey","menu-items":p.value},null,8,["menu-items"]))}};export{q as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as P,
|
|
1
|
+
import{b as P,p as _,h as b,m,o as n,n as p,a as o,F as V,e as v,t as y,f as l,w as u,c as h,N as E}from"./index-I1VDlN4g.js";import{r as c}from"./VForm-DAkW4nfy.js";import{V as w}from"./VTextField-BdyvgvkG.js";import{a as g,V as N}from"./VRow-BF35mT1S.js";import{V as R}from"./VSwitch-Cs1NQrmk.js";import{V as S}from"./VAlert-DIQTrRif.js";import{V as q}from"./VAvatar-Lpb-Dion.js";const A={class:"m-label"},F={class:"text-white mr-4"},$={__name:"AccountPasswordSubForm",props:{modelValue:{type:Object,default:null},withPasswordCheck:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},editing:{type:Boolean,default:!1},formErrors:{type:Object,required:!1,default:()=>{}}},setup(s){const{$gettext:t}=P(),k=_(),r=s,e=b(()=>r.modelValue),f=b(()=>!r.disabled&&(!r.editing||e.value.password)),x=i=>i===e.value.new_password||t("Password mismatch");function C(){navigator.clipboard.writeText(e.value.new_password).then(()=>{k.displayNotification({msg:t("Password copied to clipboard")})})}function B(i){i?E.getRandomPassword().then(a=>{e.value.new_password=a.data.password}):(e.value.new_password=null,e.value.password_confirmation=null)}return(i,a)=>(n(),m("div",null,[s.withPasswordCheck?(n(),m(V,{key:0},[v("label",A,y(l(t)("Current password")),1),o(w,{modelValue:e.value.password,"onUpdate:modelValue":a[0]||(a[0]=d=>e.value.password=d),autocomplete:"new-password",variant:"outlined",type:"password",density:"compact","validate-on":"submit",rules:s.disabled?[]:[l(c).required],disabled:s.disabled,"error-messages":r.formErrors?r.formErrors.password:[]},null,8,["modelValue","rules","disabled","error-messages"])],64)):p("",!0),o(N,{justify:"center"},{default:u(()=>[o(g,{cols:"auto"},{default:u(()=>[o(R,{modelValue:e.value.random_password,"onUpdate:modelValue":[a[1]||(a[1]=d=>e.value.random_password=d),B],label:l(t)("Random password"),density:"compact",color:"primary",class:"text-center",disabled:s.disabled},null,8,["modelValue","label","disabled"])]),_:1}),o(g,null,{default:u(()=>[e.value.random_password?(n(),h(S,{key:0,style:{"background-color":"#515d78"},class:"ml-6",density:"compact"},{default:u(()=>[v("span",F,y(e.value.new_password),1),o(q,{size:"small",color:"white",variant:"text",density:"compact",disabled:s.disabled,icon:"mdi-clipboard-multiple-outline",title:l(t)("Copy to clipboard"),onClick:C},null,8,["disabled","title"])]),_:1})):p("",!0)]),_:1})]),_:1}),e.value.random_password?p("",!0):(n(),m(V,{key:1},[o(w,{modelValue:e.value.new_password,"onUpdate:modelValue":a[2]||(a[2]=d=>e.value.new_password=d),variant:"outlined",label:l(t)("Password"),type:"password",autocomplete:"new-password",density:"compact",disabled:s.disabled,rules:f.value?[l(c).required]:[]},null,8,["modelValue","label","disabled","rules"]),o(w,{modelValue:e.value.password_confirmation,"onUpdate:modelValue":a[3]||(a[3]=d=>e.value.password_confirmation=d),variant:"outlined",type:"password",label:l(t)("Confirmation"),density:"compact",disabled:s.disabled,rules:f.value?[l(c).required,x]:[],"error-messages":r.formErrors?r.formErrors.new_password:[]},null,8,["modelValue","label","disabled","rules","error-messages"])],64))]))}};export{$ as _};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as d,o,w as e,a as t,e as k,t as a,m as _,F as p,G as T,l as s,_ as N,p as P,b as q,g as x,f,n as v,k as U,M as G,N as z,i as M}from"./index-I1VDlN4g.js";import{u as Q}from"./permissions-CITHLHVg.js";import{p as H}from"./parameters-A6iBEYQq.js";import{c as A,V,a as C}from"./VCard-er_isjE_.js";import{V as J}from"./VChip-B4iSpj8_.js";import{V as K}from"./VDataTable-4JRjbtgF.js";import{V as $,d as E,e as D}from"./VAvatar-Lpb-Dion.js";import{V as W}from"./VTextField-BdyvgvkG.js";import{V as g,a as c}from"./VRow-BF35mT1S.js";import{V as X,a as Y}from"./VToolbar-BiCiBxBJ.js";import"./tag-BnSYRTcD.js";import"./VProgressCircular-w75-3ogi.js";import"./VSelect-Cs4ARbAS.js";import"./forwardRefs-Dvjn_Xq4.js";import"./ssrBoot-AzTdjPjk.js";import"./VMenu-BPFJwj2f.js";import"./VCheckboxBtn-Dt810gWf.js";import"./VSelectionControl-Dg-XyRRS.js";import"./VTable-CNz2SGk4.js";import"./filter-CnffiQAW.js";/* empty css */const Z={class:"headline"},ee={__name:"AccountAliases",props:{account:{type:Object,default:null}},setup(l){return(n,m)=>(o(),d(C,null,{default:e(()=>[t(A,null,{default:e(()=>[k("span",Z,a(n.$gettext("Aliases")),1)]),_:1}),t(V,null,{default:e(()=>[(o(!0),_(p,null,T(l.account.aliases,u=>(o(),d(J,{key:u,class:"mr-2 mt-2"},{default:e(()=>[s(a(u),1)]),_:2},1024))),128))]),_:1})]),_:1}))}},w="senderaddresses",B={getAll(){return N.get(`${w}/`)},getAllForMailbox(l){return N.get(`${w}/`,{params:{mailbox:l}})},create(l){return N.post(`${w}/`,l)},delete(l){return N.delete(`${w}/${l}/`)}},te={class:"headline"},ae={key:0},le={__name:"AccountSenderAddresses",props:{account:{type:Object,default:null}},setup(l){const n=P(),{$gettext:m}=q(),u=l,r=x([]),y=x(!1),i=x(""),F=[{title:m("Address"),key:"address"},{title:"",key:"actions",align:"end",sortable:!1}];function I(){r.value.push({}),y.value=!0}function R(){B.getAllForMailbox(u.account.mailbox.pk).then(h=>{r.value=h.data})}function L(){const h={address:i.value,mailbox:u.account.mailbox.pk};B.create(h).then(()=>{R(),i.value=null,y.value=!1,n.displayNotification({msg:m("Sender address added")})})}function O(h){B.delete(h.pk).then(()=>{R(),n.displayNotification({msg:m("Sender address deleted")})})}return R(),(h,S)=>(o(),d(C,null,{default:e(()=>[t(A,null,{default:e(()=>[k("span",te,a(f(m)("Sender addresses")),1)]),_:1}),t(V,null,{default:e(()=>[t(K,{headers:F,items:r.value,"no-data-text":f(m)("No sender address defined for this account")},{"item.address":e(({item:b})=>[b.pk?(o(),_("span",ae,a(b.address),1)):(o(),d(W,{key:1,modelValue:i.value,"onUpdate:modelValue":S[0]||(S[0]=j=>i.value=j),label:f(m)("Specify an email address")},{append:e(()=>[i.value?(o(),d($,{key:0,icon:"mdi-content-save",color:"primary",variant:"text",onClick:L})):v("",!0)]),_:1},8,["modelValue","label"]))]),"item.actions":e(({item:b})=>[b.pk?(o(),d($,{key:0,icon:"mdi-delete-outline",color:"red",title:f(m)("Remove this address"),variant:"text",onClick:j=>O(b)},null,8,["title","onClick"])):v("",!0)]),bottom:e(()=>S[1]||(S[1]=[])),_:2},1032,["items","no-data-text"]),y.value?v("",!0):(o(),d($,{key:0,size:"small",color:"primary",variant:"outlined",onClick:I},{default:e(()=>[t(E,{size:"small",icon:"mdi-plus"}),s(" "+a(f(m)("Add sender address")),1)]),_:1}))]),_:1})]),_:1}))}},ne={class:"headline"},oe={__name:"AccountSummary",props:{account:{type:Object,default:null}},setup(l){return(n,m)=>(o(),d(C,null,{default:e(()=>[t(A,null,{default:e(()=>[k("span",ne,a(n.$gettext("General information")),1)]),_:1}),t(V,null,{default:e(()=>[t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Creation date")),1)]),_:1}),t(c,{cols:"6"},{default:e(()=>[s(a(n.$date(l.account.date_joined)),1)]),_:1})]),_:1}),t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Last login date")),1)]),_:1}),l.account.last_login?(o(),d(c,{key:0,cols:"6"},{default:e(()=>[s(a(n.$date(l.account.last_login)),1)]),_:1})):(o(),d(c,{key:1,cols:"6"},{default:e(()=>[s(a(n.$gettext("Never logged-in")),1)]),_:1}))]),_:1}),t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Full name")),1)]),_:1}),t(c,{cols:"6"},{default:e(()=>[s(a(l.account.first_name)+" "+a(l.account.last_name),1)]),_:1})]),_:1}),t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Role")),1)]),_:1}),t(c,{cols:"6"},{default:e(()=>[s(a(l.account.role),1)]),_:1})]),_:1}),t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Secondary email")),1)]),_:1}),t(c,{cols:"6"},{default:e(()=>[s(a(l.account.secondary_email),1)]),_:1})]),_:1}),t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Phone number")),1)]),_:1}),t(c,{cols:"6"},{default:e(()=>[s(a(l.account.phone_number),1)]),_:1})]),_:1}),t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Enabled")),1)]),_:1}),t(c,{cols:"6"},{default:e(()=>[t(E,{color:l.account.is_active?"success":"error",icon:l.account.is_active?"mdi-check-circle":"mdi-close-circle",variant:"flat"},null,8,["color","icon"])]),_:1})]),_:1}),l.account.mailbox?(o(),_(p,{key:0},[t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Quota")),1)]),_:1}),l.account.mailbox.quota==="0"?(o(),d(c,{key:0,cols:"6"},{default:e(()=>[s(a(n.$gettext("Unlimited")),1)]),_:1})):(o(),d(c,{key:1,cols:"6"},{default:e(()=>[t(D,{color:l.account.mailbox.quota_usage<80?"primary":"warning","model-value":l.account.mailbox.quota_usage,height:"25",class:"white--text"},{default:e(({value:u})=>[s(a(Math.ceil(u))+"% ("+a(l.account.mailbox.quota)+" "+a(n.$gettext("MB"))+") ",1)]),_:1},8,["color","model-value"])]),_:1}))]),_:1}),l.account.mailbox.message_limit!==null&&l.account.mailbox.message_limit!==void 0?(o(),d(g,{key:0},{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[s(a(n.$gettext("Daily sending limit")),1)]),_:1}),t(c,{cols:"6"},{default:e(()=>[l.account.mailbox.message_limit===0?(o(),_(p,{key:0},[s(a(n.$gettext("Sending forbidden")),1)],64)):(o(),d(D,{key:1,color:l.account.mailbox.sent_messages_in_percent<80?"primary":"warning","model-value":l.account.mailbox.sent_messages_in_percent,height:"25",class:"white--text"},{default:e(({value:u})=>[s(a(Math.ceil(u))+"% ("+a(l.account.mailbox.message_limit)+" "+a(n.$gettext("messages"))+") ",1)]),_:1},8,["color","model-value"]))]),_:1})]),_:1})):v("",!0)],64)):v("",!0)]),_:1})]),_:1}))}},se={class:"headline"},ue={key:1},ce={class:"text-disabled"},ie={__name:"DomainAdminDomains",props:{account:{type:Object,default:null}},setup(l){const{$gettext:n}=q();return(m,u)=>(o(),d(C,null,{default:e(()=>[t(A,null,{default:e(()=>[k("span",se,a(f(n)("Administered domains")),1)]),_:1}),t(V,null,{default:e(()=>[l.account.domains!==void 0&&l.account.domains.length?(o(!0),_(p,{key:0},T(l.account.domains,r=>(o(),d(g,{key:r},{default:e(()=>[t(c,{cols:"12"},{default:e(()=>[s(a(r),1)]),_:2},1024)]),_:2},1024))),128)):(o(),_("div",ue,a(f(n)("No domain managed")),1)),k("div",ce,a(f(n)("Add/Remove from the domain page")),1)]),_:1})]),_:1}))}},de={class:"headline"},re={__name:"ResourcesView",props:{resources:{type:Array,default:null}},setup(l){const{$gettext:n}=q(),m=r=>r.name==="quota"?n("No quota"):n("Creation denied");function u(r){return r<50?"primary":r<80?"warning":"error"}return(r,y)=>(o(),d(C,null,{default:e(()=>[t(A,null,{default:e(()=>[k("span",de,a(f(n)("Resources usage")),1)]),_:1}),t(V,null,{default:e(()=>[(o(!0),_(p,null,T(l.resources,i=>(o(),_("div",{key:i.name,class:"mt-4"},[i.max_value===-1?(o(),_(p,{key:0},[s(a(i.label)+" ("+a(f(n)("Unlimited"))+") ",1)],64)):i.max_value===0?(o(),_(p,{key:1},[s(a(i.label)+" ("+a(m(i))+") ",1)],64)):(o(),_(p,{key:2},[s(a(i.label)+" ("+a(Math.ceil(i.usage))+"%) ",1),t(D,{"model-value":i.usage,color:u(i.usage)},null,8,["model-value","color"])],64))]))),128))]),_:1})]),_:1}))}},me={__name:"AccountView",setup(l){const n=G(),{canSetRole:m}=Q(),u=x({pk:n.params.id}),r=x({});function y(){z.get(n.params.id).then(i=>{u.value=i.data})}return m.value&&H.getGlobalApplication("limits").then(i=>{r.value=i.data}),y(),(i,F)=>(o(),_(p,null,[t(X,{flat:""},{default:e(()=>[t(Y,null,{default:e(()=>[s(a(i.$gettext("Account"))+" "+a(u.value.username)+" ",1),t($,{color:"primary",icon:"mdi-circle-edit-outline",to:{name:"AccountEdit",params:{id:u.value.pk}}},null,8,["to"]),t($,{color:"primary",icon:"mdi-reload",onClick:y})]),_:1})]),_:1}),t(g,null,{default:e(()=>[t(c,{cols:"6"},{default:e(()=>[t(oe,{account:u.value},null,8,["account"]),u.value.role===f(M).DOMAIN_ADMIN?(o(),d(ie,{key:0,class:"mt-2",account:u.value},null,8,["account"])):v("",!0)]),_:1}),t(c,{cols:"6"},{default:e(()=>[r.value.params&&r.value.params.enable_admin_limits&&u.value.role!==f(M).USER&&u.value.role!==f(M).SUPER_ADMIN?(o(),d(re,{key:0,resources:u.value.resources},null,8,["resources"])):v("",!0),u.value.aliases?(o(),d(ee,{key:1,class:"mt-2",account:u.value},null,8,["account"])):v("",!0),u.value.mailbox?(o(),d(le,{key:2,class:"mt-2",account:u.value},null,8,["account"])):v("",!0)]),_:1})]),_:1})],64))}},Te=U(me,[["__scopeId","data-v-388d62f6"]]);export{Te as default};
|