Created PUT API and added edit support

This commit is contained in:
Gourav Kumar 2024-06-15 23:41:33 +05:30
parent 658c0b091c
commit 8210f4957e
2 changed files with 77 additions and 6 deletions

View File

@ -13,13 +13,19 @@ import ListSecrets from "./components/ListSecrets.vue";
Create Create
</el-button> </el-button>
<el-button type="warning" class="ml-2" @click="logout">Logout</el-button> <el-button type="warning" class="ml-2" @click="logout">Logout</el-button>
<el-button type="error" @click="refresh">Refresh</el-button>
</div> </div>
</div> </div>
<div class="timer" :style="{ width: timerWidth + '%' }"></div>
<el-dialog v-model="creationDialog" title="Add a new TOTP secret" width="80vw"> <el-dialog v-model="creationDialog" title="Add a new TOTP secret" width="80vw">
<CreateSecret @close="creationDialog = false" /> <CreateSecret @close="creationDialog = false" />
</el-dialog> </el-dialog>
<el-dialog v-model="editDialog" title="Edit TOTP secret" width="80vw">
<CreateSecret :editSecret="editingSecret" @close="editDialog = false" />
</el-dialog>
<div class="container"> <div class="container">
<HomePage <HomePage
msg="You did it!" msg="You did it!"
@ -33,7 +39,7 @@ import ListSecrets from "./components/ListSecrets.vue";
<el-button @click="showSecrets = false" v-if="showSecrets && loggedin"> <el-button @click="showSecrets = false" v-if="showSecrets && loggedin">
Hide secrets Hide secrets
</el-button> --> </el-button> -->
<ListSecrets :key="listUpdated" v-if="showSecrets && loggedin" /> <ListSecrets :key="listUpdated" v-if="showSecrets && loggedin" @edit="editSecret" />
</div> </div>
</div> </div>
</template> </template>
@ -47,6 +53,9 @@ export default {
creationDialog: false, creationDialog: false,
listUpdated: 1, listUpdated: 1,
apiBaseUrl: "http://localhost:8000", apiBaseUrl: "http://localhost:8000",
editDialog: false,
editingSecret: {},
timerWidth: 100,
}; };
}, },
methods: { methods: {
@ -91,6 +100,29 @@ export default {
} }
return false; return false;
}, },
editSecret(secret) {
this.editingSecret = secret;
// console.log(this.editingSecret);
this.editDialog = true;
},
refresh() {
this.listUpdated += 1;
},
startTimer() {
this.interval = setInterval(() => {
const now = new Date();
const seconds = now.getSeconds();
const remainingTime = (seconds > 30 ? 60 : 30) - seconds;
// console.log(remainingTime);
this.timerWidth = (remainingTime / 30) * 100;
if (remainingTime === 30) {
this.refresh();
}
}, 1000);
},
}, },
async mounted() { async mounted() {
@ -101,6 +133,7 @@ export default {
this.loggedin = true; this.loggedin = true;
this.showSecrets = true; this.showSecrets = true;
} }
this.startTimer();
} }
}, },
}; };
@ -118,7 +151,7 @@ export default {
} }
.container { .container {
margin-top: 2rem; margin-top: 0;
} }
.logoutBtn { .logoutBtn {
@ -147,4 +180,10 @@ export default {
font-size: 1.3rem; font-size: 1.3rem;
font-weight: 700; font-weight: 700;
} }
.timer {
margin-top: 1.2rem;
height: 0.3rem;
background-color: green;
}
</style> </style>

40
main.py
View File

@ -123,9 +123,7 @@ async def login(user: UserLogin):
@app.post("/secret") @app.post("/secret")
async def create_secret(secret: Secret, current_user: dict = Depends(get_current_user)): async def create_secret(secret: Secret, current_user: dict = Depends(get_current_user)):
""" """
Stores and encrypted secret for the user. Stores an encrypted secret for the user.
The encrypted secret is unreadable on the server and is encrypted on the front-end
""" """
data = [] data = []
@ -148,6 +146,40 @@ async def create_secret(secret: Secret, current_user: dict = Depends(get_current
return secret return secret
@app.put("/secret")
async def update_secret(secret: Secret, current_user: dict = Depends(get_current_user)):
"""
Updates an encrypted secret for the user.
"""
data = []
with open('database/secrets.json', 'r') as f:
text = f.read()
if text:
data.extend(json.loads(text))
if secret.id is None:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail="Id must be passed for updating secret")
secret.user_id = current_user['id']
found_secrets = [(i, j) for i, j in enumerate(data) if j['user_id'] == secret.user_id and j['id']==secret.id]
if not found_secrets:
raise HTTPException(status.HTTP_400_BAD_REQUEST, deatil="Secret with this Id not found for this user")
secret_pos = found_secrets[0][0]
encryption_key = current_user['encryption_key'].encode()
encrypted_data = fernet_encrypt(secret.data.encode(), encryption_key)
secret.data = encrypted_data.decode('utf-8')
data[secret_pos] = jsonable_encoder(secret)
with open('database/secrets.json', 'w') as f:
json.dump(data, f)
return secret
@app.get('/secret') @app.get('/secret')
async def list_secret(current_user: dict = Depends(get_current_user)): async def list_secret(current_user: dict = Depends(get_current_user)):
"""Returns the encrypted secrets of the user.""" """Returns the encrypted secrets of the user."""
@ -161,7 +193,7 @@ async def list_secret(current_user: dict = Depends(get_current_user)):
user_id = current_user['id'] user_id = current_user['id']
encryption_key = current_user['encryption_key'].encode() encryption_key = current_user['encryption_key'].encode()
user_secrets = [i for i in data if i['user_id']==user_id] user_secrets = [i for i in data if i['user_id']==user_id and i['active']]
for secret in user_secrets: for secret in user_secrets:
cur_data = secret['data'] cur_data = secret['data']
decrypted_data = fernet_decrypt(cur_data, encryption_key) decrypted_data = fernet_decrypt(cur_data, encryption_key)