Skip to content

Commit

Permalink
Add WHOIS XML API Website Contacts API endpoint #74 #112
Browse files Browse the repository at this point in the history
  • Loading branch information
techwinlabs committed Oct 21, 2022
1 parent a61ffe8 commit 83297a5
Show file tree
Hide file tree
Showing 14 changed files with 113 additions and 125 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="15400" systemVersion="19A602" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="ServiceUsage" representedClassName="ServiceUsage" syncable="YES" codeGenerationType="class">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21279" systemVersion="21G115" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="ServiceUsage" representedClassName="ServiceUsage" isAbstract="YES" syncable="YES" codeGenerationType="class">

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

I assume this was auto put there?

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

Yes

<attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="serviceName" optional="YES" attributeType="String"/>
</entity>
<elements>
<element name="ServiceUsage" positionX="-63" positionY="-18" width="128" height="73"/>
</elements>
</model>
2 changes: 1 addition & 1 deletion ec3730/Data Feeds/Google/GoogleWebRiskRecord.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ struct GoogleWebRiskRecordWrapper: Codable {

struct GoogleWebRiskRecord: Codable {
var threatTypes: [GoogleWebRisk.ThreatTypes]
var expireTime: Date
var expireTime: Date?

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

Did you run into issues where this was not set?

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

As per decode safely remote response, model i.e. raw representation of response should be execute safely without any crash.
That's why all values must be optional.
So in future, if any value will come null or different data type, response should be execute without any crash. This is for good end user experience.

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

But if we get a response and this isn't there it is probably a bad response and we should throw

Especially since there is no error parameter

}
24 changes: 19 additions & 5 deletions ec3730/Data Feeds/WhoisXML/WhoIsXmlContactsResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,32 @@ extension WhoIsXmlContactsResult {
}

init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
guard let data = json.data(using: encoding) else { throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) }

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

Please put back into 3 lines. Easier to set breakpoints

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

Sure

try self.init(data: data)
}

init(fromURL url: URL) throws {
try self.init(data: try Data(contentsOf: url))
}

