diff --git a/config/settings/base.py b/config/settings/base.py index 1ee4f32..278894c 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -68,6 +68,11 @@ WSGI_APPLICATION = 'config.wsgi.application' # Custom user model AUTH_USER_MODEL = 'users.User' +# Authentication backends +AUTHENTICATION_BACKENDS = [ + 'users.backends.EmailVerifiedApprovedBackend', +] + # Password validation AUTH_PASSWORD_VALIDATORS = [ { @@ -147,3 +152,9 @@ USAGE_LIMITS_ENABLED = SAAS_MODE LOGIN_URL = '/login/' LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/login/' + +# Email verification settings +EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS = int( + os.environ.get('EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS', 24) +) +SITE_DOMAIN = os.environ.get('SITE_DOMAIN', 'localhost:8000') diff --git a/tasks/serializers.py b/tasks/serializers.py index caa7784..d123a2c 100644 --- a/tasks/serializers.py +++ b/tasks/serializers.py @@ -125,13 +125,14 @@ class TaskSyncSerializer(serializers.ModelSerializer): """Serializer for tasks in sync responses - uses sync_id as id.""" id = serializers.UUIDField(source='sync_id', read_only=True) + sync_id = serializers.UUIDField(read_only=True) tag_sync_ids = serializers.SerializerMethodField() parent_sync_id = serializers.UUIDField(source='parent.sync_id', read_only=True, allow_null=True) class Meta: model = Task fields = [ - 'id', 'parent', 'parent_sync_id', + 'id', 'sync_id', 'parent', 'parent_sync_id', 'title', 'description', 'status', 'priority', 'due_date', 'due_time', 'reminder_at', 'completed_at', 'recurrence', 'recurrence_rule', 'recurrence_end_date', 'tag_sync_ids', @@ -147,10 +148,11 @@ class TagSyncSerializer(serializers.ModelSerializer): """Serializer for tags in sync responses - uses sync_id as id.""" id = serializers.UUIDField(source='sync_id', read_only=True) + sync_id = serializers.UUIDField(read_only=True) class Meta: model = Tag - fields = ['id', 'name', 'description', 'color', 'icon', 'sort_order', + fields = ['id', 'sync_id', 'name', 'description', 'color', 'icon', 'sort_order', 'is_archived', 'is_deleted', 'created_at', 'updated_at'] @@ -158,11 +160,12 @@ class TimeEntrySyncSerializer(serializers.ModelSerializer): """Serializer for time entries in sync responses - uses sync_id as id.""" id = serializers.UUIDField(source='sync_id', read_only=True) + sync_id = serializers.UUIDField(read_only=True) task = serializers.UUIDField(source='task.sync_id', read_only=True) class Meta: model = TimeEntry - fields = ['id', 'task', 'started_at', 'ended_at', 'notes', + fields = ['id', 'sync_id', 'task', 'started_at', 'ended_at', 'notes', 'is_deleted', 'created_at', 'updated_at'] diff --git a/templates/base.html b/templates/base.html index 52a5b32..39b79b6 100644 --- a/templates/base.html +++ b/templates/base.html @@ -35,6 +35,7 @@
{{ user.email }} + Profile Logout
diff --git a/templates/emails/account_approved.html b/templates/emails/account_approved.html new file mode 100644 index 0000000..0fbec7d --- /dev/null +++ b/templates/emails/account_approved.html @@ -0,0 +1,34 @@ + + + + + + + +
+

Your Account Has Been Approved!

+ +

Hi {{ user.first_name|default:user.username }},

+ +

Great news! Your KeepItGoing account has been approved by our team.

+ +

You can now log in and start using KeepItGoing to manage your tasks and stay organized.

+ +
+ + Log In Now + +
+ +

We're excited to have you on board!

+ +
+ +

+ If you have any questions, please don't hesitate to reach out to our support team. +

+
+ + diff --git a/templates/emails/account_approved.txt b/templates/emails/account_approved.txt new file mode 100644 index 0000000..a583c63 --- /dev/null +++ b/templates/emails/account_approved.txt @@ -0,0 +1,14 @@ +Your Account Has Been Approved! + +Hi {{ user.first_name|default:user.username }}, + +Great news! Your KeepItGoing account has been approved by our team. + +You can now log in and start using KeepItGoing to manage your tasks and stay organized. + +Log in here: {{ login_url }} + +We're excited to have you on board! + +--- +KeepItGoing diff --git a/templates/emails/admin_new_user.html b/templates/emails/admin_new_user.html new file mode 100644 index 0000000..4a538dc --- /dev/null +++ b/templates/emails/admin_new_user.html @@ -0,0 +1,53 @@ + + + + + + + +
+

