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
+26 -8
View File
@@ -1,13 +1,31 @@
export function normalizeApiError(error) {
const status = error?.response?.status ?? null
const data = error?.response?.data
let message = 'Произошла ошибка запроса.'
export function formatApiErrorData(data) {
if (!data) return ''
if (typeof data === 'string' && data.trim()) return data.trim()
if (typeof data?.detail === 'string' && data.detail.trim()) return data.detail.trim()
if (Array.isArray(data?.non_field_errors) && data.non_field_errors.length) {
return data.non_field_errors.join('; ')
}
if (typeof data === 'object') {
return Object.entries(data)
.map(([key, value]) => {
if (Array.isArray(value)) return `${key}: ${value.join(', ')}`
if (typeof value === 'string') return `${key}: ${value}`
return `${key}: ${JSON.stringify(value)}`
})
.join('; ')
}
return ''
}
if (typeof data === 'string' && data.trim()) {
message = data
} else if (typeof data?.error === 'string' && data.error.trim()) {
export function normalizeApiError(error) {
const status = error?.response?.status ?? error?.status ?? null
const data = error?.response?.data ?? error?.data
const formatted = formatApiErrorData(data)
let message = formatted || 'Произошла ошибка запроса.'
if (!formatted && typeof data?.error === 'string' && data.error.trim()) {
message = data.error
} else if (typeof error?.message === 'string' && error.message.trim()) {
} else if (!formatted && typeof error?.message === 'string' && error.message.trim()) {
message = error.message
}