-
+
{% for error in register_form.email.errors %}
{{ error | escape }}
{% endfor %}
diff --git a/bookwyrm/templatetags/bookwyrm_tags.py b/bookwyrm/templatetags/bookwyrm_tags.py
index 5cba5455f..4811f4fd5 100644
--- a/bookwyrm/templatetags/bookwyrm_tags.py
+++ b/bookwyrm/templatetags/bookwyrm_tags.py
@@ -12,7 +12,7 @@ register = template.Library()
def get_rating(book, user):
"""get the overall rating of a book"""
queryset = views.helpers.privacy_filter(
- user, models.Review.objects.filter(book=book)
+ user, models.Review.objects.filter(book__in=book.parent_work.editions.all())
)
return queryset.aggregate(Avg("rating"))["rating__avg"]
diff --git a/bookwyrm/tests/test_templatetags.py b/bookwyrm/tests/test_templatetags.py
index 3c5d8b258..d75d368c1 100644
--- a/bookwyrm/tests/test_templatetags.py
+++ b/bookwyrm/tests/test_templatetags.py
@@ -175,3 +175,10 @@ class TemplateTags(TestCase):
result = bookwyrm_tags.related_status(notification)
self.assertIsInstance(result, models.Status)
+
+ def test_get_next_shelf(self, *_):
+ """self progress helper"""
+ self.assertEqual(bookwyrm_tags.get_next_shelf("to-read"), "reading")
+ self.assertEqual(bookwyrm_tags.get_next_shelf("reading"), "read")
+ self.assertEqual(bookwyrm_tags.get_next_shelf("read"), "read")
+ self.assertEqual(bookwyrm_tags.get_next_shelf("blooooga"), "to-read")
diff --git a/bookwyrm/tests/views/test_authentication.py b/bookwyrm/tests/views/test_authentication.py
index 10531f517..22008e100 100644
--- a/bookwyrm/tests/views/test_authentication.py
+++ b/bookwyrm/tests/views/test_authentication.py
@@ -8,7 +8,7 @@ from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.client import RequestFactory
-from bookwyrm import models, views
+from bookwyrm import forms, models, views
from bookwyrm.settings import DOMAIN
@@ -22,7 +22,7 @@ class AuthenticationViews(TestCase):
self.factory = RequestFactory()
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"):
self.local_user = models.User.objects.create_user(
- "mouse@local.com",
+ "mouse@your.domain.here",
"mouse@mouse.com",
"password",
local=True,
@@ -31,7 +31,9 @@ class AuthenticationViews(TestCase):
self.anonymous_user = AnonymousUser
self.anonymous_user.is_authenticated = False
- self.settings = models.SiteSettings.objects.create(id=1)
+ self.settings = models.SiteSettings.objects.create(
+ id=1, require_confirm_email=False
+ )
def test_login_get(self, _):
"""there are so many views, this just makes sure it LOADS"""
@@ -49,6 +51,66 @@ class AuthenticationViews(TestCase):
self.assertEqual(result.url, "/")
self.assertEqual(result.status_code, 302)
+ def test_login_post_localname(self, _):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.Login.as_view()
+ form = forms.LoginForm()
+ form.data["localname"] = "mouse@mouse.com"
+ form.data["password"] = "password"
+ request = self.factory.post("", form.data)
+ request.user = self.anonymous_user
+
+ with patch("bookwyrm.views.authentication.login"):
+ result = view(request)
+ self.assertEqual(result.url, "/")
+ self.assertEqual(result.status_code, 302)
+
+ def test_login_post_username(self, _):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.Login.as_view()
+ form = forms.LoginForm()
+ form.data["localname"] = "mouse@your.domain.here"
+ form.data["password"] = "password"
+ request = self.factory.post("", form.data)
+ request.user = self.anonymous_user
+
+ with patch("bookwyrm.views.authentication.login"):
+ result = view(request)
+ self.assertEqual(result.url, "/")
+ self.assertEqual(result.status_code, 302)
+
+ def test_login_post_email(self, _):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.Login.as_view()
+ form = forms.LoginForm()
+ form.data["localname"] = "mouse"
+ form.data["password"] = "password"
+ request = self.factory.post("", form.data)
+ request.user = self.anonymous_user
+
+ with patch("bookwyrm.views.authentication.login"):
+ result = view(request)
+ self.assertEqual(result.url, "/")
+ self.assertEqual(result.status_code, 302)
+
+ def test_login_post_invalid_credentials(self, _):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.Login.as_view()
+ form = forms.LoginForm()
+ form.data["localname"] = "mouse"
+ form.data["password"] = "passsword1"
+ request = self.factory.post("", form.data)
+ request.user = self.anonymous_user
+
+ with patch("bookwyrm.views.authentication.login"):
+ result = view(request)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+ self.assertEqual(
+ result.context_data["login_form"].non_field_errors,
+ "Username or password are incorrect",
+ )
+
def test_register(self, _):
"""create a user"""
view = views.Register.as_view()
@@ -70,6 +132,33 @@ class AuthenticationViews(TestCase):
self.assertEqual(nutria.localname, "nutria-user.user_nutria")
self.assertEqual(nutria.local, True)
+ @patch("bookwyrm.emailing.send_email.delay")
+ def test_register_email_confirm(self, *_):
+ """create a user"""
+ self.settings.require_confirm_email = True
+ self.settings.save()
+
+ view = views.Register.as_view()
+ self.assertEqual(models.User.objects.count(), 1)
+ request = self.factory.post(
+ "register/",
+ {
+ "localname": "nutria",
+ "password": "mouseword",
+ "email": "aa@bb.cccc",
+ },
+ )
+ with patch("bookwyrm.views.authentication.login"):
+ response = view(request)
+ self.assertEqual(response.status_code, 302)
+ nutria = models.User.objects.get(localname="nutria")
+ self.assertEqual(nutria.username, "nutria@%s" % DOMAIN)
+ self.assertEqual(nutria.local, True)
+
+ self.assertFalse(nutria.is_active)
+ self.assertEqual(nutria.deactivation_reason, "pending")
+ self.assertIsNotNone(nutria.confirmation_code)
+
def test_register_trailing_space(self, _):
"""django handles this so weirdly"""
view = views.Register.as_view()
@@ -189,3 +278,74 @@ class AuthenticationViews(TestCase):
with self.assertRaises(Http404):
response = view(request)
self.assertEqual(models.User.objects.count(), 2)
+
+ def test_confirm_email_code_get(self, _):
+ """there are so many views, this just makes sure it LOADS"""
+ self.settings.require_confirm_email = True
+ self.settings.save()
+
+ self.local_user.is_active = False
+ self.local_user.deactivation_reason = "pending"
+ self.local_user.confirmation_code = "12345"
+ self.local_user.save(
+ broadcast=False,
+ update_fields=["is_active", "deactivation_reason", "confirmation_code"],
+ )
+ view = views.ConfirmEmailCode.as_view()
+ request = self.factory.get("")
+ request.user = self.anonymous_user
+
+ result = view(request, "12345")
+ self.assertEqual(result.url, "/login/confirmed")
+ self.assertEqual(result.status_code, 302)
+
+ self.local_user.refresh_from_db()
+ self.assertTrue(self.local_user.is_active)
+ self.assertIsNone(self.local_user.deactivation_reason)
+
+ request.user = self.local_user
+ result = view(request, "12345")
+ self.assertEqual(result.url, "/")
+ self.assertEqual(result.status_code, 302)
+
+ def test_confirm_email_code_get_invalid_code(self, _):
+ """there are so many views, this just makes sure it LOADS"""
+ self.settings.require_confirm_email = True
+ self.settings.save()
+
+ self.local_user.is_active = False
+ self.local_user.deactivation_reason = "pending"
+ self.local_user.confirmation_code = "12345"
+ self.local_user.save(
+ broadcast=False,
+ update_fields=["is_active", "deactivation_reason", "confirmation_code"],
+ )
+ view = views.ConfirmEmailCode.as_view()
+ request = self.factory.get("")
+ request.user = self.anonymous_user
+
+ result = view(request, "abcde")
+ self.assertIsInstance(result, TemplateResponse)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+ self.assertFalse(self.local_user.is_active)
+ self.assertEqual(self.local_user.deactivation_reason, "pending")
+
+ def test_confirm_email_get(self, _):
+ """there are so many views, this just makes sure it LOADS"""
+ self.settings.require_confirm_email = True
+ self.settings.save()
+
+ login = views.ConfirmEmail.as_view()
+ request = self.factory.get("")
+ request.user = self.anonymous_user
+
+ result = login(request)
+ self.assertIsInstance(result, TemplateResponse)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+
+ request.user = self.local_user
+ result = login(request)
+ self.assertEqual(result.url, "/")
+ self.assertEqual(result.status_code, 302)
diff --git a/bookwyrm/tests/views/test_book.py b/bookwyrm/tests/views/test_book.py
index 3b6748523..c5d86a12d 100644
--- a/bookwyrm/tests/views/test_book.py
+++ b/bookwyrm/tests/views/test_book.py
@@ -12,6 +12,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile
from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.client import RequestFactory
+from django.utils import timezone
from bookwyrm import forms, models, views
from bookwyrm.activitypub import ActivitypubResponse
@@ -52,6 +53,11 @@ class BookViews(TestCase):
def test_book_page(self):
"""there are so many views, this just makes sure it LOADS"""
view = views.Book.as_view()
+ models.ReadThrough.objects.create(
+ user=self.local_user,
+ book=self.book,
+ start_date=timezone.now(),
+ )
request = self.factory.get("")
request.user = self.local_user
with patch("bookwyrm.views.books.is_api_request") as is_api:
@@ -67,6 +73,79 @@ class BookViews(TestCase):
self.assertIsInstance(result, ActivitypubResponse)
self.assertEqual(result.status_code, 200)
+ @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay")
+ @patch("bookwyrm.activitystreams.ActivityStream.add_status")
+ def test_book_page_statuses(self, *_):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.Book.as_view()
+
+ review = models.Review.objects.create(
+ user=self.local_user,
+ book=self.book,
+ content="hi",
+ )
+
+ comment = models.Comment.objects.create(
+ user=self.local_user,
+ book=self.book,
+ content="hi",
+ )
+
+ quote = models.Quotation.objects.create(
+ user=self.local_user,
+ book=self.book,
+ content="hi",
+ quote="wow",
+ )
+
+ request = self.factory.get("")
+ request.user = self.local_user
+ with patch("bookwyrm.views.books.is_api_request") as is_api:
+ is_api.return_value = False
+ result = view(request, self.book.id, user_statuses="review")
+ self.assertIsInstance(result, TemplateResponse)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+ self.assertEqual(result.context_data["statuses"].object_list[0], review)
+
+ with patch("bookwyrm.views.books.is_api_request") as is_api:
+ is_api.return_value = False
+ result = view(request, self.book.id, user_statuses="comment")
+ self.assertIsInstance(result, TemplateResponse)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+ self.assertEqual(result.context_data["statuses"].object_list[0], comment)
+
+ with patch("bookwyrm.views.books.is_api_request") as is_api:
+ is_api.return_value = False
+ result = view(request, self.book.id, user_statuses="quotation")
+ self.assertIsInstance(result, TemplateResponse)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+ self.assertEqual(result.context_data["statuses"].object_list[0], quote)
+
+ def test_book_page_invalid_id(self):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.Book.as_view()
+ request = self.factory.get("")
+ request.user = self.local_user
+ with patch("bookwyrm.views.books.is_api_request") as is_api:
+ is_api.return_value = False
+ result = view(request, 0)
+ self.assertEqual(result.status_code, 404)
+
+ def test_book_page_work_id(self):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.Book.as_view()
+ request = self.factory.get("")
+ request.user = self.local_user
+ with patch("bookwyrm.views.books.is_api_request") as is_api:
+ is_api.return_value = False
+ result = view(request, self.work.id)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+ self.assertEqual(result.context_data["book"], self.book)
+
def test_edit_book_page(self):
"""there are so many views, this just makes sure it LOADS"""
view = views.EditBook.as_view()
diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/test_import.py
index 13c0ef5d2..d9d67d568 100644
--- a/bookwyrm/tests/views/test_import.py
+++ b/bookwyrm/tests/views/test_import.py
@@ -1,11 +1,12 @@
""" test for app action functionality """
+import pathlib
from unittest.mock import patch
+from django.core.files.uploadedfile import SimpleUploadedFile
from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.client import RequestFactory
-from bookwyrm import models
-from bookwyrm import views
+from bookwyrm import forms, models, views
class ImportViews(TestCase):
@@ -47,6 +48,27 @@ class ImportViews(TestCase):
result.render()
self.assertEqual(result.status_code, 200)
+ def test_start_import(self):
+ """retry failed items"""
+ view = views.Import.as_view()
+ form = forms.ImportForm()
+ form.data["source"] = "LibraryThing"
+ form.data["privacy"] = "public"
+ form.data["include_reviews"] = False
+ csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv")
+ form.data["csv_file"] = SimpleUploadedFile(
+ csv_file, open(csv_file, "rb").read(), content_type="text/csv"
+ )
+
+ request = self.factory.post("", form.data)
+ request.user = self.local_user
+
+ with patch("bookwyrm.importers.Importer.start_import"):
+ view(request)
+ job = models.ImportJob.objects.get()
+ self.assertFalse(job.include_reviews)
+ self.assertEqual(job.privacy, "public")
+
def test_retry_import(self):
"""retry failed items"""
view = views.ImportStatus.as_view()
diff --git a/bookwyrm/tests/views/test_invite.py b/bookwyrm/tests/views/test_invite.py
index 1eaf57c03..6ad464208 100644
--- a/bookwyrm/tests/views/test_invite.py
+++ b/bookwyrm/tests/views/test_invite.py
@@ -52,6 +52,26 @@ class InviteViews(TestCase):
result.render()
self.assertEqual(result.status_code, 200)
+ def test_manage_invites_post(self):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.ManageInvites.as_view()
+ form = forms.CreateInviteForm()
+ form.data["use_limit"] = 3
+ form.data["expiry"] = ""
+ request = self.factory.post("", form.data)
+ request.user = self.local_user
+ request.user.is_superuser = True
+
+ result = view(request)
+
+ self.assertIsInstance(result, TemplateResponse)
+ result.render()
+ self.assertEqual(result.status_code, 200)
+
+ invite = models.SiteInvite.objects.get()
+ self.assertEqual(invite.use_limit, 3)
+ self.assertIsNone(invite.expiry)
+
def test_invite_request(self):
"""request to join a server"""
form = forms.InviteRequestForm()
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py
index d3e2dad1a..eb8491a94 100644
--- a/bookwyrm/urls.py
+++ b/bookwyrm/urls.py
@@ -46,7 +46,15 @@ urlpatterns = [
re_path("^api/updates/stream/(?P
[a-z]+)/?$", views.get_unread_status_count),
# authentication
re_path(r"^login/?$", views.Login.as_view(), name="login"),
+ re_path(r"^login/(?Pconfirmed)?$", views.Login.as_view(), name="login"),
re_path(r"^register/?$", views.Register.as_view()),
+ re_path(r"confirm-email/?$", views.ConfirmEmail.as_view(), name="confirm-email"),
+ re_path(
+ r"confirm-email/(?P[A-Za-z0-9]+)/?$",
+ views.ConfirmEmailCode.as_view(),
+ name="confirm-email-code",
+ ),
+ re_path(r"resend-link", views.resend_link, name="resend-link"),
re_path(r"^logout/?$", views.Logout.as_view(), name="logout"),
re_path(
r"^password-reset/?$",
diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py
index 41bb64e54..eccb7f5e5 100644
--- a/bookwyrm/views/__init__.py
+++ b/bookwyrm/views/__init__.py
@@ -1,6 +1,7 @@
""" make sure all our nice views are available """
from .announcements import Announcements, Announcement, delete_announcement
from .authentication import Login, Register, Logout
+from .authentication import ConfirmEmail, ConfirmEmailCode, resend_link
from .author import Author, EditAuthor
from .block import Block, unblock
from .books import Book, EditBook, ConfirmEditBook, Editions
diff --git a/bookwyrm/views/authentication.py b/bookwyrm/views/authentication.py
index 003e94b09..70f51864d 100644
--- a/bookwyrm/views/authentication.py
+++ b/bookwyrm/views/authentication.py
@@ -6,24 +6,27 @@ from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils import timezone
from django.utils.decorators import method_decorator
+from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.http import require_POST
from django.views import View
-from bookwyrm import forms, models
+from bookwyrm import emailing, forms, models
from bookwyrm.settings import DOMAIN
-# pylint: disable= no-self-use
+# pylint: disable=no-self-use
@method_decorator(csrf_exempt, name="dispatch")
class Login(View):
"""authenticate an existing user"""
- def get(self, request):
+ def get(self, request, confirmed=None):
"""login page"""
if request.user.is_authenticated:
return redirect("/")
- # sene user to the login page
+ # send user to the login page
data = {
+ "show_confirmed_email": confirmed,
"login_form": forms.LoginForm(),
"register_form": forms.RegisterForm(),
}
@@ -37,35 +40,55 @@ class Login(View):
localname = login_form.data["localname"]
if "@" in localname: # looks like an email address to me
- email = localname
try:
- username = models.User.objects.get(email=email)
+ username = models.User.objects.get(email=localname).username
except models.User.DoesNotExist: # maybe it's a full username?
username = localname
else:
username = "%s@%s" % (localname, DOMAIN)
password = login_form.data["password"]
+
+ # perform authentication
user = authenticate(request, username=username, password=password)
if user is not None:
# successful login
login(request, user)
user.last_active_date = timezone.now()
user.save(broadcast=False, update_fields=["last_active_date"])
+ if request.POST.get("first_login"):
+ return redirect("get-started-profile")
return redirect(request.GET.get("next", "/"))
+ # maybe the user is pending email confirmation
+ if models.User.objects.filter(
+ username=username, is_active=False, deactivation_reason="pending"
+ ).exists():
+ return redirect("confirm-email")
+
# login errors
- login_form.non_field_errors = "Username or password are incorrect"
+ login_form.non_field_errors = _("Username or password are incorrect")
register_form = forms.RegisterForm()
data = {"login_form": login_form, "register_form": register_form}
return TemplateResponse(request, "login.html", data)
+@method_decorator(login_required, name="dispatch")
+class Logout(View):
+ """log out"""
+
+ def get(self, request):
+ """done with this place! outa here!"""
+ logout(request)
+ return redirect("/")
+
+
class Register(View):
"""register a user"""
def post(self, request):
"""join the server"""
- if not models.SiteSettings.get().allow_registration:
+ settings = models.SiteSettings.get()
+ if not settings.allow_registration:
invite_code = request.POST.get("invite_code")
if not invite_code:
@@ -104,22 +127,76 @@ class Register(View):
username = "%s@%s" % (localname, DOMAIN)
user = models.User.objects.create_user(
- username, email, password, localname=localname, local=True
+ username,
+ email,
+ password,
+ localname=localname,
+ local=True,
+ deactivation_reason="pending" if settings.require_confirm_email else None,
+ is_active=not settings.require_confirm_email,
)
if invite:
invite.times_used += 1
invite.invitees.add(user)
invite.save()
+ if settings.require_confirm_email:
+ emailing.email_confirmation_email(user)
+ return redirect("confirm-email")
+
login(request, user)
return redirect("get-started-profile")
-@method_decorator(login_required, name="dispatch")
-class Logout(View):
- """log out"""
+class ConfirmEmailCode(View):
+ """confirm email address"""
- def get(self, request):
- """done with this place! outa here!"""
- logout(request)
- return redirect("/")
+ def get(self, request, code): # pylint: disable=unused-argument
+ """you got the code! good work"""
+ settings = models.SiteSettings.get()
+ if request.user.is_authenticated or not settings.require_confirm_email:
+ return redirect("/")
+
+ # look up the user associated with this code
+ try:
+ user = models.User.objects.get(confirmation_code=code)
+ except models.User.DoesNotExist:
+ return TemplateResponse(
+ request, "confirm_email/confirm_email.html", {"valid": False}
+ )
+ # update the user
+ user.is_active = True
+ user.deactivation_reason = None
+ user.save(broadcast=False, update_fields=["is_active", "deactivation_reason"])
+ # direct the user to log in
+ return redirect("login", confirmed="confirmed")
+
+
+class ConfirmEmail(View):
+ """enter code to confirm email address"""
+
+ def get(self, request): # pylint: disable=unused-argument
+ """you need a code! keep looking"""
+ settings = models.SiteSettings.get()
+ if request.user.is_authenticated or not settings.require_confirm_email:
+ return redirect("/")
+
+ return TemplateResponse(
+ request, "confirm_email/confirm_email.html", {"valid": True}
+ )
+
+ def post(self, request):
+ """same as clicking the link"""
+ code = request.POST.get("code")
+ return ConfirmEmailCode().get(request, code)
+
+
+@require_POST
+def resend_link(request):
+ """resend confirmation link"""
+ email = request.POST.get("email")
+ user = get_object_or_404(models.User, email=email)
+ emailing.email_confirmation_email(user)
+ return TemplateResponse(
+ request, "confirm_email/confirm_email.html", {"valid": True}
+ )
diff --git a/bookwyrm/views/books.py b/bookwyrm/views/books.py
index d56e2f22c..6cd0427c1 100644
--- a/bookwyrm/views/books.py
+++ b/bookwyrm/views/books.py
@@ -65,6 +65,13 @@ class Book(View):
queryset = queryset.select_related("user")
paginated = Paginator(queryset, PAGE_LENGTH)
+ lists = privacy_filter(
+ request.user,
+ models.List.objects.filter(
+ listitem__approved=True,
+ listitem__book__in=book.parent_work.editions.all(),
+ ),
+ )
data = {
"book": book,
"statuses": paginated.get_page(request.GET.get("page")),
@@ -75,9 +82,7 @@ class Book(View):
if not user_statuses
else None,
"rating": reviews.aggregate(Avg("rating"))["rating__avg"],
- "lists": privacy_filter(
- request.user, book.list_set.filter(listitem__approved=True)
- ),
+ "lists": lists,
}
if request.user.is_authenticated:
diff --git a/bookwyrm/views/site.py b/bookwyrm/views/site.py
index 46bdf7226..42e8a6dd5 100644
--- a/bookwyrm/views/site.py
+++ b/bookwyrm/views/site.py
@@ -46,4 +46,6 @@ def email_preview(request):
data["text_content_path"] = "email/{}/text_content.html".format(template)
data["reset_link"] = "https://example.com/link"
data["invite_link"] = "https://example.com/link"
+ data["confirmation_link"] = "https://example.com/link"
+ data["confirmation_code"] = "AKJHKDGKJSDFG"
return TemplateResponse(request, "email/preview.html", data)
diff --git a/locale/de_DE/LC_MESSAGES/django.po b/locale/de_DE/LC_MESSAGES/django.po
index b047f0310..4906082a5 100644
--- a/locale/de_DE/LC_MESSAGES/django.po
+++ b/locale/de_DE/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-05 01:33+0000\n"
+"POT-Creation-Date: 2021-08-07 01:35+0000\n"
"PO-Revision-Date: 2021-03-02 17:19-0800\n"
"Last-Translator: Mouse Reeve \n"
"Language-Team: English \n"
@@ -306,7 +306,7 @@ msgstr ""
#: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98
-#: bookwyrm/templates/settings/site.html:101
+#: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@@ -739,6 +739,58 @@ msgstr "Schließen"
msgid "Compose status"
msgstr "Status teilen"
+#: bookwyrm/templates/confirm_email/confirm_email.html:4
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm email"
+msgstr "Bestätigen"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:7
+#, fuzzy
+#| msgid "Email address:"
+msgid "Confirm your email address"
+msgstr "E-Mail Adresse"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:13
+msgid "A confirmation code has been sent to the email address you used to register your account."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:15
+msgid "Sorry! We couldn't find that code."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:19
+#, fuzzy
+#| msgid "Confirm password:"
+msgid "Confirmation code:"
+msgstr "Passwort bestätigen:"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:25
+#: bookwyrm/templates/discover/landing_layout.html:70
+#: bookwyrm/templates/moderation/report_modal.html:33
+msgid "Submit"
+msgstr "Absenden"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:32
+msgid "Can't find your code?"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:4
+msgid "Resend confirmation link"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:11
+#: bookwyrm/templates/discover/landing_layout.html:64
+#: bookwyrm/templates/password_reset_request.html:18
+#: bookwyrm/templates/preferences/edit_user.html:38
+#: bookwyrm/templates/snippets/register_form.html:13
+msgid "Email address:"
+msgstr "E-Mail Adresse"
+
+#: bookwyrm/templates/confirm_email/resend_form.html:17
+msgid "Resend link"
+msgstr ""
+
#: bookwyrm/templates/directory/community_filter.html:5
#, fuzzy
#| msgid "Comment"
@@ -882,7 +934,7 @@ msgid "Join %(name)s"
msgstr "Tritt %(name)s bei"
#: bookwyrm/templates/discover/landing_layout.html:51
-#: bookwyrm/templates/login.html:51
+#: bookwyrm/templates/login.html:56
msgid "This instance is closed"
msgstr "Diese Instanz ist geschlossen"
@@ -894,22 +946,26 @@ msgstr ""
msgid "Request an Invitation"
msgstr ""
-#: bookwyrm/templates/discover/landing_layout.html:64
-#: bookwyrm/templates/password_reset_request.html:18
-#: bookwyrm/templates/preferences/edit_user.html:38
-#: bookwyrm/templates/snippets/register_form.html:13
-msgid "Email address:"
-msgstr "E-Mail Adresse"
-
-#: bookwyrm/templates/discover/landing_layout.html:70
-#: bookwyrm/templates/moderation/report_modal.html:33
-msgid "Submit"
-msgstr "Absenden"
-
#: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account"
msgstr "Dein Account"
+#: bookwyrm/templates/email/confirm/html_content.html:6
+#: bookwyrm/templates/email/confirm/text_content.html:4
+#, python-format
+msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
+msgstr ""
+
+#: bookwyrm/templates/email/confirm/html_content.html:11
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm Email"
+msgstr "Bestätigen"
+
+#: bookwyrm/templates/email/confirm/subject.html:2
+msgid "Please confirm your email"
+msgstr ""
+
#: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there,"
@@ -1342,7 +1398,7 @@ msgid "Imported"
msgstr "Importiert"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
-#: bookwyrm/templates/login.html:46
+#: bookwyrm/templates/login.html:51
msgid "Create an Account"
msgstr "Erstelle einen Account"
@@ -1412,7 +1468,7 @@ msgid "Notifications"
msgstr "Benachrichtigungen"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
-#: bookwyrm/templates/login.html:17
+#: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:"
msgstr ""
@@ -1421,12 +1477,12 @@ msgstr ""
msgid "password"
msgstr "Passwort"
-#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36
+#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?"
msgstr "Passwort vergessen?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
-#: bookwyrm/templates/login.html:33
+#: bookwyrm/templates/login.html:38
msgid "Log in"
msgstr "Anmelden"
@@ -1619,16 +1675,20 @@ msgstr "Deine Listen"
msgid "Login"
msgstr ""
-#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17
+#: bookwyrm/templates/login.html:16
+msgid "Success! Email address confirmed."
+msgstr ""
+
+#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:"
msgstr "Passwort:"
-#: bookwyrm/templates/login.html:52
+#: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite"
msgstr "Kontaktiere für eine Einladung eine*n Admin"
-#: bookwyrm/templates/login.html:63
+#: bookwyrm/templates/login.html:68
msgid "More about this site"
msgstr "Mehr über diese Seite"
@@ -2554,7 +2614,15 @@ msgstr "Registrierungen erlauben"
msgid "Allow invite requests"
msgstr "Folgeanfragen"
-#: bookwyrm/templates/settings/site.html:95
+#: bookwyrm/templates/settings/site.html:97
+msgid "Require users to confirm email address"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:99
+msgid "(Recommended if registration is open)"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:"
msgstr "Registrierungen geschlossen text"
@@ -3295,6 +3363,10 @@ msgstr ""
msgid "%(title)s: %(subtitle)s"
msgstr ""
+#: bookwyrm/views/authentication.py:69
+msgid "Username or password are incorrect"
+msgstr ""
+
#: bookwyrm/views/import_data.py:67
#, fuzzy
#| msgid "Email address:"
@@ -3371,11 +3443,6 @@ msgstr ""
#~ msgid "Enter a valid integer."
#~ msgstr "E-Mail Adresse"
-#, fuzzy
-#~| msgid "Email address:"
-#~ msgid "Enter a valid email address."
-#~ msgstr "E-Mail Adresse"
-
#, fuzzy
#~| msgid "Email address:"
#~ msgid "Enter a valid IPv4 address."
diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po
index 153d8b9a1..e8e3b0b31 100644
--- a/locale/en_US/LC_MESSAGES/django.po
+++ b/locale/en_US/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-05 01:33+0000\n"
+"POT-Creation-Date: 2021-08-07 01:35+0000\n"
"PO-Revision-Date: 2021-02-28 17:19-0800\n"
"Last-Translator: Mouse Reeve \n"
"Language-Team: English \n"
@@ -282,7 +282,7 @@ msgstr ""
#: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98
-#: bookwyrm/templates/settings/site.html:101
+#: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@@ -680,6 +680,52 @@ msgstr ""
msgid "Compose status"
msgstr ""
+#: bookwyrm/templates/confirm_email/confirm_email.html:4
+msgid "Confirm email"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:7
+msgid "Confirm your email address"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:13
+msgid "A confirmation code has been sent to the email address you used to register your account."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:15
+msgid "Sorry! We couldn't find that code."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:19
+msgid "Confirmation code:"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:25
+#: bookwyrm/templates/discover/landing_layout.html:70
+#: bookwyrm/templates/moderation/report_modal.html:33
+msgid "Submit"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:32
+msgid "Can't find your code?"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:4
+msgid "Resend confirmation link"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:11
+#: bookwyrm/templates/discover/landing_layout.html:64
+#: bookwyrm/templates/password_reset_request.html:18
+#: bookwyrm/templates/preferences/edit_user.html:38
+#: bookwyrm/templates/snippets/register_form.html:13
+msgid "Email address:"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:17
+msgid "Resend link"
+msgstr ""
+
#: bookwyrm/templates/directory/community_filter.html:5
msgid "Community"
msgstr ""
@@ -806,7 +852,7 @@ msgid "Join %(name)s"
msgstr ""
#: bookwyrm/templates/discover/landing_layout.html:51
-#: bookwyrm/templates/login.html:51
+#: bookwyrm/templates/login.html:56
msgid "This instance is closed"
msgstr ""
@@ -818,22 +864,24 @@ msgstr ""
msgid "Request an Invitation"
msgstr ""
-#: bookwyrm/templates/discover/landing_layout.html:64
-#: bookwyrm/templates/password_reset_request.html:18
-#: bookwyrm/templates/preferences/edit_user.html:38
-#: bookwyrm/templates/snippets/register_form.html:13
-msgid "Email address:"
-msgstr ""
-
-#: bookwyrm/templates/discover/landing_layout.html:70
-#: bookwyrm/templates/moderation/report_modal.html:33
-msgid "Submit"
-msgstr ""
-
#: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account"
msgstr ""
+#: bookwyrm/templates/email/confirm/html_content.html:6
+#: bookwyrm/templates/email/confirm/text_content.html:4
+#, python-format
+msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
+msgstr ""
+
+#: bookwyrm/templates/email/confirm/html_content.html:11
+msgid "Confirm Email"
+msgstr ""
+
+#: bookwyrm/templates/email/confirm/subject.html:2
+msgid "Please confirm your email"
+msgstr ""
+
#: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there,"
@@ -1235,7 +1283,7 @@ msgid "Imported"
msgstr ""
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
-#: bookwyrm/templates/login.html:46
+#: bookwyrm/templates/login.html:51
msgid "Create an Account"
msgstr ""
@@ -1303,7 +1351,7 @@ msgid "Notifications"
msgstr ""
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
-#: bookwyrm/templates/login.html:17
+#: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:"
msgstr ""
@@ -1312,12 +1360,12 @@ msgstr ""
msgid "password"
msgstr ""
-#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36
+#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?"
msgstr ""
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
-#: bookwyrm/templates/login.html:33
+#: bookwyrm/templates/login.html:38
msgid "Log in"
msgstr ""
@@ -1493,16 +1541,20 @@ msgstr ""
msgid "Login"
msgstr ""
-#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17
+#: bookwyrm/templates/login.html:16
+msgid "Success! Email address confirmed."
+msgstr ""
+
+#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:"
msgstr ""
-#: bookwyrm/templates/login.html:52
+#: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite"
msgstr ""
-#: bookwyrm/templates/login.html:63
+#: bookwyrm/templates/login.html:68
msgid "More about this site"
msgstr ""
@@ -2315,7 +2367,15 @@ msgstr ""
msgid "Allow invite requests"
msgstr ""
-#: bookwyrm/templates/settings/site.html:95
+#: bookwyrm/templates/settings/site.html:97
+msgid "Require users to confirm email address"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:99
+msgid "(Recommended if registration is open)"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:"
msgstr ""
@@ -2991,6 +3051,10 @@ msgstr ""
msgid "%(title)s: %(subtitle)s"
msgstr ""
+#: bookwyrm/views/authentication.py:69
+msgid "Username or password are incorrect"
+msgstr ""
+
#: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file"
msgstr ""
diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po
index 5bae4d7e2..9fc28535e 100644
--- a/locale/es/LC_MESSAGES/django.po
+++ b/locale/es/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-05 01:33+0000\n"
+"POT-Creation-Date: 2021-08-07 01:35+0000\n"
"PO-Revision-Date: 2021-03-19 11:49+0800\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -288,7 +288,7 @@ msgstr "Clave Goodreads:"
#: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98
-#: bookwyrm/templates/settings/site.html:101
+#: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@@ -688,6 +688,60 @@ msgstr "Cerrar"
msgid "Compose status"
msgstr "Componer status"
+#: bookwyrm/templates/confirm_email/confirm_email.html:4
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm email"
+msgstr "Confirmar"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:7
+#, fuzzy
+#| msgid "Enter a valid email address."
+msgid "Confirm your email address"
+msgstr "Ingrese una dirección de correo electrónico válida."
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:13
+msgid "A confirmation code has been sent to the email address you used to register your account."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:15
+msgid "Sorry! We couldn't find that code."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:19
+#, fuzzy
+#| msgid "Confirm password:"
+msgid "Confirmation code:"
+msgstr "Confirmar contraseña:"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:25
+#: bookwyrm/templates/discover/landing_layout.html:70
+#: bookwyrm/templates/moderation/report_modal.html:33
+msgid "Submit"
+msgstr "Enviar"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:32
+msgid "Can't find your code?"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:4
+msgid "Resend confirmation link"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:11
+#: bookwyrm/templates/discover/landing_layout.html:64
+#: bookwyrm/templates/password_reset_request.html:18
+#: bookwyrm/templates/preferences/edit_user.html:38
+#: bookwyrm/templates/snippets/register_form.html:13
+msgid "Email address:"
+msgstr "Dirección de correo electrónico:"
+
+#: bookwyrm/templates/confirm_email/resend_form.html:17
+#, fuzzy
+#| msgid "Re-send invite"
+msgid "Resend link"
+msgstr "Re-enviar invitación"
+
#: bookwyrm/templates/directory/community_filter.html:5
msgid "Community"
msgstr "Comunidad"
@@ -816,7 +870,7 @@ msgid "Join %(name)s"
msgstr "Unirse con %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51
-#: bookwyrm/templates/login.html:51
+#: bookwyrm/templates/login.html:56
msgid "This instance is closed"
msgstr "Esta instancia está cerrada."
@@ -828,22 +882,26 @@ msgstr "¡Gracias! Tu solicitud ha sido recibido."
msgid "Request an Invitation"
msgstr "Solicitar una invitación"
-#: bookwyrm/templates/discover/landing_layout.html:64
-#: bookwyrm/templates/password_reset_request.html:18
-#: bookwyrm/templates/preferences/edit_user.html:38
-#: bookwyrm/templates/snippets/register_form.html:13
-msgid "Email address:"
-msgstr "Dirección de correo electrónico:"
-
-#: bookwyrm/templates/discover/landing_layout.html:70
-#: bookwyrm/templates/moderation/report_modal.html:33
-msgid "Submit"
-msgstr "Enviar"
-
#: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account"
msgstr "Tu cuenta"
+#: bookwyrm/templates/email/confirm/html_content.html:6
+#: bookwyrm/templates/email/confirm/text_content.html:4
+#, python-format
+msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
+msgstr ""
+
+#: bookwyrm/templates/email/confirm/html_content.html:11
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm Email"
+msgstr "Confirmar"
+
+#: bookwyrm/templates/email/confirm/subject.html:2
+msgid "Please confirm your email"
+msgstr ""
+
#: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there,"
@@ -1250,7 +1308,7 @@ msgid "Imported"
msgstr "Importado"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
-#: bookwyrm/templates/login.html:46
+#: bookwyrm/templates/login.html:51
msgid "Create an Account"
msgstr "Crear una cuenta"
@@ -1318,7 +1376,7 @@ msgid "Notifications"
msgstr "Notificaciones"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
-#: bookwyrm/templates/login.html:17
+#: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:"
msgstr "Nombre de usuario:"
@@ -1327,12 +1385,12 @@ msgstr "Nombre de usuario:"
msgid "password"
msgstr "contraseña"
-#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36
+#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?"
msgstr "¿Olvidaste tu contraseña?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
-#: bookwyrm/templates/login.html:33
+#: bookwyrm/templates/login.html:38
msgid "Log in"
msgstr "Iniciar sesión"
@@ -1510,16 +1568,20 @@ msgstr "Tus listas"
msgid "Login"
msgstr "Iniciar sesión"
-#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17
+#: bookwyrm/templates/login.html:16
+msgid "Success! Email address confirmed."
+msgstr ""
+
+#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:"
msgstr "Contraseña:"
-#: bookwyrm/templates/login.html:52
+#: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite"
msgstr "Contactar a unx administradorx para recibir una invitación"
-#: bookwyrm/templates/login.html:63
+#: bookwyrm/templates/login.html:68
msgid "More about this site"
msgstr "Más sobre este sitio"
@@ -2351,7 +2413,15 @@ msgstr "Permitir registración:"
msgid "Allow invite requests"
msgstr "Permitir solicitudes de invitación:"
-#: bookwyrm/templates/settings/site.html:95
+#: bookwyrm/templates/settings/site.html:97
+msgid "Require users to confirm email address"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:99
+msgid "(Recommended if registration is open)"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:"
msgstr "Texto de registración cerrada:"
@@ -3036,6 +3106,10 @@ msgstr ""
msgid "%(title)s: %(subtitle)s"
msgstr ""
+#: bookwyrm/views/authentication.py:69
+msgid "Username or password are incorrect"
+msgstr ""
+
#: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file"
msgstr "No un archivo csv válido"
@@ -3113,9 +3187,6 @@ msgstr "Un enlace para reestablecer tu contraseña se enviará a %s"
#~ msgid "Enter a valid integer."
#~ msgstr "Ingrese un entero válido."
-#~ msgid "Enter a valid email address."
-#~ msgstr "Ingrese una dirección de correo electrónico válida."
-
#~ msgid "Enter a valid “slug” consisting of letters, numbers, underscores or hyphens."
#~ msgstr "Ingrese un “slug” válido que consiste de letras, numeros, guiones bajos, o guiones"
diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po
index 399e40563..f0a559f97 100644
--- a/locale/fr_FR/LC_MESSAGES/django.po
+++ b/locale/fr_FR/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-05 01:33+0000\n"
+"POT-Creation-Date: 2021-08-07 01:35+0000\n"
"PO-Revision-Date: 2021-04-05 12:44+0100\n"
"Last-Translator: Fabien Basmaison \n"
"Language-Team: Mouse Reeve \n"
@@ -286,7 +286,7 @@ msgstr "Clé Goodreads :"
#: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98
-#: bookwyrm/templates/settings/site.html:101
+#: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@@ -684,6 +684,60 @@ msgstr "Fermer"
msgid "Compose status"
msgstr "Rédiger un statut"
+#: bookwyrm/templates/confirm_email/confirm_email.html:4
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm email"
+msgstr "Confirmer"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:7
+#, fuzzy
+#| msgid "Email address:"
+msgid "Confirm your email address"
+msgstr "Adresse email :"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:13
+msgid "A confirmation code has been sent to the email address you used to register your account."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:15
+msgid "Sorry! We couldn't find that code."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:19
+#, fuzzy
+#| msgid "Confirm password:"
+msgid "Confirmation code:"
+msgstr "Confirmez le mot de passe :"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:25
+#: bookwyrm/templates/discover/landing_layout.html:70
+#: bookwyrm/templates/moderation/report_modal.html:33
+msgid "Submit"
+msgstr "Valider"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:32
+msgid "Can't find your code?"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:4
+msgid "Resend confirmation link"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:11
+#: bookwyrm/templates/discover/landing_layout.html:64
+#: bookwyrm/templates/password_reset_request.html:18
+#: bookwyrm/templates/preferences/edit_user.html:38
+#: bookwyrm/templates/snippets/register_form.html:13
+msgid "Email address:"
+msgstr "Adresse email :"
+
+#: bookwyrm/templates/confirm_email/resend_form.html:17
+#, fuzzy
+#| msgid "Re-send invite"
+msgid "Resend link"
+msgstr "Envoyer l’invitation de nouveau"
+
#: bookwyrm/templates/directory/community_filter.html:5
msgid "Community"
msgstr "Communauté"
@@ -812,7 +866,7 @@ msgid "Join %(name)s"
msgstr "Rejoignez %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51
-#: bookwyrm/templates/login.html:51
+#: bookwyrm/templates/login.html:56
msgid "This instance is closed"
msgstr "Cette instance est fermée"
@@ -824,22 +878,26 @@ msgstr "Merci ! Votre demande a bien été reçue."
msgid "Request an Invitation"
msgstr "Demander une invitation"
-#: bookwyrm/templates/discover/landing_layout.html:64
-#: bookwyrm/templates/password_reset_request.html:18
-#: bookwyrm/templates/preferences/edit_user.html:38
-#: bookwyrm/templates/snippets/register_form.html:13
-msgid "Email address:"
-msgstr "Adresse email :"
-
-#: bookwyrm/templates/discover/landing_layout.html:70
-#: bookwyrm/templates/moderation/report_modal.html:33
-msgid "Submit"
-msgstr "Valider"
-
#: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account"
msgstr "Votre compte"
+#: bookwyrm/templates/email/confirm/html_content.html:6
+#: bookwyrm/templates/email/confirm/text_content.html:4
+#, python-format
+msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
+msgstr ""
+
+#: bookwyrm/templates/email/confirm/html_content.html:11
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm Email"
+msgstr "Confirmer"
+
+#: bookwyrm/templates/email/confirm/subject.html:2
+msgid "Please confirm your email"
+msgstr ""
+
#: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there,"
@@ -1246,7 +1304,7 @@ msgid "Imported"
msgstr "Importé"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
-#: bookwyrm/templates/login.html:46
+#: bookwyrm/templates/login.html:51
msgid "Create an Account"
msgstr "Créer un compte"
@@ -1314,7 +1372,7 @@ msgid "Notifications"
msgstr "Notifications"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
-#: bookwyrm/templates/login.html:17
+#: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:"
msgstr "Nom du compte :"
@@ -1323,12 +1381,12 @@ msgstr "Nom du compte :"
msgid "password"
msgstr "Mot de passe"
-#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36
+#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?"
msgstr "Mot de passe oublié ?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
-#: bookwyrm/templates/login.html:33
+#: bookwyrm/templates/login.html:38
msgid "Log in"
msgstr "Se connecter"
@@ -1504,16 +1562,20 @@ msgstr "Vos listes"
msgid "Login"
msgstr "Connexion"
-#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17
+#: bookwyrm/templates/login.html:16
+msgid "Success! Email address confirmed."
+msgstr ""
+
+#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:"
msgstr "Mot de passe :"
-#: bookwyrm/templates/login.html:52
+#: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite"
msgstr "Contacter un administrateur pour obtenir une invitation"
-#: bookwyrm/templates/login.html:63
+#: bookwyrm/templates/login.html:68
msgid "More about this site"
msgstr "En savoir plus sur ce site"
@@ -2333,7 +2395,15 @@ msgstr "Autoriser les inscriptions"
msgid "Allow invite requests"
msgstr "Autoriser les demandes d’invitation"
-#: bookwyrm/templates/settings/site.html:95
+#: bookwyrm/templates/settings/site.html:97
+msgid "Require users to confirm email address"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:99
+msgid "(Recommended if registration is open)"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:"
msgstr "Texte affiché lorsque les inscriptions sont closes :"
@@ -3015,6 +3085,10 @@ msgstr "Ce fichier dépasse la taille limite : 10 Mo"
msgid "%(title)s: %(subtitle)s"
msgstr "%(title)s (%(subtitle)s)"
+#: bookwyrm/views/authentication.py:69
+msgid "Username or password are incorrect"
+msgstr ""
+
#: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file"
msgstr "Fichier CSV non valide"
@@ -3062,11 +3136,6 @@ msgstr "Un lien de réinitialisation a été envoyé à %s."
#~ msgid "Enter a valid integer."
#~ msgstr "Adresse email :"
-#, fuzzy
-#~| msgid "Email address:"
-#~ msgid "Enter a valid email address."
-#~ msgstr "Adresse email :"
-
#, fuzzy
#~| msgid "Email address:"
#~ msgid "Enter a valid IPv4 address."
diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po
index d9921655e..adb0d36c6 100644
--- a/locale/zh_Hans/LC_MESSAGES/django.po
+++ b/locale/zh_Hans/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-05 01:33+0000\n"
+"POT-Creation-Date: 2021-08-07 01:35+0000\n"
"PO-Revision-Date: 2021-03-20 00:56+0000\n"
"Last-Translator: Kana \n"
"Language-Team: Mouse Reeve \n"
@@ -284,7 +284,7 @@ msgstr "Goodreads key:"
#: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98
-#: bookwyrm/templates/settings/site.html:101
+#: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@@ -681,6 +681,60 @@ msgstr "关闭"
msgid "Compose status"
msgstr "撰写状态"
+#: bookwyrm/templates/confirm_email/confirm_email.html:4
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm email"
+msgstr "确认"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:7
+#, fuzzy
+#| msgid "Email address:"
+msgid "Confirm your email address"
+msgstr "邮箱地址:"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:13
+msgid "A confirmation code has been sent to the email address you used to register your account."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:15
+msgid "Sorry! We couldn't find that code."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:19
+#, fuzzy
+#| msgid "Confirm password:"
+msgid "Confirmation code:"
+msgstr "确认密码:"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:25
+#: bookwyrm/templates/discover/landing_layout.html:70
+#: bookwyrm/templates/moderation/report_modal.html:33
+msgid "Submit"
+msgstr "提交"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:32
+msgid "Can't find your code?"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:4
+msgid "Resend confirmation link"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:11
+#: bookwyrm/templates/discover/landing_layout.html:64
+#: bookwyrm/templates/password_reset_request.html:18
+#: bookwyrm/templates/preferences/edit_user.html:38
+#: bookwyrm/templates/snippets/register_form.html:13
+msgid "Email address:"
+msgstr "邮箱地址:"
+
+#: bookwyrm/templates/confirm_email/resend_form.html:17
+#, fuzzy
+#| msgid "Re-send invite"
+msgid "Resend link"
+msgstr "重新发送请求"
+
#: bookwyrm/templates/directory/community_filter.html:5
msgid "Community"
msgstr "社区"
@@ -807,7 +861,7 @@ msgid "Join %(name)s"
msgstr "加入 %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51
-#: bookwyrm/templates/login.html:51
+#: bookwyrm/templates/login.html:56
msgid "This instance is closed"
msgstr "本实例不开放。"
@@ -819,22 +873,26 @@ msgstr "谢谢你!我们已经收到了你的请求。"
msgid "Request an Invitation"
msgstr "请求邀请"
-#: bookwyrm/templates/discover/landing_layout.html:64
-#: bookwyrm/templates/password_reset_request.html:18
-#: bookwyrm/templates/preferences/edit_user.html:38
-#: bookwyrm/templates/snippets/register_form.html:13
-msgid "Email address:"
-msgstr "邮箱地址:"
-
-#: bookwyrm/templates/discover/landing_layout.html:70
-#: bookwyrm/templates/moderation/report_modal.html:33
-msgid "Submit"
-msgstr "提交"
-
#: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account"
msgstr "你的帐号"
+#: bookwyrm/templates/email/confirm/html_content.html:6
+#: bookwyrm/templates/email/confirm/text_content.html:4
+#, python-format
+msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
+msgstr ""
+
+#: bookwyrm/templates/email/confirm/html_content.html:11
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm Email"
+msgstr "确认"
+
+#: bookwyrm/templates/email/confirm/subject.html:2
+msgid "Please confirm your email"
+msgstr ""
+
#: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there,"
@@ -1237,7 +1295,7 @@ msgid "Imported"
msgstr "已导入"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
-#: bookwyrm/templates/login.html:46
+#: bookwyrm/templates/login.html:51
msgid "Create an Account"
msgstr "创建帐号"
@@ -1305,7 +1363,7 @@ msgid "Notifications"
msgstr "通知"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
-#: bookwyrm/templates/login.html:17
+#: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:"
msgstr "用户名:"
@@ -1314,12 +1372,12 @@ msgstr "用户名:"
msgid "password"
msgstr "密码"
-#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36
+#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?"
msgstr "忘记了密码?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
-#: bookwyrm/templates/login.html:33
+#: bookwyrm/templates/login.html:38
msgid "Log in"
msgstr "登录"
@@ -1495,16 +1553,20 @@ msgstr "你的列表"
msgid "Login"
msgstr "登录"
-#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17
+#: bookwyrm/templates/login.html:16
+msgid "Success! Email address confirmed."
+msgstr ""
+
+#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:"
msgstr "密码:"
-#: bookwyrm/templates/login.html:52
+#: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite"
msgstr "联系管理员以取得邀请"
-#: bookwyrm/templates/login.html:63
+#: bookwyrm/templates/login.html:68
msgid "More about this site"
msgstr "更多关于本站点的信息"
@@ -2319,7 +2381,15 @@ msgstr "允许注册"
msgid "Allow invite requests"
msgstr "允许请求邀请"
-#: bookwyrm/templates/settings/site.html:95
+#: bookwyrm/templates/settings/site.html:97
+msgid "Require users to confirm email address"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:99
+msgid "(Recommended if registration is open)"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:"
msgstr "注册关闭文字:"
@@ -2992,6 +3062,10 @@ msgstr "文件超过了最大大小: 10MB"
msgid "%(title)s: %(subtitle)s"
msgstr "%(title)s:%(subtitle)s"
+#: bookwyrm/views/authentication.py:69
+msgid "Username or password are incorrect"
+msgstr ""
+
#: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file"
msgstr "不是有效的 csv 文件"
diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po
index 5ce42251b..c496bb924 100644
--- a/locale/zh_Hant/LC_MESSAGES/django.po
+++ b/locale/zh_Hant/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-05 01:33+0000\n"
+"POT-Creation-Date: 2021-08-07 01:35+0000\n"
"PO-Revision-Date: 2021-06-30 10:36+0000\n"
"Last-Translator: Grace Cheng \n"
"Language-Team: LANGUAGE \n"
@@ -288,7 +288,7 @@ msgstr "Goodreads key:"
#: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98
-#: bookwyrm/templates/settings/site.html:101
+#: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@@ -687,6 +687,60 @@ msgstr "關閉"
msgid "Compose status"
msgstr "撰寫狀態"
+#: bookwyrm/templates/confirm_email/confirm_email.html:4
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm email"
+msgstr "確認"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:7
+#, fuzzy
+#| msgid "Email address:"
+msgid "Confirm your email address"
+msgstr "郵箱地址:"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:13
+msgid "A confirmation code has been sent to the email address you used to register your account."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:15
+msgid "Sorry! We couldn't find that code."
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:19
+#, fuzzy
+#| msgid "Confirm password:"
+msgid "Confirmation code:"
+msgstr "確認密碼:"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:25
+#: bookwyrm/templates/discover/landing_layout.html:70
+#: bookwyrm/templates/moderation/report_modal.html:33
+msgid "Submit"
+msgstr "提交"
+
+#: bookwyrm/templates/confirm_email/confirm_email.html:32
+msgid "Can't find your code?"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:4
+msgid "Resend confirmation link"
+msgstr ""
+
+#: bookwyrm/templates/confirm_email/resend_form.html:11
+#: bookwyrm/templates/discover/landing_layout.html:64
+#: bookwyrm/templates/password_reset_request.html:18
+#: bookwyrm/templates/preferences/edit_user.html:38
+#: bookwyrm/templates/snippets/register_form.html:13
+msgid "Email address:"
+msgstr "郵箱地址:"
+
+#: bookwyrm/templates/confirm_email/resend_form.html:17
+#, fuzzy
+#| msgid "Re-send invite"
+msgid "Resend link"
+msgstr "重新發送請求"
+
#: bookwyrm/templates/directory/community_filter.html:5
msgid "Community"
msgstr "社群"
@@ -813,7 +867,7 @@ msgid "Join %(name)s"
msgstr "加入 %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51
-#: bookwyrm/templates/login.html:51
+#: bookwyrm/templates/login.html:56
msgid "This instance is closed"
msgstr "本實例不開放。"
@@ -825,22 +879,26 @@ msgstr "謝謝你!我們已經受到了你的請求。"
msgid "Request an Invitation"
msgstr "請求邀請"
-#: bookwyrm/templates/discover/landing_layout.html:64
-#: bookwyrm/templates/password_reset_request.html:18
-#: bookwyrm/templates/preferences/edit_user.html:38
-#: bookwyrm/templates/snippets/register_form.html:13
-msgid "Email address:"
-msgstr "郵箱地址:"
-
-#: bookwyrm/templates/discover/landing_layout.html:70
-#: bookwyrm/templates/moderation/report_modal.html:33
-msgid "Submit"
-msgstr "提交"
-
#: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account"
msgstr "你的帳號"
+#: bookwyrm/templates/email/confirm/html_content.html:6
+#: bookwyrm/templates/email/confirm/text_content.html:4
+#, python-format
+msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
+msgstr ""
+
+#: bookwyrm/templates/email/confirm/html_content.html:11
+#, fuzzy
+#| msgid "Confirm"
+msgid "Confirm Email"
+msgstr "確認"
+
+#: bookwyrm/templates/email/confirm/subject.html:2
+msgid "Please confirm your email"
+msgstr ""
+
#: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there,"
@@ -1247,7 +1305,7 @@ msgid "Imported"
msgstr "已匯入"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
-#: bookwyrm/templates/login.html:46
+#: bookwyrm/templates/login.html:51
msgid "Create an Account"
msgstr "建立帳號"
@@ -1315,7 +1373,7 @@ msgid "Notifications"
msgstr "通知"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
-#: bookwyrm/templates/login.html:17
+#: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:"
msgstr "使用者名稱:"
@@ -1324,12 +1382,12 @@ msgstr "使用者名稱:"
msgid "password"
msgstr "密碼"
-#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36
+#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?"
msgstr "忘記了密碼?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
-#: bookwyrm/templates/login.html:33
+#: bookwyrm/templates/login.html:38
msgid "Log in"
msgstr "登入"
@@ -1505,16 +1563,20 @@ msgstr "你的列表"
msgid "Login"
msgstr "登入"
-#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17
+#: bookwyrm/templates/login.html:16
+msgid "Success! Email address confirmed."
+msgstr ""
+
+#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:"
msgstr "密碼:"
-#: bookwyrm/templates/login.html:52
+#: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite"
msgstr "聯絡管理員以取得邀請"
-#: bookwyrm/templates/login.html:63
+#: bookwyrm/templates/login.html:68
msgid "More about this site"
msgstr "關於本網站的更多"
@@ -2338,7 +2400,15 @@ msgstr "允許註冊:"
msgid "Allow invite requests"
msgstr "允許請求邀請:"
-#: bookwyrm/templates/settings/site.html:95
+#: bookwyrm/templates/settings/site.html:97
+msgid "Require users to confirm email address"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:99
+msgid "(Recommended if registration is open)"
+msgstr ""
+
+#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:"
msgstr "註冊關閉文字:"
@@ -3011,6 +3081,10 @@ msgstr "檔案超過了最大大小: 10MB"
msgid "%(title)s: %(subtitle)s"
msgstr ""
+#: bookwyrm/views/authentication.py:69
+msgid "Username or password are incorrect"
+msgstr ""
+
#: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file"
msgstr "不是有效的 csv 檔案"