Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 93 additions & 21 deletions lib/wificaptive/portal/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,23 @@
margin-bottom: 5px;
}

input {
input, select, textarea {
border-width: 1px;
border-radius: .75rem;
font-size: 16px;
padding: 5px;
width: 100%;
box-sizing: border-box;
}

textarea {
font-family: monospace;
resize: vertical;
}

select {
height: 35px;
}

input:focus {
outline: none;
Expand Down Expand Up @@ -334,22 +343,51 @@
location.reload();
}

function toggleEnterpriseFields(isEnterprise) {
var enterpriseFields = document.getElementById('enterprise_fields');
var enterpriseUsernameGroup = document.getElementById('enterprise_username_group');
var enterpriseIndicator = document.getElementById('enterprise_indicator');

// store the enterprise status in a hidden field
document.getElementById('isEnterpriseHidden').value = isEnterprise ? 'true' : 'false';

if (isEnterprise) {
enterpriseFields.style.display = 'flex';
enterpriseUsernameGroup.style.display = 'flex';
enterpriseIndicator.style.display = 'block';
} else {
enterpriseFields.style.display = 'none';
enterpriseUsernameGroup.style.display = 'none';
enterpriseIndicator.style.display = 'none';
}
}

function connect() {
hideAlert();
var ssid = document.getElementById('ssid').value;
var pswd = document.getElementById('password').value;
var server = document.getElementById('server').value;
var isEnterprise = document.getElementById('isEnterpriseHidden').value === 'true';

if (!ssid) {
displayAlert('Please enter your Wi-Fi name', "warning");
return;
}

if (isEnterprise) {
var identity = document.getElementById('identity').value;
if (!identity) {
displayAlert('Please enter your identity for WPA2 Enterprise', "warning");
return;
}
}

// if custom server form-group is visible, validate the url
let customServerVisible = document.getElementById('custom_server_form_group').style.display != 'none';
if (customServerVisible && server) {
try {
new URL(server);
// does it start with http:// or https://?

if (!server.startsWith('http://') && !server.startsWith('https://')) {
throw new Error();
}
Expand All @@ -364,7 +402,17 @@

saveServerToStorage();

var body = { ssid: ssid, pswd: pswd, server: server };
var body = {
ssid: ssid,
pswd: pswd,
server: server,
isEnterprise: isEnterprise
};

if (isEnterprise) {
body.identity = document.getElementById('identity').value;
body.username = document.getElementById('username').value;
}

showLoader();
fetch('/connect', {
Expand Down Expand Up @@ -446,18 +494,19 @@
document.getElementById('other-networks-caption').style.display = 'block';
}
knownNetworks.forEach((item, row) => {
appendWifiToTable("table-saved", item.name, item.open, item.rssi, false);
appendWifiToTable("table-saved", item.name, item.open, item.rssi, item.enterprise, false);
});
otherNetworks.forEach((item, row) => {
appendWifiToTable("table-others", item.name, item.open, item.rssi, true);
appendWifiToTable("table-others", item.name, item.open, item.rssi, item.enterprise, true);
});
} else if (response && response.status == 202) {
setTimeout(getInfo, 2000); // repeat in 2s
}
}

function appendWifiToTable(table, name, open, rssi, onClick) {
function appendWifiToTable(table, name, open, rssi, enterprise, onClick) {
var newRow = document.createElement('tr');
newRow.setAttribute('data-enterprise', enterprise ? 'true' : 'false');
if (onClick) {
newRow.onclick = function () {
onClickItemTable(this);
Expand Down Expand Up @@ -497,11 +546,20 @@
}
});
var value = x.querySelector('th').textContent;
var isEnterprise = x.getAttribute('data-enterprise') === 'true';

if (value) {
document.getElementById('ssid').value = value;
var passwordTag = document.getElementById('password');
passwordTag.value = '';
passwordTag.focus();

toggleEnterpriseFields(isEnterprise);

if (isEnterprise) {
document.getElementById('identity').focus();
} else {
passwordTag.focus();
}
}
}

Expand Down Expand Up @@ -597,20 +655,34 @@ <h1>Wi-Fi Configuration</h1>
<p id="scanning-info">Scanning networks, please wait...</p>
<div id="scanning-loader" class="loader"></div>
</div>
<div class="div-container">
<div class="form-group">
<label for="ssid">SSID</label>
<input type="text" id="ssid" name="ssid" placeholder="Enter your Wi-Fi name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" pattern=".{8,}" placeholder="Enter your Wi-Fi password">
<i id="toggler" class="bi bi-eye" onclick="togglePassword()"></i>
</div>
<div class="form-group" id="custom_server_form_group" style="display: none;">
<label for="server">API Server</label>
<input type="url" id="server" name="server" placeholder="Enter your custom server without a trailing / (e.g. https://trmnl.app)">
</div>
<div class="div-container">
<div class="form-group">
<label for="ssid">SSID</label>
<input type="text" id="ssid" name="ssid" placeholder="Enter your Wi-Fi name">
</div>
<input type="hidden" id="isEnterpriseHidden" value="false">
<div class="form-group" id="enterprise_indicator" style="display: none;">
<div class="alert alert-primary" style="margin-bottom: 0;">
This network uses WPA2 Enterprise authentication. If you only have a username and password, use the identity field for your username.
</div>
</div>
<div class="form-group" id="enterprise_fields" style="display: none;">
<label for="identity">Identity (required)</label>
<input type="text" id="identity" name="identity" placeholder="Enter your identity (e.g. [email protected])">
</div>
<div class="form-group" id="enterprise_username_group" style="display: none;">
<label for="username">Username (optional)</label>
<input type="text" id="username" name="username" placeholder="Enter username (if different from identity)">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" placeholder="Enter your Wi-Fi password">
<i id="toggler" class="bi bi-eye" onclick="togglePassword()"></i>
</div>
<div class="form-group" id="custom_server_form_group" style="display: none;">
<label for="server">API Server</label>
<input type="url" id="server" name="server" placeholder="Enter your custom server without a trailing / (e.g. https://trmnl.app)">
</div>
<div class="form-group">
<div class="alert alert-primary" id="message" role="alert" style="display: none;"></div>
</div>
Expand Down
35 changes: 22 additions & 13 deletions lib/wificaptive/src/WebServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#include <WiFi.h>
#include <test.h>



void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP, WifiOperationCallbacks callbacks)
{
//======================== Webserver ========================
Expand Down Expand Up @@ -40,10 +38,10 @@ void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP, WifiOperat
// Serve index.html
server.on("/", HTTP_ANY, [&](AsyncWebServerRequest *request)
{
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", INDEX_HTML, INDEX_HTML_LEN);
response->addHeader("Content-Encoding", "gzip");
request->send(response); // redirect to the local IP URL
});
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", INDEX_HTML, INDEX_HTML_LEN);
response->addHeader("Content-Encoding", "gzip");
request->send(response); // redirect to the local IP URL
});

// Servce logo.svg
server.on("/logo.svg", HTTP_ANY, [&](AsyncWebServerRequest *request)
Expand All @@ -62,14 +60,12 @@ void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP, WifiOperat
{
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", ADVANCED_HTML, ADVANCED_HTML_LEN);
response->addHeader("Content-Encoding", "gzip");
request->send(response);
});
request->send(response); });
server.on("/run-test", HTTP_GET, [](AsyncWebServerRequest *request)
{
Serial.println("Running sensor test from web...");
String json = testTemperature();
request->send(200, "application/json", json);
});
request->send(200, "application/json", json); });

