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-v1810-google-bridge.php
<?php
declare(strict_types=1);
/** POLANA V18.10: One-time credential bridge (Google Calendar -> Drive backup).
 * Never copies Calendar access/refresh tokens or touches its encrypted store.
 * Requires existing POLANA v17.3 calendar and v18.3 backup modules.
 */
require_once dirname(__DIR__) . '/includes/polana_backup_v182.php';
require_admin_role();
header('Cache-Control: private, no-store, max-age=0');
header('X-Robots-Tag: noindex,nofollow');
header('X-Content-Type-Options: nosniff');
header('Referrer-Policy: no-referrer');

function bridge_h(mixed $s): string { return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
function bridge_rollback_file(): string { return pbk_private() . '/v1810-google-bridge-rollback.json'; }
function bridge_calendar_secrets(): array {
    $lib = dirname(__DIR__) . '/includes/polana_gcal.php';
    if (!is_file($lib)) throw new RuntimeException('Brak biblioteki Kalendarza Google (includes/polana_gcal.php).');
    require_once $lib;
    if (!function_exists('pg173_read_secrets')) throw new RuntimeException('Biblioteka kalendarza nie udostępnia odczytu OAuth.');
    $s = pg173_read_secrets();
    if (!is_array($s) || empty($s['refresh_token'])) throw new RuntimeException('Kalendarz nie ma aktywnego połączenia Google. Najpierw sprawdź moduł Kalendarz.');
    $id = trim((string)($s['client_id'] ?? ''));
    $secret = trim((string)($s['client_secret'] ?? ''));
    if (strlen($id) < 20 || strlen($id) > 260 || !str_ends_with($id, '.apps.googleusercontent.com') || strlen($secret) < 8 || strlen($secret) > 500) {
        throw new RuntimeException('W kalendarzu nie znaleziono poprawnego Client ID i Secret.');
    }
    return ['client_id' => $id, 'client_secret' => $secret]; // never return a token
}
function bridge_write_rollback(array $before, array $after): void {
    $path = bridge_rollback_file();
    if (file_exists($path)) throw new RuntimeException('Istnieje już punkt cofania V18.10. Przywróć go lub zakończ konfigurację.');
    $keys = ['drive_client_id','drive_client_secret','drive_refresh_token','drive_folder_id','drive_enabled'];
    $original = [];
    foreach ($keys as $key) {
        $original[$key] = ['exists' => array_key_exists($key, $before), 'value' => $before[$key] ?? null];
    }
    $data = [
        'version' => '18.10', 'created' => gmdate('c'), 'before' => $original,
        'after_client_id' => (string)($after['drive_client_id'] ?? ''),
        'after_encrypted_secret' => (string)($after['drive_client_secret'] ?? ''),
    ];
    $encoded = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
    $handle = @fopen($path, 'x+b');
    if ($handle === false) throw new RuntimeException('Nie można bezpiecznie utworzyć punktu cofania.');
    try {
        @chmod($path, 0600);
        if (fwrite($handle, $encoded) !== strlen($encoded)) throw new RuntimeException('Błąd zapisu punktu cofania.');
        fflush($handle);
    } catch (Throwable $e) { fclose($handle); @unlink($path); throw $e; }
    fclose($handle);
}
function bridge_import(): string {
    $calendar = bridge_calendar_secrets();
    $before = pbk_cfg();
    $existingId = trim((string)($before['drive_client_id'] ?? ''));
    $connected = !empty($before['drive_refresh_token']);
    if ($connected && $existingId !== $calendar['client_id']) {
        throw new RuntimeException('Backup ma już autoryzowane INNE konto lub klienta OAuth. Nie nadpisuję go.');
    }
    if ($connected && $existingId === $calendar['client_id']) {
        return 'Drive ma już własny token i używa tego samego klienta OAuth. Niczego nie zmieniono.';
    }
    if ($existingId === $calendar['client_id'] &&
        hash_equals($calendar['client_secret'], pbk_secret_decrypt((string)($before['drive_client_secret'] ?? '')))) {
        return 'Dane OAuth z Kalendarza są już zapisane w module backupów. Teraz połącz Google Drive przez OAuth.';
    }
    // Even though the client ID is the same, we never change an already-working Drive connection.
    $after = $before;
    $after['drive_client_id'] = $calendar['client_id'];
    $after['drive_client_secret'] = pbk_secret_encrypt($calendar['client_secret']);
    // The Calendar refresh token is never imported; Drive requires fresh consent.
    $after['drive_refresh_token'] = '';
    $after['drive_folder_id'] = '';
    $after['drive_enabled'] = false;
    bridge_write_rollback($before, $after);
    try { pbk_save_cfg($after); }
    catch (Throwable $e) { @unlink(bridge_rollback_file()); throw $e; }
    return 'Przyjęto bezpiecznie zapisane Client ID i Client Secret z Kalendarza. Tokeny Kalendarza i ustawienia rezerwacji pozostają bez zmian.';
}
function bridge_rollback(): string {
    $path = bridge_rollback_file();
    if (!is_file($path)) throw new RuntimeException('Brak punktu cofania V18.10.');
    $snapshot = json_decode((string)file_get_contents($path), true);
    if (!is_array($snapshot) || ($snapshot['version'] ?? '') !== '18.10' || !isset($snapshot['before']) || !is_array($snapshot['before'])) {
        throw new RuntimeException('Punkt cofania jest uszkodzony. Nie wykonuję zmian.');
    }
    $cfg = pbk_cfg();
    if (!hash_equals((string)($snapshot['after_client_id'] ?? ''), (string)($cfg['drive_client_id'] ?? '')) ||
        !hash_equals((string)($snapshot['after_encrypted_secret'] ?? ''), (string)($cfg['drive_client_secret'] ?? '')) ||
        !empty($cfg['drive_refresh_token']) || !empty($cfg['drive_enabled'])) {
        throw new RuntimeException('Ustawienia Drive zmieniły się po imporcie lub konto zostało połączone. Rollback zablokowany, aby nie zerwać aktywnego połączenia.');
    }
    $keys = ['drive_client_id','drive_client_secret','drive_refresh_token','drive_folder_id','drive_enabled'];
    foreach ($keys as $key) {
        if (!isset($snapshot['before'][$key]) || !is_array($snapshot['before'][$key])) throw new RuntimeException('Niekompletny punkt cofania.');
        if ($snapshot['before'][$key]['exists'] === true) $cfg[$key] = $snapshot['before'][$key]['value'];
        else unset($cfg[$key]);
    }
    pbk_save_cfg($cfg);
    @unlink($path);
    return 'Przywrócono wcześniejsze ustawienia Google Drive. Połączenie Kalendarza pozostaje bez zmian.';
}

$error = ''; $notice = ''; $calendarStatus = 'nieodczytany'; $driveStatus = 'nieodczytany';
try {
    if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
        verify_csrf();
        $action = (string)($_POST['action'] ?? '');
        if ($action === 'import') $notice = bridge_import();
        elseif ($action === 'rollback') $notice = bridge_rollback();
        else throw new RuntimeException('Nieznana operacja.');
    }
    $calendar = bridge_calendar_secrets();
    $calendarStatus = 'Połączony — zapisane OAuth jest dostępne';
    $cfg = pbk_cfg();
    $driveStatus = !empty($cfg['drive_refresh_token']) ? 'Połączony — token Drive zapisany' :
        (empty($cfg['drive_client_id']) ? 'Nie skonfigurowano' : 'Client ID i Secret zapisane — oczekuje na zgodę Drive');
} catch (Throwable $e) { $error = $e->getMessage(); }
render_admin_header('Google OAuth — jeden zestaw danych');
?>
<style>
.bridge10{max-width:960px;margin:24px auto 56px;padding:0 16px;color:#26382e}.bridge10 *{box-sizing:border-box}.bridge10 h1{font-size:clamp(25px,3vw,35px)}.bridge10 h2{font-size:20px}.bridge10 section{margin:16px 0;padding:22px;border:1px solid #dbe5dd;border-radius:15px;background:#fff}.bridge10 p{line-height:1.65}.bridge10 .buttons{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.bridge10 button,.bridge10 .link{font:inherit;font-weight:700;border-radius:9px;background:#18442c;color:#fff;border:none;padding:11px 17px;cursor:pointer;display:inline-block;text-decoration:none}.bridge10 .secondary{background:#e8eee9;color:#18442c}.bridge10 .alert{background:#fff2e7;border-left:4px solid #bf7234;border-radius:8px;padding:12px 14px}.bridge10 .ok{background:#edf7e9;border-left:4px solid #4a9b55;border-radius:8px;padding:12px 14px}.bridge10 code{overflow-wrap:anywhere}.bridge10 .muted{color:#607266}.bridge10 ol{padding-left:25px;line-height:1.9}@media(max-width:620px){.bridge10 section{padding:16px}.bridge10 .buttons>*{width:100%;text-align:center}}
</style>
<div class="bridge10">
  <h1>Google — te same dane OAuth</h1>
  <p>POLANA V18.10: jednorazowy most między już skonfigurowanym Kalendarzem Google a automatycznymi kopiami na Dysk Google. <b>Bez przepisywania Client ID ani Client Secret.</b></p>
  <?php if ($notice): ?><p class="ok" role="status"><?=bridge_h($notice)?></p><?php endif; ?>
  <?php if ($error): ?><p class="alert" role="alert"><?=bridge_h($error)?></p><?php endif; ?>
  <section>
    <h2>Stan połączeń</h2>
    <p><b>Kalendarz:</b> <?=bridge_h($calendarStatus)?></p>
    <p><b>Google Drive:</b> <?=bridge_h($driveStatus)?></p>
    <p class="muted">Kopiujemy wyłącznie dane aplikacji OAuth. Nigdy nie kopiujemy tokenów ani kluczy szyfrujących Kalendarza. Kopie SQL pozostają nietknięte.</p>
    <div class="buttons">
      <form method="post"><?=csrf_field()?><input type="hidden" name="action" value="import"><button type="submit">Użyj danych Google z Kalendarza</button></form>
      <a class="link secondary" href="/admin/polana-backup-automat.php">Otwórz kopie zapasowe</a>
    </div>
  </section>
  <section>
    <h2>Jednorazowe zezwolenie na Google Drive</h2>
    <ol>
      <li>W projekcie Google Cloud włącz <b>Google Drive API</b>.</li>
      <li>W tym samym kliencie OAuth (Web application), co Kalendarz, dodaj drugi <b>Authorized redirect URI</b>:<br><code><?=bridge_h(pbk_oauth_redirect_uri())?></code>. Nie usuwaj adresu callback Kalendarza.</li>
      <li>W <b>Automatyczne kopie</b> kliknij <b>Połącz Google Drive (OAuth)</b> i wybierz to samo konto Google, które ma kalendarz.</li>
      <li>Po wyrażeniu zgody zaznacz <b>Wysyłaj kopie na Google Drive</b>, zapisz i kliknij <b>Sprawdź połączenie Drive</b>.</li>
    </ol>
    <p class="muted">Uprawnienie Drive to <code>drive.file</code>, inne niż wcześniej przyznany dostęp do Kalendarza. Kalendarz i Drive korzystają z jednego klienta OAuth, ale mają osobne tokeny.</p>
  </section>
  <section>
    <h2>Rollback — tylko przed połączeniem Drive</h2>
    <p class="muted">Przywraca wyłącznie wcześniejsze ustawienia Drive. Jeśli Google Drive został już połączony, rollback jest celowo zablokowany, aby nie utracić dostępu.</p>
    <form method="post"><?=csrf_field()?><input type="hidden" name="action" value="rollback"><button type="submit" class="secondary">Cofnij import danych OAuth</button></form>
  </section>
</div>
<?php render_admin_footer(); ?>

Youez - 2016 - github.com/yon3zu
LinuXploit