196 lines
8.1 KiB
Markdown
196 lines
8.1 KiB
Markdown
# Formularze SoftSPM - konfiguracja i uruchomienie
|
|
|
|
Wszystkie formularze strony (newsletter PL, kontakt EN, zgłoszenie na szkolenie,
|
|
rozmowa konsultingowa) wysyłają dane przez [send.php](send.php), który dopiero
|
|
woła `https://api.softspm.pl/send_email_api.php` zgodnie z
|
|
[doc/manual_send_email.html](../doc/manual_send_email.html).
|
|
|
|
**Dlaczego przez pośrednika, a nie prosto z przeglądarki:** endpoint autoryzuje
|
|
się kluczem API w nagłówku `Authorization`. Klucz wysłany z JavaScriptu byłby
|
|
widoczny w źródle strony dla każdego, kto naciśnie Ctrl+U - i każdy mógłby nim
|
|
wysyłać maile na dowolny adres. Klucz zostaje na serwerze; przeglądarka rozmawia
|
|
wyłącznie z `send.php`.
|
|
|
|
Wymagania: **PHP 7.4 lub nowszy**, rozszerzenie `curl` (jest fallback na
|
|
`file_get_contents`, ale cURL jest zalecany).
|
|
|
|
---
|
|
|
|
## 1. Co dopisać w `/etc/hydronexis/config.php`
|
|
|
|
`api/config.php` czyta ten plik automatycznie. Obsługiwane są dwa zapisy -
|
|
wybierz ten, który pasuje do tego, co już masz w pliku.
|
|
|
|
### Wariant A - plik definiuje stałe (najczęstszy)
|
|
|
|
```php
|
|
// --- formularze softspm.com -------------------------------------------
|
|
define('SOFTSPM_MAIL_API_KEY', 'tutaj_klucz_do_send_email_api');
|
|
define('SOFTSPM_FORM_SECRET', 'tutaj_losowy_ciag_min_32_znaki');
|
|
define('SOFTSPM_FORM_RECIPIENT', 'pzators@go2.pl');
|
|
```
|
|
|
|
### Wariant B - plik zwraca tablicę (`return [...]`)
|
|
|
|
```php
|
|
return [
|
|
// ... to, co już tam jest ...
|
|
|
|
// --- formularze softspm.com ---------------------------------------
|
|
'softspm_mail_api_key' => 'tutaj_klucz_do_send_email_api',
|
|
'softspm_form_secret' => 'tutaj_losowy_ciag_min_32_znaki',
|
|
'softspm_form_recipient' => 'pzators@go2.pl',
|
|
];
|
|
```
|
|
|
|
### Wpisy opcjonalne
|
|
|
|
```php
|
|
// Domeny, z których wolno wysyłać formularze. Bez tego wpisu obowiązuje
|
|
// lista z api/config.php (softspm.com, www.softspm.com, localhost).
|
|
define('SOFTSPM_FORM_HOSTS', ['softspm.com', 'www.softspm.com']);
|
|
|
|
// Osobna skrzynka dla wybranego formularza. Identyfikatory formularzy:
|
|
// newsletter, newsletter-en, szkolenia, konsulting
|
|
define('SOFTSPM_FORM_RECIPIENTS', ['szkolenia' => 'szkolenia@softspm.com']);
|
|
```
|
|
|
|
### Skąd wziąć `SOFTSPM_FORM_SECRET`
|
|
|
|
To nie jest klucz do niczego zewnętrznego - to sekret, którym `send.php`
|
|
podpisuje własne tokeny antybotowe. Wygeneruj dowolny losowy ciąg:
|
|
|
|
```bash
|
|
php -r "echo bin2hex(random_bytes(32)), PHP_EOL;"
|
|
```
|
|
|
|
Zmiana tej wartości unieważnia formularze otwarte w tej chwili w
|
|
przeglądarkach; nic poza tym się nie dzieje.
|
|
|
|
### Uwagi
|
|
|
|
- Plik musi być czytelny dla użytkownika, na którym działa PHP (zwykle
|
|
`www-data`), i **nieczytelny dla świata**: `chmod 640`, właściciel
|
|
`root:www-data`.
|
|
- `api/config.php` robi na tym pliku `require`, więc plik musi być poprawnym
|
|
PHP. Jeśli wykonuje jakieś operacje przy dołączeniu (łączenie z bazą i tym
|
|
podobne), wykonają się także przy wysyłce formularza.
|
|
- Ścieżkę można zmienić zmienną środowiskową `SOFTSPM_SHARED_CONFIG`.
|
|
|
|
## 2. Kolejność szukania ustawień
|
|
|
|
Wygrywa pierwsze znalezione:
|
|
|
|
1. zmienne środowiskowe `SOFTSPM_MAIL_API_KEY`, `SOFTSPM_FORM_SECRET`
|
|
2. `/etc/hydronexis/config.php` (stałe albo klucze tablicy - patrz wyżej)
|
|
3. `api/config.local.php` - tylko do pracy lokalnej, wzór w
|
|
[config.local.sample.php](config.local.sample.php)
|
|
|
|
Adresat (`recipient`) i lista domen działają tak samo, z tym że wartość
|
|
z `/etc/hydronexis/config.php` nadpisuje domyślną z `api/config.php`.
|
|
|
|
## 3. Katalog roboczy
|
|
|
|
`send.php` zakłada przy pierwszym uruchomieniu `api/storage/` na zużyte tokeny,
|
|
liczniki adresów IP i log. Katalog dostaje `.htaccess` z `Require all denied`.
|
|
Na serwerze innym niż Apache **zablokuj ten katalog samodzielnie** - nie
|
|
powinien być dostępny z zewnątrz. Musi być zapisywalny dla PHP:
|
|
|
|
```bash
|
|
mkdir -p /sciezka/do/strony/api/storage
|
|
chown www-data:www-data /sciezka/do/strony/api/storage
|
|
chmod 750 /sciezka/do/strony/api/storage
|
|
```
|
|
|
|
W logu (`api/storage/log/RRRR-MM.log`) zapisujemy tylko fakt wysyłki, nazwę
|
|
formularza i skrót adresu IP - bez treści zgłoszeń i bez danych osobowych.
|
|
|
|
## 4. Format wiadomości: czysty tekst, nie HTML
|
|
|
|
`send_email_api.php` **sanityzuje treść** przed osadzeniem jej we własnym
|
|
szablonie (manual, punkt 7). Znaczniki wysłane z `send.php` docierają więc do
|
|
skrzynki jako widoczny tekst `<p style="...">`. Dlatego wiadomości budujemy
|
|
z czystego tekstu i **nie wolno tu wstawiać HTML-a**.
|
|
|
|
Układ jest odporny na to, czy szablon po drugiej stronie zamienia znaki nowej
|
|
linii na `<br>`, czy nie: każda pozycja to osobna linia `Etykieta: wartość`,
|
|
która zostaje czytelna nawet po sklejeniu w jeden akapit.
|
|
|
|
```
|
|
Nowe zgłoszenie ze strony softspm.com
|
|
Formularz: Zgłoszenie - szkolenia i webinaria
|
|
Odpowiedz na: jan.kowalski@pwik.example.pl
|
|
|
|
--- DANE Z FORMULARZA ---
|
|
Imię i nazwisko: Jan Kowalski
|
|
Przedsiębiorstwo: PWiK Testowo
|
|
E-mail: jan.kowalski@pwik.example.pl
|
|
Telefon: 600 100 200
|
|
Interesujący temat: Prawo wodne i wniosek taryfowy
|
|
Wiadomość:
|
|
Sześć osób z działu rozliczeń.
|
|
Najlepiej pierwszy kwartał.
|
|
|
|
--- ZGODA UDZIELONA PRZY WYSYŁCE ---
|
|
Wyrażam zgodę na przetwarzanie moich danych osobowych przez SoftSPM (...)
|
|
|
|
--- METRYKA ---
|
|
Strona: https://softspm.com/szkolenia.html#zgloszenie
|
|
Data (UTC): 2026-09-01 09:12:33
|
|
Adres IP: 203.0.113.7
|
|
```
|
|
|
|
Jeśli w otrzymanym mailu linie nadal są sklejone w jeden akapit, znaczy to, że
|
|
szablon endpointu nie zamienia `\n` na `<br>`. `send_email_api.php` jest wasz,
|
|
więc najczystszą poprawką jest tam jedno `nl2br()` na sanityzowanej treści -
|
|
nic po stronie tej strony nie wymaga wtedy zmian.
|
|
|
|
## 5. Zabezpieczenia przed botami
|
|
|
|
Suwak sam z siebie niczego nie gwarantuje - jest elementem interfejsu, a nie
|
|
kryptografią. Blokady, które faktycznie odsiewają automaty, działają na
|
|
serwerze i składają się na całość:
|
|
|
|
| Warstwa | Co robi |
|
|
|---|---|
|
|
| Token podpisany HMAC | Wysyłka wymaga tokenu wydanego wcześniej przez `send.php`. Skrypt musi wykonać dwa dodatkowe żądania, nie jeden POST. |
|
|
| Potwierdzenie suwakiem | Osobne, podpisane potwierdzenie wydawane dopiero po przesunięciu suwaka; musi mieć ten sam identyfikator co token. |
|
|
| Jednorazowość | Każdy token przechodzi raz. Powtórka tego samego żądania dostaje HTTP 409. |
|
|
| Bramka czasowa | Minimum 3 sekundy między pierwszym dotknięciem formularza a wysyłką (`min_fill_seconds`). Automat robi to w ułamku sekundy. |
|
|
| Pole-pułapka | Ukryte pole `firma_www`. Wypełnione = bot. Odpowiadamy sukcesem, żeby nie podpowiadać, co go zdradziło. |
|
|
| Kontrola pochodzenia | `Origin`/`Referer` musi wskazywać na domenę z listy. |
|
|
| Limit adresu IP | 5 zgłoszeń na godzinę, 20 na dobę (`rate_limit` w `config.php`). |
|
|
| Stały adresat | Adres odbiorcy pochodzi wyłącznie z konfiguracji serwera, nigdy z formularza - endpoint nie jest przekaźnikiem spamu. |
|
|
|
|
Jeśli mimo to zacznie przechodzić spam, następnym krokiem jest Cloudflare
|
|
Turnstile albo hCaptcha - obie działają na tej samej zasadzie co obecny token,
|
|
więc podmiana dotknie tylko `send.php` i `assets/forms.js`.
|
|
|
|
## 6. Test po wdrożeniu
|
|
|
|
```bash
|
|
# 1. Token - powinien zwrócić {"ok":true,"token":"t.szkolenia...."}
|
|
curl -s -H "Referer: https://softspm.com/szkolenia.html" \
|
|
"https://softspm.com/api/send.php?action=token&form=szkolenia"
|
|
|
|
# 2. Bez nagłówka Referer/Origin - powinno być HTTP 403
|
|
curl -s -o /dev/null -w '%{http_code}\n' \
|
|
"https://softspm.com/api/send.php?action=token&form=szkolenia"
|
|
|
|
# 3. GET na nieznany formularz - HTTP 400
|
|
curl -s -o /dev/null -w '%{http_code}\n' -H "Referer: https://softspm.com/" \
|
|
"https://softspm.com/api/send.php?action=token&form=cokolwiek"
|
|
|
|
# 4. POST bez tokenu - HTTP 400 (bad_token)
|
|
curl -s -H "Content-Type: application/json" -H "Origin: https://softspm.com" \
|
|
-d '{"form":"szkolenia","zgoda":true,"imie":"Test"}' \
|
|
"https://softspm.com/api/send.php"
|
|
```
|
|
|
|
Jeśli krok 1 zwraca `{"error":"not_configured"}`, PHP nie widzi klucza albo
|
|
sekretu - sprawdź uprawnienia `/etc/hydronexis/config.php`.
|
|
|
|
Test całości: otwórz formularz w przeglądarce, wypełnij, przesuń suwak,
|
|
zaznacz zgodę i wyślij. Wiadomość powinna dojść na adres z
|
|
`SOFTSPM_FORM_RECIPIENT`, a w `api/storage/log/` pojawi się wpis `sent`.
|