keys-ios-integration/Sources/KeysForAll/Core/KeyValidator.swift
2025-07-22 01:42:57 -07:00

69 lines
No EOL
2.2 KiB
Swift

//
// KeyValidator.swift
// KeysForAll
//
// Key validation logic
//
import Foundation
import CryptoKit
/// Validates and processes license keys
public struct KeyValidator {
/// Validates a license key format
public static func isValidFormat(_ key: String) -> Bool {
// Expected format: XXXX-XXXX-XXXX-XXXX
let pattern = "^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$"
let regex = try? NSRegularExpression(pattern: pattern)
let range = NSRange(location: 0, length: key.utf16.count)
return regex?.firstMatch(in: key, options: [], range: range) != nil
}
/// Generates a random key for sharing
public static func generateKey() -> String {
let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let segments = (0..<4).map { _ in
String((0..<4).map { _ in characters.randomElement()! })
}
return segments.joined(separator: "-")
}
/// Validates a key (placeholder for server validation)
public static func validate(_ key: String) async throws -> Bool {
// In a real implementation, this would:
// 1. Check format
// 2. Verify with server
// 3. Check if already redeemed
// 4. Return validation result
guard isValidFormat(key) else {
throw KeyValidationError.invalidFormat
}
// For now, accept any properly formatted key
// In production, this would make an API call
return true
}
/// Errors that can occur during validation
public enum KeyValidationError: LocalizedError {
case invalidFormat
case alreadyRedeemed
case expired
case networkError
public var errorDescription: String? {
switch self {
case .invalidFormat:
return "Invalid key format. Keys should be in the format XXXX-XXXX-XXXX-XXXX"
case .alreadyRedeemed:
return "This key has already been redeemed"
case .expired:
return "This key has expired"
case .networkError:
return "Unable to validate key. Please check your internet connection"
}
}
}
}