Fix CSRF token write failure and SMTP test token sync

- Add fallback write when O_EXCL _safe_write fails for CSRF tokens
  (ensures token is always persisted to disk)
- Update SMTP test JS to sync new CSRF token into main form hidden field
  (prevents stale token after SMTP test consumes the original)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-05 00:09:24 +02:00
parent 7802d7ebe0
commit cc7e46a88f
3 changed files with 20 additions and 3 deletions

View File

@@ -120,7 +120,13 @@ sub generate_csrf_token {
} }
} }
_safe_write(_csrf_file(), time() . "\n" . $token . "\n"); my $csrf_file = _csrf_file();
unless (_safe_write($csrf_file, time() . "\n" . $token . "\n")) {
if (open my $fh, '>', $csrf_file) {
print $fh time() . "\n" . $token . "\n";
close $fh;
}
}
$_current_csrf_token = $token; $_current_csrf_token = $token;
return $token; return $token;

View File

@@ -158,7 +158,14 @@ sub generate_csrf_token {
} }
_ensure_dir($CSRF_DIR); _ensure_dir($CSRF_DIR);
_safe_write("$CSRF_DIR/token", time() . "\n" . $token . "\n"); unless (_safe_write("$CSRF_DIR/token", time() . "\n" . $token . "\n")) {
# O_EXCL can fail if unlink didn't fully remove the file;
# fall back to plain overwrite so the token is always persisted.
if (open my $fh, '>', "$CSRF_DIR/token") {
print $fh time() . "\n" . $token . "\n";
close $fh;
}
}
$_current_csrf_token = $token; $_current_csrf_token = $token;
return $token; return $token;

View File

@@ -282,7 +282,11 @@ function gnizaTestSmtp() {
fetch('settings.cgi', { method: 'POST', body: fd }) fetch('settings.cgi', { method: 'POST', body: fd })
.then(function(r) { return r.json(); }) .then(function(r) { return r.json(); })
.then(function(data) { .then(function(data) {
if (data.csrf) { gnizaCsrf = data.csrf; } if (data.csrf) {
gnizaCsrf = data.csrf;
var hf = document.querySelector('input[name="gniza_csrf"]');
if (hf) hf.value = data.csrf;
}
gnizaSmtpToast(data.success ? 'success' : 'error', data.message); gnizaSmtpToast(data.success ? 'success' : 'error', data.message);
}) })
.catch(function(err) { .catch(function(err) {