2
0
Fork 0

Merge branch 'main' into production

This commit is contained in:
Mouse Reeve 2022-11-23 22:11:59 -08:00
commit ed28e2d6e8
10 changed files with 56 additions and 13 deletions

View file

@ -37,7 +37,7 @@ Keep track of what books you've read, and what books you'd like to read in the f
Federation allows you to interact with users on other instances and services, and also shares metadata about books and authors, which collaboratively builds a decentralized database of books. Federation allows you to interact with users on other instances and services, and also shares metadata about books and authors, which collaboratively builds a decentralized database of books.
### Privacy and moderation ### Privacy and moderation
Users and administrators can control who can see thier posts and what other instances to federate with. Users and administrators can control who can see their posts and what other instances to federate with.
## Tech Stack ## Tech Stack
Web backend Web backend

View file

@ -38,7 +38,7 @@ def password_reset_email(reset_code):
data = email_data() data = email_data()
data["reset_link"] = reset_code.link data["reset_link"] = reset_code.link
data["user"] = reset_code.user.display_name data["user"] = reset_code.user.display_name
send_email.delay(reset_code.user.email, *format_email("password_reset", data)) send_email(reset_code.user.email, *format_email("password_reset", data))
def moderation_report_email(report): def moderation_report_email(report):

View file

@ -92,6 +92,10 @@ $family-secondary: $family-sans-serif;
color: $grey-light !important; color: $grey-light !important;
} }
#qrcode svg {
background-color: #a6a6a6;
}
@import "../bookwyrm.scss"; @import "../bookwyrm.scss";
@import "../vendor/icons.css"; @import "../vendor/icons.css";
@import "../vendor/shepherd.scss"; @import "../vendor/shepherd.scss";

View file

@ -45,7 +45,30 @@
<p>{% trans "Scan the QR code with your authentication app and then enter the code from your app below to confirm your app is set up." %}</p> <p>{% trans "Scan the QR code with your authentication app and then enter the code from your app below to confirm your app is set up." %}</p>
<div class="columns"> <div class="columns">
<section class="column is-narrow"> <section class="column is-narrow">
<figure class="m-4">{{ qrcode | safe }}</figure> <figure class="m-4" id="qrcode">{{ qrcode | safe }}</figure>
<details class="details-panel box">
<summary>
<span role="heading" aria-level="3" class="title is-6">
{% trans "Use setup key" %}
<span class="details-close icon icon-x" aria-hidden="true"></span>
</span>
</summary>
<dl class="block">
<dt class="has-text-weight-bold mr-5 is-pulled-left">
{% trans "Account name:" %}
</dt>
<dd>
<code>{{ user.username }}</code>
</dd>
<dt class="has-text-weight-bold mr-5 is-pulled-left">
{% trans "Code:" %}
</dt>
<dd>
<code>{{ code | safe }}</code>
</dd>
</dl>
</details>
<div class="field"> <div class="field">
<label class="label" for="id_otp">{% trans "Enter the code from your app:" %}</label> <label class="label" for="id_otp">{% trans "Enter the code from your app:" %}</label>
{{ form.otp }} {{ form.otp }}

View file

@ -73,6 +73,14 @@ User-agent: PetalBot
Disallow: / Disallow: /
User-agent: DataForSeoBot
Disallow: /
User-agent: YisouSpider
Disallow: /
User-agent: * User-agent: *
Crawl-delay: 10
Disallow: /static/js/ Disallow: /static/js/
Disallow: /static/css/ Disallow: /static/css/

View file

@ -24,7 +24,7 @@
</div> </div>
<div class="column is-2"> <div class="column is-2">
<p> <p>
<a href ="{% url 'privacy' %}">{% trans "Code of Conduct" %}</a> <a href ="{% url 'conduct' %}">{% trans "Code of Conduct" %}</a>
</p> </p>
<p> <p>
<a href ="{% url 'privacy' %}">{% trans "Privacy Policy" %}</a> <a href ="{% url 'privacy' %}">{% trans "Privacy Policy" %}</a>

