Skip to content
4 changes: 3 additions & 1 deletion assets/components/navbar.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
<li><a class="dropdown-item" href="<?= BASE_PATH ?>settings/dashboard/index.php">Dashboard</a></li>
<?php } ?>
<?php if (Permissions::check(['admin'])) { ?>
<li><a class="dropdown-item" href="<?= BASE_PATH ?>settings/system/config.php">Konfiguration</a></li>
<li><a class="dropdown-item" href="<?= BASE_PATH ?>settings/system/index.php">Updater</a></li>
<?php } ?>
</ul>
Expand Down Expand Up @@ -171,7 +172,8 @@
$iconClass = [
'antrag' => 'fa-file',
'protokoll' => 'fa-truck-medical',
'dokument' => 'fa-folder-open'
'dokument' => 'fa-folder-open',
'system' => 'fa-gears'
];
$icon = $iconClass[$notification['type']] ?? 'fa-bell';
?>
Expand Down
60 changes: 37 additions & 23 deletions assets/config/config.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use App\Auth\Permissions;
use App\Config\ConfigManager;

if (session_status() === PHP_SESSION_NONE) {
if (isset($_SESSION['userid']) && !isset($_SESSION['permissions'])) {
Expand All @@ -9,26 +10,39 @@
}
}

// BASIS DATEN
define('API_KEY', 'CHANGE_ME'); // Wird automatisch beim Setup erstellt, sonst selbst einen sicheren Key festlegen
define('SYSTEM_NAME', 'intraRP'); // Eigenname des Intranets
define('SYSTEM_COLOR', '#d10000'); // Hauptfarbe des Systems
define('SYSTEM_URL', 'CHANGE_ME'); // Domain des Systems
define('SYSTEM_LOGO', '/assets/img/defaultLogo.webp'); // Ort des Logos (entweder als relativer Pfad oder Link)
define('META_IMAGE_URL', ''); // Ort des Bildes, welches in der Link-Vorschau angezeigt werden soll (immer als Link angeben!)
// SERVER DATEN
define('SERVER_NAME', 'CHANGE_ME'); // Name des Servers
define('SERVER_CITY', 'Musterstadt'); // Name der Stadt in welcher der Server spielt
// RP DATEN
define('RP_ORGTYPE', 'Berufsfeuerwehr'); // Art/Name der Organisation
define('RP_STREET', 'Musterweg 0815'); // Straße der Organisation
define('RP_ZIP', '1337'); // PLZ der Organisation
// FUNKTIONEN
define('CHAR_ID', true); // Wird eine eindeutige Charakter-ID verwendet? (true = ja, false = nein)
define('ENOTF_PREREG', true); // Wird das Voranmeldungssystem des eNOTF verwendet? (true = ja, false = nein)
define('ENOTF_USE_PIN', true); // Wird die PIN-Funktion des eNOTF verwendet? (true = ja, false = nein)
define('ENOTF_PIN', '1234'); // PIN für den Zugang zum eNOTF - 4-6 Zahlen (nur relevant, wenn ENOTF_USE_PIN auf true gesetzt ist)
define('ENOTF_REQUIRE_USER_AUTH', false); // Wird eine Registrierung/Anmeldung im Hauptsystem für den Zugang zum eNOTF vorausgesetzt? (true = ja, false = nein)
define('REGISTRATION_MODE', 'open'); // Registrierungsmodus: open = für jeden möglich, code = nur mit Code, closed = keine Registrierung
define('LANG', 'de'); // Sprache des Systems (de = Deutsch, en = Englisch) // AKTUELL OHNE FUNKTION!
define('BASE_PATH', '/'); // Basis-Pfad des Systems (z.B. /intraRP/ für https://domain.de/intraRP/)
// Load configuration from database
require_once __DIR__ . '/database.php';

