update local changes

This commit is contained in:
Jarian Cottingham 2026-07-03 01:14:04 +00:00
parent 17e7c06b59
commit 8fdfc4fc46
3 changed files with 75 additions and 43 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.env
data/

View File

@ -4,11 +4,8 @@ services:
ports: ports:
- "8765:8765" - "8765:8765"
volumes: volumes:
- pinvault-data:/data - ./data:/data
- /mnt/aidata:/mnt/aidata - /mnt/aidata:/mnt/aidata
environment: environment:
- PINVAULT_MASTER_HASH=${PINVAULT_MASTER_HASH} - PINVAULT_MASTER_HASH=${PINVAULT_MASTER_HASH}
restart: unless-stopped restart: unless-stopped
volumes:
pinvault-data:

View File

@ -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 title = document.getElementById("modal-title");
const body = document.getElementById("modal-body"); const body = document.getElementById("modal-body");
title.textContent = `Access PIN #${id}`; title.textContent = `Access PIN #${id}`;
body.innerHTML = `
<p class="muted" style="margin-bottom:1rem;font-size:0.85rem">
Enter a recovery code to bypass the lock:
</p>
<form id="access-form">
<div class="form-group">
<textarea id="bypass-input" placeholder="Type 64-character recovery code here..." rows="2" required onpaste="return false"></textarea>
</div>
<div id="access-error" class="error-msg" style="margin-bottom:0.5rem"></div>
<button type="submit" class="btn btn-primary" style="width:100%">Unlock PIN</button>
</form>`;
document.getElementById("modal-overlay").classList.remove("hidden");
const bypassInput = document.getElementById("bypass-input"); const pins = await api("/api/pins");
bypassInput.addEventListener("paste", (e) => { e.preventDefault(); }); const pin = pins.find(p => p.id === id);
bypassInput.addEventListener("drop", (e) => { e.preventDefault(); });
document.getElementById("access-form").addEventListener("submit", async (e) => { if (pin && !pin.locked) {
e.preventDefault(); body.innerHTML = `
const code = bypassInput.value.trim(); <p class="muted" style="margin-bottom:1rem;font-size:0.85rem">
const errEl = document.getElementById("access-error"); This PIN is unlocked and ready to view.
errEl.textContent = ""; </p>
<button id="reveal-btn" class="btn btn-primary" style="width:100%">Reveal PIN</button>`;
document.getElementById("modal-overlay").classList.remove("hidden");
try { document.getElementById("reveal-btn").addEventListener("click", async () => {
const result = await api(`/api/pins/${id}/access`, { try {
method: "POST", const result = await api(`/api/pins/${id}/access`, {
body: JSON.stringify({ bypass_code: code }), method: "POST",
}); body: JSON.stringify({}),
body.innerHTML = ` });
<div class="text-center"> body.innerHTML = `
<p class="muted" style="margin-bottom:0.3rem">Your PIN</p> <div class="text-center">
<div class="pin-display">${result.pin}</div> <p class="muted" style="margin-bottom:0.3rem">Your PIN</p>
<button class="btn btn-sm" onclick="copyTextDirect('${result.pin}')" style="margin-top:0.5rem"> <div class="pin-display">${result.pin}</div>
Copy PIN &#x1f4cb; <button class="btn btn-sm" onclick="copyTextDirect('${result.pin}')" style="margin-top:0.5rem">
</button> Copy PIN &#x1f4cb;
</div>`; </button>
loadPins(); </div>`;
} catch (err) { loadPins();
errEl.textContent = err.message; } catch (err) {
} body.innerHTML = `<p class="error-msg">${esc(err.message)}</p>`;
}); }
});
} else {
body.innerHTML = `
<p class="muted" style="margin-bottom:1rem;font-size:0.85rem">
Enter a recovery code to bypass the lock:
</p>
<form id="access-form">
<div class="form-group">
<textarea id="bypass-input" placeholder="Type 64-character recovery code here..." rows="2" required onpaste="return false"></textarea>
</div>
<div id="access-error" class="error-msg" style="margin-bottom:0.5rem"></div>
<button type="submit" class="btn btn-primary" style="width:100%">Unlock PIN</button>
</form>`;
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 = `
<div class="text-center">
<p class="muted" style="margin-bottom:0.3rem">Your PIN</p>
<div class="pin-display">${result.pin}</div>
<button class="btn btn-sm" onclick="copyTextDirect('${result.pin}')" style="margin-top:0.5rem">
Copy PIN &#x1f4cb;
</button>
</div>`;
loadPins();
} catch (err) {
errEl.textContent = err.message;
}
});
}
} }
async function deletePin(id, label) { async function deletePin(id, label) {