1 | const sldMap = require('./domains/sld')
|
2 |
|
3 | module.exports = function isValidDomain(value, opts) {
|
4 | if (typeof value !== 'string') return false
|
5 | if (!(opts instanceof Object)) opts = {}
|
6 | value = value.toLowerCase()
|
7 |
|
8 | if (value.endsWith('.')) {
|
9 | value = value.slice(0, value.length-1)
|
10 | }
|
11 |
|
12 | if (value.length > 253) {
|
13 | return false
|
14 | }
|
15 |
|
16 | const validChars = /^([a-z0-9-._*]+)$/g
|
17 | if (!validChars.test(value)) {
|
18 | return false
|
19 | }
|
20 |
|
21 | const sldRegex = /(.*)\.(([a-z0-9]+)(\.[a-z0-9]+))/
|
22 | const matches = value.match(sldRegex)
|
23 | var tld = null
|
24 | var labels = null
|
25 | if (matches && matches.length > 2) {
|
26 | if (sldMap[matches[2]]) {
|
27 | tld = matches[2]
|
28 | labels = matches[1].split('.')
|
29 | }
|
30 | }
|
31 |
|
32 | if (!labels) {
|
33 | labels = value.split('.')
|
34 | if (labels.length <= 1) return false
|
35 |
|
36 | tld = labels.pop()
|
37 | const tldRegex = /^(?:xn--)?(?!^\d+$)[a-z0-9]+$/gi
|
38 |
|
39 | if (!tldRegex.test(tld)) return false
|
40 | }
|
41 |
|
42 | if (opts.subdomain == false && labels.length > 1) return false
|
43 |
|
44 | const isValid = labels.every(function(label, index) {
|
45 | if (opts.wildcard && index === 0 && label === '*' && labels.length > 1) {
|
46 | return true
|
47 | }
|
48 |
|
49 | let validLabelChars = /^([a-zA-Z0-9-_]+)$/g
|
50 | if (index === labels.length - 1) {
|
51 | validLabelChars = /^([a-zA-Z0-9-]+)$/g
|
52 | }
|
53 |
|
54 | const doubleDashCount = (label.match(/--/g) || []).length
|
55 | const xnDashCount = (label.match(/xn--/g) || []).length
|
56 | if (doubleDashCount !== xnDashCount) {
|
57 | return false
|
58 | }
|
59 |
|
60 | const isValid = (
|
61 | validLabelChars.test(label) &&
|
62 | label.length < 64 &&
|
63 | !label.startsWith('-') &&
|
64 | !label.endsWith('-')
|
65 | )
|
66 |
|
67 | return isValid
|
68 | })
|
69 |
|
70 | return isValid
|
71 | } |
\ | No newline at end of file |