403Webshell
Server IP : 188.114.96.3  /  Your IP : 216.73.216.143
Web Server : Apache
System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64
User :  ( 3194769)
PHP Version : 8.5.12
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /polana/admin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /polana/admin/polana-v1812-naprawa-maili.php
<?php
declare(strict_types=1);
/** POLANA V18.12 – emergency mail diagnostics. Install one admin file; reversible config patch.
 * This file is intentionally a standalone authenticated admin page.
 * It does not change reservation status or any customer data.
 */
require_once dirname(__DIR__) . '/includes/functions.php';
require_admin_role();
header('Cache-Control: private, no-store, max-age=0');
header('Pragma: no-cache');
header('X-Robots-Tag: noindex,nofollow');

const PM12_URL = '/admin/polana-v1812-naprawa-maili.php';
function pm12_h($s): string { return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
function pm12_settings_write(array $items): void {
    $pdo = db();
    $pdo->beginTransaction();
    try {
        $q=$pdo->prepare('INSERT INTO settings (setting_key,setting_value) VALUES (?,?) ON DUPLICATE KEY UPDATE setting_value=VALUES(setting_value)');
        foreach ($items as $k=>$v) $q->execute([(string)$k,(string)$v]);
        $pdo->commit();
    } catch (Throwable $e) {
        if($pdo->inTransaction()) $pdo->rollBack();
        throw $e;
    }
}
function pm12_is_email(string $val): bool { return $val!=='' && filter_var($val, FILTER_VALIDATE_EMAIL)!==false && !preg_match('/[\r\n]/',$val); }
function pm12_rate_limit(string $action, int $seconds=20): void {
    start_session();
    $k='pm12_last_'.$action;
    if((int)($_SESSION[$k]??0)>time()-$seconds) throw new RuntimeException('Odczekaj chwilę przed kolejną wysyłką.');
    $_SESSION[$k]=time();
}
function pm12_error_safe(Throwable $e): string {
    $s=$e->getMessage();
    $s=preg_replace('/(?i)(password|secret|token)\s*[:=]\s*\S+/','[dane ukryte]',$s)??'Nieznany błąd';
    return function_exists('mb_substr') ? mb_substr($s,0,500,'UTF-8') : substr($s,0,500);
}

if(($_SERVER['REQUEST_METHOD']??'GET')==='POST') {
    verify_csrf();
    $action=(string)($_POST['action']??'');
    try {
        if($action==='fix_from') {
            $username=trim(setting('smtp_username',''));
            $from=trim(setting('smtp_from_email',''));
            if(!pm12_is_email($username)) throw new RuntimeException('Login SMTP nie jest adresem e-mail; nie można bezpiecznie ustawić nadawcy automatycznie.');
            if(strcasecmp($from,$username)===0) throw new RuntimeException('Nadawca SMTP już odpowiada loginowi – nie ma tu nic do naprawienia.');
            // Own undo keys are created only when actually changing the setting.
            pm12_settings_write([
                'polana_v1812_previous_from'=>$from,
                'polana_v1812_fixed_from'=>$username,
                'smtp_from_email'=>$username,
            ]);
            try { admin_log('polana_v1812_smtp_from','Skorygowano nadawcę SMTP do loginu; stare ustawienie dostępne do rollbacku.'); } catch(Throwable $ignored) {}
            flash('success','Zmieniono nadawcę SMTP na konto używane do logowania. Adres powiadomień restauracji oraz hasło SMTP nie zostały zmienione. Wykonaj test wysyłki.');
        } elseif($action==='undo_from') {
            $previous=setting('polana_v1812_previous_from','');
            $fixed=setting('polana_v1812_fixed_from','');
            $current=setting('smtp_from_email','');
            if($fixed==='' || strcasecmp($current,$fixed)!==0) throw new RuntimeException('Ustawienie nadawcy zmieniło się od czasu poprawki. Cofanie automatyczne zablokowane.');
            if($previous!=='' && !pm12_is_email($previous)) throw new RuntimeException('Poprzedni adres jest niepoprawny.');
            pm12_settings_write(['smtp_from_email'=>$previous,'polana_v1812_fixed_from'=>'']);
            flash('success','Przywrócono poprzedni adres nadawcy SMTP.');
        } elseif($action==='auto_reply_on') {
            $prev=setting('reservation_auto_reply_enabled','0');
            pm12_settings_write(['polana_v1812_previous_auto_reply'=>$prev,'reservation_auto_reply_enabled'=>'1']);
            flash('success','Włączono wiadomość automatyczną: otrzymaliśmy prośbę. Nie jest ona potwierdzeniem stolika.');
        } elseif($action==='test_smtp') {
            pm12_rate_limit($action);
            $to=trim((string)($_POST['test_email']??''));
            if(!pm12_is_email($to)) throw new RuntimeException('Podaj poprawny adres odbiorcy testu.');
            if(setting('smtp_enabled','0')!=='1') throw new RuntimeException('SMTP jest wyłączone.');
            $text='Test POLANA V18.12: serwer SMTP przyjął wiadomość testową. Sprawdź odbiór i folder SPAM.';
            smtp_send_mail($to,'POLANA V18.12 — test potwierdzeń',reservation_email_html('Test potwierdzeń',$text),$text);
            flash('success','SMTP przyjął wiadomość testową do wskazanego odbiorcy. Sprawdź skrzynkę i SPAM (sam sukces SMTP nie gwarantuje doręczenia).');
        } elseif($action==='resend_received' || $action==='resend_confirmed') {
            pm12_rate_limit('resend',15);
            if((string)($_POST['confirm_send']??'')!=='TAK') throw new RuntimeException('Potwierdź świadomie ponowną wysyłkę.');
            $id=filter_var($_POST['reservation_id']??'',FILTER_VALIDATE_INT,['options'=>['min_range'=>1]]);
            if(!$id) throw new RuntimeException('Nieprawidłowy numer ID rezerwacji.');
            $reservation=reservation_by_id((int)$id);
            if(!$reservation) throw new RuntimeException('Nie znaleziono rezerwacji.');
            $kind=$action==='resend_confirmed'?'confirmed':'received';
            if($kind==='confirmed' && (string)$reservation['status']!=='confirmed') {
                throw new RuntimeException('Potwierdzenie można ponowić tylko dla rezerwacji ze statusem Potwierdzona.');
            }
            if($kind==='received' && (string)$reservation['status']!=='new') {
                throw new RuntimeException('Autoresponder prośby można ponowić tylko dla rezerwacji Nowa.');
            }
            if(!pm12_is_email(trim((string)($reservation['email']??'')))) throw new RuntimeException('Rezerwacja nie ma prawidłowego e-maila.');
            try {
                reservation_send_guest_message($reservation,$kind);
            } catch(Throwable $mailError) {
                $safe=pm12_error_safe($mailError);
                try { reservation_add_event((int)$id,'email_error','POLANA V18.12: nieudana próba ręcznej wysyłki: '.$safe); } catch(Throwable $ignored) {}
                throw new RuntimeException('E-mail nie został przyjęty przez SMTP: '.$safe);
            }
            flash('success','SMTP przyjął wiadomość dla wybranej rezerwacji; jej status NIE został zmieniony. Sprawdź doręczenie u gościa.');
        } else {
            throw new RuntimeException('Nieznana operacja.');
        }
    } catch(Throwable $e) {
        flash('error','Nie wykonano: '.pm12_error_safe($e));
    }
    redirect(PM12_URL);
}

$username=trim(setting('smtp_username',''));
$from=trim(setting('smtp_from_email',''));
$reply=trim(setting('reservation_admin_email',''));
$isEnabled=setting('smtp_enabled','0')==='1';
$autoReply=setting('reservation_auto_reply_enabled','0')==='1';
$hasPassword=function_exists('smtp_password_is_set') && smtp_password_is_set();
$match=$username!=='' && strcasecmp($username,$from)===0;
$canFix=pm12_is_email($username) && !$match;
$errors=[];$recent=[];$historyReadError='';
try {
    ensure_reservations_schema();
    $errors=db()->query("SELECT e.reservation_id, e.message, e.created_at, r.reservation_code, r.status
       FROM reservation_events e JOIN reservations r ON r.id=e.reservation_id
       WHERE e.event_type='email_error' ORDER BY e.id DESC LIMIT 20")->fetchAll(PDO::FETCH_ASSOC);
    $recent=db()->query("SELECT id, reservation_code, status, reservation_date, reservation_time, email
       FROM reservations WHERE status IN ('confirmed','new') ORDER BY id DESC LIMIT 20")->fetchAll(PDO::FETCH_ASSOC);
} catch(Throwable $e) { $historyReadError='Historia niedostępna: '.pm12_error_safe($e); }
render_admin_header('POLANA V18.12 — Naprawa potwierdzeń e-mail');
?>
<style>
.pm12{max-width:1100px;margin:0 auto;padding:14px 12px 60px}.pm12 .pane{background:var(--card,#fff);border:1px solid #d3d9d3;border-radius:14px;margin:15px 0;padding:18px;color:inherit}.pm12 h1{font-size:1.7rem}.pm12 .dim{opacity:.78}.pm12 .status{font-weight:bold}.pm12 .good{color:#15803d}.pm12 .bad{color:#b91c1c}.pm12 .warn{color:#9a6517}.pm12 table{width:100%;border-collapse:collapse;font-size:14px}.pm12 th,.pm12 td{border-bottom:1px solid #9995;padding:10px 7px;text-align:left;vertical-align:top}.pm12 input{padding:11px;border:1px solid #aebbb2;border-radius:8px;min-width:220px;max-width:100%}.pm12 button{border:0;background:#b95418;color:#fff;padding:12px 16px;border-radius:9px;cursor:pointer;font-weight:bold;margin:4px}.pm12 button.secondary{background:#3e4f50}.pm12 .wide{overflow-x:auto}.pm12 .small{font-size:13px}.pm12 form{margin:10px 0}.pm12 a{color:inherit;text-decoration:underline}.pm12 .stop{border-left:5px solid #b45309;padding-left:12px}.pm12 .line{display:flex;align-items:center;flex-wrap:wrap;gap:10px}
</style>
<div class="pm12">
<h1>Naprawa wysyłania potwierdzeń rezerwacji</h1>
<p>Diagnostyka działa na <strong>aktualnych ustawieniach hostingu</strong>, bez odczytywania haseł na ekran. Nie zmienia statusów rezerwacji, a przyciski wysyłki wymagają świadomego potwierdzenia.</p>
<section class="pane"><h2>1. Kontrola SMTP</h2>
<table><tr><td>SMTP</td><td><span class="status <?= $isEnabled?'good':'bad' ?>"><?= $isEnabled?'WŁĄCZONE':'WYŁĄCZONE' ?></span></td></tr>
<tr><td>Zaszyfrowane hasło</td><td><?= $hasPassword?'Zapisano':'BRAK' ?></td></tr>
<tr><td>Serwer</td><td><?=pm12_h(setting('smtp_host',''))?> : <?=pm12_h(setting('smtp_port',''))?> (<?=pm12_h(setting('smtp_security',''))?>)</td></tr>
<tr><td>Login SMTP</td><td><?=pm12_h($username)?></td></tr>
<tr><td>Nadawca SMTP (From)</td><td><?=pm12_h($from)?></td></tr>
<tr><td>Zgodność nadawcy z kontem</td><td class="status <?= $match?'good':'bad' ?>"><?= $match?'TAK':'NIE — może powodować 553 na home.pl' ?></td></tr>
<tr><td>Adres powiadomień restauracji (odbiorca / Reply-To)</td><td><?=pm12_h($reply)?></td></tr>
<tr><td>Autoresponder po nowej prośbie</td><td class="status <?= $autoReply?'good':'warn' ?>"><?= $autoReply?'WŁĄCZONY':'WYŁĄCZONY' ?></td></tr></table>
<?php if($canFix): ?>
<p class="stop"><strong>Naprawa możliwa:</strong> nadawca różni się od loginu. Kliknięcie zmienia tylko ustawienie <code>smtp_from_email</code> na login. Nie zmienia hasła, adresu powiadomień ani stanu rezerwacji.</p>
<form method="post"><?=csrf_field()?><input type="hidden" name="action" value="fix_from"><button type="submit">Napraw nadawcę SMTP</button></form>
<?php endif; ?>
<?php if(setting('polana_v1812_fixed_from','')!=='' && $from===setting('polana_v1812_fixed_from','')): ?>
<form method="post"><?=csrf_field()?><input type="hidden" name="action" value="undo_from"><button class="secondary" type="submit">Rollback — przywróć poprzedniego nadawcę</button></form>
<?php endif; ?>
<?php if(!$autoReply): ?><form method="post"><?=csrf_field()?><input type="hidden" name="action" value="auto_reply_on"><button class="secondary" type="submit">Włącz automatyczną odpowiedź po nowym zgłoszeniu</button></form><?php endif; ?>
<p><a href="/admin/polana-poczta.php">Pełna konfiguracja SMTP</a> · <a href="/admin/reservation-settings.php">Ustawienia rezerwacji</a></p>
</section>
<section class="pane"><h2>2. Test SMTP — bez zmiany rezerwacji</h2>
<p>Najpierw testuj na własnym adresie. SMTP może przyjąć e-mail, ale jego doręczenie do skrzynki należy jeszcze sprawdzić.</p>
<form method="post" class="line"><?=csrf_field()?><input type="hidden" name="action" value="test_smtp">
<label for="test_email">E-mail testowy <input id="test_email" name="test_email" type="email" required maxlength="254" placeholder="[email protected]"></label>
<button type="submit">Wyślij jeden test</button></form></section>
<section class="pane"><h2>3. Błędy wiadomości zapisane przy rezerwacjach</h2>
<?php if($historyReadError!==''):?><p class="bad"><?=pm12_h($historyReadError)?></p>
<?php elseif(!$errors):?><p>Nie znaleziono wpisów <code>email_error</code> w ostatnich zdarzeniach. To nie potwierdza doręczenia poczty.</p>
<?php else:?><div class="wide"><table><thead><tr><th>Termin</th><th>Rezerwacja</th><th>Wynik</th></tr></thead><tbody>
<?php foreach($errors as $row): ?><tr><td><?=pm12_h($row['created_at'])?></td><td><a href="/admin/reservation.php?id=<?=(int)$row['reservation_id']?>"><?=pm12_h($row['reservation_code'])?></a><br><?=pm12_h($row['status'])?></td><td><?=pm12_h($row['message'])?></td></tr><?php endforeach; ?>
</tbody></table></div><?php endif; ?></section>
<section class="pane"><h2>4. Ponów potwierdzenie jednej istniejącej rezerwacji</h2>
<p class="stop"><strong>Uwaga:</strong> to wysyła prawdziwy e-mail do gościa. Najpierw wykonaj test SMTP i sprawdź historię, żeby nie zdublować wiadomości. Nie zmienia statusu, terminu, kalendarza ani danych rezerwacji.</p>
<?php if($recent): ?><div class="wide"><table><thead><tr><th>Rezerwacja</th><th>Status</th><th>Operacja</th></tr></thead><tbody>
<?php foreach($recent as $row): $isConfirmed=$row['status']==='confirmed'; ?>
<tr><td><a href="/admin/reservation.php?id=<?=(int)$row['id']?>"><?=pm12_h($row['reservation_code'])?></a> <span class="dim">· <?=pm12_h($row['reservation_date'])?> <?=pm12_h(substr((string)$row['reservation_time'],0,5))?></span></td><td><?= $isConfirmed?'Potwierdzona':'Nowa' ?></td>
<td><form method="post" class="line"><?=csrf_field()?><input type="hidden" name="action" value="<?= $isConfirmed?'resend_confirmed':'resend_received' ?>"><input type="hidden" name="reservation_id" value="<?=(int)$row['id']?>">
<label class="small"><input type="checkbox" name="confirm_send" value="TAK" required style="min-width:0"> Potwierdzam wysyłkę</label>
<button type="submit" class="secondary"><?= $isConfirmed?'Wyślij potwierdzenie ponownie':'Wyślij potwierdzenie otrzymania' ?></button></form></td></tr>
<?php endforeach; ?></tbody></table></div>
<?php else: ?><p>Brak rezerwacji na liście.</p><?php endif; ?>
<p class="dim small">Lista to maksymalnie 20 ostatnich rezerwacji o statusach Nowa i Potwierdzona. Brak pozycji oznacza tylko, że nie mieści się na tej liście. Błędy są zapisywane w historii rezerwacji.</p>
</section>
<section class="pane"><h2>Ważne</h2><p>Wysłanie autorespondera „otrzymaliśmy prośbę” nie oznacza potwierdzenia stolika. Właściwy e-mail potwierdzający wysyłany jest po decyzji obsługi „Potwierdź”, o ile SMTP jest włączone. W starej wersji aplikacji zmiana statusu nie sygnalizuje jednoznacznie błędu poczty — sprawdź wpisy <code>email_error</code> powyżej.</p>
<p>Po skutecznym teście sprawdź jeszcze folder SPAM i dostarczalność u odbiorcy. Samo <code>SMTP 250</code> to akceptacja przez serwer, nie dowód dostarczenia.</p></section>
</div>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit