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 @@
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 @@ + + + + + + + +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.
+ +We're excited to have you on board!
+ ++ If you have any questions, please don't hesitate to reach out to our support team. +
+A new user has registered and verified their email address:
+ +| 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:
+ + + ++ This is an automated notification from KeepItGoing. +
+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:
+ + + +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. +
+