New User Registration

+ +

A new user has registered and verified their email address:

+ +
+ + + + + + + + + + {% if user.first_name or user.last_name %} + + + + + {% endif %} + + + + +
Email:{{ user.email }}
Username:{{ user.username }}
Name:{{ user.first_name }} {{ user.last_name }}
Registered:{{ user.created_at|date:"F j, Y, g:i a" }}
+
+ +

Please review and approve this user in the admin panel:

+ +
+ + Review in Admin Panel + +
+ +
+ +

+ This is an automated notification from KeepItGoing. +

+
+ + diff --git a/templates/emails/admin_new_user.txt b/templates/emails/admin_new_user.txt new file mode 100644 index 0000000..2c62a42 --- /dev/null +++ b/templates/emails/admin_new_user.txt @@ -0,0 +1,14 @@ +New User Registration + +A new user has registered and verified their email address: + +Email: {{ user.email }} +Username: {{ user.username }} +{% if user.first_name or user.last_name %}Name: {{ user.first_name }} {{ user.last_name }} +{% endif %}Registered: {{ user.created_at|date:"F j, Y, g:i a" }} + +Please review and approve this user in the admin panel: +{{ admin_url }} + +--- +KeepItGoing (automated notification) diff --git a/templates/emails/verify_email.html b/templates/emails/verify_email.html new file mode 100644 index 0000000..aeaa908 --- /dev/null +++ b/templates/emails/verify_email.html @@ -0,0 +1,39 @@ + + + + + + + +
+

Verify Your Email Address

+ +

Hi{% if user.first_name %} {{ user.first_name }}{% endif %},

+ +

Thank you for registering with KeepItGoing! Please verify your email address by clicking the button below:

+ +
+ + Verify Email Address + +
+ +

Or copy and paste this link into your browser:

+

+ {{ verification_url }} +

+ +

+ This link will expire in {{ expiry_hours }} hours. +

+ +
+ +

+ If you didn't create an account with KeepItGoing, you can safely ignore this email. +

+
+ + diff --git a/templates/emails/verify_email.txt b/templates/emails/verify_email.txt new file mode 100644 index 0000000..68ea0d2 --- /dev/null +++ b/templates/emails/verify_email.txt @@ -0,0 +1,14 @@ +Verify Your Email Address + +Hi{% if user.first_name %} {{ user.first_name }}{% endif %}, + +Thank you for registering with KeepItGoing! Please verify your email address by visiting this link: + +{{ verification_url }} + +This link will expire in {{ expiry_hours }} hours. + +If you didn't create an account with KeepItGoing, you can safely ignore this email. + +--- +KeepItGoing diff --git a/templates/users/change_password.html b/templates/users/change_password.html new file mode 100644 index 0000000..34d1ec1 --- /dev/null +++ b/templates/users/change_password.html @@ -0,0 +1,87 @@ +{% extends 'base.html' %} + +{% block title %}Change Password - KeepItGoing{% endblock %} + +{% block body %} +
+ +
+ KeepItGoing +
+ {{ user.email }} + Profile + Logout +
+
+ + +
+

Change Password

+ + {% if success %} +
+ ✓ Success!
+ {{ success }} +
+ {% endif %} + +
+ {% csrf_token %} + +
+ + + {% if errors.old_password %} +

{{ errors.old_password }}

+ {% endif %} +
+ +
+ + +

Must be at least 8 characters

+ {% if errors.new_password %} +

{{ errors.new_password }}

+ {% endif %} +
+ +
+ + + {% if errors.confirm_password %} +

{{ errors.confirm_password }}

+ {% endif %} +
+ +
+ + + Cancel + +
+
+ +
+ ← Back to Dashboard +
+
+
+{% endblock %} diff --git a/templates/users/login.html b/templates/users/login.html index d76945d..f4820e4 100644 --- a/templates/users/login.html +++ b/templates/users/login.html @@ -7,14 +7,24 @@

Login

{% if error %} -
{{ error }}
+
+ {{ error }} + {% if can_resend %} +

+ + Resend verification email + +

+ {% endif %} +
{% endif %}
{% csrf_token %}
- +
diff --git a/templates/users/profile.html b/templates/users/profile.html index 3d77b1f..fe947d8 100644 --- a/templates/users/profile.html +++ b/templates/users/profile.html @@ -3,75 +3,125 @@ {% block title %}Profile - KeepItGoing{% endblock %} {% block content %} -