Manos Chorianopoulos

fix problematic apiKey, webId checks

......@@ -1117,12 +1117,108 @@ After these changes, the framework should:
4. **Network Requests**: Check that all API calls work with simplified authentication
5. **Log Verification**: Ensure no more excessive credential warnings
### **🔧 Additional Safety Fixes - June 27, 2025 (Session 2)**
After the initial legacy credential removal, a comprehensive search revealed **2 additional problematic checks** that could still cause issues:
#### **Issue #5: NetworkService Signature Generation (CRITICAL)**
**File**: `SwiftWarplyFramework/SwiftWarplyFramework/Network/NetworkService.swift`
**Problem**: Conditional signature generation that skipped the `loyalty-signature` header when API key was empty
**Impact**: ❌ **CRITICAL** - Missing signature header could cause API authentication failures
**Before (Problematic)**:
```swift
// Generate loyalty signature (apiKey + timestamp SHA256)
let apiKey = getApiKey()
if !apiKey.isEmpty {
let signatureString = "\(apiKey)\(timestamp)"
let signature = signatureString.sha256()
request.setValue(signature, forHTTPHeaderField: "loyalty-signature")
}
```
**After (Safe)**:
```swift
// Generate loyalty signature (apiKey + timestamp SHA256)
// Always generate signature, even with empty API key (server expects this header)
let apiKey = getApiKey()
let signatureString = "\(apiKey)\(timestamp)"
let signature = signatureString.sha256()
request.setValue(signature, forHTTPHeaderField: "loyalty-signature")
```
**Result**: ✅ Signature header always sent, preventing authentication failures
---
#### **Issue #6: WarplySDK Registration Check (CLEANUP)**
**File**: `SwiftWarplyFramework/SwiftWarplyFramework/Core/WarplySDK.swift`
**Problem**: Dead code that checked for non-empty legacy credentials (would never execute)
**Impact**: 🟡 **MEDIUM** - Unnecessary code that could confuse developers
**Before (Dead Code)**:
```swift
// Check if we already have API key and web ID
let existingApiKey = UserDefaults.standard.string(forKey: "NBAPIKeyUD")
let existingWebId = UserDefaults.standard.string(forKey: "NBWebIDUD")
if let apiKey = existingApiKey, !apiKey.isEmpty,
let webId = existingWebId, !webId.isEmpty {
print("✅ [WarplySDK] Device already registered - API Key: \(apiKey.prefix(8))..., Web ID: \(webId)")
return
}
```
**After (Clean)**:
```swift
// Legacy credentials are deprecated - always proceed with registration if needed
// (The server will handle duplicate registrations gracefully)
```
**Result**: ✅ Cleaner code, no more dead conditional logic
---
### **📊 Complete Fix Summary**
| Session | File | Change Type | Impact | Description |
|---------|------|-------------|---------|-------------|
| **1** | `TokenRefreshManager.swift` | **Critical Fix** | 🔴 **HIGH** | Removed blocking guard for client credentials |
| **1** | `WarplySDK.swift` | **Critical Fix** | 🔴 **HIGH** | Removed registration validation for legacy credentials |
| **1** | `NetworkService.swift` | **Optimization** | 🟡 **MEDIUM** | Simplified credential methods, removed storage |
| **1** | `TokenModel.swift` | **Enhancement** | 🟢 **LOW** | Default empty strings for legacy credentials |
| **2** | `NetworkService.swift` | **Critical Fix** | 🔴 **HIGH** | Always generate signature header |
| **2** | `WarplySDK.swift` | **Cleanup** | 🟢 **LOW** | Removed dead registration check code |
### **🎯 Final Expected Results**
After all fixes, the framework should:
1.**No more WarplyError code 5** during device registration
2.**No more credential warning logs** during network requests
3.**Token refresh works** without client_id/client_secret requirements
4.**Registration succeeds** with "deprecated" API responses
5.**Signature header always sent** - no authentication failures
6.**Clean codebase** - no dead conditional logic
7.**All existing functionality preserved** - zero breaking changes
### **🔍 Comprehensive Testing Recommendations**
1. **Registration Flow**: Test device registration with "deprecated" responses
2. **Token Refresh**: Verify token refresh works without legacy credentials
3. **Campaign Loading**: Confirm campaigns load successfully (should fix getCampaigns ERROR: -1)
4. **Network Requests**: Check that all API calls work with simplified authentication
5. **Signature Verification**: Ensure loyalty-signature header is always present
6. **Log Verification**: Ensure no more excessive credential warnings
### **📝 Migration Notes**
- **Backward Compatibility**: ✅ Maintained - no breaking changes
- **API Compatibility**: ✅ Preserved - all public methods unchanged
- **Authentication Method**: Updated from legacy credentials to merchant ID + access/refresh tokens
- **Error Handling**: Improved - no more false failures for missing legacy credentials
- **Security**: Enhanced - signature header always sent for proper authentication
- **Code Quality**: Improved - removed dead code and unnecessary conditional logic
---
......
......@@ -437,15 +437,8 @@ public final class WarplySDK {
/// Perform device registration during initialization
private func performDeviceRegistration() async throws {
// Check if we already have API key and web ID
let existingApiKey = UserDefaults.standard.string(forKey: "NBAPIKeyUD")
let existingWebId = UserDefaults.standard.string(forKey: "NBWebIDUD")
if let apiKey = existingApiKey, !apiKey.isEmpty,
let webId = existingWebId, !webId.isEmpty {
print("✅ [WarplySDK] Device already registered - API Key: \(apiKey.prefix(8))..., Web ID: \(webId)")
return
}
// Legacy credentials are deprecated - always proceed with registration if needed
// (The server will handle duplicate registrations gracefully)
print("🔄 [WarplySDK] Performing automatic device registration...")
......
......@@ -308,12 +308,11 @@ public final class NetworkService: NetworkServiceProtocol {
request.setValue("\(timestamp)", forHTTPHeaderField: "loyalty-date")
// Generate loyalty signature (apiKey + timestamp SHA256)
// Always generate signature, even with empty API key (server expects this header)
let apiKey = getApiKey()
if !apiKey.isEmpty {
let signatureString = "\(apiKey)\(timestamp)"
let signature = signatureString.sha256()
request.setValue(signature, forHTTPHeaderField: "loyalty-signature")
}
// Standard HTTP headers (always sent)
request.setValue("gzip", forHTTPHeaderField: "Accept-Encoding")
......