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
+13 -11
View File
@@ -196,7 +196,7 @@ def parse_upload_file(file):
return None, 'Поддерживаются только CSV, JSON и vCard (.vcf) файлы.'
def import_contacts_from_rows(rows):
def import_contacts_from_rows(rows, owner=None):
created = 0
skipped = 0
errors = []
@@ -212,16 +212,18 @@ def import_contacts_from_rows(rows):
errors.append(f'Строка {i + 1}: отсутствует поле "name"')
skipped += 1
continue
Contact.objects.get_or_create(
name=name,
defaults={
'email': str(row.get('email') or '').strip(),
'phone': str(row.get('phone') or '').strip(),
'organization': str(row.get('organization') or '').strip(),
'position': str(row.get('position') or '').strip(),
'notes': str(row.get('notes') or '').strip(),
},
)
lookup = {'name': name}
defaults = {
'email': str(row.get('email') or '').strip(),
'phone': str(row.get('phone') or '').strip(),
'organization': str(row.get('organization') or '').strip(),
'position': str(row.get('position') or '').strip(),
'notes': str(row.get('notes') or '').strip(),
}
if owner is not None:
lookup['owner'] = owner
defaults['owner'] = owner
Contact.objects.get_or_create(**lookup, defaults=defaults)
created += 1
return {
'total': len(rows),