auto scanGET = server.on("/scan", HTTP_GET, [callbacks](AsyncWebServerRequest *request)
{
Expand Down Expand Up @@ -99,7 +95,8 @@ void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP, WifiOperat
json+= "\"name\":\""+ssid+"\",";
json+= "\"rssi\":\""+rssi+"\",";
json+= "\"open\":"+String(network.open == WIFI_AUTH_OPEN ? "true,": "false,");
json+= "\"saved\":"+String(network.saved ? "true": "false");
json+= "\"saved\":"+String(network.saved ? "true,": "false,");
json+= "\"enterprise\":"+String(network.enterprise ? "true": "false");
json+= "}";

size += 1;
Expand Down Expand Up @@ -133,7 +130,19 @@ void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP, WifiOperat
String ssid = data["ssid"];
String pswd = data["pswd"];
String api_server = data["server"];
callbacks.setConnectionCredentials({ssid, pswd}, api_server);

bool isEnterprise = data["isEnterprise"].is<bool>() && data["isEnterprise"].as<bool>();
String username = data["username"].is<String>() ? data["username"].as<String>() : "";
String identity = data["identity"].is<String>() ? data["identity"].as<String>() : "";

WifiCredentials credentials;
credentials.ssid = ssid;
credentials.pswd = pswd;
credentials.isEnterprise = isEnterprise;
credentials.username = username;
credentials.identity = identity;

callbacks.setConnectionCredentials(credentials, api_server);
String mac = WiFi.macAddress();
String message = "{\"ssid\":\"" + ssid + "\",\"mac\":\"" + mac + "\"}";
request->send(200, "application/json", message); });
Expand All @@ -142,4 +151,4 @@ void setUpWebserver(AsyncWebServer &server, const IPAddress &localIP, WifiOperat

server.onNotFound([](AsyncWebServerRequest *request)
{ request->redirect(LocalIPURL); });
}
}
Loading