summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Godwin2022-11-17 19:36:25 -0700
committerAndrew Godwin2022-11-17 19:36:25 -0700
commitadf2449d373bcd07e2b0ce557beeb1f49d1894e4 (patch)
treef9178fded8a38d02546b098ebb71b3797eb18964
parent6adfdbabe0d44c17f32abc9d48a6e252e2a0792e (diff)
downloadtakahe-adf2449d373bcd07e2b0ce557beeb1f49d1894e4.tar.gz
takahe-adf2449d373bcd07e2b0ce557beeb1f49d1894e4.tar.bz2
takahe-adf2449d373bcd07e2b0ce557beeb1f49d1894e4.zip
Add the user settings page too
-rw-r--r--README.md8
-rw-r--r--activities/views/search.py2
-rw-r--r--takahe/urls.py8
-rw-r--r--templates/auth/perform_reset.html (renamed from templates/auth/reset.html)0
-rw-r--r--templates/auth/perform_reset_success.html (renamed from templates/auth/reset_success.html)0
-rw-r--r--templates/auth/trigger_reset.html18
-rw-r--r--templates/auth/trigger_reset_success.html14
-rw-r--r--templates/settings/_menu.html2
-rw-r--r--templates/settings/login_security.html17
-rw-r--r--users/views/auth.py35
-rw-r--r--users/views/settings.py27
11 files changed, 116 insertions, 15 deletions
diff --git a/README.md b/README.md
index 4f2f5cc..4236eb1 100644
--- a/README.md
+++ b/README.md
@@ -69,16 +69,16 @@ the less sure I am about it.
- [x] Settings subsystem
- [x] Server management page
- [x] Domain management page
-- [ ] Email subsystem
-- [ ] Signup flow
-- [ ] Password change flow
-- [ ] Password reset flow
+- [x] Email subsystem
+- [x] Signup flow
+- [x] Password reset flow
### Beta
- [ ] Attach images to posts
- [ ] Edit posts
- [ ] Delete posts
+- [ ] Password change flow
- [ ] Fetch remote post images locally and thumbnail
- [ ] Show follow pending states
- [ ] Manual approval of followers
diff --git a/activities/views/search.py b/activities/views/search.py
index b748348..cf62410 100644
--- a/activities/views/search.py
+++ b/activities/views/search.py
@@ -9,7 +9,7 @@ class Search(FormView):
template_name = "activities/search.html"
class form_class(forms.Form):
- query = forms.CharField()
+ query = forms.CharField(help_text="Search for a user by @username@domain")
def form_valid(self, form):
query = form.cleaned_data["query"].lstrip("@").lower()
diff --git a/takahe/urls.py b/takahe/urls.py
index 5c0b182..0ea49d0 100644
--- a/takahe/urls.py
+++ b/takahe/urls.py
@@ -22,6 +22,11 @@ urlpatterns = [
name="settings",
),
path(
+ "settings/security/",
+ settings.SecurityPage.as_view(),
+ name="settings_security",
+ ),
+ path(
"settings/profile/",
settings.ProfilePage.as_view(),
name="settings_profile",
@@ -85,7 +90,8 @@ urlpatterns = [
path("auth/login/", auth.Login.as_view(), name="login"),
path("auth/logout/", auth.Logout.as_view(), name="logout"),
path("auth/signup/", auth.Signup.as_view(), name="signup"),
- path("auth/reset/<token>/", auth.Reset.as_view(), name="password_reset"),
+ path("auth/reset/", auth.TriggerReset.as_view(), name="trigger_reset"),
+ path("auth/reset/<token>/", auth.PerformReset.as_view(), name="password_reset"),
# Identity selection
path("@<handle>/activate/", identity.ActivateIdentity.as_view()),
path("identity/select/", identity.SelectIdentity.as_view()),
diff --git a/templates/auth/reset.html b/templates/auth/perform_reset.html
index 42eced9..42eced9 100644
--- a/templates/auth/reset.html
+++ b/templates/auth/perform_reset.html
diff --git a/templates/auth/reset_success.html b/templates/auth/perform_reset_success.html
index 001e5d7..001e5d7 100644
--- a/templates/auth/reset_success.html
+++ b/templates/auth/perform_reset_success.html
diff --git a/templates/auth/trigger_reset.html b/templates/auth/trigger_reset.html
new file mode 100644
index 0000000..b81c380
--- /dev/null
+++ b/templates/auth/trigger_reset.html
@@ -0,0 +1,18 @@
+{% extends "base.html" %}
+
+{% block title %}Reset Password{% endblock %}
+
+{% block content %}
+ <form action="." method="POST">
+ {% csrf_token %}
+ <fieldset>
+ <legend>Reset Password</legend>
+ {% for field in form %}
+ {% include "forms/_field.html" %}
+ {% endfor %}
+ </fieldset>
+ <div class="buttons">
+ <button>Send Email</button>
+ </div>
+ </form>
+{% endblock %}
diff --git a/templates/auth/trigger_reset_success.html b/templates/auth/trigger_reset_success.html
new file mode 100644
index 0000000..c0c1a0d
--- /dev/null
+++ b/templates/auth/trigger_reset_success.html
@@ -0,0 +1,14 @@
+{% extends "base.html" %}
+
+{% block title %}Password Reset Sent{% endblock %}
+
+{% block content %}
+ <form>
+ <fieldset>
+ <legend>Password Reset Sent</legend>
+ <p>
+ Please check your email at <tt>{{ email }}</tt> for the reset link.
+ </p>
+ </fieldset>
+ </form>
+{% endblock %}
diff --git a/templates/settings/_menu.html b/templates/settings/_menu.html
index d85c878..cc87941 100644
--- a/templates/settings/_menu.html
+++ b/templates/settings/_menu.html
@@ -8,7 +8,7 @@
</a>
{% if request.user.admin %}
<h3>Account</h3>
- <a href="#" {% if section == "login" %}class="selected"{% endif %}>
+ <a href="{% url "settings_security" %}" {% if section == "security" %}class="selected"{% endif %}>
<i class="fa-solid fa-key"></i> Login &amp; Security
</a>
<a href="/auth/logout/">
diff --git a/templates/settings/login_security.html b/templates/settings/login_security.html
new file mode 100644
index 0000000..701b325
--- /dev/null
+++ b/templates/settings/login_security.html
@@ -0,0 +1,17 @@
+{% extends "settings/base.html" %}
+
+{% block subtitle %}Login &amp; Security{% endblock %}
+
+{% block content %}
+ <form action="." method="POST">
+ {% csrf_token %}
+ <fieldset>
+ <legend>Login</legend>
+ {% include "forms/_field.html" with field=form.email %}
+ </fieldset>
+ <fieldset>
+ <legend>Password</legend>
+ <p>To change your password, please trigger a <a href="{% url "trigger_reset" %}">password reset</a>.
+ </fieldset>
+ </form>
+{% endblock %}
diff --git a/users/views/auth.py b/users/views/auth.py
index 7d4040b..7f51d45 100644
--- a/users/views/auth.py
+++ b/users/views/auth.py
@@ -44,9 +44,38 @@ class Signup(FormView):
)
-class Reset(FormView):
+class TriggerReset(FormView):
- template_name = "auth/reset.html"
+ template_name = "auth/trigger_reset.html"
+
+ class form_class(forms.Form):
+
+ email = forms.EmailField(
+ help_text="We will send a reset link to this email",
+ )
+
+ def clean_email(self):
+ email = self.cleaned_data.get("email").lower()
+ if not email:
+ return
+ if not User.objects.filter(email=email).exists():
+ raise forms.ValidationError("This email does not have an account")
+ return email
+
+ def form_valid(self, form):
+ PasswordReset.create_for_user(
+ User.objects.get(email=form.cleaned_data["email"])
+ )
+ return render(
+ self.request,
+ "auth/trigger_reset_success.html",
+ {"email": form.cleaned_data["email"]},
+ )
+
+
+class PerformReset(FormView):
+
+ template_name = "auth/perform_reset.html"
class form_class(forms.Form):
@@ -81,7 +110,7 @@ class Reset(FormView):
self.reset.delete()
return render(
self.request,
- "auth/reset_success.html",
+ "auth/perform_reset_success.html",
{"email": self.reset.user.email},
)
diff --git a/users/views/settings.py b/users/views/settings.py
index d823676..fd138c2 100644
--- a/users/views/settings.py
+++ b/users/views/settings.py
@@ -126,6 +126,7 @@ class ProfilePage(FormView):
"""
template_name = "settings/profile.html"
+ extra_context = {"section": "profile"}
class form_class(forms.Form):
name = forms.CharField(max_length=500)
@@ -150,11 +151,6 @@ class ProfilePage(FormView):
"image": self.request.identity.image.url,
}
- def get_context_data(self):
- context = super().get_context_data()
- context["section"] = "profile"
- return context
-
def form_valid(self, form):
# Update identity name and summary
self.request.identity.name = form.cleaned_data["name"]
@@ -174,3 +170,24 @@ class ProfilePage(FormView):
self.request.identity.image = image
self.request.identity.save()
return redirect(".")
+
+
+@method_decorator(identity_required, name="dispatch")
+class SecurityPage(FormView):
+ """
+ Lets the identity's profile be edited
+ """
+
+ template_name = "settings/login_security.html"
+ extra_context = {"section": "security"}
+
+ class form_class(forms.Form):
+ email = forms.EmailField(
+ disabled=True,
+ help_text="Your email address cannot be changed yet.",
+ )
+
+ def get_initial(self):
+ return {"email": self.request.user.email}
+
+ template_name = "settings/login_security.html"