try {
$configManager = new ConfigManager($pdo);
$configManager->loadAndDefineConfig();
} catch (Exception $e) {
// Fallback to default values if database is not available or table doesn't exist
error_log("Could not load config from database: " . $e->getMessage());

// BASIS DATEN - Fallback defaults
if (!defined('API_KEY')) define('API_KEY', 'CHANGE_ME');
if (!defined('SYSTEM_NAME')) define('SYSTEM_NAME', 'intraRP');
if (!defined('SYSTEM_COLOR')) define('SYSTEM_COLOR', '#d10000');
if (!defined('SYSTEM_URL')) define('SYSTEM_URL', 'CHANGE_ME');
if (!defined('SYSTEM_LOGO')) define('SYSTEM_LOGO', '/assets/img/defaultLogo.webp');
if (!defined('META_IMAGE_URL')) define('META_IMAGE_URL', '');

// SERVER DATEN
if (!defined('SERVER_NAME')) define('SERVER_NAME', 'CHANGE_ME');
if (!defined('SERVER_CITY')) define('SERVER_CITY', 'Musterstadt');

// RP DATEN
if (!defined('RP_ORGTYPE')) define('RP_ORGTYPE', 'Berufsfeuerwehr');
if (!defined('RP_STREET')) define('RP_STREET', 'Musterweg 0815');
if (!defined('RP_ZIP')) define('RP_ZIP', '1337');

// FUNKTIONEN
if (!defined('CHAR_ID')) define('CHAR_ID', true);
if (!defined('ENOTF_PREREG')) define('ENOTF_PREREG', true);
if (!defined('ENOTF_USE_PIN')) define('ENOTF_USE_PIN', true);
if (!defined('ENOTF_PIN')) define('ENOTF_PIN', '1234');
if (!defined('ENOTF_REQUIRE_USER_AUTH')) define('ENOTF_REQUIRE_USER_AUTH', false);
if (!defined('REGISTRATION_MODE')) define('REGISTRATION_MODE', 'open');
if (!defined('BASE_PATH')) define('BASE_PATH', '/');
}
12 changes: 12 additions & 0 deletions assets/database/alter_intra_notifications_type_04112025.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
try {
$sql = <<<SQL
ALTER TABLE `intra_notifications`
MODIFY COLUMN `type` varchar(50) NOT NULL COMMENT 'notification type: antrag, protokoll, dokument, system';
SQL;

$pdo->exec($sql);
} catch (PDOException $e) {
$message = $e->getMessage();
echo $message;
}
27 changes: 27 additions & 0 deletions assets/database/create_intra_config_04112025.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
try {
$sql = <<<SQL
CREATE TABLE IF NOT EXISTS `intra_config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`config_key` varchar(100) NOT NULL UNIQUE COMMENT 'Configuration key (e.g., SYSTEM_NAME)',
`config_value` text DEFAULT NULL COMMENT 'Configuration value',
`config_type` varchar(50) NOT NULL DEFAULT 'string' COMMENT 'Type: string, boolean, integer, color, url',
`category` varchar(50) NOT NULL COMMENT 'Category: basis, server, rp, funktionen',
`description` varchar(255) DEFAULT NULL COMMENT 'Human-readable description',
`is_editable` tinyint(1) NOT NULL DEFAULT 1 COMMENT '0=read-only, 1=editable',
`display_order` int(11) NOT NULL DEFAULT 0 COMMENT 'Order for display in UI',
`updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`updated_by` int(11) DEFAULT NULL COMMENT 'User ID who last updated',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_config_key` (`config_key`),
KEY `idx_category` (`category`),
KEY `FK_intra_config_user` (`updated_by`),
CONSTRAINT `FK_intra_config_user` FOREIGN KEY (`updated_by`) REFERENCES `intra_users` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SQL;

$pdo->exec($sql);
} catch (PDOException $e) {
$message = $e->getMessage();
echo $message;
}
57 changes: 57 additions & 0 deletions assets/database/insert_intra_config_defaults_04112025.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
try {
// Insert default configuration values from config.php
$configs = [
// BASIS DATEN
['key' => 'API_KEY', 'value' => 'CHANGE_ME', 'type' => 'string', 'category' => 'basis', 'description' => 'API-Schlüssel für externe Schnittstellen', 'editable' => 0, 'order' => 1],
['key' => 'SYSTEM_NAME', 'value' => 'intraRP', 'type' => 'string', 'category' => 'basis', 'description' => 'Eigenname des Intranets', 'editable' => 1, 'order' => 2],
['key' => 'SYSTEM_COLOR', 'value' => '#d10000', 'type' => 'color', 'category' => 'basis', 'description' => 'Hauptfarbe des Systems', 'editable' => 1, 'order' => 3],
['key' => 'SYSTEM_URL', 'value' => 'CHANGE_ME', 'type' => 'url', 'category' => 'basis', 'description' => 'Domain des Systems', 'editable' => 1, 'order' => 4],
['key' => 'SYSTEM_LOGO', 'value' => '/assets/img/defaultLogo.webp', 'type' => 'url', 'category' => 'basis', 'description' => 'Ort des Logos (relativer Pfad oder Link)', 'editable' => 1, 'order' => 5],
['key' => 'META_IMAGE_URL', 'value' => '', 'type' => 'url', 'category' => 'basis', 'description' => 'Bild für Link-Vorschau (als Link angeben)', 'editable' => 1, 'order' => 6],

// SERVER DATEN
['key' => 'SERVER_NAME', 'value' => 'CHANGE_ME', 'type' => 'string', 'category' => 'server', 'description' => 'Name des Servers', 'editable' => 1, 'order' => 10],
['key' => 'SERVER_CITY', 'value' => 'Musterstadt', 'type' => 'string', 'category' => 'server', 'description' => 'Name der Stadt in welcher der Server spielt', 'editable' => 1, 'order' => 11],

// RP DATEN
['key' => 'RP_ORGTYPE', 'value' => 'Berufsfeuerwehr', 'type' => 'string', 'category' => 'rp', 'description' => 'Art/Name der Organisation', 'editable' => 1, 'order' => 20],
['key' => 'RP_STREET', 'value' => 'Musterweg 0815', 'type' => 'string', 'category' => 'rp', 'description' => 'Straße der Organisation', 'editable' => 1, 'order' => 21],
['key' => 'RP_ZIP', 'value' => '1337', 'type' => 'string', 'category' => 'rp', 'description' => 'PLZ der Organisation', 'editable' => 1, 'order' => 22],

// FUNKTIONEN
['key' => 'CHAR_ID', 'value' => 'true', 'type' => 'boolean', 'category' => 'funktionen', 'description' => 'Wird eine eindeutige Charakter-ID verwendet?', 'editable' => 1, 'order' => 30],
['key' => 'ENOTF_PREREG', 'value' => 'true', 'type' => 'boolean', 'category' => 'funktionen', 'description' => 'Wird das Voranmeldungssystem des eNOTF verwendet?', 'editable' => 1, 'order' => 31],
['key' => 'ENOTF_USE_PIN', 'value' => 'true', 'type' => 'boolean', 'category' => 'funktionen', 'description' => 'Wird die PIN-Funktion des eNOTF verwendet?', 'editable' => 1, 'order' => 32],
['key' => 'ENOTF_PIN', 'value' => '1234', 'type' => 'string', 'category' => 'funktionen', 'description' => 'PIN für den Zugang zum eNOTF (4-6 Zahlen)', 'editable' => 1, 'order' => 33],
['key' => 'ENOTF_REQUIRE_USER_AUTH', 'value' => 'false', 'type' => 'boolean', 'category' => 'funktionen', 'description' => 'Wird eine Registrierung/Anmeldung im Hauptsystem für den Zugang zum eNOTF vorausgesetzt?', 'editable' => 1, 'order' => 34],
['key' => 'REGISTRATION_MODE', 'value' => 'open', 'type' => 'string', 'category' => 'funktionen', 'description' => 'Registrierungsmodus: open = für jeden möglich, code = nur mit Code, closed = keine Registrierung', 'editable' => 1, 'order' => 35],
['key' => 'BASE_PATH', 'value' => '/', 'type' => 'string', 'category' => 'funktionen', 'description' => 'Basis-Pfad des Systems (z.B. /intraRP/)', 'editable' => 1, 'order' => 36],
];

$stmt = $pdo->prepare("
INSERT INTO intra_config (config_key, config_value, config_type, category, description, is_editable, display_order)
VALUES (:key, :value, :type, :category, :description, :editable, :order)
ON DUPLICATE KEY UPDATE
config_type = VALUES(config_type),
category = VALUES(category),
description = VALUES(description),
is_editable = VALUES(is_editable),
display_order = VALUES(display_order)
");

foreach ($configs as $config) {
$stmt->execute([
'key' => $config['key'],
'value' => $config['value'],
'type' => $config['type'],
'category' => $config['category'],
'description' => $config['description'],
'editable' => $config['editable'],
'order' => $config['order']
]);
}
} catch (PDOException $e) {
$message = $e->getMessage();
echo $message;
}
12 changes: 12 additions & 0 deletions assets/database/remove_lang_config_04112025.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
try {
// Remove LANG config entry as it's not currently in use
$sql = <<<SQL
DELETE FROM intra_config WHERE config_key = 'LANG';
SQL;

$pdo->exec($sql);
} catch (PDOException $e) {
$message = $e->getMessage();
echo $message;
}
40 changes: 13 additions & 27 deletions assets/functions/documents/create-custom.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use App\Auth\Permissions;
use App\Notifications\NotificationManager;
use App\Personnel\PersonalLogManager;
use App\Utils\AuditLogger;

ob_clean();

Expand Down Expand Up @@ -104,14 +105,18 @@
);

// Logge die Aktion im Audit-Log
logAction($pdo, 'document_created', [
'db_id' => $dbId,
'document_id' => $documentId,
'template_id' => $input['template_id'],
'template_name' => $template['name'],
'profileid' => $input['profileid'],
'created_by' => $_SESSION['discordtag'] ?? null
]);
try {
$auditLogger = new AuditLogger($pdo);
$auditLogger->log(
(int)($_SESSION['userid']),
'Dokument erstellt [' . $documentId . ']',
'Für Profil: ' . $input['profileid'],
'Dokumente',
0
);
} catch (Exception $e) {
error_log('Audit log failed: ' . $e->getMessage());
}

// Create notification for employee if they have a user account
try {
Expand Down Expand Up @@ -162,22 +167,3 @@
ob_end_flush();
exit;
}

function logAction($pdo, $action, $data)
{
try {
$stmt = $pdo->prepare("
INSERT INTO intra_audit_log
(user, action, details, timestamp)
VALUES (:user, :action, :details, CURRENT_TIMESTAMP)
");

$stmt->execute([
'user' => $_SESSION['userid'] ?? 0,
'action' => $action,
'details' => json_encode($data)
]);
} catch (Exception $e) {
error_log("Audit Log Fehler: " . $e->getMessage());
}
}
17 changes: 17 additions & 0 deletions auth/callback.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use League\OAuth2\Client\Provider\GenericProvider;
use App\Helpers\ProtocolDetection;
use App\Notifications\NotificationManager;

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
Expand Down Expand Up @@ -114,6 +115,22 @@
'role' => $adminRole['id'],
'full_admin' => 1
]);

$firstUserId = $pdo->lastInsertId();

// Send notification to first user about configuration
try {
$notificationManager = new NotificationManager($pdo);
$notificationManager->create(
$firstUserId,
'system',
'Willkommen bei intraRP!',
'Als erster Benutzer haben Sie Administratorrechte. Bitte besuchen Sie die System-Konfiguration, um wichtige Einstellungen wie den Systemnamen, Logo und weitere Optionen anzupassen.',
BASE_PATH . 'settings/system/config.php'
);
} catch (Exception $e) {
error_log("Failed to create first user notification: " . $e->getMessage());
}
}

$stmt = $pdo->prepare("SELECT * FROM intra_users WHERE discord_id = :discord_id");
Expand Down
3 changes: 2 additions & 1 deletion benachrichtigungen/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@
$iconClass = [
'antrag' => 'fa-file',
'protokoll' => 'fa-truck-medical',
'dokument' => 'fa-folder-open'
'dokument' => 'fa-folder-open',
'system' => 'fa-gears'
];
$icon = $iconClass[$notification['type']] ?? 'fa-bell';
?>
Expand Down
Loading