Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Commit

Permalink
Edit and delete codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Levminer committed Jul 22, 2022
1 parent 35538b8 commit 5e3da0b
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 133 deletions.
133 changes: 0 additions & 133 deletions interface/windows/edit.svelte

This file was deleted.

85 changes: 85 additions & 0 deletions interface/windows/edit/edit.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<div class="transparent-900 loadSavedCodes m-auto my-20 w-4/5 rounded-2xl p-10 text-left">
<h1 class="px-10">Load saved codes</h1>
<div class="mx-auto flex flex-col items-center justify-center rounded-2xl p-10">
<div class="transparent-800 mb-5 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left">
<div>
<h2>Loading saved codes</h2>
<h3>Load your saved 2FA codes. You can edit or delete your codes, or you can even add new codes here.</h3>
</div>
<div class="ml-20 flex gap-3">
<button class="button" on:click={loadSavedCodes}>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Confirm
</button>
</div>
</div>
</div>
</div>

<div class="transparent-900 editSavedCodes m-auto my-20 hidden w-4/5 rounded-2xl p-10 text-left">
<h1 class="px-10">Edit saved codes</h1>
<div class="mx-auto flex flex-col items-center justify-center rounded-2xl p-10">
<div class="transparent-800 mb-5 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left">
<div>
<h2>Save changes</h2>
<h3>Save the changes you made. This will overwrite your codes.</h3>
</div>
<div class="ml-10 flex gap-3">
<button class="button" on:click={saveChanges}>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2" />
<circle cx="12" cy="14" r="2" />
<polyline points="14 4 14 8 8 8 8 4" />
</svg>
Save changes
</button>
</div>
</div>

<div class="transparent-800 mb-5 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left">
<div>
<h2>Revert changes</h2>
<h3>You can revert the current changes you made.</h3>
</div>
<div class="ml-10 flex gap-3">
<button class="button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4" />
<path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" />
<line x1="12" y1="9" x2="12" y2="12" />
<line x1="12" y1="15" x2="12.01" y2="15" />
</svg>
Revert changes
</button>
</div>
</div>

<div class="transparent-800 mb-5 flex w-full flex-row items-center justify-between rounded-xl p-5 text-left">
<div>
<h2>Delete codes</h2>
<h3>You can delete all codes. Be careful, this can not be undone.</h3>
</div>
<div class="ml-10 flex gap-3">
<button class="button" on:click={deleteCodes}>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
Delete codes
</button>
</div>
</div>
</div>
</div>

<div class="transparent-900 loadedCodes m-auto mb-20 hidden w-4/5 rounded-2xl p-10 text-left">
<h1 class="px-10">Loaded codes</h1>
<div class="content mx-auto flex flex-col items-center justify-center rounded-2xl p-10" />
</div>

<script lang="ts">
import { deleteCodes, loadSavedCodes, saveChanges } from "./index"
</script>
177 changes: 177 additions & 0 deletions interface/windows/edit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import { textConverter } from "../../libraries/convert"
import { encrypt, decrypt, generateMasterKey } from "../../libraries/auth"
import { dialog, fs, path } from "@tauri-apps/api"
import { getSettings, setSettings } from "../../stores/settings"
import { generateTimestamp } from "../../libraries/time"
import { getState, setState } from "../../stores/state"
import { navigate } from "../../libraries/navigate"

let names: string[] = []
let issuers: string[] = []
let secrets: string[] = []

