refactor: replace global WAHA notifications with granular user and group-specific templates and dispatch logic
This commit is contained in:
@@ -28,7 +28,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if(isset($_POST['create_password'])) {
|
||||
$stmt = $pdo->prepare("INSERT INTO passwords (title, username, password, url, notes, owner_id, folder_id, tags) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$_POST['title'], $_POST['username'], $_POST['password'], $_POST['url'], $_POST['notes'], $user_id, $_POST['folder_id'] ?: null, trim($_POST['tags'] ?? '')]);
|
||||
notify_waha('Created', 'Password Entry', $_POST['title']);
|
||||
notify_user($user_id, "You added a new password: " . $_POST['title'], ['action'=>'Created', 'module'=>'Password', 'item'=>$_POST['title']]);
|
||||
}
|
||||
|
||||
if(isset($_POST['update_password'])) {
|
||||
@@ -36,16 +36,29 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if($p && $p['owner_id'] == $user_id) {
|
||||
$stmt = $pdo->prepare("UPDATE passwords SET title=?, username=?, password=?, url=?, notes=?, folder_id=?, tags=? WHERE id=? AND owner_id=?");
|
||||
$stmt->execute([$_POST['title'], $_POST['username'], $_POST['password'], $_POST['url'], $_POST['notes'], $_POST['folder_id'] ?: null, trim($_POST['tags'] ?? ''), $_POST['password_id'], $user_id]);
|
||||
notify_waha('Updated', 'Password Entry', $_POST['title']);
|
||||
|
||||
$ctx = ['action'=>'Updated', 'module'=>'Password', 'item'=>$_POST['title']];
|
||||
notify_user($user_id, "Password '{$_POST['title']}' updated.", $ctx);
|
||||
// Notify shared users/groups
|
||||
$shares = query("SELECT share_type, share_id FROM password_shares WHERE password_id=?", [$_POST['password_id']])->fetchAll();
|
||||
foreach($shares as $sh) {
|
||||
if($sh['share_type'] === 'user') notify_user($sh['share_id'], "Shared password '{$_POST['title']}' updated.", $ctx);
|
||||
else notify_group($sh['share_id'], "Shared group password '{$_POST['title']}' updated.", $ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($_POST['delete_password'])) {
|
||||
$p = query("SELECT owner_id, title FROM passwords WHERE id=?", [$_POST['password_id']])->fetch();
|
||||
if($p && $p['owner_id'] == $user_id) {
|
||||
$ctx = ['action'=>'Deleted', 'module'=>'Password', 'item'=>$p['title']];
|
||||
// Notify shared recipients before deletion
|
||||
$shares = query("SELECT share_type, share_id FROM password_shares WHERE password_id=?", [$_POST['password_id']])->fetchAll();
|
||||
foreach($shares as $sh) {
|
||||
if($sh['share_type'] === 'user') notify_user($sh['share_id'], "Shared password '{$p['title']}' has been deleted.", $ctx);
|
||||
else notify_group($sh['share_id'], "Shared group password '{$p['title']}' has been deleted.", $ctx);
|
||||
}
|
||||
query("DELETE FROM passwords WHERE id=? AND owner_id=?", [$_POST['password_id'], $user_id]);
|
||||
notify_waha('Deleted', 'Password Entry', $p['title']);
|
||||
}
|
||||
notify_user($user_id, "Password '{$p['title']}' deleted.", $ctx);
|
||||
}
|
||||
|
||||
// Unshare a specific share record
|
||||
@@ -76,9 +89,9 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$stmt = $pdo->prepare("INSERT INTO password_shares (password_id, share_type, share_id) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$p_id, $parts[0], $parts[1]]);
|
||||
$msg = "A password '{$p['title']}' has been shared with you.";
|
||||
if($parts[0] === 'user') notify_user($parts[1], $msg);
|
||||
else notify_group($parts[1], $msg);
|
||||
notify_waha('Shared', 'Password Entry', $p['title']);
|
||||
$ctx = ['action'=>'Shared', 'module'=>'Password', 'item'=>$p['title'], 'user'=>$_SESSION['username']??'System'];
|
||||
if($parts[0] === 'user') notify_user($parts[1], $msg, $ctx);
|
||||
else notify_group($parts[1], $msg, $ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,7 +378,7 @@ $active_folder = $_GET['vault_folder'] ?? 'all';
|
||||
$favicon = $domain ? "https://www.google.com/s2/favicons?domain={$domain}&sz=32" : '';
|
||||
$pw_shares = [];
|
||||
if($p['is_mine']) {
|
||||
$pw_shares = query("SELECT ps.id, ps.share_type, ps.share_id, u.username, g.name as gname FROM password_shares ps LEFT JOIN users u ON (ps.share_type='user' AND ps.share_id=u.id) LEFT JOIN groups g ON (ps.share_type='group' AND ps.share_id=g.id) WHERE ps.password_id=?", [$p['id']])->fetchAll();
|
||||
$pw_shares = query("SELECT ps.id, ps.share_type, ps.share_id, u.username, u.profile_pic as upic, g.name as gname, g.profile_pic as gpic FROM password_shares ps LEFT JOIN users u ON (ps.share_type='user' AND ps.share_id=u.id) LEFT JOIN groups g ON (ps.share_type='group' AND ps.share_id=g.id) WHERE ps.password_id=?", [$p['id']])->fetchAll();
|
||||
}
|
||||
$shares_json = htmlspecialchars(json_encode($pw_shares), ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
@@ -589,17 +602,26 @@ function renderPasswordShares(jsonShares) {
|
||||
return;
|
||||
}
|
||||
shares.forEach(sh => {
|
||||
const label = sh.share_type === 'user' ? ('👤 ' + (sh.username || 'User')) : ('👥 ' + (sh.gname || 'Group'));
|
||||
const pic = sh.share_type === 'user' ? sh.upic : sh.gpic;
|
||||
const name = sh.share_type === 'user' ? (sh.username || 'User') : (sh.gname || 'Group');
|
||||
|
||||
const chip = document.createElement('div');
|
||||
chip.style.display = 'inline-flex';
|
||||
chip.style.alignItems = 'center';
|
||||
chip.style.gap = '0.35rem';
|
||||
chip.style.gap = '0.4rem';
|
||||
chip.style.fontSize = '0.72rem';
|
||||
chip.style.padding = '3px 7px';
|
||||
chip.style.padding = '2px 8px 2px 2px';
|
||||
chip.style.borderRadius = '999px';
|
||||
chip.style.background = 'rgba(var(--primary-rgb),0.12)';
|
||||
chip.style.background = 'rgba(var(--primary-rgb),0.1)';
|
||||
chip.style.color = 'var(--primary)';
|
||||
chip.innerHTML = `<span>${label}</span><button type="button" style="border:none;background:transparent;color:inherit;cursor:pointer;line-height:1;" title="Unshare" onclick="removePasswordShare(${Number(sh.id)})">×</button>`;
|
||||
chip.style.border = '1px solid rgba(var(--primary-rgb),0.2)';
|
||||
|
||||
let avatarHtml = `<div style="width:20px; height:20px; border-radius:50%; background:var(--primary); color:white; display:flex; align-items:center; justify-content:center; font-size:0.6rem; font-weight:700; overflow:hidden;">${name.charAt(0).toUpperCase()}</div>`;
|
||||
if(pic) {
|
||||
avatarHtml = `<img src="${pic}" style="width:20px; height:20px; border-radius:50%; object-fit:cover;">`;
|
||||
}
|
||||
|
||||
chip.innerHTML = `${avatarHtml}<span style="font-weight:600;">${name}</span><button type="button" style="border:none;background:transparent;color:inherit;cursor:pointer;line-height:1;margin-left:2px;font-size:0.9rem;" title="Unshare" onclick="removePasswordShare(${Number(sh.id)})">×</button>`;
|
||||
list.appendChild(chip);
|
||||
});
|
||||
sec.style.display = 'block';
|
||||
|
||||
Reference in New Issue
Block a user