|
|
class Authentication { |
|
|
constructor() { |
|
|
this.tokenKey = 'authToken'; |
|
|
this.userKey = 'currentUser'; |
|
|
this.usersKey = 'appUsers'; |
|
|
} |
|
|
|
|
|
generateToken(userId, username, role = 'student') { |
|
|
|
|
|
const tokenData = { |
|
|
userId: userId, |
|
|
username: username, |
|
|
role: role, |
|
|
timestamp: Date.now(), |
|
|
exp: Date.now() + (7 * 24 * 60 * 60 * 1000) |
|
|
}; |
|
|
return btoa(JSON.stringify(tokenData)); |
|
|
} |
|
|
|
|
|
verifyToken(token) { |
|
|
try { |
|
|
const tokenData = JSON.parse(atob(token)); |
|
|
if (tokenData.exp > Date.now()) { |
|
|
return tokenData; |
|
|
} else { |
|
|
this.logout(); |
|
|
return null; |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('Token verification failed:', error); |
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
hashPassword(password) { |
|
|
|
|
|
let hash = 0; |
|
|
for (let i = 0; i < password.length; i++) { |
|
|
const char = password.charCodeAt(i); |
|
|
hash = ((hash << 5) - hash) + char; |
|
|
hash = Math.abs(hash & hash); |
|
|
} |
|
|
return hash.toString(); |
|
|
} |
|
|
|
|
|
setToken(token) { |
|
|
localStorage.setItem(this.tokenKey, token); |
|
|
} |
|
|
|
|
|
getToken() { |
|
|
return localStorage.getItem(this.tokenKey); |
|
|
} |
|
|
|
|
|
setCurrentUser(user) { |
|
|
localStorage.setItem(this.userKey, JSON.stringify(user)); |
|
|
} |
|
|
|
|
|
getCurrentUser() { |
|
|
const userStr = localStorage.getItem(this.userKey); |
|
|
return userStr ? JSON.parse(userStr) : null; |
|
|
} |
|
|
|
|
|
isAuthenticated() { |
|
|
const token = this.getToken(); |
|
|
if (!token) return false; |
|
|
|
|
|
const tokenData = this.verifyToken(token); |
|
|
return tokenData !== null; |
|
|
} |
|
|
|
|
|
logout() { |
|
|
localStorage.removeItem(this.tokenKey); |
|
|
localStorage.removeItem(this.userKey); |
|
|
} |
|
|
|
|
|
|
|
|
initializeDefaultUsers() { |
|
|
const existingUsers = this.getUsers(); |
|
|
if (Object.keys(existingUsers).length === 0) { |
|
|
const defaultUsers = { |
|
|
'1': { |
|
|
userId: '1', |
|
|
username: 'student', |
|
|
email: 'student@example.com', |
|
|
password: this.hashPassword('password123'), |
|
|
role: 'student', |
|
|
createdAt: new Date().toISOString(), |
|
|
profile: { |
|
|
fullName: 'دانشجوی نمونه', |
|
|
bio: 'علاقمند به توسعه وب' |
|
|
}, |
|
|
progress: { |
|
|
totalScore: 0, |
|
|
completedLessons: [], |
|
|
currentLesson: 1 |
|
|
}, |
|
|
isActive: true |
|
|
}, |
|
|
'2': { |
|
|
userId: '2', |
|
|
username: 'admin', |
|
|
email: 'admin@example.com', |
|
|
password: this.hashPassword('admin123'), |
|
|
role: 'admin', |
|
|
createdAt: new Date().toISOString(), |
|
|
profile: { |
|
|
fullName: 'مدیر سیستم', |
|
|
bio: 'مدیر پلتفرم آموزشی' |
|
|
}, |
|
|
progress: { |
|
|
totalScore: 0, |
|
|
completedLessons: [], |
|
|
currentLesson: 1 |
|
|
}, |
|
|
isActive: true |
|
|
} |
|
|
}; |
|
|
this.saveUsers(defaultUsers); |
|
|
} |
|
|
} |
|
|
|
|
|
getUsers() { |
|
|
const usersStr = localStorage.getItem(this.usersKey); |
|
|
return usersStr ? JSON.parse(usersStr) : {}; |
|
|
} |
|
|
|
|
|
saveUsers(users) { |
|
|
localStorage.setItem(this.usersKey, JSON.stringify(users)); |
|
|
} |
|
|
|
|
|
registerUser(username, email, password, role = 'student', profile = {}) { |
|
|
const users = this.getUsers(); |
|
|
|
|
|
|
|
|
for (const userId in users) { |
|
|
if (users[userId].username === username) { |
|
|
return { success: false, message: 'نام کاربری already exists' }; |
|
|
} |
|
|
if (users[userId].email === email) { |
|
|
return { success: false, message: 'ایمیل already exists' }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const newUserId = Object.keys(users).length + 1; |
|
|
const newUser = { |
|
|
userId: newUserId.toString(), |
|
|
username: username, |
|
|
email: email, |
|
|
password: this.hashPassword(password), |
|
|
role: role, |
|
|
createdAt: new Date().toISOString(), |
|
|
profile: { |
|
|
fullName: profile.fullName || '', |
|
|
bio: profile.bio || '', |
|
|
avatar: profile.avatar || '' |
|
|
}, |
|
|
progress: { |
|
|
totalScore: 0, |
|
|
completedLessons: [], |
|
|
currentLesson: 1, |
|
|
achievements: [] |
|
|
}, |
|
|
isActive: true |
|
|
}; |
|
|
|
|
|
users[newUserId] = newUser; |
|
|
this.saveUsers(users); |
|
|
|
|
|
return { success: true, user: newUser }; |
|
|
} |
|
|
|
|
|
loginUser(username, password) { |
|
|
const users = this.getUsers(); |
|
|
const hashedPassword = this.hashPassword(password); |
|
|
console.log('🔐 Login attempt:', { username, hashedPassword }); |
|
|
|
|
|
for (const userId in users) { |
|
|
const user = users[userId]; |
|
|
console.log('📋 User in DB:', { |
|
|
username: user.username, |
|
|
password: user.password, |
|
|
isActive: user.isActive |
|
|
}); |
|
|
|
|
|
if (user.username === username && user.password === hashedPassword && user.isActive) { |
|
|
|
|
|
const token = this.generateToken(user.userId, user.username, user.role); |
|
|
this.setToken(token); |
|
|
this.setCurrentUser(user); |
|
|
|
|
|
|
|
|
user.lastLogin = new Date().toISOString(); |
|
|
this.saveUsers(users); |
|
|
|
|
|
|
|
|
document.dispatchEvent(new CustomEvent('authStateChanged')); |
|
|
|
|
|
return { success: true, user: user, token: token }; |
|
|
} |
|
|
} |
|
|
|
|
|
return { success: false, message: 'نام کاربری یا رمز عبور اشتباه است' }; |
|
|
} |
|
|
|
|
|
updateUserProgress(userId, score = 0, completedLesson = null) { |
|
|
const users = this.getUsers(); |
|
|
if (users[userId]) { |
|
|
const user = users[userId]; |
|
|
|
|
|
if (score > 0) { |
|
|
user.progress.totalScore = (user.progress.totalScore || 0) + score; |
|
|
} |
|
|
|
|
|
if (completedLesson && !user.progress.completedLessons.includes(completedLesson)) { |
|
|
user.progress.completedLessons.push(completedLesson); |
|
|
} |
|
|
|
|
|
this.saveUsers(users); |
|
|
return { success: true, progress: user.progress }; |
|
|
} |
|
|
return { success: false, message: 'User not found' }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const authManager = new Authentication(); |