2920 lines
No EOL
88 KiB
JSON
2920 lines
No EOL
88 KiB
JSON
{
|
|
"views": [
|
|
{
|
|
"id": "view_overview",
|
|
"client_requirement": "client_is_nothing+",
|
|
"items": [
|
|
{
|
|
"type": "auth_wrapper",
|
|
"client_requirement": "client_is_nothing=",
|
|
"items": [
|
|
{
|
|
"type": "auth_card",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Routlin Dashboard"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Log in to monitor and manage your network."
|
|
},
|
|
{
|
|
"type": "spacer"
|
|
},
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/view/view_log_in",
|
|
"text": "Log In"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "page_header",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Overview"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Current network status at a glance."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "stat_card_grid",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "stat_card",
|
|
"label": "DHCP Leases",
|
|
"value": "%STAT_LEASE_COUNT%",
|
|
"sub": "active leases",
|
|
"variant": "accent"
|
|
},
|
|
{
|
|
"type": "stat_card",
|
|
"label": "Queries Blocked",
|
|
"value": "%STAT_BLOCKED_TODAY%",
|
|
"sub": "since midnight",
|
|
"variant": "warning"
|
|
},
|
|
{
|
|
"type": "stat_card",
|
|
"label": "Public IP",
|
|
"value": "%STAT_PUBLIC_IP%",
|
|
"sub": "%STAT_DDNS_HOSTNAME%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Network",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "grid",
|
|
"rows": [
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "WAN Interface"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%GENERAL_WAN_INTERFACE%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "VLANs"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%OVERVIEW_VLAN_NAMES%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Firewall"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%STAT_NFTABLES_STATUS%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "System Uptime"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%STAT_UPTIME%"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "DNS Blocking",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "grid",
|
|
"rows": [
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Blocked Domains"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%STAT_BLOCKED_DOMAINS%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Active Blocklists"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%STAT_BLOCKLIST_COUNT% lists"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Last Refreshed"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%STAT_BL_LAST_UPDATE%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Active IP Bans"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%STAT_BANNED_IP_COUNT% rules"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "DNS Caching",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "grid",
|
|
"rows": [
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Total Queries"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%DNS_STAT_QUERIES%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Cache Hits"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%DNS_STAT_HITS% (%DNS_STAT_HIT_RATE% hit rate)"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Forwarded"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%DNS_STAT_FORWARDED%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Cache Capacity"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%DNS_CACHE_SIZE% entries"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "Authoritative Answers"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%DNS_STAT_AUTH%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "TCP Connections Peak"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%DNS_STAT_TCP_PEAK%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"cells": [
|
|
{
|
|
"type": "grid_label",
|
|
"text": "DNS Providers"
|
|
},
|
|
{
|
|
"type": "grid_value",
|
|
"text": "%OVERVIEW_UPSTREAM_SERVERS%"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_ddns",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "DDNS"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Dynamic DNS provider status and last known IP update."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "stat_card_grid",
|
|
"items": [
|
|
{
|
|
"type": "stat_card",
|
|
"label": "Current Public IP",
|
|
"value": "%STAT_PUBLIC_IP%",
|
|
"sub": "%STAT_PUBLIC_IP_LAST_OBTAINED%"
|
|
},
|
|
{
|
|
"type": "stat_card",
|
|
"label": "Check Interval",
|
|
"value": "%DDNS_TIMER_INTERVAL%",
|
|
"sub": "%STAT_PUBLIC_IP_LAST_CHECKED%",
|
|
"edit_action": "/action/ddns_cardinterval_save",
|
|
"edit_field": "timer_interval",
|
|
"edit_input_type": "number",
|
|
"edit_min": "1",
|
|
"edit_suffix": "minutes",
|
|
"edit_value": "%DDNS_TIMER_INTERVAL_MINS%"
|
|
},
|
|
{
|
|
"type": "stat_card",
|
|
"label": "IP Check Services",
|
|
"value": "%STAT_IP_CHECK_TOTAL%",
|
|
"sub": "%STAT_IP_CHECK_SUB%",
|
|
"reveal_card_id": "ip-check-services-edit"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "ip-check-services-edit",
|
|
"label": "IP Check Services",
|
|
"hidden": true,
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/ddns_ip_check_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "editable_list",
|
|
"label": "HTTP APIs",
|
|
"name": "http_services",
|
|
"item_placeholder": "https://...",
|
|
"add_label": "Add HTTP API",
|
|
"items": "%IP_CHECK_HTTP_JSON%"
|
|
},
|
|
{
|
|
"type": "editable_list",
|
|
"label": "Dig APIs",
|
|
"name": "dig_services",
|
|
"item_placeholder": "e.g. @1.1.1.1 ch txt whoami.cloudflare",
|
|
"add_label": "Add Dig API",
|
|
"items": "%IP_CHECK_DIG_JSON%"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel",
|
|
"class": "js-hide-card"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:ddns_providers",
|
|
"empty_message": "No DDNS providers configured.",
|
|
"columns": [
|
|
{
|
|
"label": "Description",
|
|
"field": "description"
|
|
},
|
|
{
|
|
"label": "Provider",
|
|
"field": "provider"
|
|
},
|
|
{
|
|
"label": "Hostname(s)",
|
|
"field": "hostnames",
|
|
"render": "tag_list"
|
|
},
|
|
{
|
|
"label": "Status",
|
|
"field": "enabled",
|
|
"render": "badge_enabled_disabled"
|
|
},
|
|
{
|
|
"label": "Credentials",
|
|
"field": "credentials",
|
|
"render": "raw_html"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_ddns_provider",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "description",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "provider",
|
|
"input_type": "select",
|
|
"options": "%DDNS_PROVIDER_OPTIONS%"
|
|
},
|
|
{
|
|
"col": "hostnames",
|
|
"input_type": "textarea"
|
|
},
|
|
{
|
|
"col": "enabled",
|
|
"input_type": "checkbox"
|
|
},
|
|
{
|
|
"col": "credentials",
|
|
"input_type": "credentials"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_ddns_provider",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Add DDNS Account",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_ddns_provider",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Description",
|
|
"name": "description",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. My DuckDNS Account"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Provider",
|
|
"name": "provider",
|
|
"input_type": "select",
|
|
"options": "%DDNS_PROVIDER_OPTIONS%"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Hostnames (one per line)",
|
|
"name": "hostnames",
|
|
"input_type": "textarea",
|
|
"placeholder": "e.g. myhome.duckdns.org"
|
|
},
|
|
{
|
|
"type": "credential_fields",
|
|
"provider_select": "provider"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_ddns_provider",
|
|
"method": "post",
|
|
"text": "Add Provider"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "DDNS Log",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "pre_block",
|
|
"text": "%DDNS_LOG_TAIL%",
|
|
"scroll_to_bottom": true
|
|
},
|
|
{
|
|
"type": "raw_html",
|
|
"html": "%DDNS_LOG_SUMMARY%"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_danger",
|
|
"action": "/action/clear_ddns_log",
|
|
"method": "post",
|
|
"text": "Clear Log"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "hr"
|
|
},
|
|
{
|
|
"type": "form",
|
|
"action": "/action/ddns_cardlog_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Max Log Size (KB)",
|
|
"name": "log_max_kb",
|
|
"input_type": "number",
|
|
"layout": "inline",
|
|
"value": "%DDNS_GEN_LOG_MAX_KB%",
|
|
"min": "64"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "",
|
|
"name": "log_errors_only",
|
|
"input_type": "checkbox",
|
|
"checkbox_label": "Only record errors to log",
|
|
"value": "%DDNS_GEN_LOG_ERRORS_ONLY%"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_general",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "General Settings"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Core network and logging configuration from core.json."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Logging",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/general_cardlogging_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Max Log Size (KB)",
|
|
"name": "log_max_kb",
|
|
"input_type": "number",
|
|
"value": "%GENERAL_LOG_MAX_KB%",
|
|
"min": 64,
|
|
"hint": "Log is cleared and restarted when it exceeds this size."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Errors Only",
|
|
"name": "log_errors_only",
|
|
"input_type": "checkbox",
|
|
"value": "%GENERAL_LOG_ERRORS_ONLY%",
|
|
"hint": "Only write error-level messages to the log."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Log DNS Queries",
|
|
"name": "dnsmasq_log_queries",
|
|
"input_type": "checkbox",
|
|
"value": "%GENERAL_DNSMASQ_LOG_QUERIES%",
|
|
"hint": "Log every DNS query. High volume \u2014 enable for debugging only."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/general_cardlogging_save",
|
|
"method": "post",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Pending Changes",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/general_cardpendingchanges_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Apply on Save",
|
|
"name": "apply_on_save",
|
|
"input_type": "checkbox",
|
|
"value": "%GENERAL_APPLY_ON_SAVE%",
|
|
"hint": "When enabled, saved changes are queued immediately. When disabled, changes accumulate here until you click Apply Now."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/general_cardpendingchanges_save",
|
|
"method": "post",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "raw_html",
|
|
"html": "%PENDING_CHANGES_HTML%"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_network_interfaces",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Network Interfaces"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "WAN/LAN interface assignments and per-interface settings."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Network Interfaces",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/networkinterfaces_cardnetworkinterface_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "WAN Interface",
|
|
"name": "wan_interface",
|
|
"input_type": "interface_picker",
|
|
"value": "%GENERAL_WAN_INTERFACE%",
|
|
"data": "%NETWORK_INTERFACE_DATA_JSON%"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "LAN Interface",
|
|
"name": "lan_interface",
|
|
"input_type": "interface_picker",
|
|
"value": "%GENERAL_LAN_INTERFACE%",
|
|
"data": "%NETWORK_INTERFACE_DATA_JSON%"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/networkinterfaces_cardnetworkinterface_save",
|
|
"method": "post",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "iface-config-card",
|
|
"label": "Interface Configuration",
|
|
"hidden": true,
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/networkinterfaces_cardinterfaceconfiguration_apply",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "hidden",
|
|
"name": "original_mtu",
|
|
"value": ""
|
|
},
|
|
{
|
|
"type": "hidden",
|
|
"name": "original_mac",
|
|
"value": ""
|
|
},
|
|
{
|
|
"type": "field_row",
|
|
"cols": 3,
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Interface",
|
|
"name": "iface",
|
|
"input_type": "text",
|
|
"readonly": true,
|
|
"value": ""
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "MTU",
|
|
"name": "mtu",
|
|
"input_type": "select",
|
|
"value": "",
|
|
"options": [
|
|
{
|
|
"label": "576",
|
|
"value": "576"
|
|
},
|
|
{
|
|
"label": "1280",
|
|
"value": "1280"
|
|
},
|
|
{
|
|
"label": "1492",
|
|
"value": "1492"
|
|
},
|
|
{
|
|
"label": "1500",
|
|
"value": "1500"
|
|
},
|
|
{
|
|
"label": "4096",
|
|
"value": "4096"
|
|
},
|
|
{
|
|
"label": "9000",
|
|
"value": "9000"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "MAC Address",
|
|
"name": "mac",
|
|
"input_type": "text",
|
|
"validate": "mac",
|
|
"value": ""
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/networkinterfaces_cardinterfaceconfiguration_apply",
|
|
"method": "post",
|
|
"text": "Apply"
|
|
},
|
|
{
|
|
"type": "button_secondary",
|
|
"action": "#",
|
|
"text": "Cancel",
|
|
"class": "iface-config-cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{ "type": "raw_html", "html": "<br /><br /><br /><br /><br />" }
|
|
]
|
|
},
|
|
{
|
|
"id": "view_upstream_dns",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Upstream DNS"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Upstream resolvers and caching behaviour for dnsmasq."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Upstream DNS",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/upstreamdns_cardupstreamdns_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Strict Order",
|
|
"name": "strict_order",
|
|
"input_type": "checkbox",
|
|
"value": "%DNS_STRICT_ORDER%",
|
|
"hint": "Query DNS providers in list order rather than in parallel."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Cache Size",
|
|
"name": "cache_size",
|
|
"input_type": "number",
|
|
"value": "%DNS_CACHE_SIZE%",
|
|
"min": 0,
|
|
"hint": "Max DNS responses to cache per instance. Set to 0 to disable caching."
|
|
},
|
|
{
|
|
"type": "editable_list",
|
|
"label": "DNS Providers",
|
|
"name": "upstream_servers",
|
|
"item_placeholder": "e.g. 1.1.1.1",
|
|
"add_label": "Add Provider",
|
|
"validate": "ip",
|
|
"hint": "DNS resolvers queried for external hostnames. Supports IPv4 and IPv6.",
|
|
"items": "%DNS_UPSTREAM_SERVERS_JSON%"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/upstreamdns_cardupstreamdns_save",
|
|
"method": "post",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_banned_ips",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Banned IPs"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "IPs and ranges blocked in both directions at the nftables firewall."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "info_bar",
|
|
"variant": "info",
|
|
"text": "Supports single IPs, CIDR (94.130.0.0/16), wildcards (94.130.*.*), and ranges (94.130.52.1-20). IPv4 and IPv6 are both supported."
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:banned_ips",
|
|
"empty_message": "No IP bans configured.",
|
|
"columns": [
|
|
{
|
|
"label": "Description",
|
|
"field": "description"
|
|
},
|
|
{
|
|
"label": "IP / Range",
|
|
"field": "ip",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Status",
|
|
"field": "enabled",
|
|
"render": "badge_enabled_disabled"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_banned_ip",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "description",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "ip",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "enabled",
|
|
"input_type": "checkbox"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_banned_ip",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "add-form",
|
|
"label": "Add Banned IP",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_banned_ip",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Description",
|
|
"name": "description",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. Bad actor",
|
|
"hint": "Optional label for this entry."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "IP / Range",
|
|
"name": "ip",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. 1.2.3.4 or 1.2.3.0/24"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_banned_ip",
|
|
"method": "post",
|
|
"text": "Add Banned IP"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_host_overrides",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Host Overrides"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Force a hostname to resolve to a specific internal IP."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:host_overrides",
|
|
"empty_message": "No host overrides configured.",
|
|
"columns": [
|
|
{
|
|
"label": "Description",
|
|
"field": "description"
|
|
},
|
|
{
|
|
"label": "Hostname",
|
|
"field": "host",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Resolves To",
|
|
"field": "ip",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Status",
|
|
"field": "enabled",
|
|
"render": "badge_enabled_disabled"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_host_override",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "description",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "host",
|
|
"input_type": "text",
|
|
"validate": "domainname"
|
|
},
|
|
{
|
|
"col": "ip",
|
|
"input_type": "text",
|
|
"validate": "ip"
|
|
},
|
|
{
|
|
"col": "enabled",
|
|
"input_type": "checkbox"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_host_override",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "add-form",
|
|
"label": "Add Host Override",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_host_override",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Description",
|
|
"name": "description",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. Local server"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Hostname",
|
|
"name": "host",
|
|
"input_type": "text",
|
|
"validate": "domainname",
|
|
"placeholder": "e.g. server.home.local"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Resolves To",
|
|
"name": "ip",
|
|
"input_type": "text",
|
|
"validate": "ip",
|
|
"placeholder": "e.g. 192.168.1.100"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_host_override",
|
|
"method": "post",
|
|
"text": "Add Host Override"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_dns_blocklists",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "DNS Blocklists"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Domain level blocking via dnsmasq."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:blocklists",
|
|
"empty_message": "No blocklists configured.",
|
|
"columns": [
|
|
{
|
|
"label": "Name",
|
|
"field": "name"
|
|
},
|
|
{
|
|
"label": "Description",
|
|
"field": "description"
|
|
},
|
|
{
|
|
"label": "Format",
|
|
"field": "format",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Source URL",
|
|
"field": "url",
|
|
"class": "col-mono"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/dnsblocklists_tableblocklist_rowedit",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "name",
|
|
"input_type": "text",
|
|
"validate": "dashname"
|
|
},
|
|
{
|
|
"col": "description",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "format",
|
|
"input_type": "select",
|
|
"options": "%BLOCKLIST_FORMAT_OPTIONS%"
|
|
},
|
|
{
|
|
"col": "url",
|
|
"input_type": "text",
|
|
"validate": "url"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/dnsblocklists_tableblocklists_rowdelete",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "add-form",
|
|
"label": "Add Blocklist",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/dnsblocklists_cardaddblocklist_add",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Name",
|
|
"name": "name",
|
|
"input_type": "text",
|
|
"validate": "dashname",
|
|
"placeholder": "e.g. steven-black"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Description",
|
|
"name": "description",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. Steven Black (ads, malware, trackers)"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Format",
|
|
"name": "format",
|
|
"input_type": "select",
|
|
"options": "%BLOCKLIST_FORMAT_OPTIONS%"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Source URL",
|
|
"name": "url",
|
|
"input_type": "text",
|
|
"validate": "url",
|
|
"placeholder": "https://..."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/dnsblocklists_cardaddblocklist_add",
|
|
"method": "post",
|
|
"text": "Add Blocklist"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Blocklist Refresh",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "raw_html",
|
|
"html": "%BLOCKLIST_STATS_HTML%"
|
|
},
|
|
{
|
|
"type": "raw_html",
|
|
"html": "<hr class=\"divider\">"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_secondary",
|
|
"action": "/action/dnsblocklists_cardblocklistrefresh_refresh",
|
|
"method": "post",
|
|
"text": "Refresh All Now"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "raw_html",
|
|
"html": "<hr class=\"divider\">"
|
|
},
|
|
{
|
|
"type": "form",
|
|
"action": "/action/dnsblocklists_cardblocklistrefresh_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Daily Refresh Time",
|
|
"name": "daily_execute_time_24hr_local",
|
|
"input_type": "text",
|
|
"validate": "time_24h",
|
|
"value": "%GENERAL_DAILY_EXECUTE_TIME%",
|
|
"placeholder": "e.g. 02:30",
|
|
"hint": "24-hour local time for the daily blocklist refresh."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/dnsblocklists_cardblocklistrefresh_save",
|
|
"method": "post",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_vlans",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "VLANs"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Network segments managed by systemd-networkd, dnsmasq, nftables, and freeradius."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "info_bar",
|
|
"variant": "info",
|
|
"text": "For a basic flat network with no VLAN segmentation, only use VLAN 1 and delete the others."
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:vlans",
|
|
"empty_message": "No VLANs configured.",
|
|
"columns": [
|
|
{
|
|
"label": "VLAN ID",
|
|
"field": "vlan_id",
|
|
"class": "col-mono col-narrow"
|
|
},
|
|
{
|
|
"label": "Name",
|
|
"field": "name",
|
|
"class": "col-narrow"
|
|
},
|
|
{
|
|
"label": "Interface",
|
|
"field": "interface",
|
|
"class": "col-mono col-narrow"
|
|
},
|
|
{
|
|
"label": "Subnet",
|
|
"field": "subnet",
|
|
"class": "col-mono col-narrow"
|
|
},
|
|
{
|
|
"label": "Mask",
|
|
"field": "subnet_mask",
|
|
"class": "col-mono col-narrow"
|
|
},
|
|
{
|
|
"label": "Blocklists",
|
|
"field": "use_blocklists",
|
|
"class": "col-expand",
|
|
"render": "tag_list"
|
|
},
|
|
{
|
|
"label": "RADIUS Default",
|
|
"field": "radius_default",
|
|
"class": "col-narrow",
|
|
"render": "badge_enabled_disabled"
|
|
},
|
|
{
|
|
"label": "mDNS Reflection",
|
|
"field": "mdns_reflection",
|
|
"class": "col-narrow",
|
|
"render": "badge_enabled_disabled"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_vlan",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "name",
|
|
"input_type": "text",
|
|
"validate": "dashname"
|
|
},
|
|
{
|
|
"col": "subnet",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "subnet_mask",
|
|
"input_type": "number",
|
|
"min": 1,
|
|
"max": 30
|
|
},
|
|
{
|
|
"col": "radius_default",
|
|
"input_type": "checkbox"
|
|
},
|
|
{
|
|
"col": "mdns_reflection",
|
|
"input_type": "checkbox"
|
|
},
|
|
{
|
|
"col": "use_blocklists",
|
|
"input_type": "checkbox_multi",
|
|
"options": "%BLOCKLIST_NAME_OPTIONS%"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_vlan",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm",
|
|
"disable_if": {
|
|
"field": "vlan_id",
|
|
"value": 1
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "add-form",
|
|
"label": "Add VLAN",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_vlan",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field_row",
|
|
"cols": 2,
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "VLAN Name",
|
|
"name": "name",
|
|
"input_type": "text",
|
|
"validate": "dashname",
|
|
"hint": "Lowercase letters, digits, hyphens. E.g. iot"
|
|
},
|
|
{
|
|
"type": "subnet_row",
|
|
"subnet_name": "subnet",
|
|
"prefix_name": "subnet_mask",
|
|
"subnet_placeholder": "e.g. 192.168.x.0",
|
|
"prefix_value": "24"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "field_row",
|
|
"cols": 3,
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Interface",
|
|
"name": "",
|
|
"input_type": "text",
|
|
"readonly": true,
|
|
"class": "vlan-iface-preview form-input-mono",
|
|
"value": ""
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "VLAN ID",
|
|
"name": "",
|
|
"input_type": "text",
|
|
"readonly": true,
|
|
"class": "vlan-derived-id-preview form-input-mono",
|
|
"value": ""
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "VLAN Type",
|
|
"name": "is_vpn",
|
|
"input_type": "checkbox",
|
|
"checkbox_label": "Is VPN",
|
|
"hint": "Check if this VLAN uses a WireGuard interface (e.g. wg0, wg1, etc)."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "divider"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Blocklists",
|
|
"name": "use_blocklists",
|
|
"input_type": "checkbox_group",
|
|
"options": "%BLOCKLIST_NAME_OPTIONS%",
|
|
"hint": "Note: Selected lists will be merged and de-duplicated prior to use."
|
|
},
|
|
{
|
|
"type": "divider"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "RADIUS Default",
|
|
"name": "radius_default",
|
|
"input_type": "checkbox",
|
|
"hint": "Wireless devices without a DHCP reservation will be placed into this VLAN. (Note: wired devices are not placed via RADIUS but rather by layer 3 switch policy.)"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "mDNS Reflection",
|
|
"name": "mdns_reflection",
|
|
"input_type": "checkbox",
|
|
"hint": "Reflect mDNS traffic to/from this VLAN via avahi-daemon. Not supported on WireGuard interfaces."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_vlan",
|
|
"method": "post",
|
|
"text": "Add VLAN",
|
|
"class": "add-vlan-btn",
|
|
"disabled": true
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_inter_vlan",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Inter-VLAN Exceptions"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Firewall rules that permit specific traffic to cross VLAN boundaries."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:inter_vlan_exceptions",
|
|
"empty_message": "No inter-VLAN exceptions configured. All cross-VLAN traffic is blocked by default.",
|
|
"columns": [
|
|
{
|
|
"label": "Description",
|
|
"field": "description"
|
|
},
|
|
{
|
|
"label": "Protocol",
|
|
"field": "protocol",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Source",
|
|
"field": "src_ip_or_subnet",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Destination",
|
|
"field": "dst_ip_or_subnet",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Dest Port",
|
|
"field": "dst_port",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Status",
|
|
"field": "enabled",
|
|
"render": "badge_enabled_disabled"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_inter_vlan",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "description",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "protocol",
|
|
"input_type": "select",
|
|
"options": "%PROTOCOL_OPTIONS%"
|
|
},
|
|
{
|
|
"col": "src_ip_or_subnet",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "dst_ip_or_subnet",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "dst_port",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "enabled",
|
|
"input_type": "checkbox"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_inter_vlan",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "add-form",
|
|
"label": "Add Exception",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_inter_vlan",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Description",
|
|
"name": "description",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. Allow Chromecast"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Protocol",
|
|
"name": "protocol",
|
|
"input_type": "select",
|
|
"options": "%PROTOCOL_OPTIONS%"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Source",
|
|
"name": "src_ip_or_subnet",
|
|
"input_type": "text",
|
|
"validate": "ipv4cidr",
|
|
"placeholder": "e.g. 192.168.20.0/24"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Destination",
|
|
"name": "dst_ip_or_subnet",
|
|
"input_type": "text",
|
|
"validate": "ipv4",
|
|
"placeholder": "e.g. 192.168.10.100"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Dest Port",
|
|
"name": "dst_port",
|
|
"input_type": "text",
|
|
"validate": "port",
|
|
"placeholder": "e.g. 8009"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_inter_vlan",
|
|
"method": "post",
|
|
"text": "Add Exception"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_port_forwarding",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Port Forwarding"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "DNAT rules that forward inbound WAN traffic to internal hosts."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:port_forwarding",
|
|
"empty_message": "No port forwarding rules configured.",
|
|
"columns": [
|
|
{
|
|
"label": "Description",
|
|
"field": "description"
|
|
},
|
|
{
|
|
"label": "Protocol",
|
|
"field": "protocol",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Ext Port",
|
|
"field": "dest_port",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "NAT IP",
|
|
"field": "nat_ip",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "NAT Port",
|
|
"field": "nat_port",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Status",
|
|
"field": "enabled",
|
|
"render": "badge_enabled_disabled"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_port_forward",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "description",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "protocol",
|
|
"input_type": "select",
|
|
"options": "%PROTOCOL_OPTIONS%"
|
|
},
|
|
{
|
|
"col": "dest_port",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "nat_ip",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "nat_port",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "enabled",
|
|
"input_type": "checkbox"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_port_forward",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "add-form",
|
|
"label": "Add Rule",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_port_forward",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Description",
|
|
"name": "description",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. Minecraft server"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Protocol",
|
|
"name": "protocol",
|
|
"input_type": "select",
|
|
"options": "%PROTOCOL_OPTIONS%"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Ext Port",
|
|
"name": "dest_port",
|
|
"input_type": "text",
|
|
"validate": "port",
|
|
"placeholder": "e.g. 25565"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "NAT IP",
|
|
"name": "nat_ip",
|
|
"input_type": "text",
|
|
"validate": "ipv4",
|
|
"placeholder": "e.g. 192.168.1.50"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "NAT Port",
|
|
"name": "nat_port",
|
|
"input_type": "text",
|
|
"validate": "port",
|
|
"placeholder": "e.g. 25565"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_port_forward",
|
|
"method": "post",
|
|
"text": "Add Rule"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_dhcp",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "DHCP"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Active leases and static reservations across all VLANs."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "live:dhcp_leases",
|
|
"empty_message": "No active DHCP leases found.",
|
|
"columns": [
|
|
{
|
|
"label": "Hostname",
|
|
"field": "hostname"
|
|
},
|
|
{
|
|
"label": "IP Address",
|
|
"field": "ip_address",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "MAC Address",
|
|
"field": "mac_address",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "VLAN",
|
|
"field": "vlan_name"
|
|
},
|
|
{
|
|
"label": "Expires",
|
|
"field": "expires"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:dhcp_reservations",
|
|
"empty_message": "No DHCP reservations configured.",
|
|
"columns": [
|
|
{
|
|
"label": "Description",
|
|
"field": "description"
|
|
},
|
|
{
|
|
"label": "Hostname",
|
|
"field": "hostname",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "MAC",
|
|
"field": "mac",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "IP",
|
|
"field": "ip",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "VLAN",
|
|
"field": "vlan_name"
|
|
},
|
|
{
|
|
"label": "RADIUS",
|
|
"field": "radius_client",
|
|
"render": "badge_enabled_disabled"
|
|
},
|
|
{
|
|
"label": "Status",
|
|
"field": "enabled",
|
|
"render": "badge_enabled_disabled"
|
|
}
|
|
],
|
|
"toolbar": {
|
|
"items": [
|
|
{
|
|
"type": "select",
|
|
"name": "vlan_filter",
|
|
"value": "all",
|
|
"options": "%VLAN_FILTER_OPTIONS%",
|
|
"filter_col": "vlan_name"
|
|
}
|
|
]
|
|
},
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_dhcp_reservation",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "description",
|
|
"input_type": "text"
|
|
},
|
|
{
|
|
"col": "hostname",
|
|
"input_type": "text",
|
|
"validate": "networkname"
|
|
},
|
|
{
|
|
"col": "mac",
|
|
"input_type": "text",
|
|
"validate": "mac"
|
|
},
|
|
{
|
|
"col": "ip",
|
|
"input_type": "text",
|
|
"validate": "ipv4"
|
|
},
|
|
{
|
|
"col": "radius_client",
|
|
"input_type": "checkbox"
|
|
},
|
|
{
|
|
"col": "enabled",
|
|
"input_type": "checkbox"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_dhcp_reservation",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "add-form",
|
|
"label": "Add Reservation",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_dhcp_reservation",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "VLAN",
|
|
"name": "vlan_name",
|
|
"input_type": "select",
|
|
"options": "%VLAN_NAMES_AS_OPTIONS%",
|
|
"hint": "VLAN this reservation belongs to."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Description",
|
|
"name": "description",
|
|
"input_type": "text",
|
|
"placeholder": "e.g. NAS"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Hostname",
|
|
"name": "hostname",
|
|
"input_type": "text",
|
|
"validate": "networkname",
|
|
"placeholder": "e.g. nas"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "MAC Address",
|
|
"name": "mac",
|
|
"input_type": "text",
|
|
"validate": "mac",
|
|
"placeholder": "e.g. aa:bb:cc:dd:ee:ff"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "IP Address",
|
|
"name": "ip",
|
|
"input_type": "text",
|
|
"validate": "ipv4",
|
|
"placeholder": "e.g. 192.168.10.50"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "RADIUS Client",
|
|
"name": "radius_client",
|
|
"input_type": "checkbox",
|
|
"hint": "Authenticate this device via RADIUS."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_dhcp_reservation",
|
|
"method": "post",
|
|
"text": "Add Reservation"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_vpn",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "VPN"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "WireGuard peer management and server interface configuration."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"label": "Active Sessions",
|
|
"datasource": "live:vpn_sessions",
|
|
"empty_message": "No active VPN sessions.",
|
|
"columns": [
|
|
{
|
|
"label": "Peer",
|
|
"field": "peer_name"
|
|
},
|
|
{
|
|
"label": "Tunnel IP",
|
|
"field": "tunnel_ip",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Endpoint",
|
|
"field": "endpoint",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Last Handshake",
|
|
"field": "last_handshake"
|
|
},
|
|
{
|
|
"label": "Received",
|
|
"field": "rx_bytes",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Sent",
|
|
"field": "tx_bytes",
|
|
"class": "col-mono"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"label": "Peers",
|
|
"datasource": "config:vpn_peers",
|
|
"empty_message": "No peers configured. Use Add Peer below.",
|
|
"columns": [
|
|
{
|
|
"label": "Name",
|
|
"field": "name"
|
|
},
|
|
{
|
|
"label": "Assigned VLAN",
|
|
"field": "vlan_display",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Assigned IP",
|
|
"field": "ip",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Split Tunnel",
|
|
"field": "split_tunnel"
|
|
},
|
|
{
|
|
"label": "Enabled",
|
|
"field": "enabled",
|
|
"render": "badge_enabled_disabled"
|
|
},
|
|
{
|
|
"label": "Public Key",
|
|
"field": "pubkey_short",
|
|
"class": "col-mono"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/edit_vpn_peer",
|
|
"method": "inline_edit",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm",
|
|
"fields": [
|
|
{
|
|
"col": "name",
|
|
"input_type": "text",
|
|
"validate": "dashname"
|
|
},
|
|
{
|
|
"col": "split_tunnel",
|
|
"input_type": "checkbox"
|
|
},
|
|
{
|
|
"col": "enabled",
|
|
"input_type": "checkbox"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/regenerate_vpn_peer",
|
|
"method": "post",
|
|
"text": "Regen Conf",
|
|
"class": "btn-ghost btn-sm"
|
|
},
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"action": "/action/delete_vpn_peer",
|
|
"method": "post",
|
|
"text": "Delete",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Add Peer",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_vpn_peer",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Name",
|
|
"name": "peer_name",
|
|
"input_type": "text",
|
|
"validate": "dashname",
|
|
"placeholder": "e.g. laptop",
|
|
"hint": "Friendly name for this peer."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Assigned VLAN",
|
|
"name": "peer_vlan",
|
|
"input_type": "select",
|
|
"options": "%VPN_VLAN_OPTIONS%"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Assigned IP",
|
|
"name": "peer_ip",
|
|
"input_type": "text",
|
|
"validate": "ipv4",
|
|
"placeholder": "e.g. 192.168.40.2",
|
|
"hint": "Static IP assigned to this peer within the VPN subnet."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Split Tunnel",
|
|
"name": "split_tunnel",
|
|
"input_type": "checkbox",
|
|
"hint": "Route only VPN subnet traffic through the tunnel. When unchecked all traffic is routed through the VPN."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Enabled",
|
|
"name": "enabled",
|
|
"input_type": "checkbox",
|
|
"checked": true
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_vpn_peer",
|
|
"method": "post",
|
|
"text": "Add Peer & Download Conf"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "WireGuard Interface",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/apply_vpn",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Listen Port",
|
|
"name": "vpn_listen_port",
|
|
"input_type": "number",
|
|
"value": "%VPN_LISTEN_PORT%",
|
|
"min": 1024,
|
|
"max": 65535,
|
|
"hint": "UDP port WireGuard listens on. Must match your port forwarding rule."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Server Endpoint",
|
|
"name": "vpn_server_endpoint",
|
|
"input_type": "text",
|
|
"validate": "endpoint",
|
|
"value": "%VPN_SERVER_ENDPOINT%",
|
|
"placeholder": "e.g. vpn.example.com",
|
|
"hint": "Publicly reachable hostname or IP of this server, embedded in client config files."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Domain",
|
|
"name": "vpn_domain",
|
|
"input_type": "text",
|
|
"validate": "dashname",
|
|
"value": "%VPN_DOMAIN%",
|
|
"placeholder": "e.g. local",
|
|
"hint": "DNS search domain pushed to VPN clients."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "DNS Override",
|
|
"name": "vpn_dns_server",
|
|
"input_type": "text",
|
|
"validate": "ipv4",
|
|
"value": "%VPN_DNS_SERVER%",
|
|
"placeholder": "Leave blank to use gateway IP (%VPN_GATEWAY%)",
|
|
"hint": "Explicit DNS server pushed to peers. Defaults to the gateway IP."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "MTU Override",
|
|
"name": "vpn_mtu",
|
|
"input_type": "number",
|
|
"value": "%VPN_MTU%",
|
|
"placeholder": "Leave blank for default",
|
|
"hint": "Override tunnel MTU. Leave blank for the system default."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/apply_vpn",
|
|
"method": "post",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_log_in",
|
|
"client_requirement": "client_is_nothing=",
|
|
"items": [
|
|
{
|
|
"type": "auth_wrapper",
|
|
"client_requirement": "client_is_nothing=",
|
|
"items": [
|
|
{
|
|
"type": "auth_card",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Log In"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Enter your credentials to access the dashboard."
|
|
},
|
|
{
|
|
"type": "divider"
|
|
},
|
|
{
|
|
"type": "form",
|
|
"action": "/action/log_in",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Email Address",
|
|
"name": "email",
|
|
"input_type": "text",
|
|
"placeholder": "you@example.com"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Password",
|
|
"name": "password",
|
|
"input_type": "password",
|
|
"placeholder": "Password"
|
|
},
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/log_in",
|
|
"method": "post",
|
|
"text": "Log In",
|
|
"class": "btn-full"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Need to complete your account?",
|
|
"link": {
|
|
"action": "/view/view_create_account",
|
|
"text": "Create Account"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "section",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Already logged in."
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "You are already authenticated."
|
|
},
|
|
{
|
|
"type": "spacer"
|
|
},
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/view/overview",
|
|
"text": "Go to Overview"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_create_account",
|
|
"client_requirement": "client_is_nothing=",
|
|
"items": [
|
|
{
|
|
"type": "auth_wrapper",
|
|
"client_requirement": "client_is_nothing=",
|
|
"items": [
|
|
{
|
|
"type": "auth_card",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Complete Your Account"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "If your email has been pre-registered by a manager, setup your account below."
|
|
},
|
|
{
|
|
"type": "divider"
|
|
},
|
|
{
|
|
"type": "form",
|
|
"action": "/action/create_account",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Email Address",
|
|
"name": "email",
|
|
"input_type": "text",
|
|
"placeholder": "you@example.com",
|
|
"hint": "Must match your pre-registered email address."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "New Password",
|
|
"name": "password",
|
|
"input_type": "password",
|
|
"placeholder": "Choose a strong password"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Confirm Password",
|
|
"name": "password_confirm",
|
|
"input_type": "password",
|
|
"placeholder": "Repeat your password"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Timezone",
|
|
"name": "timezone",
|
|
"input_type": "select",
|
|
"value": "",
|
|
"options": "%TIMEZONE_OPTIONS%",
|
|
"hint": "Used to display timestamps in your local time."
|
|
},
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/create_account",
|
|
"method": "post",
|
|
"text": "Create Account",
|
|
"class": "btn-full"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Already have an account?",
|
|
"link": {
|
|
"action": "/view/view_log_in",
|
|
"text": "Log In"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "section",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Already logged in."
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Your account is already active."
|
|
},
|
|
{
|
|
"type": "spacer"
|
|
},
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/view/overview",
|
|
"text": "Go to Overview"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_verify_email",
|
|
"client_requirement": "client_is_nothing=",
|
|
"items": [
|
|
{
|
|
"type": "auth_wrapper",
|
|
"client_requirement": "client_is_nothing=",
|
|
"items": [
|
|
{
|
|
"type": "auth_card",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Verify Your Email"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "A 6-digit code was sent to your email address. Enter it below to complete your account."
|
|
},
|
|
{
|
|
"type": "form",
|
|
"action": "/action/verify_email",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Verification Code",
|
|
"name": "code",
|
|
"input_type": "text",
|
|
"placeholder": "000000",
|
|
"hint": "The code expires in 15 minutes."
|
|
},
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/verify_email",
|
|
"method": "post",
|
|
"text": "Verify",
|
|
"class": "btn-full"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Didn't receive it?",
|
|
"link": {
|
|
"action": "/action/resend_verification",
|
|
"text": "Resend code"
|
|
}
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Wrong email?",
|
|
"link": {
|
|
"action": "/view/view_create_account",
|
|
"text": "Start over"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "section",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Already logged in."
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Your account is already active."
|
|
},
|
|
{
|
|
"type": "spacer"
|
|
},
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/view/view_overview",
|
|
"text": "Go to Overview"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_preferences",
|
|
"client_requirement": "client_is_viewer+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Preferences"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Your personal account settings."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Account Details",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/save_preferences",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Email Address",
|
|
"name": "email",
|
|
"input_type": "text",
|
|
"value": "%PREF_EMAIL%",
|
|
"hint": "Contact your manager to change your email address."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Timezone",
|
|
"name": "timezone",
|
|
"input_type": "select",
|
|
"value": "%PREF_TIMEZONE%",
|
|
"options": "%TIMEZONE_OPTIONS%",
|
|
"hint": "All timestamps will be displayed in this timezone."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/save_preferences",
|
|
"method": "post",
|
|
"text": "Save Preferences"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Change Password",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/change_password",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Current Password",
|
|
"name": "current_password",
|
|
"input_type": "password",
|
|
"placeholder": "Current password"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "New Password",
|
|
"name": "new_password",
|
|
"input_type": "password",
|
|
"placeholder": "New password"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Confirm Password",
|
|
"name": "confirm_password",
|
|
"input_type": "password",
|
|
"placeholder": "Repeat new password"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/change_password",
|
|
"method": "post",
|
|
"text": "Change Password"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "view_manage_accounts",
|
|
"client_requirement": "client_is_manager+",
|
|
"items": [
|
|
{
|
|
"type": "page_header",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Manage Accounts"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "config:accounts",
|
|
"empty_message": "No accounts configured.",
|
|
"columns": [
|
|
{
|
|
"label": "Email Address",
|
|
"field": "email_address"
|
|
},
|
|
{
|
|
"label": "Access Level",
|
|
"field": "access_level"
|
|
},
|
|
{
|
|
"label": "Added By",
|
|
"field": "account_created_by"
|
|
},
|
|
{
|
|
"label": "Added",
|
|
"field": "account_created_utc"
|
|
},
|
|
{
|
|
"label": "Status",
|
|
"field": "account_status",
|
|
"render": "badge_active_inactive"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"action": "/action/delete_account",
|
|
"method": "post",
|
|
"text": "Remove",
|
|
"class": "btn-danger btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Authorize New Account",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/add_account",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Email Address",
|
|
"name": "email_address",
|
|
"input_type": "text",
|
|
"placeholder": "user@example.com",
|
|
"hint": "The user will verify ownership of this address during account setup."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Access Level",
|
|
"name": "access_level",
|
|
"input_type": "select",
|
|
"options": "%ACCOUNT_LEVEL_OPTIONS%"
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"action": "/action/add_account",
|
|
"method": "post",
|
|
"text": "Authorize"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
} |