const generateEditElements = () => {
document.querySelector(".editSavedCodes").style.display = "block"
document.querySelector(".loadedCodes").style.display = "block"
document.querySelector(".loadSavedCodes").style.display = "none"

for (let i = 0; i < names.length; i++) {
// create div
const element = document.createElement("div")

// set div content
element.innerHTML = `
<div class="flex flex-wrap gap-5">
<div>
<h5>Name</h5>
<input id="issuer${i}" class="input mt-1" type="text" value="${issuers[i]}" readonly />
</div>
<div>
<h5>Description</h5>
<input id="name${i}" class="input mt-1 w-96" type="text" value="${names[i]}" readonly />
</div>
</div>
<div class="ml-10 flex gap-3">
<button id="editCode${i}" class="button requirePassword">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
</svg>
Edit
</button>
<button id="deleteCode${i}" class="button requirePassword">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
Delete
</button>
</div>`

// add div
element.classList.add("edit")
element.setAttribute("id", `edit${i}`)

document.querySelector(".content").appendChild(element)

document.querySelector(`#editCode${i}`).addEventListener("click", () => {
editCode(i)
})

document.querySelector(`#deleteCode${i}`).addEventListener("click", () => {
deleteCode(i)
})
}
}

export const loadSavedCodes = async () => {
const settings = getSettings()
const filePath = await path.join(await path.configDir(), "Levminer", "Authme 4", "codes", "codes.authme")

let file: LibAuthmeFile

try {
file = JSON.parse(await fs.readTextFile(filePath))
} catch (error) {
return dialog.message("No save file found. \n\nGo to the codes or the import page and import your codes!", { type: "error" })
}

const password = Buffer.from(settings.security.password, "base64")
const key = Buffer.from(settings.security.key, "base64")

const masterKey = await generateMasterKey(password, key)

const decrypted = await decrypt(file.codes, masterKey)

const data = textConverter(decrypted, 0)

names = data.names
issuers = data.issuers
secrets = data.secrets

generateEditElements()
}

export const saveChanges = async () => {
const settings = getSettings()

let saveText = ""

for (let i = 0; i < names.length; i++) {
const string = `\nName: ${names[i]} \nSecret: ${secrets[i]} \nIssuer: ${issuers[i]} \nType: OTP_TOTP\n`
saveText += string
}

const password = Buffer.from(settings.security.password, "base64")
const key = Buffer.from(settings.security.key, "base64")

const masterKey = await generateMasterKey(password, key)

const encrypted = await encrypt(saveText, masterKey)

const fileContents: LibAuthmeFile = {
codes: encrypted,
encrypted: true,
version: 3,
role: "codes",
date: generateTimestamp(),
}
const filePath = await path.join(await path.configDir(), "Levminer", "Authme 4", "codes", "codes.authme")

await fs.writeTextFile(filePath, JSON.stringify(fileContents, null, "\t"))
}

/**
* Delete all imported codes
*/
export const deleteCodes = async () => {
const confirm0 = await dialog.ask("Are you sure you want to delete all codes? \n\nYou can not revert this.", { type: "warning" })

if (confirm0 === false) {
return
}

const confirm1 = await dialog.ask("Are you absolutely sure? \n\nThere is no way back!", { type: "warning" })

if (confirm1 === true) {
const filePath = await path.join(await path.configDir(), "Levminer", "Authme 4", "codes", "codes.authme")
await fs.removeFile(filePath)

navigate("/")
}
}

export const editCode = (id: number) => {
const issuer: HTMLInputElement = document.querySelector(`#issuer${id}`)
const name: HTMLInputElement = document.querySelector(`#name${id}`)

issuer.focus()
const length = issuer.value.length
issuer.setSelectionRange(length, length)

if (issuer.readOnly === true) {
issuer.readOnly = false
name.readOnly = false
} else {
issuer.readOnly = true
name.readOnly = true

const newIssuer = document.querySelector(`#issuer${id}`).value
const newName = document.querySelector(`#name${id}`).value

issuers[id] = newIssuer
names[id] = newName
}
}

export const deleteCode = async (id: number) => {
const res = await dialog.ask("Are you sure?")

if (res === true) {
names.splice(id, 1)
secrets.splice(id, 1)
issuers.splice(id, 1)

document.querySelector(`#edit${id}`).remove()
}
}

0 comments on commit 5e3da0b

Please sign in to comment.