diff --git a/agent/asset.php b/agent/asset.php index 380a93c6..2c1eca88 100644 --- a/agent/asset.php +++ b/agent/asset.php @@ -655,7 +655,6 @@ if (isset($_GET['asset_id'])) { $credential_username_display = "$credential_username"; } $credential_otp_secret = escapeHtml($row['credential_otp_secret']); - $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"'; if (empty($credential_otp_secret)) { $otp_display = "-"; } else { diff --git a/agent/client_overview.php b/agent/client_overview.php index e8012d87..ac18de8b 100644 --- a/agent/client_overview.php +++ b/agent/client_overview.php @@ -379,7 +379,6 @@ $sql_asset_retired = mysqli_query( $credential_username_display = "$credential_username"; } $credential_otp_secret = escapeHtml($row['credential_otp_secret']); - $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"'; if (empty($credential_otp_secret)) { $otp_display = ""; } else { diff --git a/agent/contact.php b/agent/contact.php index 1996b246..111fb629 100644 --- a/agent/contact.php +++ b/agent/contact.php @@ -553,7 +553,6 @@ if (isset($_GET['contact_id'])) { $credential_username_display = "$credential_username"; } $credential_otp_secret = escapeHtml($row['credential_otp_secret']); - $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"'; if (empty($credential_otp_secret)) { $otp_display = "-"; } else { diff --git a/agent/modals/asset/asset.php b/agent/modals/asset/asset.php index 5c592ab9..8335b772 100644 --- a/agent/modals/asset/asset.php +++ b/agent/modals/asset/asset.php @@ -535,7 +535,6 @@ ob_start(); $credential_username_display = "$credential_username "; } $credential_otp_secret = escapeHtml($row['credential_otp_secret']); - $credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"'; if (empty($credential_otp_secret)) { $otp_display = "-"; } else { diff --git a/guest/guest_ajax.php b/guest/guest_ajax.php index 2f06b7c5..42adb7f2 100644 --- a/guest/guest_ajax.php +++ b/guest/guest_ajax.php @@ -102,3 +102,46 @@ if (isset($_GET['stripe_create_pi'])) { exit; } + +/* + * Returns the current TOTP code for a shared credential + * Authenticated via the share ID + key, same as guest_view_item.php + */ +if (isset($_GET['get_share_totp_token'])) { + + header('Content-Type: application/json'); + + $item_id = intval($_GET['id']); + $item_key = escapeSql($_GET['key']); + + // Deliberately no item_view_limit check here - the page view already consumed a view, + // and blocking token refreshes would break rotation for limit-1 shares. + // Active + expiry checks still apply, so revoking the share stops codes immediately. + $sql = mysqli_query($mysqli, "SELECT item_related_id, item_client_id FROM shared_items WHERE item_id = $item_id AND item_key = '$item_key' AND item_type = 'Credential' AND item_active = 1 AND item_expire_at > NOW() LIMIT 1"); + + if (!$sql || mysqli_num_rows($sql) !== 1) { + exit(json_encode(['error' => 'invalid'])); + } + + $row = mysqli_fetch_assoc($sql); + $credential_id = intval($row['item_related_id']); + $client_id = intval($row['item_client_id']); + + $credential_sql = mysqli_query($mysqli, "SELECT credential_otp_secret FROM credentials WHERE credential_id = $credential_id AND credential_client_id = $client_id LIMIT 1"); + + if (!$credential_sql || mysqli_num_rows($credential_sql) !== 1) { + exit(json_encode(['error' => 'invalid'])); + } + + $totp_secret = mysqli_fetch_assoc($credential_sql)['credential_otp_secret']; + + if (empty($totp_secret)) { + exit(json_encode(['error' => 'invalid'])); + } + + echo json_encode([ + 'token' => TokenAuth6238::getTokenCode(strtoupper($totp_secret)), + 'expires_in' => 30 - (time() % 30) + ]); + exit; +} diff --git a/guest/guest_view_item.php b/guest/guest_view_item.php index 5f57966b..6fb737b1 100644 --- a/guest/guest_view_item.php +++ b/guest/guest_view_item.php @@ -188,20 +188,16 @@ if ($item_type == "Document") { $password_ciphertext = substr($row['item_encrypted_credential'], 16); $credential_password = escapeHtml(openssl_decrypt($password_ciphertext, 'aes-128-cbc', $encryption_key, 0, $password_iv)); - $credential_otp = escapeHtml($credential_row['credential_otp_secret']); - - $credential_otp_secret = escapeHtml($credential_row['credential_otp_secret']); - $credential_id_with_secret = '"' . $credential_row['credential_id'] . '","' . $credential_row['credential_otp_secret'] . '"'; + // TOTP secret never leaves the server - the page polls guest_ajax.php for rotating codes + $credential_otp_secret = $credential_row['credential_otp_secret']; if (empty($credential_otp_secret)) { $otp_display = "-"; } else { - $otp_display = " Hover.."; + $otp_display = ""; } $credential_notes = escapeHtml($credential_row['credential_note']); - - ?>
@@ -227,26 +223,35 @@ if ($item_type == "Document") { + +