Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions website/css/passwords.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ input::-webkit-inner-spin-button{

input[type=number]{
-moz-appearance: textfield;
}

input[type=checkbox]{
display: none;
}

#delete-checked-container {
display:none;
}
9 changes: 9 additions & 0 deletions website/css/themes/blue.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ input[type="checkbox"] {
border-color: #111827 !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #2b416e;
}

tr.triggerSelectPassword.timer {
background-color:#2b416e;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ input[type="checkbox"] {
border-color: #000000 !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #1e252e;
}

tr.triggerSelectPassword.timer {
background-color:#1e252e;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/dracula.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ input[type="checkbox"] {
border-color: #21222c !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #4d5066;
}

tr.triggerSelectPassword.timer {
background-color:#4d5066;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/gray.css
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,15 @@ input[type="checkbox"] {
border-color: #D1D1DB !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #d0dae1;
}

tr.triggerSelectPassword.timer {
background-color:#d0dae1;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,15 @@ input[type="checkbox"] {
border-color: #e5e7eb !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #f2f2f2;
}

tr.triggerSelectPassword.timer {
background-color:#f2f2f2;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/monokai.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ input[type="checkbox"] {
border-color: #000000 !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #36372f;
}

tr.triggerSelectPassword.timer {
background-color:#36372f;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/nord.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ input[type="checkbox"] {
border-color: #111827 !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #404859;
}

tr.triggerSelectPassword.timer {
background-color:#404859;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/solarizedDark.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ input[type="checkbox"] {
border-color: #000000 !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #003d4d;
}

tr.triggerSelectPassword.timer {
background-color:#003d4d;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
9 changes: 9 additions & 0 deletions website/css/themes/tokyoNight.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ input[type="checkbox"] {
border-color: #000000 !important;
}

tr.triggerSelectPassword[data-sel="t"] {
background-color: #1f202e;
}

tr.triggerSelectPassword.timer {
background-color:#1f202e;
transition: background-color 0.5s ease;
}

/*
Import and Export buttons
*/
Expand Down
32 changes: 32 additions & 0 deletions website/js/PasskyAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,38 @@
});
}

static deleteCheckedPasswords(server, username, token, passwordIDS){
return new Promise((resolve, reject) => {
if(!Validate.url(server)) return reject(1001);
if(!Validate.username(username)) return reject(1005);
if(!Validate.token(token)) return reject(1003);
if(!Validate.json(passwordIDS)) return reject(1012);

let data = new FormData();
data.append("password_id", passwordIDS);

let headers = new Headers();
headers.append('Authorization', 'Basic ' + btoa(username + ":" + token));

fetch(server + "?action=deletePassword", {
method: "POST",
headers: headers,
body: data
}).then((result) => {
if (result.status != 200 && result.status != 429) return reject(1000);
return result.text();
}).then((response) => {
try{
return resolve(JSON.parse(response));
}catch(error){
return reject(1000);
}
}).catch(() => {
return reject(1000);
});
});
}

