Compare commits

...

50 Commits

Author SHA1 Message Date
Kosh
25c1a73901 Updat README.md 2023-10-27 08:25:42 +05:30
6239a38ff7 Merge branch 'yash-priv' of https://gitlab.com/koshinhegde/unnamed-password-manager 2023-10-26 21:40:58 +05:30
2a54553dc2 Add await 2023-10-26 21:38:18 +05:30
Kosh
e34045e3c0 Changed delays to await 2023-10-26 21:30:28 +05:30
Kosh
5d7e5d1cc7 Changed delays to await 2023-10-26 21:27:55 +05:30
85458c05e4 Remove dev folder 2023-10-25 23:51:10 +05:30
afb67f34d4 Merge branch 'yash-priv' of https://gitlab.com/koshinhegde/unnamed-password-manager 2023-10-25 23:48:35 +05:30
f66e1c4b26 Remove content security policy 2023-10-25 23:44:28 +05:30
60f843b6d2 i hate rebase 2023-10-25 23:43:05 +05:30
b1ef6a6b8f Rebase changes 2023-10-25 23:34:57 +05:30
42bfe61e54 Merge branch 'main' of https://gitlab.com/koshinhegde/unnamed-password-manager 2023-10-25 23:12:00 +05:30
53544492a8 Clear bad rebased files 2023-10-25 23:09:35 +05:30
7f6f73779c Merge branch 'yash-priv' of https://gitlab.com/koshinhegde/unnamed-password-manager into yash-priv 2023-10-25 23:08:45 +05:30
fa9cdee863 Remove package.json 2023-10-25 23:08:29 +05:30
e2730b393e Edit package.json dependancies 2023-10-25 23:08:12 +05:30
f9da14d044 Add success popup to Password Change UI 2023-10-25 23:08:12 +05:30
89f3653bca Finish Frontend
-Added Register Logic
-Added Change Password Logic

This is the Alpha Version of the PasswordManager, there shouldn't
be any bugs as far as I know. Report any that are found..Plz Don't
Good Night!
2023-10-25 23:08:11 +05:30
20d02fa2ce Add Change Password Function + Dashboard Complete 2023-10-25 23:08:03 +05:30
30a9110623 Link Api to Edit Data Fields + Animations 2023-10-25 23:07:58 +05:30
591c478325 Add "Edit Data" Data Logic 2023-10-25 23:07:58 +05:30
0142794302 Add Data Edit Page UI 2023-10-25 23:07:57 +05:30
2977da4b32 Add Display For Information + Logic 2023-10-25 23:07:50 +05:30
42de93efe5 Add "Add Entry" Functionality 2023-10-25 23:07:44 +05:30
2dd1c87bb7 Add Form Logic 2023-10-25 23:07:43 +05:30
22c0f04cde Add input boxes for Add entry page 2023-10-25 23:07:37 +05:30
4357c58dfd Add Add Entry Page & CSS Animations 2023-10-25 23:07:29 +05:30
8c2d58beb8 Make UI changes, Implement Logout 2023-10-25 23:07:21 +05:30
0db6f71655 Add Entry List with Functionality 2023-10-25 23:07:21 +05:30
02273208fd Dashboard Entry Update 2023-10-25 23:07:14 +05:30
6cf10ae7f9 Reorganize Folders 2023-10-25 23:07:06 +05:30
Kosh
49420c5a1d Add content box in the dashboard 2023-10-25 23:06:50 +05:30
Kosh
b9eea92668 Add compatibility for a get request to /index.html 2023-10-25 23:06:50 +05:30
Kosh
73770a1904 Move static folder from backend to frontend folder 2023-10-25 23:06:50 +05:30
8db7639e37 Add error message to login, Fix Internal Error 500
Yeah i touched the rest api and fixed the internal favicon error :P
Cleaned up the pages and linked the error messages
2023-10-25 23:06:50 +05:30
9a29e5da68 Add all other pages 2023-10-25 23:06:38 +05:30
f95899f68d Add api request changes 2023-10-25 23:06:32 +05:30
317e92ec7f Add dev code to test 2023-10-25 23:06:13 +05:30
Kosh
6b2ce5c8fb Add .gitkeep to every subfolder 2023-10-25 23:04:56 +05:30
Kosh
b65b5570cc Moved frontend/index.html to frontend/html/index.html
Closing #2; Closing #1
2023-10-25 23:04:56 +05:30
Kosh
feb5689757 Added compatibility for subfolders 2023-10-25 23:04:41 +05:30
Koshin Hegde
06eedbdd63 Add LICENSE 2023-10-25 23:04:41 +05:30
Kosh
81921fa4ba Interacting with data with rest api 2023-10-25 23:04:41 +05:30
Kosh
4e85d9e33a Implement getting data using rest api 2023-10-25 23:03:56 +05:30
Kosh
b01aa43f32 Make the file paths cross-platform compatible 2023-10-25 23:02:52 +05:30
87fd6ecd6e Add git ignor 2023-10-25 23:02:52 +05:30
1eb6af9afd Add error message to login, Fix Internal Error 500
Yeah i touched the rest api and fixed the internal favicon error :P
Cleaned up the pages and linked the error messages
2023-10-25 23:02:31 +05:30
c03a80c66d Add all other pages 2023-10-25 23:02:31 +05:30
08c11d4f6e Add api request changes 2023-10-25 23:02:31 +05:30
762dd9974c Add dev code to test 2023-10-25 23:00:47 +05:30
c60f635a89 Add git ignore 2023-10-24 18:53:43 +05:30
10 changed files with 981 additions and 845 deletions

2
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,2 @@
{
}

114
README.md
View File

@ -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
```

View File

@ -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>

View File

@ -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>

View File

@ -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()
};
};

View File

@ -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'

View File

@ -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
});
@ -75,4 +75,4 @@ async function Login(username,password){
} catch (error) {
console.error('Error:', error.message);
}
}
}

File diff suppressed because it is too large Load Diff

13
package-lock.json generated Normal file
View 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
View File

@ -0,0 +1,12 @@
{
"name": "unnamed-password-manager",
"version": "1.0.0",
"description": "Hi",
"main": "index.js",
"scripts": {
"start": ""
},
"keywords": [],
"author": "",
"license": "ISC"
}