- Markenrecht-Monitoring (Python) — täglich URLs capturen - Webhook-Receiver (Node.js Express) — capture.ready Events archivieren - WordPress-Plugin (PHP) — Captures aus dem WP-Backend
205 lines
8.3 KiB
PHP
205 lines
8.3 KiB
PHP
<?php
|
|
/**
|
|
* Plugin Name: hightrusted CAPTURE
|
|
* Plugin URI: https://capture.hightrusted.net
|
|
* Description: Forensische Web-Captures direkt aus dem WordPress-Backend — mit qualifiziertem Zeitstempel nach RFC 3161 / eIDAS Art. 41.
|
|
* Version: 0.1.0
|
|
* Requires at least: 6.0
|
|
* Requires PHP: 8.1
|
|
* Author: hightrusted GmbH
|
|
* Author URI: https://hightrusted.net
|
|
* License: MIT
|
|
* License URI: https://opensource.org/licenses/MIT
|
|
* Text Domain: hightrusted-capture
|
|
*
|
|
* Use-Case:
|
|
* Du betreibst ein Forum/Bewertungsportal/Kommentarsystem auf WordPress.
|
|
* Bei beleidigenden, rechtswidrigen oder einfach beweisrelevanten Inhalten
|
|
* willst du *vor* der Moderation eine forensische Capture haben.
|
|
*
|
|
* Das Plugin fügt einen Button "Capture erstellen" zur Beitrags-/Kommentar-
|
|
* Ansicht hinzu. Klick → Capture entsteht via API → URL + Verify-Link in den
|
|
* Beitrags-Metadaten gespeichert.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit; // Direktaufruf verbieten
|
|
}
|
|
|
|
require_once __DIR__.'/vendor/autoload.php';
|
|
|
|
use Hightrusted\Capture\Client;
|
|
use Hightrusted\Capture\HightrustedException;
|
|
|
|
class HightrustedCapturePlugin
|
|
{
|
|
private const OPTION_API_KEY = 'hightrusted_capture_api_key';
|
|
|
|
public static function init(): void
|
|
{
|
|
add_action('admin_menu', [self::class, 'addAdminMenu']);
|
|
add_action('admin_init', [self::class, 'registerSettings']);
|
|
add_action('add_meta_boxes', [self::class, 'addMetaBox']);
|
|
add_action('save_post', [self::class, 'handleManualCapture'], 10, 2);
|
|
}
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// Settings-Page
|
|
// ────────────────────────────────────────────────────────────
|
|
public static function addAdminMenu(): void
|
|
{
|
|
add_options_page(
|
|
'hightrusted CAPTURE',
|
|
'hightrusted CAPTURE',
|
|
'manage_options',
|
|
'hightrusted-capture',
|
|
[self::class, 'renderSettingsPage'],
|
|
);
|
|
}
|
|
|
|
public static function registerSettings(): void
|
|
{
|
|
register_setting('hightrusted_capture', self::OPTION_API_KEY);
|
|
}
|
|
|
|
public static function renderSettingsPage(): void
|
|
{
|
|
?>
|
|
<div class="wrap">
|
|
<h1>hightrusted CAPTURE</h1>
|
|
<form method="post" action="options.php">
|
|
<?php settings_fields('hightrusted_capture'); ?>
|
|
<table class="form-table">
|
|
<tr>
|
|
<th><label for="api_key">API-Key</label></th>
|
|
<td>
|
|
<input type="password" name="<?= esc_attr(self::OPTION_API_KEY) ?>"
|
|
id="api_key" class="regular-text"
|
|
value="<?= esc_attr(get_option(self::OPTION_API_KEY, '')) ?>" />
|
|
<p class="description">
|
|
API-Key holen unter
|
|
<a href="https://capture.hightrusted.net/dashboard/api-keys" target="_blank">
|
|
capture.hightrusted.net
|
|
</a>
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<?php submit_button(); ?>
|
|
</form>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// Meta-Box im Beitrags-Editor
|
|
// ────────────────────────────────────────────────────────────
|
|
public static function addMetaBox(): void
|
|
{
|
|
add_meta_box(
|
|
'hightrusted_capture_box',
|
|
'hightrusted CAPTURE',
|
|
[self::class, 'renderMetaBox'],
|
|
['post', 'page'],
|
|
'side',
|
|
'high',
|
|
);
|
|
}
|
|
|
|
public static function renderMetaBox(\WP_Post $post): void
|
|
{
|
|
wp_nonce_field('hightrusted_capture', 'hightrusted_capture_nonce');
|
|
|
|
$captureId = get_post_meta($post->ID, '_hightrusted_capture_id', true);
|
|
$verifyUrl = get_post_meta($post->ID, '_hightrusted_verify_url', true);
|
|
$issuedAt = get_post_meta($post->ID, '_hightrusted_issued_at', true);
|
|
|
|
if ($captureId) {
|
|
?>
|
|
<p><strong>✓ Capture vorhanden</strong></p>
|
|
<p><code><?= esc_html($captureId) ?></code></p>
|
|
<p><a href="<?= esc_url($verifyUrl) ?>" target="_blank">Verifikations-Link</a></p>
|
|
<p><em>Zeitstempel: <?= esc_html($issuedAt) ?></em></p>
|
|
<p>
|
|
<label>
|
|
<input type="checkbox" name="hightrusted_recapture" value="1">
|
|
Erneut capturen (überschreibt obige)
|
|
</label>
|
|
</p>
|
|
<?php
|
|
} else {
|
|
?>
|
|
<p>Noch keine Capture für diesen Beitrag.</p>
|
|
<p>
|
|
<label>
|
|
<input type="checkbox" name="hightrusted_capture_now" value="1">
|
|
Jetzt forensische Capture erstellen
|
|
</label>
|
|
</p>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
// ────────────────────────────────────────────────────────────
|
|
// Speichern: Capture erstellen wenn angefordert
|
|
// ────────────────────────────────────────────────────────────
|
|
public static function handleManualCapture(int $postId, \WP_Post $post): void
|
|
{
|
|
if (!isset($_POST['hightrusted_capture_nonce'])
|
|
|| !wp_verify_nonce($_POST['hightrusted_capture_nonce'], 'hightrusted_capture')) {
|
|
return;
|
|
}
|
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
|
|
if (!current_user_can('edit_post', $postId)) return;
|
|
|
|
$shouldCapture = !empty($_POST['hightrusted_capture_now'])
|
|
|| !empty($_POST['hightrusted_recapture']);
|
|
if (!$shouldCapture) return;
|
|
|
|
$apiKey = get_option(self::OPTION_API_KEY);
|
|
if (!$apiKey) {
|
|
self::adminNotice('error', 'hightrusted CAPTURE: API-Key fehlt. Siehe Einstellungen.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$client = new Client(['api_key' => $apiKey]);
|
|
$capture = $client->capture([
|
|
'url' => get_permalink($postId),
|
|
'reference' => "wp-post:{$postId}",
|
|
'viewport' => ['width' => 1920, 'height' => 1080],
|
|
]);
|
|
|
|
update_post_meta($postId, '_hightrusted_capture_id', $capture['id']);
|
|
update_post_meta($postId, '_hightrusted_verify_url', $capture['verify_url']);
|
|
update_post_meta($postId, '_hightrusted_issued_at', $capture['timestamp']['issued_at']);
|
|
|
|
self::adminNotice('success', sprintf(
|
|
'hightrusted CAPTURE erstellt: <a href="%s" target="_blank">Verifikations-Link</a>',
|
|
esc_url($capture['verify_url']),
|
|
));
|
|
} catch (HightrustedException $e) {
|
|
self::adminNotice('error', "hightrusted CAPTURE: {$e->getMessage()} (Code: {$e->errorCode})");
|
|
}
|
|
}
|
|
|
|
private static function adminNotice(string $type, string $message): void
|
|
{
|
|
$key = 'hightrusted_capture_notice';
|
|
set_transient($key, ['type' => $type, 'message' => $message], 30);
|
|
add_action('admin_notices', function () use ($key) {
|
|
$notice = get_transient($key);
|
|
if (!$notice) return;
|
|
delete_transient($key);
|
|
printf(
|
|
'<div class="notice notice-%s is-dismissible"><p>%s</p></div>',
|
|
esc_attr($notice['type']),
|
|
wp_kses_post($notice['message']),
|
|
);
|
|
});
|
|
}
|
|
}
|
|
|
|
HightrustedCapturePlugin::init();
|