var globalDb = []; var globalGroups = [] var globalCurrentGroup = "" function Error(message) { alert(message); } function Copy(id) { var elem = document.getElementById(id); elem.select(); document.execCommand("copy"); } function AESEncrypt(source, phrase) { var encryptedAES = CryptoJS.AES.encrypt(source, phrase); return encryptedAES.toString(); } function AESDecrypt(source, phrase) { var decryptedBytes = CryptoJS.AES.decrypt(source, phrase); return decryptedBytes.toString(CryptoJS.enc.Latin1); } function Decrypt(val) { var phrase = document.getElementById("PassPhrase").value; return AESDecrypt(val, phrase); } function Encrypt(val) { var phrase = document.getElementById("PassPhrase").value; return AESEncrypt(val, phrase); } function WebRequest(url, func, args) { var f; for(f = 0; f < args.length; f += 2) { if (f == 0) { url += "?"; } else { url += "&"; } url += args[f] + "="; url += encodeURIComponent(args[f+1]); } var req = new XMLHttpRequest(); req.addEventListener("load", func); req.open("GET", url); req.send(); } function ArrayContains(haystack, needle) { for(var f = 0; f < haystack.length; f++) { if (haystack[f] === needle) { return true; } } return false; } function IsEmpty(id) { var elem = document.getElementById(id); return elem.value == ""; } function LoadGroups(keep_selection) { globalGroups = []; for(var f = 0; f < globalDb.length; f++) { var group = globalDb[f].group; if (!ArrayContains(globalGroups, group)) { globalGroups.push(group); } } if (!keep_selection) { globalCurrentGroup = ""; } if (!ArrayContains(globalGroups, globalCurrentGroup)) { if (globalGroups.length > 0) { globalCurrentGroup = globalGroups[0]; } else { globalCurrentGroup = ""; } } var elem = document.getElementById("Group"); while(elem.length > 0) { elem.remove(0); } for(var f = 0; f < globalGroups.length; f++) { var option = document.createElement("option"); option.text = globalGroups[f]; option.value = globalGroups[f]; elem.add(option); } elem.value = globalCurrentGroup; } function AddTableInputCell(id, text, name, maxlen, classname, type, node) { var td = document.createElement("td"); var input = document.createElement("input"); input.value = text; input.id = name + id; input.type = type; input.maxLength = maxlen; td.className = classname; td.appendChild(input); node.appendChild(td); } function AddSmallLink(node, text, func, id) { var anchor = document.createElement("a"); anchor.href = "#"; anchor.onclick = func; anchor.text = text; anchor.className = "smalltext"; anchor.dataset.pmId = id; node.appendChild(anchor); } function AddSmallLinkPrevNext(node, text, func, id, prev, next) { var anchor = document.createElement("a"); anchor.href = "#"; anchor.onclick = func; anchor.text = text; anchor.className = "smalltext"; anchor.dataset.pmId = id; anchor.dataset.pmPrevId = prev; anchor.dataset.pmNextId = next; node.appendChild(anchor); } function AddSmallLinkUpDown(node, text, down_func, up_func, id) { var anchor = document.createElement("a"); anchor.href = "#"; anchor.onmousedown = down_func; anchor.onmouseup = up_func; anchor.text = text; anchor.className = "smalltext"; anchor.dataset.pmId = id; node.appendChild(anchor); } function AddText(node, text) { var t = document.createTextNode(text); node.appendChild(t); } function AddElement(node, elementname) { var elem = document.createElement(elementname); node.appendChild(elem); } function AddRow(table, id, prev_id, next_id, desc, username, password, rowcount) { var tr = document.createElement("tr"); if ((rowcount % 2) == 1) { tr.className = "style1"; } else { tr.className = "style2"; } AddTableInputCell(id, desc, "Description", 1024, "description", "text", tr); AddTableInputCell(id, username, "Username", 256, "username", "text", tr); AddTableInputCell(id, password, "Password", 256, "password", "password", tr); var td = document.createElement("td"); td.className = "commands"; if (id == -1) { AddSmallLink(td, "Add", DoAdd, id); } else { AddSmallLink(td, "Edit", DoEdit, id); AddText(td, "\u00a0"); AddText(td, "\u00a0"); AddSmallLink(td, "Delete", DoDelete, id); AddText(td, "\u00a0"); AddText(td, "\u00a0"); AddSmallLinkUpDown(td, "Show", DoShow, DoHide, id); if (next_id != -1 || prev_id != -1) { if (prev_id != -1) { AddText(td, "\u00a0"); AddText(td, "\u00a0"); AddSmallLinkPrevNext(td, "Up", DoUp, id, prev_id, next_id); } if (next_id != -1) { AddText(td, "\u00a0"); AddText(td, "\u00a0"); AddSmallLinkPrevNext(td, "Down", DoDown, id, prev_id, next_id); } } AddElement(td, "br"); AddSmallLink(td, "Copy Username", DoCopyUsername, id); AddText(td, "\u00a0"); AddText(td, "\u00a0"); AddSmallLink(td, "Copy Password", DoCopyPassword, id); } tr.appendChild(td); table.appendChild(tr); } function GetGroupRows() { var result = []; for(var f = 0; f < globalDb.length; f++) { if (globalDb[f].group == globalCurrentGroup) { result.push(globalDb[f]); } } return result; } function LoadTable() { var table = document.getElementById("DataTable"); table.innerHTML = ""; var rowcount = 0; var rows = GetGroupRows(); for(var f = 0; f < rows.length; f++) { var prevId = -1; var nextId = -1; if (f > 0) { prevId = rows[f-1].id; } if (f < rows.length - 1) { nextId = rows[f+1].id; } AddRow(table, rows[f].id, prevId, nextId, rows[f].description, rows[f].username, Decrypt(rows[f].password), rowcount++); } AddRow(table, -1, -1, -1, "", "", "", rowcount++); } function RefreshDataAsync() { globalDb = JSON.parse(this.responseText); LoadGroups(true); LoadTable(); } function RefreshData() { WebRequest("get.php", RefreshDataAsync, []); } function LoadInitialData() { LoadGroups(false); LoadTable(); } function DoLoadAsync() { globalDb = JSON.parse(this.responseText); LoadInitialData(); } function DoLoad() { if (IsEmpty("PassPhrase")) { Error("Passphrase empty"); return; } WebRequest("get.php", DoLoadAsync, []); } function DoSelectGroup() { var elem = document.getElementById("Group"); globalCurrentGroup = elem.value; document.getElementById("NewGroup").value = ""; LoadTable(); } function DoAddAsync() { var response = JSON.parse(this.responseText); if (response.error) { Error(response.error); } else { RefreshData(); } } function DoAdd() { if (IsEmpty("Group") && IsEmpty("NewGroup")) { Error("No groups defined -- please enter a group name"); return; } var id = this.dataset.pmId; var description = document.getElementById("Description" + id).value; var username = document.getElementById("Username" + id).value; var password = document.getElementById("Password" + id).value; var group; if (description == "" || username == "" | password == "") { Error("Please enter the description, username and password"); return; } if (!IsEmpty("NewGroup")) { group = document.getElementById("NewGroup").value; document.getElementById("NewGroup").value = ""; } else { group = document.getElementById("Group").value; } WebRequest("add.php", DoAddAsync, [ "description", description, "group", group, "username", username, "password", Encrypt(password) ] ); } function DoEditAsync() { var response = JSON.parse(this.responseText); if (response.error) { Error(response.error); } else { RefreshData(); } } function DoEdit() { var id = this.dataset.pmId; var description = document.getElementById("Description" + id).value; var username = document.getElementById("Username" + id).value; var password = document.getElementById("Password" + id).value; var group; if (description == "" || username == "" | password == "") { Error("Please enter the description, username and password"); return; } if (!IsEmpty("NewGroup")) { group = document.getElementById("NewGroup").value; document.getElementById("NewGroup").value = ""; } else { group = document.getElementById("Group").value; } WebRequest("edit.php", DoEditAsync, [ "id", id, "description", description, "group", group, "username", username, "password", Encrypt(password) ] ); } function DoDeleteAsync() { var response = JSON.parse(this.responseText); if (response.error) { Error(response.error); } else { RefreshData(); } } function DoDelete() { var id = this.dataset.pmId; WebRequest("delete.php", DoDeleteAsync, [ "id", id ] ); } function DoCopyUsername() { var id = "Username" + this.dataset.pmId; Copy(id); } function DoCopyPassword() { var id = "Password" + this.dataset.pmId; document.getElementById(id).type = "text"; Copy(id); document.getElementById(id).type = "password"; } function DoShow() { var elem = document.getElementById("Password" + this.dataset.pmId); elem.type = "text"; } function DoHide() { var elem = document.getElementById("Password" + this.dataset.pmId); elem.type = "password"; } function DoReorderAsync() { var response = JSON.parse(this.responseText); if (response.error) { Error(response.error); } else { RefreshData(); } } function DoUp() { var id = this.dataset.pmId; var prev = this.dataset.pmPrevId; WebRequest("reorder.php", DoReorderAsync, [ "from_id", id, "to_id", prev ] ); } function DoDown() { var id = this.dataset.pmId; var next = this.dataset.pmNextId; WebRequest("reorder.php", DoReorderAsync, [ "from_id", id, "to_id", next ] ); } // vim: sw=4 ts=4