mirror of
https://github.com/itflow-org/itflow
synced 2026-08-22 07:25:12 +00:00
Remove Legacy OTP code and fix guest view credential
This commit is contained in:
@@ -655,7 +655,6 @@ if (isset($_GET['asset_id'])) {
|
|||||||
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
||||||
}
|
}
|
||||||
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
||||||
$credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
|
|
||||||
if (empty($credential_otp_secret)) {
|
if (empty($credential_otp_secret)) {
|
||||||
$otp_display = "-";
|
$otp_display = "-";
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -379,7 +379,6 @@ $sql_asset_retired = mysqli_query(
|
|||||||
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' type='button' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
||||||
}
|
}
|
||||||
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
||||||
$credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
|
|
||||||
if (empty($credential_otp_secret)) {
|
if (empty($credential_otp_secret)) {
|
||||||
$otp_display = "";
|
$otp_display = "";
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -553,7 +553,6 @@ if (isset($_GET['contact_id'])) {
|
|||||||
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
$credential_username_display = "$credential_username<button class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
||||||
}
|
}
|
||||||
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
||||||
$credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
|
|
||||||
if (empty($credential_otp_secret)) {
|
if (empty($credential_otp_secret)) {
|
||||||
$otp_display = "-";
|
$otp_display = "-";
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -535,7 +535,6 @@ ob_start();
|
|||||||
$credential_username_display = "$credential_username <button type='button' class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
$credential_username_display = "$credential_username <button type='button' class='btn btn-sm clipboardjs' data-clipboard-text='$credential_username'><i class='far fa-copy text-secondary'></i></button>";
|
||||||
}
|
}
|
||||||
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
$credential_otp_secret = escapeHtml($row['credential_otp_secret']);
|
||||||
$credential_id_with_secret = '"' . $row['credential_id'] . '","' . $row['credential_otp_secret'] . '"';
|
|
||||||
if (empty($credential_otp_secret)) {
|
if (empty($credential_otp_secret)) {
|
||||||
$otp_display = "-";
|
$otp_display = "-";
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -102,3 +102,46 @@ if (isset($_GET['stripe_create_pi'])) {
|
|||||||
|
|
||||||
exit;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -188,20 +188,16 @@ if ($item_type == "Document") {
|
|||||||
$password_ciphertext = substr($row['item_encrypted_credential'], 16);
|
$password_ciphertext = substr($row['item_encrypted_credential'], 16);
|
||||||
$credential_password = escapeHtml(openssl_decrypt($password_ciphertext, 'aes-128-cbc', $encryption_key, 0, $password_iv));
|
$credential_password = escapeHtml(openssl_decrypt($password_ciphertext, 'aes-128-cbc', $encryption_key, 0, $password_iv));
|
||||||
|
|
||||||
$credential_otp = escapeHtml($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'];
|
||||||
$credential_otp_secret = escapeHtml($credential_row['credential_otp_secret']);
|
|
||||||
$credential_id_with_secret = '"' . $credential_row['credential_id'] . '","' . $credential_row['credential_otp_secret'] . '"';
|
|
||||||
if (empty($credential_otp_secret)) {
|
if (empty($credential_otp_secret)) {
|
||||||
$otp_display = "-";
|
$otp_display = "-";
|
||||||
} else {
|
} else {
|
||||||
$otp_display = "<span onmouseenter='showOTP($credential_id_with_secret)'><i class='far fa-clock'></i> <span id='otp_$credential_id'><i>Hover..</i></span></span>";
|
$otp_display = "<span id='otp'><i class='fas fa-spinner fa-spin'></i></span>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$credential_notes = escapeHtml($credential_row['credential_note']);
|
$credential_notes = escapeHtml($credential_row['credential_note']);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<h5><?php echo $credential_name; ?></h5>
|
<h5><?php echo $credential_name; ?></h5>
|
||||||
@@ -227,26 +223,35 @@ if ($item_type == "Document") {
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<?php if (!empty($credential_otp_secret)) { ?>
|
||||||
<script>
|
<script>
|
||||||
function showOTP(id, secret) {
|
function refreshOTP() {
|
||||||
//Send a GET request to ajax.php as guest_ajax.php?get_totp_token=true&totp_secret=SECRET
|
// Send a GET request to guest_ajax.php as guest_ajax.php?get_share_totp_token=true&id=ID&key=KEY
|
||||||
jQuery.get(
|
jQuery.get(
|
||||||
"/agent/ajax.php",
|
"guest_ajax.php",
|
||||||
{get_totp_token: 'true', totp_secret: secret},
|
{
|
||||||
|
get_share_totp_token: 'true',
|
||||||
|
id: <?php echo $item_id; ?>,
|
||||||
|
key: "<?php echo $item_key; ?>"
|
||||||
|
},
|
||||||
function(data) {
|
function(data) {
|
||||||
//If we get a response from post.php, parse it as JSON
|
const response = JSON.parse(data);
|
||||||
const token = JSON.parse(data);
|
|
||||||
|
|
||||||
document.getElementById("otp_" + id).innerText = token
|
|
||||||
|
|
||||||
|
if (response.token) {
|
||||||
|
document.getElementById("otp").innerText = response.token;
|
||||||
|
// Refresh exactly when this code rotates
|
||||||
|
setTimeout(refreshOTP, response.expires_in * 1000);
|
||||||
|
} else {
|
||||||
|
// Share expired or revoked - stop rotating
|
||||||
|
document.getElementById("otp").innerText = "-";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePassword() {
|
refreshOTP();
|
||||||
document.getElementById("password").value = "<?php echo randomString(); ?>"
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
Reference in New Issue
Block a user