diff options
-rw-r--r-- | INSTRUCTIONS | 20 | ||||
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | www/css/main.css | 51 | ||||
-rw-r--r-- | www/favicon.png | bin | 0 -> 236 bytes | |||
-rw-r--r-- | www/index.html | 31 | ||||
-rw-r--r-- | www/scripts/main.js | 203 |
6 files changed, 287 insertions, 21 deletions
diff --git a/INSTRUCTIONS b/INSTRUCTIONS new file mode 100644 index 0000000..8bd6260 --- /dev/null +++ b/INSTRUCTIONS @@ -0,0 +1,20 @@ +On loading the website you will be greeted by a passphrase prompt, a load +button, a group selection box and a text box to enter a new group name. + +To start, enter your passphrase and hit Load. If you have previously saved +entries they should be displayed. If there are no records just one blank row +will be displayed. Note if you get your passphrase wrong there is no indication +except for the passwords being blank or jumbled. If this is the case alter the +passphrase and hit Load again. + +The last row displayed is the row where new entries can be added. If a group +name is entered in the New Group box then the entry will be added to that +group. To add the record enter a description, username and password and hit the +Add link. + +To edit an existing entry modify the fields as desired and hit the Edit link. + +To delete an existing record simply hit the Delete link. + +The Copy Username and Copy Password links can be used to copy the username or +password respectively to the clipboard. @@ -46,4 +46,5 @@ rights reserved. PassMan is a simple, web-based password manager. It was written in a fit of boredom and need. -Details of installation can be found in INSTALL. +Details of installation can be found in INSTALL. Instructions can be found in +INSTRUCTIONS. diff --git a/www/css/main.css b/www/css/main.css index ab6eb04..d400b22 100644 --- a/www/css/main.css +++ b/www/css/main.css @@ -6,7 +6,7 @@ body .smalltext { - font-size: small; + font-size: x-small; } td input @@ -26,6 +26,55 @@ tr.style2 background-color: #ccccff; } +td.headertext +{ + width: 150px; +} + +td.headerinput +{ + width: 200px; +} + +td.headerbutton +{ + width: 100px; +} + +td.description +{ + width: 40%; + min-width: 100px; + max-width: 500px; +} + +td.username +{ + width: 20%; + min-width: 50px; + max-width: 200px; +} + +td.password +{ + width: 20%; + min-width: 50px; + max-width: 200px; +} + +td.commands +{ + width: 20%; + min-width: 50px; + max-width: 100px; +} + +table.datatable +{ + width: 100%; + max-width: 1000px; +} + a:link { color: black; diff --git a/www/favicon.png b/www/favicon.png Binary files differnew file mode 100644 index 0000000..2f14358 --- /dev/null +++ b/www/favicon.png diff --git a/www/index.html b/www/index.html index 4a1b421..1d8becb 100644 --- a/www/index.html +++ b/www/index.html @@ -3,28 +3,39 @@ <head> <meta charset="utf-8"> <title>PassMan</title> +<link rel="shortcut icon" href="favicon.png" type="image/png"/> <link href="css/main.css" rel="stylesheet" id="stylelink"> <script src="scripts/aes.js"></script> <script src="scripts/main.js"></script> </head> <body> -<div> -Passphrase: <input type="password" id="PassPhrase"> - - +<table> +<tr> +<td class="headertext">Passphrase:</td> +<td class="headerinput"><input type="password" id="PassPhrase"></td> +<td class="headerbutton"> <input type="button" id="LoadButton" value="Load" onclick="DoLoad()"> -<br> -Group: +</td> +</tr> +<tr> +<td class="headertext">Group:</td> +<td class="headerinput"> <select id="Group" onchange="DoSelectGroup()"> </select> - -<input type="text" id="NewGroup" maxlength="512"> -</div> +</td> +<td class="headerbutton"></td> +</tr> +<tr> +<td class="headertext">New Group:</td> +<td class="headerinput"><input type="text" id="NewGroup" maxlength="512"></td> +<td class="headerbutton"></td> +</tr> +</table> <hr> -<table id="DataTable"></table> +<table id="DataTable" class="datatable"></table> </body> </html> diff --git a/www/scripts/main.js b/www/scripts/main.js index 9c77f56..f10139f 100644 --- a/www/scripts/main.js +++ b/www/scripts/main.js @@ -3,6 +3,19 @@ var globalDb = [{"id":"3","description":"TestDescription2","group":"TestGroup"," 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); @@ -43,7 +56,7 @@ function WebRequest(url, func, args) } else { - url += "#"; + url += "&"; } url += args[f] + "="; @@ -70,6 +83,13 @@ function ArrayContains(haystack, needle) return false; } +function IsEmpty(id) +{ + var elem = document.getElementById(id); + + return elem.value == ""; +} + function LoadGroups(keep_selection) { globalGroups = []; @@ -121,7 +141,7 @@ function LoadGroups(keep_selection) elem.value = globalCurrentGroup; } -function AddTableInputCell(id, text, name, node) +function AddTableInputCell(id, text, name, maxlen, classname, node) { var td = document.createElement("td"); var input = document.createElement("input"); @@ -129,6 +149,9 @@ function AddTableInputCell(id, text, name, node) input.value = text; input.id = name + id; input.type = "text"; + input.maxLength = maxlen; + + td.className = classname; td.appendChild(input); node.appendChild(td); @@ -147,10 +170,17 @@ function AddSmallLink(node, text, func, id) node.appendChild(anchor); } -function AddNBSP(node) +function AddText(node, text) +{ + var t = document.createTextNode(text); + node.appendChild(t); +} + +function AddElement(node, elementname) { - var nbsp = document.createTextNode("\u00a0"); - node.appendChild(nbsp); + var elem = document.createElement(elementname); + + node.appendChild(elem); } function AddRow(table, id, desc, username, password, rowcount) @@ -166,12 +196,14 @@ function AddRow(table, id, desc, username, password, rowcount) tr.className = "style2"; } - AddTableInputCell(id, desc, "Description", tr); - AddTableInputCell(id, username, "Username", tr); - AddTableInputCell(id, password, "Password", tr); + AddTableInputCell(id, desc, "Description", 1024, "description", tr); + AddTableInputCell(id, username, "Username", 256, "username", tr); + AddTableInputCell(id, password, "Password", 256, "password", tr); var td = document.createElement("td"); + td.className = "commands"; + if (id == -1) { AddSmallLink(td, "Add", DoAdd, id); @@ -179,8 +211,14 @@ function AddRow(table, id, desc, username, password, rowcount) else { AddSmallLink(td, "Edit", DoEdit, id); - AddNBSP(td); + AddText(td, "\u00a0"); + AddText(td, "\u00a0"); AddSmallLink(td, "Delete", DoDelete, 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); @@ -212,6 +250,18 @@ function LoadTable() AddRow(table, -1, "", "", "", rowcount++); } +function RefreshDataAsync() +{ + globalDb = JSON.parse(this.responseText); + LoadGroups(true); + LoadTable(); +} + +function RefreshData() +{ + WebRequest("get.php", RefreshDataAsync, []); +} + function LoadInitialData() { LoadGroups(false); @@ -226,6 +276,12 @@ function DoLoadAsync() function DoLoad() { + if (IsEmpty("PassPhrase")) + { + Error("Passphrase empty"); + return; + } + // WebRequest("get.php", DoLoadAsync, []); LoadInitialData(); } @@ -235,19 +291,148 @@ 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; + Copy(id); } // vim: sw=4 ts=4 |