krz/domain-dig
an ios app for DNS & SSL analysis
clone: git clone https://gitbay.org/krz/domain-dig.git
v4.7.0: DomainDig/DataResetService.swift · raw
1import Foundation
2import Security
3
4enum DataResetService {
5 enum ResetError: LocalizedError {
6 case missingBundleIdentifier
7
8 var errorDescription: String? {
9 switch self {
10 case .missingBundleIdentifier:
11 "DomainDig could not determine its local storage identifier."
12 }
13 }
14 }
15
16 static func wipeAllLocalData(viewModel: DomainViewModel) async throws {
17 let secretReferences = await MainActor.run {
18 IntegrationService.shared.localSecretReferences() + LocalAPIService.shared.localSecretReferences()
19 }
20
21 try await Task.detached(priority: .userInitiated) {
22 try performPersistentWipe(secretReferences: secretReferences)
23 }.value
24
25 await LookupRuntime.shared.clearCache()
26 await LocalNotificationService.shared.clearAllNotifications()
27 await UsageCreditService.shared.resetForCurrentVersion()
28
29 await MainActor.run {
30 IntegrationService.shared.resetAfterLocalWipe()
31 LocalAPIService.shared.resetAfterLocalWipe()
32 CloudSyncService.shared.resetLocalStateAfterWipe()
33 PurchaseService.shared.resetCachedStateAfterLocalWipe()
34 _ = DomainMonitoringScheduler.shared.syncSchedule()
35 }
36
37 await viewModel.applyLocalDataReset()
38 }
39
40 private nonisolated static func performPersistentWipe(secretReferences: [String]) throws {
41 guard let bundleIdentifier = Bundle.main.bundleIdentifier else {
42 throw ResetError.missingBundleIdentifier
43 }
44
45 for reference in secretReferences {
46 deleteIntegrationSecret(reference: reference)
47 }
48
49 try removeTemporaryFiles()
50
51 let defaults = UserDefaults.standard
52 defaults.removePersistentDomain(forName: bundleIdentifier)
53 defaults.synchronize()
54 }
55
56 private nonisolated static func removeTemporaryFiles() throws {
57 let tempDirectory = FileManager.default.temporaryDirectory
58 let urls = try FileManager.default.contentsOfDirectory(
59 at: tempDirectory,
60 includingPropertiesForKeys: nil,
61 options: [.skipsHiddenFiles]
62 )
63
64 for url in urls {
65 try? FileManager.default.removeItem(at: url)
66 }
67 }
68
69 private nonisolated static func deleteIntegrationSecret(reference: String) {
70 let query: [String: Any] = [
71 kSecClass as String: kSecClassGenericPassword,
72 kSecAttrAccount as String: reference
73 ]
74
75 SecItemDelete(query as CFDictionary)
76 }
77}