diff --git a/backend/tests/user/api/test_user_viewsets.py b/backend/tests/user/api/test_user_viewsets.py index 0298ea9..ff5ea99 100644 --- a/backend/tests/user/api/test_user_viewsets.py +++ b/backend/tests/user/api/test_user_viewsets.py @@ -138,6 +138,24 @@ def test_register_rejects_duplicate_username(self, api_client, user_factory): response = api_client.post(reverse('user:user_signup'), data=self._payload(), format='json') assert response.status_code == 400 + def test_register_silently_drops_duplicate_email(self, api_client, user_factory): + with patch('user.tasks.send_email_verification_code.apply_async') as send_code: + owner = user_factory(username='original_owner', email='newpilot@example.com') + response = api_client.post( + reverse('user:user_signup'), data=self._payload(username='second_pilot'), format='json' + ) + + assert response.status_code == 201 + assert response.data['username'] == 'second_pilot' + # only the owner's own creation should have queued a code, not the second registration + send_code.assert_called_once() + + user = User.objects.get(username='second_pilot') + assert user.email is None + + owner.refresh_from_db() + assert owner.email == 'newpilot@example.com' + class TestUserAPIKeyViewSet: def test_list_requires_auth(self, api_client): diff --git a/backend/user/api/serializer.py b/backend/user/api/serializer.py index ebae601..e6020e5 100644 --- a/backend/user/api/serializer.py +++ b/backend/user/api/serializer.py @@ -86,11 +86,10 @@ def validate_username(self, value): return value def validate_email(self, value): - # Only check uniqueness if an email was actually provided - if value: - # Case-insensitive check - if User.objects.filter(email__iexact=value).exists(): - raise serializers.ValidationError('A user with this email already exists.') + # Don't reveal whether an email is already registered (account enumeration): + # silently drop it so registration still succeeds, just without that email attached. + if value and User.objects.filter(email__iexact=value).exists(): + return None return value def validate(self, attrs):