package main import ( "crypto/rand" "crypto/sha256" "encoding/base64" "encoding/hex" "errors" "fmt" "strings" "sync" "time" ) type TokenInfo struct { Token string CreatedAt time.Time UserID int } var ( tokenMap = make(map[int]*TokenInfo) tokenMux sync.RWMutex tokenTTL = time.Hour ) func GenerateToken(userID int) (string, error) { randomBytes := make([]byte, 32) _, err := rand.Read(randomBytes) if err != nil { return "", fmt.Errorf("failed to generate random bytes: %w", err) } hash := sha256.Sum256(append(randomBytes, []byte(fmt.Sprintf("%d", userID))...)) token := base64.URLEncoding.EncodeToString(hash[:]) tokenMux.Lock() defer tokenMux.Unlock() tokenMap[userID] = &TokenInfo{ Token: token, CreatedAt: time.Now(), UserID: userID, } return token, nil } func ValidateToken(userID int, token string) error { tokenMux.RLock() defer tokenMux.RUnlock() tokenInfo, exists := tokenMap[userID] if !exists { return errors.New("token not found") } if tokenInfo.Token != token { return errors.New("invalid token") } if time.Since(tokenInfo.CreatedAt) > tokenTTL { return errors.New("token expired") } return nil } func RefreshToken(userID int) (string, error) { tokenMux.Lock() defer tokenMux.Unlock() randomBytes := make([]byte, 32) _, err := rand.Read(randomBytes) if err != nil { return "", fmt.Errorf("failed to generate random bytes: %w", err) } hash := sha256.Sum256(append(randomBytes, []byte(fmt.Sprintf("%d", userID))...)) token := base64.URLEncoding.EncodeToString(hash[:]) tokenMap[userID] = &TokenInfo{ Token: token, CreatedAt: time.Now(), UserID: userID, } return token, nil } func RemoveToken(userID int) { tokenMux.Lock() defer tokenMux.Unlock() delete(tokenMap, userID) } func GetTokenInfo(userID int) (*TokenInfo, error) { tokenMux.RLock() defer tokenMux.RUnlock() tokenInfo, exists := tokenMap[userID] if !exists { return nil, errors.New("token not found") } return tokenInfo, nil } func extractUserIDFromToken(token string) (int, error) { tokenMux.RLock() defer tokenMux.RUnlock() for userID, tokenInfo := range tokenMap { if tokenInfo.Token == token { return userID, nil } } return 0, errors.New("invalid token") } func CleanupExpiredTokens() { tokenMux.Lock() defer tokenMux.Unlock() for userID, tokenInfo := range tokenMap { if time.Since(tokenInfo.CreatedAt) > tokenTTL { delete(tokenMap, userID) } } } func hashPassword(password string) (string, error) { hash := sha256.Sum256([]byte(password)) return hex.EncodeToString(hash[:]), nil } func verifyPassword(password, hashedPassword string) bool { hash, err := hashPassword(password) if err != nil { return false } return hash == hashedPassword } func isValidPassword(password string) bool { if len(password) < 8 { return false } hasUpper := false hasLower := false hasDigit := false hasSpecial := false specialChars := "!@#$%^&*()_+-=[]{}|;:,.<>?" for _, char := range password { switch { case char >= 'A' && char <= 'Z': hasUpper = true case char >= 'a' && char <= 'z': hasLower = true case char >= '0' && char <= '9': hasDigit = true case strings.ContainsRune(specialChars, char): hasSpecial = true } } return hasUpper && hasLower && hasDigit && hasSpecial } func ValidateTimeStamp(timeStamp int64) error { currentTime := time.Now().UnixMilli() if !globalConfig.Debug && (currentTime-timeStamp > 3000 || timeStamp-currentTime > 3000) { return errors.New("timestamp out of valid range") } return nil }