2 Commits

Author SHA1 Message Date
98bb6f50a8 chore: Config IMAP dans le Front 2025-05-27 20:01:00 +02:00
39d6a8e909 chore: Synchronisation IMAP 2025-05-27 19:59:53 +02:00
18 changed files with 234 additions and 69 deletions

View File

@ -2,6 +2,7 @@ from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.core.validators import EmailValidator from django.core.validators import EmailValidator
from django_mailbox.models import Mailbox
class Profile(AbstractUser): class Profile(AbstractUser):
email = models.EmailField(max_length=255, unique=True, default="", validators=[EmailValidator()]) email = models.EmailField(max_length=255, unique=True, default="", validators=[EmailValidator()])
@ -11,9 +12,13 @@ class Profile(AbstractUser):
roleIndexLoginDefault = models.IntegerField(default=0) roleIndexLoginDefault = models.IntegerField(default=0)
code = models.CharField(max_length=200, default="", blank=True) code = models.CharField(max_length=200, default="", blank=True)
datePeremption = models.CharField(max_length=200, default="", blank=True) datePeremption = models.CharField(max_length=200, default="", blank=True)
mailbox = models.OneToOneField(
def __str__(self): Mailbox,
return self.email on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='profile'
)
class ProfileRole(models.Model): class ProfileRole(models.Model):
class RoleType(models.IntegerChoices): class RoleType(models.IntegerChoices):

View File

@ -1,5 +1,4 @@
from django.apps import AppConfig from django.apps import AppConfig
class GestionMessagerieConfig(AppConfig): class GestionMessagerieConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'GestionMessagerie' name = 'GestionMessagerie'

View File

@ -1,6 +1,5 @@
from django.db import models from django.db import models
from Auth.models import Profile from Auth.models import Profile
from django.utils import timezone
class Messagerie(models.Model): class Messagerie(models.Model):
id = models.AutoField(primary_key=True) id = models.AutoField(primary_key=True)

View File

@ -6,7 +6,7 @@ import re
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from rest_framework.exceptions import NotFound from rest_framework.exceptions import NotFound
from Settings.models import SMTPSettings from Settings.models import MailSettings
from Establishment.models import Establishment # Importer le modèle Establishment from Establishment.models import Establishment # Importer le modèle Establishment
def getConnection(id_establishement): def getConnection(id_establishement):
@ -15,14 +15,14 @@ def getConnection(id_establishement):
establishment = Establishment.objects.get(id=id_establishement) establishment = Establishment.objects.get(id=id_establishement)
# Récupérer les paramètres SMTP associés à l'établissement # Récupérer les paramètres SMTP associés à l'établissement
smtp_settings = SMTPSettings.objects.get(establishment=establishment) smtp_settings = MailSettings.objects.get(establishment=establishment)
# Créer une connexion SMTP avec les paramètres récupérés # Créer une connexion SMTP avec les paramètres récupérés
connection = get_connection( connection = get_connection(
host=smtp_settings.smtp_server, host=smtp_settings.smtp_server,
port=smtp_settings.smtp_port, port=smtp_settings.smtp_port,
username=smtp_settings.smtp_user, username=smtp_settings.mail_user,
password=smtp_settings.smtp_password, password=smtp_settings.mail_password,
use_tls=smtp_settings.use_tls, use_tls=smtp_settings.use_tls,
use_ssl=smtp_settings.use_ssl use_ssl=smtp_settings.use_ssl
) )
@ -30,7 +30,7 @@ def getConnection(id_establishement):
except Establishment.DoesNotExist: except Establishment.DoesNotExist:
raise NotFound(f"Aucun établissement trouvé avec l'ID {id_establishement}") raise NotFound(f"Aucun établissement trouvé avec l'ID {id_establishement}")
except SMTPSettings.DoesNotExist: except MailSettings.DoesNotExist:
raise NotFound(f"Aucun paramètre SMTP trouvé pour l'établissement {id_establishement}") raise NotFound(f"Aucun paramètre SMTP trouvé pour l'établissement {id_establishement}")
@ -154,3 +154,24 @@ def isValid(message, fiche_inscription):
mailReponsableAVerifier = responsable.mail mailReponsableAVerifier = responsable.mail
return responsableMail == mailReponsableAVerifier and str(idMail) == str(fiche_inscription.eleve.id) return responsableMail == mailReponsableAVerifier and str(idMail) == str(fiche_inscription.eleve.id)
def test_mailbox_uri(uri):
"""
Teste la validité d'une URI IMAP en tentant une connexion réelle.
Retourne True si la connexion réussit, False sinon.
"""
from django_mailbox.models import Mailbox
try:
mailbox = Mailbox(uri=uri)
conn = mailbox.get_connection()
# Essaye de récupérer un message (ou juste la connexion)
# Pour IMAP, get_message() va ouvrir et fermer la connexion
try:
next(conn.get_message())
except StopIteration:
# Aucun message, mais connexion OK
pass
return True
except Exception as e:
print(f"Erreur de connexion IMAP : {e}")
return False