static deletePasswords(server, username, token){
return new Promise((resolve, reject) => {
if(!Validate.url(server)) return reject(1001);
Expand Down
4 changes: 2 additions & 2 deletions website/js/default-functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ function refreshPasswords(){
}else{
writeData('passwords', '{}');
}

location.assign('passwords.html');
let page = (parms.get("page") != null && IsNumeric(parms.get("page")) && parseFloat(parms.get("page")) >= 1) ? parseFloat(parms.get("page")) : 1;
location.assign('passwords.html?page='+page);
}).catch();

}
Expand Down
92 changes: 91 additions & 1 deletion website/js/passwords.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
loadData().then(() => {
startAuthenticator();

var selectMode = false;

document.getElementById("passwords-link").innerText = lang["passwords"];
document.getElementById("import-export-link").innerText = lang["import_export"];
document.getElementById("settings-link").innerText = lang["settings"];
Expand Down Expand Up @@ -87,7 +89,7 @@ loadData().then(() => {
const website = XChaCha20.decrypt(passwords[i].website, decryptPassword(readData('password')));
const username = XChaCha20.decrypt(passwords[i].username, decryptPassword(readData('password')));

html_passwords += "<tr class='passwordsBorderColor'><td class='px-8 py-4 max-w-xs whitespace-nowrap overflow-hidden'><div class='flex items-center'><div class='flex-shrink-0 h-10 w-10'>";
html_passwords += "<tr class='passwordsBorderColor triggerSelectPassword' id='password-container-" + id + "' data-sel=''><td class='px-8 py-4 max-w-xs whitespace-nowrap overflow-hidden'><div class='flex items-center'><div class='flex-shrink-0 h-10 w-10'>";
//Icon
if(websiteIcons == "true"){
html_passwords += "<img id='icon-" + id + "' class='h-10 w-10 rounded-full cursor-pointer' loading='lazy' src='https://www.google.com/s2/favicons?domain=" + website + "' alt=''>";
Expand All @@ -114,6 +116,8 @@ loadData().then(() => {
html_passwords += "<span id='delete-password-" + id + "' role='button'>";
html_passwords += "<svg class='m-auto' xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='1.5' stroke='#2c3e50' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='none' d='M0 0h24v24H0z' fill='none'/><path stroke='none' d='M0 0h24v24H0z' fill='none'/><path d='M19 19h-11l-4 -4a1 1 0 0 1 0 -1.41l10 -10a1 1 0 0 1 1.41 0l5 5a1 1 0 0 1 0 1.41l-9 9' /><line x1='18' y1='12.3' x2='11.7' y2='6' /></svg></span></td></tr>";
}
html_passwords += "<tr class='passwordsBorderColor' id='delete-checked-container'><td class='px-4 py-4 w-16 whitespace-nowrap' colspan='6'>";
html_passwords += "<button id='delete-checked' type='button' class='primaryButton relative inline-flex items-center px-2 py-2 border border-transparent shadow-sm text-sm font-medium rounded focus:outline-none float-right'>" + lang["delete_passwords"] + "</button></td></tr>";

document.getElementById("table-data").innerHTML = html_passwords;

Expand Down Expand Up @@ -156,9 +160,42 @@ loadData().then(() => {
show('dialog');
});
}
let passwordContainers = document.querySelectorAll("tr.triggerSelectPassword");
if (passwordContainers.length) {
for (i = 0; i < passwordContainers.length; i++) {
passwordContainers[i].addEventListener("mousedown", (event) => {
if (!selectMode) {
event.currentTarget.classList.add("timer");
timerSelect = setTimeout(() => {
selectMode = true;
timerSelect = null;
}, 500);
}
});
passwordContainers[i].addEventListener("mouseup", (event) => {
event.currentTarget.classList.remove("timer");
if (timerSelect) {
clearTimeout(timerSelect);
timerSelect = null;
} else {
event.currentTarget.dataset.sel = (event.currentTarget.dataset.sel == "")?"t":"";
if (document.querySelectorAll('tr.triggerSelectPassword[data-sel="t"]').length == 0) {
selectMode = false;
document.getElementById("delete-checked-container").style.display = "none"
} else
document.getElementById("delete-checked-container").style.display = "table-row"
}
});
}
}
}
let end = new Date().getTime();
document.getElementById("stats-loading-time").innerText = (end - start) + " ms";

document.getElementById("delete-checked").addEventListener("click",() => {
changeDialog(9,JSON.stringify(Array.from(document.querySelectorAll('tr.triggerSelectPassword[data-sel="t"]'),e => e.id.substring(e.id.lastIndexOf("-")+1))));
show('dialog');
});
});

document.getElementById("search").addEventListener("keypress", (event) => {
Expand Down Expand Up @@ -402,6 +439,20 @@ function changeDialog(style, text) {

hideDialogButtons();
break;
case 9:
//Delete password dialog
document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10";
document.getElementById('dialog-icon').innerHTML = "<svg class='h-6 w-6 text-red-600' xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor' aria-hidden='true'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z' /></svg>";

document.getElementById('dialog-title').innerText = lang["delete_passwords"];
document.getElementById('dialog-text').innerText = lang["delete_passwords_confirmation"];

document.getElementById('dialog-button-cancel').style.display = 'initial';

document.getElementById('dialog-button').className = "dangerButton inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:w-auto sm:text-sm";
document.getElementById('dialog-button').innerText = lang["delete"];
document.getElementById('dialog-button').onclick = () => deleteCheckedPasswords(text);
break;
default:
//Add password dialog
document.getElementById('dialog-icon').className = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10";
Expand Down Expand Up @@ -601,3 +652,42 @@ function deletePassword(password_id) {
}
});
}

function deleteCheckedPasswords(password_ids) {

changeDialog(8, "deleting_password");

Passky.deleteCheckedPasswords(readData('url'), readData('username'), readData('token'), password_ids).then(response => {

showDialogButtons();

if (typeof response['error'] === 'undefined') {
changeDialog(2, lang["server_unreachable"]);
return;
}

if (response['error'] != 0) {
changeDialog(2, lang[response['error']]);
return;
}

changeDialog(3, 2);

}).catch(err => {
showDialogButtons();
switch(err){
case 1001:
changeDialog(2, lang["url_invalid"]);
break;
case 1003:
changeDialog(2, lang["25"]);
break;
case 1005:
changeDialog(2, lang["12"]);
break;
default:
changeDialog(2, lang["server_unreachable"]);
break;
}
});
}