mirror of
https://github.com/jointakahe/takahe.git
synced 2024-11-25 16:51:00 +00:00
Add the user settings page too
This commit is contained in:
parent
6adfdbabe0
commit
adf2449d37
11 changed files with 116 additions and 15 deletions
|
@ -69,16 +69,16 @@ the less sure I am about it.
|
||||||
- [x] Settings subsystem
|
- [x] Settings subsystem
|
||||||
- [x] Server management page
|
- [x] Server management page
|
||||||
- [x] Domain management page
|
- [x] Domain management page
|
||||||
- [ ] Email subsystem
|
- [x] Email subsystem
|
||||||
- [ ] Signup flow
|
- [x] Signup flow
|
||||||
- [ ] Password change flow
|
- [x] Password reset flow
|
||||||
- [ ] Password reset flow
|
|
||||||
|
|
||||||
### Beta
|
### Beta
|
||||||
|
|
||||||
- [ ] Attach images to posts
|
- [ ] Attach images to posts
|
||||||
- [ ] Edit posts
|
- [ ] Edit posts
|
||||||
- [ ] Delete posts
|
- [ ] Delete posts
|
||||||
|
- [ ] Password change flow
|
||||||
- [ ] Fetch remote post images locally and thumbnail
|
- [ ] Fetch remote post images locally and thumbnail
|
||||||
- [ ] Show follow pending states
|
- [ ] Show follow pending states
|
||||||
- [ ] Manual approval of followers
|
- [ ] Manual approval of followers
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Search(FormView):
|
||||||
template_name = "activities/search.html"
|
template_name = "activities/search.html"
|
||||||
|
|
||||||
class form_class(forms.Form):
|
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):
|
def form_valid(self, form):
|
||||||
query = form.cleaned_data["query"].lstrip("@").lower()
|
query = form.cleaned_data["query"].lstrip("@").lower()
|
||||||
|
|
|
@ -21,6 +21,11 @@ urlpatterns = [
|
||||||
settings.SettingsRoot.as_view(),
|
settings.SettingsRoot.as_view(),
|
||||||
name="settings",
|
name="settings",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"settings/security/",
|
||||||
|
settings.SecurityPage.as_view(),
|
||||||
|
name="settings_security",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"settings/profile/",
|
"settings/profile/",
|
||||||
settings.ProfilePage.as_view(),
|
settings.ProfilePage.as_view(),
|
||||||
|
@ -85,7 +90,8 @@ urlpatterns = [
|
||||||
path("auth/login/", auth.Login.as_view(), name="login"),
|
path("auth/login/", auth.Login.as_view(), name="login"),
|
||||||
path("auth/logout/", auth.Logout.as_view(), name="logout"),
|
path("auth/logout/", auth.Logout.as_view(), name="logout"),
|
||||||
path("auth/signup/", auth.Signup.as_view(), name="signup"),
|
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
|
# Identity selection
|
||||||
path("@<handle>/activate/", identity.ActivateIdentity.as_view()),
|
path("@<handle>/activate/", identity.ActivateIdentity.as_view()),
|
||||||
path("identity/select/", identity.SelectIdentity.as_view()),
|
path("identity/select/", identity.SelectIdentity.as_view()),
|
||||||
|
|
18
templates/auth/trigger_reset.html
Normal file
18
templates/auth/trigger_reset.html
Normal file
|
@ -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 %}
|
14
templates/auth/trigger_reset_success.html
Normal file
14
templates/auth/trigger_reset_success.html
Normal file
|
@ -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 %}
|
|
@ -8,7 +8,7 @@
|
||||||
</a>
|
</a>
|
||||||
{% if request.user.admin %}
|
{% if request.user.admin %}
|
||||||
<h3>Account</h3>
|
<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 & Security
|
<i class="fa-solid fa-key"></i> Login & Security
|
||||||
</a>
|
</a>
|
||||||
<a href="/auth/logout/">
|
<a href="/auth/logout/">
|
||||||
|
|
17
templates/settings/login_security.html
Normal file
17
templates/settings/login_security.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "settings/base.html" %}
|
||||||
|
|
||||||
|
{% block subtitle %}Login & 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 %}
|
|
@ -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):
|
class form_class(forms.Form):
|
||||||
|
|
||||||
|
@ -81,7 +110,7 @@ class Reset(FormView):
|
||||||
self.reset.delete()
|
self.reset.delete()
|
||||||
return render(
|
return render(
|
||||||
self.request,
|
self.request,
|
||||||
"auth/reset_success.html",
|
"auth/perform_reset_success.html",
|
||||||
{"email": self.reset.user.email},
|
{"email": self.reset.user.email},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ class ProfilePage(FormView):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
template_name = "settings/profile.html"
|
template_name = "settings/profile.html"
|
||||||
|
extra_context = {"section": "profile"}
|
||||||
|
|
||||||
class form_class(forms.Form):
|
class form_class(forms.Form):
|
||||||
name = forms.CharField(max_length=500)
|
name = forms.CharField(max_length=500)
|
||||||
|
@ -150,11 +151,6 @@ class ProfilePage(FormView):
|
||||||
"image": self.request.identity.image.url,
|
"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):
|
def form_valid(self, form):
|
||||||
# Update identity name and summary
|
# Update identity name and summary
|
||||||
self.request.identity.name = form.cleaned_data["name"]
|
self.request.identity.name = form.cleaned_data["name"]
|
||||||
|
@ -174,3 +170,24 @@ class ProfilePage(FormView):
|
||||||
self.request.identity.image = image
|
self.request.identity.image = image
|
||||||
self.request.identity.save()
|
self.request.identity.save()
|
||||||
return redirect(".")
|
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"
|
||||||
|
|
Loading…
Reference in a new issue