131 lines
5.2 KiB
PHP
131 lines
5.2 KiB
PHP
<?php
|
|
/**
|
|
* Microsoft 365 OAuth 2.0 Callback Handler
|
|
* Verwerkt de autorisatiecode, wisselt tokens uit en slaat de verbinding op.
|
|
*/
|
|
|
|
require_once __DIR__ . '/../includes/auth.php';
|
|
require_once __DIR__ . '/../includes/integrations/microsoft.php';
|
|
|
|
start_secure_session();
|
|
|
|
// 1. CSRF State validatie & Sessieherstel
|
|
$receivedState = $_GET['state'] ?? '';
|
|
$stateUserId = !empty($receivedState) ? verify_oauth_state($receivedState) : null;
|
|
|
|
// Als de sessie verloren is gegaan tijdens de externe cross-site redirect vanaf Microsoft,
|
|
// herstellen we de gebruiker veilig aan de hand van de cryptografisch ondertekende OAuth state!
|
|
if (empty($_SESSION['user_id']) && $stateUserId) {
|
|
try {
|
|
$db = get_db_connection();
|
|
$stmtUser = $db->prepare("SELECT id, name, email, role, two_factor_enabled, created_at FROM users WHERE id = ?");
|
|
$stmtUser->execute([$stateUserId]);
|
|
$recoveredUser = $stmtUser->fetch();
|
|
if ($recoveredUser) {
|
|
$_SESSION['user_id'] = $recoveredUser['id'];
|
|
$_SESSION['user_name'] = $recoveredUser['name'];
|
|
$_SESSION['user_email'] = $recoveredUser['email'];
|
|
$_SESSION['user_role'] = $recoveredUser['role'];
|
|
$_SESSION['is_2fa_verified'] = true;
|
|
issue_remember_token((int)$recoveredUser['id']);
|
|
}
|
|
} catch (Throwable $e) {
|
|
// Foutafhandeling
|
|
}
|
|
}
|
|
|
|
// 2. Controleer authenticatie
|
|
$user = get_logged_in_user();
|
|
if (!$user) {
|
|
header('Location: /auth/login.php?error=' . urlencode('Sessie verlopen tijdens Microsoft koppeling. Log opnieuw in en probeer het nogmaals.'));
|
|
exit;
|
|
}
|
|
|
|
$db = get_db_connection();
|
|
|
|
// 3. Foutafhandeling vanuit Microsoft (bijv. gebruiker weigerde machtiging)
|
|
if (!empty($_GET['error'])) {
|
|
$errorDescription = $_GET['error_description'] ?? $_GET['error'];
|
|
header('Location: /integrations.php?error=' . urlencode("Microsoft melding: {$errorDescription}"));
|
|
exit;
|
|
}
|
|
|
|
// 4. Valideer de state (via HMAC handtekening of fallback sessiestate)
|
|
$expectedState = $_SESSION['ms_oauth_state'] ?? '';
|
|
unset($_SESSION['ms_oauth_state'], $_SESSION['ms_oauth_user_id']);
|
|
|
|
if (!$stateUserId && (empty($receivedState) || empty($expectedState) || !hash_equals($expectedState, $receivedState))) {
|
|
header('Location: /integrations.php?error=' . urlencode('Ongeldige sessie of CSRF-controle mislukt. Probeer opnieuw in te loggen via Microsoft.'));
|
|
exit;
|
|
}
|
|
|
|
// 3. Autorisatiecode controleren
|
|
$code = $_GET['code'] ?? '';
|
|
if (empty($code)) {
|
|
header('Location: /integrations.php?error=' . urlencode('Geen autorisatiecode ontvangen van Microsoft.'));
|
|
exit;
|
|
}
|
|
|
|
// 4. Instellingen ophalen
|
|
$stmt = $db->prepare("SELECT settings FROM integrations WHERE user_id = ? AND provider = 'OUTLOOK'");
|
|
$stmt->execute([$user['id']]);
|
|
$row = $stmt->fetch();
|
|
$savedSettings = json_decode($row['settings'] ?? '{}', true) ?: [];
|
|
|
|
$clientId = !empty($savedSettings['client_id']) ? $savedSettings['client_id'] : fociz_env('MICROSOFT_CLIENT_ID', '');
|
|
$clientSecret = !empty($savedSettings['client_secret']) ? $savedSettings['client_secret'] : fociz_env('MICROSOFT_CLIENT_SECRET', '');
|
|
$tenantId = !empty($savedSettings['tenant_id']) ? $savedSettings['tenant_id'] : fociz_env('MICROSOFT_TENANT_ID', 'common');
|
|
|
|
if (empty($clientId) || empty($clientSecret)) {
|
|
header('Location: /integrations.php?error=' . urlencode('Client ID of Client Secret ontbreekt in Fociz. Vul deze eerst in bij de Outlook instellingen.'));
|
|
exit;
|
|
}
|
|
|
|
$redirectUri = rtrim(APP_URL, '/') . '/auth/callback_microsoft.php';
|
|
|
|
// 5. Code omwisselen voor access & refresh tokens
|
|
$tokenResult = microsoft_exchange_code($code, $clientId, $clientSecret, $redirectUri, $tenantId);
|
|
|
|
if (!$tokenResult['success']) {
|
|
header('Location: /integrations.php?error=' . urlencode('Token uitwisseling mislukt: ' . $tokenResult['error']));
|
|
exit;
|
|
}
|
|
|
|
$accessToken = $tokenResult['access_token'];
|
|
$refreshToken = $tokenResult['refresh_token'];
|
|
$expiresIn = $tokenResult['expires_in'];
|
|
$expiresAt = time() + $expiresIn;
|
|
|
|
// 6. Microsoft gebruikersprofiel ophalen
|
|
$profile = microsoft_get_user_profile($accessToken);
|
|
$accountEmail = $profile['mail'] ?? ($profile['userPrincipalName'] ?? $user['email']);
|
|
$accountName = $profile['displayName'] ?? 'Microsoft 365 Account';
|
|
|
|
// 7. Opslaan in MariaDB
|
|
$newSettings = array_merge($savedSettings, [
|
|
'client_id' => $clientId,
|
|
'client_secret' => $clientSecret,
|
|
'tenant_id' => $tenantId,
|
|
'expires_at' => $expiresAt,
|
|
'account_email' => $accountEmail,
|
|
'account_name' => $accountName,
|
|
]);
|
|
|
|
$saveStmt = $db->prepare("
|
|
INSERT INTO integrations (user_id, provider, is_enabled, is_demo_mode, access_token, refresh_token, settings, last_sync_at)
|
|
VALUES (?, 'OUTLOOK', 1, 0, ?, ?, ?, NOW())
|
|
ON DUPLICATE KEY UPDATE
|
|
is_enabled = 1,
|
|
is_demo_mode = 0,
|
|
access_token = VALUES(access_token),
|
|
refresh_token = VALUES(refresh_token),
|
|
settings = VALUES(settings),
|
|
last_sync_at = NOW()
|
|
");
|
|
$saveStmt->execute([$user['id'], $accessToken, $refreshToken, json_encode($newSettings)]);
|
|
|
|
// 8. Succesvol terugkeren naar de Integraties Hub
|
|
header('Location: /integrations.php?success=' . urlencode("Microsoft Outlook succesvol gekoppeld als {$accountEmail}!"));
|
|
exit;
|
|
|