modoboa 2.6.3__py3-none-any.whl → 2.6.4__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/calendars/backends/caldav_.py +3 -1
- modoboa/core/checks.py +5 -0
- modoboa/core/tests/test_checks.py +27 -0
- modoboa/frontend_dist/assets/{AccountAliasForm-OvFAP6Ru.js → AccountAliasForm-tLHotdIR.js} +1 -1
- modoboa/frontend_dist/assets/AccountEditView-DnQIIg47.js +1 -0
- modoboa/frontend_dist/assets/AccountLayout-B2HptJzY.js +1 -0
- modoboa/frontend_dist/assets/{AccountPasswordSubForm-XZN7PcjO.js → AccountPasswordSubForm-DpADntAL.js} +1 -1
- modoboa/frontend_dist/assets/AccountView-CJBGh9Oe.js +1 -0
- modoboa/frontend_dist/assets/{AddressBook-xlb9-9-o.js → AddressBook-CrFqzlzZ.js} +1 -1
- modoboa/frontend_dist/assets/{AdminLayout-BQfhhYgv.js → AdminLayout-BbCt7YxX.js} +1 -1
- modoboa/frontend_dist/assets/AlarmsView-CIlt_IKQ.js +1 -0
- modoboa/frontend_dist/assets/AliasEditView-n75NEN_s.js +1 -0
- modoboa/frontend_dist/assets/{AliasRecipientForm-_pUaKKG_.js → AliasRecipientForm-jjj5yJJw.js} +1 -1
- modoboa/frontend_dist/assets/{AliasView-Da4mvH53.js → AliasView-DFIvPeIm.js} +1 -1
- modoboa/frontend_dist/assets/{AuditTrailView-BfLVvAwj.js → AuditTrailView-sWnED3E9.js} +1 -1
- modoboa/frontend_dist/assets/CalendarView-DSCBIvef.js +1 -0
- modoboa/frontend_dist/assets/{ChoiceField-BpSW5-Ay.js → ChoiceField-RDT6XcnX.js} +1 -1
- modoboa/frontend_dist/assets/ComposeEmailForm-D3yUbBJX.css +1 -0
- modoboa/frontend_dist/assets/ComposeEmailForm-G3sXQAwI.js +1 -0
- modoboa/frontend_dist/assets/ComposeEmailView-Ce1CtFjD.js +1 -0
- modoboa/frontend_dist/assets/{ConfirmDialog-BemItW2F.js → ConfirmDialog-Du7aqKbR.js} +1 -1
- modoboa/frontend_dist/assets/ConnectedLayout-BHWaBAzH.js +1 -0
- modoboa/frontend_dist/assets/ConnectedLayout-C6HNXWkp.css +1 -0
- modoboa/frontend_dist/assets/{CreationForm-B00QE2E0.js → CreationForm-CjtILq0_.js} +1 -1
- modoboa/frontend_dist/assets/{CreationForm-HaiQhqwK.css → CreationForm-NOzzyspA.css} +1 -1
- modoboa/frontend_dist/assets/{DashboardView-CZyZayos.js → DashboardView-DFNwusDZ.js} +1 -1
- modoboa/frontend_dist/assets/DomainAdminList-BjtfbhRj.js +1 -0
- modoboa/frontend_dist/assets/{DomainEditView-CMsF-ytQ.js → DomainEditView-Cq5Ea4RW.js} +1 -1
- modoboa/frontend_dist/assets/{DomainTransportForm-BUDOfXiX.js → DomainTransportForm-DAXJGNLA.js} +1 -1
- modoboa/frontend_dist/assets/DomainView-BfpK7U14.js +4 -0
- modoboa/frontend_dist/assets/DomainsView-CYxLy-3Y.js +1 -0
- modoboa/frontend_dist/assets/{EmailField-BXU27oIO.js → EmailField-DmPc4pyP.js} +1 -1
- modoboa/frontend_dist/assets/{EmailView-WHGLT3Ne.js → EmailView-BE3vYZtJ.js} +1 -1
- modoboa/frontend_dist/assets/EmptyLayout-DMwKNHfI.js +1 -0
- modoboa/frontend_dist/assets/FiltersView-Dps3_fAh.js +1 -0
- modoboa/frontend_dist/assets/ForwardEmailView-C0I00eXf.js +1 -0
- modoboa/frontend_dist/assets/HtmlEditor-D753fIAJ.js +140 -0
- modoboa/frontend_dist/assets/{IdentitiesView-Cl2lbfkM.css → IdentitiesView-C93He_db.css} +1 -1
- modoboa/frontend_dist/assets/IdentitiesView-CoGBVhZx.js +1 -0
- modoboa/frontend_dist/assets/{InformationView-DF80M5Z2.js → InformationView-eB2ayeLD.js} +1 -1
- modoboa/frontend_dist/assets/{LoadingData-Dcu-PCpp.js → LoadingData-Tm56XNwj.js} +1 -1
- modoboa/frontend_dist/assets/{LoginCallbackView-D4hN9u_5.js → LoginCallbackView-DjCHUgz5.js} +1 -1
- modoboa/frontend_dist/assets/{LoginView-1M33LHpJ.js → LoginView-D0r4XBEl.js} +1 -1
- modoboa/frontend_dist/assets/MailboxView-DIVABvk5.css +1 -0
- modoboa/frontend_dist/assets/MailboxView-DNokO2WZ.js +5 -0
- modoboa/frontend_dist/assets/{MenuItems-CpOwNJeC.js → MenuItems-dl38msRA.js} +1 -1
- modoboa/frontend_dist/assets/{MessageView-DODItZwB.js → MessageView-BWh9BqzS.js} +1 -1
- modoboa/frontend_dist/assets/{MessagesView-CCYdnuSv.js → MessagesView-BZ7NUOwo.js} +1 -1
- modoboa/frontend_dist/assets/MigrationsView-DcOVgmcH.js +1 -0
- modoboa/frontend_dist/assets/{ParametersForm-CWxNQ8rG.js → ParametersForm-y02-GM0r.js} +1 -1
- modoboa/frontend_dist/assets/ParametersView-B6abt-LH.js +1 -0
- modoboa/frontend_dist/assets/ParametersView-v0YS6WU4.js +1 -0
- modoboa/frontend_dist/assets/{ProviderEditView-DxGMMxi1.js → ProviderEditView-BaL9mKxJ.js} +1 -1
- modoboa/frontend_dist/assets/ProviderGeneralForm-eoHMDO5v.js +1 -0
- modoboa/frontend_dist/assets/{ProvidersView-YAYrezMm.js → ProvidersView-Zu-G35u7.js} +1 -1
- modoboa/frontend_dist/assets/QuarantineLayout-BHiiksnP.js +1 -0
- modoboa/frontend_dist/assets/{QuarantineView-CZewBT4b.js → QuarantineView-BOXSobRz.js} +1 -1
- modoboa/frontend_dist/assets/ReplyEmailView-JmSiNWPy.js +1 -0
- modoboa/frontend_dist/assets/{ResourcesForm-CD3wObzE.js → ResourcesForm-D0YBapCG.js} +1 -1
- modoboa/frontend_dist/assets/SelfServiceLayout-DUmQzUDk.js +1 -0
- modoboa/frontend_dist/assets/SettingsView-DMuaKagM.js +6 -0
- modoboa/frontend_dist/assets/{StatisticsView-BxSjiD65.js → StatisticsView-CyY_CNcI.js} +1 -1
- modoboa/frontend_dist/assets/TimeSerieChart-BTDBH33K.js +1 -0
- modoboa/frontend_dist/assets/TimeSerieChart-C3XHmlRd.css +1 -0
- modoboa/frontend_dist/assets/UserLayout-DwxcQr4L.js +1 -0
- modoboa/frontend_dist/assets/{VAlert-iGJ3gOzk.css → VAlert-Bkuw9MFB.css} +1 -1
- modoboa/frontend_dist/assets/VAlert-CNys_LUS.js +1 -0
- modoboa/frontend_dist/assets/VApp-B0vRc3-6.js +1 -0
- modoboa/frontend_dist/assets/VApp-C9NK-Gu6.css +1 -0
- modoboa/frontend_dist/assets/VAutocomplete-Huaz_-hf.js +1 -0
- modoboa/frontend_dist/assets/VAutocomplete-hzGuLlUI.css +1 -0
- modoboa/frontend_dist/assets/VAvatar-BPhnln71.css +1 -0
- modoboa/frontend_dist/assets/VAvatar-JdJfoK0C.js +1 -0
- modoboa/frontend_dist/assets/{VBadge-BQrRJ9S0.css → VBadge-Bqx6XeRo.css} +1 -1
- modoboa/frontend_dist/assets/VBadge-Cg5iu5LG.js +1 -0
- modoboa/frontend_dist/assets/{VCard-BNvk7mV7.css → VCard-BdSLQNRY.css} +1 -1
- modoboa/frontend_dist/assets/VCard-BoH6kjPa.js +1 -0
- modoboa/frontend_dist/assets/VCheckbox-CCLOJFKF.js +1 -0
- modoboa/frontend_dist/assets/{VCheckboxBtn-p4bo2BTE.js → VCheckboxBtn-Ccl786Rg.js} +1 -1
- modoboa/frontend_dist/assets/VColorPicker-452uc3tY.js +1 -0
- modoboa/frontend_dist/assets/VColorPicker-B_lVDaYR.css +1 -0
- modoboa/frontend_dist/assets/{VContainer-CmyIOuWp.js → VContainer-DKMcKasC.js} +1 -1
- modoboa/frontend_dist/assets/VDataTable-BkLLfcQK.js +1 -0
- modoboa/frontend_dist/assets/VDataTable-CLcLRj9B.css +1 -0
- modoboa/frontend_dist/assets/VDataTableServer-B_6fWBA3.js +1 -0
- modoboa/frontend_dist/assets/VDataTableVirtual-Ike7oqcC.js +1 -0
- modoboa/frontend_dist/assets/VDialog-DIUeAIpw.js +1 -0
- modoboa/frontend_dist/assets/{VExpansionPanels-CBqUBAh-.js → VExpansionPanels-BeMgiS7A.js} +1 -1
- modoboa/frontend_dist/assets/VExpansionPanels-Dyw0hWW-.css +1 -0
- modoboa/frontend_dist/assets/VFileInput-Dvj95FL5.js +1 -0
- modoboa/frontend_dist/assets/{VFileInput-VtUg4zpy.css → VFileInput-Dwzvf-gD.css} +1 -1
- modoboa/frontend_dist/assets/{VForm-CxFPdkZa.js → VForm-DkphQD3e.js} +1 -1
- modoboa/frontend_dist/assets/VGrid-GYROgRMo.css +1 -0
- modoboa/frontend_dist/assets/VInput-CbqehdOu.js +1 -0
- modoboa/frontend_dist/assets/VMenu-B6SCtOwT.js +1 -0
- modoboa/frontend_dist/assets/VMenu-BEipA1lw.css +1 -0
- modoboa/frontend_dist/assets/VPicker-BUx70Wjg.js +1 -0
- modoboa/frontend_dist/assets/VPicker-ClSXs6kv.css +1 -0
- modoboa/frontend_dist/assets/VProgressCircular-C6u34DRJ.css +1 -0
- modoboa/frontend_dist/assets/VProgressCircular-DTDGzl2O.js +1 -0
- modoboa/frontend_dist/assets/VRadioGroup-CS9ULZ1c.js +1 -0
- modoboa/frontend_dist/assets/{VRow-CVWfiMs5.js → VRow-CuVZGqBj.js} +1 -1
- modoboa/frontend_dist/assets/VSelect-D5IXDPEX.js +1 -0
- modoboa/frontend_dist/assets/VSelect-DQzySRN1.css +1 -0
- modoboa/frontend_dist/assets/VSelectionControl-uKY9Zull.js +1 -0
- modoboa/frontend_dist/assets/VSheet-HeHw6g5_.js +1 -0
- modoboa/frontend_dist/assets/VSpacer-BUxSSJbH.js +1 -0
- modoboa/frontend_dist/assets/{VSwitch-Mm7Rd7At.css → VSwitch-C6REVr_Y.css} +1 -1
- modoboa/frontend_dist/assets/VSwitch-Dh_dserW.js +1 -0
- modoboa/frontend_dist/assets/VTable-BsI6FsWH.css +1 -0
- modoboa/frontend_dist/assets/VTable-gDsAUSLX.js +1 -0
- modoboa/frontend_dist/assets/VTabs-5XSICLQP.js +1 -0
- modoboa/frontend_dist/assets/VTabs-NzpINroH.css +1 -0
- modoboa/frontend_dist/assets/VTextField-Cow3HZvI.css +1 -0
- modoboa/frontend_dist/assets/VTextField-QXQFhKxm.js +1 -0
- modoboa/frontend_dist/assets/VTextarea-Bdy4UKmV.js +1 -0
- modoboa/frontend_dist/assets/VTextarea-DyGjqrlm.css +1 -0
- modoboa/frontend_dist/assets/VToolbar-CB2GrZpA.css +1 -0
- modoboa/frontend_dist/assets/VToolbar-CyrYSqJZ.js +1 -0
- modoboa/frontend_dist/assets/VWindowItem-DqNaT6b1.css +1 -0
- modoboa/frontend_dist/assets/VWindowItem-kZpArwK1.js +1 -0
- modoboa/frontend_dist/assets/WebmailLayout-BzW0LWYp.css +1 -0
- modoboa/frontend_dist/assets/WebmailLayout-CNUHODnw.js +1 -0
- modoboa/frontend_dist/assets/{accounts-CaYgxMST.js → accounts-DqbBlaLK.js} +1 -1
- modoboa/frontend_dist/assets/{admin-BZpOSErf.js → admin-D36m_nXq.js} +1 -1
- modoboa/frontend_dist/assets/{aliases-CbIEbmJ9.js → aliases-BtyF8GC8.js} +1 -1
- modoboa/frontend_dist/assets/{amavis-BUExu2Ci.js → amavis-B4QhM5Fa.js} +1 -1
- modoboa/frontend_dist/assets/{amavis-DrKC7POz.js → amavis-DySmsCJQ.js} +1 -1
- modoboa/frontend_dist/assets/{contacts-BszP28I9.js → contacts-Df8ptuMn.js} +1 -1
- modoboa/frontend_dist/assets/{domains-DGdr9Equ.js → domains-CSxtTvUh.js} +1 -1
- modoboa/frontend_dist/assets/{domains.store-W5AiCN3q.js → domains.store-D4ZqCQ-O.js} +1 -1
- modoboa/frontend_dist/assets/filter-DHKXX97M.js +1 -0
- modoboa/frontend_dist/assets/{global.store-xmZ6sXxZ.js → global.store-DYMmGKpn.js} +1 -1
- modoboa/frontend_dist/assets/{importExport-DMPLMrzl.js → importExport-C-adpHJX.js} +1 -1
- modoboa/frontend_dist/assets/index-B1bntsLR.js +995 -0
- modoboa/frontend_dist/assets/{index-B1bJH8Ti.css → index-B9q1vO3K.css} +1 -1
- modoboa/frontend_dist/assets/index-Bp9Fb67E.js +1 -0
- modoboa/frontend_dist/assets/{language.store-DuvIgs5v.js → language.store-_-zrrEiS.js} +1 -1
- modoboa/frontend_dist/assets/languages-CxjoT69j.js +1 -0
- modoboa/frontend_dist/assets/layout-CjSP_k58.js +1 -0
- modoboa/frontend_dist/assets/{layout.store-oWyirLgk.js → layout.store-CF5WRevH.js} +1 -1
- modoboa/frontend_dist/assets/{logos-DYp82smF.js → logos-95XYS6uH.js} +1 -1
- modoboa/frontend_dist/assets/{logs-B8GaGVAK.js → logs-CyU_PIDh.js} +1 -1
- modoboa/frontend_dist/assets/{parameters-CxHnQU2I.js → parameters-BxAXBXU1.js} +1 -1
- modoboa/frontend_dist/assets/{parameters.store-VA_AUeEJ.js → parameters.store-CATOSoQZ.js} +1 -1
- modoboa/frontend_dist/assets/{permissions-TImOfY3I.js → permissions-cSkGqV3M.js} +1 -1
- modoboa/frontend_dist/assets/{ssrBoot-B5vxBC28.js → ssrBoot-05WtbG6H.js} +1 -1
- modoboa/frontend_dist/assets/{tag-D-paBiFC.js → tag-BmV84V2s.js} +1 -1
- modoboa/frontend_dist/assets/{theme-Tvpj701M.js → theme-myV4ekXo.js} +1 -1
- modoboa/frontend_dist/assets/transports-ChdHV5hX.js +1 -0
- modoboa/frontend_dist/assets/webmail-B7MNMkv_.js +1 -0
- modoboa/frontend_dist/assets/webmail.store-Cm-h6hhE.js +1 -0
- modoboa/frontend_dist/index.html +2 -2
- modoboa/sievefilters/api/v2/tests.py +6 -0
- modoboa/sievefilters/api/v2/viewsets.py +10 -0
- modoboa/webmail/serializers.py +2 -1
- modoboa/webmail/tests/test_viewsets.py +16 -4
- modoboa/webmail/viewsets.py +17 -3
- {modoboa-2.6.3.dist-info → modoboa-2.6.4.dist-info}/METADATA +2 -2
- {modoboa-2.6.3.dist-info → modoboa-2.6.4.dist-info}/RECORD +165 -164
- modoboa/frontend_dist/assets/AccountEditView-N9Rsx1Lu.js +0 -1
- modoboa/frontend_dist/assets/AccountLayout-y-oYLez4.js +0 -1
- modoboa/frontend_dist/assets/AccountView-CGjtYjdN.js +0 -1
- modoboa/frontend_dist/assets/AlarmsView-CWISEf0x.js +0 -1
- modoboa/frontend_dist/assets/AliasEditView-BojxR0y0.js +0 -1
- modoboa/frontend_dist/assets/CalendarView-BiD8oiJQ.js +0 -1
- modoboa/frontend_dist/assets/ComposeEmailForm-DHFthaP6.css +0 -1
- modoboa/frontend_dist/assets/ComposeEmailForm-THBK5DPz.js +0 -1
- modoboa/frontend_dist/assets/ComposeEmailView-Byb6o1lF.js +0 -1
- modoboa/frontend_dist/assets/ConnectedLayout-Bxh21hcH.css +0 -1
- modoboa/frontend_dist/assets/ConnectedLayout-CuyGO8mE.js +0 -1
- modoboa/frontend_dist/assets/DomainAdminList-BW50F_7s.js +0 -1
- modoboa/frontend_dist/assets/DomainView-HFg7eBrA.js +0 -5
- modoboa/frontend_dist/assets/DomainsView-DSIdADod.js +0 -1
- modoboa/frontend_dist/assets/EmptyLayout-9_hUsyI4.js +0 -1
- modoboa/frontend_dist/assets/FiltersView-DxwCWP6V.js +0 -1
- modoboa/frontend_dist/assets/ForwardEmailView-R2VNw89Y.js +0 -1
- modoboa/frontend_dist/assets/HtmlEditor-9PKspQnj.js +0 -93
- modoboa/frontend_dist/assets/IdentitiesView-BiBhYfLG.js +0 -1
- modoboa/frontend_dist/assets/MailboxView-7GDx4hP8.js +0 -1
- modoboa/frontend_dist/assets/MailboxView-CfStlWhk.css +0 -1
- modoboa/frontend_dist/assets/MigrationsView-D8zvt5Gg.js +0 -1
- modoboa/frontend_dist/assets/ParametersView-B4LtgRrm.js +0 -1
- modoboa/frontend_dist/assets/ParametersView-BEM87Op8.js +0 -1
- modoboa/frontend_dist/assets/ProviderGeneralForm-DqVUshAw.js +0 -1
- modoboa/frontend_dist/assets/QuarantineLayout-Bj2STsUo.js +0 -1
- modoboa/frontend_dist/assets/ReplyEmailView-C-L78-Uh.js +0 -1
- modoboa/frontend_dist/assets/SelfServiceLayout-CFzaGLsg.js +0 -1
- modoboa/frontend_dist/assets/SettingsView-C7_cp9nZ.js +0 -6
- modoboa/frontend_dist/assets/TimeSerieChart-BY4l0TOt.js +0 -1
- modoboa/frontend_dist/assets/TimeSerieChart-Dn6Wznn8.css +0 -1
- modoboa/frontend_dist/assets/UserLayout-ByBCLOr-.js +0 -1
- modoboa/frontend_dist/assets/VAlert-Ck0PurTo.js +0 -1
- modoboa/frontend_dist/assets/VApp-CSICh40V.js +0 -1
- modoboa/frontend_dist/assets/VApp-DwhR0sAF.css +0 -1
- modoboa/frontend_dist/assets/VAutocomplete-BdsSHywe.js +0 -1
- modoboa/frontend_dist/assets/VAutocomplete-CPd3yAvV.css +0 -1
- modoboa/frontend_dist/assets/VAvatar-BKSHKr1K.js +0 -1
- modoboa/frontend_dist/assets/VAvatar-DXG1YGB5.css +0 -1
- modoboa/frontend_dist/assets/VBadge-DvuthTvS.js +0 -1
- modoboa/frontend_dist/assets/VCard-B7MvPr5E.js +0 -1
- modoboa/frontend_dist/assets/VCheckbox-er0bxYP_.js +0 -1
- modoboa/frontend_dist/assets/VColorPicker-C5_3l312.css +0 -1
- modoboa/frontend_dist/assets/VColorPicker-Dnoyj5rl.js +0 -1
- modoboa/frontend_dist/assets/VDataTable-CJyX7uj5.css +0 -1
- modoboa/frontend_dist/assets/VDataTable-uO4iY3PI.js +0 -1
- modoboa/frontend_dist/assets/VDataTableServer-LfLFgxCE.js +0 -1
- modoboa/frontend_dist/assets/VDataTableVirtual-C_aJRTho.js +0 -1
- modoboa/frontend_dist/assets/VDialog-ByBq-y2_.js +0 -1
- modoboa/frontend_dist/assets/VExpansionPanels-RsCANmDP.css +0 -1
- modoboa/frontend_dist/assets/VFileInput-CYUvB_Lr.js +0 -1
- modoboa/frontend_dist/assets/VGrid-Cb7FdSrp.css +0 -1
- modoboa/frontend_dist/assets/VInput-quQSdtEy.js +0 -1
- modoboa/frontend_dist/assets/VMenu--sryJ9Uc.js +0 -1
- modoboa/frontend_dist/assets/VMenu-5VuRw-HA.css +0 -1
- modoboa/frontend_dist/assets/VPicker-C6hgT7tI.js +0 -1
- modoboa/frontend_dist/assets/VPicker-CfsXFhHv.css +0 -1
- modoboa/frontend_dist/assets/VProgressCircular-BPJdTVu4.css +0 -1
- modoboa/frontend_dist/assets/VProgressCircular-DN4UW8ON.js +0 -1
- modoboa/frontend_dist/assets/VRadioGroup-G5s53Jnf.js +0 -1
- modoboa/frontend_dist/assets/VSelect-Dvkl50dw.css +0 -1
- modoboa/frontend_dist/assets/VSelect-Okzuwz-S.js +0 -1
- modoboa/frontend_dist/assets/VSelectionControl-DMlq6-TE.js +0 -1
- modoboa/frontend_dist/assets/VSheet-iS_sxEl7.js +0 -1
- modoboa/frontend_dist/assets/VSpacer-yH183XvN.js +0 -1
- modoboa/frontend_dist/assets/VSwitch-BYsITk7O.js +0 -1
- modoboa/frontend_dist/assets/VTable-C1FqhNBY.js +0 -1
- modoboa/frontend_dist/assets/VTable-CHRVGI94.css +0 -1
- modoboa/frontend_dist/assets/VTabs-Bv8FUb0o.css +0 -1
- modoboa/frontend_dist/assets/VTabs-DMJmfYTo.js +0 -1
- modoboa/frontend_dist/assets/VTextField-BzBVKKob.css +0 -1
- modoboa/frontend_dist/assets/VTextField-fWt9fUJr.js +0 -1
- modoboa/frontend_dist/assets/VTextarea-BTR7f0gW.css +0 -1
- modoboa/frontend_dist/assets/VTextarea-CVJNAf81.js +0 -1
- modoboa/frontend_dist/assets/VToolbar-BxjAEfSk.css +0 -1
- modoboa/frontend_dist/assets/VToolbar-DYf0Nubr.js +0 -1
- modoboa/frontend_dist/assets/VWindowItem-CWBhiE_Y.css +0 -1
- modoboa/frontend_dist/assets/VWindowItem-mmufRveK.js +0 -1
- modoboa/frontend_dist/assets/WebmailLayout-BmMZ58iv.js +0 -1
- modoboa/frontend_dist/assets/WebmailLayout-UlftFiiT.css +0 -1
- modoboa/frontend_dist/assets/filter-BH0Tmqu3.js +0 -1
- modoboa/frontend_dist/assets/index-DuzUMVLM.js +0 -1
- modoboa/frontend_dist/assets/index-WQ41F5VK.js +0 -982
- modoboa/frontend_dist/assets/languages-CE73-P-v.js +0 -1
- modoboa/frontend_dist/assets/layout-eXe9ZQ1u.js +0 -1
- modoboa/frontend_dist/assets/transports-DmREsCgU.js +0 -1
- modoboa/frontend_dist/assets/webmail-BsviLQXI.js +0 -1
- {modoboa-2.6.3.data → modoboa-2.6.4.data}/scripts/modoboa-admin.py +0 -0
- {modoboa-2.6.3.dist-info → modoboa-2.6.4.dist-info}/WHEEL +0 -0
- {modoboa-2.6.3.dist-info → modoboa-2.6.4.dist-info}/entry_points.txt +0 -0
- {modoboa-2.6.3.dist-info → modoboa-2.6.4.dist-info}/licenses/LICENSE +0 -0
- {modoboa-2.6.3.dist-info → modoboa-2.6.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{bN as h}from"./index-B1bntsLR.js";var u={exports:{}},g;function x(){if(g)return u.exports;g=1;function l(s,i=100,c={}){if(typeof s!="function")throw new TypeError(`Expected the first parameter to be a function, got \`${typeof s}\`.`);if(i<0)throw new RangeError("`wait` must not be negative.");const{immediate:p}=typeof c=="boolean"?{immediate:c}:c;let o,f,e,m,n;function d(){const r=o,a=f;return o=void 0,f=void 0,n=s.apply(r,a),n}function b(){const r=Date.now()-m;r<i&&r>=0?e=setTimeout(b,i-r):(e=void 0,p||(n=d()))}const t=function(...r){if(o&&this!==o&&Object.getPrototypeOf(this)===Object.getPrototypeOf(o))throw new Error("Debounced method called with different contexts of the same prototype.");o=this,f=r,m=Date.now();const a=p&&!e;return e||(e=setTimeout(b,i)),a&&(n=d()),n};return Object.defineProperty(t,"isPending",{get(){return e!==void 0}}),t.clear=()=>{e&&(clearTimeout(e),e=void 0)},t.flush=()=>{e&&t.trigger()},t.trigger=()=>{n=d(),t.clear()},t}return u.exports.debounce=l,u.exports=l,u.exports}var y=x();const D=h(y);export{D as d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{E as l,h as n}from"./index-
|
|
1
|
+
import{E as l,h as n}from"./index-B1bntsLR.js";import{l as u}from"./languages-CxjoT69j.js";const i=l("language",()=>{const a=n([]),t=n(!1);return{availableLanguages:a,getLanguages:async()=>{const e=await u.getAll();a.value=e.data,t.value=!0},getLanguageLabel:e=>{const s=a.value.find(g=>g.code===e);return s?s.label:e},loaded:t,$reset:async()=>{a.value=[],t.value=!1}}});export{i as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{C as e}from"./index-B1bntsLR.js";const s="languages",o={getAll(){return e.get(`/${s}/`)}};export{o as l};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as ne}from"./tag-BmV84V2s.js";import{J as D,N as E,i as v,h as ae,aY as w,a7 as B,a2 as R,aW as U,a6 as W,d as se,aA as ue,aZ as le,a_ as ie,aB as re,an as X,a$ as ce}from"./index-B1bntsLR.js";const M=Symbol.for("vuetify:layout"),Y=Symbol.for("vuetify:layout-item"),k=1e3,pe=D({overlaps:{type:Array,default:()=>[]},fullHeight:Boolean},"layout"),me=D({name:{type:String},order:{type:[Number,String],default:0},absolute:Boolean},"layout-item");function ge(){const s=E(M);if(!s)throw new Error("[Vuetify] Could not find injected layout");return{getLayoutItem:s.getLayoutItem,mainRect:s.mainRect,mainStyles:s.mainStyles}}function he(s){const u=E(M);if(!u)throw new Error("[Vuetify] Could not find injected layout");const d=s.id??`layout-item-${ue()}`,i=U("useLayoutItem");X(Y,{id:d});const n=W(!1);le(()=>n.value=!0),ie(()=>n.value=!1);const{layoutItemStyles:r,layoutItemScrimStyles:c}=u.register(i,{...s,active:v(()=>n.value?!1:s.active.value),id:d});return re(()=>u.unregister(d)),{layoutItemStyles:r,layoutRect:u.layoutRect,layoutItemScrimStyles:c}}const ve=(s,u,d,i)=>{let n={top:0,left:0,right:0,bottom:0};const r=[{id:"",layer:{...n}}];for(const c of s){const m=u.get(c),g=d.get(c),z=i.get(c);if(!m||!g||!z)continue;const h={...n,[m.value]:parseInt(n[m.value],10)+(z.value?parseInt(g.value,10):0)};r.push({id:c,layer:h}),n=h}return r};function Ie(s){const u=E(M,null),d=v(()=>u?u.rootZIndex.value-100:k),i=ae([]),n=w(new Map),r=w(new Map),c=w(new Map),m=w(new Map),g=w(new Map),{resizeRef:z,contentRect:h}=ne(),_=v(()=>{const t=new Map,l=s.overlaps??[];for(const e of l.filter(a=>a.includes(":"))){const[a,o]=e.split(":");if(!i.value.includes(a)||!i.value.includes(o))continue;const y=n.get(a),p=n.get(o),S=r.get(a),L=r.get(o);!y||!p||!S||!L||(t.set(o,{position:y.value,amount:parseInt(S.value,10)}),t.set(a,{position:p.value,amount:-parseInt(L.value,10)}))}return t}),I=v(()=>{const t=[...new Set([...c.values()].map(e=>e.value))].sort((e,a)=>e-a),l=[];for(const e of t){const a=i.value.filter(o=>{var y;return((y=c.get(o))==null?void 0:y.value)===e});l.push(...a)}return ve(l,n,r,m)}),H=v(()=>!Array.from(g.values()).some(t=>t.value)),b=v(()=>I.value[I.value.length-1].layer),q=B(()=>({"--v-layout-left":R(b.value.left),"--v-layout-right":R(b.value.right),"--v-layout-top":R(b.value.top),"--v-layout-bottom":R(b.value.bottom),...H.value?void 0:{transition:"none"}})),x=v(()=>I.value.slice(1).map((t,l)=>{let{id:e}=t;const{layer:a}=I.value[l],o=r.get(e),y=n.get(e);return{id:e,...a,size:Number(o.value),position:y.value}})),N=t=>x.value.find(l=>l.id===t),A=U("createLayout"),T=W(!1);se(()=>{T.value=!0}),X(M,{register:(t,l)=>{let{id:e,order:a,position:o,layoutSize:y,elementSize:p,active:S,disableTransitions:L,absolute:G}=l;c.set(e,a),n.set(e,o),r.set(e,y),m.set(e,S),L&&g.set(e,L);const Z=ce(Y,A==null?void 0:A.vnode).indexOf(t);Z>-1?i.value.splice(Z,0,e):i.value.push(e);const j=v(()=>x.value.findIndex($=>$.id===e)),O=v(()=>d.value+I.value.length*2-j.value*2),Q=v(()=>{const $=o.value==="left"||o.value==="right",P=o.value==="right",te=o.value==="bottom",C=p.value??y.value,oe=C===0?"%":"px",K={[o.value]:0,zIndex:O.value,transform:`translate${$?"X":"Y"}(${(S.value?0:-(C===0?100:C))*(P||te?-1:1)}${oe})`,position:G.value||d.value!==k?"absolute":"fixed",...H.value?void 0:{transition:"none"}};if(!T.value)return K;const f=x.value[j.value],V=_.value.get(e);return V&&(f[V.position]+=V.amount),{...K,height:$?`calc(100% - ${f.top}px - ${f.bottom}px)`:p.value?`${p.value}px`:void 0,left:P?void 0:`${f.left}px`,right:P?`${f.right}px`:void 0,top:o.value!=="bottom"?`${f.top}px`:void 0,bottom:o.value!=="top"?`${f.bottom}px`:void 0,width:$?p.value?`${p.value}px`:void 0:`calc(100% - ${f.left}px - ${f.right}px)`}}),ee=v(()=>({zIndex:O.value-1}));return{layoutItemStyles:Q,layoutItemScrimStyles:ee,zIndex:O}},unregister:t=>{c.delete(t),n.delete(t),r.delete(t),m.delete(t),g.delete(t),i.value=i.value.filter(l=>l!==t)},mainRect:b,mainStyles:q,getLayoutItem:N,items:x,layoutRect:h,rootZIndex:d});const F=B(()=>["v-layout",{"v-layout--full-height":s.fullHeight}]),J=B(()=>({zIndex:u?d.value:void 0,position:u?"relative":void 0,overflow:u?"hidden":void 0}));return{layoutClasses:F,layoutStyles:J,getLayoutItem:N,items:x,layoutRect:h,layoutRef:z}}export{M as V,he as a,me as b,Ie as c,pe as m,ge as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{E as a,h as s}from"./index-
|
|
1
|
+
import{E as a,h as s}from"./index-B1bntsLR.js";const r=a("layout",()=>{const e=s([]),t=s(!1);function n(u){e.value=u}async function o(){e.value=[],t.value=!1}return{leftMenuItems:e,compactLeftMenu:t,setLeftMenuItems:n,$reset:o}});export{r as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as r,
|
|
1
|
+
import{i as r,bq as s}from"./index-B1bntsLR.js";function i(){const o=s(),t=r(()=>o.MENU_LOGO_PATH?o.MENU_LOGO_PATH:new URL("/assets/Modoboa_RVB-BLANC-SANS-BBGoASES.png",import.meta.url).href),n=r(()=>o.CREATION_FORM_LOGO_PATH?o.CREATION_FORM_LOGO_PATH:new URL("/assets/Modoboa_RVB-BLEU-SANS-pKrnjsR_.png",import.meta.url).href);return{menuLogoPath:t,creationFormLogoPath:n}}export{i as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e}from"./index-
|
|
1
|
+
import{C as e}from"./index-B1bntsLR.js";const t="logs",o={getAuditTrail(s){return e.get(`/${t}/audit-trail/`,{params:s})},getMessages(s){return e.get(`/${t}/messages/`,{params:s})}};export{o as l};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e}from"./index-
|
|
1
|
+
import{C as e}from"./index-B1bntsLR.js";const r="parameters",l={getGlobalApplications(){return e.get(`/${r}/global/applications/`)},getGlobalApplication(t){return e.get(`/${r}/global/${t}/`)},getGlobalApplicationStructure(t){return e.get(`/${r}/global/structure/?app=${t}`)},saveGlobalApplication(t,p){return e.put(`/${r}/global/${t}/`,p)},getUserApplications(){return e.get(`/${r}/user/applications/`)},getUserApplication(t){return e.get(`/${r}/user/${t}/`)},getUserApplicationStructure(t){return e.get(`/${r}/user/structure/?app=${t}`)},saveUserApplication(t,p){return e.put(`/${r}/user/${t}/`,p)}};export{l as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{E as a,h as t}from"./index-
|
|
1
|
+
import{E as a,h as t}from"./index-B1bntsLR.js";const s=a("parameters",()=>{const e=t(null);async function r(){e.value=null}return{imapMigrationEnabled:e,$reset:r}});export{s as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u,i as n,j as e}from"./index-
|
|
1
|
+
import{u,i as n,j as e}from"./index-B1bntsLR.js";function c(){const t=u(),s=n(()=>[e.RESELLER,e.SUPER_ADMIN].includes(t.authUser.role)),r=n(()=>[e.RESELLER,e.SUPER_ADMIN].includes(t.authUser.role)),o=n(()=>[e.DOMAIN_ADMIN,e.RESELLER,e.SUPER_ADMIN].includes(t.authUser.role));return{canSetRole:s,canAddDomain:r,canViewDomain:o}}export{c as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a6 as t,d as e,a7 as s,
|
|
1
|
+
import{a6 as t,d as e,a7 as s,aX as n}from"./index-B1bntsLR.js";function i(){const o=t(!1);return e(()=>{window.requestAnimationFrame(()=>{o.value=!0})}),{ssrBootStyles:s(()=>o.value?void 0:{transition:"none !important"}),isBooted:n(o)}}export{i as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{J as m,
|
|
1
|
+
import{J as m,aW as g,ab as h,h as d,aq as f,aB as l,z as b,aX as R,i as S,a2 as r}from"./index-B1bntsLR.js";const x=m({class:[String,Array,Object],style:{type:[String,Array,Object],default:null}},"component");function y(t){const a=g("useRender");a.render=t}function W(t){let a=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"content";const e=h(),i=d();if(f){const s=new ResizeObserver(n=>{t==null||t(n,s),n.length&&(a==="content"?i.value=n[0].contentRect:i.value=n[0].target.getBoundingClientRect())});l(()=>{s.disconnect()}),b(()=>e.el,(n,o)=>{o&&(s.unobserve(o),i.value=void 0),n&&s.observe(n)},{flush:"post"})}return{resizeRef:e,contentRect:R(i)}}const H=m({height:[Number,String],maxHeight:[Number,String],maxWidth:[Number,String],minHeight:[Number,String],minWidth:[Number,String],width:[Number,String]},"dimension");function N(t){return{dimensionStyles:S(()=>{const e={},i=r(t.height),s=r(t.maxHeight),n=r(t.maxWidth),o=r(t.minHeight),u=r(t.minWidth),c=r(t.width);return i!=null&&(e.height=i),s!=null&&(e.maxHeight=s),n!=null&&(e.maxWidth=n),o!=null&&(e.minHeight=o),u!=null&&(e.minWidth=u),c!=null&&(e.width=c),e})}}const O=m({tag:{type:[String,Object,Function],default:"div"}},"tag");export{N as a,x as b,O as c,W as d,H as m,y as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as a,
|
|
1
|
+
import{C as a,bb as o,h as t}from"./index-B1bntsLR.js";const h={getTheme(){return a.get("/theme/")}};function i(){const l=o(),e=t(null);return{theme:e,enableTheme:async()=>{const r=await h.getTheme();e.value=r.data,e.value.theme_primary_color!==l.themes.value.light.colors.primary&&(l.themes.value.light.colors.primary=e.value.theme_primary_color),e.value.theme_primary_color_light!==l.themes.value.light.colors["primary-lighten-1"]&&(l.themes.value.light.colors["primary-lighten-1"]=e.value.theme_primary_color_light),e.value.theme_primary_color_dark!==l.themes.value.light.colors["primary-darken-1"]&&(l.themes.value.light.colors["primary-darken-1"]=e.value.theme_primary_color_dark),e.value.theme_secondary_color!==l.themes.value.light.colors.secondary&&(l.themes.value.light.colors.secondary=e.value.theme_secondary_color),e.value.theme_label_color!==l.themes.value.light.colors.label&&(l.themes.value.light.colors.label=e.value.theme_label_color)}}}export{i as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{C as t}from"./index-B1bntsLR.js";const r="transports",s={getAll(){return t.get(`/${r}/`)}};export{s as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{C as t}from"./index-B1bntsLR.js";const r={getUserMailboxes(e){const s={};return e&&(s.mailbox=e),t.get("/webmail/mailboxes/",{params:s})},getUserMailboxQuota(e){const s={mailbox:e};return t.get("/webmail/mailboxes/quota/",{params:s})},getUserMailboxUnseen(e){const s={mailbox:e};return t.get("webmail/mailboxes/unseen/",{params:s})},createUserMailbox(e){return t.post("/webmail/mailboxes/",e)},renameUserMailbox(e){return t.post("/webmail/mailboxes/rename/",e)},compressUserMailbox(e){return t.post("/webmail/mailboxes/compress/",e)},deleteUserMailbox(e){return t.post("/webmail/mailboxes/delete/",e)},emptyUserMailbox(e){const s={name:e};return t.post("/webmail/mailboxes/empty/",s)},getMailboxEmails(e,s){const o={mailbox:e,...s};return t.get("/webmail/emails/",{params:o})},getEmailContent(e,s,o){const a={mailbox:e,mailid:s,...o};return t.get("/webmail/emails/content/",{params:a})},getEmailSource(e,s){const o={mailbox:e,mailid:s};return t.get("/webmail/emails/source/",{params:o})},getEmailAttachment(e,s,o){const a={mailbox:e,mailid:s,partnum:o};return t.get("/webmail/emails/attachment/",{params:a,responseType:"blob"})},moveSelection(e,s,o){const a={source:e,destination:s,selection:o};return t.post("/webmail/emails/move/",a)},deleteSelection(e,s){const o={source:e,selection:s};return t.post("/webmail/emails/delete/",o)},markSelectionAsJunk(e,s){const o={source:e,selection:s};return t.post("/webmail/emails/mark_as_junk/",o)},markSelectionAsNotJunk(e,s){const o={source:e,selection:s};return t.post("/webmail/emails/mark_as_not_junk/",o)},flagSelection(e,s,o){const a={mailbox:e,selection:s,status:o};return t.post("/webmail/emails/flag/",a)},sendEmailFromComposeSession(e,s){return t.post(`/webmail/compose-sessions/${e}/send/`,s)},getComposeSession(e){return t.get(`/webmail/compose-sessions/${e}/`)},createComposeSession(){return t.post("/webmail/compose-sessions/")},getAllowedSenders(){return t.get("/webmail/compose-sessions/allowed_senders/")},uploadAttachment(e,s){return t.post(`/webmail/compose-sessions/${e}/attachments/`,s,{headers:{"Content-Type":"multipart/form-data"}})},removeAttachment(e,s){return t.delete(`/webmail/compose-sessions/${e}/attachments/${s}/`)}};export{r as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{E as s,h as e}from"./index-B1bntsLR.js";const i=s("webmail",()=>{const t=e([]),o=e(0);return{selection:t,listingKey:o}});export{i as u};
|
modoboa/frontend_dist/index.html
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
<link rel="icon" href="/favicon.ico" />
|
|
13
13
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
14
14
|
<title>Welcome to Modoboa</title>
|
|
15
|
-
<script type="module" crossorigin src="/assets/index-
|
|
16
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
15
|
+
<script type="module" crossorigin src="/assets/index-B1bntsLR.js"></script>
|
|
16
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B9q1vO3K.css">
|
|
17
17
|
</head>
|
|
18
18
|
|
|
19
19
|
<body>
|
|
@@ -96,6 +96,12 @@ class FilterSetViewSetTestCase(PatcherMixin, ModoAPITestCase):
|
|
|
96
96
|
resp = self.client.post(url)
|
|
97
97
|
self.assertEqual(resp.status_code, 200)
|
|
98
98
|
|
|
99
|
+
def test_deactivate_active(self):
|
|
100
|
+
self.authenticate()
|
|
101
|
+
url = reverse("v2:filterset-deactivate-active")
|
|
102
|
+
resp = self.client.post(url)
|
|
103
|
+
self.assertEqual(resp.status_code, 200)
|
|
104
|
+
|
|
99
105
|
def test_download(self):
|
|
100
106
|
self.authenticate()
|
|
101
107
|
url = reverse("v2:filterset-download", args=["unknown"])
|
|
@@ -99,6 +99,16 @@ class FilterSetViewSet(viewsets.ViewSet):
|
|
|
99
99
|
return response.Response({"error": str(err)}, status=400)
|
|
100
100
|
return response.Response()
|
|
101
101
|
|
|
102
|
+
@action(methods=["post"], detail=False)
|
|
103
|
+
def deactivate_active(self, request):
|
|
104
|
+
"""Deactivate the current active filterset."""
|
|
105
|
+
sclient = self.get_sieve_client(request)
|
|
106
|
+
try:
|
|
107
|
+
sclient.activatescript("")
|
|
108
|
+
except SieveClientError as err:
|
|
109
|
+
return response.Response({"error": str(err)}, status=400)
|
|
110
|
+
return response.Response()
|
|
111
|
+
|
|
102
112
|
@action(methods=["get"], detail=True)
|
|
103
113
|
def download(self, request, pk):
|
|
104
114
|
"""Download the content of an existing filter set."""
|
modoboa/webmail/serializers.py
CHANGED
|
@@ -173,7 +173,8 @@ class EmailSerializer(serializers.Serializer):
|
|
|
173
173
|
|
|
174
174
|
class MoveSelectionSerializer(serializers.Serializer):
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
source = serializers.CharField()
|
|
177
|
+
destination = serializers.CharField(required=False)
|
|
177
178
|
selection = serializers.ListField(child=serializers.CharField())
|
|
178
179
|
|
|
179
180
|
def validate_selection(self, value):
|
|
@@ -173,15 +173,27 @@ class UserEmailViewSetTestCase(WebmailTestCase):
|
|
|
173
173
|
self.assertEqual(response.status_code, 200)
|
|
174
174
|
self.assertIn("Message-ID", response.json()["source"])
|
|
175
175
|
|
|
176
|
+
def test_move(self):
|
|
177
|
+
self.authenticate()
|
|
178
|
+
url = reverse("v2:webmail-email-move")
|
|
179
|
+
body = {"source": "INBOX", "destination": "Junk", "selection": [1]}
|
|
180
|
+
response = self.client.post(url, body, format="json")
|
|
181
|
+
self.assertEqual(response.status_code, 200)
|
|
182
|
+
self.assertEqual(response.json()["count"], 1)
|
|
183
|
+
|
|
184
|
+
body = {"source": "INBOX", "selection": [1]}
|
|
185
|
+
response = self.client.post(url, body, format="json")
|
|
186
|
+
self.assertEqual(response.status_code, 400)
|
|
187
|
+
|
|
176
188
|
def test_delete(self):
|
|
177
189
|
self.authenticate()
|
|
178
190
|
url = reverse("v2:webmail-email-delete")
|
|
179
|
-
body = {"
|
|
191
|
+
body = {"source": "INBOX", "selection": [1]}
|
|
180
192
|
response = self.client.post(url, body, format="json")
|
|
181
193
|
self.assertEqual(response.status_code, 200)
|
|
182
194
|
self.assertEqual(response.json()["count"], 1)
|
|
183
195
|
|
|
184
|
-
body = {"
|
|
196
|
+
body = {"source": "INBOX", "selection": ["truc"]}
|
|
185
197
|
response = self.client.post(url, body, format="json")
|
|
186
198
|
self.assertEqual(response.status_code, 200)
|
|
187
199
|
self.assertEqual(response.json()["count"], 0)
|
|
@@ -189,7 +201,7 @@ class UserEmailViewSetTestCase(WebmailTestCase):
|
|
|
189
201
|
def test_mark_as_junk(self):
|
|
190
202
|
self.authenticate()
|
|
191
203
|
url = reverse("v2:webmail-email-mark-as-junk")
|
|
192
|
-
body = {"
|
|
204
|
+
body = {"source": "INBOX", "selection": [1]}
|
|
193
205
|
response = self.client.post(url, body, format="json")
|
|
194
206
|
self.assertEqual(response.status_code, 200)
|
|
195
207
|
self.assertEqual(response.json()["count"], 1)
|
|
@@ -197,7 +209,7 @@ class UserEmailViewSetTestCase(WebmailTestCase):
|
|
|
197
209
|
def test_mark_as_not_junk(self):
|
|
198
210
|
self.authenticate()
|
|
199
211
|
url = reverse("v2:webmail-email-mark-as-not-junk")
|
|
200
|
-
body = {"
|
|
212
|
+
body = {"source": "INBOX", "selection": [1]}
|
|
201
213
|
response = self.client.post(url, body, format="json")
|
|
202
214
|
self.assertEqual(response.status_code, 200)
|
|
203
215
|
self.assertEqual(response.json()["count"], 1)
|
modoboa/webmail/viewsets.py
CHANGED
|
@@ -9,6 +9,7 @@ from rest_framework import parsers, response, viewsets
|
|
|
9
9
|
from rest_framework.decorators import action
|
|
10
10
|
from rest_framework.permissions import IsAuthenticated
|
|
11
11
|
|
|
12
|
+
from modoboa.lib import exceptions
|
|
12
13
|
from modoboa.lib.paginator import Paginator
|
|
13
14
|
from modoboa.lib.viewsets import HasMailbox
|
|
14
15
|
from modoboa.webmail import lib, serializers
|
|
@@ -123,7 +124,7 @@ class UserEmailViewSet(viewsets.GenericViewSet):
|
|
|
123
124
|
def get_serializer_class(self):
|
|
124
125
|
if self.action == "list":
|
|
125
126
|
return serializers.PaginatedEmailListSerializer
|
|
126
|
-
if self.action in ["delete", "mark_as_junk", "mark_as_not_junk"]:
|
|
127
|
+
if self.action in ["move", "delete", "mark_as_junk", "mark_as_not_junk"]:
|
|
127
128
|
return serializers.MoveSelectionSerializer
|
|
128
129
|
if self.action == "flag":
|
|
129
130
|
return serializers.FlagSelectionSerializer
|
|
@@ -167,18 +168,31 @@ class UserEmailViewSet(viewsets.GenericViewSet):
|
|
|
167
168
|
)
|
|
168
169
|
return response.Response(serializer.data)
|
|
169
170
|
|
|
170
|
-
def move_selection(self, request, destination: str) -> int:
|
|
171
|
+
def move_selection(self, request, destination: str | None = None) -> int:
|
|
171
172
|
"""Move selected messages to the given mailbox."""
|
|
172
173
|
serializer = self.get_serializer(data=request.data)
|
|
173
174
|
serializer.is_valid(raise_exception=True)
|
|
175
|
+
if destination is None:
|
|
176
|
+
if "destination" not in serializer.validated_data:
|
|
177
|
+
raise exceptions.BadRequest("No destination provided")
|
|
178
|
+
destination = serializer.validated_data["destination"]
|
|
174
179
|
with lib.get_imapconnector(request) as mbc:
|
|
175
180
|
mbc.move(
|
|
176
181
|
",".join(serializer.validated_data["selection"]),
|
|
177
|
-
serializer.validated_data["
|
|
182
|
+
serializer.validated_data["source"],
|
|
178
183
|
destination,
|
|
179
184
|
)
|
|
180
185
|
return len(serializer.validated_data["selection"])
|
|
181
186
|
|
|
187
|
+
@action(
|
|
188
|
+
methods=["post"],
|
|
189
|
+
detail=False,
|
|
190
|
+
serializer_class=serializers.MoveSelectionSerializer,
|
|
191
|
+
)
|
|
192
|
+
def move(self, request):
|
|
193
|
+
count = self.move_selection(request)
|
|
194
|
+
return response.Response({"count": count})
|
|
195
|
+
|
|
182
196
|
@action(
|
|
183
197
|
methods=["post"],
|
|
184
198
|
detail=False,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modoboa
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.4
|
|
4
4
|
Summary: Mail hosting made simple
|
|
5
5
|
Author-email: Antoine Nguyen <tonio@ngyn.org>
|
|
6
6
|
License: ISC License
|
|
@@ -41,7 +41,7 @@ Requires-Python: >=3.10
|
|
|
41
41
|
Description-Content-Type: text/x-rst
|
|
42
42
|
License-File: LICENSE
|
|
43
43
|
Requires-Dist: django==5.2.8
|
|
44
|
-
Requires-Dist: django-phonenumber-field[phonenumbers]==8.
|
|
44
|
+
Requires-Dist: django-phonenumber-field[phonenumbers]==8.4.0
|
|
45
45
|
Requires-Dist: django-reversion==6.0.0
|
|
46
46
|
Requires-Dist: django-xforwardedfor-middleware==2.0
|
|
47
47
|
Requires-Dist: django-otp==1.6.3
|