From de10a81dbf9682c655c674d02539d7e58c693c1e Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 26 May 2022 19:08:36 +0000 Subject: [PATCH 01/29] Apply translations in fr translation completed for the source file '/modoboa/locale/en/LC_MESSAGES/django.po' on the 'fr' language. --- modoboa/locale/fr/LC_MESSAGES/django.po | 247 ++++++++---------------- 1 file changed, 83 insertions(+), 164 deletions(-) diff --git a/modoboa/locale/fr/LC_MESSAGES/django.po b/modoboa/locale/fr/LC_MESSAGES/django.po index 745856a20..9d5aa5c53 100644 --- a/modoboa/locale/fr/LC_MESSAGES/django.po +++ b/modoboa/locale/fr/LC_MESSAGES/django.po @@ -1,24 +1,26 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Antoine Nguyen , 2016-2017,2020 # Christophe CHAUVET , 2018 +# Icarus Flight, 2022 +# Jan-Philipp Sprung, 2021 # Jorg722, 2019 msgid "" msgstr "" "Project-Id-Version: Modoboa\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-11-05 15:36+0100\n" -"PO-Revision-Date: 2020-11-05 15:49+0100\n" -"Last-Translator: Antoine Nguyen \n" +"PO-Revision-Date: 2011-07-01 08:15+0000\n" +"Last-Translator: Icarus Flight, 2022\n" "Language-Team: French (http://www.transifex.com/tonio/modoboa/language/fr/)\n" -"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Language: fr\n" +"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: core/app_settings.py:26 msgid "User profile" @@ -46,8 +48,7 @@ msgstr "Méthode de chiffrement par défaut" #: core/app_settings.py:56 msgid "Scheme used to crypt mailbox passwords" -msgstr "" -"Méthode utilisée pour chiffrer les mots de passe des boites aux lettres" +msgstr "Méthode utilisée pour chiffrer les mots de passe des boites aux lettres" #: core/app_settings.py:60 msgid "Rounds" @@ -57,9 +58,7 @@ msgstr "Tours" msgid "" "Number of rounds to use (only used by sha256crypt and sha512crypt). Must be " "between 1000 and 999999999, inclusive." -msgstr "" -"Nombre de tours à utiliser (sha256crypt et sha512crypt uniquement). Doit " -"être compris entre 1000 et 999999999 inclue." +msgstr "Nombre de tours à utiliser (sha256crypt et sha512crypt uniquement). Doit être compris entre 1000 et 999999999 inclue." #: core/app_settings.py:69 msgid "Update password scheme at login" @@ -67,9 +66,7 @@ msgstr "Mettre à jour la méthode de chiffrement du mot de passe à la connexio #: core/app_settings.py:72 msgid "Update user password at login to use the default password scheme" -msgstr "" -"Mise à jour du mot de passe utilisateur lors d'une connexion pour utiliser " -"la méthode de chiffrement par défaut" +msgstr "Mise à jour du mot de passe utilisateur lors d'une connexion pour utiliser la méthode de chiffrement par défaut" #: core/app_settings.py:77 msgid "Default password" @@ -96,10 +93,7 @@ msgid "" "The URL of an external page where users will be able to update their " "password. It applies only to non local users, ie. those automatically " "created after a successful external authentication (LDAP, SMTP)." -msgstr "" -"L'URL d'une page externe où les utilisateurs pourront mettre à jour leur mot " -"de passe. Elle s'applique uniquement aux utilisateurs non locaux, c'est à " -"dire ceux créés après une authentification externe réussie (LDAP, SMTP)." +msgstr "L'URL d'une page externe où les utilisateurs pourront mettre à jour leur mot de passe. Elle s'applique uniquement aux utilisateurs non locaux, c'est à dire ceux créés après une authentification externe réussie (LDAP, SMTP)." #: core/app_settings.py:104 msgid "Password recovery announcement" @@ -107,9 +101,7 @@ msgstr "Annonce pour la récupération de mot de passe" #: core/app_settings.py:109 msgid "A temporary message that will be displayed on the reset password page." -msgstr "" -"Un message temporaire qui sera affiché sur la page de récupération de mot de " -"passe" +msgstr "Un message temporaire qui sera affiché sur la page de récupération de mot de passe" #: core/app_settings.py:115 msgid "Enable password recovery by SMS" @@ -117,9 +109,7 @@ msgstr "Activer la récupération de mot de passe par SMS" #: core/app_settings.py:118 msgid "Enable password recovery by SMS for users who filled a phone number." -msgstr "" -"Activer la récupération de mot de passe par SMS pour les utilisateurs ayant " -"renseigné un numéro de téléphone" +msgstr "Activer la récupération de mot de passe par SMS pour les utilisateurs ayant renseigné un numéro de téléphone" #: core/app_settings.py:124 msgid "SMS provider" @@ -127,8 +117,7 @@ msgstr "Fournisseur SMS" #: core/app_settings.py:127 msgid "Choose a provider to send password recovery SMS" -msgstr "" -"Choisir un fournisseur pour envoyer les SMS de récupération de mot de passe" +msgstr "Choisir un fournisseur pour envoyer les SMS de récupération de mot de passe" #: core/app_settings.py:133 msgid "LDAP settings" @@ -157,9 +146,7 @@ msgstr "Activer le serveur secondaire (secours)" #: core/app_settings.py:152 msgid "" "Enable a secondary LDAP server which will be used if the primary one fails" -msgstr "" -"Activer un serveur LDAP secondaire qui sera utilisé si le principal est en " -"échec" +msgstr "Activer un serveur LDAP secondaire qui sera utilisé si le principal est en échec" #: core/app_settings.py:158 msgid "Secondary server address" @@ -199,12 +186,9 @@ msgstr "Groupes administrateurs" #: core/app_settings.py:190 msgid "" -"Members of those LDAP Posix groups will be created as domain administrators. " -"Use ';' characters to separate groups." -msgstr "" -"Les membres de ces groupes LDAP (Posix) seront créés en tant " -"qu'administrateurs de domaine. Utiliser des caractères ';' pour séparer les " -"groupes." +"Members of those LDAP Posix groups will be created as domain administrators." +" Use ';' characters to separate groups." +msgstr "Les membres de ces groupes LDAP (Posix) seront créés en tant qu'administrateurs de domaine. Utiliser des caractères ';' pour séparer les groupes." #: core/app_settings.py:197 msgid "Group type" @@ -220,9 +204,7 @@ msgstr "Base de recherche des groupes" #: core/app_settings.py:209 msgid "The distinguished name of the search base used to find groups" -msgstr "" -"Le nom distinctif de la base de recherche utilisée pour rechercher les " -"groupes" +msgstr "Le nom distinctif de la base de recherche utilisée pour rechercher les groupes" #: core/app_settings.py:215 msgid "Password attribute" @@ -260,9 +242,7 @@ msgstr "ND de connexion" msgid "" "The distinguished name to use when binding to the LDAP server. Leave empty " "for an anonymous bind" -msgstr "" -"Le nom distinctif à utiliser pour les connections au serveur LDAP. Laisser " -"vide pour une connexion anonyme" +msgstr "Le nom distinctif à utiliser pour les connections au serveur LDAP. Laisser vide pour une connexion anonyme" #: core/app_settings.py:243 core/app_settings.py:297 msgid "Bind password" @@ -270,9 +250,7 @@ msgstr "Mot de passe de connexion" #: core/app_settings.py:246 core/app_settings.py:300 msgid "The password to use when binding to the LDAP server (with 'Bind DN')" -msgstr "" -"Le mot de passe à utiliser pour les connections au serveur LDAP (avec 'ND de " -"connexion')" +msgstr "Le mot de passe à utiliser pour les connections au serveur LDAP (avec 'ND de connexion')" #: core/app_settings.py:254 core/app_settings.py:346 msgid "Users search base" @@ -280,9 +258,7 @@ msgstr "Base de recherche des utilisateurs" #: core/app_settings.py:257 core/app_settings.py:349 msgid "The distinguished name of the search base used to find users" -msgstr "" -"Le nom distinctif de la base de recherche utilisée pour rechercher les " -"utilisateurs" +msgstr "Le nom distinctif de la base de recherche utilisée pour rechercher les utilisateurs" #: core/app_settings.py:263 core/app_settings.py:355 msgid "Search filter" @@ -292,9 +268,7 @@ msgstr "Filtre de recherche" msgid "" "An optional filter string (e.g. '(objectClass=person)'). In order to be " "valid, it must be enclosed in parentheses." -msgstr "" -"Un filtre de recherche optionel (ex. '(objectClass=person)'). Pour être " -"valide, il doit être entouré de parenthèses." +msgstr "Un filtre de recherche optionel (ex. '(objectClass=person)'). Pour être valide, il doit être entouré de parenthèses." #: core/app_settings.py:273 msgid "User DN template" @@ -305,9 +279,7 @@ msgstr "Modèle de nom distinctif utilisateur" msgid "" "The template used to construct a user's DN. It should contain one " "placeholder (ie. %(user)s)" -msgstr "" -"Le modèle utilisé pour construire le nom distinctif d'un utilisateur. Il " -"doit contenir un espace réservé (ex. %(user)s)" +msgstr "Le modèle utilisé pour construire le nom distinctif d'un utilisateur. Il doit contenir un espace réservé (ex. %(user)s)" #: core/app_settings.py:284 msgid "LDAP synchronization settings" @@ -320,9 +292,7 @@ msgstr "Activer l'export LDAP" #: core/app_settings.py:311 msgid "" "Enable automatic synchronization between local database and LDAP directory" -msgstr "" -"Activer la synchronisation automatique entre la base de données locale et " -"l'annuaire LDAP" +msgstr "Activer la synchronisation automatique entre la base de données locale et l'annuaire LDAP" #: core/app_settings.py:317 msgid "Delete remote LDAP account when local account is deleted" @@ -332,9 +302,7 @@ msgstr "Supprimer un compte LDAP distant lorsqu'un compte local est supprimé" msgid "" "Delete remote LDAP account when local account is deleted, otherwise it will " "be disabled." -msgstr "" -"Supprimer un compte LDAP distant lorsqu'un compte local supprimé, autrement " -"il sera désactivé." +msgstr "Supprimer un compte LDAP distant lorsqu'un compte local supprimé, autrement il sera désactivé." #: core/app_settings.py:327 msgid "Account DN template" @@ -345,9 +313,7 @@ msgstr "Modèle des DN de compte" msgid "" "The template used to construct an account's DN. It should contain one " "placeholder (ie. %(user)s)" -msgstr "" -"Le modèle utilisé pour construite un DN de compte (nom unique). Il doit " -"contenir un emplacement (c'est à dire 1%(user)s)" +msgstr "Le modèle utilisé pour construite un DN de compte (nom unique). Il doit contenir un emplacement (c'est à dire 1%(user)s)" #: core/app_settings.py:337 msgid "Enable import from LDAP" @@ -355,9 +321,7 @@ msgstr "Activer l'import LDAP" #: core/app_settings.py:340 msgid "Enable account synchronization from LDAP directory to local database" -msgstr "" -"Activer la synchronisation des comptes entre un annuaire LDAP et la base de " -"données locale" +msgstr "Activer la synchronisation des comptes entre un annuaire LDAP et la base de données locale" #: core/app_settings.py:365 msgid "Username attribute" @@ -365,8 +329,7 @@ msgstr "Attribut nom d'utilisateur" #: core/app_settings.py:368 msgid "The name of the LDAP attribute where the username can be found." -msgstr "" -"Le nom de l'attribut LDAP dans lequel le nom d'utilisateur peut être trouvé." +msgstr "Le nom de l'attribut LDAP dans lequel le nom d'utilisateur peut être trouvé." #: core/app_settings.py:373 msgid "Enable Dovecot LDAP sync" @@ -374,9 +337,7 @@ msgstr "Activer la synchronisation LDAP pour Dovecot" #: core/app_settings.py:376 msgid "LDAP authentication settings will be applied to Dovecot configuration." -msgstr "" -"Les paramètres d'authentification LDAP seront appliqués à la configuration " -"de Dovecot." +msgstr "Les paramètres d'authentification LDAP seront appliqués à la configuration de Dovecot." #: core/app_settings.py:382 msgid "Dovecot LDAP config file" @@ -385,9 +346,7 @@ msgstr "Fichier de configuration Dovecot pour LDAP" #: core/app_settings.py:386 msgid "" "Location of the configuration file which contains Dovecot LDAP settings." -msgstr "" -"Emplacement du fichier de configuration qui contient les paramètres LDAP de " -"Dovecot" +msgstr "Emplacement du fichier de configuration qui contient les paramètres LDAP de Dovecot" #: core/app_settings.py:391 core/templates/core/dashboard.html:5 msgid "Dashboard" @@ -399,9 +358,7 @@ msgstr "Flux RSS personnalisé" #: core/app_settings.py:397 msgid "Display custom RSS feed to resellers and domain administrators" -msgstr "" -"Afficher un flux RSS personnalisé aux revendeurs et administrateurs de " -"domaine" +msgstr "Afficher un flux RSS personnalisé aux revendeurs et administrateurs de domaine" #: core/app_settings.py:402 msgid "Hide features widget" @@ -409,9 +366,7 @@ msgstr "Masquer le widget des fonctionnalités" #: core/app_settings.py:405 msgid "Hide features widget for resellers and domain administrators" -msgstr "" -"Masquer le widget des fonctionnalités pour les revendeurs et les " -"administrateurs de domaine" +msgstr "Masquer le widget des fonctionnalités pour les revendeurs et les administrateurs de domaine" #: core/app_settings.py:409 msgid "Notifications" @@ -451,9 +406,7 @@ msgstr "Envoyer un email quand de nouvelles versions sont trouvées" #: core/app_settings.py:439 msgid "Send an email to notify admins about new versions" -msgstr "" -"Envoyer un email pour notifier les administrateurs à propos des nouvelles " -"versions" +msgstr "Envoyer un email pour notifier les administrateurs à propos des nouvelles versions" #: core/app_settings.py:443 msgid "Recipient" @@ -469,9 +422,7 @@ msgstr "Envoyer des statistiques" #: core/app_settings.py:454 msgid "Send statistics to Modoboa public API (counters and used extensions)" -msgstr "" -"Envoyer des statistiques à l'API publique de Modoboa (compteurs et " -"extensions utilisées)" +msgstr "Envoyer des statistiques à l'API publique de Modoboa (compteurs et extensions utilisées)" #: core/app_settings.py:458 msgid "Miscellaneous" @@ -483,11 +434,9 @@ msgstr "Seuil des comptes inactifs" #: core/app_settings.py:464 msgid "" -"An account with a last login date greater than this threshold (in days) will " -"be considered as inactive" -msgstr "" -"Un compte avec une date de dernière connexion antérieure à ce seuil sera " -"considéré comme inactif" +"An account with a last login date greater than this threshold (in days) will" +" be considered as inactive" +msgstr "Un compte avec une date de dernière connexion antérieure à ce seuil sera considéré comme inactif" #: core/app_settings.py:470 msgid "Top notifications check interval" @@ -519,8 +468,7 @@ msgstr "Redirection par défaut" #: core/app_settings.py:494 msgid "The default redirection used when no application is specified" -msgstr "" -"La redirection appliquée par défaut quand aucune application n'est spécifiée" +msgstr "La redirection appliquée par défaut quand aucune application n'est spécifiée" #: core/app_settings.py:548 core/app_settings.py:556 core/app_settings.py:564 msgid "Invalid syntax" @@ -543,10 +491,7 @@ msgid "" "You have USE_TZ set to False, this may result in issues during transitions " "between summer/winter time (ie the same local time occuring twice due to " "clock change)." -msgstr "" -"Vous avez défini USE_TZ à False, ce qui peut entraîner des problèmes lors " -"des transitions entre l'heure d'été et l'heure d'hiver (c.-à-d. La même " -"heure locale se produisant deux fois en raison d'un changement d'horloge)." +msgstr "Vous avez défini USE_TZ à False, ce qui peut entraîner des problèmes lors des transitions entre l'heure d'été et l'heure d'hiver (c.-à-d. La même heure locale se produisant deux fois en raison d'un changement d'horloge)." #: core/checks/settings_checks.py:9 msgid "Set `USE_TZ = True` in settings.py" @@ -622,7 +567,7 @@ msgstr "Code incorrect" #: core/forms.py:163 msgid "This code is invalid" -msgstr "Ce code est incorrect" +msgstr "Ce code n'est pas valide" #: core/handlers.py:36 msgid "added" @@ -700,8 +645,7 @@ msgstr "Une adresse e-mail alternative ou de secours." #: core/models.py:126 msgid "Failed to update password: LDAP module not installed" -msgstr "" -"Echec de la mise à jour du mot de passe : le module LDAP n'est pas installé" +msgstr "Echec de la mise à jour du mot de passe : le module LDAP n'est pas installé" #: core/models.py:155 msgid "account" @@ -734,38 +678,40 @@ msgid "Password must contain at least {} digit." msgid_plural "Password must contain at least {} digits." msgstr[0] "Le mot de passe doit contenir au moins {} chiffre." msgstr[1] "Le mot de passe doit contenir au moins {} chiffres." +msgstr[2] "Le mot de passe doit contenir au moins {} chiffres." #: core/password_validation.py:34 msgid "Password must contain at least {} lowercase letter." msgid_plural "Password must contain at least {} lowercase letters." msgstr[0] "Le mot de passe doit contenir au moins {} minuscule." msgstr[1] "Le mot de passe doit contenir au moins {} minuscules." +msgstr[2] "Le mot de passe doit contenir au moins {} minuscules." #: core/password_validation.py:45 msgid "Password must contain at least {} uppercase letter." msgid_plural "Password must contain at least {} uppercase letters." msgstr[0] "Le mot de passe doit contenir au moins {} majuscule." msgstr[1] "Le mot de passe doit contenir au moins {} majuscules." +msgstr[2] "Le mot de passe doit contenir au moins {} majuscules." #: core/password_validation.py:57 msgid "Password must contain at least {} special character." msgid_plural "Password must contain at least {} special characters." msgstr[0] "Le mot de passe doit contenir au moins {} caractère spécial." msgstr[1] "Le mot de passe doit contenir au moins {} caractères spéciaux." +msgstr[2] "Le mot de passe doit contenir au moins {} caractères spéciaux." #: core/password_validation.py:65 msgid "Your password must contain a combination of different character types." -msgstr "" -"Votre mot de passe doit contenir une combinaison de différents types de " -"caractère." +msgstr "Votre mot de passe doit contenir une combinaison de différents types de caractère." #: core/serializers.py:15 msgid "Invalid PIN code" -msgstr "Code PIN incorrect" +msgstr "Code PIN non valide" #: core/serializers.py:21 msgid "2FA is already enabled" -msgstr "La 2FA est déjà activée" +msgstr "2FA est déjà activf" #: core/sms_backends/ovh.py:19 msgid "API endpoint" @@ -835,9 +781,7 @@ msgstr "Dernières nouvelles" msgid "" "Visit the official " "weblog for more information." -msgstr "" -"Visitez le blog " -"officiel pour plus d'information." +msgstr "Visitez le blog officiel pour plus d'information." #: core/templates/core/api_access.html:3 msgid "API access" @@ -850,11 +794,9 @@ msgstr "Contrôlez votre accès à l'API de Modoboa" #: core/templates/core/api_access.html:7 #, python-format msgid "" -"A documentation of the API is available here." -msgstr "" -"Une documentation de l'API est disponible ici." +"A documentation of the API is available here." +msgstr "Une documentation de l'API est disponible ici." #: core/templates/core/api_access.html:14 msgid "API access token" @@ -884,8 +826,7 @@ msgstr "Une ou plusieurs mises à jour sont disponibles!" #: core/templates/core/information.html:6 msgid "Check the following list to find the component(s) that can be updated." -msgstr "" -"Consulter la liste suivante pour trouver le(s) composant(s) concerné(s)." +msgstr "Consulter la liste suivante pour trouver le(s) composant(s) concerné(s)." #: core/templates/core/information.html:10 msgid "Applications" @@ -951,12 +892,9 @@ msgid "" msgid_plural "" "\n" " The following updates are available:\n" -msgstr[0] "" -"\n" -"La mise à jour suivante est disponible :\n" -msgstr[1] "" -"\n" -"Les mises à jour suivantes sont disponibles :\n" +msgstr[0] "\nLa mise à jour suivante est disponible :\n" +msgstr[1] "\nLes mises à jour suivantes sont disponibles :\n" +msgstr[2] "\nLes mises à jour suivantes sont disponibles :\n" #: core/templates/core/parameters.html:2 core/templatetags/core_tags.py:71 msgid "Parameters" @@ -1010,13 +948,13 @@ msgstr "Sécurité" #: core/templates/core/user_security.html:6 msgid "Two-Factor authentication" -msgstr "Authentification à double facteur" +msgstr "Authentification à deux facteurs" #: core/templates/core/user_security.html:17 msgid "" -"Install a soft token authenticator like FreeOTP or Google Authenticator from " -"your application repository and use that app to scan this QR code." -msgstr "Installer une application de génération de mots de passe à usage unique comme FreeOTP ou Google Athenticator depuis votre magasin d'applications et utiliser le pour scanner ce code QR." +"Install a soft token authenticator like FreeOTP or Google Authenticator from" +" your application repository and use that app to scan this QR code." +msgstr "Installez une application d'authentification par jetons comme FreeOTP ou Google Authenticator à partir de votre appstore et utilisez-la pour scanner ce QR code." #: core/templates/core/user_security.html:25 msgid "Pin code" @@ -1024,12 +962,12 @@ msgstr "Code PIN" #: core/templates/core/user_security.html:28 msgid "Register" -msgstr "Enregistrer" +msgstr "Enregistrement" #: core/templates/core/user_security.html:33 msgid "" "Congratulations! Two-Factor Authentication is now enabled for your account." -msgstr "Félicitations ! L'authentification à double facteur est activée pour votre compte." +msgstr "Félicitations ! L'authentification à deux facteurs est maintenant activée pour votre compte." #: core/templates/core/user_security.html:38 #: core/templates/core/user_security.html:89 @@ -1038,34 +976,35 @@ msgid "" "access to your account, in case you lose your phone for example. Make sure " "to save them in a safe place, otherwise you won't be able to access your " "account anymore." -msgstr "Les codes de récuparation suivants peuvent être utilisés une fois chacun pour récupérer l'accès à votre compte, par exemple si vous perdez votre téléphone. Assurez vous de les sauvegarder dans un endroit sûr, autrement vous ne pourrez plus accéder à votre compte." +msgstr "Les codes de récupération suivants peuvent être utilisés une fois chacun pour vous permettre de récupérer un accès à votre compte, au cas où vous perdriez votre téléphone par exemple. Assurez-vous de les conserver dans un lieu sûr, autrement vous ne serez définitivement plus en mesure d'accéder à votre compte." #: core/templates/core/user_security.html:53 msgid "Two-Factor Authentication is enabled for your account." -msgstr "L'authentication à double facteur est activée pour votre compte." +msgstr "L'authentification à deux facteurs est activée pour votre compte." #: core/templates/core/user_security.html:58 msgid "Disable 2FA" -msgstr "Désactiver la 2FA" +msgstr "Désactiver authentification à 2 facteurs." #: core/templates/core/user_security.html:61 msgid "Reset recovery codes" -msgstr "Réinitialiser les codes de récupération" +msgstr "Réinitialiser les codes de récupération." #: core/templates/core/user_security.html:65 msgid "" "Two-Factor Authentication (2FA) is not yet activated for your account. " "Enabling this feature will increase your account's security." -msgstr "L'authentification à double facteur (2FA) n'est pas encore activée pour votre compte. Activer cette fonctionnalité améliorera la sécurité de votre compte." +msgstr "L'authentification à 2 facteurs n'est pas encore activée pour votre compte. Activer cette fonctionnalité renforcera la sécurité de votre compte." #: core/templates/core/user_security.html:73 msgid "Enable 2FA" -msgstr "Activer la 2FA" +msgstr "Activer authentification à 2 facteurs." #: core/templates/core/user_security.html:83 #: core/templates/core/user_security.html:99 -#: templates/common/generic_modal.html:6 templates/common/generic_modal.html:13 -#: templates/common/wizard_forms.html:6 templates/common/wizard_forms.html:27 +#: templates/common/generic_modal.html:6 +#: templates/common/generic_modal.html:13 templates/common/wizard_forms.html:6 +#: templates/common/wizard_forms.html:27 msgid "Close" msgstr "Fermer" @@ -1075,7 +1014,7 @@ msgstr "Nouveaux codes de récupération" #: core/templates/core/user_security.html:88 msgid "Here are your new recovery codes. " -msgstr "Voici vos nouveaux codes de récupération." +msgstr "Vous trouverez ici vos nouveaux codes de récupération." #: core/templatetags/core_tags.py:34 msgid "Modoboa" @@ -1100,14 +1039,12 @@ msgstr "Paramètres enregistrés" #: core/views/auth.py:61 #, python-format msgid "Password scheme mismatch. Updating %s password" -msgstr "" -"La méthode de chiffrement du mot de passe diffère. Mise à jour du mot de " -"passe de %s" +msgstr "La méthode de chiffrement du mot de passe diffère. Mise à jour du mot de passe de %s" #: core/views/auth.py:68 #, python-format msgid "Password hash parameter missmatch. Updating %s password" -msgstr "" +msgstr "Le paramètre de hash du mot de passe ne correspond pas. Mise à jour %s du mot de passe" #: core/views/auth.py:84 #, python-format @@ -1116,9 +1053,7 @@ msgstr "Utiliseur '%s' connecté avec succès" #: core/views/auth.py:92 msgid "Your username and password didn't match. Please try again." -msgstr "" -"Votre nom d'utilisateur et mot de passe ne correspondent pas. Veuillez " -"réessayer." +msgstr "Votre nom d'utilisateur et mot de passe ne correspondent pas. Veuillez réessayer." #: core/views/auth.py:127 msgid "User '{}' successfully logged out" @@ -1126,9 +1061,7 @@ msgstr "Utilisateur '{}' déconnecté avec succès" #: core/views/auth.py:172 core/views/auth.py:227 msgid "Please use the following code to recover your Modoboa password: {}" -msgstr "" -"Veuillez utiliser le code suivant pour récupérer votre mot de passe " -"Modoboa : {}" +msgstr "Veuillez utiliser le code suivant pour récupérer votre mot de passe Modoboa : {}" #: core/views/user.py:60 msgid "Profile updated" @@ -1144,7 +1077,7 @@ msgstr "Accès mis à jour" #: core/viewsets.py:52 msgid "2FA is not enabled" -msgstr "La 2FA n'est pas activée" +msgstr "Authentification 2 facteurs non activée" #: lib/db_utils.py:23 #, python-format @@ -1265,9 +1198,7 @@ msgstr "Mot de passe oublié ?" msgid "" "Your password has been set. You may go ahead and sign " "in now." -msgstr "" -"Votre mot de passe a été défini. Vous pouvez continuer et vous connecter dès maintenant." +msgstr "Votre mot de passe a été défini. Vous pouvez continuer et vous connecter dès maintenant." #: templates/registration/password_reset_confirm.html:7 msgid "Change password" @@ -1277,10 +1208,7 @@ msgstr "Changer le mot de passe" msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." -msgstr "" -"Le lien de réinitialisation du mot de passe était invalide, probablement " -"parce qu'il a déjà été utilisé. Merci de demander une nouvelle " -"réinitialisation de mot de passe." +msgstr "Le lien de réinitialisation du mot de passe était invalide, probablement parce qu'il a déjà été utilisé. Merci de demander une nouvelle réinitialisation de mot de passe." #: templates/registration/password_reset_confirm_code.html:20 msgid "Enter the code you've just received by SMS" @@ -1296,29 +1224,20 @@ msgid "" "exists with the email you entered. You should receive them shortly.

