Fix board registration blocked by HMAC auth

- /register endpoint no longer requires verifyAPIRequest() - it is
  the bootstrap handshake and api_secret cannot be set before it runs
- Add api_secret field to the Add Board form (hardware boards only)
  with a cryptographic Generate button, same as the Edit form
- Save api_secret from the add-board POST so the driver can sign
  requests immediately after registration
This commit is contained in:
2026-03-15 16:12:18 +02:00
parent 36de1623c2
commit fbf5802c69
2 changed files with 24 additions and 0 deletions

View File

@@ -75,6 +75,8 @@ def add_board():
num_relays = 0
num_inputs = 0
api_secret = request.form.get("api_secret", "").strip() or None
board = Board(
name=name,
board_type=board_type,
@@ -82,6 +84,7 @@ def add_board():
port=port,
num_relays=num_relays,
num_inputs=num_inputs,
api_secret=api_secret,
)
db.session.add(board)
db.session.commit()

View File

@@ -149,6 +149,18 @@
</div>
</div>
<div id="f-secret-section" class="d-none mb-4">
<label class="form-label fw-semibold">API Secret <span class="text-secondary fw-normal small">(HMAC-SHA256 shared secret)</span></label>
<div class="input-group">
<input type="text" name="api_secret" id="f-api-secret" class="form-control font-monospace"
placeholder="Leave empty to disable API authentication">
<button class="btn btn-outline-secondary" type="button" onclick="genSecret()">
<i class="bi bi-shuffle me-1"></i>Generate
</button>
</div>
<div class="form-text">Must match <code>API_SECRET</code> in the board's <code>secrets.h</code>. You can also set this later in the board's Edit page.</div>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary px-4">
<i class="bi bi-check-lg me-1"></i>Add Board
@@ -317,10 +329,12 @@
gwAlert.className = "alert py-3 d-flex gap-3 align-items-start " + meta.alertCls;
gwIcon.innerHTML = meta.alertIcon;
gwText.innerHTML = meta.alertBody;
document.getElementById("f-secret-section").classList.add("d-none");
} else {
hwSec.classList.remove("d-none");
fHost.required = true;
gwSec.classList.add("d-none");
document.getElementById("f-secret-section").classList.remove("d-none");
}
// Step indicator
@@ -336,6 +350,13 @@
fName.focus();
}
window.genSecret = function () {
const buf = new Uint8Array(32);
crypto.getRandomValues(buf);
document.getElementById('f-api-secret').value =
Array.from(buf).map(b => b.toString(16).padStart(2, '0')).join('');
};
}());
</script>
{% endblock %}