diff --git a/CHANGELOG.md b/CHANGELOG.md index f7da7f9..d8b4855 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to ### Fixed +- 🐛(domains) use a dedicated mail to invite user to manage domain - 🐛(mailbox) fix mailbox creation email language ## [1.13.1] - 2025-03-04 diff --git a/src/backend/core/models.py b/src/backend/core/models.py index b0e812f..42acb17 100644 --- a/src/backend/core/models.py +++ b/src/backend/core/models.py @@ -908,6 +908,9 @@ class BaseInvitation(BaseModel): related_name="invitations", ) + MAIL_TEMPLATE_HTML = None + MAIL_TEMPLATE_TXT = None + class Meta: abstract = True @@ -938,17 +941,24 @@ class BaseInvitation(BaseModel): validity_duration = timedelta(seconds=settings.INVITATION_VALIDITY_DURATION) return timezone.now() > (self.created_at + validity_duration) + def _get_mail_subject(self): + """Get the subject of the invitation.""" + return gettext("Invitation to join La Régie!") + + def _get_mail_context(self): + """Get the template variables for the invitation.""" + return { + "site": Site.objects.get_current(), + } + def email_invitation(self): """Email invitation to the user.""" try: with override(self.issuer.language): - subject = gettext("Invitation to join La Régie!") - template_vars = { - "title": subject, - "site": Site.objects.get_current(), - } - msg_html = render_to_string("mail/html/invitation.html", template_vars) - msg_plain = render_to_string("mail/text/invitation.txt", template_vars) + subject = self._get_mail_subject() + context = self._get_mail_context() + msg_html = render_to_string(self.MAIL_TEMPLATE_HTML, context) + msg_plain = render_to_string(self.MAIL_TEMPLATE_TXT, context) mail.send_mail( subject, msg_plain, @@ -974,6 +984,9 @@ class Invitation(BaseInvitation): max_length=20, choices=RoleChoices.choices, default=RoleChoices.MEMBER ) + MAIL_TEMPLATE_HTML = "mail/html/team_invitation.html" + MAIL_TEMPLATE_TXT = "mail/text/team_invitation.txt" + class Meta: db_table = "people_invitation" verbose_name = _("Team invitation") diff --git a/src/backend/core/static/images/arrow.png b/src/backend/core/static/images/arrow.png new file mode 100644 index 0000000..bf12478 Binary files /dev/null and b/src/backend/core/static/images/arrow.png differ diff --git a/src/backend/core/static/images/logo-footer-mail.png b/src/backend/core/static/images/logo-footer-mail.png new file mode 100644 index 0000000..76e9a85 Binary files /dev/null and b/src/backend/core/static/images/logo-footer-mail.png differ diff --git a/src/backend/core/static/images/logo-laregie.png b/src/backend/core/static/images/logo-laregie.png new file mode 100644 index 0000000..953be44 Binary files /dev/null and b/src/backend/core/static/images/logo-laregie.png differ diff --git a/src/backend/core/tests/test_models_invitations.py b/src/backend/core/tests/test_models_invitations.py index 6b55b58..d0518a5 100644 --- a/src/backend/core/tests/test_models_invitations.py +++ b/src/backend/core/tests/test_models_invitations.py @@ -262,7 +262,7 @@ def test_models_team_invitations_email(): assert email.subject == "Invitation à rejoindre La Régie !" email_content = " ".join(email.body.split()) - assert "Invitation à rejoindre La Régie !" in email_content + assert "Nous sommes ravis de vous accueillir" in email_content assert "[//example.com]" in email_content diff --git a/src/backend/debug/urls.py b/src/backend/debug/urls.py index f162285..89cab28 100644 --- a/src/backend/debug/urls.py +++ b/src/backend/debug/urls.py @@ -3,25 +3,37 @@ from django.urls import path from .views import ( - DebugViewHtml, + DebugViewMaildomainInvitationHtml, + DebugViewMaildomainInvitationTxt, DebugViewNewMailboxHtml, - DebugViewTxt, + DebugViewTeamInvitationHtml, + DebugViewTeamInvitationTxt, ) urlpatterns = [ path( - "__debug__/mail/invitation_html", - DebugViewHtml.as_view(), - name="debug.mail.invitation_html", + "__debug__/mail/team_invitation_html", + DebugViewTeamInvitationHtml.as_view(), + name="debug.mail.team_invitation_html", ), path( - "__debug__/mail/invitation_txt", - DebugViewTxt.as_view(), - name="debug.mail.invitation_txt", + "__debug__/mail/team_invitation_txt", + DebugViewTeamInvitationTxt.as_view(), + name="debug.mail.team_invitation_txt", ), path( "__debug__/mail/new_mailbox_html", DebugViewNewMailboxHtml.as_view(), name="debug.mail.new_mailbox_html", ), + path( + "__debug__/mail/maildomain_invitation_txt", + DebugViewMaildomainInvitationTxt.as_view(), + name="debug.mail.maildomain_invitation_txt", + ), + path( + "__debug__/mail/maildomain_invitation_html", + DebugViewMaildomainInvitationHtml.as_view(), + name="debug.mail.maildomain_invitation_html", + ), ] diff --git a/src/backend/debug/views.py b/src/backend/debug/views.py index 3904e7f..26eff8d 100644 --- a/src/backend/debug/views.py +++ b/src/backend/debug/views.py @@ -8,25 +8,49 @@ class DebugBaseView(TemplateView): def get_context_data(self, **kwargs): """Generates sample datas to have a valid debug email""" - context = super().get_context_data(**kwargs) context["title"] = "Development email preview" - return context -class DebugViewHtml(DebugBaseView): - """Debug View for HTML Email Layout""" +# TEAM INVITATION +class DebugViewTeamInvitationHtml(DebugBaseView): + """Debug view for team invitation html email layout""" - template_name = "mail/html/invitation.html" + template_name = "mail/html/team_invitation.html" -class DebugViewTxt(DebugBaseView): - """Debug View for Text Email Layout""" +class DebugViewTeamInvitationTxt(DebugBaseView): + """Debug view for team invitation text email layout""" - template_name = "mail/text/invitation.txt" + template_name = "mail/text/team_invitation.txt" +# MAIL DOMAIN INVITATION +class DebugViewMaildomainInvitationBase(DebugBaseView): + """Debug view for mail domain invitation base email layout""" + + def get_context_data(self, **kwargs): + """Add some fake context data for mail domain invitation email layout""" + context = super().get_context_data(**kwargs) + context["domain"] = "example.com" + context["role"] = "owner" + return context + + +class DebugViewMaildomainInvitationHtml(DebugViewMaildomainInvitationBase): + """Debug view for mail domain invitation html email layout""" + + template_name = "mail/html/maildomain_invitation.html" + + +class DebugViewMaildomainInvitationTxt(DebugViewMaildomainInvitationBase): + """Debug view for mail domain invitation text email layout""" + + template_name = "mail/text/maildomain_invitation.txt" + + +# NEW MAILBOX class DebugViewNewMailboxHtml(DebugBaseView): """Debug view for new mailbox email layout""" diff --git a/src/backend/mailbox_manager/models.py b/src/backend/mailbox_manager/models.py index 8814241..4f1373f 100644 --- a/src/backend/mailbox_manager/models.py +++ b/src/backend/mailbox_manager/models.py @@ -7,6 +7,7 @@ from django.contrib.auth.base_user import AbstractBaseUser from django.core import exceptions, validators from django.db import models from django.utils.text import slugify +from django.utils.translation import gettext from django.utils.translation import gettext_lazy as _ from core.models import BaseInvitation, BaseModel, Organization, User @@ -294,6 +295,9 @@ class MailDomainInvitation(BaseInvitation): default=MailDomainRoleChoices.VIEWER, ) + MAIL_TEMPLATE_HTML = "mail/html/maildomain_invitation.html" + MAIL_TEMPLATE_TXT = "mail/text/maildomain_invitation.txt" + class Meta: db_table = "people_mail_domain_invitation" verbose_name = _("Mail domain invitation") @@ -307,6 +311,18 @@ class MailDomainInvitation(BaseInvitation): def __str__(self): return f"{self.email} invited to {self.domain}" + def _get_mail_subject(self): + """Get the subject of the invitation.""" + return gettext("[La Suite] You have been invited to join La Régie") + + def _get_mail_context(self): + """Get the template variables for the invitation.""" + return { + **super()._get_mail_context(), + "domain": self.domain.name, + "role": self.get_role_display(), + } + def get_abilities(self, user): """Compute and return abilities for a given user.""" can_delete = False diff --git a/src/backend/mailbox_manager/tests/api/invitations/test_api_domain_invitations_create.py b/src/backend/mailbox_manager/tests/api/invitations/test_api_domain_invitations_create.py index fd5db23..6de5188 100644 --- a/src/backend/mailbox_manager/tests/api/invitations/test_api_domain_invitations_create.py +++ b/src/backend/mailbox_manager/tests/api/invitations/test_api_domain_invitations_create.py @@ -3,6 +3,8 @@ Tests for MailDomainInvitations API endpoint in People's app mailbox_manager. Focus on "create" action. """ +from django.core import mail + import pytest from rest_framework import status from rest_framework.test import APIClient @@ -70,12 +72,18 @@ def test_api_domain_invitations__admin_should_create_invites(role): client = APIClient() client.force_login(user) + assert len(mail.outbox) == 0 + response = client.post( f"/api/v1.0/mail-domains/{domain.slug}/invitations/", invitation_values, format="json", ) assert response.status_code == status.HTTP_201_CREATED + assert len(mail.outbox) == 1 + email = mail.outbox[0] + assert email.to == [invitation_values["email"]] + assert email.subject == "[La Suite] You have been invited to join La Régie" def test_api_domain_invitations__viewers_should_not_invite_to_manage_domains(): diff --git a/src/mail/mjml/maildomain_invitation.mjml b/src/mail/mjml/maildomain_invitation.mjml new file mode 100644 index 0000000..b2eb7b3 --- /dev/null +++ b/src/mail/mjml/maildomain_invitation.mjml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + {% trans "Welcome to" %} La Régie + + + {% trans "Hello," %} + {% blocktranslate with role=role domain=domain trimmed %} + You have been invited to join La Régie to be {{ role }} of the domain {{ domain }}. + {% endblocktranslate %} + + {% trans "To do so, please log in La Régie via ProConnect, by following this link:" %} + + arrow + {% trans "Go to La Régie"%} + + + + {% trans "What is La Régie?" %} + + + {% trans "La Régie is the administration center of la Suite, where you can manage users, groups and domains. You will be able to:" %} +
    +
  • {% trans "create work groups,"%}
  • +
  • {% trans "invite new members,"%}
  • +
  • {% trans "manage mail domains,"%}
  • +
  • {% trans "create new mail accounts,"%}
  • +
  • {% trans "etc."%}
  • +
+
+ + {% trans "Welcome aboard!" %} + + + +

{% trans "Regards," %}

+

{% trans "La Suite Team" %}

+
+ + +
+
+
+
+ +
+ diff --git a/src/mail/mjml/invitation.mjml b/src/mail/mjml/team_invitation.mjml similarity index 100% rename from src/mail/mjml/invitation.mjml rename to src/mail/mjml/team_invitation.mjml