View File

@ -62,7 +62,8 @@ INSTALLED_APPS = [
'django_celery_beat', 'django_celery_beat',
'N3wtSchool', 'N3wtSchool',
'drf_yasg', 'drf_yasg',
'rest_framework_simplejwt' 'rest_framework_simplejwt',
'django_mailbox',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -166,6 +167,16 @@ LOGGING = {
"level": os.getenv("GESTION_ENSEIGNANTS_LOG_LEVEL", "INFO"), "level": os.getenv("GESTION_ENSEIGNANTS_LOG_LEVEL", "INFO"),
"propagate": False, "propagate": False,
}, },
"django_mailbox": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": False,
},
"django_mailbox.models": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": False,
},
}, },
} }

View File

@ -14,8 +14,9 @@ def setup_periodic_tasks(sender, **kwargs):
# Déclarer la tâche périodique # Déclarer la tâche périodique
PeriodicTask.objects.get_or_create( PeriodicTask.objects.get_or_create(
interval=schedule, # Utiliser l'intervalle défini ci-dessus interval=schedule,
name='Tâche périodique toutes les 5 secondes', name='getMail',
task='Subscriptions.tasks.check_for_signature_deadlines', # Remplacer par le nom de ta tâche task='N3wtSchool.tasks.run_getmail',
kwargs=json.dumps({}) # Si nécessaire, ajoute kwargs=json.dumps({}),
defaults={"enabled": False}
) )

View File

@ -0,0 +1,33 @@
from celery import shared_task
from django_mailbox.models import Message, Mailbox
from django_celery_beat.models import PeriodicTask
import logging
logger = logging.getLogger("django_mailbox")
@shared_task
def run_getmail():
"""
Tâche périodique pour lancer l'import IMAP sur toutes les mailboxes actives
et traiter les nouveaux messages interceptés selon des critères.
"""
logger.info("Début import IMAP")
for mailbox in Mailbox.objects.filter(active=True):
messages = mailbox.get_new_mail()
try:
for message in messages:
logger.info(f"[IMAP] Tentative d'import : {message.subject} de {message.from_address}")
# Filtrage sur le sujet et l'émetteur
if (
message.subject == "n3wt"
and message.from_address == "anthony.casini.30@gmail.com"
):
logger.info(f"[IMAP] Message importé : {message.subject} de {message.from_address}")
else:
# Optionnel : supprimer le message importé qui ne correspond pas
message.delete()
except Exception as e:
logger.error(f"Erreur lors de l'import des messages pour la mailbox {mailbox}: {e}", exc_info=True)
logger.info("Fin import IMAP")

View File

