Add roadmap management feature with database schema and user management
- Implemented roadmap.php for displaying and managing roadmap items with filters for quarter and status. - Created schema.sql to define the database structure for users, invites, daily plans, tasks, brainstorm sessions, brainstorm cards, roadmap items, and integrations. - Developed users.php for admin panel to manage team members and invitations, including functionality to create and revoke invites.
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Authenticatie & Autorisatie Guard voor Fociz
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../config/database.php';
|
||||
require_once __DIR__ . '/totp.php';
|
||||
|
||||
function start_secure_session(): void {
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
// Veilige sessiecookie parameters
|
||||
$isSecure = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on');
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 7 * 24 * 60 * 60, // 7 dagen
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => $isSecure,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controleert of er al een beheerder bestaat in MariaDB
|
||||
*/
|
||||
function has_admin_user(): bool {
|
||||
$db = get_db_connection();
|
||||
$stmt = $db->query("SELECT COUNT(*) FROM users WHERE role = 'ADMIN'");
|
||||
return ((int)$stmt->fetchColumn()) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Haalt de huidige ingelogde gebruiker op uit de database
|
||||
*/
|
||||
function get_logged_in_user(): ?array {
|
||||
start_secure_session();
|
||||
|
||||
if (empty($_SESSION['user_id']) || empty($_SESSION['is_2fa_verified'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$db = get_db_connection();
|
||||
$stmt = $db->prepare("SELECT id, name, email, role, two_factor_enabled, created_at FROM users WHERE id = ?");
|
||||
$stmt->execute([$_SESSION['user_id']]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
return $user ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Beschermt pagina's: dwingt login + 2FA af
|
||||
*/
|
||||
function require_auth(): array {
|
||||
start_secure_session();
|
||||
|
||||
// 1. Controleer of eerste setup nodig is
|
||||
if (!has_admin_user()) {
|
||||
header('Location: /auth/setup.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2. Controleer of gebruiker ingelogd én 2FA geverifieerd is
|
||||
$user = get_logged_in_user();
|
||||
if (!$user) {
|
||||
header('Location: /auth/login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dwingt beheerder (ADMIN) rol af
|
||||
*/
|
||||
function require_admin(): array {
|
||||
$user = require_auth();
|
||||
if ($user['role'] !== 'ADMIN') {
|
||||
header('Location: /planner.php');
|
||||
exit;
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maakt een nieuwe uitnodiging aan voor een collega
|
||||
*/
|
||||
function create_invite(int $createdById, string $email, string $role = 'MEMBER'): string {
|
||||
$db = get_db_connection();
|
||||
$token = bin2hex(random_bytes(24));
|
||||
$expiresAt = date('Y-m-d H:i:s', strtotime('+7 days'));
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO invites (token, email, role, expires_at, created_by_id) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$token, strtolower(trim($email)), $role, $expiresAt, $createdById]);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valideert een invite token
|
||||
*/
|
||||
function validate_invite(string $token): ?array {
|
||||
$db = get_db_connection();
|
||||
$stmt = $db->prepare("
|
||||
SELECT i.*, u.name as inviter_name, u.email as inviter_email
|
||||
FROM invites i
|
||||
JOIN users u ON i.created_by_id = u.id
|
||||
WHERE i.token = ?
|
||||
");
|
||||
$stmt->execute([$token]);
|
||||
$invite = $stmt->fetch();
|
||||
|
||||
if (!$invite) return null;
|
||||
if ($invite['used_at'] !== null) return null;
|
||||
if (strtotime($invite['expires_at']) < time()) return null;
|
||||
|
||||
return $invite;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSRF token helpers
|
||||
*/
|
||||
function get_csrf_token(): string {
|
||||
start_secure_session();
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
return $_SESSION['csrf_token'];
|
||||
}
|
||||
|
||||
function verify_csrf_token(?string $token): bool {
|
||||
start_secure_session();
|
||||
return !empty($token) && !empty($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user