Production deployment with Docker and full system fixes
- Added Docker support (Dockerfiles, docker-compose.yml) - Fixed authentication and authorization (token storage, CORS, permissions) - Fixed API response transformations for all modules - Added production deployment scripts and guides - Fixed frontend permission checks and module access - Added database seeding script for production - Complete documentation for deployment and configuration Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5001/api/v1'
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
employeeId: string
|
||||
@@ -20,12 +22,13 @@ interface User {
|
||||
interface Permission {
|
||||
id: string
|
||||
module: string
|
||||
canView: boolean
|
||||
canCreate: boolean
|
||||
canEdit: boolean
|
||||
canDelete: boolean
|
||||
canExport: boolean
|
||||
canApprove: boolean
|
||||
actions?: string[]
|
||||
canView?: boolean
|
||||
canCreate?: boolean
|
||||
canEdit?: boolean
|
||||
canDelete?: boolean
|
||||
canExport?: boolean
|
||||
canApprove?: boolean
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
@@ -46,7 +49,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
// Check for existing token on mount
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem('token')
|
||||
const token = localStorage.getItem('accessToken')
|
||||
if (token) {
|
||||
// Verify token and get user data
|
||||
fetchUserData(token)
|
||||
@@ -55,9 +58,24 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Transform backend permissions format to frontend format
|
||||
const transformPermissions = (permissions: any[]): Permission[] => {
|
||||
return permissions.map(p => ({
|
||||
id: p.id,
|
||||
module: p.module,
|
||||
actions: p.actions,
|
||||
canView: p.actions?.includes('read') || false,
|
||||
canCreate: p.actions?.includes('create') || false,
|
||||
canEdit: p.actions?.includes('update') || false,
|
||||
canDelete: p.actions?.includes('delete') || false,
|
||||
canExport: p.actions?.includes('export') || false,
|
||||
canApprove: p.actions?.includes('approve') || false,
|
||||
}))
|
||||
}
|
||||
|
||||
const fetchUserData = async (token: string) => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:5001/api/v1/auth/me', {
|
||||
const response = await fetch(`${API_URL}/auth/me`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
@@ -65,13 +83,17 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
if (response.ok) {
|
||||
const userData = await response.json()
|
||||
setUser(userData.data)
|
||||
const user = userData.data
|
||||
if (user.role?.permissions) {
|
||||
user.role.permissions = transformPermissions(user.role.permissions)
|
||||
}
|
||||
setUser(user)
|
||||
} else {
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('accessToken')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch user data:', error)
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('accessToken')
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
@@ -79,7 +101,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:5001/api/v1/auth/login', {
|
||||
const response = await fetch(`${API_URL}/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -94,10 +116,15 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
|
||||
// Store token
|
||||
localStorage.setItem('token', data.data.accessToken)
|
||||
localStorage.setItem('accessToken', data.data.accessToken)
|
||||
localStorage.setItem('refreshToken', data.data.refreshToken)
|
||||
|
||||
// Set user data
|
||||
setUser(data.data.user)
|
||||
// Transform permissions and set user data
|
||||
const userData = data.data.user
|
||||
if (userData.role?.permissions) {
|
||||
userData.role.permissions = transformPermissions(userData.role.permissions)
|
||||
}
|
||||
setUser(userData)
|
||||
|
||||
// Redirect to dashboard
|
||||
router.push('/dashboard')
|
||||
@@ -107,7 +134,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('accessToken')
|
||||
localStorage.removeItem('refreshToken')
|
||||
setUser(null)
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user