From bd2e82bc3640b6afc3176e88d5431bcd79d8ce7a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 4 Oct 2024 05:53:19 +0200 Subject: [PATCH] chore: migrate from lucia to nuxt-auth-utils (#2546) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### ๐Ÿ”— Linked issue ### ๐Ÿ“š Description Reasons: - Lucia mainly handles session management, but for this nuxt has h3 - nuxt-auth provides better integration with nuxt - nuxt-auth provides passkey etc - Lucia has some conventions that make it hard to work around it (especially the whole "prisma adapter" thing, that is not quite working well) - doesn't get really better with v4 see https://github.com/JabRef/JabRefOnline/pull/2335 --- .github/scripts/README.md | 2 +- .github/scripts/deploy.py | 4 +- .github/workflows/ci.yml | 1 + .github/workflows/deploy-preview.yml | 1 - .github/workflows/deploy.yml | 2 +- auth.d.ts | 33 + config.ts | 6 +- middleware/authenticated.global.ts | 28 +- nuxt.config.ts | 7 + package.json | 6 +- pages/user/login.vue | 45 +- pnpm-lock.yaml | 699 ++++++++++++------ renovate.json5 | 1 - server/api/index.ts | 4 - server/context.ts | 73 +- .../migrations/20241002152302_/migration.sql | 15 + server/database/schema.prisma | 11 +- server/database/seed.ts | 11 +- server/middleware/validateSession.ts | 39 + server/plugins/tsyringe.ts | 9 + server/user/auth.service.ts | 199 +++-- server/user/e2e.test.ts | 31 +- server/user/resolvers.ts | 35 +- server/utils/crypto.spec.ts | 8 +- server/utils/crypto.ts | 52 +- server/utils/luciaMiddleware.ts | 20 - shims-lucia.d.ts | 14 - test/apollo.server.ts | 3 + 28 files changed, 874 insertions(+), 485 deletions(-) create mode 100644 auth.d.ts create mode 100644 server/database/migrations/20241002152302_/migration.sql create mode 100644 server/middleware/validateSession.ts create mode 100644 server/plugins/tsyringe.ts delete mode 100644 server/utils/luciaMiddleware.ts delete mode 100644 shims-lucia.d.ts diff --git a/.github/scripts/README.md b/.github/scripts/README.md index add105b4a..e2cba50bc 100644 --- a/.github/scripts/README.md +++ b/.github/scripts/README.md @@ -9,6 +9,6 @@ pip install azure-identity azure-mgmt-web azure-mgmt-storage azure-mgmt-applicat az login export SUBSCRIPTION_ID=<...> export DATABASE_URL=<...> -export AZURE_SESSION_SECRET=<...> +export NUXT_SESSION_PASSWORD=<...> python3 .github/scripts/deploy.py --env dev -v ``` diff --git a/.github/scripts/deploy.py b/.github/scripts/deploy.py index d0ad31cad..61607d56f 100644 --- a/.github/scripts/deploy.py +++ b/.github/scripts/deploy.py @@ -36,7 +36,7 @@ def main(environment_name: str, verbose: bool = False): APP_INSIGHTS_NAME = "jabref-online" REDIS_NAME = "jabref" DATABASE_URL = os.environ.get("DATABASE_URL", "") - SESSION_SECRET = os.environ.get("AZURE_SESSION_SECRET", "") + SESSION_SECRET = os.environ.get("NUXT_SESSION_PASSWORD", "") GITHUB_REPO_TOKEN = os.environ.get("GITHUB_REPO_TOKEN", "") function_app_name = "jabref-function-" + environment_name @@ -132,7 +132,7 @@ def main(environment_name: str, verbose: bool = False): "name": "REDIS_PASSWORD", "value": redis_keys.primary_key, }, - {"name": "SESSION_SECRET_PRIMARY", "value": SESSION_SECRET}, + {"name": "NUXT_SESSION_PASSWORD", "value": SESSION_SECRET}, {"name": "GITHUB_REPO_TOKEN", "value": GITHUB_REPO_TOKEN}, # Disable indexing of non-production sites # https://nuxtseo.com/robots/guides/disable-indexing#preview-staging-testing-environments diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 794809933..ffb1b067d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,6 +82,7 @@ jobs: env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/jabref?schema=public GITHUB_REPO_TOKEN: ${{ secrets.GITHUBS_REPO_TOKEN }} + NUXT_SESSION_PASSWORD: somerandompasswordNxFHaqCSPpBe6n5kRz2dru4hJ7K9bjgEtmsV8QAT3MDXcUfWGL steps: - name: Checkout diff --git a/.github/workflows/deploy-preview.yml b/.github/workflows/deploy-preview.yml index 22b244213..2c70beadc 100644 --- a/.github/workflows/deploy-preview.yml +++ b/.github/workflows/deploy-preview.yml @@ -107,7 +107,6 @@ jobs: python .github\scripts\deploy.py --env $env:PREVIEW_NAME env: SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - AZURE_SESSION_SECRET: ${{ secrets.AZURE_SESSION_SECRET }} - name: Deploy Function App run: | diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c330d24d6..c2d4eb45d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -36,6 +36,7 @@ jobs: env: DATABASE_URL: ${{ matrix.environment == 'Test' && secrets.AZURE_TEST_DATABASE_URL || secrets.AZURE_DATABASE_URL }} GITHUB_REPO_TOKEN: ${{ secrets.GITHUBS_REPO_TOKEN }} + NUXT_SESSION_PASSWORD: ${{ secrets.AZURE_SESSION_SECRET }} steps: - name: Checkout @@ -91,7 +92,6 @@ jobs: python .github\scripts\deploy.py --env ${{ matrix.deployment_environment }} env: SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - AZURE_SESSION_SECRET: ${{ secrets.AZURE_SESSION_SECRET }} - name: Deploy Function App run: | diff --git a/auth.d.ts b/auth.d.ts new file mode 100644 index 000000000..f0b294e64 --- /dev/null +++ b/auth.d.ts @@ -0,0 +1,33 @@ +declare module '#auth-utils' { + /** + * The public information about a user stored in the session + */ + interface User { + id: string + } + + /** + * The public information about the current session + */ + interface UserSession { + /** + * The secure data associated with the session, only accessible on the server + */ + server: ServerSessionData + } + + /** + * Private information about the current session, only accessible on the server + * (exposed in an encrypted form to the client) + */ + interface SecureSessionData {} + + /** + * The data stored for the session on the server + */ + interface ServerSessionData { + lastActive: Date + } +} + +export {} diff --git a/config.ts b/config.ts index 2b3296768..e4565b20d 100644 --- a/config.ts +++ b/config.ts @@ -63,8 +63,7 @@ export interface Config { } emailClient?: string session: { - primarySecret: string - secondarySecret: string + secret: string } githubRepoToken: string public: { @@ -85,8 +84,7 @@ export function constructConfig() { }, emailClient: process.env.EMAIL_CLIENT, session: { - primarySecret: process.env.SESSION_SECRET_PRIMARY ?? 'session_secret', - secondarySecret: process.env.SESSION_SECRET_SECONDARY ?? 'session_secret', + secret: process.env.NUXT_SESSION_PASSWORD ?? 'session_secret', }, githubRepoToken: process.env.GITHUB_REPO_TOKEN ?? 'UNDEFINED', public: { diff --git a/middleware/authenticated.global.ts b/middleware/authenticated.global.ts index f2aa3bf89..195bf3d04 100644 --- a/middleware/authenticated.global.ts +++ b/middleware/authenticated.global.ts @@ -1,32 +1,10 @@ -import { gql } from '@apollo/client/core' - /** * Plugin that adds checks if the user is logged in, and redirects her to the login page if not. */ export default defineNuxtRouteMiddleware(async (to, _from) => { if (to.matched.some((record) => record.meta.requiresAuth)) { - const { $apolloClient } = useNuxtApp() - try { - // TODO: Only call this if we have a session cookie? - const response = await $apolloClient.query({ - query: gql(/* GraphQL */ ` - query CheckLoggedIn { - me { - id - } - } - `), - }) - - // If the user is not authenticated, then redirect - if ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - response.data?.me?.id === undefined || - response.errors !== undefined - ) { - return redirectToLogin() - } - } catch { + const { loggedIn } = useUserSession() + if (!loggedIn.value) { return redirectToLogin() } } @@ -34,5 +12,5 @@ export default defineNuxtRouteMiddleware(async (to, _from) => { async function redirectToLogin() { // TODO: Remember the intended url by appending something like ?redirect=context.route.fullPath - return await navigateTo({ path: '/user/login' }) + return await navigateTo('/user/login') } diff --git a/nuxt.config.ts b/nuxt.config.ts index 0bfbce017..abb1ac961 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -152,6 +152,9 @@ export default defineNuxtConfig({ // Preset for configuring SEO // https://nuxtseo.com/nuxt-seo '@nuxtjs/seo', + // Add authentication support + // https://github.com/atinux/nuxt-auth-utils + 'nuxt-auth-utils', ], /* @@ -238,6 +241,10 @@ export default defineNuxtConfig({ define: { 'process.env': {}, }, + optimizeDeps: { + // Workaround for https://github.com/nuxt/nuxt/issues/27544 + exclude: ['vee-validate'], + }, server: { // Configure vite for HMR with Gitpod // Taken from https://github.com/vitejs/vite/issues/1653#issuecomment-1079322770 diff --git a/package.json b/package.json index 8781a1881..940249a84 100644 --- a/package.json +++ b/package.json @@ -49,8 +49,6 @@ "@azure/communication-email": "1.0.0", "@graphql-tools/schema": "10.0.6", "@he-tree/vue": "2.8.7", - "@lucia-auth/adapter-prisma": "3.0.2", - "@lucia-auth/adapter-session-unstorage": "2.1.0", "@nuxtjs/tailwindcss": "6.12.1", "@pinia/nuxt": "0.5.3", "@popperjs/core": "2.11.8", @@ -69,7 +67,6 @@ "ioredis": "5.4.1", "json-bigint-patch": "0.0.8", "lodash": "4.17.21", - "lucia": "2.7.7", "pinia": "2.2.1", "reflect-metadata": "0.2.2", "ts-loader": "9.5.1", @@ -83,6 +80,7 @@ "zod": "3.23.8" }, "devDependencies": { + "@adonisjs/hash": "^9.0.5", "@apollo/utils.keyvaluecache": "3.1.0", "@azure/core-rest-pipeline": "1.17.0", "@azure/static-web-apps-cli": "2.0.1", @@ -125,6 +123,7 @@ "@vue/compiler-sfc": "3.5.10", "@vue/runtime-dom": "3.5.10", "@vue/test-utils": "2.4.6", + "argon2": "^0.41.1", "chalk": "5.3.0", "chromatic": "11.11.0", "concurrently": "9.0.1", @@ -143,6 +142,7 @@ "mount-vue-component": "0.10.2", "naive-ui": "2.40.1", "nuxt": "3.12.4", + "nuxt-auth-utils": "^0.4.2", "nuxt-graphql-server": "3.1.4", "nuxt-icon": "0.6.10", "oxlint": "0.9.9", diff --git a/pages/user/login.vue b/pages/user/login.vue index 4be8d1733..4eb0d6c10 100644 --- a/pages/user/login.vue +++ b/pages/user/login.vue @@ -34,7 +34,8 @@ :validation-status="errors.email ? 'error' : undefined" > @@ -45,7 +46,8 @@ :validation-status="errors.password ? 'error' : undefined" > @@ -101,17 +103,15 @@ definePageMeta({ layout: false }) // TODO: Automatically go to home if already logged in // middleware: 'guest', -const { handleSubmit, errors, values } = useForm({ +const { handleSubmit, errors, defineField } = useForm({ validationSchema: toTypedSchema(LoginInputSchema), }) +const [email, emailAttrs] = defineField('email') +const [password, passwordAttrs] = defineField('password') const otherError = ref('') -const { - mutate: loginUser, - onDone, - error: graphqlError, -} = useMutation( +const { mutate: loginUser, error: graphqlError } = useMutation( gql(/* GraphQL */ ` mutation Login($input: LoginInput!) { login(input: $input) { @@ -140,23 +140,28 @@ const { }, }, ) -onDone((result) => { - if (result.data?.login?.__typename === 'UserReturned') { - void navigateTo({ name: 'dashboard' }) - } else { - otherError.value = - result.data?.login?.__typename === 'InputValidationProblem' && - result.data.login.problems[0] - ? result.data.login.problems[0].message - : 'Unknown error' - } -}) const error = computed(() => graphqlError.value ?? otherError.value) // TODO: Implement remember login const rememberLogin = ref(false) const onSubmit = handleSubmit(async (values) => { - await loginUser({ input: values }) + // Reset errors + otherError.value = '' + + const result = await loginUser({ input: values }) + if (result?.data?.login?.__typename === 'UserReturned') { + // Update user info + const { fetch } = useUserSession() + await fetch() + + await navigateTo({ name: 'dashboard' }) + } else { + otherError.value = + result?.data?.login?.__typename === 'InputValidationProblem' && + result.data.login.problems[0] + ? result.data.login.problems[0].message + : 'Unknown error' + } }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f222f1379..8be0bd5e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,12 +37,6 @@ importers: '@he-tree/vue': specifier: 2.8.7 version: 2.8.7(vue@3.5.10(typescript@5.5.4)) - '@lucia-auth/adapter-prisma': - specifier: 3.0.2 - version: 3.0.2(@prisma/client@5.20.0(prisma@5.20.0))(lucia@2.7.7) - '@lucia-auth/adapter-session-unstorage': - specifier: 2.1.0 - version: 2.1.0(lucia@2.7.7)(unstorage@1.12.0(@azure/identity@4.4.1)(ioredis@5.4.1)) '@nuxtjs/tailwindcss': specifier: 6.12.1 version: 6.12.1(magicast@0.3.4)(rollup@4.20.0)(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)) @@ -97,9 +91,6 @@ importers: lodash: specifier: 4.17.21 version: 4.17.21 - lucia: - specifier: 2.7.7 - version: 2.7.7 pinia: specifier: 2.2.1 version: 2.2.1(typescript@5.5.4)(vue@3.5.10(typescript@5.5.4)) @@ -134,6 +125,9 @@ importers: specifier: 3.23.8 version: 3.23.8 devDependencies: + '@adonisjs/hash': + specifier: ^9.0.5 + version: 9.0.5(argon2@0.41.1) '@apollo/utils.keyvaluecache': specifier: 3.1.0 version: 3.1.0 @@ -260,6 +254,9 @@ importers: '@vue/test-utils': specifier: 2.4.6 version: 2.4.6 + argon2: + specifier: ^0.41.1 + version: 0.41.1 chalk: specifier: 5.3.0 version: 5.3.0 @@ -314,6 +311,9 @@ importers: nuxt: specifier: 3.12.4 version: 3.12.4(@azure/identity@4.4.1)(@parcel/watcher@2.4.1)(@types/node@20.16.10)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.20.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.0(@types/node@20.16.10)(terser@5.31.6))(vue-tsc@2.1.6(typescript@5.5.4)) + nuxt-auth-utils: + specifier: ^0.4.2 + version: 0.4.2(argon2@0.41.1)(magicast@0.3.4)(rollup@4.20.0)(webpack-sources@3.2.3) nuxt-graphql-server: specifier: 3.1.4 version: 3.1.4(graphql@16.9.0)(magicast@0.3.4)(rollup@4.20.0) @@ -340,7 +340,7 @@ importers: version: 7.6.20 storybook-vue-addon: specifier: 0.6.1 - version: 0.6.1(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.20.0))(@nuxt/schema@3.12.4(rollup@4.20.0))(esbuild@0.18.20)(rollup@4.20.0)(typescript@5.5.4)(vite@5.4.0(@types/node@20.16.10)(terser@5.31.6))(vue-tsc@2.1.6(typescript@5.5.4))(vue@3.5.10(typescript@5.5.4))(webpack@5.93.0(esbuild@0.18.20)) + version: 0.6.1(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.20.0))(@nuxt/schema@3.13.2(rollup@4.20.0)(webpack-sources@3.2.3))(esbuild@0.18.20)(rollup@4.20.0)(typescript@5.5.4)(vite@5.4.0(@types/node@20.16.10)(terser@5.31.6))(vue-tsc@2.1.6(typescript@5.5.4))(vue@3.5.10(typescript@5.5.4))(webpack@5.93.0(esbuild@0.18.20)) tailwindcss: specifier: 3.4.13 version: 3.4.13(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.5.4)) @@ -377,6 +377,18 @@ packages: '@actions/http-client@2.2.1': resolution: {integrity: sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==} + '@adonisjs/hash@9.0.5': + resolution: {integrity: sha512-oY8PafBrdGsr5UY8cAzzxPCtehZDW7KsPcI47dZpjydOdL/PQrT4liX+cGujL6mSbi3JEgQLBgBs/+SlPFvCrg==, tarball: https://registry.npmjs.org/@adonisjs/hash/-/hash-9.0.5.tgz} + engines: {node: '>=20.6.0'} + peerDependencies: + argon2: ^0.31.2 || ^0.41.0 + bcrypt: ^5.1.1 + peerDependenciesMeta: + argon2: + optional: true + bcrypt: + optional: true + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -1293,7 +1305,7 @@ packages: engines: {node: '>=16.13'} '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==, tarball: https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz} engines: {node: '>=0.1.90'} '@cspotcode/source-map-support@0.8.1': @@ -1342,553 +1354,553 @@ packages: engines: {node: '>=18.0.0'} '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [aix] '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [aix] '@esbuild/aix-ppc64@0.23.0': - resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz} engines: {node: '>=12'} cpu: [arm64] os: [android] '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz} engines: {node: '>=12'} cpu: [arm64] os: [android] '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [android] '@esbuild/android-arm64@0.23.0': - resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} + resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [android] '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz} engines: {node: '>=12'} cpu: [arm] os: [android] '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz} engines: {node: '>=12'} cpu: [arm] os: [android] '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm] os: [android] '@esbuild/android-arm@0.23.0': - resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} + resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm] os: [android] '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [android] '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [android] '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [android] '@esbuild/android-x64@0.23.0': - resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz} engines: {node: '>=12'} cpu: [arm64] os: [darwin] '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz} engines: {node: '>=12'} cpu: [arm64] os: [darwin] '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [darwin] '@esbuild/darwin-arm64@0.23.0': - resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} + resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [darwin] '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [darwin] '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [darwin] '@esbuild/darwin-x64@0.23.0': - resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-arm64@0.23.0': - resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} + resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [freebsd] '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [freebsd] '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [freebsd] '@esbuild/freebsd-x64@0.23.0': - resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz} engines: {node: '>=12'} cpu: [arm64] os: [linux] '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz} engines: {node: '>=12'} cpu: [arm64] os: [linux] '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [linux] '@esbuild/linux-arm64@0.23.0': - resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} + resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz} engines: {node: '>=12'} cpu: [arm] os: [linux] '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz} engines: {node: '>=12'} cpu: [arm] os: [linux] '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm] os: [linux] '@esbuild/linux-arm@0.23.0': - resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} + resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz} engines: {node: '>=12'} cpu: [ia32] os: [linux] '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz} engines: {node: '>=12'} cpu: [ia32] os: [linux] '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz} engines: {node: '>=12'} cpu: [ia32] os: [linux] '@esbuild/linux-ia32@0.23.0': - resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} + resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz} engines: {node: '>=18'} cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz} engines: {node: '>=12'} cpu: [loong64] os: [linux] '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz} engines: {node: '>=12'} cpu: [loong64] os: [linux] '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz} engines: {node: '>=12'} cpu: [loong64] os: [linux] '@esbuild/linux-loong64@0.23.0': - resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} + resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz} engines: {node: '>=18'} cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz} engines: {node: '>=12'} cpu: [mips64el] os: [linux] '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz} engines: {node: '>=12'} cpu: [mips64el] os: [linux] '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz} engines: {node: '>=12'} cpu: [mips64el] os: [linux] '@esbuild/linux-mips64el@0.23.0': - resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} + resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz} engines: {node: '>=18'} cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [linux] '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [linux] '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [linux] '@esbuild/linux-ppc64@0.23.0': - resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} + resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz} engines: {node: '>=12'} cpu: [riscv64] os: [linux] '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz} engines: {node: '>=12'} cpu: [riscv64] os: [linux] '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz} engines: {node: '>=12'} cpu: [riscv64] os: [linux] '@esbuild/linux-riscv64@0.23.0': - resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} + resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz} engines: {node: '>=18'} cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz} engines: {node: '>=12'} cpu: [s390x] os: [linux] '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz} engines: {node: '>=12'} cpu: [s390x] os: [linux] '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz} engines: {node: '>=12'} cpu: [s390x] os: [linux] '@esbuild/linux-s390x@0.23.0': - resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} + resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz} engines: {node: '>=18'} cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [linux] '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [linux] '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [linux] '@esbuild/linux-x64@0.23.0': - resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} + resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [linux] '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [netbsd] '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [netbsd] '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [netbsd] '@esbuild/netbsd-x64@0.23.0': - resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} + resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [netbsd] '@esbuild/openbsd-arm64@0.23.0': - resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==, tarball: https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [openbsd] '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [openbsd] '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [openbsd] '@esbuild/openbsd-x64@0.23.0': - resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} + resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [openbsd] '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [sunos] '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [sunos] '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [sunos] '@esbuild/sunos-x64@0.23.0': - resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz} engines: {node: '>=12'} cpu: [arm64] os: [win32] '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz} engines: {node: '>=12'} cpu: [arm64] os: [win32] '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [win32] '@esbuild/win32-arm64@0.23.0': - resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} + resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz} engines: {node: '>=18'} cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz} engines: {node: '>=12'} cpu: [ia32] os: [win32] '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz} engines: {node: '>=12'} cpu: [ia32] os: [win32] '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz} engines: {node: '>=12'} cpu: [ia32] os: [win32] '@esbuild/win32-ia32@0.23.0': - resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} + resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz} engines: {node: '>=18'} cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz} engines: {node: '>=12'} cpu: [x64] os: [win32] '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz} engines: {node: '>=12'} cpu: [x64] os: [win32] '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [win32] '@esbuild/win32-x64@0.23.0': - resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -2455,7 +2467,7 @@ packages: resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} '@he-tree/dnd-utils@0.1.0-alpha.4': - resolution: {integrity: sha512-DuxkFOQ8eztoHrX1/VelqOnQphQbRszemfMKSKlAEEhVjqR/IkaOE2QSRlAdj6OC6AfMvHDPvIZOiEPFwP6/ZQ==} + resolution: {integrity: sha512-DuxkFOQ8eztoHrX1/VelqOnQphQbRszemfMKSKlAEEhVjqR/IkaOE2QSRlAdj6OC6AfMvHDPvIZOiEPFwP6/ZQ==, tarball: https://registry.npmjs.org/@he-tree/dnd-utils/-/dnd-utils-0.1.0-alpha.4.tgz} '@he-tree/tree-utils@0.1.0-alpha.6': resolution: {integrity: sha512-TIH1iIRLpn3sjd4EuIfKQzFd6ToY8GLYk3i5bfK1njCW7lBBDHLqSyK0mlJPbCPk4PfkZBC4K+sMcYyH4hokyg==} @@ -2546,17 +2558,9 @@ packages: '@kwsites/promise-deferred@1.1.1': resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - '@lucia-auth/adapter-prisma@3.0.2': - resolution: {integrity: sha512-EyJWZene1/zasPwPctv8wwNErZt5mwwm5JATbhg+kXr3R8pbC7lJfVzDTAeeFClVH5k/FywRcsBl3JkPaNIcow==} - peerDependencies: - '@prisma/client': ^4.2.0 || ^5.0.0 - lucia: ^2.0.0 - - '@lucia-auth/adapter-session-unstorage@2.1.0': - resolution: {integrity: sha512-ItK7urZhLZv7UO99BcODjRhSAv58UPc+KQAmnkSvri2WBc22vFEjnjd/oWp3CZPdbbrJkuTvsuhFXH1ySBfOLg==} - peerDependencies: - lucia: ^2.0.0 - unstorage: ^1.9.0 + '@lukeed/ms@2.0.2': + resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==, tarball: https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz} + engines: {node: '>=8'} '@mapbox/node-pre-gyp@1.0.11': resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} @@ -2614,10 +2618,18 @@ packages: resolution: {integrity: sha512-aNRD1ylzijY0oYolldNcZJXVyxdGzNTl+Xd0UYyFQCu9f4wqUZqQ9l+b7arCEzchr96pMK0xdpvLcS3xo1wDcw==} engines: {node: ^14.18.0 || >=16.10.0} + '@nuxt/kit@3.13.2': + resolution: {integrity: sha512-KvRw21zU//wdz25IeE1E5m/aFSzhJloBRAQtv+evcFeZvuroIxpIQuUqhbzuwznaUwpiWbmwlcsp5uOWmi4vwA==, tarball: https://registry.npmjs.org/@nuxt/kit/-/kit-3.13.2.tgz} + engines: {node: ^14.18.0 || >=16.10.0} + '@nuxt/schema@3.12.4': resolution: {integrity: sha512-H7FwBV4ChssMaeiLyPdVLOLUa0326ebp3pNbJfGgFt7rSoKh1MmgjorecA8JMxOQZziy3w6EELf4+5cgLh/F1w==} engines: {node: ^14.18.0 || >=16.10.0} + '@nuxt/schema@3.13.2': + resolution: {integrity: sha512-CCZgpm+MkqtOMDEgF9SWgGPBXlQ01hV/6+2reDEpJuqFPGzV8HYKPBcIFvn7/z5ahtgutHLzjP71Na+hYcqSpw==, tarball: https://registry.npmjs.org/@nuxt/schema/-/schema-3.13.2.tgz} + engines: {node: ^14.18.0 || >=16.10.0} + '@nuxt/telemetry@2.5.4': resolution: {integrity: sha512-KH6wxzsNys69daSO0xUv0LEBAfhwwjK1M+0Cdi1/vxmifCslMIY7lN11B4eywSfscbyVPAYJvANyc7XiVPImBQ==} hasBin: true @@ -2699,95 +2711,95 @@ packages: resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} '@oxlint/darwin-arm64@0.9.9': - resolution: {integrity: sha512-My2KfUByjRl49p0rr/Glx9Y/hjney1uFk0JXNjwHqYToHqO9fY/IZ6XT1fdw9sX+1hdpq9bmj88rnkpvu0/cRw==} + resolution: {integrity: sha512-My2KfUByjRl49p0rr/Glx9Y/hjney1uFk0JXNjwHqYToHqO9fY/IZ6XT1fdw9sX+1hdpq9bmj88rnkpvu0/cRw==, tarball: https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-0.9.9.tgz} cpu: [arm64] os: [darwin] '@oxlint/darwin-x64@0.9.9': - resolution: {integrity: sha512-k0r0t+MAzrk8yWs0nxyD9Skfb+Ozmu6HRMTJIsUTLV4AKMt9CZBlLVS0OXzXHi72AOHz3UUve5rXxevVVY9lHQ==} + resolution: {integrity: sha512-k0r0t+MAzrk8yWs0nxyD9Skfb+Ozmu6HRMTJIsUTLV4AKMt9CZBlLVS0OXzXHi72AOHz3UUve5rXxevVVY9lHQ==, tarball: https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-0.9.9.tgz} cpu: [x64] os: [darwin] '@oxlint/linux-arm64-gnu@0.9.9': - resolution: {integrity: sha512-atiotr1pN3rr0i7Ww3SpOEOvkFex97S8GwYmiTlSng0kp+FSIZD6Kjlr9k3oayf9RZUDRuAE4WptwV1KYLvIDw==} + resolution: {integrity: sha512-atiotr1pN3rr0i7Ww3SpOEOvkFex97S8GwYmiTlSng0kp+FSIZD6Kjlr9k3oayf9RZUDRuAE4WptwV1KYLvIDw==, tarball: https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-0.9.9.tgz} cpu: [arm64] os: [linux] '@oxlint/linux-arm64-musl@0.9.9': - resolution: {integrity: sha512-vmd6Eog6WiudMTT0Fa8u5N+47caaWF2KVUHOSEV/d/WauVx+ZOR9z1LEM+54AZwn3Z2TbtFOJDiz7iDukZPbfw==} + resolution: {integrity: sha512-vmd6Eog6WiudMTT0Fa8u5N+47caaWF2KVUHOSEV/d/WauVx+ZOR9z1LEM+54AZwn3Z2TbtFOJDiz7iDukZPbfw==, tarball: https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-0.9.9.tgz} cpu: [arm64] os: [linux] '@oxlint/linux-x64-gnu@0.9.9': - resolution: {integrity: sha512-AUmSRerK4VXIMcTYYk25KGoOU2/z+NGItUhI6nJgMFktrbF8MUD6hlf3vaQZNle454z7FDJNSjARM0bB+xpBiQ==} + resolution: {integrity: sha512-AUmSRerK4VXIMcTYYk25KGoOU2/z+NGItUhI6nJgMFktrbF8MUD6hlf3vaQZNle454z7FDJNSjARM0bB+xpBiQ==, tarball: https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-0.9.9.tgz} cpu: [x64] os: [linux] '@oxlint/linux-x64-musl@0.9.9': - resolution: {integrity: sha512-jQYIx5KUYbpXbXBFPgIwRPLSm3AO5wa+32BQYASIOCPcsPywV+HJKbQpzmWqXDYel6hrifmIxspgxHhGMlHJ1Q==} + resolution: {integrity: sha512-jQYIx5KUYbpXbXBFPgIwRPLSm3AO5wa+32BQYASIOCPcsPywV+HJKbQpzmWqXDYel6hrifmIxspgxHhGMlHJ1Q==, tarball: https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-0.9.9.tgz} cpu: [x64] os: [linux] '@oxlint/win32-arm64@0.9.9': - resolution: {integrity: sha512-HSOztIKmiivfUAoxGx4qyerYV+aAXGvKbwWf8j4RorAEg2WWBdhVe9XHoSdqgYsOBi1515+YXxXiSRX3F/0xAg==} + resolution: {integrity: sha512-HSOztIKmiivfUAoxGx4qyerYV+aAXGvKbwWf8j4RorAEg2WWBdhVe9XHoSdqgYsOBi1515+YXxXiSRX3F/0xAg==, tarball: https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-0.9.9.tgz} cpu: [arm64] os: [win32] '@oxlint/win32-x64@0.9.9': - resolution: {integrity: sha512-T1/tNxqoYd/MMqi1dhSVzAVL0ZINvXDBEQWm6OCSrrjRM6c9UQydTzsgLWfvm9uHWngcMuRGXhN3F+D6KEYs3w==} + resolution: {integrity: sha512-T1/tNxqoYd/MMqi1dhSVzAVL0ZINvXDBEQWm6OCSrrjRM6c9UQydTzsgLWfvm9uHWngcMuRGXhN3F+D6KEYs3w==, tarball: https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-0.9.9.tgz} cpu: [x64] os: [win32] '@parcel/watcher-android-arm64@2.4.1': - resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==, tarball: https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] '@parcel/watcher-darwin-arm64@2.4.1': - resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==, tarball: https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] '@parcel/watcher-darwin-x64@2.4.1': - resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==, tarball: https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [darwin] '@parcel/watcher-freebsd-x64@2.4.1': - resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==, tarball: https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [freebsd] '@parcel/watcher-linux-arm-glibc@2.4.1': - resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==, tarball: https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] '@parcel/watcher-linux-arm64-glibc@2.4.1': - resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==, tarball: https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] '@parcel/watcher-linux-arm64-musl@2.4.1': - resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==, tarball: https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] '@parcel/watcher-linux-x64-glibc@2.4.1': - resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==, tarball: https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] '@parcel/watcher-linux-x64-musl@2.4.1': - resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==, tarball: https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] @@ -2799,19 +2811,19 @@ packages: - napi-wasm '@parcel/watcher-win32-arm64@2.4.1': - resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==, tarball: https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [win32] '@parcel/watcher-win32-ia32@2.4.1': - resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==, tarball: https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [ia32] os: [win32] '@parcel/watcher-win32-x64@2.4.1': - resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==, tarball: https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz} engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] @@ -2831,11 +2843,15 @@ packages: resolution: {integrity: sha512-BRs5XUAwiyCDQMsVA9IDvDa7UBR9gAvPHgugOeGng3YN6vJ9JYonyDc0lNczErgtCWtucjR5N7VtaonboD/ezg==} engines: {node: '>=10.12.0'} + '@phc/format@1.0.0': + resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==, tarball: https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz} + engines: {node: '>=10'} + '@pinia/nuxt@0.5.3': resolution: {integrity: sha512-AEuHEcaxZdAl73qUOco1TpOGjcmn83nJlYORZ63zhufSCVMj28lPq15ZnfhhofwBh5IjkT/lB7d8Ff958LajDQ==} '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, tarball: https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz} engines: {node: '>=14'} '@pnpm/config.env-replace@1.1.0': @@ -2856,6 +2872,10 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@poppinss/utils@6.8.3': + resolution: {integrity: sha512-YGeH7pIUm9ExONURNH3xN61dBZ0SXgVuPA9E76t7EHeZHXPNrmR8TlbXQaka6kd5n+cpBNcHG4VsVfYf59bZ7g==, tarball: https://registry.npmjs.org/@poppinss/utils/-/utils-6.8.3.tgz} + engines: {node: '>=18.16.0'} + '@prisma/client@5.20.0': resolution: {integrity: sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA==} engines: {node: '>=16.13'} @@ -2917,73 +2937,73 @@ packages: resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} '@resvg/resvg-js-android-arm-eabi@2.6.2': - resolution: {integrity: sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==} + resolution: {integrity: sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==, tarball: https://registry.npmjs.org/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.6.2.tgz} engines: {node: '>= 10'} cpu: [arm] os: [android] '@resvg/resvg-js-android-arm64@2.6.2': - resolution: {integrity: sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ==} + resolution: {integrity: sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ==, tarball: https://registry.npmjs.org/@resvg/resvg-js-android-arm64/-/resvg-js-android-arm64-2.6.2.tgz} engines: {node: '>= 10'} cpu: [arm64] os: [android] '@resvg/resvg-js-darwin-arm64@2.6.2': - resolution: {integrity: sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A==} + resolution: {integrity: sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A==, tarball: https://registry.npmjs.org/@resvg/resvg-js-darwin-arm64/-/resvg-js-darwin-arm64-2.6.2.tgz} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] '@resvg/resvg-js-darwin-x64@2.6.2': - resolution: {integrity: sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw==} + resolution: {integrity: sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw==, tarball: https://registry.npmjs.org/@resvg/resvg-js-darwin-x64/-/resvg-js-darwin-x64-2.6.2.tgz} engines: {node: '>= 10'} cpu: [x64] os: [darwin] '@resvg/resvg-js-linux-arm-gnueabihf@2.6.2': - resolution: {integrity: sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw==} + resolution: {integrity: sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw==, tarball: https://registry.npmjs.org/@resvg/resvg-js-linux-arm-gnueabihf/-/resvg-js-linux-arm-gnueabihf-2.6.2.tgz} engines: {node: '>= 10'} cpu: [arm] os: [linux] '@resvg/resvg-js-linux-arm64-gnu@2.6.2': - resolution: {integrity: sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg==} + resolution: {integrity: sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg==, tarball: https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-gnu/-/resvg-js-linux-arm64-gnu-2.6.2.tgz} engines: {node: '>= 10'} cpu: [arm64] os: [linux] '@resvg/resvg-js-linux-arm64-musl@2.6.2': - resolution: {integrity: sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg==} + resolution: {integrity: sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg==, tarball: https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-musl/-/resvg-js-linux-arm64-musl-2.6.2.tgz} engines: {node: '>= 10'} cpu: [arm64] os: [linux] '@resvg/resvg-js-linux-x64-gnu@2.6.2': - resolution: {integrity: sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw==} + resolution: {integrity: sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw==, tarball: https://registry.npmjs.org/@resvg/resvg-js-linux-x64-gnu/-/resvg-js-linux-x64-gnu-2.6.2.tgz} engines: {node: '>= 10'} cpu: [x64] os: [linux] '@resvg/resvg-js-linux-x64-musl@2.6.2': - resolution: {integrity: sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ==} + resolution: {integrity: sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ==, tarball: https://registry.npmjs.org/@resvg/resvg-js-linux-x64-musl/-/resvg-js-linux-x64-musl-2.6.2.tgz} engines: {node: '>= 10'} cpu: [x64] os: [linux] '@resvg/resvg-js-win32-arm64-msvc@2.6.2': - resolution: {integrity: sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ==} + resolution: {integrity: sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ==, tarball: https://registry.npmjs.org/@resvg/resvg-js-win32-arm64-msvc/-/resvg-js-win32-arm64-msvc-2.6.2.tgz} engines: {node: '>= 10'} cpu: [arm64] os: [win32] '@resvg/resvg-js-win32-ia32-msvc@2.6.2': - resolution: {integrity: sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w==} + resolution: {integrity: sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w==, tarball: https://registry.npmjs.org/@resvg/resvg-js-win32-ia32-msvc/-/resvg-js-win32-ia32-msvc-2.6.2.tgz} engines: {node: '>= 10'} cpu: [ia32] os: [win32] '@resvg/resvg-js-win32-x64-msvc@2.6.2': - resolution: {integrity: sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ==} + resolution: {integrity: sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ==, tarball: https://registry.npmjs.org/@resvg/resvg-js-win32-x64-msvc/-/resvg-js-win32-x64-msvc-2.6.2.tgz} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3072,83 +3092,92 @@ packages: rollup: optional: true + '@rollup/pluginutils@5.1.2': + resolution: {integrity: sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==, tarball: https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.20.0': - resolution: {integrity: sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==} + resolution: {integrity: sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz} cpu: [arm] os: [android] '@rollup/rollup-android-arm64@4.20.0': - resolution: {integrity: sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==} + resolution: {integrity: sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz} cpu: [arm64] os: [android] '@rollup/rollup-darwin-arm64@4.20.0': - resolution: {integrity: sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==} + resolution: {integrity: sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz} cpu: [arm64] os: [darwin] '@rollup/rollup-darwin-x64@4.20.0': - resolution: {integrity: sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==} + resolution: {integrity: sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz} cpu: [x64] os: [darwin] '@rollup/rollup-linux-arm-gnueabihf@4.20.0': - resolution: {integrity: sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==} + resolution: {integrity: sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz} cpu: [arm] os: [linux] '@rollup/rollup-linux-arm-musleabihf@4.20.0': - resolution: {integrity: sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==} + resolution: {integrity: sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz} cpu: [arm] os: [linux] '@rollup/rollup-linux-arm64-gnu@4.20.0': - resolution: {integrity: sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==} + resolution: {integrity: sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz} cpu: [arm64] os: [linux] '@rollup/rollup-linux-arm64-musl@4.20.0': - resolution: {integrity: sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==} + resolution: {integrity: sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz} cpu: [arm64] os: [linux] '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': - resolution: {integrity: sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==} + resolution: {integrity: sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz} cpu: [ppc64] os: [linux] '@rollup/rollup-linux-riscv64-gnu@4.20.0': - resolution: {integrity: sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==} + resolution: {integrity: sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz} cpu: [riscv64] os: [linux] '@rollup/rollup-linux-s390x-gnu@4.20.0': - resolution: {integrity: sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==} + resolution: {integrity: sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz} cpu: [s390x] os: [linux] '@rollup/rollup-linux-x64-gnu@4.20.0': - resolution: {integrity: sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==} + resolution: {integrity: sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz} cpu: [x64] os: [linux] '@rollup/rollup-linux-x64-musl@4.20.0': - resolution: {integrity: sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==} + resolution: {integrity: sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz} cpu: [x64] os: [linux] '@rollup/rollup-win32-arm64-msvc@4.20.0': - resolution: {integrity: sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==} + resolution: {integrity: sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz} cpu: [arm64] os: [win32] '@rollup/rollup-win32-ia32-msvc@4.20.0': - resolution: {integrity: sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==} + resolution: {integrity: sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz} cpu: [ia32] os: [win32] '@rollup/rollup-win32-x64-msvc@4.20.0': - resolution: {integrity: sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==} + resolution: {integrity: sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz} cpu: [x64] os: [win32] @@ -3357,6 +3386,9 @@ packages: '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/bytes@3.1.4': + resolution: {integrity: sha512-A0uYgOj3zNc4hNjHc5lYUfJQ/HVyBXiUMKdXd7ysclaE6k9oJdavQzODHuwjpUu2/boCP8afjQYi8z/GtvNCWA==, tarball: https://registry.npmjs.org/@types/bytes/-/bytes-3.1.4.tgz} + '@types/configstore@2.1.1': resolution: {integrity: sha512-YY+hm3afkDHeSM2rsFXxeZtu0garnusBWNG1+7MknmDWQHqcH2w21/xOU9arJUi8ch4qyFklidANLCu3ihhVwQ==} @@ -3385,10 +3417,10 @@ packages: resolution: {integrity: sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==} '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==, tarball: https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz} '@types/eslint@9.6.0': - resolution: {integrity: sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==} + resolution: {integrity: sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==, tarball: https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz} '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -3477,6 +3509,9 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/pluralize@0.0.33': + resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==, tarball: https://registry.npmjs.org/@types/pluralize/-/pluralize-0.0.33.tgz} + '@types/pretty-hrtime@1.0.3': resolution: {integrity: sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA==} @@ -3924,49 +3959,49 @@ packages: resolution: {integrity: sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==} '@webassemblyjs/ast@1.12.1': - resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==, tarball: https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz} '@webassemblyjs/floating-point-hex-parser@1.11.6': - resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==, tarball: https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz} '@webassemblyjs/helper-api-error@1.11.6': - resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==, tarball: https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz} '@webassemblyjs/helper-buffer@1.12.1': - resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==, tarball: https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz} '@webassemblyjs/helper-numbers@1.11.6': - resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==, tarball: https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz} '@webassemblyjs/helper-wasm-bytecode@1.11.6': - resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==, tarball: https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz} '@webassemblyjs/helper-wasm-section@1.12.1': - resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==, tarball: https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz} '@webassemblyjs/ieee754@1.11.6': - resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==, tarball: https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz} '@webassemblyjs/leb128@1.11.6': - resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==, tarball: https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz} '@webassemblyjs/utf8@1.11.6': - resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==, tarball: https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz} '@webassemblyjs/wasm-edit@1.12.1': - resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz} '@webassemblyjs/wasm-gen@1.12.1': - resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz} '@webassemblyjs/wasm-opt@1.12.1': - resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz} '@webassemblyjs/wasm-parser@1.12.1': - resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==, tarball: https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz} '@webassemblyjs/wast-printer@1.12.1': - resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==, tarball: https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz} '@whatwg-node/events@0.0.3': resolution: {integrity: sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA==} @@ -4014,10 +4049,10 @@ packages: engines: {node: '>=8'} '@xtuc/ieee754@1.2.0': - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==, tarball: https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz} '@xtuc/long@4.2.2': - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==, tarball: https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz} '@yaireo/tagify@4.31.3': resolution: {integrity: sha512-YpBvYxqkJkOGyHg+0OzTCgt8Zb4vlYq+qE7jgxBLyPrvheSI0SXj3dbc4lVhCQhtbos4Kb2+t7ou8a+LYQk0Og==} @@ -4105,7 +4140,7 @@ packages: engines: {node: '>=8'} ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==, tarball: https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz} peerDependencies: ajv: ^6.9.1 @@ -4178,6 +4213,10 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argon2@0.41.1: + resolution: {integrity: sha512-dqCW8kJXke8Ik+McUcMDltrbuAWETPyU6iq+4AhxqKphWi7pChB/Zgd/Tp/o8xRLbg8ksMj46F/vph9wnxpTzQ==, tarball: https://registry.npmjs.org/argon2/-/argon2-0.41.1.tgz} + engines: {node: '>=16.17.0'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -4349,7 +4388,7 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} bare-events@2.4.2: - resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==} + resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==, tarball: https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz} base64-js@0.0.8: resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} @@ -4460,7 +4499,7 @@ packages: engines: {node: '>= 0.8'} bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, tarball: https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz} engines: {node: '>= 0.8'} c12@1.11.1: @@ -4471,6 +4510,14 @@ packages: magicast: optional: true + c12@1.11.2: + resolution: {integrity: sha512-oBs8a4uvSDO9dm8b7OCFW7+dgtVrwmwnrVXYzLm43ta7ep2jCn/0MhoUFygIWtxhyy6+/MG7/agvpY0U1Iemew==, tarball: https://registry.npmjs.org/c12/-/c12-1.11.2.tgz} + peerDependencies: + magicast: ^0.3.4 + peerDependenciesMeta: + magicast: + optional: true + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -4518,6 +4565,10 @@ packages: capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + case-anything@3.1.0: + resolution: {integrity: sha512-rRYnn5Elur8RuNHKoJ2b0tgn+pjYxL7BzWom+JZ7NKKn1lt/yGV/tUNwOovxYa9l9VL5hnXQdMc+mENbhJzosQ==, tarball: https://registry.npmjs.org/case-anything/-/case-anything-3.1.0.tgz} + engines: {node: '>=18'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -4608,7 +4659,7 @@ packages: hasBin: true chrome-trace-event@1.0.4: - resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==, tarball: https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz} engines: {node: '>=6.0'} ci-info@4.0.0: @@ -5277,7 +5328,7 @@ packages: engines: {node: '>=12'} drag-event-service@2.0.0: - resolution: {integrity: sha512-JVEnOEbbNDS3RrWd+tVVIDu2SHQZ9luhEFGSQ1hXMjl+ABw0PxhHmnkGjzPVE836Tsg+k7rkm5GM9Ln/UgbYpA==} + resolution: {integrity: sha512-JVEnOEbbNDS3RrWd+tVVIDu2SHQZ9luhEFGSQ1hXMjl+ABw0PxhHmnkGjzPVE836Tsg+k7rkm5GM9Ln/UgbYpA==, tarball: https://registry.npmjs.org/drag-event-service/-/drag-event-service-2.0.0.tgz} dset@3.1.3: resolution: {integrity: sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==} @@ -5389,7 +5440,7 @@ packages: resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} es-module-lexer@1.5.4: - resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==, tarball: https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz} es-object-atoms@1.0.0: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} @@ -5599,7 +5650,7 @@ packages: engines: {node: '>=4.0.0'} eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==, tarball: https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz} engines: {node: '>=8.0.0'} eslint-scope@7.2.2: @@ -5644,7 +5695,7 @@ packages: engines: {node: '>=4.0'} estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==, tarball: https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz} engines: {node: '>=4.0'} estraverse@5.3.0: @@ -5838,6 +5889,10 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==, tarball: https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz} + engines: {node: '>=8'} + flow-parser@0.243.0: resolution: {integrity: sha512-HCDBfH+kZcY5etWYeAqatjW78gkIryzb9XixRsA8lGI1uyYc7aCpElkkO4H+KIpoyQMiY0VAZPI4cyac3wQe8w==} engines: {node: '>=0.4.0'} @@ -5896,7 +5951,7 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -6696,7 +6751,7 @@ packages: hasBin: true jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==, tarball: https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz} engines: {node: '>= 10.13.0'} jiti@1.17.1: @@ -6923,7 +6978,7 @@ packages: optional: true loader-runner@4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==, tarball: https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz} engines: {node: '>=6.11.5'} local-pkg@0.5.0: @@ -7041,9 +7096,6 @@ packages: resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} engines: {node: '>=16.14'} - lucia@2.7.7: - resolution: {integrity: sha512-Hy1nMcLquLl3yDvV9zYA9fSBGUDy/Fw2zEUw2Ia4iGdk/O+hI/TvQ1tAfED/U1WE/c5DT1hEger3m7qIx1qbUg==} - magic-string-ast@0.6.2: resolution: {integrity: sha512-oN3Bcd7ZVt+0VGEs7402qR/tjgjbM7kPlH/z7ufJnzTLVBzXJITRHOJiwMmmYMgZfdoWQsfQcY+iKlxiBppnMA==} engines: {node: '>=16.14.0'} @@ -7457,6 +7509,10 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-addon-api@8.2.0: + resolution: {integrity: sha512-qnyuI2ROiCkye42n9Tj5aX1ns7rzj6n7zW1XReSnLSL9v/vbLeR6fJq6PU27YU/ICfYw6W7Ouk/N7cysWu/hlw==, tarball: https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.2.0.tgz} + engines: {node: ^18 || ^20 || >= 21} + node-dir@0.1.17: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} @@ -7482,7 +7538,7 @@ packages: engines: {node: '>= 6.13.0'} node-gyp-build@4.8.1: - resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==, tarball: https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz} hasBin: true node-int64@0.4.0: @@ -7539,6 +7595,17 @@ packages: engines: {node: ^16.10.0 || >=18.0.0} hasBin: true + nuxt-auth-utils@0.4.2: + resolution: {integrity: sha512-qDzSye1EovzlFkfnNOZyYdg9YXIlm75MqawsMdhDpH1n9bVZ2ydNyfHEZbpc1NWs5YfX3TyeJFpuvaXb4O/6yA==, tarball: https://registry.npmjs.org/nuxt-auth-utils/-/nuxt-auth-utils-0.4.2.tgz} + peerDependencies: + '@simplewebauthn/browser': ^10.0.0 + '@simplewebauthn/server': ^10.0.1 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nuxt-graphql-server@3.1.4: resolution: {integrity: sha512-kP6ttn6sg5FYSEZ2Ai/4W6aAcyuVvDXlb/eU9EtOOSLNPeNG1Dp2OgA4WIDD+K+OhR2kEZ+EjXqnGxsJ/vY4Lw==} engines: {node: ^16.10.0 || >=18.0.0} @@ -7627,9 +7694,15 @@ packages: ofetch@1.3.4: resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + ofetch@1.4.0: + resolution: {integrity: sha512-MuHgsEhU6zGeX+EMh+8mSMrYTnsqJQQrpM00Q6QHMKNqQ0bKy0B43tk8tL1wg+CnsSTy1kg4Ir2T5Ig6rD+dfQ==, tarball: https://registry.npmjs.org/ofetch/-/ofetch-1.4.0.tgz} + ohash@1.1.3: resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + ohash@1.1.4: + resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==, tarball: https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -7913,6 +7986,9 @@ packages: pkg-types@1.1.3: resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} + pkg-types@1.2.0: + resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==, tarball: https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz} + playwright-core@1.46.0: resolution: {integrity: sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==} engines: {node: '>=18'} @@ -8621,6 +8697,10 @@ packages: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==, tarball: https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz} + engines: {node: '>=10'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -8632,7 +8712,7 @@ packages: engines: {node: '>=16'} schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==, tarball: https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz} engines: {node: '>= 10.13.0'} scuid@1.1.0: @@ -8641,6 +8721,9 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==, tarball: https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz} + seemly@0.3.8: resolution: {integrity: sha512-MW8Qs6vbzo0pHmDpFSYPna+lwpZ6Zk1ancbajw/7E8TKtHdV+1DfZZD+kKJEhG/cAoB/i+LiT+5msZOqj0DwRA==} @@ -9098,7 +9181,7 @@ packages: engines: {node: '>=10'} terser-webpack-plugin@5.3.10: - resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==, tarball: https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -9211,6 +9294,9 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + truncatise@0.0.8: + resolution: {integrity: sha512-cXzueh9pzBCsLzhToB4X4gZCb3KYkrsAcBAX97JnazE74HOl3cpBJYEV7nabHeG/6/WXCU5Yujlde/WPBUwnsg==, tarball: https://registry.npmjs.org/truncatise/-/truncatise-0.0.8.tgz} + ts-api-utils@1.3.0: resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} @@ -9372,7 +9458,7 @@ packages: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} uglify-js@3.19.2: - resolution: {integrity: sha512-S8KA6DDI47nQXJSi2ctQ629YzwOVs+bQML6DAtvy0wgNdpi+0ySpQK0g2pxBq2xfF2z3YCscu7NNA8nXT9PlIQ==} + resolution: {integrity: sha512-S8KA6DDI47nQXJSi2ctQ629YzwOVs+bQML6DAtvy0wgNdpi+0ySpQK0g2pxBq2xfF2z3YCscu7NNA8nXT9PlIQ==, tarball: https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.2.tgz} engines: {node: '>=0.8.0'} hasBin: true @@ -9441,6 +9527,9 @@ packages: unimport@3.10.0: resolution: {integrity: sha512-/UvKRfWx3mNDWwWQhR62HsoM3wxHwYdTq8ellZzMOHnnw4Dp8tovgthyW7DjTrbjDL+i4idOp06voz2VKlvrLw==} + unimport@3.13.1: + resolution: {integrity: sha512-nNrVzcs93yrZQOW77qnyOVHtb68LegvhYFwxFMfuuWScmwQmyVCG/NBuN8tYsaGzgQUVYv34E/af+Cc9u4og4A==, tarball: https://registry.npmjs.org/unimport/-/unimport-3.13.1.tgz} + unique-string@2.0.0: resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} engines: {node: '>=8'} @@ -9504,6 +9593,15 @@ packages: resolution: {integrity: sha512-aXEH9c5qi3uYZHo0niUtxDlT9ylG/luMW/dZslSCkbtC31wCyFkmM0kyoBBh+Grhn7CL+/kvKLfN61/EdxPxMQ==} engines: {node: '>=14.0.0'} + unplugin@1.14.1: + resolution: {integrity: sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==, tarball: https://registry.npmjs.org/unplugin/-/unplugin-1.14.1.tgz} + engines: {node: '>=14.0.0'} + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + unstorage@1.12.0: resolution: {integrity: sha512-ARZYTXiC+e8z3lRM7/qY9oyaOkaozCeNd2xoz7sYK9fv7OLGhVsf+BZbmASqiK/HTZ7T6eAlnVq9JynZppyk3w==} peerDependencies: @@ -9820,10 +9918,10 @@ packages: resolution: {integrity: sha512-58i+ZhUAUpwQ+9h5Hck0D+jr1qbYl4voRt5KffBx8qzELViQ4XdT/Tuo+mzq8u63teAG8K0lLaOiL5ofqW38rg==} vue-component-type-helpers@2.1.6: - resolution: {integrity: sha512-ng11B8B/ZADUMMOsRbqv0arc442q7lifSubD0v8oDXIFoMg/mXwAPUunrroIDkY+mcD0dHKccdaznSVp8EoX3w==} + resolution: {integrity: sha512-ng11B8B/ZADUMMOsRbqv0arc442q7lifSubD0v8oDXIFoMg/mXwAPUunrroIDkY+mcD0dHKccdaznSVp8EoX3w==, tarball: https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.1.6.tgz} vue-demi@0.14.10: - resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==, tarball: https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz} engines: {node: '>=12'} hasBin: true peerDependencies: @@ -9909,7 +10007,7 @@ packages: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} webpack@5.93.0: - resolution: {integrity: sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==} + resolution: {integrity: sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==, tarball: https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -10146,6 +10244,13 @@ snapshots: tunnel: 0.0.6 undici: 5.28.4 + '@adonisjs/hash@9.0.5(argon2@0.41.1)': + dependencies: + '@phc/format': 1.0.0 + '@poppinss/utils': 6.8.3 + optionalDependencies: + argon2: 0.41.1 + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -12987,15 +13092,7 @@ snapshots: '@kwsites/promise-deferred@1.1.1': {} - '@lucia-auth/adapter-prisma@3.0.2(@prisma/client@5.20.0(prisma@5.20.0))(lucia@2.7.7)': - dependencies: - '@prisma/client': 5.20.0(prisma@5.20.0) - lucia: 2.7.7 - - '@lucia-auth/adapter-session-unstorage@2.1.0(lucia@2.7.7)(unstorage@1.12.0(@azure/identity@4.4.1)(ioredis@5.4.1))': - dependencies: - lucia: 2.7.7 - unstorage: 1.12.0(@azure/identity@4.4.1)(ioredis@5.4.1) + '@lukeed/ms@2.0.2': {} '@mapbox/node-pre-gyp@1.0.11': dependencies: @@ -13193,6 +13290,34 @@ snapshots: - rollup - supports-color + '@nuxt/kit@3.13.2(magicast@0.3.4)(rollup@4.20.0)(webpack-sources@3.2.3)': + dependencies: + '@nuxt/schema': 3.13.2(rollup@4.20.0)(webpack-sources@3.2.3) + c12: 1.11.2(magicast@0.3.4) + consola: 3.2.3 + defu: 6.1.4 + destr: 2.0.3 + globby: 14.0.2 + hash-sum: 2.0.0 + ignore: 5.3.2 + jiti: 1.21.6 + klona: 2.0.6 + knitwork: 1.1.0 + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.2.0 + scule: 1.3.0 + semver: 7.6.3 + ufo: 1.5.4 + unctx: 2.3.1 + unimport: 3.13.1(rollup@4.20.0)(webpack-sources@3.2.3) + untyped: 1.4.2 + transitivePeerDependencies: + - magicast + - rollup + - supports-color + - webpack-sources + '@nuxt/schema@3.12.4(rollup@4.20.0)': dependencies: compatx: 0.1.8 @@ -13211,6 +13336,25 @@ snapshots: - rollup - supports-color + '@nuxt/schema@3.13.2(rollup@4.20.0)(webpack-sources@3.2.3)': + dependencies: + compatx: 0.1.8 + consola: 3.2.3 + defu: 6.1.4 + hookable: 5.5.3 + pathe: 1.1.2 + pkg-types: 1.2.0 + scule: 1.3.0 + std-env: 3.7.0 + ufo: 1.5.4 + uncrypto: 0.1.3 + unimport: 3.13.1(rollup@4.20.0)(webpack-sources@3.2.3) + untyped: 1.4.2 + transitivePeerDependencies: + - rollup + - supports-color + - webpack-sources + '@nuxt/telemetry@2.5.4(magicast@0.3.4)(rollup@4.20.0)': dependencies: '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.20.0) @@ -13618,6 +13762,8 @@ snapshots: tslib: 2.6.3 webcrypto-core: 1.8.0 + '@phc/format@1.0.0': {} + '@pinia/nuxt@0.5.3(magicast@0.3.4)(rollup@4.20.0)(typescript@5.5.4)(vue@3.5.10(typescript@5.5.4))': dependencies: '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.20.0) @@ -13649,6 +13795,21 @@ snapshots: '@popperjs/core@2.11.8': {} + '@poppinss/utils@6.8.3': + dependencies: + '@lukeed/ms': 2.0.2 + '@types/bytes': 3.1.4 + '@types/pluralize': 0.0.33 + bytes: 3.1.2 + case-anything: 3.1.0 + flattie: 1.1.1 + pluralize: 8.0.0 + safe-stable-stringify: 2.5.0 + secure-json-parse: 2.7.0 + slash: 5.1.0 + slugify: 1.6.6 + truncatise: 0.0.8 + '@prisma/client@5.20.0(prisma@5.20.0)': optionalDependencies: prisma: 5.20.0 @@ -13824,6 +13985,14 @@ snapshots: optionalDependencies: rollup: 4.20.0 + '@rollup/pluginutils@5.1.2(rollup@4.20.0)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.20.0 + '@rollup/rollup-android-arm-eabi@4.20.0': optional: true @@ -14348,6 +14517,8 @@ snapshots: '@types/connect': 3.4.38 '@types/node': 20.16.10 + '@types/bytes@3.1.4': {} + '@types/configstore@2.1.1': {} '@types/connect@3.4.38': @@ -14474,6 +14645,8 @@ snapshots: '@types/normalize-package-data@2.4.4': {} + '@types/pluralize@0.0.33': {} + '@types/pretty-hrtime@1.0.3': {} '@types/prop-types@15.7.12': {} @@ -15429,6 +15602,12 @@ snapshots: arg@5.0.2: {} + argon2@0.41.1: + dependencies: + '@phc/format': 1.0.0 + node-addon-api: 8.2.0 + node-gyp-build: 4.8.1 + argparse@2.0.1: {} array-buffer-byte-length@1.0.1: @@ -15798,6 +15977,23 @@ snapshots: optionalDependencies: magicast: 0.3.4 + c12@1.11.2(magicast@0.3.4): + dependencies: + chokidar: 3.6.0 + confbox: 0.1.7 + defu: 6.1.4 + dotenv: 16.4.5 + giget: 1.2.3 + jiti: 1.21.6 + mlly: 1.7.1 + ohash: 1.1.4 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.2.0 + rc9: 2.1.2 + optionalDependencies: + magicast: 0.3.4 + cac@6.7.14: {} cache-content-type@1.0.1: @@ -15845,6 +16041,8 @@ snapshots: tslib: 2.6.3 upper-case-first: 2.0.2 + case-anything@3.1.0: {} + ccount@2.0.1: {} chai@5.1.1: @@ -17510,6 +17708,8 @@ snapshots: flatted@3.3.1: {} + flattie@1.1.1: {} + flow-parser@0.243.0: {} follow-redirects@1.15.6: {} @@ -18854,8 +19054,6 @@ snapshots: lru-cache@8.0.5: {} - lucia@2.7.7: {} - magic-string-ast@0.6.2: dependencies: magic-string: 0.30.11 @@ -19492,6 +19690,8 @@ snapshots: node-addon-api@7.1.1: {} + node-addon-api@8.2.0: {} + node-dir@0.1.17: dependencies: minimatch: 3.1.2 @@ -19565,6 +19765,25 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + nuxt-auth-utils@0.4.2(argon2@0.41.1)(magicast@0.3.4)(rollup@4.20.0)(webpack-sources@3.2.3): + dependencies: + '@adonisjs/hash': 9.0.5(argon2@0.41.1) + '@nuxt/kit': 3.13.2(magicast@0.3.4)(rollup@4.20.0)(webpack-sources@3.2.3) + defu: 6.1.4 + hookable: 5.5.3 + ofetch: 1.4.0 + ohash: 1.1.4 + pathe: 1.1.2 + scule: 1.3.0 + uncrypto: 0.1.3 + transitivePeerDependencies: + - argon2 + - bcrypt + - magicast + - rollup + - supports-color + - webpack-sources + nuxt-graphql-server@3.1.4(graphql@16.9.0)(magicast@0.3.4)(rollup@4.20.0): dependencies: '@graphql-codegen/core': 4.0.2(graphql@16.9.0) @@ -19887,8 +20106,16 @@ snapshots: node-fetch-native: 1.6.4 ufo: 1.5.4 + ofetch@1.4.0: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.4 + ohash@1.1.3: {} + ohash@1.1.4: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -20195,6 +20422,12 @@ snapshots: mlly: 1.7.1 pathe: 1.1.2 + pkg-types@1.2.0: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + playwright-core@1.46.0: {} pluralize@8.0.0: {} @@ -21014,6 +21247,8 @@ snapshots: es-errors: 1.3.0 is-regex: 1.1.4 + safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} satori-html@0.3.2: @@ -21043,6 +21278,8 @@ snapshots: scule@1.3.0: {} + secure-json-parse@2.7.0: {} + seemly@0.3.8: {} selfsigned@2.4.1: @@ -21293,7 +21530,7 @@ snapshots: stoppable@1.1.0: {} - storybook-vue-addon@0.6.1(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.20.0))(@nuxt/schema@3.12.4(rollup@4.20.0))(esbuild@0.18.20)(rollup@4.20.0)(typescript@5.5.4)(vite@5.4.0(@types/node@20.16.10)(terser@5.31.6))(vue-tsc@2.1.6(typescript@5.5.4))(vue@3.5.10(typescript@5.5.4))(webpack@5.93.0(esbuild@0.18.20)): + storybook-vue-addon@0.6.1(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.20.0))(@nuxt/schema@3.13.2(rollup@4.20.0)(webpack-sources@3.2.3))(esbuild@0.18.20)(rollup@4.20.0)(typescript@5.5.4)(vite@5.4.0(@types/node@20.16.10)(terser@5.31.6))(vue-tsc@2.1.6(typescript@5.5.4))(vue@3.5.10(typescript@5.5.4))(webpack@5.93.0(esbuild@0.18.20)): dependencies: '@storybook/csf': 0.1.11 '@storybook/mdx2-csf': 1.1.0 @@ -21304,7 +21541,7 @@ snapshots: vue: 3.5.10(typescript@5.5.4) optionalDependencies: '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.20.0) - '@nuxt/schema': 3.12.4(rollup@4.20.0) + '@nuxt/schema': 3.13.2(rollup@4.20.0)(webpack-sources@3.2.3) esbuild: 0.18.20 rollup: 4.20.0 vite: 5.4.0(@types/node@20.16.10)(terser@5.31.6) @@ -21660,6 +21897,8 @@ snapshots: trough@2.2.0: {} + truncatise@0.0.8: {} + ts-api-utils@1.3.0(typescript@5.5.4): dependencies: typescript: 5.5.4 @@ -21898,6 +22137,25 @@ snapshots: transitivePeerDependencies: - rollup + unimport@3.13.1(rollup@4.20.0)(webpack-sources@3.2.3): + dependencies: + '@rollup/pluginutils': 5.1.2(rollup@4.20.0) + acorn: 8.12.1 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.2 + local-pkg: 0.5.0 + magic-string: 0.30.11 + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.2.0 + scule: 1.3.0 + strip-literal: 2.1.0 + unplugin: 1.14.1(webpack-sources@3.2.3) + transitivePeerDependencies: + - rollup + - webpack-sources + unique-string@2.0.0: dependencies: crypto-random-string: 2.0.0 @@ -21997,6 +22255,13 @@ snapshots: webpack-sources: 3.2.3 webpack-virtual-modules: 0.6.2 + unplugin@1.14.1(webpack-sources@3.2.3): + dependencies: + acorn: 8.12.1 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + webpack-sources: 3.2.3 + unstorage@1.12.0(@azure/identity@4.4.1)(ioredis@5.4.1): dependencies: anymatch: 3.1.3 diff --git a/renovate.json5 b/renovate.json5 index 85ef9ea4e..f9d284bcd 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -75,7 +75,6 @@ }, { matchPackageNames: ['prisma', '@prisma{/,}**'], groupName: 'prisma' }, { matchPackageNames: ['@azure{/,}**'], groupName: 'azure' }, - { matchPackageNames: ['lucia', '@lucia-auth{/,}**'], groupName: 'lucia' }, { matchPackageNames: ['@vitest{/,}**', 'vitest', 'vitest-**'], groupName: 'vitest', diff --git a/server/api/index.ts b/server/api/index.ts index 33ee23b58..6322e17af 100644 --- a/server/api/index.ts +++ b/server/api/index.ts @@ -5,10 +5,8 @@ import { startServerAndCreateH3Handler } from '@as-integrations/h3' import { handleCors } from 'h3' import http from 'http' import 'json-bigint-patch' // Needed for bigint support in JSON -import 'reflect-metadata' // Needed for tsyringe import { buildContext, type Context } from '../context' import { loadSchemaWithResolvers } from '../schema' -import { configure as configureTsyringe } from './../tsyringe.config' // Workaround for issue with Azure deploy: https://github.com/unjs/nitro/issues/351 // Original code taken from https://github.com/nodejs/node/blob/main/lib/_http_outgoing.js @@ -85,8 +83,6 @@ http.IncomingMessage.Readable.prototype.unpipe = function (dest) { } export default defineLazyEventHandler(async () => { - configureTsyringe() - const server = new ApolloServer({ schema: await loadSchemaWithResolvers(), introspection: true, diff --git a/server/context.ts b/server/context.ts index 9842b8505..d82136aeb 100644 --- a/server/context.ts +++ b/server/context.ts @@ -1,9 +1,22 @@ +import type { User, UserSession } from '#auth-utils' import type { H3ContextFunctionArgument } from '@as-integrations/h3' -import type { User } from '@prisma/client' -import type { Session } from 'lucia' -import { resolve } from '~/server/tsyringe' +import { defu } from 'defu' +import type { H3Event, SessionConfig } from 'h3' export interface Context { + /** + * Returns the current (raw) session or initializes a new session if no session is present. + */ + getOrInitSession: () => Promise<{ + readonly id: string | undefined + readonly data: UserSession + update: ( + update: + | Partial + | ((oldData: UserSession) => Partial | undefined), + ) => Promise + clear: () => Promise + }> /** * Returns the currently logged in user or null if no user is logged in. */ @@ -12,21 +25,61 @@ export interface Context { * Writes the given session to the response (e.g. sets the session cookie). * If the session is null, the session information is removed from the response, which effectively logs the user out. */ - setSession: (session: Session | null) => void + setSession: (session: UserSession | null) => Promise +} + +let sessionConfig: SessionConfig | null = null +function _useSession(event: H3Event, config: Partial = {}) { + if (!sessionConfig) { + const runtimeConfig = useRuntimeConfig(event) + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- false positive + const envSessionPassword = `${runtimeConfig.nitro?.envPrefix ?? 'NUXT_'}SESSION_PASSWORD` + + // @ts-expect-error hard to define with defu + sessionConfig = defu( + { password: process.env[envSessionPassword] }, + runtimeConfig.session, + ) + } + const finalConfig = defu(config, sessionConfig) as SessionConfig + return useSession(event, finalConfig) } export function buildContext({ event, }: H3ContextFunctionArgument): Promise { - const authHandler = resolve('AuthService').createAuthContext(event) return Promise.resolve({ + getOrInitSession: async () => { + return _useSession(event) + }, getUser: async () => { - // Validate internally caches the result, so we don't need to cache it here - const session = await authHandler.validate() - return session?.user ?? null + return (await getUserSession(event)).user ?? null }, - setSession: (session) => { - authHandler.setSession(session) + setSession: async (session) => { + if (session === null) { + await clearUserSession(event) + } else { + // TODO: Handle this properly (i.e. don't expose to client but still have it available on the server) + // @ts-expect-error -- hacky workaround + delete session.server + + // This is all very hacky + // h3 currently doesn't deduplicate cookies. So just calling "setUserSession" + // creates actually 4 cookies... + // We clear the cookie in between, and then manually set the session data + // TODO: Remove this workaround once h3 v2 comes out + const rawSession = await _useSession(event, { + // Session completely expires after half a year + maxAge: 0.5 * 31556952 * 1000, + cookie: { + // Blocks sending a cookie in a cross-origin request, protects somewhat against CORS attacks + sameSite: 'strict', + }, + }) + // This actually clears all cookies! Probably not what we want + setResponseHeader(event, 'Set-Cookie', '') + await rawSession.update(() => session) + } }, }) } diff --git a/server/database/migrations/20241002152302_/migration.sql b/server/database/migrations/20241002152302_/migration.sql new file mode 100644 index 000000000..1059f83b2 --- /dev/null +++ b/server/database/migrations/20241002152302_/migration.sql @@ -0,0 +1,15 @@ +/* + Warnings: + + - You are about to drop the `Key` table. If the table is not empty, all the data it contains will be lost. + - Added the required column `hashedPassword` to the `User` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropForeignKey +ALTER TABLE "Key" DROP CONSTRAINT "Key_user_id_fkey"; + +-- AlterTable +ALTER TABLE "User" ADD COLUMN "hashedPassword" TEXT NOT NULL; + +-- DropTable +DROP TABLE "Key"; diff --git a/server/database/schema.prisma b/server/database/schema.prisma index 3db87a263..0548f073e 100644 --- a/server/database/schema.prisma +++ b/server/database/schema.prisma @@ -17,16 +17,7 @@ model User { createdAt DateTime @default(now()) documents UserDocument[] groups Group[] - key Key[] // TODO: Rename to keys -} - -model Key { - id String @id @unique - hashed_password String? // TODO: Rename to hashedPassword - user_id String // TODO: Rename to userId - user User @relation(references: [id], fields: [user_id], onDelete: Cascade) - - @@index([user_id]) + hashedPassword String } enum DocumentType { diff --git a/server/database/seed.ts b/server/database/seed.ts index d63985f6c..25426b496 100644 --- a/server/database/seed.ts +++ b/server/database/seed.ts @@ -18,15 +18,8 @@ async function seedInternal(prisma: PrismaClientT): Promise { id: 'ckn4oul7100004cv7y3t94n8j', email: 'alice@jabref.org', name: 'Alice', - key: { - create: [ - { - id: 'email:alice@jabref.org', - hashed_password: - 's2:v0m1wv8ia158m21f:6b60b32e60cf1ed5960afca58f2feb1779e409b3570d46919b21d93e342e532238631f8218c9d7854a69f210830c0d1c0bcd74d0ba2a7a2e5483b676f2b619cb', // EBNPXY35TYkYXHs - }, - ], - }, + hashedPassword: + '$argon2id$v=19$m=65536,t=3,p=4$JpPQhFOXODmSV6mebUqD1g$B2JyogUsj80kxjqiKPlFIiXF72v7SxqWdcw0C10ByhQ', // EBNPXY35TYkYXHs }, }) diff --git a/server/middleware/validateSession.ts b/server/middleware/validateSession.ts new file mode 100644 index 000000000..206495c02 --- /dev/null +++ b/server/middleware/validateSession.ts @@ -0,0 +1,39 @@ +import type { UserSession } from '#auth-utils' +import { defu } from 'defu' +import type { H3Event, SessionConfig } from 'h3' +import { resolve } from '../tsyringe' + +let sessionConfig: SessionConfig | null = null +function _useSession(event: H3Event) { + if (!sessionConfig) { + const runtimeConfig = useRuntimeConfig(event) + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- false positive + const envSessionPassword = `${runtimeConfig.nitro?.envPrefix ?? 'NUXT_'}SESSION_PASSWORD` + + // @ts-expect-error hard to define with defu + sessionConfig = defu( + { password: process.env[envSessionPassword] }, + runtimeConfig.session, + ) + } + // @ts-expect-error sessionConfig is not null here + return useSession(event, sessionConfig) +} + +export default defineEventHandler(async (event) => { + const authHandler = resolve('AuthService') + const session = await _useSession(event) + // session.id is not a good way to check if there is a session as it will always be set by h3 (except if one calls clearSession) + // use session.data instead, with the convention that if it is an empty object, there is no session + if (session.id && Object.keys(session.data).length !== 0) { + try { + // Check if session is valid + await authHandler.refreshSession(session) + // TODO: This would exposes the "server" info to the client + // await session.update((data) => defu({ server: info }, data)) + } catch { + // Clear session + await session.clear() + } + } +}) diff --git a/server/plugins/tsyringe.ts b/server/plugins/tsyringe.ts new file mode 100644 index 000000000..1c2c67ba0 --- /dev/null +++ b/server/plugins/tsyringe.ts @@ -0,0 +1,9 @@ +import 'reflect-metadata' // Needed for tsyringe +import { configure as configureTsyringe } from './../tsyringe.config' + +/** + * This plugin configures the tsyringe dependency injection container. + */ +export default defineNitroPlugin(() => { + configureTsyringe() +}) diff --git a/server/user/auth.service.ts b/server/user/auth.service.ts index fa581bb11..3d313b928 100644 --- a/server/user/auth.service.ts +++ b/server/user/auth.service.ts @@ -1,10 +1,9 @@ +import type { ServerSessionData, UserSession } from '#auth-utils' import type { PrismaClient, User } from '@prisma/client' import type { ResolversTypes } from '#graphql/resolver' -import { LuciaError, lucia as luciaConstructor, type Auth } from 'lucia' -import type { Storage } from 'unstorage' +import { prefixStorage, type Storage } from 'unstorage' import { v4 as generateToken } from 'uuid' -import { Environment, type Config } from '~/config' import { hash, verifyHash } from '../utils/crypto' import type { EmailService } from '../utils/email.service' import { @@ -14,12 +13,6 @@ import { } from '../utils/emailTemplates' import { inject, injectable } from './../tsyringe' -import { prisma as prismaAdapter } from '@lucia-auth/adapter-prisma' -import { unstorage as unstorageAdapter } from '@lucia-auth/adapter-session-unstorage' -import { H3Event } from 'h3' -import { h3 } from '../utils/luciaMiddleware' - -const EMAIL_PROVIDER = 'email' const FORGOT_PASSWORD_PREFIX = 'forgot-password' export type ChangePasswordPayload = ResolversTypes['ChangePasswordPayload'] @@ -28,39 +21,25 @@ export type LogoutPayload = ResolversTypes['LogoutPayload'] export type ForgotPasswordPayload = ResolversTypes['ForgotPasswordPayload'] export type LoginPayload = ResolversTypes['LoginPayload'] +const invalidCredentialsError = { + problems: [ + { path: ['email', 'password'], message: 'Wrong email or password' }, + ], +} + @injectable() export class AuthService { - lucia: Auth + /** + * Storage for all sessions associated with a user. Base is the user ID, keys are session IDs. + */ + sessionStorage: Storage + constructor( @inject('PrismaClient') private prisma: PrismaClient, @inject('RedisClient') private redisClient: Storage, @inject('EmailService') private emailService: EmailService, - @inject('Config') private config: Config, ) { - this.lucia = luciaConstructor({ - env: - config.public.environment === Environment.Production ? 'PROD' : 'DEV', - middleware: h3(), - adapter: { - user: prismaAdapter(prisma), - session: unstorageAdapter(redisClient), - }, - getUserAttributes: (user: User) => user, - sessionExpiresIn: { - // Session counts as active for 1 day (afterwards it has to be refreshed) - activePeriod: 1000 * 60 * 60 * 24, - // Session completely expires after half a year - idlePeriod: 0.5 * 31556952 * 1000, - }, - sessionCookie: { - attributes: { - // Blocks sending a cookie in a cross-origin request, protects somewhat against CORS attacks - sameSite: 'strict', - }, - }, - // TODO: Enable (once figure out why login then no longer works) - csrfProtection: false, - }) + this.sessionStorage = prefixStorage(redisClient, 'session') } async getUsers(): Promise { @@ -68,31 +47,15 @@ export class AuthService { } async validateUser(email: string, password: string) { - try { - const key = await this.lucia.useKey( - EMAIL_PROVIDER, - email.toLowerCase(), - password, - ) - const user = await this.getUserById(key.userId) - if (!user) { - throw new Error('User not found although key was valid') - } - return user - } catch (error) { - if ( - error instanceof LuciaError && - (error.message === 'AUTH_INVALID_KEY_ID' || - error.message === 'AUTH_INVALID_PASSWORD') - ) { - return { - problems: [ - { path: ['email', 'password'], message: 'Wrong email or password' }, - ], - } - } - throw error + const user = await this.getUserByEmail(email) + if (!user) { + return invalidCredentialsError + } + if (!(await verifyHash(password, user.hashedPassword))) { + return invalidCredentialsError } + + return user } async resetPassword(email: string): Promise { @@ -130,48 +93,37 @@ export class AuthService { async getUserByEmail(email: string): Promise { return await this.prisma.user.findFirst({ where: { - id: email.toLowerCase(), + email: email.toLowerCase(), }, }) } async createAccount(email: string, password: string) { - try { - const user = await this.lucia.createUser({ - key: { - providerId: EMAIL_PROVIDER, - providerUserId: email.toLowerCase(), - password, - }, - // @ts-expect-error: lucia forces us to pass all attributes, but they are actually generated by the database - attributes: { - email: email.toLowerCase(), - }, - }) - - await this.emailService.sendEmail( - { address: email }, - 'Welcome! Confirm your email and get started', - welcomeTemplate(user), - ) - - return user - } catch (error) { - if ( - error instanceof LuciaError && - error.message === 'AUTH_DUPLICATE_KEY_ID' - ) { - return { - problems: [ - { - path: ['email'], - message: `User with email '${email}' already exists.`, - }, - ], - } + if (await this.getUserByEmail(email)) { + return { + problems: [ + { + path: ['email'], + message: `User with email '${email}' already exists.`, + }, + ], } - throw error } + + const user = await this.prisma.user.create({ + data: { + email: email.toLowerCase(), + hashedPassword: await hash(password), + }, + }) + + await this.emailService.sendEmail( + { address: email }, + 'Welcome! Confirm your email and get started', + welcomeTemplate(user), + ) + + return user } async updatePassword(token: string, userId: string, newPassword: string) { @@ -206,20 +158,61 @@ export class AuthService { message: 'User not found', } } - await this.lucia.invalidateAllUserSessions(user.id) - await this.lucia.updateKeyPassword(EMAIL_PROVIDER, user.email, newPassword) + await this._invalidateAllUserSessions(user.id) + await this.prisma.user.update({ + where: { id: user.id }, + data: { + hashedPassword: await hash(newPassword), + }, + }) return { user } } - async createSession(user: User | string) { - const userId = typeof user === 'string' ? user : user.id - return await this.lucia.createSession({ - userId, - attributes: {}, + /** + * Refreshes a session in the session storage. + * If the session is no longer valid, an error is thrown. + * + * @returns Server session data + */ + async refreshSession({ id, data }: { id?: string; data: UserSession }) { + if (!id || !data.user?.id) { + throw new Error('Invalid session') + } + + const info = await this.sessionStorage.getItem(`${data.user.id}:${id}`) + if (!info) { + throw new Error('Session not found') + } else { + info.lastActive = new Date() + await this._setSession(data.user.id, id, info) + return info + } + } + + _invalidateAllUserSessions(userId: string) { + return this.sessionStorage.clear(userId) + } + + _setSession(userId: string, sessionId: string, data: ServerSessionData) { + return this.sessionStorage.setItem(`${userId}:${sessionId}`, data, { + ttl: 1000 * 60 * 60 * 24 * 7, // 1 week }) } - createAuthContext(event: H3Event) { - return this.lucia.handleRequest(event) + async initSession( + sessionId: string, + user: User | string, + ): Promise { + const userId = typeof user === 'string' ? user : user.id + const serverData = { + lastActive: new Date(), + } + await this._setSession(userId, sessionId, serverData) + return { + user: { + id: userId, + }, + server: serverData, + } } } diff --git a/server/user/e2e.test.ts b/server/user/e2e.test.ts index efff5fa91..917130f11 100644 --- a/server/user/e2e.test.ts +++ b/server/user/e2e.test.ts @@ -1,4 +1,4 @@ -import { setup } from '@nuxt/test-utils' +import { $fetch, setup } from '@nuxt/test-utils' import { gql } from 'graphql-tag' import { describe, expect, it, test } from 'vitest' import { api, login } from '~/test/api-e2e/graphqlClient' @@ -133,3 +133,32 @@ describe('query', () => { }) }) }) + +describe('nuxt-auth-endpoint', () => { + it('returns the session info when logged in', async () => { + const request = api() + const { cookies } = await login(request) + const html = await $fetch('api/_auth/session', { + headers: { cookie: cookies.join('; ') }, + }) + expect(html).toStrictEqual({ + user: { id: 'ckn4oul7100004cv7y3t94n8j' }, + }) + }) + it('returns nothing when not logged in', async () => { + const html = await $fetch('api/_auth/session') + expect(html).toStrictEqual({}) + }) +}) + +describe('test-utils', () => { + it('login returns session cookie', async () => { + const request = api() + const { cookies } = await login(request) + expect(cookies.length).toBe(1) + expect(cookies[0]).toMatch('nuxt-session=') + expect(cookies[0].toLowerCase()).toContain('httponly') + expect(cookies[0].toLowerCase()).toContain('secure') + expect(cookies[0].toLowerCase()).toContain('samesite=strict') + }) +}) diff --git a/server/user/resolvers.ts b/server/user/resolvers.ts index 97cca3844..7c2776246 100644 --- a/server/user/resolvers.ts +++ b/server/user/resolvers.ts @@ -56,7 +56,12 @@ export class Query { _args: Record, context: Context, ): Promise { - return await context.getUser() + const userId = (await context.getUser())?.id + if (userId) { + return this.authService.getUserById(userId) + } else { + return null + } } } @@ -74,8 +79,15 @@ export class Mutation { if ('problems' in userOrProblems) { return userOrProblems } - const session = await this.authService.createSession(userOrProblems) - context.setSession(session) + const rawSession = await context.getOrInitSession() + if (!rawSession.id) { + throw new Error('Session ID not set') + } + const session = await this.authService.initSession( + rawSession.id, + userOrProblems, + ) + await context.setSession(session) return { user: userOrProblems } } @@ -91,17 +103,24 @@ export class Mutation { } // Make login persistent by putting it in the session store - const session = await this.authService.createSession(userOrProblems) - context.setSession(session) + const rawSession = await context.getOrInitSession() + if (!rawSession.id) { + throw new Error('Session ID not set') + } + const session = await this.authService.initSession( + rawSession.id, + userOrProblems, + ) + await context.setSession(session) return { user: userOrProblems } } - logout( + async logout( _root: Record, _args: Record, context: Context, - ): LogoutPayload { - context.setSession(null) + ): Promise { + await context.setSession(null) return { result: true, } diff --git a/server/utils/crypto.spec.ts b/server/utils/crypto.spec.ts index f1737ba77..2c0cd9013 100644 --- a/server/utils/crypto.spec.ts +++ b/server/utils/crypto.spec.ts @@ -3,10 +3,8 @@ import { hash, verifyHash } from './crypto' describe('hash', () => { it('should return the correct hash', async () => { - expect( - await hash('EBNPXY35TYkYXHs', 'saltsaltsaltsaltsaltsaltsaltsalt'), - ).toBe( - 'saltsaltsaltsaltsaltsaltsaltsalt63f7e072b6a9faf6e77616c098c4bb3ac69c58d249e620e1dd51257018ac7fcb40b576e9f69e9c556c70a980327dac12b1ee76a76f22b249d585fe2de10b365a', + expect(await hash('EBNPXY35TYkYXHs')).toMatch( + '$argon2id$v=19$m=65536,t=3,p=4$', ) }) }) @@ -27,7 +25,7 @@ describe('verify hash', () => { expect( await verifyHash( 'EBNPXY35TYkYXHs', - '19184d8c1c1e9b483d8347f8da0d53ad92170233100d32c3a0d748725948c28d09a060d7f02962b7b93320c72a2cdd94f21b16b08bf8bd1cba0c5f77afeffddbb24df527c4f16f1fca6eb5480159b56df3d818b4b3c74ead04227a78b3d810b8', + '$argon2id$v=19$m=65536,t=3,p=4$JpPQhFOXODmSV6mebUqD1g$B2JyogUsj80kxjqiKPlFIiXF72v7SxqWdcw0C10ByhQ', ), ).toBe(true) }) diff --git a/server/utils/crypto.ts b/server/utils/crypto.ts index 72138119c..84fcd33ec 100644 --- a/server/utils/crypto.ts +++ b/server/utils/crypto.ts @@ -1,28 +1,35 @@ import crypto from 'crypto' -const lengthSaltBytes = 16 -const lengthSaltString = lengthSaltBytes * 2 // lengthSaltBytes is in bytes, but salt is encoded in hex, so times 2 +import { Hash } from '@adonisjs/hash' +// @ts-expect-error -- not sure why this is not working +import { Argon } from '@adonisjs/hash/drivers/argon' + +// This is mostly taken from nuxt-auth-utils, but with a few changes to make it work it work with argon2 and to fix a few shortcomings +let _hash: Hash | null = null +function getHash() { + if (!_hash) { + _hash = new Hash(new Argon()) + } + return _hash +} +export async function hashPassword(password: string) { + return await getHash().make(password) +} +export async function verifyPassword( + hashedPassword: string, + plainPassword: string, +) { + return await getHash().verify(hashedPassword, plainPassword) +} /** * Hash the given string. - * We use salted hashing to prevent rainbow table attacks. + * * @param token the token to hash - * @returns the salted hash + * @returns the hash */ -export async function hash(token: string, salt?: string): Promise { - if (salt && salt.length !== lengthSaltString) { - throw new Error( - `Invalid salt length: ${salt.length} but needs to be ${lengthSaltString}`, - ) - } - - const usedSalt = salt ?? crypto.randomBytes(lengthSaltString).toString('hex') - return new Promise((resolve, reject) => { - crypto.scrypt(token, usedSalt, 64, (err, derivedKey) => { - if (err) reject(err) - resolve(`${usedSalt}${derivedKey.toString('hex')}`) - }) - }) +export async function hash(token: string): Promise { + return await hashPassword(token) } export function unsecureHash(token: string | object): string { @@ -34,12 +41,5 @@ export async function verifyHash( token: string, hashedToken: string, ): Promise { - return new Promise((resolve, reject) => { - const salt = hashedToken.substring(0, 2 * lengthSaltString) - const hashedTokenWithoutSalt = hashedToken.substring(2 * lengthSaltString) - crypto.scrypt(token, salt, 64, (err, derivedKey) => { - if (err) reject(err) - resolve(derivedKey.toString('hex') === hashedTokenWithoutSalt) - }) - }) + return await verifyPassword(hashedToken, token) } diff --git a/server/utils/luciaMiddleware.ts b/server/utils/luciaMiddleware.ts deleted file mode 100644 index 46f8d9e83..000000000 --- a/server/utils/luciaMiddleware.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { Middleware } from 'lucia' - -import { H3Event, getCookie, getRequestURL, setCookie } from 'h3' - -export function h3(): Middleware<[H3Event]> { - return ({ args, sessionCookieName }) => { - const [event] = args - return { - request: { - url: getRequestURL(event).toString(), - headers: event.headers, - method: event.method, - }, - sessionCookie: getCookie(event, sessionCookieName), - setCookie: (cookie) => { - setCookie(event, cookie.name, cookie.value, cookie.attributes) - }, - } - } -} diff --git a/shims-lucia.d.ts b/shims-lucia.d.ts deleted file mode 100644 index f3d0acd4b..000000000 --- a/shims-lucia.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { User } from '@prisma/client' - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-unused-vars -- https://github.com/lucia-auth/lucia/issues/1074 - namespace Lucia { - type DatabaseUserAttributes = User - // eslint-disable-next-line @typescript-eslint/no-empty-interface - interface DatabaseSessionAttributes {} - interface Auth { - getUserAttributes: (user: DatabaseUserAttributes) => User - getSessionAttributes: () => {} - } - } -} diff --git a/test/apollo.server.ts b/test/apollo.server.ts index 29d4e09a5..7b433774f 100644 --- a/test/apollo.server.ts +++ b/test/apollo.server.ts @@ -34,6 +34,9 @@ export async function createAuthenticatedClient(): Promise { executeOperation: async (operation) => { return await server.executeOperation(operation, { contextValue: { + getOrInitSession: () => { + throw new Error('Not implemented') + }, getUser: () => Promise.resolve(user), setSession: () => { throw new Error('Not implemented')