@ -4,14 +4,22 @@ from django.utils.translation import gettext_lazy as _
from django.conf import settings from django.conf import settings
from Establishment.models import Establishment from Establishment.models import Establishment
class SMTPSettings(models.Model): class MailSettings(models.Model):
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE) establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE)
# Paramètres communs (si tu veux un seul user/pass pour SMTP et IMAP)
mail_user = models.CharField(max_length=255)
mail_password = models.CharField(max_length=255)
# SMTP
smtp_server = models.CharField(max_length=255) smtp_server = models.CharField(max_length=255)
smtp_port = models.PositiveIntegerField() smtp_port = models.PositiveIntegerField()
smtp_user = models.CharField(max_length=255)
smtp_password = models.CharField(max_length=255)
use_tls = models.BooleanField(default=True) use_tls = models.BooleanField(default=True)
use_ssl = models.BooleanField(default=False) use_ssl = models.BooleanField(default=False)
# IMAP
imap_server = models.CharField(max_length=255)
imap_port = models.PositiveIntegerField(default=993)
def __str__(self): def __str__(self):
return f"SMTP Settings ({self.smtp_server}:{self.smtp_port})" return f"MailSettings ({self.establishment} - {self.mail_user})"

View File

@ -1,7 +1,7 @@
from rest_framework import serializers from rest_framework import serializers
from .models import SMTPSettings from .models import MailSettings
class SMTPSettingsSerializer(serializers.ModelSerializer): class MailSettingsSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = SMTPSettings model = MailSettings
fields = '__all__' fields = '__all__'

View File

@ -1,6 +1,7 @@
from django.urls import path from django.urls import path
from .views import SMTPSettingsView from .views import MailSettingsView, SyncImapView
urlpatterns = [ urlpatterns = [
path('smtp-settings/', SMTPSettingsView.as_view(), name='smtp_settings'), path('mail-settings/', MailSettingsView.as_view(), name='smtp_settings'),
path('sync-imap/', SyncImapView.as_view(), name='sync-imap'),
] ]

View File

