diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5abd863eff6d608a365be48693ef394f9fb30cf8..eb96ddcf445deb36155db0d308393edfe0803d1e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -45,6 +45,9 @@ Fixed * Django messages were not displayed in Vue frontend. * Links to data check objects did not work properly. * Backend cleanup task for Celery wasn't working. +* Urls in invitation email were broken. +* Invitation view didn't work. +* Invitation emails were using wrong styling. `3.0b3`_ - 2023-03-19 --------------------- diff --git a/aleksis/core/frontend/routes.js b/aleksis/core/frontend/routes.js index e7fc1e4fe28da824dd4d7f308154c120551b43ed..aa84f36c4aa9f634f081edb9338f8f264dc9c2fe 100644 --- a/aleksis/core/frontend/routes.js +++ b/aleksis/core/frontend/routes.js @@ -1055,6 +1055,14 @@ const routes = [ titleKey: "about.page_title", }, }, + { + path: "/invitations/accept-invite/:code", + component: () => import("./components/LegacyBaseTemplate.vue"), + props: { + byTheGreatnessOfTheAlmightyAleksolotlISwearIAmWorthyOfUsingTheLegacyBaseTemplate: true, + }, + name: "invitations.accept_invite", + }, ]; // This imports all known AlekSIS app entrypoints diff --git a/aleksis/core/models.py b/aleksis/core/models.py index 964306358262c94687f53400b4adc134bf2ef118..d90790427fb3c22531ec0cda50e9c48eb615e196 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -13,6 +13,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.fields import ArrayField from django.contrib.sites.models import Site +from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import ValidationError from django.core.validators import MaxValueValidator from django.db import models, transaction @@ -1223,8 +1224,36 @@ class PersonInvitation(AbstractBaseInvitation, PureDjangoModel): instance = cls.objects.create(email=email, inviter=inviter, key=code, **kwargs) return instance + def send_invitation(self, request, **kwargs): + """Send the invitation email to the person.""" + current_site = get_current_site(request) + invite_url = reverse("invitations:accept-invite", args=[self.key]) + invite_url = request.build_absolute_uri(invite_url).replace("/django", "") + context = kwargs + context.update( + { + "invite_url": invite_url, + "site_name": current_site.name, + "email": self.email, + "inviter": self.inviter, + "person": self.person, + }, + ) + + send_email(template_name="invitation", recipient_list=[self.email], context=context) + + self.sent = timezone.now() + self.save() + + signals.invite_url_sent.send( + sender=self.__class__, + instance=self, + invite_url_sent=invite_url, + inviter=self.inviter, + ) + key_expired = Invitation.key_expired - send_invitation = Invitation.send_invitation + send_invitation = send_invitation class PDFFile(ExtensibleModel): diff --git a/aleksis/core/tables.py b/aleksis/core/tables.py index c912d13477c607e3374b3c8b4619338a8cb8a6a0..5411cad4747bc8c5de011fcdd2abcde432842236 100644 --- a/aleksis/core/tables.py +++ b/aleksis/core/tables.py @@ -152,13 +152,6 @@ class DashboardWidgetTable(tables.Table): return record._meta.verbose_name -class PersonColumn(tables.Column): - """Returns person object from given id.""" - - def render(self, value): - return Person.objects.get(pk=value) - - class InvitationCodeColumn(tables.Column): """Returns invitation code in a more readable format.""" @@ -170,10 +163,10 @@ class InvitationCodeColumn(tables.Column): class InvitationsTable(tables.Table): """Table to list persons.""" - person_id = PersonColumn() + person = tables.Column() email = tables.EmailColumn() sent = tables.DateColumn() - inviter_id = PersonColumn() + inviter = tables.Column() key = InvitationCodeColumn() accepted = tables.BooleanColumn( yesno="check,cancel", attrs={"span": {"class": "material-icons"}} diff --git a/aleksis/core/templates/invitations/forms/_invite.html b/aleksis/core/templates/invitations/forms/_invite.html index 297997e0b04f3d99a1e1279c8900d0bcc9c50024..4378ff639af86da13091094d70cf1d4b295085be 100644 --- a/aleksis/core/templates/invitations/forms/_invite.html +++ b/aleksis/core/templates/invitations/forms/_invite.html @@ -19,13 +19,14 @@ {% csrf_token %} {% form form=form %}{% endform %} {% trans "Invite" as caption %} - {% include "core/partials/save_button.html" with caption=caption icon="card_giftcard" %} + {% include "core/partials/save_button.html" with caption=caption icon="mdi:account-multiple-plus" %} </form> </div> <div class="col s6"> <h5>{% trans "Generate invitation code" %}</h5> <a class="btn waves-effect waves-light hundred-percent" href="{% url 'generate_invitation_code' %}"> + <i class="material-icons iconify left" data-icon="mdi:account-multiple-plus"></i> {% trans "Generate code" %} </a> </div> diff --git a/aleksis/core/templates/templated_email/invitation.email b/aleksis/core/templates/templated_email/invitation.email new file mode 100644 index 0000000000000000000000000000000000000000..3bf0311b61dbadc6eba025a1ae801a95c0d87521 --- /dev/null +++ b/aleksis/core/templates/templated_email/invitation.email @@ -0,0 +1,24 @@ +{% extends "templated_email/base.email" %} +{% load i18n %} + +{% block subject_content %}{% blocktrans with site=site_name %}Invitation to register on {{ site }}{% endblocktrans %}{% endblock %} + +{% block plain_greeting %}{% if person %}{% blocktrans with person=person.addressing_name %}Hello {{ person }}{% endblocktrans %}{% else %}{% trans "Hello" %}{% endif %},{% endblock %} + +{% block plain_content %} +{% blocktrans with site=site_name %}you have been invited to register on {{ site }}. If you would like to accept this invitation, please click on the following link:{% endblocktrans %} + +{{ invite_url }} +{% endblock %} + +{% block html_greeting %}{% if person %}{% blocktrans with person=person.addressing_name %}Hello {{ person }}{% endblocktrans %}{% else %}{% trans "Hello" %}{% endif %},{% endblock %} + +{% block html_content %} + <p> + {% blocktrans with site=site_name %}you have been invited to register on {{ site }}. If you would like to accept this invitation, please click on the following link:{% endblocktrans %} + </p> + + <a href="{{ invite_url}}"> + {{ invite_url }} + </a> +{% endblock %}