Fix authentication state persistence and admin role display

- Implement complete authentication system with JWT token validation
- Add auth provider with persistent login state across page refreshes
- Create multilingual login/register forms with Material-UI components
- Fix token validation using raw SQL queries to bypass Prisma sync issues
- Add comprehensive error handling for expired/invalid tokens
- Create profile and settings pages with full i18n support
- Add proper user role management (admin/user) with database sync
- Implement secure middleware with CSRF protection and auth checks
- Add debug endpoints for troubleshooting authentication issues
- Fix Zustand store persistence for authentication state

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
andupetcu
2025-09-21 01:06:30 +03:00
parent 62ca73b2ac
commit 196ca00194
174 changed files with 181207 additions and 179 deletions

View File

@@ -1,25 +1,71 @@
import { z } from 'zod'
// User validation schemas
export const userRegistrationSchema = z.object({
email: z.string()
.email('Email invalid')
.min(3, 'Email-ul trebuie să aibă cel puțin 3 caractere')
.max(254, 'Email-ul trebuie să aibă maximum 254 caractere'),
password: z.string()
.min(8, 'Parola trebuie să aibă cel puțin 8 caractere')
.max(128, 'Parola trebuie să aibă maximum 128 caractere')
.regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, 'Parola trebuie să conțină cel puțin o literă mică, o literă mare și o cifră'),
name: z.string()
.min(2, 'Numele trebuie să aibă cel puțin 2 caractere')
.max(100, 'Numele trebuie să aibă maximum 100 caractere')
.optional()
})
// User validation schemas - localized
export const createUserRegistrationSchema = (locale: string = 'ro') => {
const messages = {
ro: {
invalidEmail: 'Email invalid',
emailMinLength: 'Email-ul trebuie să aibă cel puțin 3 caractere',
emailMaxLength: 'Email-ul trebuie să aibă maximum 254 caractere',
passwordMinLength: 'Parola trebuie să aibă cel puțin 8 caractere',
passwordMaxLength: 'Parola trebuie să aibă maximum 128 caractere',
passwordComplexity: 'Parola trebuie să conțină cel puțin o literă mică, o literă mare și o cifră',
nameMinLength: 'Numele trebuie să aibă cel puțin 2 caractere',
nameMaxLength: 'Numele trebuie să aibă maximum 100 caractere'
},
en: {
invalidEmail: 'Invalid email',
emailMinLength: 'Email must be at least 3 characters',
emailMaxLength: 'Email must be maximum 254 characters',
passwordMinLength: 'Password must be at least 8 characters',
passwordMaxLength: 'Password must be maximum 128 characters',
passwordComplexity: 'Password must contain at least one lowercase letter, one uppercase letter and one digit',
nameMinLength: 'Name must be at least 2 characters',
nameMaxLength: 'Name must be maximum 100 characters'
}
}
export const userLoginSchema = z.object({
email: z.string().email('Email invalid'),
password: z.string().min(1, 'Parola este obligatorie')
})
const msg = messages[locale as keyof typeof messages] || messages.ro
return z.object({
email: z.string()
.email(msg.invalidEmail)
.min(3, msg.emailMinLength)
.max(254, msg.emailMaxLength),
password: z.string()
.min(8, msg.passwordMinLength)
.max(128, msg.passwordMaxLength)
.regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, msg.passwordComplexity),
name: z.string()
.min(2, msg.nameMinLength)
.max(100, msg.nameMaxLength)
.optional()
})
}
export const createUserLoginSchema = (locale: string = 'ro') => {
const messages = {
ro: {
invalidEmail: 'Email invalid',
passwordRequired: 'Parola este obligatorie'
},
en: {
invalidEmail: 'Invalid email',
passwordRequired: 'Password is required'
}
}
const msg = messages[locale as keyof typeof messages] || messages.ro
return z.object({
email: z.string().email(msg.invalidEmail),
password: z.string().min(1, msg.passwordRequired)
})
}
// Backward compatibility - default to Romanian
export const userRegistrationSchema = createUserRegistrationSchema('ro')
export const userLoginSchema = createUserLoginSchema('ro')
// Chat validation schemas
export const chatMessageSchema = z.object({