v2.0.0: Multi-user authentication with JWT
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 16s
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 16s
Features: - User registration and login with JWT tokens - All data is now user-specific (multi-tenancy) - Profile page with integrations and logout - Automatic migration of existing data to first user Backend changes: - Added users and refresh_tokens tables - Added user_id to all data tables (projects, entries, nodes, dictionaries, words, progress, configs, telegram_integrations, weekly_goals) - JWT authentication middleware - claimOrphanedData() for data migration Frontend changes: - AuthContext for state management - Login/Register forms - Profile page (replaced Integrations) - All API calls use authFetch with Bearer token Migration notes: - On first deploy, backend automatically adds user_id columns - First user to login claims all existing data
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
} from '@dnd-kit/sortable'
|
||||
import { CSS } from '@dnd-kit/utilities'
|
||||
import { getAllProjectsSorted, getProjectColor } from '../utils/projectUtils'
|
||||
import { useAuth } from './auth/AuthContext'
|
||||
|
||||
// API endpoints (используем относительные пути, проксирование настроено в nginx/vite)
|
||||
const PROJECTS_API_URL = '/projects'
|
||||
@@ -46,7 +47,7 @@ function MoveProjectScreen({ project, allProjects, onClose, onSuccess }) {
|
||||
|
||||
try {
|
||||
const projectId = project.id ?? project.name
|
||||
const response = await fetch(PROJECT_MOVE_API_URL, {
|
||||
const response = await authFetch(PROJECT_MOVE_API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -263,6 +264,7 @@ function PrioritySlot({ title, projects, allProjects, onMenuClick, maxItems = nu
|
||||
}
|
||||
|
||||
function ProjectPriorityManager({ allProjectsData, currentWeekData, shouldLoad, onLoadingChange, onErrorChange, refreshTrigger, onNavigate }) {
|
||||
const { authFetch } = useAuth()
|
||||
const [projectsLoading, setProjectsLoading] = useState(false)
|
||||
const [projectsError, setProjectsError] = useState(null)
|
||||
const [hasDataCache, setHasDataCache] = useState(false) // Отслеживаем наличие кеша
|
||||
@@ -381,7 +383,7 @@ function ProjectPriorityManager({ allProjectsData, currentWeekData, shouldLoad,
|
||||
}
|
||||
setProjectsError(null)
|
||||
|
||||
const response = await fetch(PROJECTS_API_URL)
|
||||
const response = await authFetch(PROJECTS_API_URL)
|
||||
if (!response.ok) {
|
||||
throw new Error('Не удалось загрузить проекты')
|
||||
}
|
||||
@@ -483,7 +485,7 @@ function ProjectPriorityManager({ allProjectsData, currentWeekData, shouldLoad,
|
||||
const sendPriorityChanges = useCallback(async (changes) => {
|
||||
if (!changes.length) return
|
||||
try {
|
||||
await fetch(PRIORITY_UPDATE_API_URL, {
|
||||
await authFetch(PRIORITY_UPDATE_API_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(changes),
|
||||
@@ -723,7 +725,7 @@ function ProjectPriorityManager({ allProjectsData, currentWeekData, shouldLoad,
|
||||
|
||||
try {
|
||||
const projectId = selectedProject.id ?? selectedProject.name
|
||||
const response = await fetch(`/project/delete`, {
|
||||
const response = await authFetch(`/project/delete`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: projectId }),
|
||||
|
||||
Reference in New Issue
Block a user