diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Database/DataBrokerProtectionDataManager.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Database/DataBrokerProtectionDataManager.swift index 857f174360..52eabbae92 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Database/DataBrokerProtectionDataManager.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Database/DataBrokerProtectionDataManager.swift @@ -290,4 +290,26 @@ extension InMemoryDataCache: DBPUICommunicationDelegate { return mapper.maintenanceScanState(brokerProfileQueryData) } + + func getDataBrokers() async -> [DBPUIDataBroker] { + brokerProfileQueryData + // 1. We get all brokers (in this list brokers are repeated) + .map { $0.dataBroker } + // 2. We map the brokers to the UI model + .flatMap { dataBroker -> [DBPUIDataBroker] in + var result: [DBPUIDataBroker] = [] + result.append(DBPUIDataBroker(name: dataBroker.name, url: dataBroker.url)) + + for mirrorSite in dataBroker.mirrorSites { + result.append(DBPUIDataBroker(name: mirrorSite.name, url: mirrorSite.url)) + } + return result + } + // 3. We delete duplicates + .reduce(into: [DBPUIDataBroker]()) { (result, dataBroker) in + if !result.contains(where: { $0.url == dataBroker.url }) { + result.append(dataBroker) + } + } + } } diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/DebugUI/DataBaseBrowser/DataBrokerDatabaseBrowserView.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/DebugUI/DataBaseBrowser/DataBrokerDatabaseBrowserView.swift index 18b5ffa6b6..fd09e77417 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/DebugUI/DataBaseBrowser/DataBrokerDatabaseBrowserView.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/DebugUI/DataBaseBrowser/DataBrokerDatabaseBrowserView.swift @@ -49,6 +49,7 @@ struct DatabaseView: View { @State private var isPopoverVisible = false @State private var selectedData: String = "" let data: [DataBrokerDatabaseBrowserData.Row] + let rowHeight: CGFloat = 40.0 var body: some View { if data.count > 0 { @@ -62,6 +63,11 @@ struct DatabaseView: View { } } + private func spacerHeight(_ geometry: GeometryProxy) -> CGFloat { + let result = geometry.size.height - CGFloat(data.count) * rowHeight + return max(0, result) + } + private func dataView() -> some View { GeometryReader { geometry in ScrollView([.horizontal, .vertical]) { @@ -86,7 +92,8 @@ struct DatabaseView: View { ForEach(row.data.keys.sorted(), id: \.self) { key in VStack { Text("\(row.data[key]?.description ?? "")") - .frame(maxWidth: 200, maxHeight: 50) + .frame(maxWidth: 200) + .frame(height: rowHeight) .frame(minWidth: 60) .onTapGesture { selectedData = row.data[key]?.description ?? "" @@ -100,7 +107,8 @@ struct DatabaseView: View { } } } - Spacer(minLength: geometry.size.height) + Spacer() + .frame(height: spacerHeight(geometry)) } .frame(minWidth: geometry.size.width, minHeight: 0, alignment: .topLeading) } diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DBPUICommunicationModel.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DBPUICommunicationModel.swift index 353e3912df..5f242b34a2 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DBPUICommunicationModel.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DBPUICommunicationModel.swift @@ -103,12 +103,24 @@ struct DBPUIAddressAtIndex: Codable { /// Message Object representing a data broker struct DBPUIDataBroker: Codable, Hashable { let name: String + let url: String + let date: Double? + + init(name: String, url: String, date: Double? = nil) { + self.name = name + self.url = url + self.date = date + } func hash(into hasher: inout Hasher) { hasher.combine(name) } } +struct DBPUIDataBrokerList: DBPUISendableMessage { + let dataBrokers: [DBPUIDataBroker] +} + /// Message Object representing a requested change to the user profile's brith year struct DBPUIBirthYear: Codable { let year: Int @@ -123,6 +135,7 @@ struct DBPUIDataBrokerProfileMatch: Codable { let addresses: [DBPUIUserProfileAddress] let alternativeNames: [String] let relatives: [String] + let date: Double? // Used in some methods to set the removedDate or found date } /// Protocol to represent a message that can be passed from the host to the UI @@ -139,6 +152,10 @@ struct DBPUIScanAndOptOutMaintenanceState: DBPUISendableMessage { struct DBPUIOptOutMatch: DBPUISendableMessage { let dataBroker: DBPUIDataBroker let matches: Int + let name: String + let alternativeNames: [String] + let addresses: [DBPUIUserProfileAddress] + let date: Double } /// Data representing the initial scan progress diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DataBroker.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DataBroker.swift index fb96638206..e1a17f590b 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DataBroker.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/DataBroker.swift @@ -32,13 +32,46 @@ extension Int { struct MirrorSite: Codable, Sendable { let name: String + let url: String let addedAt: Date let removedAt: Date? + + enum CodingKeys: CodingKey { + case name + case url + case addedAt + case removedAt + } + + init(name: String, url: String, addedAt: Date, removedAt: Date? = nil) { + self.name = name + self.url = url + self.addedAt = addedAt + self.removedAt = removedAt + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + name = try container.decode(String.self, forKey: .name) + + // The older versions of the JSON file did not have a URL property. + // When decoding those cases, we fallback to its name, since the name was the URL. + do { + url = try container.decode(String.self, forKey: .url) + } catch { + url = name + } + + addedAt = try container.decode(Date.self, forKey: .addedAt) + removedAt = try? container.decode(Date.self, forKey: .removedAt) + + } } struct DataBroker: Codable, Sendable { let id: Int64? let name: String + let url: String let steps: [Step] let version: String let schedulingConfig: DataBrokerScheduleConfig @@ -51,6 +84,7 @@ struct DataBroker: Codable, Sendable { enum CodingKeys: CodingKey { case name + case url case steps case version case schedulingConfig @@ -60,6 +94,7 @@ struct DataBroker: Codable, Sendable { init(id: Int64? = nil, name: String, + url: String, steps: [Step], version: String, schedulingConfig: DataBrokerScheduleConfig, @@ -68,6 +103,13 @@ struct DataBroker: Codable, Sendable { ) { self.id = id self.name = name + + if url.isEmpty { + self.url = name + } else { + self.url = url + } + self.steps = steps self.version = version self.schedulingConfig = schedulingConfig @@ -78,6 +120,15 @@ struct DataBroker: Codable, Sendable { init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) name = try container.decode(String.self, forKey: .name) + + // The older versions of the JSON file did not have a URL property. + // When decoding those cases, we fallback to its name, since the name was the URL. + do { + url = try container.decode(String.self, forKey: .url) + } catch { + url = name + } + version = try container.decode(String.self, forKey: .version) steps = try container.decode([Step].self, forKey: .steps) schedulingConfig = try container.decode(DataBrokerScheduleConfig.self, forKey: .schedulingConfig) diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerOperation.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerOperation.swift index 5777596838..37cd385e4e 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerOperation.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerOperation.swift @@ -99,7 +99,7 @@ extension DataBrokerOperation { if action.needsEmail { do { stageCalculator?.setStage(.emailGenerate) - extractedProfile?.email = try await emailService.getEmail(dataBrokerName: query.dataBroker.name) + extractedProfile?.email = try await emailService.getEmail(dataBrokerURL: query.dataBroker.url) stageCalculator?.fireOptOutEmailGenerate() } catch { await onError(error: DataBrokerProtectionError.emailError(error as? EmailError)) diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerProtectionBrokerUpdater.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerProtectionBrokerUpdater.swift index 28c2128a00..f3203334e2 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerProtectionBrokerUpdater.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Operations/DataBrokerProtectionBrokerUpdater.swift @@ -152,7 +152,7 @@ public struct DataBrokerProtectionBrokerUpdater { // 2. If does exist, we check the number version, if the version number is new, we update it // 3. If it does not exist, we add it, and we create the scan operations related to it private func update(_ broker: DataBroker) throws { - guard let savedBroker = try vault.fetchBroker(with: broker.name) else { + guard let savedBroker = try vault.fetchBroker(with: broker.url) else { // The broker does not exist in the current storage. We need to add it. try add(broker) return diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/advancedbackgroundchecks.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/advancedbackgroundchecks.com.json index 60823c78ac..ee35af6d17 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/advancedbackgroundchecks.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/advancedbackgroundchecks.com.json @@ -1,8 +1,9 @@ { - "name": "advancedbackgroundchecks.com", - "version": "0.1.0", + "name": "AdvancedBackgroundChecks", + "url": "advancedbackgroundchecks.com", + "version": "0.1.4", "parent": "peoplefinders.com", - "addedDatetime": 1678078800000, + "addedDatetime": 1678082400000, "steps": [ { "stepType": "scan", @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "ef8031e6-5e61-4183-b57e-7df156c7129a", + "id": "c73ba931-9e01-4d37-9e15-2fd7a14eefa3", "url": "https://www.advancedbackgroundchecks.com/names/${firstName}-${lastName}_${city}-${state}_age_${age}" }, { "actionType": "extract", - "id": "f3ed744c-6cfc-4a99-b46e-6095587eadfc", + "id": "94003082-0a9d-4418-ac88-68595c7f4953", "selector": ".card-block", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/backgroundcheck.run.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/backgroundcheck.run.json index 5b3800cfcf..552923ca1f 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/backgroundcheck.run.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/backgroundcheck.run.json @@ -1,6 +1,7 @@ { "name": "backgroundcheck.run", - "version": "0.1.1", + "url": "backgroundcheck.run", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1677736800000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "aa12b430-8e5d-4c64-bb77-2961f19a1bc8", + "id": "5f90e39f-cb94-4b8d-94ed-48ba0060dc08", "url": "https://backgroundcheck.run/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}" }, { "actionType": "extract", - "id": "75fd2e16-d84a-4bbe-9cf1-79c6d1cc4dec", + "id": "3225fa15-4e00-4e6a-bfc7-a85dfb504c86", "selector": ".b-pfl-list", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/centeda.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/centeda.com.json index 130c996369..bb15f0093f 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/centeda.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/centeda.com.json @@ -1,8 +1,9 @@ { - "name": "centeda.com", - "version": "0.1.1", + "name": "Centeda", + "url": "centeda.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1677733200000, + "addedDatetime": 1677736800000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "25990359-3d58-45de-bdfd-d524b1946e57", + "id": "2f6639c0-201f-4d5e-8467-ae0ba457b409", "url": "https://centeda.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "7108af78-dbbf-47ec-8bb9-e44be505993e", + "id": "e2e236b0-515b-43b3-9154-0432ed9b7566", "selector": ".search-item", "profile": { "name": { @@ -63,4 +64,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clubset.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clubset.com.json index f871133c15..8b6801fc48 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clubset.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clubset.com.json @@ -1,6 +1,7 @@ { - "name": "clubset.com", - "version": "0.1.1", + "name": "Clubset", + "url": "clubset.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1702965600000, "steps": [ @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "917f5d40-2011-4fe5-9ef6-136d6bfaea35", + "id": "5c559c67-c13c-4055-a318-6ba35d62a2cf", "url": "https://clubset.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state|upcase}&city=${city|capitalize}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "06e37215-ef34-4971-bf86-e5a03dfe46e8", + "id": "866bdfc5-069e-4734-9ce0-a19976fa796b", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clustrmaps.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clustrmaps.com.json index 0aca895c02..4c2bd20999 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clustrmaps.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/clustrmaps.com.json @@ -1,8 +1,9 @@ { - "name": "clustrmaps.com", - "version": "0.1.1", + "name": "ClustrMaps", + "url": "clustrmaps.com", + "version": "0.1.4", "parent": "neighbor.report", - "addedDatetime": 1692590400000, + "addedDatetime": 1692594000000, "steps": [ { "stepType": "scan", @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "a39655de-5c23-477d-9887-1d34966a1069", + "id": "e6929e37-4764-450a-be2a-73479f11842a", "url": "https://clustrmaps.com/persons/${firstName}-${lastName}/${state|stateFull|capitalize}/${city|hyphenated}" }, { "actionType": "extract", - "id": "4e3a628e-3634-4a2b-b632-4fbb8ce0b52b", + "id": "06f39df7-89c2-40da-b288-cdf3ed0e4bfd", "selector": ".//div[@itemprop='Person']", "profile": { "name": { @@ -55,4 +56,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/councilon.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/councilon.com.json index d68f6b9f4c..3df8d7f195 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/councilon.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/councilon.com.json @@ -1,6 +1,7 @@ { - "name": "councilon.com", - "version": "0.1.1", + "name": "Councilon", + "url": "councilon.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1702965600000, "steps": [ @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "295418e5-e1da-43b4-af50-75576ca4f843", + "id": "a5052dda-d4e7-4d3f-97bc-ef9f0aa9ae5f", "url": "https://councilon.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "eead1b72-7d6b-4cdc-988d-5ea66eb398f1", + "id": "55a50a37-9b1b-40fa-8533-af1273a26258", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/curadvisor.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/curadvisor.com.json index 33f27d0c79..3b59ed585e 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/curadvisor.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/curadvisor.com.json @@ -1,8 +1,9 @@ { - "name": "curadvisor.com", - "version": "0.1.1", + "name": "CurAdvisor", + "url": "curadvisor.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1677736800000, + "addedDatetime": 1703052000000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "bdb69f52-8ece-4d65-9b78-543fef0e90ae", + "id": "ab5503c7-bd11-4320-b38e-c637b239182e", "url": "https://curadvisor.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "3b9bc992-ecc0-4dc5-b716-fcea021cbcdb", + "id": "d273c1cf-2635-40d7-b26f-6f34467282cf", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/cyberbackgroundchecks.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/cyberbackgroundchecks.com.json index e27b744790..f930834db9 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/cyberbackgroundchecks.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/cyberbackgroundchecks.com.json @@ -1,6 +1,7 @@ { - "name": "cyberbackgroundchecks.com", - "version": "0.1.1", + "name": "Cyber Background Checks", + "url": "cyberbackgroundchecks.com", + "version": "0.1.4", "parent": "peoplefinders.com", "addedDatetime": 1705644000000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "4b7037f3-9c6a-42b5-929e-621256e0a044", + "id": "d8c84470-d8b3-4c46-a645-01cc6b139b3b", "url": "https://www.cyberbackgroundchecks.com/people/${firstName}-${lastName}/${state}/${city}" }, { "actionType": "extract", - "id": "f36a73d7-9efb-452e-8c60-6d9df2964bcf", + "id": "b4c12cf2-0fd6-4209-8816-3bf2cce23cde", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/dataveria.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/dataveria.com.json index 3dfe8e5431..9949e04675 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/dataveria.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/dataveria.com.json @@ -1,8 +1,9 @@ { - "name": "dataveria.com", - "version": "0.1.1", + "name": "Dataveria", + "url": "dataveria.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1677733200000, + "addedDatetime": 1677736800000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "fc449310-7b7b-45d4-bcf9-0c5d51c246f8", + "id": "a8f3a259-2d39-4ae3-ac13-65aa63a53331", "url": "https://dataveria.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "0481dc49-43e8-4af0-b697-680fb57ec24b", + "id": "e810cc23-2d2a-4e6e-b06f-dfc8a2e1e85d", "selector": ".search-item", "profile": { "name": { @@ -64,4 +65,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/fastbackgroundcheck.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/fastbackgroundcheck.com.json index 4462e0c86d..9c1129a333 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/fastbackgroundcheck.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/fastbackgroundcheck.com.json @@ -1,8 +1,9 @@ { - "name": "fastbackgroundcheck.com", - "version": "0.1.1", + "name": "FastBackgroundCheck.com", + "url": "fastbackgroundcheck.com", + "version": "0.1.4", "parent": "peoplefinders.com", - "addedDatetime": 1678082400000, + "addedDatetime": 1706248800000, "steps": [ { "stepType": "scan", @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "2a3a5979-9de0-44b2-ae03-f25422f0c2aa", + "id": "997adf8d-023c-409e-9206-57871cd25f0a", "url": "https://www.fastbackgroundcheck.com/people/${firstName}-${lastName}/${city}-${state}" }, { "actionType": "extract", - "id": "4818ff1c-d419-44c2-8168-501b456c6c6a", + "id": "2f531e34-2ac0-4743-a760-065187d6c951", "selector": ".person-container", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/freepeopledirectory.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/freepeopledirectory.com.json index 2c215abdf6..c448989448 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/freepeopledirectory.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/freepeopledirectory.com.json @@ -1,6 +1,7 @@ { - "name": "freepeopledirectory.com", - "version": "0.1.1", + "name": "FreePeopleDirectory", + "url": "freepeopledirectory.com", + "version": "0.1.4", "parent": "spokeo.com", "addedDatetime": 1674540000000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "815a1cd3-2577-4f43-a163-0cf4d22e66a4", + "id": "4c607417-36bc-47d4-8562-9c2244db354d", "url": "https://www.freepeopledirectory.com/name/${firstName}-${lastName}/${state|upcase}/${city}" }, { "actionType": "extract", - "id": "10738ba0-bc6b-42ba-a37c-487ff3927dd5", + "id": "a1637310-ca7a-40b0-b2f5-db22b43b5d54", "selector": ".whole-card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/inforver.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/inforver.com.json index 961bb83ae3..2c035a980c 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/inforver.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/inforver.com.json @@ -1,8 +1,9 @@ { - "name": "inforver.com", - "version": "0.1.1", + "name": "Inforver", + "url": "inforver.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1677733200000, + "addedDatetime": 1677736800000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "a56ab792-fc1b-4e60-b0b9-0bd4f580476f", + "id": "85fac850-36ad-4d9c-ad7c-c1250c7b5585", "url": "https://inforver.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "591ba784-106c-421b-b188-a376f1f9cb01", + "id": "e5e9c1b0-4af4-4fb6-bd2d-7d026ffd95e7", "selector": ".search-item", "profile": { "name": { @@ -64,4 +65,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/kwold.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/kwold.com.json index 31b5dc20a8..5f7e750909 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/kwold.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/kwold.com.json @@ -1,6 +1,7 @@ { - "name": "kwold.com", - "version": "0.1.1", + "name": "Kwold", + "url": "kwold.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1702965600000, "steps": [ @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "47152fc1-79d5-4bcc-b930-6b5cdc66e972", + "id": "936eee30-d31e-48fb-8cc4-9391869934b9", "url": "https://kwold.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "50507ab4-2e75-4f1d-af23-9725b9955bc3", + "id": "870ee174-275a-4ea8-b2d7-a222418e5de9", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/neighbor.report.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/neighbor.report.json index d640212852..92a0d2af57 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/neighbor.report.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/neighbor.report.json @@ -1,7 +1,8 @@ { - "name": "neighbor.report", + "name": "Neighbor Report", + "url": "neighbor.report", "version": "0.1.4", - "addedDatetime": 1703559600000, + "addedDatetime": 1703570400000, "steps": [ { "stepType": "scan", @@ -9,12 +10,12 @@ "actions": [ { "actionType": "navigate", - "id": "a554d7d2-f348-487a-97de-8d4f0d1d35c0", + "id": "bbaf8a18-fef8-42a6-9682-747b8ff485b2", "url": "https://neighbor.report/${firstName}-${lastName}/${state|stateFull|hyphenated}/${city|hyphenated}" }, { "actionType": "extract", - "id": "17f80250-1e3c-4e55-8e50-68fe98a6ce23", + "id": "0dac4a6d-1291-47c3-97b8-56200f751ac8", "selector": ".lstd", "profile": { "name": { @@ -50,12 +51,12 @@ "actions": [ { "actionType": "navigate", - "id": "59cc488d-e317-4fb4-8aaa-a20cb71f7480", + "id": "b1f7f4ab-51b0-4885-ba73-97be0822d0ba", "url": "https://neighbor.report/remove" }, { "actionType": "fillForm", - "id": "3a4c1775-941a-4f48-873d-c780f5ea25a0", + "id": "743afa6c-7dea-4115-934b-bea369307acd", "selector": ".form-horizontal", "elements": [ { @@ -74,17 +75,17 @@ }, { "actionType": "getCaptchaInfo", - "id": "f470e245-d5ee-4908-bd6c-16e604a1a29b", + "id": "24ce0da0-7cc3-47e7-bf8e-6f5fe98b7a91", "selector": ".recaptcha-div" }, { "actionType": "solveCaptcha", - "id": "7f0a8fc6-32a3-4f4a-b61d-267f9666de91", + "id": "b720de9a-f519-466f-980d-d9c52d8870a2", "selector": ".recaptcha-div" }, { "actionType": "click", - "id": "7fbc5a97-bc57-41bc-a556-0fdfd8a0845d", + "id": "46690938-f112-4091-bd07-b5641e38151f", "elements": [ { "type": "button", @@ -94,7 +95,7 @@ }, { "actionType": "click", - "id": "d1513f65-a746-4597-9ed2-4cd5e40dead3", + "id": "07cfed17-9d75-471a-b6a0-0522add35ffa", "elements": [ { "type": "button", @@ -108,7 +109,7 @@ }, { "actionType": "expectation", - "id": "8acd9c96-443d-4593-a3a7-9efc9fd5070a", + "id": "ebd61347-60e1-4c19-bc41-dd1ce36d3138", "expectations": [ { "type": "text", @@ -125,4 +126,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/newenglandfacts.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/newenglandfacts.com.json index ddb83134f9..54f8d23ac8 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/newenglandfacts.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/newenglandfacts.com.json @@ -1,6 +1,7 @@ { - "name": "newenglandfacts.com", - "version": "0.1.1", + "name": "New England Facts", + "url": "newenglandfacts.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1703052000000, "steps": [ @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "8bd7953c-ee22-49be-8937-a1798046a0c1", + "id": "05725a5a-ec3f-49c8-875b-ab9787b9385f", "url": "https://newenglandfacts.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "4012d312-2f7f-4cc1-bf7a-b7655f550c1a", + "id": "7f41b78a-bb65-4bb2-a6ca-1a6ab55890ce", "selector": ".b-pfl-list", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/officialusa.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/officialusa.com.json index a7b4efd714..9cb63483be 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/officialusa.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/officialusa.com.json @@ -1,8 +1,9 @@ { - "name": "officialusa.com", - "version": "0.1.0", + "name": "OfficialUSA", + "url": "officialusa.com", + "version": "0.1.4", "parent": "neighbor.report", - "addedDatetime": 1692590400000, + "addedDatetime": 1692594000000, "steps": [ { "stepType": "scan", @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "dad25b4c-743b-4bca-a395-05f1e76ef5c9", + "id": "b430e29e-89f0-4994-96b2-08d0cbdc388c", "url": "https://officialusa.com/names/${firstName}-${lastName}/" }, { "actionType": "extract", - "id": "b867d570-6124-40d9-9076-7ee0fa5b4d68", + "id": "d989f3b7-9b8a-44a6-a51e-70762255f3fc", "selector": ".person", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/people-background-check.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/people-background-check.com.json index 7b1d26eb38..b8550c93e4 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/people-background-check.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/people-background-check.com.json @@ -1,6 +1,7 @@ { - "name": "people-background-check.com", - "version": "0.1.1", + "name": "People Background Check", + "url": "people-background-check.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1702965600000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "18e35c3b-b837-40e9-b353-20230d36bc4d", + "id": "6fee90c5-5f7e-4fd0-badf-069e2b94a65d", "url": "https://people-background-check.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}" }, { "actionType": "extract", - "id": "7a23b927-acfc-4d29-b4b6-3f204687619c", + "id": "ee03ba42-e9a5-4489-a7d6-d50bf21238aa", "selector": ".b-pfl-list", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplefinders.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplefinders.com.json index 7e690167c8..34bc5b8770 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplefinders.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplefinders.com.json @@ -1,7 +1,8 @@ { - "name": "peoplefinders.com", - "version": "0.1.0", - "addedDatetime": 1677128400000, + "name": "PeopleFinders", + "url": "peoplefinders.com", + "version": "0.1.4", + "addedDatetime": 1677132000000, "steps": [ { "stepType": "scan", @@ -9,12 +10,12 @@ "actions": [ { "actionType": "navigate", - "id": "aafba5bd-a157-4e35-b653-0797a732d94c", + "id": "71c7cb2f-14fe-43b8-9623-452b8bd10d4e", "url": "https://www.peoplefinders.com/people/${firstName}-${lastName}/${state}/${city}?landing=all&age=${age}" }, { "actionType": "extract", - "id": "b8f10f20-3363-4781-a03b-c4958b6269c7", + "id": "5c5af912-091f-4f48-922f-ba554951ddd9", "selector": ".record", "profile": { "name": { @@ -48,12 +49,12 @@ "actions": [ { "actionType": "navigate", - "id": "f5fbd4f5-23f7-45ed-a9ce-3e9b0a5a7a0a", + "id": "4b065fde-35c7-43d7-aed6-3abcdac94f08", "url": "https://www.peoplefinders.com/opt-out" }, { "actionType": "click", - "id": "7b33cd1b-3948-4454-8434-e703cc235123", + "id": "b5c0929e-e362-4570-815b-0433ef97fddf", "elements": [ { "type": "button", @@ -63,7 +64,7 @@ }, { "actionType": "fillForm", - "id": "32056b7a-dc80-4d5d-b9cc-dccd32cb56be", + "id": "2fb91804-e5ea-414e-9354-fba98f3c00e1", "selector": ".opt-out-form", "elements": [ { @@ -78,17 +79,17 @@ }, { "actionType": "getCaptchaInfo", - "id": "5d5068aa-5c16-4fdc-8f3b-e412ad4eabed", + "id": "4b9706ef-dd9b-47d6-b337-12f66a5f9138", "selector": ".g-recaptcha" }, { "actionType": "solveCaptcha", - "id": "3443e060-8aee-4bd0-ab2c-ea03f8b8f93c", + "id": "770019d3-fa88-400a-8480-7cc31d6b3382", "selector": ".g-recaptcha" }, { "actionType": "click", - "id": "cb9ef5b0-0155-42f1-a766-145b3c14586b", + "id": "a7285f44-6c99-44b1-8199-eb6c383fe12b", "elements": [ { "type": "button", @@ -98,22 +99,22 @@ }, { "actionType": "emailConfirmation", - "id": "5cc7cfa5-e8ab-4dc1-b58b-973af3d3f364", + "id": "05cc08ea-fb80-40fb-8cce-3ca674eea03b", "pollingTime": 30 }, { "actionType": "getCaptchaInfo", - "id": "3a44c15d-1dd0-4e92-beba-bf3d8544c6e9", + "id": "8cb4256a-b162-407f-8434-5536c7560c98", "selector": ".g-recaptcha" }, { "actionType": "solveCaptcha", - "id": "d2566371-8b02-4414-9a24-1f9d2761eb1d", + "id": "38c64eec-6bd9-4751-a7cf-8cbe9901b0f6", "selector": ".g-recaptcha" }, { "actionType": "click", - "id": "259d8895-ac58-46b0-a209-7f209171e13c", + "id": "d1d25423-912b-4828-825b-eb83809ada08", "elements": [ { "type": "button", @@ -123,7 +124,7 @@ }, { "actionType": "expectation", - "id": "ed02f55b-67b3-4efc-a3cc-ce6b6c7ceeed", + "id": "fdb755da-8970-426f-b09e-12165c2169dd", "expectations": [ { "type": "url", @@ -139,4 +140,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplesearchnow.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplesearchnow.com.json index 6e477c6e13..6189f3d311 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplesearchnow.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/peoplesearchnow.com.json @@ -1,6 +1,7 @@ { - "name": "peoplesearchnow.com", - "version": "0.1.1", + "name": "People Search Now", + "url": "peoplesearchnow.com", + "version": "0.1.4", "parent": "peoplefinders.com", "addedDatetime": 1705989600000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "b6994b26-9904-407b-9bcf-0fd6f809771d", + "id": "db9e093d-68c2-45e1-a529-29a2dc67dfab", "url": "https://peoplesearchnow.com/person/${firstName}-${lastName}_${city}_${state}/" }, { "actionType": "extract", - "id": "4e7f0e9a-1d24-47c0-886f-a08d88074878", + "id": "78912133-761b-4971-9780-4e16c8dd43b2", "selector": ".result-search-block", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/pub360.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/pub360.com.json index 503392f378..815fdcb8fc 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/pub360.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/pub360.com.json @@ -1,8 +1,9 @@ { - "name": "pub360.com", - "version": "0.1.1", + "name": "Pub360", + "url": "pub360.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1677733200000, + "addedDatetime": 1677736800000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "72fc91c4-e8bc-4656-8260-cd3bb15e2001", + "id": "8e2a1251-2685-476a-b4c1-53d138331abe", "url": "https://pub360.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "2cb4778d-e3d6-4432-8421-84438c280e19", + "id": "9ce62e6f-b103-45f6-9f92-56785eb22320", "selector": ".search-item", "profile": { "name": { @@ -64,4 +65,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/publicreports.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/publicreports.com.json index 991d4d2b2c..5ea3d241e4 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/publicreports.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/publicreports.com.json @@ -1,6 +1,7 @@ { - "name": "publicreports.com", - "version": "0.1.1", + "name": "PublicReports", + "url": "publicreports.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1703052000000, "steps": [ @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "ae0104a2-a75c-4d97-bada-dda4f21dd446", + "id": "b995b1bf-6610-4085-9d07-d38857807535", "url": "https://publicreports.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "388c55e3-fa12-4376-9a02-01190b8a30fd", + "id": "7fb121fb-e2a0-4fa2-9b97-51130104971c", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/quickpeopletrace.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/quickpeopletrace.com.json index 7409fd240b..e8b18f9ec8 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/quickpeopletrace.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/quickpeopletrace.com.json @@ -1,6 +1,7 @@ { - "name": "quickpeopletrace.com", - "version": "0.1.1", + "name": "Quick People Trace", + "url": "quickpeopletrace.com", + "version": "0.1.4", "parent": "peoplefinders.com", "addedDatetime": 1674540000000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "45443ab2-7563-4c7d-8bf2-b1b550f4b825", + "id": "2db8c120-a8c3-4aa0-a9ce-b075ca85fc68", "url": "https://www.quickpeopletrace.com/search/?addresssearch=1&tabid=1&teaser-firstname=${firstName}&teaser-middlename=&teaser-lastname=${lastName}&teaser-city=${city}&teaser-state=${state|upcase}&teaser-submitted=Search" }, { "actionType": "extract", - "id": "08607047-96e8-4fbb-9af9-bf7b8e163b20", + "id": "bd48b737-89c4-408a-a28c-2dfa828aebd8", "selector": "//table/tbody/tr[position() > 1]", "profile": { "name": { @@ -24,9 +25,6 @@ "age": { "selector": ".//td[3]" }, - "addressCityState": { - "selector": ".//td[4]/strong" - }, "addressCityStateList": { "selector": ".//td[4]" }, diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/searchpeoplefree.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/searchpeoplefree.com.json index 535ec0f63d..4a68c912e3 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/searchpeoplefree.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/searchpeoplefree.com.json @@ -1,6 +1,7 @@ { - "name": "searchpeoplefree.com", - "version": "0.1.1", + "name": "Search People FREE", + "url": "searchpeoplefree.com", + "version": "0.1.4", "parent": "peoplefinders.com", "addedDatetime": 1703052000000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "2b537ff2-8967-465c-ad5c-c4c2d31f60e1", + "id": "f5bad072-6f55-4357-b23b-1df4c9584e67", "url": "https://searchpeoplefree.com/find/${firstName}-${lastName}/${state}/${city}" }, { "actionType": "extract", - "id": "70728718-fe02-43f6-b86f-6d6c6bbbf009", + "id": "749fb8fe-9994-41e2-a0ea-ae6334c5aee0", "selector": "//li[@class='toc l-i mb-5']", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/smartbackgroundchecks.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/smartbackgroundchecks.com.json index 31424db72d..23f588c796 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/smartbackgroundchecks.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/smartbackgroundchecks.com.json @@ -1,6 +1,7 @@ { - "name": "smartbackgroundchecks.com", - "version": "0.1.1", + "name": "SmartBackgroundChecks", + "url": "smartbackgroundchecks.com", + "version": "0.1.4", "parent": "peoplefinders.com", "addedDatetime": 1678082400000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "97b307c8-e3e4-4090-a6ab-c5eeb599d248", + "id": "1c6bdc6e-12dd-47db-b5b0-13055c1f3d5d", "url": "https://www.smartbackgroundchecks.com/people/${firstName}-${lastName}/${city}/${state}" }, { "actionType": "extract", - "id": "ca20a933-b703-427e-8cbf-e2f25cd763a6", + "id": "ac554b4f-e4a0-44c5-81a6-c04e46e4ce3b", "selector": ".card-block", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/spokeo.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/spokeo.com.json index 2618099829..3c0f0008f8 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/spokeo.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/spokeo.com.json @@ -1,12 +1,33 @@ { - "name": "spokeo.com", - "version": "0.1.3", + "name": "Spokeo", + "url": "spokeo.com", + "version": "0.1.4", "addedDatetime": 1692594000000, "mirrorSites": [ - { "name": "callersmart.com", "addedAt": 1705599286529, "removedAt": null }, - { "name": "selfie.network", "addedAt": 1705599286529, "removedAt": null }, - { "name": "selfie.systems", "addedAt": 1705599286529, "removedAt": null }, - { "name": "peoplewin.com", "addedAt": 1705599286529, "removedAt": null } + { + "name": "CallerSmart", + "url": "callersmart.com", + "addedAt": 1705599286529, + "removedAt": null + }, + { + "name": "Selfie Network", + "url": "selfie.network", + "addedAt": 1705599286529, + "removedAt": null + }, + { + "name": "Selfie Systems", + "url": "selfie.systems", + "addedAt": 1705599286529, + "removedAt": null + }, + { + "name": "PeopleWin", + "url": "peoplewin.com", + "addedAt": 1705599286529, + "removedAt": null + } ], "steps": [ { @@ -15,12 +36,12 @@ "actions": [ { "actionType": "navigate", - "id": "d3174bd8-3253-45e3-88f0-1366882a2df7", + "id": "9b617d27-b330-46fc-bdb0-6239c0873897", "url": "https://www.spokeo.com/${firstName}-${lastName}/${state|stateFull}/${city}" }, { "actionType": "extract", - "id": "e47f5f27-dfbf-4f2c-8d7a-43f581abdaa2", + "id": "4f7124c2-bd8c-4649-84f2-04f0962225b5", "selector": ".single-column-list-item", "profile": { "name": { @@ -52,12 +73,12 @@ "actions": [ { "actionType": "navigate", - "id": "dba8f444-a433-4ad2-9819-3c555bfedd9c", + "id": "df75e4fb-f14b-4b65-afe2-82e03b71c6a9", "url": "https://www.spokeo.com/optout" }, { "actionType": "fillForm", - "id": "b1145fca-3e35-4ee9-86f2-e35c393846d3", + "id": "42cbfc2b-d96b-4bd6-8d16-0542a672d869", "selector": ".optout_container", "elements": [ { @@ -72,17 +93,17 @@ }, { "actionType": "getCaptchaInfo", - "id": "8f9608b4-bbf7-4540-8b22-5c381225cd02", + "id": "e1581b9e-7460-4bbd-a010-634c2db12ca1", "selector": "#g-recaptcha" }, { "actionType": "solveCaptcha", - "id": "a5a884b8-12f6-4029-aa80-244f1a163f67", + "id": "01ca39d9-e842-41cf-b0f9-a7d517bc0dd6", "selector": "#g-recaptcha" }, { "actionType": "click", - "id": "a7d4fdd4-30b8-46f7-8700-67c633da1f91", + "id": "7556edd5-570b-4c4a-acc7-f1066138d513", "elements": [ { "type": "button", @@ -92,7 +113,7 @@ }, { "actionType": "expectation", - "id": "d4a804a3-de62-4f66-a56e-e9d7e65fb8bb", + "id": "f7b5125e-0dda-4a14-8943-8c20c09125bc", "expectations": [ { "type": "text", @@ -103,12 +124,12 @@ }, { "actionType": "emailConfirmation", - "id": "5138062c-99d3-4523-b222-8123b13bc524", + "id": "dbd875b6-bdc7-48ca-962b-885941e6284a", "pollingTime": 30 }, { "actionType": "expectation", - "id": "cc14f3ea-35f8-4d31-a280-dc97526de12a", + "id": "b2f1c371-d779-4b3b-8516-0d13169cf873", "expectations": [ { "type": "text", @@ -125,4 +146,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/truepeoplesearch.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/truepeoplesearch.com.json index 84d468f943..a226c959a0 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/truepeoplesearch.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/truepeoplesearch.com.json @@ -1,6 +1,7 @@ { - "name": "truepeoplesearch.com", - "version": "0.1.1", + "name": "TruePeopleSearch", + "url": "truepeoplesearch.com", + "version": "0.1.4", "parent": "peoplefinders.com", "addedDatetime": 1703138400000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "4b7d8751-d3cd-4e4b-b2a2-66219eb6a8e8", + "id": "12eb70c1-53d5-4881-9dce-74ed4fada583", "url": "https://www.truepeoplesearch.com/results?name=${firstName}%20${lastName}&citystatezip=${city|capitalize},${state|upcase}" }, { "actionType": "extract", - "id": "cdb5940a-8505-4b28-9699-d98235e1fff1", + "id": "881e0e21-c375-4083-a9be-86f82063849b", "selector": ".card-summary", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usa-people-search.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usa-people-search.com.json index 71c8e711ed..b8fba84277 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usa-people-search.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usa-people-search.com.json @@ -1,8 +1,9 @@ { - "name": "usa-people-search.com", - "version": "0.1.1", + "name": "USA People Search", + "url": "usa-people-search.com", + "version": "0.1.4", "parent": "peoplefinders.com", - "addedDatetime": 1678078800000, + "addedDatetime": 1678082400000, "steps": [ { "stepType": "scan", @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "2c4b31a3-661b-4f30-a4d3-b5a4a13c95db", + "id": "67e80e69-f542-4714-8705-c43af630ac72", "url": "https://usa-people-search.com/name/${firstName|downcase}-${lastName|downcase}/${city|downcase}-${state|stateFull|downcase}?age=${age}" }, { "actionType": "extract", - "id": "20a4d510-56b6-46a8-92ce-be16ed3ce049", + "id": "c0a82b15-7564-4e12-8c4e-084174242623", "selector": ".card-block", "profile": { "name": { @@ -62,4 +63,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usatrace.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usatrace.com.json index 412a14d7d9..4645c85dd0 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usatrace.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usatrace.com.json @@ -1,6 +1,7 @@ { - "name": "usatrace.com", - "version": "0.1.1", + "name": "USA Trace", + "url": "usatrace.com", + "version": "0.1.4", "parent": "peoplefinders.com", "addedDatetime": 1674540000000, "steps": [ @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "5071e480-88ae-49b5-91b6-1daf26c55acf", + "id": "17217b04-28ae-4262-aa33-ee3695bb6bd6", "url": "https://www.usatrace.com/people-search/${firstName}-${lastName}/${city}-${state|upcase}" }, { "actionType": "extract", - "id": "3237fc09-247c-4942-9920-9bbb937f6ac2", + "id": "426d8e8a-2f32-46f3-9d1d-e7f6e2fddadb", "selector": "//table/tbody/tr[position() > 1]", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usphonebook.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usphonebook.com.json index 0770b2f474..5aff073d4a 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usphonebook.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/usphonebook.com.json @@ -1,8 +1,9 @@ { - "name": "usphonebook.com", - "version": "0.1.1", + "name": "USPhoneBook", + "url": "usphonebook.com", + "version": "0.1.4", "parent": "peoplefinders.com", - "addedDatetime": 1678078800000, + "addedDatetime": 1678082400000, "steps": [ { "stepType": "scan", @@ -10,12 +11,12 @@ "actions": [ { "actionType": "navigate", - "id": "f214150b-4f02-46e1-b7ea-81f6bb1bf097", + "id": "6ee93554-95da-4a36-a7f7-c059d8f53ca3", "url": "https://www.usphonebook.com/${firstName}-${lastName}/${state|stateFull}/${city}" }, { "actionType": "extract", - "id": "af98bb63-b885-4f47-bb47-5f9ec5b491a4", + "id": "fffae12f-4ca1-4a8f-81b9-00adf0487129", "selector": ".ls_contacts-people-finder-wrapper", "profile": { "name": { @@ -56,4 +57,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/verecor.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/verecor.com.json index f493fbd347..5aff5bd46e 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/verecor.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/verecor.com.json @@ -1,7 +1,8 @@ { - "name": "verecor.com", - "version": "0.1.2", - "addedDatetime": 1677128400000, + "name": "Verecor", + "url": "verecor.com", + "version": "0.1.4", + "addedDatetime": 1677132000000, "steps": [ { "stepType": "scan", @@ -9,7 +10,7 @@ "actions": [ { "actionType": "navigate", - "id": "6f53d146-af6a-4bce-970d-f1dcbc496037", + "id": "37fc63a6-e434-4ba0-9e9e-d80898e4dfa4", "url": "https://verecor.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -23,7 +24,7 @@ }, { "actionType": "extract", - "id": "e8c09200-030c-492a-8e54-22bc6bdb6829", + "id": "a955924c-7959-48c8-9511-3f843baed729", "selector": ".search-item", "profile": { "name": { @@ -58,12 +59,12 @@ "actions": [ { "actionType": "navigate", - "id": "f4bbe480-a6ff-40a5-aa25-8ff9ac40c9bf", + "id": "85cd9682-94d8-46ac-9999-e03dfa9f8d4e", "url": "https://verecor.com/ng/control/privacy" }, { "actionType": "fillForm", - "id": "1e6302e1-daf9-49d6-951f-506ea5e266a0", + "id": "ed45c76b-e537-4072-9f46-9515c6e215be", "selector": ".ahm", "elements": [ { @@ -82,17 +83,17 @@ }, { "actionType": "getCaptchaInfo", - "id": "6a3dc470-3bf7-4b8b-bb44-f77ef1a2c540", + "id": "0e1474f0-24fe-4f6a-8d2e-2dfd91cf574b", "selector": ".g-recaptcha" }, { "actionType": "solveCaptcha", - "id": "83157244-c5bf-44a9-979c-679e1404d67d", + "id": "52a858f5-7dc5-40aa-aaa7-7090e06ea55e", "selector": ".g-recaptcha" }, { "actionType": "click", - "id": "15c50d7f-0e72-4509-be2b-40cde34b48e6", + "id": "759e0dd2-3a93-42a8-9a83-5e3408f5566b", "elements": [ { "type": "button", @@ -102,7 +103,7 @@ }, { "actionType": "expectation", - "id": "2ed336a2-a7a9-4cbd-933c-cd463df4f553", + "id": "089924be-5ea3-48a9-a325-8976d262f39b", "expectations": [ { "type": "text", @@ -113,12 +114,12 @@ }, { "actionType": "emailConfirmation", - "id": "88c09081-e848-4e75-a7b9-3ee28e95a459", + "id": "8094718e-412a-418f-b74d-cd4fc5e42c56", "pollingTime": 30 }, { "actionType": "expectation", - "id": "dd03cf9f-8227-4881-86bf-09ce158bf151", + "id": "af8fb89b-88d2-4901-b90c-eaac3c7566db", "expectations": [ { "type": "text", @@ -135,4 +136,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/vericora.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/vericora.com.json index 814e908fae..c7a3bad5c2 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/vericora.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/vericora.com.json @@ -1,8 +1,9 @@ { - "name": "vericora.com", - "version": "0.1.1", + "name": "Vericora", + "url": "vericora.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1677733200000, + "addedDatetime": 1677736800000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "9488e141-d109-4cbf-bc65-1b9036728ff4", + "id": "69175f1a-0024-4efd-ab3e-67bcf915a770", "url": "https://vericora.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "baaecb74-8d63-496c-a3e0-a8acbdee2c99", + "id": "bd941009-4462-4d59-ba44-46250f580531", "selector": ".search-item", "profile": { "name": { @@ -64,4 +65,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veriforia.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veriforia.com.json index 121bc68d3e..5f4f307f92 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veriforia.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veriforia.com.json @@ -1,8 +1,9 @@ { - "name": "veriforia.com", - "version": "0.1.1", + "name": "Veriforia", + "url": "veriforia.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1677733200000, + "addedDatetime": 1677736800000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "ffb30e97-b03f-4157-a511-09ad8ffb8b54", + "id": "17442975-944c-4b01-8518-7f1dff171ad2", "url": "https://veriforia.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "1d8d9c20-9897-4386-8bc1-bd591abe7c81", + "id": "32e963e1-4959-4e5e-981b-550f1bf36f9a", "selector": ".search-item", "profile": { "name": { @@ -64,4 +65,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veripages.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veripages.com.json index 43d95caf8a..61becad701 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veripages.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/veripages.com.json @@ -1,8 +1,9 @@ { - "name": "veripages.com", - "version": "0.1.2", + "name": "Veripages", + "url": "veripages.com", + "version": "0.1.4", "parent": "verecor.com", - "addedDatetime": 1691982000000, + "addedDatetime": 1691989200000, "steps": [ { "stepType": "scan", @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "5bf98772-1804-4939-a06b-dbf9cd31f198", + "id": "2346b569-1c46-4ef9-8ea0-fa18bea967fa", "url": "https://veripages.com/inner/profile/search?fname=${firstName}&lname=${lastName}&fage=${age|ageRange}&state=${state}&city=${city}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "f3d53642-9a58-4275-b97f-5547e3ef8e55", + "id": "c4281ca8-d4d0-4091-b6c2-3094801e99c0", "selector": ".search-item", "profile": { "name": { @@ -66,4 +67,4 @@ "confirmOptOutScan": 72, "maintenanceScan": 240 } -} +} \ No newline at end of file diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/virtory.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/virtory.com.json index d12865681f..3d94019338 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/virtory.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/virtory.com.json @@ -1,6 +1,7 @@ { - "name": "virtory.com", - "version": "0.1.1", + "name": "Virtory", + "url": "virtory.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1703052000000, "steps": [ @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "99465bd6-ce87-4fc6-96a2-eea8137e4a30", + "id": "0568e4f5-73c2-4b1a-9eb6-ac3571b1a01e", "url": "https://virtory.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "8d66ac98-f788-4fbd-acec-56034682b4b1", + "id": "df2216f3-0890-4d13-b2aa-233084167720", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/wellnut.com.json b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/wellnut.com.json index b4fd3669ec..12c43b7fa4 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/wellnut.com.json +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Resources/JSON/wellnut.com.json @@ -1,6 +1,7 @@ { - "name": "wellnut.com", - "version": "0.1.1", + "name": "Wellnut", + "url": "wellnut.com", + "version": "0.1.4", "parent": "verecor.com", "addedDatetime": 1703052000000, "steps": [ @@ -10,7 +11,7 @@ "actions": [ { "actionType": "navigate", - "id": "b9db3c1e-ece6-45d1-94ec-1143da9607aa", + "id": "a38752f3-ae69-45c3-ba3f-3a73e549e644", "url": "https://wellnut.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${age|ageRange}", "ageRange": [ "18-30", @@ -24,7 +25,7 @@ }, { "actionType": "extract", - "id": "e4b7c983-c96e-4ce8-8703-3cb319454db7", + "id": "b7747e92-5fe5-46f7-b083-5df6fbdc2b84", "selector": ".card", "profile": { "name": { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Services/EmailService.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Services/EmailService.swift index 75b80b195a..038c72c2d8 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Services/EmailService.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Services/EmailService.swift @@ -30,7 +30,7 @@ public enum EmailError: Error, Equatable, Codable { } protocol EmailServiceProtocol { - func getEmail(dataBrokerName: String?) async throws -> String + func getEmail(dataBrokerURL: String?) async throws -> String func getConfirmationLink(from email: String, numberOfRetries: Int, pollingIntervalInSeconds: Int, @@ -51,10 +51,10 @@ struct EmailService: EmailServiceProtocol { self.redeemUseCase = redeemUseCase } - func getEmail(dataBrokerName: String? = nil) async throws -> String { + func getEmail(dataBrokerURL: String? = nil) async throws -> String { var urlString = Constants.baseUrl + "/generate" - if let dataBrokerValue = dataBrokerName { + if let dataBrokerValue = dataBrokerURL { urlString += "?dataBroker=\(dataBrokerValue)" } diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift index ab59f166cc..a70ad31818 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/DataBrokerProtectionDatabaseProvider.swift @@ -34,7 +34,7 @@ protocol DataBrokerProtectionDatabaseProvider: SecureStorageDatabaseProvider { func save(_ broker: BrokerDB) throws -> Int64 func update(_ broker: BrokerDB) throws func fetchBroker(with id: Int64) throws -> BrokerDB? - func fetchBroker(with name: String) throws -> BrokerDB? + func fetchBroker(with url: String) throws -> BrokerDB? func fetchAllBrokers() throws -> [BrokerDB] func save(_ profileQuery: ProfileQueryDB) throws -> Int64 @@ -85,6 +85,8 @@ final class DefaultDataBrokerProtectionDatabaseProvider: GRDBSecureStorageDataba public init(file: URL = DefaultDataBrokerProtectionDatabaseProvider.defaultDatabaseURL(), key: Data) throws { try super.init(file: file, key: key, writerType: .pool) { migrator in migrator.registerMigration("v1", migrate: Self.migrateV1(database:)) + migrator.registerMigration("v2", migrate: Self.migrateV2(database:)) + } } @@ -259,6 +261,16 @@ final class DefaultDataBrokerProtectionDatabaseProvider: GRDBSecureStorageDataba $0.column(OptOutAttemptDB.Columns.startDate.name, .date).notNull() } } + + static func migrateV2(database: Database) throws { + try database.alter(table: BrokerDB.databaseTableName) { + $0.add(column: BrokerDB.Columns.url.name, .text) + } + try database.execute(sql: """ + UPDATE \(BrokerDB.databaseTableName) SET \(BrokerDB.Columns.url.name) = \(BrokerDB.Columns.name.name) + """) + } + // swiftlint:enable function_body_length func updateProfile(profile: DataBrokerProtectionProfile, mapperToDB: MapperToDB) throws -> Int64 { @@ -359,10 +371,10 @@ final class DefaultDataBrokerProtectionDatabaseProvider: GRDBSecureStorageDataba } } - func fetchBroker(with name: String) throws -> BrokerDB? { + func fetchBroker(with url: String) throws -> BrokerDB? { try db.read { db in return try BrokerDB - .filter(Column(BrokerDB.Columns.name.name) == name) + .filter(Column(BrokerDB.Columns.url.name) == url) .fetchOne(db) } } diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/Mappers.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/Mappers.swift index 267b013ed8..56b08dd5f2 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/Mappers.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/Mappers.swift @@ -58,7 +58,7 @@ struct MapperToDB { func mapToDB(_ broker: DataBroker, id: Int64? = nil) throws -> BrokerDB { let encodedBroker = try jsonEncoder.encode(broker) - return .init(id: id, name: broker.name, json: encodedBroker, version: broker.version) + return .init(id: id, name: broker.name, json: encodedBroker, version: broker.version, url: broker.url) } func mapToDB(_ profileQuery: ProfileQuery, relatedTo profileId: Int64) throws -> ProfileQueryDB { @@ -171,6 +171,7 @@ struct MapperToModel { return DataBroker( id: brokerDB.id, name: decodedBroker.name, + url: decodedBroker.url, steps: decodedBroker.steps, version: decodedBroker.version, schedulingConfig: decodedBroker.schedulingConfig, diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/SchedulerSchema.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/SchedulerSchema.swift index 348d99180d..a772e4d543 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/SchedulerSchema.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Storage/SchedulerSchema.swift @@ -94,6 +94,7 @@ struct BrokerDB: Codable { let name: String let json: Data let version: String + let url: String } extension BrokerDB: PersistableRecord, FetchableRecord { @@ -104,6 +105,7 @@ extension BrokerDB: PersistableRecord, FetchableRecord { case name case json case version + case url } init(row: Row) throws { @@ -111,6 +113,7 @@ extension BrokerDB: PersistableRecord, FetchableRecord { name = row[Columns.name] json = row[Columns.json] version = row[Columns.version] + url = row[Columns.url] } func encode(to container: inout PersistenceContainer) throws { @@ -118,6 +121,7 @@ extension BrokerDB: PersistableRecord, FetchableRecord { container[Columns.name] = name container[Columns.json] = json container[Columns.version] = version + container[Columns.url] = url } } diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DBPUICommunicationLayer.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DBPUICommunicationLayer.swift index 63b1b4a47e..9f77b8a675 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DBPUICommunicationLayer.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DBPUICommunicationLayer.swift @@ -36,6 +36,7 @@ protocol DBPUICommunicationDelegate: AnyObject { func startScanAndOptOut() -> Bool func getInitialScanState() async -> DBPUIInitialScanState func getMaintananceScanState() async -> DBPUIScanAndOptOutMaintenanceState + func getDataBrokers() async -> [DBPUIDataBroker] } enum DBPUIReceivedMethodName: String { @@ -53,6 +54,7 @@ enum DBPUIReceivedMethodName: String { case startScanAndOptOut case initialScanStatus case maintenanceScanStatus + case getDataBrokers } enum DBPUISendableMethodName: String { @@ -69,7 +71,7 @@ struct DBPUICommunicationLayer: Subfeature { weak var delegate: DBPUICommunicationDelegate? private enum Constants { - static let version = 1 + static let version = 2 } internal init(webURLSettings: DataBrokerProtectionWebUIURLSettingsRepresentable) { @@ -101,6 +103,7 @@ struct DBPUICommunicationLayer: Subfeature { case .startScanAndOptOut: return startScanAndOptOut case .initialScanStatus: return initialScanStatus case .maintenanceScanStatus: return maintenanceScanStatus + case .getDataBrokers: return getDataBrokers } } @@ -264,6 +267,11 @@ struct DBPUICommunicationLayer: Subfeature { return maintenanceScanStatus } + func getDataBrokers(params: Any, origin: WKScriptMessage) async throws -> Encodable? { + let dataBrokers = await delegate?.getDataBrokers() ?? [DBPUIDataBroker]() + return DBPUIDataBrokerList(dataBrokers: dataBrokers) + } + func sendMessageToUI(method: DBPUISendableMethodName, params: DBPUISendableMessage, into webView: WKWebView) { broker?.push(method: method.rawValue, params: params, for: self, into: webView) } diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DataBrokerProtectionWebUIURLSettings.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DataBrokerProtectionWebUIURLSettings.swift index 5597a11ab6..4f18f9fe88 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DataBrokerProtectionWebUIURLSettings.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/DataBrokerProtectionWebUIURLSettings.swift @@ -37,7 +37,7 @@ public protocol DataBrokerProtectionWebUIURLSettingsRepresentable { public final class DataBrokerProtectionWebUIURLSettings: DataBrokerProtectionWebUIURLSettingsRepresentable { - public let productionURL = "https://duckduckgo.com/dbp" + public let productionURL = "https://use-devtesting9.duckduckgo.com/dbp" private let userDefault: UserDefaults public var selectedURLType: DataBrokerProtectionWebUIURLType { diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/UIMapper.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/UIMapper.swift index 836bd52a30..454f1c75a9 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/UIMapper.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/UI/UIMapper.swift @@ -26,22 +26,24 @@ struct MapperToUI { name: extractedProfile.fullName ?? "No name", addresses: extractedProfile.addresses?.map(mapToUI) ?? [], alternativeNames: extractedProfile.alternativeNames ?? [String](), - relatives: extractedProfile.relatives ?? [String]() + relatives: extractedProfile.relatives ?? [String](), + date: extractedProfile.removedDate?.timeIntervalSince1970 ) } - func mapToUI(_ dataBrokerName: String, extractedProfile: ExtractedProfile) -> DBPUIDataBrokerProfileMatch { + func mapToUI(_ dataBrokerName: String, databrokerURL: String, extractedProfile: ExtractedProfile) -> DBPUIDataBrokerProfileMatch { DBPUIDataBrokerProfileMatch( - dataBroker: DBPUIDataBroker(name: dataBrokerName), + dataBroker: DBPUIDataBroker(name: dataBrokerName, url: databrokerURL), name: extractedProfile.fullName ?? "No name", addresses: extractedProfile.addresses?.map(mapToUI) ?? [], alternativeNames: extractedProfile.alternativeNames ?? [String](), - relatives: extractedProfile.relatives ?? [String]() + relatives: extractedProfile.relatives ?? [String](), + date: extractedProfile.removedDate?.timeIntervalSince1970 ) } func mapToUI(_ dataBroker: DataBroker) -> DBPUIDataBroker { - DBPUIDataBroker(name: dataBroker.name) + DBPUIDataBroker(name: dataBroker.name, url: dataBroker.url) } func mapToUI(_ address: AddressCityState) -> DBPUIUserProfileAddress { @@ -75,7 +77,7 @@ struct MapperToUI { if !$0.dataBroker.mirrorSites.isEmpty { let mirrorSitesMatches = $0.dataBroker.mirrorSites.compactMap { mirrorSite in if mirrorSite.shouldWeIncludeMirrorSite() { - return mapToUI(mirrorSite.name, extractedProfile: extractedProfile) + return mapToUI(mirrorSite.name, databrokerURL: mirrorSite.url, extractedProfile: extractedProfile) } return nil @@ -110,7 +112,7 @@ struct MapperToUI { if let closestMatchesFoundEvent = scanOperation.closestMatchesFoundEvent() { for mirrorSite in dataBroker.mirrorSites where mirrorSite.shouldWeIncludeMirrorSite(for: closestMatchesFoundEvent.date) { - let mirrorSiteMatch = mapToUI(mirrorSite.name, extractedProfile: extractedProfile) + let mirrorSiteMatch = mapToUI(mirrorSite.name, databrokerURL: mirrorSite.url, extractedProfile: extractedProfile) if let extractedProfileRemovedDate = extractedProfile.removedDate, mirrorSite.shouldWeIncludeMirrorSite(for: extractedProfileRemovedDate) { @@ -124,11 +126,21 @@ struct MapperToUI { } let completedOptOutsDictionary = Dictionary(grouping: removedProfiles, by: { $0.dataBroker }) - let completedOptOuts = completedOptOutsDictionary.map { (key: DBPUIDataBroker, value: [DBPUIDataBrokerProfileMatch]) in - DBPUIOptOutMatch(dataBroker: key, matches: value.count) - } - let lastScans = getLastScanInformation(brokerProfileQueryData: brokerProfileQueryData) - let nextScans = getNextScansInformation(brokerProfileQueryData: brokerProfileQueryData) + let completedOptOuts: [DBPUIOptOutMatch] = completedOptOutsDictionary.compactMap { (key: DBPUIDataBroker, value: [DBPUIDataBrokerProfileMatch]) in + value.compactMap { match in + guard let removedDate = match.date else { return nil } + return DBPUIOptOutMatch(dataBroker: key, + matches: value.count, + name: match.name, + alternativeNames: match.alternativeNames, + addresses: match.addresses, + date: removedDate) + } + }.flatMap { $0 } + + let nearestScanByBrokerURL = nearestRunDates(for: brokerProfileQueryData) + let lastScans = getLastScanInformation(brokerProfileQueryData: brokerProfileQueryData, nearestScanOperationByBroker: nearestScanByBrokerURL) + let nextScans = getNextScansInformation(brokerProfileQueryData: brokerProfileQueryData, nearestScanOperationByBroker: nearestScanByBrokerURL) return DBPUIScanAndOptOutMaintenanceState( inProgressOptOuts: inProgressOptOuts, @@ -140,7 +152,8 @@ struct MapperToUI { private func getLastScanInformation(brokerProfileQueryData: [BrokerProfileQueryData], currentDate: Date = Date(), - format: String = "dd/MM/yyyy") -> DBUIScanDate { + format: String = "dd/MM/yyyy", + nearestScanOperationByBroker: [String: Date]) -> DBUIScanDate { let scansGroupedByLastRunDate = Dictionary(grouping: brokerProfileQueryData, by: { $0.scanOperationData.lastRunDate?.toFormat(format) }) let closestScansBeforeToday = scansGroupedByLastRunDate .filter { $0.key != nil && $0.key!.toDate(using: format) < currentDate } @@ -148,12 +161,13 @@ struct MapperToUI { .flatMap { [$0.key?.toDate(using: format): $0.value] } .last - return scanDate(element: closestScansBeforeToday) + return scanDate(element: closestScansBeforeToday, nearestScanOperationByBroker: nearestScanOperationByBroker) } private func getNextScansInformation(brokerProfileQueryData: [BrokerProfileQueryData], currentDate: Date = Date(), - format: String = "dd/MM/yyyy") -> DBUIScanDate { + format: String = "dd/MM/yyyy", + nearestScanOperationByBroker: [String: Date]) -> DBUIScanDate { let scansGroupedByPreferredRunDate = Dictionary(grouping: brokerProfileQueryData, by: { $0.scanOperationData.preferredRunDate?.toFormat(format) }) let closestScansAfterToday = scansGroupedByPreferredRunDate .filter { $0.key != nil && $0.key!.toDate(using: format) > currentDate } @@ -161,22 +175,50 @@ struct MapperToUI { .flatMap { [$0.key?.toDate(using: format): $0.value] } .first - return scanDate(element: closestScansAfterToday) + return scanDate(element: closestScansAfterToday, nearestScanOperationByBroker: nearestScanOperationByBroker) + } + + // A dictionary containing the closest scan by broker + private func nearestRunDates(for brokerData: [BrokerProfileQueryData]) -> [String: Date] { + let today = Date() + let nearestDates = brokerData.reduce(into: [String: Date]()) { result, data in + let url = data.dataBroker.url + if let operationDate = data.scanOperationData.preferredRunDate { + if operationDate > today { + if let existingDate = result[url] { + if operationDate < existingDate { + result[url] = operationDate + } + } else { + result[url] = operationDate + } + } + } + } + return nearestDates } - private func scanDate(element: Dictionary.Element?) -> DBUIScanDate { + private func scanDate(element: Dictionary.Element?, + nearestScanOperationByBroker: [String: Date]) -> DBUIScanDate { if let element = element, let date = element.key { return DBUIScanDate( date: date.timeIntervalSince1970, dataBrokers: element.value.flatMap { - var brokers = [DBPUIDataBroker(name: $0.dataBroker.name)] + let brokerOperationDate = nearestScanOperationByBroker[$0.dataBroker.url] + var brokers = [DBPUIDataBroker(name: $0.dataBroker.name, url: $0.dataBroker.url, date: brokerOperationDate?.timeIntervalSince1970 ?? nil)] for mirrorSite in $0.dataBroker.mirrorSites where mirrorSite.shouldWeIncludeMirrorSite(for: date) { - brokers.append(DBPUIDataBroker(name: mirrorSite.name)) + brokers.append(DBPUIDataBroker(name: mirrorSite.name, url: mirrorSite.url, date: brokerOperationDate?.timeIntervalSince1970 ?? nil)) } return brokers } + .reduce(into: []) { result, dataBroker in // Remove dupes + guard !result.contains(where: { $0.url == dataBroker.url }) else { + return + } + result.append(dataBroker) + } ) } else { return DBUIScanDate(date: 0, dataBrokers: [DBPUIDataBroker]()) diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/BrokerJSONCodableTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/BrokerJSONCodableTests.swift index 2a6108f826..a604a0a4d7 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/BrokerJSONCodableTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/BrokerJSONCodableTests.swift @@ -20,11 +20,174 @@ import XCTest @testable import DataBrokerProtection final class BrokerJSONCodableTests: XCTestCase { - let verecorJSONString = """ + let verecorWithURLJSONString = """ + { + "name": "Verecor", + "url": "verecor.com", + "version": "0.1.0", + "addedDatetime": 1677128400000, + "mirrorSites": [ + { + "name": "Potato", + "url": "potato.com", + "addedAt": 1705599286529, + "removedAt": null + }, + { + "name": "Tomato", + "url": "tomato.com", + "addedAt": 1705599286529, + "removedAt": null + } + ], + "steps": [ + { + "stepType": "scan", + "scanType": "templatedUrl", + "actions": [ + { + "actionType": "navigate", + "id": "84aa05bc-1ca0-4f16-ae74-dfb352ce0eee", + "url": "https://verecor.com/profile/search?fname=${firstName}&lname=${lastName}&state=${state}&city=${city}&fage=${ageRange}", + "ageRange": [ + "18-30", + "31-40", + "41-50", + "51-60", + "61-70", + "71-80", + "81+" + ] + }, + { + "actionType": "extract", + "id": "92252eb5-ccaf-4b00-a3fe-019110ce0534", + "selector": ".search-item", + "profile": { + "name": { + "selector": "h4" + }, + "alternativeNamesList": { + "selector": ".//div[@class='col-sm-24 col-md-16 name']//li", + "findElements": true + }, + "age": { + "selector": ".age" + }, + "addressCityStateList": { + "selector": ".//div[@class='col-sm-24 col-md-8 location']//li", + "findElements": true + }, + "profileUrl": { + "selector": "a" + } + } + } + ] + }, + { + "stepType": "optOut", + "optOutType": "formOptOut", + "actions": [ + { + "actionType": "navigate", + "id": "49f9aa73-4f97-47c0-b8bf-1729e9c169c0", + "url": "https://verecor.com/ng/control/privacy" + }, + { + "actionType": "fillForm", + "id": "55b1d0bb-d303-4b6f-bf9e-3fd96746f27e", + "selector": ".ahm", + "elements": [ + { + "type": "fullName", + "selector": "#user_name" + }, + { + "type": "email", + "selector": "#user_email" + }, + { + "type": "profileUrl", + "selector": "#url" + } + ] + }, + { + "actionType": "getCaptchaInfo", + "id": "9efb1153-8f52-41e4-a8fb-3077a97a586d", + "selector": ".g-recaptcha" + }, + { + "actionType": "solveCaptcha", + "id": "ed49e4c3-0cfa-4f1e-b3d1-06ad7b8b9ba4", + "selector": ".g-recaptcha" + }, + { + "actionType": "click", + "id": "6b986aa4-3d1b-44d5-8b2b-5463ee8916c9", + "elements": [ + { + "type": "button", + "selector": ".btn-sbmt" + } + ] + }, + { + "actionType": "expectation", + "id": "d4c64d9b-1004-487e-ab06-ae74869bc9a7", + "expectations": [ + { + "type": "text", + "selector": "body", + "expect": "Your removal request has been received" + } + ] + }, + { + "actionType": "emailConfirmation", + "id": "3b4c611a-61ab-4792-810e-d5b3633ea203", + "pollingTime": 30 + }, + { + "actionType": "expectation", + "id": "afe805a0-d422-473c-b47f-995a8672d476", + "expectations": [ + { + "type": "text", + "selector": "body", + "expect": "Your information control request has been confirmed." + } + ] + } + ] + } + ], + "schedulingConfig": { + "retryError": 48, + "confirmOptOutScan": 72, + "maintenanceScan": 240 + } + } + + """ + let verecorNoURLJSONString = """ { "name": "verecor.com", "version": "0.1.0", "addedDatetime": 1677128400000, + "mirrorSites": [ + { + "name": "tomato.com", + "addedAt": 1705599286529, + "removedAt": null + }, + { + "name": "potato.com", + "addedAt": 1705599286529, + "removedAt": null + } + ], "steps": [ { "stepType": "scan", @@ -157,9 +320,27 @@ final class BrokerJSONCodableTests: XCTestCase { """ - func testVerecorJSON_isCorrectlyParsed() { + func testVerecorJSONNoURL_isCorrectlyParsed() { do { - _ = try JSONDecoder().decode(DataBroker.self, from: verecorJSONString.data(using: .utf8)!) + let broker = try JSONDecoder().decode(DataBroker.self, from: verecorNoURLJSONString.data(using: .utf8)!) + XCTAssertEqual(broker.url, broker.name) + for mirror in broker.mirrorSites { + XCTAssertEqual(mirror.url, mirror.name) + } + } catch { + XCTFail("JSON string should be parsed correctly.") + } + } + + func testVerecorJSONWithURL_isCorrectlyParsed() { + do { + let broker = try JSONDecoder().decode(DataBroker.self, from: verecorWithURLJSONString.data(using: .utf8)!) + XCTAssertEqual(broker.url, "verecor.com") + XCTAssertEqual(broker.name, "Verecor") + + for mirror in broker.mirrorSites { + XCTAssertNotEqual(mirror.url, mirror.name) + } } catch { XCTFail("JSON string should be parsed correctly.") } diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProfileQueryOperationManagerTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProfileQueryOperationManagerTests.swift index 3a65f7ae9a..5fa7f4b069 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProfileQueryOperationManagerTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProfileQueryOperationManagerTests.swift @@ -44,7 +44,7 @@ final class DataBrokerProfileQueryOperationManagerTests: XCTestCase { let extractedProfileId: Int64 = 1 let currentPreferredRunDate = Date() - let mockDataBroker = DataBroker(name: "databroker", steps: [Step](), version: "1.0", schedulingConfig: config) + let mockDataBroker = DataBroker(name: "databroker", url: "databroker.com", steps: [Step](), version: "1.0", schedulingConfig: config) let mockProfileQuery = ProfileQuery(id: profileQueryId, firstName: "a", lastName: "b", city: "c", state: "d", birthYear: 1222) let historyEvents = [HistoryEvent(extractedProfileId: extractedProfileId, brokerId: brokerId, profileQueryId: profileQueryId, type: .optOutRequested)] @@ -92,7 +92,7 @@ final class DataBrokerProfileQueryOperationManagerTests: XCTestCase { let extractedProfileId: Int64 = 1 let currentPreferredRunDate = Date() - let mockDataBroker = DataBroker(name: "databroker", steps: [Step](), version: "1.0", schedulingConfig: config) + let mockDataBroker = DataBroker(name: "databroker", url: "databroker.com", steps: [Step](), version: "1.0", schedulingConfig: config) let mockProfileQuery = ProfileQuery(id: profileQueryId, firstName: "a", lastName: "b", city: "c", state: "d", birthYear: 1222) let historyEvents = [HistoryEvent(extractedProfileId: extractedProfileId, brokerId: brokerId, profileQueryId: profileQueryId, type: .optOutRequested)] @@ -143,7 +143,7 @@ final class DataBrokerProfileQueryOperationManagerTests: XCTestCase { let extractedProfileId: Int64 = 1 let currentPreferredRunDate = Date() - let mockDataBroker = DataBroker(name: "databroker", steps: [Step](), version: "1.0", schedulingConfig: config) + let mockDataBroker = DataBroker(name: "databroker", url: "databroker.com", steps: [Step](), version: "1.0", schedulingConfig: config) let mockProfileQuery = ProfileQuery(id: profileQueryId, firstName: "a", lastName: "b", city: "c", state: "d", birthYear: 1222) let historyEvents = [HistoryEvent(extractedProfileId: extractedProfileId, brokerId: brokerId, profileQueryId: profileQueryId, type: .optOutRequested)] @@ -745,7 +745,7 @@ final class DataBrokerProfileQueryOperationManagerTests: XCTestCase { let extractedProfileId: Int64 = 1 let currentPreferredRunDate = Date() - let mockDataBroker = DataBroker(name: "databroker", steps: [Step](), version: "1.0", schedulingConfig: config) + let mockDataBroker = DataBroker(name: "databroker", url: "databroker.com", steps: [Step](), version: "1.0", schedulingConfig: config) let mockProfileQuery = ProfileQuery(id: profileQueryId, firstName: "a", lastName: "b", city: "c", state: "d", birthYear: 1222) let historyEvents = [HistoryEvent(extractedProfileId: extractedProfileId, brokerId: brokerId, profileQueryId: profileQueryId, type: .optOutRequested)] @@ -770,7 +770,7 @@ final class DataBrokerProfileQueryOperationManagerTests: XCTestCase { let currentPreferredRunDate = Date() let expectedPreferredRunDate = Date().addingTimeInterval(config.confirmOptOutScan.hoursToSeconds) - let mockDataBroker = DataBroker(name: "databroker", steps: [Step](), version: "1.0", schedulingConfig: config) + let mockDataBroker = DataBroker(name: "databroker", url: "databroker.com", steps: [Step](), version: "1.0", schedulingConfig: config) let mockProfileQuery = ProfileQuery(id: profileQueryId, firstName: "a", lastName: "b", city: "c", state: "d", birthYear: 1222) let historyEvents = [HistoryEvent(extractedProfileId: extractedProfileId, brokerId: brokerId, profileQueryId: profileQueryId, type: .optOutRequested)] @@ -846,6 +846,7 @@ extension DataBroker { DataBroker( id: 1, name: "Test broker", + url: "testbroker.com", steps: [ Step(type: .scan, actions: [Action]()), Step(type: .optOut, actions: [Action]()) @@ -863,6 +864,7 @@ extension DataBroker { DataBroker( id: 1, name: "Test broker", + url: "testbroker.com", steps: [ Step(type: .scan, actions: [Action]()), Step(type: .optOut, actions: [Action](), optOutType: .parentSiteOptOut) @@ -879,6 +881,7 @@ extension DataBroker { static var mockWithoutId: DataBroker { DataBroker( name: "Test broker", + url: "testbroker.com", steps: [Step](), version: "1.0", schedulingConfig: DataBrokerScheduleConfig( diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionUpdaterTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionUpdaterTests.swift index dcbc31a911..d5bec76ee0 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionUpdaterTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerProtectionUpdaterTests.swift @@ -111,7 +111,7 @@ final class DataBrokerProtectionUpdaterTests: XCTestCase { if let vault = self.vault { let sut = DataBrokerProtectionBrokerUpdater(repository: repository, resources: resources, vault: vault) repository.lastCheckedVersion = nil - resources.brokersList = [.init(id: 1, name: "Broker", steps: [Step](), version: "1.0.1", schedulingConfig: .mock)] + resources.brokersList = [.init(id: 1, name: "Broker", url: "www.broker.com", steps: [Step](), version: "1.0.1", schedulingConfig: .mock)] vault.shouldReturnOldVersionBroker = true sut.checkForUpdatesInBrokerJSONFiles() @@ -129,7 +129,7 @@ final class DataBrokerProtectionUpdaterTests: XCTestCase { if let vault = self.vault { let sut = DataBrokerProtectionBrokerUpdater(repository: repository, resources: resources, vault: vault) repository.lastCheckedVersion = nil - resources.brokersList = [.init(id: 1, name: "Broker", steps: [Step](), version: "1.0.1", schedulingConfig: .mock)] + resources.brokersList = [.init(id: 1, name: "Broker", url: "www.broker.com", steps: [Step](), version: "1.0.1", schedulingConfig: .mock)] vault.shouldReturnNewVersionBroker = true sut.checkForUpdatesInBrokerJSONFiles() @@ -146,7 +146,7 @@ final class DataBrokerProtectionUpdaterTests: XCTestCase { if let vault = self.vault { let sut = DataBrokerProtectionBrokerUpdater(repository: repository, resources: resources, vault: vault) repository.lastCheckedVersion = nil - resources.brokersList = [.init(id: 1, name: "Broker", steps: [Step](), version: "1.0.0", schedulingConfig: .mock)] + resources.brokersList = [.init(id: 1, name: "Broker", url: "www.broker.com", steps: [Step](), version: "1.0.0", schedulingConfig: .mock)] vault.profileQueries = [.mock] sut.checkForUpdatesInBrokerJSONFiles() diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/EmailServiceTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/EmailServiceTests.swift index cc23589ec8..c82680d1e9 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/EmailServiceTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/EmailServiceTests.swift @@ -41,7 +41,7 @@ final class EmailServiceTests: XCTestCase { let sut = EmailService(urlSession: mockURLSession, redeemUseCase: MockRedeemUseCase()) do { - _ = try await sut.getEmail(dataBrokerName: "fakeBroker") + _ = try await sut.getEmail(dataBrokerURL: "fakeBroker") XCTFail("Expected an error to be thrown") } catch { if let error = error as? EmailError, @@ -62,7 +62,7 @@ final class EmailServiceTests: XCTestCase { let sut = EmailService(urlSession: mockURLSession, redeemUseCase: MockRedeemUseCase()) do { - _ = try await sut.getEmail(dataBrokerName: "fakeBroker") + _ = try await sut.getEmail(dataBrokerURL: "fakeBroker") XCTFail("Expected an error to be thrown") } catch { if let error = error as? EmailError, case .cantFindEmail = error { @@ -81,7 +81,7 @@ final class EmailServiceTests: XCTestCase { let sut = EmailService(urlSession: mockURLSession, redeemUseCase: MockRedeemUseCase()) do { - let email = try await sut.getEmail(dataBrokerName: "fakeBroker") + let email = try await sut.getEmail(dataBrokerURL: "fakeBroker") XCTAssertEqual("test@ddg.com", email) } catch { XCTFail("Unexpected. It should not throw") diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MapperToUITests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MapperToUITests.swift index 4d1ff6b8f8..c59ee80486 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MapperToUITests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MapperToUITests.swift @@ -140,9 +140,9 @@ final class MapperToUITests: XCTestCase { func testLastScans_areMappedCorrectly() { let brokerProfileQueryData: [BrokerProfileQueryData] = [ - .mock(dataBrokerName: "Broker #1", lastRunDate: Date().yesterday), - .mock(dataBrokerName: "Broker #2", lastRunDate: Date().yesterday), - .mock(dataBrokerName: "Broker #3") + .mock(dataBrokerName: "Broker #1", url: "broker1.com", lastRunDate: Date().yesterday), + .mock(dataBrokerName: "Broker #2", url: "broker2.com", lastRunDate: Date().yesterday), + .mock(dataBrokerName: "Broker #3", url: "broker3.com") ] let result = sut.maintenanceScanState(brokerProfileQueryData) @@ -153,9 +153,9 @@ final class MapperToUITests: XCTestCase { func testNextScans_areMappedCorrectly() { let brokerProfileQueryData: [BrokerProfileQueryData] = [ - .mock(dataBrokerName: "Broker #1", preferredRunDate: Date().tomorrow), - .mock(dataBrokerName: "Broker #2", preferredRunDate: Date().tomorrow), - .mock(dataBrokerName: "Broker #3") + .mock(dataBrokerName: "Broker #1", url: "broker1.com", preferredRunDate: Date().tomorrow), + .mock(dataBrokerName: "Broker #2", url: "broker2.com", preferredRunDate: Date().tomorrow), + .mock(dataBrokerName: "Broker #3", url: "broker3.com") ] let result = sut.maintenanceScanState(brokerProfileQueryData) @@ -165,7 +165,7 @@ final class MapperToUITests: XCTestCase { } func testWhenMirrorSiteIsNotInRemovedPeriod_thenItShouldBeAddedToTotalScans() { - let brokerProfileQueryWithMirrorSite: BrokerProfileQueryData = .mock(dataBrokerName: "Broker #1", mirrorSites: [.init(name: "mirror", addedAt: Date(), removedAt: nil)]) + let brokerProfileQueryWithMirrorSite: BrokerProfileQueryData = .mock(dataBrokerName: "Broker #1", mirrorSites: [.init(name: "mirror", url: "mirror1.com", addedAt: Date(), removedAt: nil)]) let brokerProfileQueryData: [BrokerProfileQueryData] = [ brokerProfileQueryWithMirrorSite, brokerProfileQueryWithMirrorSite, @@ -178,7 +178,7 @@ final class MapperToUITests: XCTestCase { } func testWhenMirrorSiteIsInRemovedPeriod_thenItShouldNotBeAddedToTotalScans() { - let brokerWithMirrorSiteThatWasRemoved = BrokerProfileQueryData.mock(dataBrokerName: "Broker #1", mirrorSites: [.init(name: "mirror", addedAt: Date(), removedAt: Date().yesterday)]) + let brokerWithMirrorSiteThatWasRemoved = BrokerProfileQueryData.mock(dataBrokerName: "Broker #1", mirrorSites: [.init(name: "mirror", url: "mirror1.com", addedAt: Date(), removedAt: Date().yesterday)]) let brokerProfileQueryData: [BrokerProfileQueryData] = [.mock(dataBrokerName: "Broker #1"), brokerWithMirrorSiteThatWasRemoved, .mock(dataBrokerName: "Broker #2")] let result = sut.initialScanState(brokerProfileQueryData) @@ -190,7 +190,7 @@ final class MapperToUITests: XCTestCase { let brokerWithMirrorSiteNotRemovedAndWithScan = BrokerProfileQueryData.mock( dataBrokerName: "Broker #1", lastRunDate: Date(), - mirrorSites: [.init(name: "mirror", addedAt: Date(), removedAt: nil)] + mirrorSites: [.init(name: "mirror", url: "mirror.com", addedAt: Date(), removedAt: nil)] ) let brokerProfileQueryData: [BrokerProfileQueryData] = [ brokerWithMirrorSiteNotRemovedAndWithScan, @@ -207,7 +207,7 @@ final class MapperToUITests: XCTestCase { let brokerWithMirrorSiteRemovedAndWithScan = BrokerProfileQueryData.mock( dataBrokerName: "Broker #2", lastRunDate: Date(), - mirrorSites: [.init(name: "mirror", addedAt: Date(), removedAt: Date().yesterday)] + mirrorSites: [.init(name: "mirror", url: "mirror1.com", addedAt: Date(), removedAt: Date().yesterday)] ) let brokerProfileQueryData: [BrokerProfileQueryData] = [ .mock(dataBrokerName: "Broker #1"), @@ -223,7 +223,7 @@ final class MapperToUITests: XCTestCase { func testWhenMirrorSiteIsNotInRemovedPeriod_thenMatchIsAdded() { let brokerWithMirrorSiteNotRemovedAndWithMatch = BrokerProfileQueryData.mock( extractedProfile: .mockWithoutRemovedDate, - mirrorSites: [.init(name: "mirror", addedAt: Date(), removedAt: nil)] + mirrorSites: [.init(name: "mirror", url: "mirror1.com", addedAt: Date(), removedAt: nil)] ) let brokerProfileQueryData: [BrokerProfileQueryData] = [.mock(), .mock(), brokerWithMirrorSiteNotRemovedAndWithMatch] @@ -235,7 +235,7 @@ final class MapperToUITests: XCTestCase { func testWhenMirrorSiteIsInRemovedPeriod_thenMatchIsNotAdded() { let brokerWithMirrorSiteRemovedAndWithMatch = BrokerProfileQueryData.mock( extractedProfile: .mockWithoutRemovedDate, - mirrorSites: [.init(name: "mirror", addedAt: Date(), removedAt: Date().yesterday)] + mirrorSites: [.init(name: "mirror", url: "mirror1.com", addedAt: Date(), removedAt: Date().yesterday)] ) let brokerProfileQueryData: [BrokerProfileQueryData] = [.mock(), .mock(), brokerWithMirrorSiteRemovedAndWithMatch] @@ -246,8 +246,8 @@ final class MapperToUITests: XCTestCase { func testMirrorSites_areCorrectlyMappedToInProgressOptOuts() { let scanHistoryEventsWithMatchesFound: [HistoryEvent] = [.init(brokerId: 1, profileQueryId: 1, type: .matchesFound(count: 1), date: Date())] - let mirrorSiteNotRemoved = MirrorSite(name: "mirror #1", addedAt: Date.distantPast, removedAt: nil) - let mirrorSiteRemoved = MirrorSite(name: "mirror #2", addedAt: Date.distantPast, removedAt: Date().yesterday) // Should not be added + let mirrorSiteNotRemoved = MirrorSite(name: "mirror #1", url: "mirror1.com", addedAt: Date.distantPast, removedAt: nil) + let mirrorSiteRemoved = MirrorSite(name: "mirror #2", url: "mirror2.com", addedAt: Date.distantPast, removedAt: Date().yesterday) // Should not be added let brokerProfileQueryData: [BrokerProfileQueryData] = [ .mock(extractedProfile: .mockWithoutRemovedDate, scanHistoryEvents: scanHistoryEventsWithMatchesFound, @@ -261,10 +261,10 @@ final class MapperToUITests: XCTestCase { func testWhenMirrorSiteRemovedIsInRangeToPastRemovedProfile_thenIsAddedToCompletedOptOuts() { let scanHistoryEventsWithMatchesFound: [HistoryEvent] = [.init(brokerId: 1, profileQueryId: 1, type: .matchesFound(count: 1), date: Date().yesterday!)] - let mirrorSiteRemoved = MirrorSite(name: "mirror #1", addedAt: Date.distantPast, removedAt: Date()) // Should be added + let mirrorSiteRemoved = MirrorSite(name: "mirror #1", url: "mirror1.com", addedAt: Date.distantPast, removedAt: Date()) // Should be added // The next two mirror sites should not be added. New mirror sites should not count for old opt-outs - let newMirrorSiteOne = MirrorSite(name: "mirror #2", addedAt: Date(), removedAt: nil) - let newMirrorSiteTwo = MirrorSite(name: "mirror #3", addedAt: Date(), removedAt: nil) + let newMirrorSiteOne = MirrorSite(name: "mirror #2", url: "mirror2.com", addedAt: Date(), removedAt: nil) + let newMirrorSiteTwo = MirrorSite(name: "mirror #3", url: "mirror3.com", addedAt: Date(), removedAt: nil) let brokerProfileQuery = BrokerProfileQueryData.mock(extractedProfile: .mockWithRemoveDate(Date().yesterday!), scanHistoryEvents: scanHistoryEventsWithMatchesFound, mirrorSites: [mirrorSiteRemoved, newMirrorSiteOne, newMirrorSiteTwo]) @@ -276,12 +276,12 @@ final class MapperToUITests: XCTestCase { } func testLastScansWithMirrorSites_areMappedCorrectly() { - let includedMirrorSite = MirrorSite(name: "mirror #1", addedAt: Date.distantPast, removedAt: nil) - let notIncludedMirrorSite = MirrorSite(name: "mirror #2", addedAt: Date(), removedAt: nil) + let includedMirrorSite = MirrorSite(name: "mirror #1", url: "mirror1.com", addedAt: Date.distantPast, removedAt: nil) + let notIncludedMirrorSite = MirrorSite(name: "mirror #2", url: "mirror2.com", addedAt: Date(), removedAt: nil) let brokerProfileQueryData: [BrokerProfileQueryData] = [ - .mock(dataBrokerName: "Broker #1", lastRunDate: Date().yesterday, mirrorSites: [includedMirrorSite, notIncludedMirrorSite]), - .mock(dataBrokerName: "Broker #2", lastRunDate: Date().yesterday), - .mock(dataBrokerName: "Broker #3") + .mock(dataBrokerName: "Broker #1", url: "broker1.com", lastRunDate: Date().yesterday, mirrorSites: [includedMirrorSite, notIncludedMirrorSite]), + .mock(dataBrokerName: "Broker #2", url: "broker2.com", lastRunDate: Date().yesterday), + .mock(dataBrokerName: "Broker #3", url: "broker3.com") ] let result = sut.maintenanceScanState(brokerProfileQueryData) @@ -291,12 +291,12 @@ final class MapperToUITests: XCTestCase { } func testNextScansWithMirrorSites_areMappedCorrectly() { - let includedMirrorSite = MirrorSite(name: "mirror #1", addedAt: Date.distantPast, removedAt: nil) - let notIncludedMirrorSite = MirrorSite(name: "mirror #2", addedAt: Date.distantPast, removedAt: Date()) + let includedMirrorSite = MirrorSite(name: "mirror #1", url: "mirror1.com", addedAt: Date.distantPast, removedAt: nil) + let notIncludedMirrorSite = MirrorSite(name: "mirror #2", url: "mirror2.com", addedAt: Date.distantPast, removedAt: Date()) let brokerProfileQueryData: [BrokerProfileQueryData] = [ - .mock(dataBrokerName: "Broker #1", preferredRunDate: Date().tomorrow, mirrorSites: [includedMirrorSite, notIncludedMirrorSite]), - .mock(dataBrokerName: "Broker #2", preferredRunDate: Date().tomorrow), - .mock(dataBrokerName: "Broker #3") + .mock(dataBrokerName: "Broker #1", url: "broker1.com", preferredRunDate: Date().tomorrow, mirrorSites: [includedMirrorSite, notIncludedMirrorSite]), + .mock(dataBrokerName: "Broker #2", url: "broker2.com", preferredRunDate: Date().tomorrow), + .mock(dataBrokerName: "Broker #3", url: "broker3.com") ] let result = sut.maintenanceScanState(brokerProfileQueryData) diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MismatchCalculatorUseCaseTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MismatchCalculatorUseCaseTests.swift index 8585792744..12b7120077 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MismatchCalculatorUseCaseTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/MismatchCalculatorUseCaseTests.swift @@ -152,6 +152,7 @@ extension BrokerProfileQueryData { BrokerProfileQueryData( dataBroker: DataBroker( name: "parent", + url: "parent.com", steps: [Step](), version: "1.0.0", schedulingConfig: DataBrokerScheduleConfig.mock @@ -165,6 +166,7 @@ extension BrokerProfileQueryData { BrokerProfileQueryData( dataBroker: DataBroker( name: "child", + url: "child.com", steps: [Step](), version: "1.0.0", schedulingConfig: DataBrokerScheduleConfig.mock, diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/Mocks.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/Mocks.swift index d053404255..95ea0d1493 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/Mocks.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/Mocks.swift @@ -27,6 +27,7 @@ import GRDB extension BrokerProfileQueryData { static func mock(with steps: [Step] = [Step](), dataBrokerName: String = "test", + url: String = "test.com", lastRunDate: Date? = nil, preferredRunDate: Date? = nil, extractedProfile: ExtractedProfile? = nil, @@ -36,6 +37,7 @@ extension BrokerProfileQueryData { BrokerProfileQueryData( dataBroker: DataBroker( name: dataBrokerName, + url: url, steps: steps, version: "1.0.0", schedulingConfig: DataBrokerScheduleConfig.mock, @@ -232,7 +234,7 @@ final class EmailServiceMock: EmailServiceProtocol { var shouldThrow: Bool = false - func getEmail(dataBrokerName: String?) async throws -> String { + func getEmail(dataBrokerURL: String?) async throws -> String { if shouldThrow { throw DataBrokerProtectionError.emailError(nil) } @@ -491,9 +493,9 @@ final class DataBrokerProtectionSecureVaultMock: DataBrokerProtectionSecureVault func fetchBroker(with name: String) throws -> DataBroker? { if shouldReturnOldVersionBroker { - return .init(id: 1, name: "Broker", steps: [Step](), version: "1.0.0", schedulingConfig: .mock) + return .init(id: 1, name: "Broker", url: "broker.com", steps: [Step](), version: "1.0.0", schedulingConfig: .mock) } else if shouldReturnNewVersionBroker { - return .init(id: 1, name: "Broker", steps: [Step](), version: "1.0.1", schedulingConfig: .mock) + return .init(id: 1, name: "Broker", url: "broker.com", steps: [Step](), version: "1.0.1", schedulingConfig: .mock) } return nil diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateUpdaterTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateUpdaterTests.swift index b9472a9ab9..369f80ee32 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateUpdaterTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/OperationPreferredDateUpdaterTests.swift @@ -35,6 +35,7 @@ final class OperationPreferredDateUpdaterTests: XCTestCase { let childBroker = DataBroker( id: 1, name: "Child broker", + url: "childbroker.com", steps: [Step](), version: "1.0", schedulingConfig: DataBrokerScheduleConfig(