- Add Apple Sign-In backend (JWKS verification, account linking, session management) - Implement push notification deep linking with NotificationDeepLinkRouter - Add jailbreak detection, runtime integrity monitoring, secure enclave service - Implement OAuth social login, token refresh, and secure logout flows - Add image caching (memory/disk), optimizer, upload queue, async semaphore - Implement notification analytics, type preferences, and category setup - Expand UI test suite with UITestBase, accessibility, auth flow, performance tests - Add CI pipeline for iOS UI tests (3 device sizes) and performance benchmarks - Restructure Xcode project to manual groups with KordantWidgets target - Add SwiftLint, Swift Collections/Algorithms/GoogleSignIn dependencies - Update project.yml for XcodeGen with new targets and configurations
106 lines
2.7 KiB
Swift
106 lines
2.7 KiB
Swift
import Foundation
|
|
|
|
/// Data model shared between the main app and widget extension via App Group UserDefaults.
|
|
struct WidgetData: Codable, Equatable {
|
|
let threatScore: Double
|
|
let recentAlerts: [WidgetAlert]
|
|
let alertCount: Int
|
|
let unreadCount: Int
|
|
let criticalCount: Int
|
|
let exposureCount: Int
|
|
let lastUpdated: Date
|
|
|
|
static let placeholder = WidgetData(
|
|
threatScore: 0.25,
|
|
recentAlerts: WidgetAlert.placeholders,
|
|
alertCount: 5,
|
|
unreadCount: 3,
|
|
criticalCount: 1,
|
|
exposureCount: 2,
|
|
lastUpdated: Date()
|
|
)
|
|
|
|
static let unavailable = WidgetData(
|
|
threatScore: 0,
|
|
recentAlerts: [],
|
|
alertCount: 0,
|
|
unreadCount: 0,
|
|
criticalCount: 0,
|
|
exposureCount: 0,
|
|
lastUpdated: Date()
|
|
)
|
|
|
|
var threatLevel: ThreatLevel {
|
|
let pct = threatScore
|
|
if pct >= 0.7 { return .critical }
|
|
if pct >= 0.4 { return .high }
|
|
if pct >= 0.2 { return .medium }
|
|
return .low
|
|
}
|
|
}
|
|
|
|
enum ThreatLevel: String, Codable {
|
|
case low, medium, high, critical
|
|
|
|
var label: String { rawValue.capitalized }
|
|
}
|
|
|
|
struct WidgetAlert: Codable, Identifiable, Equatable {
|
|
let id: String
|
|
let title: String
|
|
let message: String
|
|
let severity: String
|
|
let type: String
|
|
let createdAt: Date?
|
|
|
|
var severityEnum: AlertSeverity {
|
|
AlertSeverity(rawValue: severity) ?? .low
|
|
}
|
|
|
|
var typeEnum: AlertType {
|
|
AlertType(rawValue: type) ?? .exposure
|
|
}
|
|
|
|
static let placeholders: [WidgetAlert] = [
|
|
WidgetAlert(
|
|
id: "placeholder-1",
|
|
title: "Data Breach Detected",
|
|
message: "Your email was found in a recent data breach.",
|
|
severity: "critical",
|
|
type: "breach",
|
|
createdAt: Date()
|
|
),
|
|
WidgetAlert(
|
|
id: "placeholder-2",
|
|
title: "New Exposure Found",
|
|
message: "Personal information exposed on a public forum.",
|
|
severity: "high",
|
|
type: "exposure",
|
|
createdAt: Date().addingTimeInterval(-3600)
|
|
),
|
|
WidgetAlert(
|
|
id: "placeholder-3",
|
|
title: "Voice Match Detected",
|
|
message: "Suspicious call pattern flagged.",
|
|
severity: "medium",
|
|
type: "voiceMatch",
|
|
createdAt: Date().addingTimeInterval(-7200)
|
|
),
|
|
]
|
|
}
|
|
|
|
enum AlertSeverity: String, Codable {
|
|
case low = "low"
|
|
case medium = "medium"
|
|
case high = "high"
|
|
case critical = "critical"
|
|
}
|
|
|
|
enum AlertType: String, Codable {
|
|
case exposure = "exposure"
|
|
case breach = "breach"
|
|
case login = "login"
|
|
case voiceMatch = "voiceMatch"
|
|
case removal = "removal"
|
|
}
|