@ -1,12 +1,16 @@
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi from drf_yasg import openapi
from .models import SMTPSettings from .models import MailSettings
from .serializers import SMTPSettingsSerializer from .serializers import MailSettingsSerializer
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from django_mailbox.models import Mailbox
from Auth.models import Profile
from django_celery_beat.models import PeriodicTask
import urllib.parse
class SMTPSettingsView(APIView): class MailSettingsView(APIView):
""" """
API pour gérer les paramètres SMTP. API pour gérer les paramètres SMTP.
""" """
@ -23,7 +27,7 @@ class SMTPSettingsView(APIView):
) )
], ],
responses={ responses={
200: SMTPSettingsSerializer(many=True), 200: MailSettingsSerializer(many=True),
404: openapi.Response(description="Aucun paramètre SMTP trouvé."), 404: openapi.Response(description="Aucun paramètre SMTP trouvé."),
500: openapi.Response(description="Erreur interne du serveur."), 500: openapi.Response(description="Erreur interne du serveur."),
}, },
@ -34,32 +38,48 @@ class SMTPSettingsView(APIView):
try: try:
if establishment_id: if establishment_id:
# Récupérer les paramètres SMTP pour un établissement spécifique # Récupérer les paramètres SMTP pour un établissement spécifique
smtp_settings = SMTPSettings.objects.filter(establishment_id=establishment_id).first() mail_settings = MailSettings.objects.filter(establishment_id=establishment_id).first()
if not smtp_settings: if not mail_settings:
return Response( return Response(
{'error': f"Aucun paramètre SMTP trouvé pour l'établissement {establishment_id}."}, {'error': f"Aucun paramètre SMTP trouvé pour l'établissement {establishment_id}."},
status=status.HTTP_404_NOT_FOUND status=status.HTTP_404_NOT_FOUND
) )
serializer = SMTPSettingsSerializer(smtp_settings) serializer = MailSettingsSerializer(mail_settings)
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
else: else:
# Récupérer tous les paramètres SMTP # Récupérer tous les paramètres SMTP
smtp_settings = SMTPSettings.objects.all() mail_settings = MailSettings.objects.all()
if not smtp_settings.exists(): if not mail_settings.exists():
return Response( return Response(
{'error': "Aucun paramètre SMTP trouvé."}, {'error': "Aucun paramètre SMTP trouvé."},
status=status.HTTP_404_NOT_FOUND status=status.HTTP_404_NOT_FOUND
) )
serializer = SMTPSettingsSerializer(smtp_settings, many=True) serializer = MailSettingsSerializer(mail_settings, many=True)
# ...dans une vue ou un serializer...
from N3wtSchool.mailManager import test_mailbox_uri
import urllib.parse
imap_user = "anthony.audrey.34@gmail.com"
imap_password = "cztn wyme odjt lbjt"
imap_server = "imap.gmail.com"
imap_port = 993
encoded_user = urllib.parse.quote(imap_user)
encoded_password = urllib.parse.quote(imap_password)
uri = f"imap+ssl://{encoded_user}:{encoded_password}@{imap_server}:{imap_port}"
if not test_mailbox_uri(uri):
print(f'uri : {uri}')
return Response({'error': "Connexion IMAP impossible. Vérifiez les paramètres."}, status=status.HTTP_400_BAD_REQUEST)
# Ensuite, tu peux créer la Mailbox si la connexion est OK
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
except Exception as e: except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@swagger_auto_schema( @swagger_auto_schema(
operation_description="Créer ou mettre à jour les paramètres SMTP pour un établissement spécifique", operation_description="Créer ou mettre à jour les paramètres SMTP pour un établissement spécifique",
request_body=SMTPSettingsSerializer, request_body=MailSettingsSerializer,
responses={ responses={
200: SMTPSettingsSerializer(), 200: MailSettingsSerializer(),
400: openapi.Response(description="Données invalides."), 400: openapi.Response(description="Données invalides."),
500: openapi.Response(description="Erreur interne du serveur."), 500: openapi.Response(description="Erreur interne du serveur."),
}, },
@ -67,15 +87,58 @@ class SMTPSettingsView(APIView):
def post(self, request): def post(self, request):
data = request.data data = request.data
try: try:
smtp_settings = SMTPSettings.objects.first() mail_settings = MailSettings.objects.first()
if smtp_settings: if mail_settings:
serializer = SMTPSettingsSerializer(smtp_settings, data=data) serializer = MailSettingsSerializer(mail_settings, data=data)
else: else:
serializer = SMTPSettingsSerializer(data=data) serializer = MailSettingsSerializer(data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() mail_settings_instance = serializer.save()
# Création de la mailbox pour le profil si profil_id fourni
profile_id = data.get('profile_id')
if profile_id:
try:
profile = Profile.objects.get(id=profile_id)
email = mail_settings_instance.mail_user
imap_server = mail_settings_instance.imap_server
imap_port = mail_settings_instance.imap_port
imap_user = mail_settings_instance.mail_user
imap_password = mail_settings_instance.mail_password
# Encodage du username et du mot de passe pour l'URI IMAP
encoded_user = urllib.parse.quote(imap_user)
encoded_password = urllib.parse.quote(imap_password)
uri = f"imap+ssl://{encoded_user}:{encoded_password}@{imap_server}:{imap_port}"
mailbox, created = Mailbox.objects.get_or_create(
name=email,
defaults={
"uri": uri,
"from_email": email,
"active": True,
}
)
# Associer la mailbox au profil si champ prévu
if hasattr(profile, "mailbox"):
profile.mailbox = mailbox
profile.save()
except Profile.DoesNotExist:
pass # Profil non trouvé, on ignore
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class SyncImapView(APIView):
def post(self, request):
sync_imap = request.data.get("sync_imap", False)
try:
task = PeriodicTask.objects.get(name='getMail')
task.enabled = bool(sync_imap)
task.save()
return Response({"success": True, "enabled": task.enabled})
except PeriodicTask.DoesNotExist:
return Response({"error": "Tâche non trouvée."}, status=status.HTTP_404_NOT_FOUND)

View File

@ -4,9 +4,8 @@ from rest_framework import status
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from Subscriptions.models import StudentCompetency, Student from Subscriptions.models import StudentCompetency, Student, BilanCompetence
from Common.models import Domain from Common.models import Domain
from Subscriptions.models import BilanCompetence
from datetime import date from datetime import date
from N3wtSchool.renderers import render_to_pdf from N3wtSchool.renderers import render_to_pdf
from django.core.files import File from django.core.files import File

Binary file not shown.

View File

@ -21,12 +21,14 @@ export default function SettingsPage() {
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState('');
const [smtpServer, setSmtpServer] = useState(''); const [smtpServer, setSmtpServer] = useState('');
const [imapServer, setImapServer] = useState('');
const [smtpPort, setSmtpPort] = useState(''); const [smtpPort, setSmtpPort] = useState('');
const [smtpUser, setSmtpUser] = useState(''); const [imapPort, setImapPort] = useState('');
const [smtpPassword, setSmtpPassword] = useState(''); const [mailUser, setMailUser] = useState('');
const [mailPassword, setMailPassword] = useState('');
const [useTls, setUseTls] = useState(true); const [useTls, setUseTls] = useState(true);
const [useSsl, setUseSsl] = useState(false); const [useSsl, setUseSsl] = useState(false);
const { selectedEstablishmentId } = useEstablishment(); const { user, selectedEstablishmentId } = useEstablishment();
const csrfToken = useCsrfToken(); // Récupération du csrfToken const csrfToken = useCsrfToken(); // Récupération du csrfToken
const { showNotification } = useNotification(); const { showNotification } = useNotification();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
@ -52,8 +54,10 @@ export default function SettingsPage() {
.then((data) => { .then((data) => {
setSmtpServer(data.smtp_server || ''); setSmtpServer(data.smtp_server || '');
setSmtpPort(data.smtp_port || ''); setSmtpPort(data.smtp_port || '');
setSmtpUser(data.smtp_user || ''); setImapServer(data.imap_server || '');
setSmtpPassword(data.smtp_password || ''); setImapPort(data.imap_port || '');
setMailUser(data.mail_user || '');
setMailPassword(data.mail_password || '');
setUseTls(data.use_tls || false); setUseTls(data.use_tls || false);
setUseSsl(data.use_ssl || false); setUseSsl(data.use_ssl || false);
}) })
@ -95,16 +99,24 @@ export default function SettingsPage() {
setSmtpServer(e.target.value); setSmtpServer(e.target.value);
}; };
const handleImapServerChange = (e) => {
setImapServer(e.target.value);
};
const handleSmtpPortChange = (e) => { const handleSmtpPortChange = (e) => {
setSmtpPort(e.target.value); setSmtpPort(e.target.value);
}; };
const handleSmtpUserChange = (e) => { const handleImapPortChange = (e) => {
setSmtpUser(e.target.value); setImapPort(e.target.value);
}; };
const handleSmtpPasswordChange = (e) => { const handleMailUserChange = (e) => {
setSmtpPassword(e.target.value); setMailUser(e.target.value);
};
const handleMailPasswordChange = (e) => {
setMailPassword(e.target.value);
}; };
const handleUseTlsChange = (e) => { const handleUseTlsChange = (e) => {
@ -131,10 +143,13 @@ export default function SettingsPage() {
e.preventDefault(); e.preventDefault();
const smtpData = { const smtpData = {
establishment: selectedEstablishmentId, establishment: selectedEstablishmentId,
profile_id: user.user_id,
smtp_server: smtpServer, smtp_server: smtpServer,
smtp_port: smtpPort, smtp_port: smtpPort,
smtp_user: smtpUser, imap_server: imapServer,
smtp_password: smtpPassword, imap_port: imapPort,
mail_user: mailUser,
mail_password: mailPassword,
use_tls: useTls, use_tls: useTls,
use_ssl: useSsl, use_ssl: useSsl,
}; };
@ -212,15 +227,25 @@ export default function SettingsPage() {
onChange={handleSmtpPortChange} onChange={handleSmtpPortChange}
/> />
<InputText <InputText
label="Utilisateur SMTP" label="Serveur IMAP"
value={smtpUser} value={imapServer}
onChange={handleSmtpUserChange} onChange={handleImapServerChange}
/> />
<InputText <InputText
label="Mot de passe SMTP" label="Port IMAP"
value={imapPort}
onChange={handleImapPortChange}
/>
<InputText
label="Adresse mail"
value={mailUser}
onChange={handleMailUserChange}
/>
<InputText
label="Mot de passe"
type="password" type="password"
value={smtpPassword} value={mailPassword}
onChange={handleSmtpPasswordChange} onChange={handleMailPasswordChange}
/> />
</div> </div>
<div className="mt-6 border-t pt-4"> <div className="mt-6 border-t pt-4">

View File

@ -1,4 +1,4 @@
import { BE_SETTINGS_SMTP_URL } from '@/utils/Url'; import { BE_SETTINGS_MAIL_URL } from '@/utils/Url';
import { errorHandler, requestResponseHandler } from './actionsHandlers'; import { errorHandler, requestResponseHandler } from './actionsHandlers';
export const PENDING = 'pending'; export const PENDING = 'pending';
@ -6,7 +6,7 @@ export const SUBSCRIBED = 'subscribed';
export const ARCHIVED = 'archived'; export const ARCHIVED = 'archived';
export const fetchSmtpSettings = (csrfToken, establishment_id = null) => { export const fetchSmtpSettings = (csrfToken, establishment_id = null) => {
let url = `${BE_SETTINGS_SMTP_URL}/`; let url = `${BE_SETTINGS_MAIL_URL}/`;
if (establishment_id) { if (establishment_id) {
url += `?establishment_id=${establishment_id}`; url += `?establishment_id=${establishment_id}`;
} }
@ -21,7 +21,7 @@ export const fetchSmtpSettings = (csrfToken, establishment_id = null) => {
}; };
export const editSmtpSettings = (data, csrfToken) => { export const editSmtpSettings = (data, csrfToken) => {
return fetch(`${BE_SETTINGS_SMTP_URL}/`, { return fetch(`${BE_SETTINGS_MAIL_URL}/`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@ -30,7 +30,7 @@ export default function EmailSender({ csrfToken }) {
// Vérifier si les paramètres SMTP sont configurés // Vérifier si les paramètres SMTP sont configurés
fetchSmtpSettings(csrfToken, selectedEstablishmentId) fetchSmtpSettings(csrfToken, selectedEstablishmentId)
.then((data) => { .then((data) => {
if (data.smtp_server && data.smtp_port && data.smtp_user) { if (data.smtp_server && data.smtp_port && data.mail_user) {
setFromEmail(data.smtp_user); setFromEmail(data.smtp_user);
setSmtpConfigured(true); setSmtpConfigured(true);
} else { } else {

View File

@ -62,7 +62,7 @@ export const BE_GESTIONMESSAGERIE_SEND_MESSAGE_URL = `${BASE_URL}/GestionMessage
export const BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL = `${BASE_URL}/GestionMessagerie/search-recipients`; export const BE_GESTIONMESSAGERIE_SEARCH_RECIPIENTS_URL = `${BASE_URL}/GestionMessagerie/search-recipients`;
// SETTINGS // SETTINGS
export const BE_SETTINGS_SMTP_URL = `${BASE_URL}/Settings/smtp-settings`; export const BE_SETTINGS_MAIL_URL = `${BASE_URL}/Settings/mail-settings`;
// URL FRONT-END // URL FRONT-END
export const FE_HOME_URL = '/'; export const FE_HOME_URL = '/';