OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

share_view.php

6 KB
<?php
// Öffentliche Einmal-Freigabe – bewusst OHNE App-Layout (kein Login nötig).
$share = $share ?? null;
?><!DOCTYPE html>
<html lang="<?= $this->e($this->lang()) ?>">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="robots" content="noindex,nofollow">
    <title><?= $this->te('Passwort-Freigabe') ?></title>
    <link rel="stylesheet" href="/assets/css/fonts.css">
    <link rel="stylesheet" href="/assets/css/tokens.css">
    <?php if (($design_style ?? 'standard') === 'material'): ?><link rel="stylesheet" href="/assets/css/theme-material.css"><?php endif; ?>
    <link rel="stylesheet" href="/assets/css/app.css">
    <!-- Diese Seite läuft ohne 'unsafe-inline'; der Verteiler verdrahtet die data-Attribute. -->
    <script src="/assets/js/vault-actions.js" defer></script>
    <style>
        /* Zentrierte Einzelkarte – Formularfelder und Buttons kommen aus app.css */
        body { display:flex; align-items:center; justify-content:center; min-height:100vh; padding:1rem; }
        .sv-card { background:var(--color-bg); border:1px solid var(--color-border); border-radius:0.75rem; box-shadow:0 10px 40px rgba(0,0,0,0.08); width:100%; max-width:440px; padding:1.75rem; }
        .sv-icon { width:52px; height:52px; border-radius:50%; background:var(--color-primary-pale); color:var(--blue-600); display:flex; align-items:center; justify-content:center; margin:0 auto 0.9rem; font-size:1.3rem; }
        .sv-card h1 { font-size:1.05rem; text-align:center; margin-bottom:0.3rem; }
        .sv-sub { font-size:0.8rem; color:var(--color-text-muted); text-align:center; margin-bottom:1.25rem; }
        .sv-field { margin-bottom:0.8rem; }
        .sv-label { font-size:0.68rem; font-weight:700; text-transform:uppercase; letter-spacing:0.06em; color:var(--gray-400); margin-bottom:0.2rem; }
        .sv-value { display:flex; align-items:center; gap:0.5rem; }
        .sv-value .form-control { flex:1; width:auto; font-family:var(--font-family-mono); background:var(--gray-50); }
        .sv-copy { width:36px; min-height:2.375rem; padding:0; flex-shrink:0; }
        .sv-warn-spacing { margin:1rem 0 0; font-size:0.8rem; }
        .sv-gone { text-align:center; color:var(--color-text-muted); font-size:0.9rem; padding:1rem 0; }
        .sv-notes { white-space:pre-wrap; font-size:0.85rem; color:var(--gray-700); background:var(--gray-50); border:1px solid var(--color-border); border-radius:0.4rem; padding:0.6rem 0.8rem; }
    </style>
</head>
<body<?= ($design_style ?? 'standard') === 'material' ? ' class="design-material"' : '' ?>>
    <div class="sv-card">
        <div class="sv-icon">&#128273;</div>
        <?php if ($share === null): ?>
            <h1><?= $this->te('Freigabe nicht verfügbar') ?></h1>
            <div class="sv-gone">
                <?= $this->t('Dieser Link wurde bereits verwendet, ist abgelaufen oder ungültig.<br> Einmal-Freigaben können nur ein einziges Mal geöffnet werden.') ?>
            </div>
        <?php else: ?>
            <h1><?= htmlspecialchars((string)($share['title'] ?? 'Zugangsdaten')) ?></h1>
            <p class="sv-sub"><?= $this->te('Einmalige Passwort-Freigabe – dieser Link ist jetzt verbraucht.') ?></p>

            <?php if (!empty($share['username'])): ?>
            <div class="sv-field">
                <div class="sv-label"><?= $this->te('Benutzername') ?></div>
                <div class="sv-value">
                    <input type="text" class="form-control" readonly value="<?= htmlspecialchars((string)$share['username']) ?>" id="svUser">
                    <button type="button" class="btn btn-default sv-copy" data-act="svCopy" data-args='["svUser"]' title="<?= $this->te('Kopieren') ?>">&#128203;</button>
                </div>
            </div>
            <?php endif; ?>

            <div class="sv-field">
                <div class="sv-label"><?= $this->te('Passwort') ?></div>
                <div class="sv-value">
                    <input type="password" class="form-control" readonly value="<?= htmlspecialchars((string)($share['password'] ?? '')) ?>" id="svPass">
                    <button type="button" class="btn btn-default sv-copy" data-act="svToggle" title="<?= $this->te('Anzeigen') ?>">&#128065;</button>
                    <button type="button" class="btn btn-default sv-copy" data-act="svCopy" data-args='["svPass"]' title="<?= $this->te('Kopieren') ?>">&#128203;</button>
                </div>
            </div>

            <?php if (!empty($share['url'])): ?>
            <div class="sv-field">
                <div class="sv-label">URL</div>
                <div class="sv-value"><input type="text" class="form-control" readonly value="<?= htmlspecialchars((string)$share['url']) ?>" id="svUrl">
                    <button type="button" class="btn btn-default sv-copy" data-act="svCopy" data-args='["svUrl"]' title="<?= $this->te('Kopieren') ?>">&#128203;</button></div>
            </div>
            <?php endif; ?>

            <?php if (!empty($share['notes'])): ?>
            <div class="sv-field">
                <div class="sv-label"><?= $this->te('Notizen') ?></div>
                <div class="sv-notes"><?= htmlspecialchars((string)$share['notes']) ?></div>
            </div>
            <?php endif; ?>

            <div class="alert alert-danger sv-warn-spacing">
                <?= $this->t('<strong>Wichtig:</strong> Speichern Sie die Daten jetzt sicher ab – diese Seite kann nach dem Schließen nicht erneut geöffnet werden.') ?>
            </div>
        <?php endif; ?>
    </div>
    <script<?= $this->scriptNonce() ?>>
        function svCopy(id) {
            var el = document.getElementById(id);
            navigator.clipboard.writeText(el.value).catch(function () {
                el.type = 'text'; el.select(); document.execCommand('copy');
            });
        }
        function svToggle() {
            var el = document.getElementById('svPass');
            el.type = el.type === 'password' ? 'text' : 'password';
        }
    </script>
</body>
</html>