mirror of
https://github.com/artemium428/428th-website-2026.git
synced 2026-09-15 17:06:20 +00:00
Compare commits
No commits in common. "1fb33e1bd83ac67a7b503c91bfde0852b67a896d" and "793d093c86bc2982d1a1dd43a8e34b90fa665191" have entirely different histories.
1fb33e1bd8
...
793d093c86
11 changed files with 38 additions and 57 deletions
|
|
@ -104,6 +104,6 @@ Backup is written even if Telegram fails (`telegram_ok: false`), so you still ha
|
||||||
|
|
||||||
## Behaviour notes
|
## Behaviour notes
|
||||||
|
|
||||||
- Honeypot field `hp_company` (legacy `website` still checked): if filled, returns `200` without notifying Telegram or writing a backup.
|
- Honeypot field `website`: if filled, returns `200` without notifying Telegram or writing a backup.
|
||||||
- In-memory rate limit: 5 POSTs per IP per 60 seconds → `429`.
|
- In-memory rate limit: 5 POSTs per IP per 60 seconds → `429`.
|
||||||
- Field limits: name/contact ≤ 200 chars, message ≤ 4000.
|
- Field limits: name/contact ≤ 200 chars, message ≤ 4000.
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,9 @@ def validate_fields(data: dict) -> tuple[str, str, str] | str:
|
||||||
return "invalid"
|
return "invalid"
|
||||||
|
|
||||||
# Honeypot — treat as success upstream; caller checks separately.
|
# Honeypot — treat as success upstream; caller checks separately.
|
||||||
# Accept legacy "website" (autofill magnets) and current "hp_company".
|
website = data.get("website", "")
|
||||||
for pot in ("hp_company", "website"):
|
if isinstance(website, str) and website.strip():
|
||||||
raw_pot = data.get(pot, "")
|
return "honeypot"
|
||||||
if isinstance(raw_pot, str) and raw_pot.strip():
|
|
||||||
return "honeypot"
|
|
||||||
|
|
||||||
def field(key: str, max_len: int) -> str | None:
|
def field(key: str, max_len: int) -> str | None:
|
||||||
raw = data.get(key, "")
|
raw = data.get(key, "")
|
||||||
|
|
|
||||||
|
|
@ -428,10 +428,10 @@
|
||||||
<h3>Contact form</h3>
|
<h3>Contact form</h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="..." data-status-success="Sent ✓" data-status-error="Could not send. Please try again.">
|
<form id="contactForm" data-status-loading="..." data-status-success="Sent ✓" data-status-error="Could not send. Please try again.">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span>Name</span>
|
<span>Name</span>
|
||||||
|
|
|
||||||
|
|
@ -277,10 +277,10 @@
|
||||||
<h3>Contact form</h3>
|
<h3>Contact form</h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="..." data-status-success="Sent ✓" data-status-error="Could not send. Please try again.">
|
<form id="contactForm" data-status-loading="..." data-status-success="Sent ✓" data-status-error="Could not send. Please try again.">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span>Name</span>
|
<span>Name</span>
|
||||||
|
|
|
||||||
|
|
@ -428,10 +428,10 @@
|
||||||
<h3>Форма для связи</h3>
|
<h3>Форма для связи</h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="..." data-status-success="Отправлено ✓" data-status-error="Не удалось отправить. Попробуйте ещё раз.">
|
<form id="contactForm" data-status-loading="..." data-status-success="Отправлено ✓" data-status-error="Не удалось отправить. Попробуйте ещё раз.">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span>Имя</span>
|
<span>Имя</span>
|
||||||
|
|
|
||||||
|
|
@ -333,10 +333,10 @@
|
||||||
<h3 data-i18n="form.title"></h3>
|
<h3 data-i18n="form.title"></h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="{{FORM_STATUS_LOADING}}" data-status-success="{{FORM_STATUS_SUCCESS}}" data-status-error="{{FORM_STATUS_ERROR}}">
|
<form id="contactForm" data-status-loading="{{FORM_STATUS_LOADING}}" data-status-success="{{FORM_STATUS_SUCCESS}}" data-status-error="{{FORM_STATUS_ERROR}}">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span data-i18n="form.nameLabel"></span>
|
<span data-i18n="form.nameLabel"></span>
|
||||||
|
|
|
||||||
|
|
@ -182,10 +182,10 @@
|
||||||
<h3 data-i18n="form.title"></h3>
|
<h3 data-i18n="form.title"></h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="{{FORM_STATUS_LOADING}}" data-status-success="{{FORM_STATUS_SUCCESS}}" data-status-error="{{FORM_STATUS_ERROR}}">
|
<form id="contactForm" data-status-loading="{{FORM_STATUS_LOADING}}" data-status-success="{{FORM_STATUS_SUCCESS}}" data-status-error="{{FORM_STATUS_ERROR}}">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span data-i18n="form.nameLabel"></span>
|
<span data-i18n="form.nameLabel"></span>
|
||||||
|
|
|
||||||
21
styles.css
21
styles.css
|
|
@ -441,25 +441,8 @@ a:hover{opacity:0.7;}
|
||||||
}
|
}
|
||||||
#contactForm label{display:block; margin-bottom:20px; font-size:13px; color:var(--text);}
|
#contactForm label{display:block; margin-bottom:20px; font-size:13px; color:var(--text);}
|
||||||
#contactForm .hp-field{
|
#contactForm .hp-field{
|
||||||
position:absolute !important;
|
position:absolute; left:-10000px; top:auto; width:1px; height:1px;
|
||||||
left:-10000px !important;
|
overflow:hidden; opacity:0; pointer-events:none;
|
||||||
top:auto !important;
|
|
||||||
width:1px !important;
|
|
||||||
height:1px !important;
|
|
||||||
margin:0 !important;
|
|
||||||
padding:0 !important;
|
|
||||||
overflow:hidden !important;
|
|
||||||
clip:rect(0,0,0,0) !important;
|
|
||||||
border:0 !important;
|
|
||||||
opacity:0 !important;
|
|
||||||
pointer-events:none !important;
|
|
||||||
}
|
|
||||||
#contactForm .hp-field input{
|
|
||||||
width:1px !important;
|
|
||||||
height:1px !important;
|
|
||||||
margin:0 !important;
|
|
||||||
padding:0 !important;
|
|
||||||
border:0 !important;
|
|
||||||
}
|
}
|
||||||
#contactForm input, #contactForm textarea{
|
#contactForm input, #contactForm textarea{
|
||||||
width:100%; margin-top:6px; padding:10px; border:1px solid var(--border);
|
width:100%; margin-top:6px; padding:10px; border:1px solid var(--border);
|
||||||
|
|
|
||||||
|
|
@ -277,10 +277,10 @@
|
||||||
<h3>Форма для связи</h3>
|
<h3>Форма для связи</h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="..." data-status-success="Отправлено ✓" data-status-error="Не удалось отправить. Попробуйте ещё раз.">
|
<form id="contactForm" data-status-loading="..." data-status-success="Отправлено ✓" data-status-error="Не удалось отправить. Попробуйте ещё раз.">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span>Имя</span>
|
<span>Имя</span>
|
||||||
|
|
|
||||||
|
|
@ -428,10 +428,10 @@
|
||||||
<h3>Форма для зв'язку</h3>
|
<h3>Форма для зв'язку</h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="..." data-status-success="Надіслано ✓" data-status-error="Не вдалося надіслати. Спробуйте ще раз.">
|
<form id="contactForm" data-status-loading="..." data-status-success="Надіслано ✓" data-status-error="Не вдалося надіслати. Спробуйте ще раз.">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span>Ім'я</span>
|
<span>Ім'я</span>
|
||||||
|
|
|
||||||
|
|
@ -277,10 +277,10 @@
|
||||||
<h3>Форма для зв'язку</h3>
|
<h3>Форма для зв'язку</h3>
|
||||||
|
|
||||||
<form id="contactForm" data-status-loading="..." data-status-success="Надіслано ✓" data-status-error="Не вдалося надіслати. Спробуйте ще раз.">
|
<form id="contactForm" data-status-loading="..." data-status-success="Надіслано ✓" data-status-error="Не вдалося надіслати. Спробуйте ще раз.">
|
||||||
<div class="hp-field" aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;opacity:0;pointer-events:none">
|
<label class="hp-field" aria-hidden="true">
|
||||||
<label for="hp_company">Company fax</label>
|
<span>Website</span>
|
||||||
<input id="hp_company" type="text" name="hp_company" value="" tabindex="-1" autocomplete="off">
|
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||||
</div>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span>Ім'я</span>
|
<span>Ім'я</span>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue