203 lines
5.8 KiB
JSON
203 lines
5.8 KiB
JSON
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "header_page_title",
|
|
"items": [
|
|
{
|
|
"type": "h1",
|
|
"text": "Captive Portal"
|
|
},
|
|
{
|
|
"type": "p",
|
|
"text": "Redirect unauthenticated guests on captive portal VLANs to a login page before allowing internet access."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "info_bar",
|
|
"variant": "info",
|
|
"text": "%CAPTIVE_STATUS_TEXT%"
|
|
},
|
|
{
|
|
"type": "card",
|
|
"label": "Options",
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/captiveportal/options_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "HTTP Port",
|
|
"name": "http_port",
|
|
"input_type": "number",
|
|
"value": "%CAPTIVE_HTTP_PORT%",
|
|
"min": 1024,
|
|
"max": 65535,
|
|
"hint": "Port the captive portal service listens on. nftables redirects unauthenticated HTTP traffic from captive portal VLANs to this port."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "HTTPS Domain",
|
|
"name": "https_domain",
|
|
"input_type": "text",
|
|
"value": "%CAPTIVE_HTTPS_DOMAIN%",
|
|
"hint": "Domain with an existing Caddy + Let's Encrypt certificate. The portal login page is served at https://<domain>/. Leave blank for HTTP-only."
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "table",
|
|
"datasource": "captive_portals",
|
|
"empty_message": "No captive portal VLANs configured. Set Restricted VLAN = Captive Portal on the Network Layout page.",
|
|
"columns": [
|
|
{
|
|
"label": "VLAN",
|
|
"field": "vlan_name",
|
|
"class": "col-mono"
|
|
},
|
|
{
|
|
"label": "Title",
|
|
"field": "portal_splash_title"
|
|
},
|
|
{
|
|
"label": "Splash Text",
|
|
"field": "portal_splash_text"
|
|
},
|
|
{
|
|
"label": "Terms",
|
|
"field": "portal_terms_display",
|
|
"class": "col-narrow"
|
|
},
|
|
{
|
|
"label": "U/P Required",
|
|
"field": "require_upw",
|
|
"class": "col-narrow",
|
|
"render": "badge_yes_no"
|
|
}
|
|
],
|
|
"row_actions": [
|
|
{
|
|
"client_requirement": "client_is_administrator+",
|
|
"method": "js_edit",
|
|
"target": "portal-edit-form",
|
|
"text": "Edit",
|
|
"class": "btn-ghost btn-sm"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "card",
|
|
"id": "portal-edit-form",
|
|
"label": "Edit Portal",
|
|
"hidden": true,
|
|
"client_requirement": "client_is_administrator+",
|
|
"items": [
|
|
{
|
|
"type": "form",
|
|
"action": "/action/captiveportal/portal_save",
|
|
"method": "post",
|
|
"items": [
|
|
{
|
|
"type": "hidden",
|
|
"name": "vlan_name",
|
|
"value": ""
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Title",
|
|
"name": "portal_splash_title",
|
|
"input_type": "text",
|
|
"hint": "Heading shown at the top of the login page."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Splash Text",
|
|
"name": "portal_splash_text",
|
|
"input_type": "text",
|
|
"hint": "Welcome message shown below the title."
|
|
},
|
|
{
|
|
"type": "hr"
|
|
},
|
|
{
|
|
"type": "editable_list",
|
|
"label": "Terms",
|
|
"name": "portal_terms",
|
|
"items": "[]",
|
|
"add_label": "Add Term",
|
|
"item_placeholder": "e.g. I agree to the acceptable use policy.",
|
|
"hint": "Each term renders as a required checkbox the user must tick before submitting credentials. Leave empty for no terms."
|
|
},
|
|
{
|
|
"type": "hr"
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "",
|
|
"name": "require_username_password",
|
|
"input_type": "checkbox",
|
|
"checkbox_label": "Require username and password"
|
|
},
|
|
{
|
|
"type": "field_row",
|
|
"cols": 2,
|
|
"items": [
|
|
{
|
|
"type": "field",
|
|
"label": "Default Session Duration",
|
|
"name": "default_duration_value",
|
|
"input_type": "number",
|
|
"min": 0,
|
|
"value": "0",
|
|
"hint": "How long portal access lasts after authentication. 0 = no expiration."
|
|
},
|
|
{
|
|
"type": "field",
|
|
"label": "Unit",
|
|
"name": "default_duration_unit",
|
|
"input_type": "select",
|
|
"options": [
|
|
{"value": "hours", "label": "Hours"},
|
|
{"value": "days", "label": "Days"}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "button_row",
|
|
"items": [
|
|
{
|
|
"type": "button_primary",
|
|
"text": "Save"
|
|
},
|
|
{
|
|
"type": "button_cancel",
|
|
"text": "Cancel"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|