diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24f9f8d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +data/ diff --git a/docker-compose.yml b/docker-compose.yml index ed6f792..a8e2df7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,11 +4,8 @@ services: ports: - "8765:8765" volumes: - - pinvault-data:/data + - ./data:/data - /mnt/aidata:/mnt/aidata environment: - PINVAULT_MASTER_HASH=${PINVAULT_MASTER_HASH} restart: unless-stopped - -volumes: - pinvault-data: \ No newline at end of file diff --git a/static/app.js b/static/app.js index 78bc5bb..8470576 100644 --- a/static/app.js +++ b/static/app.js @@ -133,51 +133,84 @@ document.getElementById("add-form").addEventListener("submit", async (e) => { } }); -function accessPin(id) { +async function accessPin(id) { const title = document.getElementById("modal-title"); const body = document.getElementById("modal-body"); title.textContent = `Access PIN #${id}`; - body.innerHTML = ` -

- Enter a recovery code to bypass the lock: -

-
-
- -
-
- -
`; - document.getElementById("modal-overlay").classList.remove("hidden"); - const bypassInput = document.getElementById("bypass-input"); - bypassInput.addEventListener("paste", (e) => { e.preventDefault(); }); - bypassInput.addEventListener("drop", (e) => { e.preventDefault(); }); + const pins = await api("/api/pins"); + const pin = pins.find(p => p.id === id); - document.getElementById("access-form").addEventListener("submit", async (e) => { - e.preventDefault(); - const code = bypassInput.value.trim(); - const errEl = document.getElementById("access-error"); - errEl.textContent = ""; + if (pin && !pin.locked) { + body.innerHTML = ` +

+ This PIN is unlocked and ready to view. +

+ `; + document.getElementById("modal-overlay").classList.remove("hidden"); - try { - const result = await api(`/api/pins/${id}/access`, { - method: "POST", - body: JSON.stringify({ bypass_code: code }), - }); - body.innerHTML = ` -
-

Your PIN

-
${result.pin}
- -
`; - loadPins(); - } catch (err) { - errEl.textContent = err.message; - } - }); + document.getElementById("reveal-btn").addEventListener("click", async () => { + try { + const result = await api(`/api/pins/${id}/access`, { + method: "POST", + body: JSON.stringify({}), + }); + body.innerHTML = ` +
+

Your PIN

+
${result.pin}
+ +
`; + loadPins(); + } catch (err) { + body.innerHTML = `

${esc(err.message)}

`; + } + }); + } else { + body.innerHTML = ` +

+ Enter a recovery code to bypass the lock: +

+
+
+ +
+
+ +
`; + document.getElementById("modal-overlay").classList.remove("hidden"); + + const bypassInput = document.getElementById("bypass-input"); + bypassInput.addEventListener("paste", (e) => { e.preventDefault(); }); + bypassInput.addEventListener("drop", (e) => { e.preventDefault(); }); + + document.getElementById("access-form").addEventListener("submit", async (e) => { + e.preventDefault(); + const code = bypassInput.value.trim(); + const errEl = document.getElementById("access-error"); + errEl.textContent = ""; + + try { + const result = await api(`/api/pins/${id}/access`, { + method: "POST", + body: JSON.stringify({ bypass_code: code }), + }); + body.innerHTML = ` +
+

Your PIN

+
${result.pin}
+ +
`; + loadPins(); + } catch (err) { + errEl.textContent = err.message; + } + }); + } } async function deletePin(id, label) {