diff --git a/app-code/account/index.php b/app-code/account/index.php index cfd67a2..be9b820 100644 --- a/app-code/account/index.php +++ b/app-code/account/index.php @@ -75,6 +75,9 @@ if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { + @@ -173,6 +176,11 @@ if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { +
+

These external domains have been approved to receive your login data. You can revoke access at any time.

+
+ +
@@ -734,6 +742,53 @@ function generate2FAQRCode(issuer, accountName, secret) { } }); } + + function loadConfirmedDomains() { + fetch('/api/account/manage_domains.php') + .then(r => r.json()) + .then(data => { + const list = document.getElementById('confirmedDomainsList'); + const noMsg = document.getElementById('noDomainsMessage'); + list.innerHTML = ''; + if (!data.domains || data.domains.length === 0) { + noMsg.style.display = 'block'; + return; + } + noMsg.style.display = 'none'; + data.domains.forEach(d => { + const item = document.createElement('div'); + item.className = 'list-group-item d-flex justify-content-between align-items-center'; + item.innerHTML = '' + d.domain + '
Approved: ' + d.confirmed_at + '
' + + ''; + list.appendChild(item); + }); + }); + } + + function removeDomain(id) { + fetch('/api/account/manage_domains.php', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-Token': window.csrfToken + }, + body: JSON.stringify({ id: id }) + }).then(r => r.json()).then(data => { + if (data.success) { + loadConfirmedDomains(); + showSuccessModal('Domain access revoked.'); + } else { + showErrorModal(data.message || 'Failed to revoke domain.'); + } + }); + } + + document.addEventListener('DOMContentLoaded', function() { + const domainsTab = document.getElementById('domains-tab'); + if (domainsTab) { + domainsTab.addEventListener('shown.bs.tab', loadConfirmedDomains); + } + }); diff --git a/app-code/api/account/manage_domains.php b/app-code/api/account/manage_domains.php new file mode 100644 index 0000000..5456e55 --- /dev/null +++ b/app-code/api/account/manage_domains.php @@ -0,0 +1,48 @@ + true, 'domains' => $domains]); + +} elseif ($method === 'POST') { + require_csrf_token(); + $input = json_decode(file_get_contents('php://input'), true); + $domain_id = (int)($input['id'] ?? 0); + + if ($domain_id <= 0) { + echo json_encode(['success' => false, 'message' => 'Invalid domain ID.']); + exit; + } + + $sql = "DELETE FROM confirmed_domains WHERE id = ? AND user_id = ?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $domain_id, $user_id); + mysqli_stmt_execute($stmt); + mysqli_stmt_close($stmt); + + echo json_encode(['success' => true, 'message' => 'Domain removed.']); + +} else { + echo json_encode(['success' => false, 'message' => 'Invalid request method.'], 405); +} +?> \ No newline at end of file diff --git a/app-code/api/login/confirm_external_redirect.php b/app-code/api/login/confirm_external_redirect.php index d8a0d82..eb62e0a 100644 --- a/app-code/api/login/confirm_external_redirect.php +++ b/app-code/api/login/confirm_external_redirect.php @@ -3,6 +3,27 @@ include "../utils/security.php"; secure_session_start(); header('Content-Type: application/json'); -$_SESSION["external_domain_confirmed"] = true; +if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + echo json_encode(['success' => false, 'message' => 'Invalid request method.']); + exit; +} + +$input = json_decode(file_get_contents('php://input'), true); +$domain = $input['domain'] ?? ''; + +if ($domain === '' || !isset($_SESSION['id'])) { + echo json_encode(['success' => false, 'message' => 'Missing domain or not logged in.']); + exit; +} + +include "../../config/config.php"; +$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); + +$user_id = $_SESSION['id']; +$sql = "INSERT IGNORE INTO confirmed_domains (user_id, domain) VALUES (?, ?)"; +$stmt = mysqli_prepare($conn, $sql); +mysqli_stmt_bind_param($stmt, 'is', $user_id, $domain); +mysqli_stmt_execute($stmt); +mysqli_stmt_close($stmt); echo json_encode(['success' => true]); \ No newline at end of file diff --git a/app-code/api/login/redirect.php b/app-code/api/login/redirect.php index d5aa451..992cf8c 100644 --- a/app-code/api/login/redirect.php +++ b/app-code/api/login/redirect.php @@ -57,12 +57,26 @@ else if ($_SESSION["needs_auth"]===false && $_SESSION["mfa_authenticated"]==1 && mysqli_stmt_close($stmt); if(!empty($send_to)){ $external_domain = is_external_domain($send_to); - if ($external_domain !== null && !isset($_SESSION["external_domain_confirmed"])){ - $data=[ - 'message' => 'external_redirect_warning', - 'domain' => $external_domain, - 'redirect' => append_auth_token_to_redirect($send_to, $auth_token) - ]; + if ($external_domain !== null){ + $sql="SELECT id FROM confirmed_domains WHERE user_id = ? AND domain = ?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'is', $user_id, $external_domain); + mysqli_stmt_execute($stmt); + mysqli_stmt_store_result($stmt); + $domain_confirmed = mysqli_stmt_num_rows($stmt) > 0; + mysqli_stmt_close($stmt); + if (!$domain_confirmed){ + $data=[ + 'message' => 'external_redirect_warning', + 'domain' => $external_domain, + 'redirect' => append_auth_token_to_redirect($send_to, $auth_token) + ]; + }else{ + $data=[ + 'message' => 'done', + 'redirect' => append_auth_token_to_redirect($send_to, $auth_token) + ]; + } }else{ $data=[ 'message' => 'done', diff --git a/app-code/api/login/set_username.php b/app-code/api/login/set_username.php index 0da5c52..ab03182 100644 --- a/app-code/api/login/set_username.php +++ b/app-code/api/login/set_username.php @@ -11,7 +11,6 @@ $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); check_rate_limit($conn, 'set_username', 30, 60); $_SESSION["needs_auth"]=true; $_SESSION["logged_in"]=false; -unset($_SESSION["external_domain_confirmed"]); $username = strtolower((string) ($_POST["username"] ?? "")); $_SESSION["username"]=preg_replace("/[^a-z0-9_]/","",$username); session_regenerate_id(true); diff --git a/app-code/install/create_db.php b/app-code/install/create_db.php index a859b31..23a6247 100644 --- a/app-code/install/create_db.php +++ b/app-code/install/create_db.php @@ -154,6 +154,26 @@ '; } + $sql="CREATE TABLE IF NOT EXISTS confirmed_domains ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT NOT NULL, + domain VARCHAR(255) NOT NULL, + confirmed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE KEY unique_user_domain (user_id, domain) + );"; + + + if ($conn->query($sql) === TRUE) { + echo '
'; + } else { + $success=0; + echo '
'; + } + if($success!==1){ diff --git a/app-code/login/index.php b/app-code/login/index.php index 9759b19..c0d4296 100644 --- a/app-code/login/index.php +++ b/app-code/login/index.php @@ -45,6 +45,7 @@