mirror of
https://gitlab.com/animath/si/plateforme-corres2math.git
synced 2025-02-06 11:33:00 +00:00
Confirm email addresses
This commit is contained in:
parent
3741557200
commit
ae56203970
@ -1,9 +1,10 @@
|
|||||||
FROM python:3-alpine
|
FROM python:3-alpine
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED 1
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
ENV DJANGO_ALLOW_ASYNC_UNSAFE 1
|
||||||
|
|
||||||
# Install LaTeX requirements
|
# Install LaTeX requirements
|
||||||
RUN apk add --no-cache gettext texlive nginx gcc libc-dev libffi-dev postgresql-dev mariadb-connector-c-dev
|
RUN apk add --no-cache gettext texlive nginx gcc libc-dev libffi-dev postgresql-dev
|
||||||
|
|
||||||
RUN apk add --no-cache bash
|
RUN apk add --no-cache bash
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/
|
|||||||
RUN ln -sf /code/nginx_corres2math.conf /etc/nginx/conf.d/corres2math.conf
|
RUN ln -sf /code/nginx_corres2math.conf /etc/nginx/conf.d/corres2math.conf
|
||||||
RUN rm /etc/nginx/conf.d/default.conf
|
RUN rm /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
RUN cp /code/corres2math.cron /etc/crontabs/corres2math
|
RUN crontab /code/corres2math.cron
|
||||||
|
|
||||||
# With a bashrc, the shell is better
|
# With a bashrc, the shell is better
|
||||||
RUN ln -s /code/.bashrc /root/.bashrc
|
RUN ln -s /code/.bashrc /root/.bashrc
|
||||||
|
@ -6,6 +6,7 @@ class RegistrationConfig(AppConfig):
|
|||||||
name = 'registration'
|
name = 'registration'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from registration.signals import set_username, create_admin_registration
|
from registration.signals import set_username, send_email_link, create_admin_registration
|
||||||
pre_save.connect(set_username, "auth.User")
|
pre_save.connect(set_username, "auth.User")
|
||||||
|
pre_save.connect(send_email_link, "auth.User")
|
||||||
post_save.connect(create_admin_registration, "auth.User")
|
post_save.connect(create_admin_registration, "auth.User")
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.1.1 on 2020-09-22 16:56
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('registration', '0002_auto_20200921_1948'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='registration',
|
||||||
|
name='email_confirmed',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='email confirmed'),
|
||||||
|
),
|
||||||
|
]
|
@ -1,7 +1,13 @@
|
|||||||
|
from django.contrib.sites.models import Site
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.template import loader
|
||||||
|
from django.utils.encoding import force_bytes
|
||||||
|
from django.utils.http import urlsafe_base64_encode
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from polymorphic.models import PolymorphicModel
|
from polymorphic.models import PolymorphicModel
|
||||||
|
|
||||||
|
from corres2math.tokens import email_validation_token
|
||||||
|
|
||||||
|
|
||||||
class Registration(PolymorphicModel):
|
class Registration(PolymorphicModel):
|
||||||
user = models.OneToOneField(
|
user = models.OneToOneField(
|
||||||
@ -15,6 +21,36 @@ class Registration(PolymorphicModel):
|
|||||||
verbose_name=_("Grant Animath to contact me in the future about other actions"),
|
verbose_name=_("Grant Animath to contact me in the future about other actions"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
email_confirmed = models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("email confirmed"),
|
||||||
|
)
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
self.send_email_validation_link()
|
||||||
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
def send_email_validation_link(self):
|
||||||
|
subject = "[Corres2math] " + str(_("Activate your Correspondances account"))
|
||||||
|
token = email_validation_token.make_token(self.user)
|
||||||
|
uid = urlsafe_base64_encode(force_bytes(self.user.pk))
|
||||||
|
site = Site.objects.first()
|
||||||
|
message = loader.render_to_string('registration/mails/email_validation_email.txt',
|
||||||
|
{
|
||||||
|
'user': self.user,
|
||||||
|
'domain': site.domain,
|
||||||
|
'token': token,
|
||||||
|
'uid': uid,
|
||||||
|
})
|
||||||
|
html = loader.render_to_string('registration/mails/email_validation_email.html',
|
||||||
|
{
|
||||||
|
'user': self.user,
|
||||||
|
'domain': site.domain,
|
||||||
|
'token': token,
|
||||||
|
'uid': uid,
|
||||||
|
})
|
||||||
|
self.user.email_user(subject, message, html_message=html)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
from registration.models import AdminRegistration
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from registration.models import AdminRegistration, Registration
|
||||||
|
|
||||||
|
|
||||||
def set_username(instance, **_):
|
def set_username(instance, **_):
|
||||||
instance.username = instance.email
|
instance.username = instance.email
|
||||||
|
|
||||||
|
|
||||||
|
def send_email_link(instance, **_):
|
||||||
|
if instance.pk:
|
||||||
|
old_instance = User.objects.get(pk=instance.pk)
|
||||||
|
if old_instance.email != instance.email:
|
||||||
|
registration = Registration.objects.get(user=instance)
|
||||||
|
registration.email_confirmed = False
|
||||||
|
registration.save()
|
||||||
|
registration.user = instance
|
||||||
|
registration.send_email_validation_link()
|
||||||
|
|
||||||
|
|
||||||
def create_admin_registration(instance, **_):
|
def create_admin_registration(instance, **_):
|
||||||
if instance.is_superuser:
|
if instance.is_superuser:
|
||||||
AdminRegistration.objects.get_or_create(user=instance)
|
AdminRegistration.objects.get_or_create(user=instance)
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from .views import SignupView
|
from .views import SignupView, UserValidationEmailSentView, UserResendValidationEmailView, UserValidateView
|
||||||
|
|
||||||
app_name = "registration"
|
app_name = "registration"
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("signup", SignupView.as_view(), name="signup"),
|
path("signup", SignupView.as_view(), name="signup"),
|
||||||
|
path('validate_email/sent/', UserValidationEmailSentView.as_view(), name='email_validation_sent'),
|
||||||
|
path('validate_email/resend/<int:pk>/', UserResendValidationEmailView.as_view(),
|
||||||
|
name='email_validation_resend'),
|
||||||
|
path('validate_email/<uidb64>/<token>/', UserValidateView.as_view(), name='email_validation'),
|
||||||
]
|
]
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.shortcuts import resolve_url, redirect
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.views.generic import CreateView
|
from django.utils.http import urlsafe_base64_decode
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views.generic import CreateView, TemplateView, DetailView
|
||||||
|
|
||||||
|
from corres2math.tokens import email_validation_token
|
||||||
from .forms import SignupForm, StudentRegistrationForm, CoachRegistrationForm
|
from .forms import SignupForm, StudentRegistrationForm, CoachRegistrationForm
|
||||||
|
|
||||||
|
|
||||||
@ -39,3 +46,78 @@ class SignupView(CreateView):
|
|||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse_lazy("index")
|
return reverse_lazy("index")
|
||||||
|
|
||||||
|
|
||||||
|
class UserValidateView(TemplateView):
|
||||||
|
"""
|
||||||
|
A view to validate the email address.
|
||||||
|
"""
|
||||||
|
title = _("Email validation")
|
||||||
|
template_name = 'registration/email_validation_complete.html'
|
||||||
|
extra_context = {"title": _("Validate email")}
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
With a given token and user id (in params), validate the email address.
|
||||||
|
"""
|
||||||
|
assert 'uidb64' in kwargs and 'token' in kwargs
|
||||||
|
|
||||||
|
self.validlink = False
|
||||||
|
user = self.get_user(kwargs['uidb64'])
|
||||||
|
token = kwargs['token']
|
||||||
|
|
||||||
|
# Validate the token
|
||||||
|
if user is not None and email_validation_token.check_token(user, token):
|
||||||
|
self.validlink = True
|
||||||
|
user.registration.email_confirmed = True
|
||||||
|
user.save()
|
||||||
|
return self.render_to_response(self.get_context_data(), status=200 if self.validlink else 400)
|
||||||
|
|
||||||
|
def get_user(self, uidb64):
|
||||||
|
"""
|
||||||
|
Get user from the base64-encoded string.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# urlsafe_base64_decode() decodes to bytestring
|
||||||
|
uid = urlsafe_base64_decode(uidb64).decode()
|
||||||
|
user = User.objects.get(pk=uid)
|
||||||
|
except (TypeError, ValueError, OverflowError, User.DoesNotExist, ValidationError):
|
||||||
|
user = None
|
||||||
|
return user
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['user_object'] = self.get_user(self.kwargs["uidb64"])
|
||||||
|
context['login_url'] = resolve_url(settings.LOGIN_URL)
|
||||||
|
if self.validlink:
|
||||||
|
context['validlink'] = True
|
||||||
|
else:
|
||||||
|
context.update({
|
||||||
|
'title': _('Email validation unsuccessful'),
|
||||||
|
'validlink': False,
|
||||||
|
})
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class UserValidationEmailSentView(TemplateView):
|
||||||
|
"""
|
||||||
|
Display the information that the validation link has been sent.
|
||||||
|
"""
|
||||||
|
template_name = 'registration/email_validation_email_sent.html'
|
||||||
|
extra_context = {"title": _('Email validation email sent')}
|
||||||
|
|
||||||
|
|
||||||
|
class UserResendValidationEmailView(LoginRequiredMixin, DetailView):
|
||||||
|
"""
|
||||||
|
Rensend the email validation link.
|
||||||
|
"""
|
||||||
|
model = User
|
||||||
|
extra_context = {"title": _("Resend email validation link")}
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
user = self.get_object()
|
||||||
|
|
||||||
|
user.profile.send_email_validation_link()
|
||||||
|
|
||||||
|
# TODO Change URL
|
||||||
|
return redirect('index')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# m h dom mon dow user command
|
# min hour day month weekday command
|
||||||
# Envoyer les mails en attente
|
# Envoyer les mails en attente
|
||||||
* * * * * root cd /code && python manage.py send_mail -c 1
|
* * * * * cd /code && python manage.py send_mail -c 1
|
||||||
* * * * * root cd /code && python manage.py retry_deferred -c 1
|
* * * * * cd /code && python manage.py retry_deferred -c 1
|
||||||
00 0 * * * root cd /code && python manage.py purge_mail_log 7 -c 1
|
0 0 * * * cd /code && python manage.py purge_mail_log 7 -c 1
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||||
|
|
||||||
EMAIL_BACKEND = 'mailer.backend.DbBackend'
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
MAILER_EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
|
||||||
|
26
corres2math/tokens.py
Normal file
26
corres2math/tokens.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
|
||||||
|
"""
|
||||||
|
Create a unique token generator to confirm email addresses.
|
||||||
|
"""
|
||||||
|
def _make_hash_value(self, user, timestamp):
|
||||||
|
"""
|
||||||
|
Hash the user's primary key and some user state that's sure to change
|
||||||
|
after an account validation to produce a token that invalidated when
|
||||||
|
it's used:
|
||||||
|
1. The user.profile.email_confirmed field will change upon an account
|
||||||
|
validation.
|
||||||
|
2. The last_login field will usually be updated very shortly after
|
||||||
|
an account validation.
|
||||||
|
Failing those things, settings.PASSWORD_RESET_TIMEOUT_DAYS eventually
|
||||||
|
invalidates the token.
|
||||||
|
"""
|
||||||
|
# Truncate microseconds so that tokens are consistent even if the
|
||||||
|
# database doesn't support microseconds.
|
||||||
|
login_timestamp = '' if user.last_login is None else user.last_login.replace(microsecond=0, tzinfo=None)
|
||||||
|
return str(user.pk) + str(user.email) + str(login_timestamp) + str(timestamp)
|
||||||
|
|
||||||
|
|
||||||
|
email_validation_token = AccountActivationTokenGenerator()
|
@ -1,5 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
crond -l 0
|
||||||
|
|
||||||
python manage.py compilemessages
|
python manage.py compilemessages
|
||||||
python manage.py migrate
|
python manage.py migrate
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Corres2math\n"
|
"Project-Id-Version: Corres2math\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-09-22 18:21+0200\n"
|
"POT-Creation-Date: 2020-09-22 18:49+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
|
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -25,7 +25,7 @@ msgstr "API"
|
|||||||
msgid "Logs"
|
msgid "Logs"
|
||||||
msgstr "Logs"
|
msgstr "Logs"
|
||||||
|
|
||||||
#: apps/logs/models.py:22 apps/registration/models.py:10
|
#: apps/logs/models.py:22 apps/registration/models.py:16
|
||||||
msgid "user"
|
msgid "user"
|
||||||
msgstr "utilisateur"
|
msgstr "utilisateur"
|
||||||
|
|
||||||
@ -115,7 +115,8 @@ msgid ""
|
|||||||
"Give the authorisation to publish the video on the main website to promote "
|
"Give the authorisation to publish the video on the main website to promote "
|
||||||
"the action."
|
"the action."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Donner l'autorisation de publier la vidéo sur le site principal pour promouvoir les Correspondances."
|
"Donner l'autorisation de publier la vidéo sur le site principal pour "
|
||||||
|
"promouvoir les Correspondances."
|
||||||
|
|
||||||
#: apps/participation/models.py:35
|
#: apps/participation/models.py:35
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@ -123,7 +124,7 @@ msgid "Team {name} ({trigram})"
|
|||||||
msgstr "Équipe {name} ({trigram})"
|
msgstr "Équipe {name} ({trigram})"
|
||||||
|
|
||||||
#: apps/participation/models.py:38 apps/participation/models.py:49
|
#: apps/participation/models.py:38 apps/participation/models.py:49
|
||||||
#: apps/registration/models.py:38 apps/registration/models.py:71
|
#: apps/registration/models.py:70 apps/registration/models.py:103
|
||||||
msgid "team"
|
msgid "team"
|
||||||
msgstr "équipe"
|
msgstr "équipe"
|
||||||
|
|
||||||
@ -202,85 +203,93 @@ msgstr "rôle"
|
|||||||
msgid "participant"
|
msgid "participant"
|
||||||
msgstr "participant"
|
msgstr "participant"
|
||||||
|
|
||||||
#: apps/registration/forms.py:14 apps/registration/models.py:80
|
#: apps/registration/forms.py:14 apps/registration/models.py:112
|
||||||
msgid "coach"
|
msgid "coach"
|
||||||
msgstr "encadrant"
|
msgstr "encadrant"
|
||||||
|
|
||||||
#: apps/registration/models.py:15
|
#: apps/registration/models.py:21
|
||||||
msgid "Grant Animath to contact me in the future about other actions"
|
msgid "Grant Animath to contact me in the future about other actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Autoriser Animath à me recontacter à l'avenir à propos d'autres actions"
|
"Autoriser Animath à me recontacter à l'avenir à propos d'autres actions"
|
||||||
|
|
||||||
#: apps/registration/models.py:23
|
#: apps/registration/models.py:26
|
||||||
|
msgid "email confirmed"
|
||||||
|
msgstr "email confirmé"
|
||||||
|
|
||||||
|
#: apps/registration/models.py:30
|
||||||
|
msgid "Activate your Correspondances account"
|
||||||
|
msgstr "Activez votre compte des Correspondances"
|
||||||
|
|
||||||
|
#: apps/registration/models.py:55
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "registration of {first_name} {last_name}"
|
msgid "registration of {first_name} {last_name}"
|
||||||
msgstr "inscription de {first_name} {last_name}"
|
msgstr "inscription de {first_name} {last_name}"
|
||||||
|
|
||||||
#: apps/registration/models.py:27
|
#: apps/registration/models.py:59
|
||||||
msgid "registration"
|
msgid "registration"
|
||||||
msgstr "inscription"
|
msgstr "inscription"
|
||||||
|
|
||||||
#: apps/registration/models.py:28
|
#: apps/registration/models.py:60
|
||||||
msgid "registrations"
|
msgid "registrations"
|
||||||
msgstr "inscriptions"
|
msgstr "inscriptions"
|
||||||
|
|
||||||
#: apps/registration/models.py:43
|
#: apps/registration/models.py:75
|
||||||
msgid "12th grade"
|
msgid "12th grade"
|
||||||
msgstr "Terminale"
|
msgstr "Terminale"
|
||||||
|
|
||||||
#: apps/registration/models.py:44
|
#: apps/registration/models.py:76
|
||||||
msgid "11th grade"
|
msgid "11th grade"
|
||||||
msgstr "Première"
|
msgstr "Première"
|
||||||
|
|
||||||
#: apps/registration/models.py:45
|
#: apps/registration/models.py:77
|
||||||
msgid "10th grade or lower"
|
msgid "10th grade or lower"
|
||||||
msgstr "Seconde ou inférieur"
|
msgstr "Seconde ou inférieur"
|
||||||
|
|
||||||
#: apps/registration/models.py:47
|
#: apps/registration/models.py:79
|
||||||
msgid "student class"
|
msgid "student class"
|
||||||
msgstr "classe"
|
msgstr "classe"
|
||||||
|
|
||||||
#: apps/registration/models.py:52
|
#: apps/registration/models.py:84
|
||||||
msgid "school"
|
msgid "school"
|
||||||
msgstr "école"
|
msgstr "école"
|
||||||
|
|
||||||
#: apps/registration/models.py:57
|
#: apps/registration/models.py:89
|
||||||
msgid "student"
|
msgid "student"
|
||||||
msgstr "étudiant"
|
msgstr "étudiant"
|
||||||
|
|
||||||
#: apps/registration/models.py:60
|
#: apps/registration/models.py:92
|
||||||
msgid "student registration"
|
msgid "student registration"
|
||||||
msgstr "inscription d'élève"
|
msgstr "inscription d'élève"
|
||||||
|
|
||||||
#: apps/registration/models.py:61
|
#: apps/registration/models.py:93
|
||||||
msgid "student registrations"
|
msgid "student registrations"
|
||||||
msgstr "inscriptions d'élève"
|
msgstr "inscriptions d'élève"
|
||||||
|
|
||||||
#: apps/registration/models.py:75
|
#: apps/registration/models.py:107
|
||||||
msgid "professional activity"
|
msgid "professional activity"
|
||||||
msgstr "activité professionnelle"
|
msgstr "activité professionnelle"
|
||||||
|
|
||||||
#: apps/registration/models.py:83
|
#: apps/registration/models.py:115
|
||||||
msgid "coach registration"
|
msgid "coach registration"
|
||||||
msgstr "inscription d'encadrant"
|
msgstr "inscription d'encadrant"
|
||||||
|
|
||||||
#: apps/registration/models.py:84
|
#: apps/registration/models.py:116
|
||||||
msgid "coach registrations"
|
msgid "coach registrations"
|
||||||
msgstr "inscriptions d'encadrants"
|
msgstr "inscriptions d'encadrants"
|
||||||
|
|
||||||
#: apps/registration/models.py:89
|
#: apps/registration/models.py:121
|
||||||
msgid "role of the administrator"
|
msgid "role of the administrator"
|
||||||
msgstr "rôle de l'administrateur"
|
msgstr "rôle de l'administrateur"
|
||||||
|
|
||||||
#: apps/registration/models.py:94
|
#: apps/registration/models.py:126
|
||||||
msgid "admin"
|
msgid "admin"
|
||||||
msgstr "admin"
|
msgstr "admin"
|
||||||
|
|
||||||
#: apps/registration/models.py:97
|
#: apps/registration/models.py:129
|
||||||
msgid "admin registration"
|
msgid "admin registration"
|
||||||
msgstr "inscription d'administrateur"
|
msgstr "inscription d'administrateur"
|
||||||
|
|
||||||
#: apps/registration/models.py:98
|
#: apps/registration/models.py:130
|
||||||
msgid "admin registrations"
|
msgid "admin registrations"
|
||||||
msgstr "inscriptions d'administrateur"
|
msgstr "inscriptions d'administrateur"
|
||||||
|
|
||||||
@ -443,6 +452,8 @@ msgid ""
|
|||||||
"You recently registered on the Correspondances platform. Please click on the "
|
"You recently registered on the Correspondances platform. Please click on the "
|
||||||
"link below to confirm your registration."
|
"link below to confirm your registration."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Vous vous êtes inscrits sur la plateforme des Correspondances. Merci de "
|
||||||
|
"cliquer sur le lien ci-dessous pour confirmer votre inscription."
|
||||||
|
|
||||||
#: templates/registration/mails/email_validation_email.html:26
|
#: templates/registration/mails/email_validation_email.html:26
|
||||||
#: templates/registration/mails/email_validation_email.txt:9
|
#: templates/registration/mails/email_validation_email.txt:9
|
||||||
@ -450,6 +461,8 @@ msgid ""
|
|||||||
"This link is only valid for a couple of days, after that you will need to "
|
"This link is only valid for a couple of days, after that you will need to "
|
||||||
"contact us to validate your email."
|
"contact us to validate your email."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Ce lien n'est valide que pendant quelques jours, après cela vous devrez nous "
|
||||||
|
"contacter pour valider votre email."
|
||||||
|
|
||||||
#: templates/registration/mails/email_validation_email.html:30
|
#: templates/registration/mails/email_validation_email.html:30
|
||||||
#: templates/registration/mails/email_validation_email.txt:11
|
#: templates/registration/mails/email_validation_email.txt:11
|
||||||
@ -458,8 +471,8 @@ msgstr "Merci"
|
|||||||
|
|
||||||
#: templates/registration/mails/email_validation_email.html:35
|
#: templates/registration/mails/email_validation_email.html:35
|
||||||
#: templates/registration/mails/email_validation_email.txt:13
|
#: templates/registration/mails/email_validation_email.txt:13
|
||||||
msgid "The CNO."
|
msgid "The Correspondances team."
|
||||||
msgstr ""
|
msgstr "L'équipe des Correspondances"
|
||||||
|
|
||||||
#: templates/registration/password_change_done.html:8
|
#: templates/registration/password_change_done.html:8
|
||||||
msgid "Your password was changed."
|
msgid "Your password was changed."
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://{{ domain }}{% url 'member:email_validation' uidb64=uid token=token %}">
|
<a href="https://{{ domain }}{% url 'registration:email_validation' uidb64=uid token=token %}">
|
||||||
https://{{ domain }}{% url 'member:email_validation' uidb64=uid token=token %}
|
https://{{ domain }}{% url 'registration:email_validation' uidb64=uid token=token %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -32,5 +32,5 @@
|
|||||||
|
|
||||||
--
|
--
|
||||||
<p>
|
<p>
|
||||||
{% trans "The CNO." %}<br>
|
{% trans "The Correspondances team." %}<br>
|
||||||
</p>
|
</p>
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
{% trans "You recently registered on the Correspondances platform. Please click on the link below to confirm your registration." %}
|
{% trans "You recently registered on the Correspondances platform. Please click on the link below to confirm your registration." %}
|
||||||
|
|
||||||
https://{{ domain }}{% url 'member:email_validation' uidb64=uid token=token %}
|
https://{{ domain }}{% url 'registration:email_validation' uidb64=uid token=token %}
|
||||||
|
|
||||||
{% trans "This link is only valid for a couple of days, after that you will need to contact us to validate your email." %}
|
{% trans "This link is only valid for a couple of days, after that you will need to contact us to validate your email." %}
|
||||||
|
|
||||||
{% trans "Thanks" %},
|
{% trans "Thanks" %},
|
||||||
|
|
||||||
{% trans "The CNO." %}
|
{% trans "The Correspondances team." %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user