From 9dc5ef01437628fd06908329709d5ff1585a112b Mon Sep 17 00:00:00 2001 From: c3z Date: Sat, 7 Mar 2026 19:40:14 +0100 Subject: [PATCH] (feat) Add password-based document encryption (AES-256-GCM) - Lock/unlock documents via menu with password protection - Uses Web Crypto API: PBKDF2 (100k iterations) + AES-256-GCM - Encrypted URLs use `#e0_` prefix to distinguish from plain - Password dialog with confirmation when setting, retry on wrong password - Cached derived key per session to avoid PBKDF2 on every save - Extracted deflate/inflate primitives to deduplicate compression logic Co-Authored-By: Claude Opus 4.6 --- index.html | 318 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 305 insertions(+), 13 deletions(-) diff --git a/index.html b/index.html index 5fb7b3a..7116662 100644 --- a/index.html +++ b/index.html @@ -256,6 +256,79 @@ visibility: visible; } + dialog { + border: none; + border-radius: 12px; + padding: 24px; + background: var(--elevated); + color: var(--text); + box-shadow: 0 19px 38px rgba(0, 0, 0, 0.15); + max-width: 300px; + width: calc(100% - 32px); + } + + dialog::backdrop { + background: rgba(0, 0, 0, 0.5); + } + + dialog form { + display: flex; + flex-direction: column; + gap: 14px; + } + + dialog p { + font: 600 16px / 1.5 system-ui; + margin: 0; + } + + dialog .error { + color: #e53e3e; + font: 14px / 1.5 system-ui; + font-weight: normal; + min-height: 0; + } + + dialog input[type="password"] { + font: 16px / 1.5 system-ui; + padding: 8px 12px; + border: 1px solid rgba(128, 128, 128, 0.3); + border-radius: 8px; + background: transparent; + color: var(--text); + outline: none; + width: 100%; + } + + dialog input[type="password"]:focus { + border-color: var(--outline); + box-shadow: 0 0 0 1px var(--outline); + } + + dialog .buttons { + display: flex; + gap: 8px; + justify-content: flex-end; + } + + dialog button { + font: 600 14px / 1.5 system-ui; + padding: 6px 16px; + border-radius: 8px; + border: none; + cursor: pointer; + } + + dialog button[type="submit"] { + background: #0569fa; + color: #fff; + } + + dialog button[type="button"] { + background: transparent; + color: var(--text); + } + @media print { .noprint { visibility: hidden !important; @@ -303,6 +376,12 @@ Save as TEXT + + + Lock document +
+ +
+

Enter password

+ + +

+
+ + +
+
+