-
Notifications
You must be signed in to change notification settings - Fork 85
/
DomainNameValidator.swift
60 lines (48 loc) · 1.65 KB
/
DomainNameValidator.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//
// DomainNameValidator.swift
// Lockdown
//
// Created by Oleg Dreyman on 19.05.2020.
// Copyright © 2020 Confirmed Inc. All rights reserved.
//
import Foundation
enum DomainNameValidator {
enum Status {
case valid
case notValid(FailureReason)
// Not currently shown to the user, but can be leveraged in the future
enum FailureReason {
case emptyString
case noDots
case invalidCharacters(in: String)
case labelEmpty
}
}
/// All "url host allowed" characters with the exception of the wildcard symbol
static let allowedChars = CharacterSet.urlHostAllowed
.subtracting(CharacterSet(charactersIn: "*"))
static func validate(_ domainName: String) -> Status {
guard domainName.isEmpty == false else {
return .notValid(.emptyString)
}
var labels = domainName.components(separatedBy: ".")
guard labels.count > 1 else {
return .notValid(.noDots)
}
// Wildcard is allowed only as a first label.
// If first label is a wildcard, we're removing
// it from the elements to validate
if labels.first == "*" {
labels.removeFirst()
}
for label in labels {
guard label.isEmpty == false else {
return .notValid(.labelEmpty)
}
guard allowedChars.isSuperset(of: CharacterSet(charactersIn: label)) else {
return .notValid(.invalidCharacters(in: label))
}
}
return .valid
}
}