| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/seaside.pacim.de/web/ |
Upload File : |
<?php
/**
* apikeys-admin.php – Verwaltung der API-Schlüssel im Backend (Einstellungen → API).
* Session-/Admin-geschützt. Aktionen: list | create | delete | toggle.
*/
require_once( __DIR__ . '/includes/config.inc.php' );
@ini_set( 'display_errors', '0' );
error_reporting( 0 );
ob_start();
function ak_json( $a ) { while ( ob_get_level() > 0 ) ob_end_clean(); header( 'Content-Type: application/json; charset=utf-8' ); echo json_encode( $a ); exit(); }
function ak_fail( $m ) { ak_json( array( 'ok' => false, 'error' => $m ) ); }
if ( ! function_exists( 'is_admin' ) || ! is_admin() ) { http_response_code( 403 ); ak_json( array( 'ok' => false, 'error' => 'forbidden' ) ); }
$action = $_GET['action'] ?? ( $_POST['action'] ?? '' );
if ( $action === 'list' ) {
ak_json( array( 'ok' => true, 'keys' => apikeys::all(), 'scopes' => apikeys::scopes(), 'base_url' => SITE_URL . '/api.php' ) );
}
/* Globales Zugriffsprotokoll (alle API-Zugriffe, neueste zuerst). */
if ( $action === 'log' ) {
apilog::ensureTable();
$db = new MysqliDb( MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB );
$kind = (string) ( $_GET['kind'] ?? 'all' );
$q = trim( (string) ( $_GET['q'] ?? '' ) );
$key = (int) ( $_GET['key'] ?? 0 );
$limit = min( 500, max( 1, (int) ( $_GET['limit'] ?? 200 ) ) );
$where = array( '1=1' ); $params = array();
if ( $kind === 'read' || $kind === 'write' ) { $where[] = 'log_kind = ?'; $params[] = $kind; }
if ( $key > 0 ) { $where[] = 'log_key = ?'; $params[] = $key; }
if ( $q !== '' ) { $where[] = '(log_target LIKE ? OR log_key_name LIKE ? OR log_action LIKE ? OR log_resource LIKE ? OR log_ip LIKE ?)'; for ( $i = 0; $i < 5; $i++ ) $params[] = '%' . $q . '%'; }
$w = implode( ' AND ', $where );
$rows = $db->rawQuery( "SELECT log_id, log_datetime, log_key_name, log_broker, log_ip, log_method, log_resource, log_action, log_kind, log_booking, log_invoice, log_target, log_status, log_error, log_reverted, JSON_LENGTH(log_changes) AS change_count FROM pacim_api_log WHERE $w ORDER BY log_datetime DESC, log_id DESC LIMIT $limit", $params );
$tot = $db->rawQueryOne( "SELECT COUNT(*) c, SUM(log_kind='write') w, SUM(log_kind='read') r FROM pacim_api_log" );
ak_json( array( 'ok' => true, 'entries' => $rows ?: array(), 'totals' => array( 'all' => (int) ( $tot['c'] ?? 0 ), 'write' => (int) ( $tot['w'] ?? 0 ), 'read' => (int) ( $tot['r'] ?? 0 ) ), 'base_url' => SITE_URL ) );
}
if ( $action === 'create' ) {
$name = (string) ( $_POST['name'] ?? '' );
$scopes = isset( $_POST['scopes'] ) ? (array) $_POST['scopes'] : array();
$res = apikeys::create( $name, $scopes );
if ( empty( $res['ok'] ) ) ak_fail( $res['error'] ?? 'Fehler' );
// Klartext-Schlüssel wird hier EINMALIG zurückgegeben.
ak_json( array( 'ok' => true, 'id' => $res['id'], 'key' => $res['key'], 'prefix' => $res['prefix'] ) );
}
if ( $action === 'update' ) {
$id = (int) ( $_POST['id'] ?? 0 );
$name = (string) ( $_POST['name'] ?? '' );
$scopes = isset( $_POST['scopes'] ) ? (array) $_POST['scopes'] : array();
if ( $id <= 0 ) ak_fail( 'not_found' );
$res = apikeys::update( $id, $name, $scopes );
if ( empty( $res['ok'] ) ) ak_fail( $res['error'] ?? 'Fehler' );
ak_json( array( 'ok' => true, 'id' => $res['id'] ) );
}
if ( $action === 'delete' ) {
$id = (int) ( $_POST['id'] ?? 0 );
if ( $id <= 0 ) ak_fail( 'not_found' );
apikeys::delete( $id );
ak_json( array( 'ok' => true ) );
}
if ( $action === 'toggle' ) {
$id = (int) ( $_POST['id'] ?? 0 );
$active = ! empty( $_POST['active'] );
if ( $id <= 0 ) ak_fail( 'not_found' );
apikeys::setActive( $id, $active );
ak_json( array( 'ok' => true ) );
}
ak_fail( 'unknown_action' );