diff --git a/.env.example b/.env.example index 70172a5..882e9cd 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,7 @@ JWT_SECRET= # Generate with: openssl rand -hex 16 MEILI_MASTER_KEY= -# Secure cookies (true in production, false in development) +# Secure cookies (default true; set to false only when serving over plain HTTP) COOKIE_SECURE= # App port diff --git a/README.md b/README.md index 442e7f7..0dfec8c 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ The app reads secrets from `.env` (created by `setup.sh`). |---|---|---| | `JWT_SECRET` | Yes | Secret for signing auth tokens (min 32 chars). | | `MEILI_MASTER_KEY` | Yes | Meilisearch master key. | -| `COOKIE_SECURE` | Yes | Use secure cookies (HTTPS). | +| `COOKIE_SECURE` | No | Use secure cookies (HTTPS). Defaults to `true`; set to `false` when serving over plain HTTP. | | `PORT` | Yes | Host port for the app. Default `3000`. | | `DATABASE_PATH` | Yes | SQLite database file path. | | `FILES_PATH` | Yes | Attachments storage path. | diff --git a/app/assets/css/main.css b/app/assets/css/main.css index d00ccac..faf738c 100644 --- a/app/assets/css/main.css +++ b/app/assets/css/main.css @@ -154,3 +154,11 @@ ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background-color: var(--nord-ice); border-radius: 9999px; } .dark ::-webkit-scrollbar-thumb { background-color: var(--nord-graphite); } + +/* Global so it reaches both the PIN input component and the mobile PIN dots */ +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 20%, 60% { transform: translateX(-6px); } + 40%, 80% { transform: translateX(6px); } +} +.animate-shake { animation: shake 0.5s ease-in-out; } diff --git a/app/components/attachment/ImageGrid.vue b/app/components/attachment/ImageGrid.vue index db2c813..b52b796 100644 --- a/app/components/attachment/ImageGrid.vue +++ b/app/components/attachment/ImageGrid.vue @@ -11,7 +11,7 @@ class="w-full object-cover cursor-zoom-in" :class="visibleAttachments.length === 1 ? 'max-h-56' : 'h-32'" loading="lazy" - @error="(e) => (e.target as HTMLImageElement).src = `/api/files/${att.id}`" + @error="(e) => fallbackToOriginal(e, att.id)" @click.stop="openLightbox(idx)" > @@ -65,6 +65,14 @@