func with(companyNames: [String]? = nil, countryCode: String? = nil, domainName: String? = nil, emails: [EmailData]? = nil, meta: Meta? = nil, phones: [PhoneData]? = nil, postalAddresses: [String]? = nil, socialLinks: SocialLinks? = nil, websiteResponded: Bool? = nil) -> WhoIsXmlContactsResult {
WhoIsXmlContactsResult(companyNames: companyNames ?? self.companyNames, countryCode: countryCode ?? self.countryCode, domainName: domainName ?? self.domainName, emails: emails ?? self.emails, meta: meta ?? self.meta, phones: phones ?? self.phones, postalAddresses: postalAddresses ?? self.postalAddresses, socialLinks: socialLinks ?? self.socialLinks, websiteResponded: websiteResponded ?? self.websiteResponded)
func with(companyNames: [String]? = nil,
countryCode: String? = nil,

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

thank you for breaking this up

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

Regards

domainName: String? = nil,
emails: [EmailData]? = nil,
meta: Meta? = nil,
phones: [PhoneData]? = nil,
postalAddresses: [String]? = nil,
socialLinks: SocialLinks? = nil,
websiteResponded: Bool? = nil) -> WhoIsXmlContactsResult {
WhoIsXmlContactsResult(companyNames: companyNames ?? self.companyNames,
countryCode: countryCode ?? self.countryCode,
domainName: domainName ?? self.domainName,
emails: emails ?? self.emails,
meta: meta ?? self.meta,
phones: phones ?? self.phones,
postalAddresses: postalAddresses ?? self.postalAddresses,
socialLinks: socialLinks ?? self.socialLinks,
websiteResponded: websiteResponded ?? self.websiteResponded)
}

func jsonData() throws -> Data {
Expand Down
22 changes: 11 additions & 11 deletions ec3730/Data Feeds/WhoisXML/WhoisDnsResults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

struct DnsCoordinate: Codable {
let dnsData: DNSResults
let dnsData: DNSResults?

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

Did you run into issues where this was not set?

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

Response model data type should be optional.
Explanation: Mentioned above
Reference: ec3730/Data Feeds/Google/GoogleWebRiskRecord.swift

let error: String?

enum CodingKeys: String, CodingKey {
Expand Down Expand Up @@ -50,10 +50,10 @@ extension DnsCoordinate {
}

struct DNSResults: Codable {
let domainName: String
let types: [Int]
let dnsTypes: String
let audit: WhoisRecordAudit
let domainName: String?
let types: [Int]?
let dnsTypes: String?
let audit: WhoisRecordAudit?
let dnsRecords: [DNSRecords]?
}

Expand Down Expand Up @@ -91,12 +91,12 @@ extension DNSResults {
}

struct DNSRecords: Codable {
let type: Int
let dnsType: String
let name: String
let ttl: Int
let rRsetType: Int
let rawText: String
let type: Int?

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

Same as above

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

Response model data type should be optional.
Explanation: Mentioned above
Reference: ec3730/Data Feeds/Google/GoogleWebRiskRecord.swift

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

I think it's fine when there is the optional error? but if there is nothing in a DNSRecord then it is probably malformed and we should be throwing

let dnsType: String?
let name: String?
let ttl: Int?
let rRsetType: Int?
let rawText: String?

// optionals
let address: String?
Expand Down
56 changes: 28 additions & 28 deletions ec3730/Data Feeds/WhoisXML/WhoisRecord.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Foundation
// MARK: - Coordinate

struct Coordinate: Codable {
let whoisRecord: WhoisRecord
let whoisRecord: WhoisRecord?
let error: String?

enum CodingKeys: String, CodingKey {
Expand Down Expand Up @@ -79,7 +79,7 @@ extension Coordinate {

struct WhoisRecord: Codable {
let administrativeContact: WhoisRecordAdministrativeContact?
let audit: WhoisRecordAudit
let audit: WhoisRecordAudit?
let billingContact: WhoisRecordBillingContact?
let contactEmail: String?
let createdDate, createdDateNormalized: Date?
Expand Down Expand Up @@ -230,7 +230,7 @@ struct WhoisRecordAdministrativeContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -325,7 +325,7 @@ extension WhoisRecordAdministrativeContact {
// MARK: - WhoisRecordAudit

struct WhoisRecordAudit: Codable {
let createdDate, updatedDate: Date
let createdDate, updatedDate: Date?
}

// MARK: WhoisRecordAudit convenience initializers and mutators
Expand All @@ -347,12 +347,12 @@ extension WhoisRecordAudit {
}

func with(
createdDate: Date? = nil,
updatedDate: Date? = nil
createdDate _: Date? = nil,
updatedDate _: Date? = nil
) -> WhoisRecordAudit {
WhoisRecordAudit(
createdDate: createdDate ?? self.createdDate,
updatedDate: updatedDate ?? self.updatedDate
createdDate: createdDate ?? createdDate,
updatedDate: updatedDate ?? updatedDate
)
}

Expand Down Expand Up @@ -382,7 +382,7 @@ struct WhoisRecordBillingContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -477,9 +477,9 @@ extension WhoisRecordBillingContact {
// MARK: - WhoisRecordNameServers

struct WhoisRecordNameServers: Codable {
let hostNames: [String]
let hostNames: [String]?
let ips: [JSONAny]?
let rawText: String
let rawText: String?
}

// MARK: WhoisRecordNameServers convenience initializers and mutators
Expand Down Expand Up @@ -538,7 +538,7 @@ struct Registrant: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -634,23 +634,23 @@ extension Registrant {

struct RegistryData: Codable {
let administrativeContact: RegistryDataAdministrativeContact?
let audit: RegistryDataAudit
let audit: RegistryDataAudit?
let billingContact: RegistryDataBillingContact?
let createdDate, createdDateNormalized: Date?
let customField1Name, customField1Value, customField2Name, customField2Value: String?
let customField3Name, customField3Value: String?
let domainName: String
let domainName: String?
let expiresDate, expiresDateNormalized: Date?
let footer, header: String?
let nameServers: RegistryDataNameServers?
let parseCode: Int
let rawText: String
let parseCode: Int?
let rawText: String?
let registrarIANAID, registrarName: String?
let regustrant: Regustrant?
let status, strippedText: String?
let technicalContact: RegistryDataTechnicalContact?
let updatedDate, updatedDateNormalized: Date?
let whoisServer: String
let whoisServer: String?
let dataError: String?
let zoneContact: RegistryDataZoneContact?
}
Expand Down Expand Up @@ -764,7 +764,7 @@ struct RegistryDataAdministrativeContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -859,7 +859,7 @@ extension RegistryDataAdministrativeContact {
// MARK: - RegistryDataAudit

struct RegistryDataAudit: Codable {
let createdDate, updatedDate: Date
let createdDate, updatedDate: Date?
}

// MARK: RegistryDataAudit convenience initializers and mutators
Expand Down Expand Up @@ -916,7 +916,7 @@ struct RegistryDataBillingContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -1011,9 +1011,9 @@ extension RegistryDataBillingContact {
// MARK: - RegistryDataNameServers

struct RegistryDataNameServers: Codable {
let hostNames: [String]
let hostNames: [String]?
let ips: [JSONAny]?
let rawText: String
let rawText: String?
}

// MARK: RegistryDataNameServers convenience initializers and mutators
Expand Down Expand Up @@ -1069,10 +1069,10 @@ extension RegistryDataNameServers {

struct Regustrant: Codable {
let city, name, organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4: String?
let unparsable: String
let unparsable: String?
}

// MARK: Regustrant convenience initializers and mutators
Expand Down Expand Up @@ -1147,7 +1147,7 @@ struct RegistryDataTechnicalContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -1246,7 +1246,7 @@ struct RegistryDataZoneContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -1345,7 +1345,7 @@ struct WhoisRecordTechnicalContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down Expand Up @@ -1444,7 +1444,7 @@ struct WhoisRecordZoneContact: Codable {
let country, countryCode: String?
let email, fax, faxEXT, name: String?
let organization, postalCode: String?
let rawText: String
let rawText: String?
let state, street1, street2, street3: String?
let street4, telephone, telephoneEXT, unparsable: String?

Expand Down
21 changes: 14 additions & 7 deletions ec3730/Data Feeds/WhoisXML/WhoisXMLService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class WhoisXMLService: Service {
block?(error, nil)
return
}

guard let data = data else {
block?(DataFeedError.empty, nil)
return
Expand Down Expand Up @@ -200,22 +201,28 @@ class WhoisXMLService: Service {
throw DataFeedError.invalidUrl
}

let minimumBalance = userData?["minimumBalance"] as? Int ?? 100
// TODO: Response
// below #208, #215, #216, due to balance validation some services haven't any data,
// if you want to check please uncomment above mentioned line number (#)

// let minimumBalance = userData?["minimumBalance"] as? Int ?? 100

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

Starting balance is 100 for Contacts API so minimum balance should probably be like 25? or 10?


if let cached: T = cache.value(for: endpointURL.absoluteString) {
usage += 1
return cached
}

let balance = try await balance(for: WhoisXml.current.userKey)

guard balance > minimumBalance else {
throw DataFeedError.lowBalance(balance: balance)
}
// let balance = try await balance(for: WhoisXml.current.userKey)
// guard balance > minimumBalance else { throw DataFeedError.lowBalance(balance: balance) }

usage += 1

let (data, _) = try await WhoisXml.session.data(from: endpointURL)

// TODO: Response
// uncomment below #223, #224 line for validate response
// if let dataIntoStr = String(data: data, encoding: .utf8) { debugPrint("services response: ", dataIntoStr) }
// else { debugPrint("services haven't any data due to balance or parse error") }

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom {
decoder in
Expand Down
3 changes: 1 addition & 2 deletions ec3730/Data Feeds/WhoisXML/WhoisXml.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ extension WhoisXml {
params.append(URLQueryItem(name: "apiKey", value: key))
}

return Endpoint(host: "api.netutils.workers.dev",
path: "/service/account-balance", queryItems: params).url
return Endpoint(host: "api.netutils.workers.dev", path: "/service/account-balance", queryItems: params).url

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

keep broken up

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

Sure

}
}
}
Expand Down
19 changes: 5 additions & 14 deletions ec3730/Data Feeds/WhoisXML/WhoisXmlContactsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,18 @@
// Copyright © 2022 Zachary Gorak. All rights reserved.
//

import Foundation

import UIKit

class WhoisXmlContactsService: WhoisXMLService {
fileprivate var contactServiceAPIKey = "at_l54dNyKOiaxH5KV9BWZbNPiOkksmK"

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

remove

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

FYSA you can set your own key in the settings

This comment has been minimized.

Copy link
@iphone201988

iphone201988 Oct 21, 2022

Contributor

Sure


override func endpoint(_ userData: [String: Any?]?) -> DataFeedEndpoint? {
guard let userData = userData, let userInput = userData["domain"] as? String, let domain = userInput.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else {
return nil
}

var params = [URLQueryItem(name: "domainName", value: domain),
URLQueryItem(name: "outputFormat", value: "JSON"),
URLQueryItem(name: "type", value: "_all"),
URLQueryItem(name: "api", value: "whoisXml"),
URLQueryItem(name: "identifierForVendor", value: UIDevice.current.identifierForVendor?.uuidString),
URLQueryItem(name: "bundleIdentifier", value: Bundle.main.bundleIdentifier)]

This comment has been minimized.

Copy link
@twodayslate

twodayslate Oct 21, 2022

Owner

Let's leave this in for the API service. It is stripped out

See https://github.com/twodayslate/NetUtils/blob/master/cloudflare_worker.js


if let key = WhoisXml.current.userKey {
params.append(URLQueryItem(name: "apiKey", value: key))
}

return WhoisXml.Endpoint(host: "api.netutils.workers.dev", path: "/whoisserver/DNSService", queryItems: params)
let params = [URLQueryItem(name: "domainName", value: domain),
URLQueryItem(name: "apiKey", value: contactServiceAPIKey)]
return WhoisXml.Endpoint(host: "website-contacts.whoisxmlapi.com", path: "/api/v1", queryItems: params)
}
}
Loading

3 comments on commit 83297a5

@twodayslate
Copy link
Owner

@twodayslate twodayslate commented on 83297a5 Oct 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of this should be reverted. Unless you actually found a response where it should be optional

@twodayslate
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created #113 based on your feedback

@twodayslate
Copy link
Owner

@twodayslate twodayslate commented on 83297a5 Oct 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's break this pull request into smaller parts. So please just have the Contacts API changes.

If you have found an actual parsing bug please document/create a ticket.

Please sign in to comment.