View file

@ -11,6 +11,7 @@ from bookwyrm import emailing, models
class Emailing(TestCase): class Emailing(TestCase):
"""every response to a get request, html or json""" """every response to a get request, html or json"""
# pylint: disable=invalid-name
def setUp(self): def setUp(self):
"""we need basic test data and mocks""" """we need basic test data and mocks"""
self.factory = RequestFactory() self.factory = RequestFactory()
@ -41,10 +42,12 @@ class Emailing(TestCase):
self.assertEqual(args[1], "You're invited to join BookWyrm!") self.assertEqual(args[1], "You're invited to join BookWyrm!")
self.assertEqual(len(args), 4) self.assertEqual(len(args), 4)
def test_password_reset_email(self, email_mock): def test_password_reset_email(self, _):
"""load the password reset email""" """load the password reset email"""
reset = models.PasswordReset.objects.create(user=self.local_user) reset = models.PasswordReset.objects.create(user=self.local_user)
emailing.password_reset_email(reset)
with patch("bookwyrm.emailing.send_email") as email_mock:
emailing.password_reset_email(reset)
self.assertEqual(email_mock.call_count, 1) self.assertEqual(email_mock.call_count, 1)
args = email_mock.call_args[0] args = email_mock.call_args[0]

View file

@ -110,8 +110,8 @@ def get_list_suggestions(book_list, user, query=None):
s.default_edition s.default_edition
for s in models.Work.objects.filter( for s in models.Work.objects.filter(
~Q(editions__in=book_list.books.all()), ~Q(editions__in=book_list.books.all()),
).order_by("-updated_date") ).order_by("-updated_date")[: 5 - len(suggestions)]
][: 5 - len(suggestions)] ]
return suggestions return suggestions

View file

@ -35,10 +35,12 @@ class Edit2FA(View):
if not form.is_valid(): if not form.is_valid():
data = {"form": form} data = {"form": form}
return TemplateResponse(request, "preferences/2fa.html", data) return TemplateResponse(request, "preferences/2fa.html", data)
data = self.create_qr_code(request.user)
qr_form = forms.Confirm2FAForm() qr_form = forms.Confirm2FAForm()
data = { data = {
"password_confirmed": True, "password_confirmed": True,
"qrcode": self.create_qr_code(request.user), "qrcode": data[0],
"code": data[1],
"form": qr_form, "form": qr_form,
} }
return TemplateResponse(request, "preferences/2fa.html", data) return TemplateResponse(request, "preferences/2fa.html", data)
@ -57,7 +59,10 @@ class Edit2FA(View):
qr_code.add_data(provisioning_url) qr_code.add_data(provisioning_url)
qr_code.make(fit=True) qr_code.make(fit=True)
img = qr_code.make_image(attrib={"fill": "black"}) img = qr_code.make_image(attrib={"fill": "black"})
return str(img.to_string(), "utf-8") # to_string() returns a byte string return [
str(img.to_string(), "utf-8"),
otp_secret,
] # to_string() returns a byte string
@method_decorator(login_required, name="dispatch") @method_decorator(login_required, name="dispatch")

View file

@ -5,8 +5,8 @@ services:
image: nginx:latest image: nginx:latest
restart: unless-stopped restart: unless-stopped
ports: ports:
- 80:80 - "80:80"
- 443:443 - "443:443"
depends_on: depends_on:
- web - web
networks: networks:
@ -50,7 +50,7 @@ services:
networks: networks:
- main - main
ports: ports:
- 8000 - "8000"
redis_activity: redis_activity:
image: redis image: redis
command: redis-server --requirepass ${REDIS_ACTIVITY_PASSWORD} --appendonly yes --port ${REDIS_ACTIVITY_PORT} command: redis-server --requirepass ${REDIS_ACTIVITY_PASSWORD} --appendonly yes --port ${REDIS_ACTIVITY_PORT}