fix: switch to form-encoded POST + CSRF as query param + form field
This commit is contained in:
parent
78cae8dea4
commit
76e7fc3d5c
2 changed files with 28 additions and 18 deletions
22
server.go
22
server.go
|
|
@ -246,12 +246,15 @@ func handleListLeases(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func handlePinLease(w http.ResponseWriter, r *http.Request) {
|
||||
var req PinRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, ErrorResponse{Error: "invalid JSON: " + err.Error()})
|
||||
if err := r.ParseForm(); err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, ErrorResponse{Error: "invalid form data: " + err.Error()})
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
req := PinRequest{
|
||||
MAC: r.FormValue("mac"),
|
||||
IP: r.FormValue("ip"),
|
||||
Hostname: r.FormValue("hostname"),
|
||||
}
|
||||
|
||||
if req.MAC == "" || req.IP == "" {
|
||||
writeJSON(w, http.StatusBadRequest, ErrorResponse{Error: "mac and ip are required"})
|
||||
|
|
@ -280,12 +283,15 @@ func handlePinLease(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func handleUnpinLease(w http.ResponseWriter, r *http.Request) {
|
||||
var req PinRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, ErrorResponse{Error: "invalid JSON: " + err.Error()})
|
||||
if err := r.ParseForm(); err != nil {
|
||||
writeJSON(w, http.StatusBadRequest, ErrorResponse{Error: "invalid form data: " + err.Error()})
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
req := PinRequest{
|
||||
MAC: r.FormValue("mac"),
|
||||
IP: r.FormValue("ip"),
|
||||
Hostname: r.FormValue("hostname"),
|
||||
}
|
||||
|
||||
if req.MAC == "" {
|
||||
writeJSON(w, http.StatusBadRequest, ErrorResponse{Error: "mac is required"})
|
||||
|
|
|
|||
24
web/app.js
24
web/app.js
|
|
@ -26,20 +26,24 @@ async function apiFetch(path, opts) {
|
|||
var method = (opts.method || 'GET').toUpperCase();
|
||||
var isPost = (method === 'POST' || method === 'PUT' || method === 'PATCH');
|
||||
|
||||
// Attach CSRF token as query param (Zoraxy may validate it there)
|
||||
if (csrfToken && csrfToken !== '{{.csrfToken}}') {
|
||||
var sep = path.indexOf('?') >= 0 ? '&' : '?';
|
||||
path = path + sep + 'csrfToken=' + encodeURIComponent(csrfToken);
|
||||
opts.headers['X-Zoraxy-Csrf'] = csrfToken;
|
||||
// For POST requests, include token in body (Zoraxy validates via form field)
|
||||
if (isPost) {
|
||||
if (opts.body && typeof opts.body === 'object') {
|
||||
opts.body.csrfToken = csrfToken;
|
||||
} else {
|
||||
opts.body = { csrfToken: csrfToken };
|
||||
}
|
||||
|
||||
if (isPost && opts.body && typeof opts.body === 'object') {
|
||||
// Send as URL-encoded form data (Zoraxy's CSRF middleware parses forms, not JSON)
|
||||
var formBody = new URLSearchParams();
|
||||
for (var key in opts.body) {
|
||||
if (opts.body.hasOwnProperty(key)) {
|
||||
formBody.append(key, opts.body[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts.body && typeof opts.body === 'object') {
|
||||
opts.body = JSON.stringify(opts.body);
|
||||
opts.headers['Content-Type'] = 'application/json';
|
||||
formBody.append('csrfToken', csrfToken || '');
|
||||
opts.body = formBody.toString();
|
||||
opts.headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
var res = await fetch(API_BASE + path, opts);
|
||||
var text = await res.text();
|
||||
|
|
|
|||
Loading…
Reference in a new issue