{ "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:///. 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" } ] } ] } ] } ] }