{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "description": "The settings for the web interface",
  "additionalProperties": false,
  "required": ["version", "listeners", "hosts"],
  "definitions": {
    "features": {
      "type": "object",
      "properties": {
        "preview": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": true
            }
          }
        },
        "rates": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": true
            }
          }
        },
        "memory": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": true
            }
          }
        },
        "datamasking": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "localpart": {
              "type": "boolean",
              "default": false
            },
            "subject": {
              "type": "boolean",
              "default": false
            },
            "retryreason": {
              "type": "boolean",
              "default": false
            },
            "saslusername": {
              "type": "boolean",
              "default": false
            }
          }
        },
        "readonly": {
          "type": "boolean",
          "default": false
        },
        "writable": {
          "type": "array",
          "items": {
            "type": "string",
            "description": "If readonly is enabled globally but access of individial command is wanted.",
            "enum": [
              "a",
              "b",
              "c",
              "e",
              "f",
              "g",
              "h",
              "o",
              "p",
              "q",
              "r",
              "s",
              "t",
              "O",
              "u",
              "v",
              "w",
              "P",
              "x",
              "y",
              "z",
              "A",
              "B",
              "C",
              "D",
              "E",
              "J",
              "I",
              "F",
              "G",
              "H",
              "K",
              "L",
              "M",
              "N",
              "Q",
              "R",
              "S",
              "T",
              "U",
              "V",
              "W",
              "X",
              "i",
              "j",
              "l",
              "m"
            ]
          }
        }
      },
      "dependencies": {
        "writable": {
          "properties": {
            "readonly": {
              "enum": [true]
            }
          }
        }
      }
    }
  },
  "properties": {
    "version": {
      "type": "string",
      "enum": ["1.28"],
      "description": "The software version the configuration was created for"
    },
    "instance": {
      "type": "string",
      "description": "The name that will be shown in the document title"
    },
    "accounting": {
      "type": "boolean",
      "default": false,
      "description": "If accounting logs should be generated"
    },
    "listeners": {
      "type": "array",
      "uniqueItems": true,
      "minItems": 1,
      "description": "The IP addresses and ports to listen on. If no IP addresses are specificed it will bind to any (both IPv4 and IPv6)",
      "items": {
        "type": "object",
        "required": ["port"],
        "additionalProperties": false,
        "properties": {
          "port": {
            "type": "integer",
            "maximum": 65535,
            "minimum": 1,
            "description": "Port number"
          },
          "address": {
            "description": "IP address",
            "anyOf": [
              {
                "type": "string",
                "format": "ipv4",
                "description": "IPv4 address"
              },
              {
                "type": "string",
                "format": "ipv6",
                "description": "IPv6 address"
              }
            ]
          },
          "tls": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "pki": {
                "type": "object",
                "description": "The X.509 certificate and private key",
                "additionalProperties": false,
                "required": ["certificate", "privatekey"],
                "properties": {
                  "certificate": {
                    "oneOf": [
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["data"],
                        "properties": {
                          "data": {
                            "type": "string",
                            "minLength": 1,
                            "description": "The PKCS #8 PEM data"
                          }
                        }
                      },
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["path"],
                        "properties": {
                          "path": {
                            "type": "string",
                            "minLength": 1,
                            "description": "The PKCS #8 PEM path"
                          }
                        }
                      }
                    ]
                  },
                  "privatekey": {
                    "oneOf": [
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["data"],
                        "properties": {
                          "data": {
                            "type": "string",
                            "minLength": 1,
                            "description": "The private key data"
                          }
                        }
                      },
                      {
                        "type": "object",
                        "additionalProperties": false,
                        "required": ["path"],
                        "properties": {
                          "path": {
                            "type": "string",
                            "minLength": 1,
                            "description": "The private key path"
                          }
                        }
                      }
                    ]
                  }
                }
              },
              "ciphers": {
                "type": "string",
                "description": "Cipher suite specification"
              },
              "protocols": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "min": {
                    "type": "string",
                    "enum": ["TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1"],
                    "description": "Minimum TLS version to allow"
                  },
                  "max": {
                    "type": "string",
                    "enum": ["TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1"],
                    "description": "Maximum TLS version to allow"
                  }
                }
              }
            }
          },
          "proxy": {
            "type": "object",
            "required": ["trust"],
            "additionalProperties": false,
            "properties": {
              "trust": {
                "oneOf": [
                  {
                    "type": "boolean",
                    "description": "Trust all IP-addresses and subnets as being reverse proxies",
                    "default": false
                  },
                  {
                    "type": "array",
                    "uniqueItems": true,
                    "minItems": 1,
                    "description": "A list of IP addresses and subnets to trust as being reverse proxies",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    },
                    "default": []
                  }
                ]
              },
              "userheader": {
                "type": "string",
                "minLength": 1,
                "description": "This setting allows for automatic login when behind a reverse proxy. If configured, this header should be set by the reverse proxy and contain the username for the session"
              },
              "groupheader": {
                "type": "string",
                "minLength": 1,
                "description": "When logging in via reverse proxy. This header is set to assign group permissions for the user."
              }
            }
          }
        }
      }
    },
    "hosts": {
      "type": "array",
      "uniqueItems": true,
      "minItems": 1,
      "description": "The Halon MTA node(s)",
      "items": {
        "type": "object",
        "required": ["address", "port"],
        "additionalProperties": false,
        "properties": {
          "processes": {
            "type": "array",
            "uniqueItems": true,
            "minItems": 1,
            "description": "The processes that are running on the host",
            "items": {
              "enum": ["smtpd", "rated"]
            },
            "default": ["smtpd", "rated"]
          },
          "address": {
            "description": "IP address or hostname",
            "anyOf": [
              {
                "type": "string",
                "format": "ipv4",
                "description": "IPv4 address"
              },
              {
                "type": "string",
                "format": "ipv6",
                "description": "IPv6 address"
              },
              {
                "type": "string",
                "description": "Hostname"
              }
            ]
          },
          "expand": {
            "type": "boolean",
            "default": false,
            "description": "Add all IP addresses for the hostname as unique hosts"
          },
          "kubernetes": {
            "type": "object",
            "description": "Kubernetes settings",
            "additionalProperties": false,
            "required": ["namespace", "name"],
            "properties": {
              "namespace": {
                "type": "string",
                "description": "The namespace for the smtpd StatefulSet"
              },
              "name": {
                "type": "string",
                "description": "The name for the smtpd StatefulSet"
              }
            }
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "The display name. The default is the address. Cannot be combined with the expand option"
          },
          "port": {
            "type": "integer",
            "maximum": 65535,
            "minimum": 1,
            "description": "Port number"
          },
          "tls": {
            "oneOf": [
              {
                "type": "boolean",
                "default": false,
                "description": "If TLS should be used for the requests"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "description": "The TLS options",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "default": false,
                    "description": "If TLS should be used for the requests"
                  },
                  "verify": {
                    "type": "boolean",
                    "default": true,
                    "description": "If the server certificate should be verified"
                  },
                  "verifyname": {
                    "type": "string",
                    "description": "Hostname to verify against"
                  }
                }
              }
            ]
          },
          "secret": {
            "type": "string",
            "minLength": 1,
            "description": "The secret that will be sent in the requests using the X-API-Key header"
          },
          "timeout": {
            "type": "integer",
            "minimum": 1,
            "default": 5,
            "description": "The timeout against the node (in seconds)"
          }
        }
      }
    },
    "database": {
      "type": "object",
      "description": "Enable database storage for per-user settings (knex)",
      "required": ["client", "connection"],
      "properties": {
        "client": {
          "type": "string",
          "enum": ["sqlite3", "pg", "mysql", "mysql2"],
          "description": "The database driver"
        },
        "connection": {
          "oneOf": [
            {
              "description": "The database connection settings",
              "type": "string"
            },
            {
              "description": "The database connection settings",
              "type": "object"
            }
          ]
        }
      }
    },
    "elasticsearch": {
      "type": "object",
      "properties": {
        "index": {
          "oneOf": [
            {
              "type": "string",
              "description": "The index pattern for Elasticsearch"
            },
            {
              "type": "object",
              "description": "The index pattern for Elasticsearch",
              "properties": {
                "history": {
                  "type": "string",
                  "description": "The index pattern for history logs"
                },
                "policyd": {
                  "type": "string",
                  "description": "The index pattern for policyd logs"
                }
              },
              "required": ["history"]
            }
          ]
        },
        "nodes": {
          "type": "array",
          "description": "A list of Elasticsearch nodes",
          "items": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "agent": {},
              "ssl": {},
              "headers": {
                "type": "object"
              }
            },
            "required": ["url"],
            "additionalProperties": false
          }
        },
        "auth": {
          "type": "object",
          "description": "Authentication for the Elasticsearch nodes",
          "properties": {
            "username": {
              "type": "string"
            },
            "password": {
              "type": "string"
            }
          },
          "required": ["username", "password"],
          "additionalProperties": false
        },
        "tls": {
          "type": "object",
          "description": "TLS settings",
          "properties": {
            "rejectUnauthorized": {
              "type": "boolean",
              "default": true
            }
          }
        }
      },
      "required": ["index", "nodes"],
      "additionalProperties": false
    },
    "reresolve": {
      "type": "number",
      "minimum": 1,
      "description": "Automatically re-resolve the hostnames of the hosts every x seconds (The default is to never re-resolve the hostnames of the hosts automatically)"
    },
    "trustedorigins": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "List of trusted origins"
    },
    "oidc": {
      "type": "object",
      "additionalProperties": false,
      "required": ["enabled", "provider"],
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": false,
          "description": "If OIDC should be enabled"
        },
        "provider": {
          "description": "The OIDC provider",
          "type": "object",
          "required": [
            "providerid",
            "discoveryurl",
            "clientid",
            "clientsecret"
          ],
          "properties": {
            "providerid": {
              "type": "string",
              "minLength": 1,
              "description": "The unique provider ID"
            },
            "discoveryurl": {
              "type": "string",
              "minLength": 1,
              "description": "The OIDC discovery URL"
            },
            "clientid": {
              "type": "string",
              "minLength": 1,
              "description": "The OIDC client ID"
            },
            "clientsecret": {
              "type": "string",
              "minLength": 1,
              "description": "The OIDC client secret"
            },
            "pkce": {
              "type": "boolean",
              "default": true,
              "description": "If PKCE should be used"
            },
            "groupclaim": {
              "type": "string",
              "minLength": 1,
              "description": "The claim containing the users group(s), matches against configured groups in YAML config"
            },
            "allowedgroups": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "description": "List of allowed config groups that oidc users can be a part of"
            },
            "displayname": {
              "type": "string",
              "minLength": 1,
              "description": "The display name of the provider"
            },
            "displayicon": {
              "oneOf": [
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["data", "extension"],
                  "properties": {
                    "data": {
                      "type": "string",
                      "minLength": 1,
                      "description": "An absolute path to the icon"
                    },
                    "extension": {
                      "type": "string",
                      "enum": [".png", ".svg"],
                      "minLength": 1,
                      "description": "The file extension of the icon. Supported extensions are .png and .svg"
                    }
                  }
                },
                {
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["path"],
                  "properties": {
                    "path": {
                      "type": "string",
                      "minLength": 1,
                      "description": "An absolute path to the icon"
                    },
                    "extension": {
                      "type": "string",
                      "enum": [".png", ".svg"],
                      "minLength": 1,
                      "description": "The file extension of the icon. Supported extensions are .png and .svg"
                    }
                  }
                }
              ]
            }
          },
          "allOf": [
            {
              "if": {
                "properties": { "groupclaim": { "type": "string" } },
                "required": ["groupclaim"]
              },
              "then": {
                "required": ["allowedgroups"]
              },
              "else": {
                "not": { "required": ["allowedgroups"] }
              }
            }
          ]
        }
      }
    },
    "users": {
      "type": "array",
      "uniqueItems": true,
      "description": "The users",
      "default": [],
      "items": {
        "type": "object",
        "required": ["username"],
        "additionalProperties": false,
        "properties": {
          "username": {
            "type": "string",
            "description": "The username"
          },
          "password": {
            "type": "string",
            "description": "The password"
          },
          "features": {
            "$ref": "#/definitions/features"
          },
          "group": {
            "type": "string",
            "description": "Group user belongs to."
          }
        }
      }
    },
    "groups": {
      "type": "array",
      "uniqueItems": true,
      "description": "User groups",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the group"
          },
          "features": {
            "$ref": "#/definitions/features"
          }
        }
      }
    },
    "solution": {
      "type": "string",
      "enum": ["engage", "protect"],
      "description": "The solution"
    },
    "environment": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "privdrop": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "user": {
              "type": "string",
              "description": "Privdrop user"
            },
            "group": {
              "type": "string",
              "description": "Privdrop group"
            }
          }
        },
        "session": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "secret": {
              "type": "string",
              "minLength": 32,
              "description": "The secret used for encryption, signing, and hashing. The default is to generate a unique UUID during startup"
            }
          }
        }
      }
    },
    "policyd": {
      "type": "object",
      "additionalProperties": false,
      "required": ["address", "port"],
      "properties": {
        "address": {
          "anyOf": [
            {
              "type": "string",
              "description": "The hostname of the policyd server"
            },
            {
              "type": "string",
              "format": "ipv4",
              "description": "The IP address of the policyd server"
            },
            {
              "type": "string",
              "format": "ipv6",
              "description": "The IP address of the policyd server"
            }
          ]
        },
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535,
          "default": 10025,
          "description": "The port of the policyd server"
        },
        "tls": {
          "oneOf": [
            {
              "type": "boolean",
              "default": false,
              "description": "If TLS should be used for the requests"
            },
            {
              "type": "object",
              "additionalProperties": false,
              "description": "The TLS options",
              "properties": {
                "enabled": {
                  "type": "boolean",
                  "default": false,
                  "description": "If TLS should be used for the requests"
                },
                "verify": {
                  "type": "boolean",
                  "default": true,
                  "description": "If the server certificate should be verified"
                }
              }
            }
          ]
        },
        "secret": {
          "type": "string",
          "minLength": 1,
          "description": "The secret that will be sent in the requests using the X-API-Key header"
        }
      }
    },
    "maxmind": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "geoip": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "path": {
              "type": "string",
              "default": "/var/lib/GeoIP/GeoLite2-Country.mmdb",
              "description": "The directory to MaxMind's GeoIP database"
            }
          }
        }
      }
    }
  }
}
