Compare commits
50 Commits
yash-priv-
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
25c1a73901 | ||
6239a38ff7 | |||
2a54553dc2 | |||
![]() |
e34045e3c0 | ||
![]() |
5d7e5d1cc7 | ||
85458c05e4 | |||
afb67f34d4 | |||
f66e1c4b26 | |||
60f843b6d2 | |||
b1ef6a6b8f | |||
42bfe61e54 | |||
53544492a8 | |||
7f6f73779c | |||
fa9cdee863 | |||
e2730b393e | |||
f9da14d044 | |||
89f3653bca | |||
20d02fa2ce | |||
30a9110623 | |||
591c478325 | |||
0142794302 | |||
2977da4b32 | |||
42de93efe5 | |||
2dd1c87bb7 | |||
22c0f04cde | |||
4357c58dfd | |||
8c2d58beb8 | |||
0db6f71655 | |||
02273208fd | |||
6cf10ae7f9 | |||
![]() |
49420c5a1d | ||
![]() |
b9eea92668 | ||
![]() |
73770a1904 | ||
8db7639e37 | |||
9a29e5da68 | |||
f95899f68d | |||
317e92ec7f | |||
![]() |
6b2ce5c8fb | ||
![]() |
b65b5570cc | ||
![]() |
feb5689757 | ||
![]() |
06eedbdd63 | ||
![]() |
81921fa4ba | ||
![]() |
4e85d9e33a | ||
![]() |
b01aa43f32 | ||
87fd6ecd6e | |||
1eb6af9afd | |||
c03a80c66d | |||
08c11d4f6e | |||
762dd9974c | |||
c60f635a89 |
2
.vscode/settings.json
vendored
Normal file
2
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
{
|
||||
}
|
114
README.md
114
README.md
@ -1,2 +1,114 @@
|
||||
# Unnamed Password Manager
|
||||
Hi
|
||||
### Introduction
|
||||
This is a password manager. Keep your passwords safe. :><br>
|
||||
|
||||
### Features:
|
||||
- Fully local storage
|
||||
- Symmetric AES encryption
|
||||
- Multiple users
|
||||
- Cross platform
|
||||
- Web ui
|
||||
|
||||
## Working
|
||||
Why use Unnamed Password Manager (UNPM)
|
||||
### Before UNPM
|
||||
"Never use common password"
|
||||
- A wise person
|
||||
```mermaid
|
||||
flowchart LR
|
||||
vw[Visit Website]
|
||||
--> s[Sign up using unique password]
|
||||
--> fp["Forgot Password 😭"]
|
||||
vw[Visit Website]
|
||||
--> sa[Sign up with common password]
|
||||
--> gh[Get all your accounts hacked]
|
||||
```
|
||||
### After UNPM
|
||||
```mermaid
|
||||
flowchart LR
|
||||
vw[Visit Website]
|
||||
--> s[Sign up using unique password]
|
||||
--> sp[Save password safely in UNPM]
|
||||
vwa[Visit Website again]
|
||||
--> gp[Get password using our web-app]
|
||||
--> l[Login]
|
||||
```
|
||||
|
||||
## FAQ
|
||||
#### How to Backup?
|
||||
- Check where AppData is standard stored if your OS is not mentioned here.
|
||||
- Linux:
|
||||
- - Backup the file at the location "~/.local/share/Unnamed_Password_Manager/\<USERNAME\>"
|
||||
- - Paste it in the same location or follow the directions for the OS.
|
||||
|
||||
|
||||
# Dev docs
|
||||
## Rest API
|
||||
##### WARNING:
|
||||
Do NOT use this api for ANY reason EXCEPT if usage is ONLY local, i.e.,
|
||||
this api is NOT built for usage over an external network and doing so
|
||||
WILL NOT BE SECURE
|
||||
###### Note:
|
||||
Server throws 405 METHOD NOT ALLOWED if the url is mistyped
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User
|
||||
box App
|
||||
participant Frontend
|
||||
participant Backend
|
||||
end
|
||||
|
||||
Note over User, Backend : LOGIN
|
||||
User -->> Frontend : Wants to login
|
||||
Frontend -->> Backend : { user_name : "...", password : "..." } to /login
|
||||
Backend -->> Frontend : Success : http 200
|
||||
Backend -->> Frontend : user_name / password not given : http 400
|
||||
Backend -->> User : user_name / password is wrong : http 403
|
||||
|
||||
Note over User, Backend : LOGOUT
|
||||
User -->> Frontend : Wants to logout
|
||||
Frontend -->> Backend : /logout
|
||||
Backend -->> Frontend : Success : http 200
|
||||
Backend -->> User : Not logged in : http 403
|
||||
|
||||
Note over User, Backend : ADD USER
|
||||
User -->> Frontend : Wants to add user
|
||||
Frontend -->> Backend : { user_name : "...", password : "..." } to /add_user
|
||||
Backend -->> Frontend : Success : http 200
|
||||
Backend -->> Frontend : user_name / password not given : http 400
|
||||
Backend -->> User : user_name is taken : http 403
|
||||
|
||||
Note over User, Backend : GET DATA
|
||||
User -->> Frontend : field/ entry, etc.
|
||||
Frontend -->> Backend : /get_data
|
||||
Backend -->> User : Not logged in : http 403
|
||||
|
||||
Note over User, Backend : CHANGE PASSWORD
|
||||
User -->> Frontend : Wants to change password
|
||||
Frontend -->> Backend : { password : "..." } to /change_password
|
||||
Backend -->> Frontend : password not given : http 400
|
||||
Backend -->> User : Not logged in : http 403
|
||||
|
||||
Note over User, Backend : ADD ENTRY
|
||||
User -->> Frontend : Wants to add entry
|
||||
Frontend -->> Backend : entry data to /add_entry
|
||||
Note over Frontend, Backend : entry data is { entry_name : "...", fields : "..." }
|
||||
Note over Frontend, Backend : fields should be string({ field1 : "...", field2 : "...", ... })
|
||||
Backend -->> Frontend : Entry data is not correct : http 400
|
||||
Backend -->> User : Not logged in : http 403
|
||||
|
||||
Note over User, Backend : DELETE ENTRY
|
||||
User -->> Frontend : Wants to delete entry
|
||||
Frontend -->> Backend : { entry_name : "..." } to /delete_entry
|
||||
Backend -->> Frontend : entry_name not given : http 400
|
||||
Backend -->> User : Not logged in or entry_name does not exist : http 403
|
||||
|
||||
Note over User, Backend : EDIT ENTRY NAME
|
||||
User -->> Frontend : Wants to change entry name
|
||||
Frontend -->> Backend : { old_entry_name : "...", new_entry_name : "..." }
|
||||
Backend -->> Frontend : Success : http 200
|
||||
Backend -->> Frontend : old or new entry names not given : http 400
|
||||
Backend -->> User : Old user name doesn't exist or the new one already exists
|
||||
```
|
||||
|
@ -81,7 +81,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<label id="greetname"></label>
|
||||
<a href="#" onclick="changePassConfirm()">Change Password</a>
|
||||
<a href="#" onclick="await changePassConfirm()">Change Password</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -114,9 +114,9 @@
|
||||
<input type="text" name="sitename" placeholder="Site Name" id="sitenamefield" >
|
||||
<input type="text" name="url" placeholder="Site URL" id="urlfield" value="https://">
|
||||
<label></label>
|
||||
<button type="button" onclick="validateData()" id="submitdatabtn"></button>
|
||||
<button type="button" onclick="deleteEntryConfirm()" id="deletedata"></button>
|
||||
<button type="button" onclick="validateDataEdit()" id="submiteditdatabtn">Save</button>
|
||||
<button type="button" onclick="await validateData()" id="submitdatabtn"></button>
|
||||
<button type="button" onclick="await deleteEntryConfirm()" id="deletedata"></button>
|
||||
<button type="button" onclick="await validateDataEdit()" id="submiteditdatabtn">Save</button>
|
||||
</div>
|
||||
|
||||
<div class="inputfieldpanel">
|
||||
@ -146,7 +146,7 @@
|
||||
<div class="popupdivparent">
|
||||
<div class="popupdiv">
|
||||
<div>
|
||||
<button onclick="closePopup()" id="closepopup"></button>
|
||||
<button onclick="await closePopup()" id="closepopup"></button>
|
||||
</div>
|
||||
<div class="popupdivchild"></div>
|
||||
</div>
|
||||
|
@ -29,7 +29,7 @@
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<button id="loginb" onclick="validateRegister()">Sign Up</button>
|
||||
<button id="loginb" onclick="await validateRegister()">Sign Up</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -14,9 +14,11 @@
|
||||
|
||||
//-----------------------------------------------------------------------------------------(Getting Data)
|
||||
|
||||
const PORT = 5000;
|
||||
|
||||
async function getData() {
|
||||
try {
|
||||
let response = await fetch('/get_data', {
|
||||
let response = await fetch(`http://127.0.0.1:${PORT}/get_data`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@ -113,10 +115,10 @@ function getDisplayList(fieldnames,userdata){
|
||||
|
||||
const search = document.getElementById('search');
|
||||
|
||||
search.addEventListener('keyup', function() {
|
||||
search.addEventListener('keyup', async function() {
|
||||
let result = search.value;
|
||||
if(result == ""){
|
||||
getData()
|
||||
await getData()
|
||||
} else {
|
||||
getFilterList(result,JSON.parse(localStorage.getItem("userdata")))
|
||||
}
|
||||
@ -194,13 +196,13 @@ function addFieldLogic() {
|
||||
|
||||
//----------------------------------------------------------------------------------------- Form Data Logic
|
||||
|
||||
function submitForm() {
|
||||
async function submitForm() {
|
||||
const form = document.getElementById('formdata')
|
||||
const formdata = new FormData(form)
|
||||
formatData(formdata)
|
||||
await formatData(formdata)
|
||||
}
|
||||
|
||||
function formatData(userdata) {
|
||||
async function formatData(userdata) {
|
||||
const formData = new FormData()
|
||||
const objData = {}
|
||||
let sitename;
|
||||
@ -214,7 +216,7 @@ function formatData(userdata) {
|
||||
formData.append("entry_name", sitename)
|
||||
formData.append("fields", JSON.stringify(objData))
|
||||
// console.log(sitename)
|
||||
sendData(formData)
|
||||
await sendData(formData)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------- Post Entry Data to API
|
||||
@ -223,7 +225,7 @@ const errorlabel = document.querySelector('.fieldcontainer label')
|
||||
|
||||
async function sendData(formData){
|
||||
try {
|
||||
const response = await fetch('/add_entry', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/add_entry`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
@ -233,7 +235,7 @@ async function sendData(formData){
|
||||
entrywindow.style.display = "none"
|
||||
localStorage.removeItem("editVal")
|
||||
}, 1000);
|
||||
getData()
|
||||
await getData()
|
||||
}
|
||||
if(!response.ok){
|
||||
const errorMessage = await response.text();
|
||||
@ -250,9 +252,9 @@ async function sendData(formData){
|
||||
|
||||
//----------------------------------------------------------------------------------------- Form Data Validation Logic
|
||||
|
||||
function validateData() {
|
||||
async function validateData() {
|
||||
if(validateSitename() && validateUrl())
|
||||
submitForm();
|
||||
await submitForm();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -356,9 +358,9 @@ function addFieldEditLogic(field){
|
||||
|
||||
//----------------------------------------------------------------------------------------- Edit Data Validation
|
||||
|
||||
function validateDataEdit() {
|
||||
async function validateDataEdit() {
|
||||
if(validateEditSitename() && validateEditUrl())
|
||||
editData();
|
||||
await editData();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -401,16 +403,15 @@ async function deleteEntry() {
|
||||
const formData = new FormData()
|
||||
formData.append("entry_name", localStorage.getItem("editVal"))
|
||||
try {
|
||||
const response = await fetch('/delete_entry', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/delete_entry`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
if(response.ok){
|
||||
console.log(`Deleted ${localStorage.getItem("editVal")}`)
|
||||
localStorage.removeItem("editVal")
|
||||
getData()
|
||||
await getData()
|
||||
confirmation()
|
||||
await delay(1000)
|
||||
const infobox = document.querySelector('.infobox')
|
||||
const infopanel = document.querySelector('.infopanel')
|
||||
const popupdivparent = document.querySelector('.popupdivparent')
|
||||
@ -441,7 +442,7 @@ function deleteEntryConfirm() {
|
||||
const popupdivparent = document.querySelector('.popupdivparent')
|
||||
const popupdiv = document.querySelector('.popupdivchild')
|
||||
popupdivparent.style.display = "flex"
|
||||
popupdiv.innerHTML = "<div class='c1f'><label>Are You Sure?</label></div>\n <div class='c1l'><button onclick='deleteEntry()'>Yes</button> <button onclick='closePopup()'>No</button></div>"
|
||||
popupdiv.innerHTML = "<div class='c1f'><label>Are You Sure?</label></div>\n <div class='c1l'><button onclick='await deleteEntry()'>Yes</button> <button onclick='closePopup()'>No</button></div>"
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------- Change Pass Entry Popup
|
||||
@ -450,10 +451,10 @@ function changePassConfirm() {
|
||||
const popupdivparent = document.querySelector('.popupdivparent')
|
||||
const popupdiv = document.querySelector('.popupdivchild')
|
||||
popupdivparent.style.display = "flex"
|
||||
popupdiv.innerHTML = "<div class='c2'><input id='c2i1' placeholder='Enter Password' type='password'></input><input id='c2i2' placeholder='Confirm Password' type='password'></input><label id='passerrlabel'></label><button id='changepassbtn' onclick='changePass()'>Submit</button></div>"
|
||||
popupdiv.innerHTML = "<div class='c2'><input id='c2i1' placeholder='Enter Password' type='password'></input><input id='c2i2' placeholder='Confirm Password' type='password'></input><label id='passerrlabel'></label><button id='changepassbtn' onclick='await changePass()'>Submit</button></div>"
|
||||
}
|
||||
|
||||
function changePass() {
|
||||
async function changePass() {
|
||||
const password = document.getElementById('c2i1').value
|
||||
const confirmpassword = document.getElementById('c2i2').value
|
||||
const errlabel = document.getElementById('passerrlabel')
|
||||
@ -470,7 +471,7 @@ function changePass() {
|
||||
},3000)
|
||||
}
|
||||
else if(password == confirmpassword){
|
||||
sendPass(password)
|
||||
await sendPass(password)
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,14 +480,13 @@ async function sendPass(password) {
|
||||
const formData = new FormData()
|
||||
formData.append("password", password)
|
||||
try {
|
||||
const response = await fetch('/change_password', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/change_password`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
if(response.ok){
|
||||
console.log(`Password Changed!`)
|
||||
confirmation()
|
||||
await delay(1000)
|
||||
const popupdivparent = document.querySelector('.popupdivparent')
|
||||
const popupdiv = document.querySelector('.popupdivchild')
|
||||
popupdivparent.style.display = "none"
|
||||
@ -508,7 +508,7 @@ async function sendPass(password) {
|
||||
|
||||
//----------------------------------------------------------------------------------------- Edit Data Submission Logic
|
||||
|
||||
function editData() {
|
||||
async function editData() {
|
||||
const backbtn = document.getElementById('backbtn')
|
||||
const submitbtn = document.getElementById('submiteditdatabtn')
|
||||
const binbutton = document.getElementById('deletedata')
|
||||
@ -517,7 +517,7 @@ function editData() {
|
||||
submitbtn.disabled = true
|
||||
const form = document.getElementById('formdata')
|
||||
const formeditdata = new FormData(form)
|
||||
editDataHandler(formeditdata)
|
||||
await editDataHandler(formeditdata)
|
||||
}
|
||||
|
||||
let isError;
|
||||
@ -551,23 +551,19 @@ async function editDataHandler(editdata) {
|
||||
let value = objData[field]
|
||||
|
||||
if(!(field in userdata[entryname])){
|
||||
addNewField(entryname, field, value)
|
||||
await delay(500)
|
||||
await addNewField(entryname, field, value)
|
||||
}
|
||||
else if(value != userdata[entryname][field]){
|
||||
editFieldValue(entryname, field, value )
|
||||
await delay(500)
|
||||
await editFieldValue(entryname, field, value )
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(sitename != entryname){
|
||||
changeEntryName(entryname, sitename)
|
||||
await delay(500)
|
||||
await changeEntryName(entryname, sitename)
|
||||
}
|
||||
getData()
|
||||
await delay(100)
|
||||
await getData()
|
||||
if(!isError){
|
||||
updateInfoGui(localStorage.getItem("editVal"))
|
||||
confirmation()
|
||||
@ -599,7 +595,7 @@ async function addNewField(sitename, field, value) {
|
||||
formData.append("field_value", value)
|
||||
|
||||
try {
|
||||
const response = await fetch('/add_field', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/add_field`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
@ -628,7 +624,7 @@ async function editFieldValue(sitename, field, value) {
|
||||
formData.append("field_value", value)
|
||||
|
||||
try {
|
||||
const response = await fetch('/edit_field_value', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/edit_field_value`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
@ -655,7 +651,7 @@ async function changeEntryName(entryname, sitename) {
|
||||
formData.append("new_entry_name", sitename)
|
||||
|
||||
try {
|
||||
const response = await fetch('/edit_entry_name', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/edit_entry_name`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
@ -795,7 +791,7 @@ function closePopup() {
|
||||
|
||||
async function logOut() {
|
||||
try{
|
||||
await fetch("/logout", {
|
||||
await fetch(`http://127.0.0.1:${PORT}/logout`, {
|
||||
method:'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@ -821,7 +817,7 @@ logoutbtn.addEventListener('click', () => {
|
||||
|
||||
|
||||
|
||||
window.onload = function() {
|
||||
getData();
|
||||
window.onload = async function() {
|
||||
await getData();
|
||||
greet()
|
||||
};
|
@ -1,3 +1,5 @@
|
||||
const PORT = 5000;
|
||||
|
||||
let loginb = document.getElementById("loginb");
|
||||
|
||||
loginb.addEventListener("click", validateLogin);
|
||||
@ -28,9 +30,9 @@ function validatePass() {
|
||||
}
|
||||
}
|
||||
|
||||
function validateLogin() {
|
||||
async function validateLogin() {
|
||||
if(validateName() && validatePass()) {
|
||||
getAuth();
|
||||
await getAuth();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -48,7 +50,7 @@ formData.append('password', _password);
|
||||
// console.log(formData)
|
||||
|
||||
try {
|
||||
const response = await fetch('/login', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/login`, {
|
||||
method: "post",
|
||||
body: formData
|
||||
});
|
||||
@ -88,7 +90,7 @@ register.addEventListener("click", function(event) {
|
||||
|
||||
window.onload = async function() {
|
||||
try {
|
||||
let response = await fetch('/get_data', {
|
||||
let response = await fetch(`http://127.0.0.1:${PORT}/get_data`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
const errlabel = document.getElementById('errlabel')
|
||||
|
||||
function validateRegister() {
|
||||
async function validateRegister() {
|
||||
const username = document.getElementById('username').value
|
||||
const password = document.getElementById('password').value
|
||||
const confirmpassword = document.getElementById('conpassword').value
|
||||
@ -19,7 +19,7 @@ function validateRegister() {
|
||||
}, 3000);
|
||||
}
|
||||
else if(password == confirmpassword && username!=''){
|
||||
createUser(username,password)
|
||||
await createUser(username,password)
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,13 +29,13 @@ async function createUser(username,password) {
|
||||
formData.append("password", password)
|
||||
|
||||
try {
|
||||
const response = await fetch('/add_user', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/add_user`, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
if(response.ok) {
|
||||
console.log("User Created!")
|
||||
Login(username,password)
|
||||
await Login(username,password)
|
||||
} else if(!response.ok) {
|
||||
const errorMessage = await response.text();
|
||||
errlabel.textContentL = errorMessage;
|
||||
@ -55,7 +55,7 @@ async function Login(username,password){
|
||||
formData.append('password', password);
|
||||
|
||||
try {
|
||||
const response = await fetch('/login', {
|
||||
const response = await fetch(`http://127.0.0.1:${PORT}/login`, {
|
||||
method: "post",
|
||||
body: formData
|
||||
});
|
||||
|
@ -1193,7 +1193,6 @@ footer p{
|
||||
@media (max-width: 860px) {
|
||||
.container{
|
||||
position: fixed;
|
||||
width: 774px;
|
||||
}
|
||||
}
|
||||
|
||||
|
13
package-lock.json
generated
Normal file
13
package-lock.json
generated
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "unnamed-password-manager",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "unnamed-password-manager",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
12
package.json
Normal file
12
package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "unnamed-password-manager",
|
||||
"version": "1.0.0",
|
||||
"description": "Hi",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": ""
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user