diff --git a/.env.example b/.env.example index a7d36c8..f4555ea 100644 --- a/.env.example +++ b/.env.example @@ -51,3 +51,6 @@ AUTO_MIGRATE=true # hCaptcha keys, leave empty if not using it PUBLIC_HCAPTCHA_KEY= HCAPTCHA_SECRET= + +# Use Valkey for cache, leave empty to use in-memory cache +VALKEY_URI= \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f0bd407..2d208b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,14 +8,17 @@ "name": "icysso", "version": "0.0.1", "dependencies": { + "@keyv/valkey": "^1.0.3", "@sveltejs/adapter-node": "^5.2.12", "bcryptjs": "^3.0.2", + "cache-manager": "^6.4.0", + "cacheable": "^1.8.8", "chalk": "^5.4.1", "cropperjs": "^1.6.2", "dotenv": "^16.4.7", "drizzle-orm": "^0.39.3", "image-size": "^1.2.0", - "jose": "^5.10.0", + "jose": "^6.0.4", "mime-types": "^2.1.35", "mysql2": "^3.12.0", "nodemailer": "^6.10.0", @@ -1135,6 +1138,12 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@iovalkey/commands": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@iovalkey/commands/-/commands-0.1.0.tgz", + "integrity": "sha512-/B9W4qKSSITDii5nkBCHyPkIkAi+ealUtr1oqBJsLxjSRLka4pxun2VvMNSmcwgAMxgXtQfl0qRv7TE+udPJzg==", + "license": "MIT" + }, "node_modules/@isaacs/ttlcache": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", @@ -1187,6 +1196,27 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@keyv/serialize": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz", + "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3" + } + }, + "node_modules/@keyv/valkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@keyv/valkey/-/valkey-1.0.3.tgz", + "integrity": "sha512-QCC6OzI3K1PjAvcj9n5CB+hy8M+hl8PxLkJQWs0DAOP+4XXuJPPRdQqf/jPm7zunrZl5+G+JL8WGsv4Kq0TeoQ==", + "license": "MIT", + "dependencies": { + "iovalkey": "^0.3.1" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/@noble/ciphers": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", @@ -2305,6 +2335,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/bcryptjs": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz", @@ -2343,12 +2393,73 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/cache-manager": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-6.4.0.tgz", + "integrity": "sha512-eUmPyVqQYzWCt7hx1QrYzQ7oC3MGKM1etxxe8zuq1o7IB4NzdBeWcUGDSWYahaI8fkd538SEZRGadyZWQfvOzQ==", + "license": "MIT", + "dependencies": { + "keyv": "^5.2.3" + } + }, + "node_modules/cache-manager/node_modules/keyv": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.2.3.tgz", + "integrity": "sha512-AGKecUfzrowabUv0bH1RIR5Vf7w+l4S3xtQAypKaUpTdIR1EbrAcTxHCrpo9Q+IWeUlFE2palRtgIQcgm+PQJw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.0.2" + } + }, + "node_modules/cacheable": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.8.8.tgz", + "integrity": "sha512-OE1/jlarWxROUIpd0qGBSKFLkNsotY8pt4GeiVErUYh/NUeTNrT+SBksUgllQv4m6a0W/VZsLuiHb88maavqEw==", + "license": "MIT", + "dependencies": { + "hookified": "^1.7.0", + "keyv": "^5.2.3" + } + }, + "node_modules/cacheable/node_modules/keyv": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.2.3.tgz", + "integrity": "sha512-AGKecUfzrowabUv0bH1RIR5Vf7w+l4S3xtQAypKaUpTdIR1EbrAcTxHCrpo9Q+IWeUlFE2palRtgIQcgm+PQJw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.0.2" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2414,6 +2525,15 @@ "node": ">=6" } }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3767,6 +3887,12 @@ "node": ">= 0.4" } }, + "node_modules/hookified": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.7.1.tgz", + "integrity": "sha512-OXcdHsXeOiD7OJ5zvWj8Oy/6RCdLwntAX+wUrfemNcMGn6sux4xbEHi2QXwqePYhjQ/yvxxq2MvCRirdlHscBw==", + "license": "MIT" + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -3778,6 +3904,26 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -3842,6 +3988,26 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/iovalkey": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/iovalkey/-/iovalkey-0.3.1.tgz", + "integrity": "sha512-pSmFj/ZDFLP8AzqIAMpNJArhHYNeyqIwfcUULwZv8g6y3eaUGrlnlT7QXLrJAp0yiGCAqe1hPA33x/h5opNP9w==", + "license": "MIT", + "dependencies": { + "@iovalkey/commands": "^0.1.0", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", @@ -3924,9 +4090,9 @@ "license": "ISC" }, "node_modules/jose": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", - "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.0.4.tgz", + "integrity": "sha512-GTWKmlIq0xs50pnwa7q+8eG0ZLR1DVcHxa75s2VArJcriBd+YEC18uK/kbTObF3gMXgqBeZXAoZA9eMLhPjSpQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -4032,6 +4198,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -4592,6 +4770,27 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4833,6 +5032,12 @@ "node": ">= 0.6" } }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "license": "MIT" + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", diff --git a/package.json b/package.json index 732daa1..415dde0 100644 --- a/package.json +++ b/package.json @@ -37,14 +37,17 @@ }, "type": "module", "dependencies": { + "@keyv/valkey": "^1.0.3", "@sveltejs/adapter-node": "^5.2.12", "bcryptjs": "^3.0.2", + "cache-manager": "^6.4.0", + "cacheable": "^1.8.8", "chalk": "^5.4.1", "cropperjs": "^1.6.2", "dotenv": "^16.4.7", "drizzle-orm": "^0.39.3", "image-size": "^1.2.0", - "jose": "^5.10.0", + "jose": "^6.0.4", "mime-types": "^2.1.35", "mysql2": "^3.12.0", "nodemailer": "^6.10.0", diff --git a/src/colors.css b/src/colors.css index f9b35e0..e41afec 100644 --- a/src/colors.css +++ b/src/colors.css @@ -6,7 +6,9 @@ --in-background-image: none; --in-normalized-background: #cceaff; --in-container-background: #f1faff; + --in-inner-container-background: #b7e5ff; --in-container-shadow: 0px 0px 16px 0px rgba(0, 0, 0, 0.15); + --in-alert-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.45); --in-text-color: #000000; --in-link-color: #000000; @@ -71,6 +73,7 @@ html[theme-base='dark'] { --in-background-image: url('/background.webp'); --in-normalized-background: #000; --in-container-background: transparent; + --in-inner-container-background: #ffffff15; --in-text-color: #fff; --in-link-color: #fff; diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 2443ebf..2b5feb0 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,7 +1,9 @@ import { env } from '$env/dynamic/private'; +import { CacheBackend } from '$lib/server/cache-backend'; import { csrf } from '$lib/server/csrf'; import { DB } from '$lib/server/drizzle'; import { runSeeds } from '$lib/server/drizzle/seeds'; +import { FileBackend } from '$lib/server/file-backend'; import { JWT } from '$lib/server/jwt'; import { Logger, LogLevel } from '$lib/server/logger'; import type { ThemeModeType } from '$lib/theme-mode'; @@ -12,6 +14,9 @@ import { handleSession } from 'svelte-kit-cookie-session'; const { AUTO_MIGRATE, SESSION_SECRET, SESSION_SECURE, NODE_ENV } = env; +await FileBackend.init(); +await CacheBackend.init(); + // Set logger to debug mode if (NODE_ENV === 'development') { Logger.setLogLevel(LogLevel.DEBUG); diff --git a/src/lib/components/Alert.svelte b/src/lib/components/Alert.svelte index 56df0e7..a057e82 100644 --- a/src/lib/components/Alert.svelte +++ b/src/lib/components/Alert.svelte @@ -1,21 +1,19 @@
{@render children?.()}
- {#if dismissable}{/if} + {#if dismissable}{/if}