Add JWT auth with per-user data isolation and account settings.

Users can register, log in, and manage profile/password in a personal account page; server data is scoped by owner across contacts, maps, tags, and import.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-28 21:10:16 +03:00
co-authored by Cursor
parent 85b8b2e9b8
commit 4eb4c145b6
40 changed files with 2301 additions and 117 deletions
+19 -13
View File
@@ -1,19 +1,25 @@
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from core.access import use_jwt_auth
from core.drf_mixins import JwtAuthMixin
from .services import parse_upload_file, import_contacts_from_rows
@api_view(['POST'])
def import_contacts(request):
file = request.FILES.get('file')
if not file:
return Response({'error': 'Файл не передан.'}, status=status.HTTP_400_BAD_REQUEST)
try:
rows, error = parse_upload_file(file)
if error:
return Response({'error': error}, status=status.HTTP_400_BAD_REQUEST)
return Response(import_contacts_from_rows(rows))
except Exception as e:
return Response({'error': f'Ошибка разбора файла: {e}'}, status=status.HTTP_400_BAD_REQUEST)
class ImportContactsView(JwtAuthMixin, APIView):
def post(self, request):
file = request.FILES.get('file')
if not file:
return Response({'error': 'Файл не передан.'}, status=status.HTTP_400_BAD_REQUEST)
try:
rows, error = parse_upload_file(file)
if error:
return Response({'error': error}, status=status.HTTP_400_BAD_REQUEST)
owner = request.user if use_jwt_auth() and request.user.is_authenticated else None
return Response(import_contacts_from_rows(rows, owner=owner))
except Exception as e:
return Response(
{'error': f'Ошибка разбора файла: {e}'},
status=status.HTTP_400_BAD_REQUEST,
)