" "

If you don't receive an email, please make sure you've entered your " "primary address, and check your spam folder.

" -msgstr "" -"

Nous vous avons envoyé par email les instructions pour définir votre mot " -"de passe, pour peu qu'un compte avec l'email que vous avez renseigné existe. " -"Vous devriez les recevoir rapidement.

Si vous ne recevez pas d'email, " -"merci de vérifier que vous avez renseigné votre adresse principale et de " -"vérifier votre dossier spam.

" +msgstr "

Nous vous avons envoyé par email les instructions pour définir votre mot de passe, pour peu qu'un compte avec l'email que vous avez renseigné existe. Vous devriez les recevoir rapidement.

Si vous ne recevez pas d'email, merci de vérifier que vous avez renseigné votre adresse principale et de vérifier votre dossier spam.

" #: templates/registration/password_reset_email.html:4 #, python-format msgid "" "To initiate the password reset process for your %(username)s Modoboa " "account, click the link below:" -msgstr "" -"Pour initier la procédure de réinitialisation du mot de passe de votre " -"compte Modoboa %(username)s, cliquez sur le lien ci-dessous :" +msgstr "Pour initier la procédure de réinitialisation du mot de passe de votre compte Modoboa %(username)s, cliquez sur le lien ci-dessous :" #: templates/registration/password_reset_email.html:10 msgid "" "If clicking the link above doesn't work, please copy and paste the URL in a " "new browser window instead." -msgstr "" -"Si cliquer sur lien ci-dessous ne fonctionne pas, merci de copier / coller " -"cette URL dans une nouvelle fenêtre navigateur à la place." +msgstr "Si cliquer sur lien ci-dessous ne fonctionne pas, merci de copier / coller cette URL dans une nouvelle fenêtre navigateur à la place." #: templates/registration/password_reset_email.html:14 msgid "Sincerely, The Modoboa Team." From c2d812429682d316294aceaf402407a1cfed892e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jun 2022 12:00:53 +0000 Subject: [PATCH 02/29] Bump django-phonenumber-field[phonenumbers] from 6.1.0 to 6.2.0 Bumps [django-phonenumber-field[phonenumbers]](https://github.com/stefanfoulis/django-phonenumber-field) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/stefanfoulis/django-phonenumber-field/releases) - [Changelog](https://github.com/stefanfoulis/django-phonenumber-field/blob/main/CHANGELOG.rst) - [Commits](https://github.com/stefanfoulis/django-phonenumber-field/compare/6.1.0...6.2.0) --- updated-dependencies: - dependency-name: django-phonenumber-field[phonenumbers] dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8043c712f..8a2c3e50c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ django<4.0 django-ckeditor==6.3.0 -django-phonenumber-field[phonenumbers]==6.1.0 +django-phonenumber-field[phonenumbers]==6.2.0 django-reversion==5.0.0 django-xforwardedfor-middleware==2.0 django-otp==1.1.3 From e7190253a4a90caa5e8e047a20bcdbcf1faaa167 Mon Sep 17 00:00:00 2001 From: MeIchthys <10717998+meichthys@users.noreply.github.com> Date: Thu, 16 Jun 2022 10:43:06 -0400 Subject: [PATCH 03/29] Minor gramatical changes --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index d3e7fd69a..c553721e7 100644 --- a/README.rst +++ b/README.rst @@ -6,7 +6,7 @@ Modoboa is a mail hosting and management platform including a modern and simplified Web User Interface. It provides useful components such -as an administration panel or a webmail. +as an administration panel and webmail. Modoboa integrates with well known software such as `Postfix `_ or `Dovecot `_. A SQL @@ -53,7 +53,7 @@ If you want to try out Modoboa, check out our `demo installation `_ * Mailing list: join the `modoboa-users `_ group on Google Groups From 2b7ac5344ba1926e0e037312ff7a117945271dd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jun 2022 12:00:51 +0000 Subject: [PATCH 04/29] Bump django-phonenumber-field[phonenumbers] from 6.2.0 to 6.3.0 Bumps [django-phonenumber-field[phonenumbers]](https://github.com/stefanfoulis/django-phonenumber-field) from 6.2.0 to 6.3.0. - [Release notes](https://github.com/stefanfoulis/django-phonenumber-field/releases) - [Changelog](https://github.com/stefanfoulis/django-phonenumber-field/blob/main/CHANGELOG.rst) - [Commits](https://github.com/stefanfoulis/django-phonenumber-field/compare/6.2.0...6.3.0) --- updated-dependencies: - dependency-name: django-phonenumber-field[phonenumbers] dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8a2c3e50c..7b8527e5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ django<4.0 django-ckeditor==6.3.0 -django-phonenumber-field[phonenumbers]==6.2.0 +django-phonenumber-field[phonenumbers]==6.3.0 django-reversion==5.0.0 django-xforwardedfor-middleware==2.0 django-otp==1.1.3 From 24f3967231526bc427544a38be0de2b541ec231f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jun 2022 07:24:32 +0000 Subject: [PATCH 05/29] Bump django-reversion from 5.0.0 to 5.0.1 Bumps [django-reversion](https://github.com/etianen/django-reversion) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/etianen/django-reversion/releases) - [Changelog](https://github.com/etianen/django-reversion/blob/master/CHANGELOG.rst) - [Commits](https://github.com/etianen/django-reversion/compare/v5.0.0...v5.0.1) --- updated-dependencies: - dependency-name: django-reversion dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7b8527e5d..ef9b053dd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ django<4.0 django-ckeditor==6.3.0 django-phonenumber-field[phonenumbers]==6.3.0 -django-reversion==5.0.0 +django-reversion==5.0.1 django-xforwardedfor-middleware==2.0 django-otp==1.1.3 django-filter From ff73592edd0503cfdc577d10df3c9198a74d73d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jun 2022 07:24:32 +0000 Subject: [PATCH 06/29] Update mysqlclient requirement from <2.1.1 to <2.1.2 Updates the requirements on [mysqlclient](https://github.com/PyMySQL/mysqlclient) to permit the latest version. - [Release notes](https://github.com/PyMySQL/mysqlclient/releases) - [Changelog](https://github.com/PyMySQL/mysqlclient/blob/main/HISTORY.rst) - [Commits](https://github.com/PyMySQL/mysqlclient/compare/MySQLdb-0.3.3...v2.1.1) --- updated-dependencies: - dependency-name: mysqlclient dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- mysql-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-requirements.txt b/mysql-requirements.txt index 14a879582..631e1ff03 100644 --- a/mysql-requirements.txt +++ b/mysql-requirements.txt @@ -1 +1 @@ -mysqlclient<2.1.1 +mysqlclient<2.1.2 From 5ab2379a4d2b59cad7c841f71de6f37cde123a53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jun 2022 07:24:36 +0000 Subject: [PATCH 07/29] Bump shell-quote from 1.7.2 to 1.7.3 in /frontend Bumps [shell-quote](https://github.com/substack/node-shell-quote) from 1.7.2 to 1.7.3. - [Release notes](https://github.com/substack/node-shell-quote/releases) - [Changelog](https://github.com/substack/node-shell-quote/blob/master/CHANGELOG.md) - [Commits](https://github.com/substack/node-shell-quote/compare/v1.7.2...1.7.3) --- updated-dependencies: - dependency-name: shell-quote dependency-type: indirect ... Signed-off-by: dependabot[bot] --- frontend/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/yarn.lock b/frontend/yarn.lock index b7a14356c..d1b603921 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -8577,9 +8577,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.6.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== shelljs@^0.8.3: version "0.8.5" From 9485f2a9a2b1c4e9de7745a5001f652e6d817c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Fri, 1 Jul 2022 09:38:14 +0200 Subject: [PATCH 08/29] Update doc for Dovecot's authentication configuration --- doc/manual_installation/dovecot.rst | 34 ++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/doc/manual_installation/dovecot.rst b/doc/manual_installation/dovecot.rst index 4d7cd6754..d9e8fa961 100644 --- a/doc/manual_installation/dovecot.rst +++ b/doc/manual_installation/dovecot.rst @@ -147,11 +147,22 @@ MySQL users default_pass_scheme = CRYPT - password_query = SELECT email AS user, password FROM core_user WHERE email='%Lu' and is_active=1 + password_query = \ + SELECT email AS user, password \ + FROM core_user u \ + INNER JOIN admin_mailbox mb ON u.id=mb.user_id \ + INNER JOIN admin_domain dom ON mb.domain_id=dom.id \ + WHERE u.email='%L{user}' AND u.is_active=1 AND dom.enabled=1 - user_query = SELECT '/%Ld/%Ln' AS home, as uid, as gid, concat('*:bytes=', mb.quota, 'M') AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE mb.address='%Ln' AND dom.name='%Ld' + user_query = \ + SELECT '/%Ld/%Ln' AS home, \ + as uid, as gid, CONCAT('*:bytes=', mb.quota, 'M') AS quota_rule \ + FROM admin_mailbox mb \ + INNER JOIN admin_domain dom ON mb.domain_id=dom.id \ + INNER JOIN core_user u ON mb.user_id=u.id \ + WHERE mb.address='%L{username}' AND dom.name='%L{domain}' AND u.is_active=1 AND dom.enabled=1 - iterate_query = SELECT email AS user FROM core_user + iterate_query = SELECT email AS user FROM core_user WHERE is_active .. _dovecot_pg_queries: @@ -166,11 +177,22 @@ PostgreSQL users default_pass_scheme = CRYPT - password_query = SELECT email AS user, password FROM core_user u INNER JOIN admin_mailbox mb ON u.id=mb.user_id INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE u.email='%Lu' AND u.is_active AND dom.enabled + password_query = \ + SELECT email AS user, password \ + FROM core_user u \ + INNER JOIN admin_mailbox mb ON u.id=mb.user_id \ + INNER JOIN admin_domain dom ON mb.domain_id=dom.id \ + WHERE u.email='%L{user}' AND u.is_active AND dom.enabled - user_query = SELECT '/%Ld/%Ln' AS home, as uid, as gid, '*:bytes=' || mb.quota || 'M' AS quota_rule FROM admin_mailbox mb INNER JOIN admin_domain dom ON mb.domain_id=dom.id WHERE mb.address='%Ln' AND dom.name='%Ld' + user_query = \ + SELECT '/%Ld/%Ln' AS home, \ + as uid, as gid, CONCAT('*:bytes=', mb.quota, 'M') AS quota_rule \ + FROM admin_mailbox mb \ + INNER JOIN admin_domain dom ON mb.domain_id=dom.id \ + INNER JOIN core_user u ON mb.user_id=u.id \ + WHERE mb.address='%L{username}' AND dom.name='%L{domain}' AND u.is_active AND dom.enabled - iterate_query = SELECT email AS user FROM core_user + iterate_query = SELECT email AS user FROM core_user WHERE is_active SQLite users ------------ From 6386440877cc494d8cf450d5da8bfc8fadb91391 Mon Sep 17 00:00:00 2001 From: Marcel Herrguth Date: Wed, 6 Jul 2022 13:08:14 +0200 Subject: [PATCH 09/29] Maintenance: Add missing log parse parts plus hint Modoboa also offers log parsing which was not yet reflected in the cron job sample of the manual installation part. As log parsing can be fairly CPU intensive there's also a hint for that. --- doc/manual_installation/modoboa.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/manual_installation/modoboa.rst b/doc/manual_installation/modoboa.rst index 156ace9a9..f78ec8aef 100644 --- a/doc/manual_installation/modoboa.rst +++ b/doc/manual_installation/modoboa.rst @@ -235,11 +235,23 @@ following content inside: 0 0 * * * modoboa $PYTHON $INSTANCE/manage.py clearsessions # Logs table cleanup 0 0 * * * modoboa $PYTHON $INSTANCE/manage.py cleanlogs + # Logs parsing + */15 * * * * root $PYTHON $INSTANCE/manage.py logparser &> /dev/null + 0 * * * * modoboa $PYTHON $INSTANCE/manage.py update_statistics # DNSBL checks */30 * * * * modoboa $PYTHON $INSTANCE/manage.py modo check_mx # Public API communication 0 * * * * modoboa $PYTHON $INSTANCE/manage.py communicate_with_public_api +.. hint:: **🥵 potential high load configuration** + + Please note that above crontab might not be ideal on high load systems. + If you receive a fairly high amount of emails per day, you may want to + run modoboas logparser tasks *once per night*. + + This has the down side that the statistic graph and message log within + the UI are updated once per day only. + .. _policy_daemon: Policy daemon From 7eecf0b97ce1feda7171e1e216b576ee99edac5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 12:01:10 +0000 Subject: [PATCH 10/29] Bump testfixtures from 6.18.5 to 7.0.0 Bumps [testfixtures](https://github.com/Simplistix/testfixtures) from 6.18.5 to 7.0.0. - [Release notes](https://github.com/Simplistix/testfixtures/releases) - [Changelog](https://github.com/simplistix/testfixtures/blob/master/CHANGELOG.rst) - [Commits](https://github.com/Simplistix/testfixtures/compare/6.18.5...7.0.0) --- updated-dependencies: - dependency-name: testfixtures dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- test-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-requirements.txt b/test-requirements.txt index d18c9a1d3..a1badef69 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,6 +1,6 @@ argon2-cffi>=16.1.0 factory-boy<3.3.0 httmock==1.4.0 -testfixtures==6.18.5 +testfixtures==7.0.0 tox asynctest From dc2d12189cc2d6d26a70f33e3a5640bdf92d195e Mon Sep 17 00:00:00 2001 From: Spitap Date: Thu, 14 Jul 2022 20:45:42 +0200 Subject: [PATCH 11/29] Fix depreaciation from python 3.10 --- modoboa/policyd/management/commands/policy_daemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modoboa/policyd/management/commands/policy_daemon.py b/modoboa/policyd/management/commands/policy_daemon.py index f0c94edfa..2808a5086 100644 --- a/modoboa/policyd/management/commands/policy_daemon.py +++ b/modoboa/policyd/management/commands/policy_daemon.py @@ -34,7 +34,7 @@ class Command(BaseCommand): """Entry point.""" loop = asyncio.get_event_loop() coro = asyncio.start_server( - core.new_connection, options["host"], options["port"], loop=loop + core.new_connection, options["host"], options["port"] ) server = loop.run_until_complete(coro) From 268f2c9e161e7523dcb761d7561de8dd0d9a3b85 Mon Sep 17 00:00:00 2001 From: Spitap Date: Thu, 28 Jul 2022 14:28:43 +0200 Subject: [PATCH 12/29] Fix autoconfig check written as SPF check on new admin --- modoboa/admin/app_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modoboa/admin/app_settings.py b/modoboa/admin/app_settings.py index 1b763c0ad..76f683b5c 100644 --- a/modoboa/admin/app_settings.py +++ b/modoboa/admin/app_settings.py @@ -341,7 +341,7 @@ GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([ ) }), ("enable_autoconfig_checks", { - "label": ugettext_lazy("Enable SPF checks"), + "label": ugettext_lazy("Enable autoconfig checks"), "help_text": ugettext_lazy( "Check if every domain has a valid records for " "autoconfiguration" From be883a83493e5f089af1a7dd2024e9dd52556fa2 Mon Sep 17 00:00:00 2001 From: Gael Pasgrimaud Date: Thu, 18 Aug 2022 15:56:17 +0200 Subject: [PATCH 13/29] set root_url js var in template so we can use a PATH_PREFIX without breaking the tfa js stuff --- modoboa/static/js/twocols_nav.js | 4 ++-- modoboa/templates/nlayout.html | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modoboa/static/js/twocols_nav.js b/modoboa/static/js/twocols_nav.js index 45d8bae1c..d04b3e3e8 100644 --- a/modoboa/static/js/twocols_nav.js +++ b/modoboa/static/js/twocols_nav.js @@ -177,7 +177,7 @@ TwocolsNav.prototype = { startTFASetup: function (evt) { evt.preventDefault(); $.ajax({ - url: '/api/v1/account/tfa/setup/', + url: window.root_url + '/api/v1/account/tfa/setup/', type: 'post', contentType: 'application/json' }).done(function (resp) { @@ -191,7 +191,7 @@ TwocolsNav.prototype = { pin_code: $('#pin-code').val() }; $.ajax({ - url: '/api/v1/account/tfa/setup/check/', + url: window.root_url + '/api/v1/account/tfa/setup/check/', type: 'post', global: false, data: JSON.stringify(data), diff --git a/modoboa/templates/nlayout.html b/modoboa/templates/nlayout.html index 2c94c30a4..8a219c595 100644 --- a/modoboa/templates/nlayout.html +++ b/modoboa/templates/nlayout.html @@ -87,6 +87,7 @@