aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/form-validators/host-validators.ts
blob: 3d9c476b5ff30870330423cb8e9a463e882d5f34 (plain) (blame)
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { AbstractControl, ValidatorFn, Validators } from '@angular/forms'
import { BuildFormValidator } from './form-validator.model'

export function validateHost (value: string) {
  // Thanks to http://stackoverflow.com/a/106223
  const HOST_REGEXP = new RegExp(
    '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$'
  )

  return HOST_REGEXP.test(value)
}

export function validateHandle (value: string) {
  if (!value) return false

  return value.includes('@')
}

const validHosts: ValidatorFn = (control: AbstractControl) => {
  if (!control.value) return null

  const errors = []
  const hosts = splitAndGetNotEmpty(control.value)

  for (const host of hosts) {
    if (validateHost(host) === false) {
      errors.push($localize`${host} is not valid`)
    }
  }

  // valid
  if (errors.length === 0) return null

  return {
    validHosts: {
      reason: 'invalid',
      value: errors.join('. ') + '.'
    }
  }
}

const validHostsOrHandles: ValidatorFn = (control: AbstractControl) => {
  if (!control.value) return null

  const errors = []
  const lines = splitAndGetNotEmpty(control.value)

  for (const line of lines) {
    if (validateHost(line) === false && validateHandle(line) === false) {
      errors.push($localize`${line} is not valid`)
    }
  }

  // valid
  if (errors.length === 0) return null

  return {
    validHostsOrHandles: {
      reason: 'invalid',
      value: errors.join('. ') + '.'
    }
  }
}

// ---------------------------------------------------------------------------

export function splitAndGetNotEmpty (value: string) {
  return value
    .split('\n')
    .filter(line => line && line.length !== 0) // Eject empty hosts
}

export const unique: ValidatorFn = (control: AbstractControl) => {
  if (!control.value) return null

  const hosts = splitAndGetNotEmpty(control.value)

  if (hosts.every((host: string) => hosts.indexOf(host) === hosts.lastIndexOf(host))) {
    return null
  }

  return {
    unique: {
      reason: 'invalid'
    }
  }
}

export const UNIQUE_HOSTS_VALIDATOR: BuildFormValidator = {
  VALIDATORS: [ Validators.required, validHosts, unique ],
  MESSAGES: {
    required: $localize`Domain is required.`,
    validHosts: $localize`Hosts entered are invalid.`,
    unique: $localize`Hosts entered contain duplicates.`
  }
}

export const UNIQUE_HOSTS_OR_HANDLE_VALIDATOR: BuildFormValidator = {
  VALIDATORS: [ Validators.required, validHostsOrHandles, unique ],
  MESSAGES: {
    required: $localize`Domain is required.`,
    validHostsOrHandles: $localize`Hosts or handles are invalid.`,
    unique: $localize`Hosts or handles contain duplicates.`
  }
}