diff --git a/package-lock.json b/package-lock.json index 110560bfb225df090d54e783967c11562364058b..a77dac2e553a39500bc91d16bf0f9c7c1a80ea95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,7 +56,7 @@ "rollup-plugin-node-polyfills": "~0.2.1", "sass": "^1.66.0", "typescript": "~5.4.0", - "vite": "~5.2.0", + "vite": "~5.3.0", "vue-tsc": "~2.0.0" } }, @@ -973,7 +973,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=12" } @@ -990,7 +989,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -1007,7 +1005,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -1024,7 +1021,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=12" } @@ -1041,7 +1037,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -1058,7 +1053,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=12" } @@ -1075,7 +1069,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -1092,7 +1085,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -1109,7 +1101,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1126,7 +1117,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1143,7 +1133,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1160,7 +1149,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1177,7 +1165,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1194,7 +1181,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1211,7 +1197,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1228,7 +1213,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1245,7 +1229,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=12" } @@ -1262,7 +1245,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -1279,7 +1261,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=12" } @@ -1296,7 +1277,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=12" } @@ -1313,7 +1293,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -1330,7 +1309,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -1347,7 +1325,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=12" } @@ -2744,12 +2721,12 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz", - "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.29.tgz", + "integrity": "sha512-TFKiRkKKsRCKvg/jTSSKK7mYLJEQdUiUfykbG49rubC9SfDyvT2JrzTReopWlz2MxqeLyxh9UZhvxEIBgAhtrg==", "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/shared": "3.4.27", + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.29", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" @@ -2761,24 +2738,24 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, "node_modules/@vue/compiler-dom": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz", - "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.29.tgz", + "integrity": "sha512-A6+iZ2fKIEGnfPJejdB7b1FlJzgiD+Y/sxxKwJWg1EbJu6ZPgzaPQQ51ESGNv0CP6jm6Z7/pO6Ia8Ze6IKrX7w==", "dependencies": { - "@vue/compiler-core": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-core": "3.4.29", + "@vue/shared": "3.4.29" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz", - "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==", - "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/compiler-core": "3.4.27", - "@vue/compiler-dom": "3.4.27", - "@vue/compiler-ssr": "3.4.27", - "@vue/shared": "3.4.27", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.29.tgz", + "integrity": "sha512-zygDcEtn8ZimDlrEQyLUovoWgKQic6aEQqRXce2WXBvSeHbEbcAsXyCk9oG33ZkyWH4sl9D3tkYc1idoOkdqZQ==", + "dependencies": { + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.29", + "@vue/compiler-dom": "3.4.29", + "@vue/compiler-ssr": "3.4.29", + "@vue/shared": "3.4.29", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", "postcss": "^8.4.38", @@ -2799,12 +2776,12 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz", - "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.29.tgz", + "integrity": "sha512-rFbwCmxJ16tDp3N8XCx5xSQzjhidYjXllvEcqX/lopkoznlNPz3jyy0WGJCyhAaVQK677WWFt3YO/WUEkMMUFQ==", "dependencies": { - "@vue/compiler-dom": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-dom": "3.4.29", + "@vue/shared": "3.4.29" } }, "node_modules/@vue/devtools-api": { @@ -2874,48 +2851,49 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz", - "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.29.tgz", + "integrity": "sha512-w8+KV+mb1a8ornnGQitnMdLfE0kXmteaxLdccm2XwdFxXst4q/Z7SEboCV5SqJNpZbKFeaRBBJBhW24aJyGINg==", "dependencies": { - "@vue/shared": "3.4.27" + "@vue/shared": "3.4.29" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz", - "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.29.tgz", + "integrity": "sha512-s8fmX3YVR/Rk5ig0ic0NuzTNjK2M7iLuVSZyMmCzN/+Mjuqqif1JasCtEtmtoJWF32pAtUjyuT2ljNKNLeOmnQ==", "dependencies": { - "@vue/reactivity": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/reactivity": "3.4.29", + "@vue/shared": "3.4.29" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz", - "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.29.tgz", + "integrity": "sha512-gI10atCrtOLf/2MPPMM+dpz3NGulo9ZZR9d1dWo4fYvm+xkfvRrw1ZmJ7mkWtiJVXSsdmPbcK1p5dZzOCKDN0g==", "dependencies": { - "@vue/runtime-core": "3.4.27", - "@vue/shared": "3.4.27", + "@vue/reactivity": "3.4.29", + "@vue/runtime-core": "3.4.29", + "@vue/shared": "3.4.29", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz", - "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.29.tgz", + "integrity": "sha512-HMLCmPI2j/k8PVkSBysrA2RxcxC5DgBiCdj7n7H2QtR8bQQPqKAe8qoaxLcInzouBmzwJ+J0x20ygN/B5mYBng==", "dependencies": { - "@vue/compiler-ssr": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-ssr": "3.4.29", + "@vue/shared": "3.4.29" }, "peerDependencies": { - "vue": "3.4.27" + "vue": "3.4.29" } }, "node_modules/@vue/shared": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", - "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==" + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.29.tgz", + "integrity": "sha512-hQ2gAQcBO/CDpC82DCrinJNgOHI2v+FA7BDW4lMSPeBpQ7sRe2OLHWe5cph1s7D8DUQAwRt18dBDfJJ220APEA==" }, "node_modules/@vue/tsconfig": { "version": "0.5.1", @@ -2924,9 +2902,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3680,7 +3658,6 @@ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -6057,9 +6034,9 @@ } }, "node_modules/sass": { - "version": "1.77.4", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.4.tgz", - "integrity": "sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==", + "version": "1.77.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.5.tgz", + "integrity": "sha512-oDfX1mukIlxacPdQqNb6mV2tVCrnE+P3nVYioy72V5tlk56CPNcO4TCuFcaCRKKfJ1M3lH95CleRS+dVKL2qMg==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -6643,12 +6620,12 @@ } }, "node_modules/vite": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.13.tgz", - "integrity": "sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz", + "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", + "esbuild": "^0.21.3", "postcss": "^8.4.38", "rollup": "^4.13.0" }, @@ -6697,412 +6674,6 @@ } } }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, "node_modules/vscode-uri": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", @@ -7110,15 +6681,15 @@ "dev": true }, "node_modules/vue": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz", - "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==", - "dependencies": { - "@vue/compiler-dom": "3.4.27", - "@vue/compiler-sfc": "3.4.27", - "@vue/runtime-dom": "3.4.27", - "@vue/server-renderer": "3.4.27", - "@vue/shared": "3.4.27" + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.29.tgz", + "integrity": "sha512-8QUYfRcYzNlYuzKPfge1UWC6nF9ym0lx7mpGVPJYNhddxEf3DD0+kU07NTL0sXuiT2HuJuKr/iEO8WvXvT0RSQ==", + "dependencies": { + "@vue/compiler-dom": "3.4.29", + "@vue/compiler-sfc": "3.4.29", + "@vue/runtime-dom": "3.4.29", + "@vue/server-renderer": "3.4.29", + "@vue/shared": "3.4.29" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index fece0f765c7be49bec6b7c3abae08de28887b33c..1d9479a6f5d65fd4741320d34c7233fe5a4f218d 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "rollup-plugin-node-polyfills": "~0.2.1", "sass": "^1.66.0", "typescript": "~5.4.0", - "vite": "~5.2.0", + "vite": "~5.3.0", "vue-tsc": "~2.0.0" } } diff --git a/src/App.vue b/src/App.vue index d48b90e30e90cbab56645584b3f1e2e547849cf8..f679a7aebb1acd2a24d1ef92ab348399f7b1cf3b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -26,28 +26,31 @@ const s3KeyRepository = useS3KeyStore(); onBeforeMount(() => { OpenAPI.BASE = environment.API_BASE_URL; + userRepository.updateJWT(cookies.get("clowm-jwt")); + if (userRepository.authenticated) { + userRepository.getCurrentUser(); + } axios.interceptors.response.use( (res) => res, (err) => { if ( - (err.response.status === 400 || err.response.status === 403) && - err.response.data.detail?.includes("JWT") + err.response.status === 401 || + (err.response.status === 400 && + err.response.data.detail?.includes("JWT")) ) { userRepository.logout(); - cookies.remove("bearer"); router.push({ name: "login", query: { login_error: - err.response.status === 400 ? "token_invalid" : "token_expired", - next: route.name != "login" ? encodeURI(route.path) : undefined, + err.response.status === 401 ? "token_invalid" : "token_expired", + next: route.name !== "login" ? encodeURI(route.path) : undefined, }, }); } return Promise.reject(err); }, ); - userRepository.setToken(cookies.get("bearer")); router.afterEach((to, from) => { window._paq.push(["setReferrerUrl", from.path]); window._paq.push(["deleteCustomVariables", "page"]); @@ -82,7 +85,7 @@ onBeforeMount(() => { return { name: "workflows" }; } else if ( to.meta.requiresReviewerRole && - !(userRepository.rewiewer || userRepository.admin) + !(userRepository.reviewer || userRepository.admin) ) { return "/"; } else if ( diff --git a/src/client/index.ts b/src/client/index.ts index 4e8c4b36cd6a701bba0ad2f7b46e078f6fcd73e9..98752ac488193a71a44ea94354a30ae46310a955 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -8,6 +8,9 @@ export { OpenAPI } from './core/OpenAPI'; export type { OpenAPIConfig } from './core/OpenAPI'; export type { AnonymizedWorkflowExecution } from './models/AnonymizedWorkflowExecution'; +export type { ApiTokenIn } from './models/ApiTokenIn'; +export type { ApiTokenOut } from './models/ApiTokenOut'; +export type { ApiTokenPrivateOut } from './models/ApiTokenPrivateOut'; export type { Body_Bucket_update_bucket_public_state } from './models/Body_Bucket_update_bucket_public_state'; export type { Body_Workflow_Version_upload_workflow_version_icon } from './models/Body_Workflow_Version_upload_workflow_version_icon'; export type { BucketIn } from './models/BucketIn'; @@ -34,6 +37,7 @@ export type { ResourceVersionOut } from './models/ResourceVersionOut'; export { ResourceVersionStatus } from './models/ResourceVersionStatus'; export { RoleEnum } from './models/RoleEnum'; export type { S3Key } from './models/S3Key'; +export { ScopeEnum } from './models/ScopeEnum'; export type { UserIn } from './models/UserIn'; export type { UserOut } from './models/UserOut'; export type { UserOutExtended } from './models/UserOutExtended'; @@ -57,6 +61,7 @@ export type { WorkflowVersion } from './models/WorkflowVersion'; export { WorkflowVersionStatus } from './models/WorkflowVersionStatus'; export type { WorkflowVersionStatusSchema } from './models/WorkflowVersionStatusSchema'; +export { ApiTokenService } from './services/ApiTokenService'; export { AuthService } from './services/AuthService'; export { BucketService } from './services/BucketService'; export { BucketPermissionService } from './services/BucketPermissionService'; diff --git a/src/client/models/ApiTokenIn.ts b/src/client/models/ApiTokenIn.ts new file mode 100644 index 0000000000000000000000000000000000000000..38a68cae7c7cb1a5d59cc3983b88d7442ba74ffc --- /dev/null +++ b/src/client/models/ApiTokenIn.ts @@ -0,0 +1,20 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ScopeEnum } from './ScopeEnum'; +export type ApiTokenIn = { + /** + * Short name for the API token + */ + name: string; + /** + * Unix timestamp when the token should expire + */ + expires_at?: (number | null); + /** + * List of scopes this Api token has + */ + scopes: Array<ScopeEnum>; +}; + diff --git a/src/client/models/ApiTokenOut.ts b/src/client/models/ApiTokenOut.ts new file mode 100644 index 0000000000000000000000000000000000000000..d10e0620c8c81ce53f3fa550bb7446fef01746ad --- /dev/null +++ b/src/client/models/ApiTokenOut.ts @@ -0,0 +1,32 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ScopeEnum } from './ScopeEnum'; +export type ApiTokenOut = { + /** + * Short name for the API token + */ + name: string; + /** + * Unix timestamp when the token should expire + */ + expires_at?: (number | null); + /** + * List of scopes this Api token has + */ + scopes: Array<ScopeEnum>; + /** + * The ID of the token + */ + token_id: string; + /** + * The ID of the owner + */ + uid: string; + /** + * The UNIX timestamp when this token was created + */ + created_at: number; +}; + diff --git a/src/client/models/ApiTokenPrivateOut.ts b/src/client/models/ApiTokenPrivateOut.ts new file mode 100644 index 0000000000000000000000000000000000000000..6d2d22e9b6b6811d9128805f2f800581d18842eb --- /dev/null +++ b/src/client/models/ApiTokenPrivateOut.ts @@ -0,0 +1,36 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ScopeEnum } from './ScopeEnum'; +export type ApiTokenPrivateOut = { + /** + * Short name for the API token + */ + name: string; + /** + * Unix timestamp when the token should expire + */ + expires_at?: (number | null); + /** + * List of scopes this Api token has + */ + scopes: Array<ScopeEnum>; + /** + * The ID of the token + */ + token_id: string; + /** + * The ID of the owner + */ + uid: string; + /** + * The UNIX timestamp when this token was created + */ + created_at: number; + /** + * The actual token used for authentication + */ + token: string; +}; + diff --git a/src/client/models/ScopeEnum.ts b/src/client/models/ScopeEnum.ts new file mode 100644 index 0000000000000000000000000000000000000000..4dc5a355e7933c5ba9bd3959c1b16cb7835c8b61 --- /dev/null +++ b/src/client/models/ScopeEnum.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export enum ScopeEnum { + USER = 'user', + TOKEN = 'token', + X = 'x', +} diff --git a/src/client/models/UserOutExtended.ts b/src/client/models/UserOutExtended.ts index 4b0aa20a5c17d903740c1b1cfef598e178b62337..a05ecb616dfa92c76dde11b89fa03407d39cd2dd 100644 --- a/src/client/models/UserOutExtended.ts +++ b/src/client/models/UserOutExtended.ts @@ -24,5 +24,9 @@ export type UserOutExtended = { * Timestamp when the invitation token was created as UNIX timestamp */ invitation_token_created_at?: (number | null); + /** + * URL to the gravatar avatar based on the users email + */ + gravatar_url?: (string | null); }; diff --git a/src/client/services/ApiTokenService.ts b/src/client/services/ApiTokenService.ts new file mode 100644 index 0000000000000000000000000000000000000000..a088864e6bfe05b57cc85b40635d80da8ed11188 --- /dev/null +++ b/src/client/services/ApiTokenService.ts @@ -0,0 +1,121 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ApiTokenIn } from '../models/ApiTokenIn'; +import type { ApiTokenOut } from '../models/ApiTokenOut'; +import type { ApiTokenPrivateOut } from '../models/ApiTokenPrivateOut'; +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; +export class ApiTokenService { + /** + * List API token + * List meta information about all API token. + * + * Permissions `api_token:list_all` required. See parameter `uid` for exception. + * @param uid UID of the user to filter for. Permission `api_token:list` required if current users is the target. + * @returns ApiTokenOut Successful Response + * @throws ApiError + */ + public static apiTokenListToken( + uid?: string, + ): CancelablePromise<Array<ApiTokenOut>> { + return __request(OpenAPI, { + method: 'GET', + url: '/tokens', + query: { + 'uid': uid, + }, + errors: { + 400: `Error decoding JWT Token`, + 401: `Not Authenticated`, + 403: `Not Authorized`, + 404: `Entity not Found`, + 422: `Validation Error`, + }, + }); + } + /** + * Create new API token + * Create a new API token for the current user. + * + * Permission `api_token:create` required. + * @param requestBody + * @returns ApiTokenPrivateOut Successful Response + * @throws ApiError + */ + public static apiTokenCreateToken( + requestBody: ApiTokenIn, + ): CancelablePromise<ApiTokenPrivateOut> { + return __request(OpenAPI, { + method: 'POST', + url: '/tokens', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Error decoding JWT Token`, + 401: `Not Authenticated`, + 403: `Not Authorized`, + 404: `Entity not Found`, + 422: `Validation Error`, + }, + }); + } + /** + * Get API token + * Get an API token by id. + * + * Permission `api_token:read` required if the current user is the owner of the API token, + * otherwise `api_token:read_any` required. + * @param tid ID of an API token + * @returns ApiTokenOut Successful Response + * @throws ApiError + */ + public static apiTokenGetToken( + tid: string, + ): CancelablePromise<ApiTokenOut> { + return __request(OpenAPI, { + method: 'GET', + url: '/tokens/{tid}', + path: { + 'tid': tid, + }, + errors: { + 400: `Error decoding JWT Token`, + 401: `Not Authenticated`, + 403: `Not Authorized`, + 404: `Entity not Found`, + 422: `Validation Error`, + }, + }); + } + /** + * Delete API token + * Delete an API token by id. + * + * Permission `api_token:delete` required if the current user is the owner of the API token, + * otherwise `api_token:delete_any` required. + * @param tid ID of an API token + * @returns void + * @throws ApiError + */ + public static apiTokenDeleteToken( + tid: string, + ): CancelablePromise<void> { + return __request(OpenAPI, { + method: 'DELETE', + url: '/tokens/{tid}', + path: { + 'tid': tid, + }, + errors: { + 400: `Error decoding JWT Token`, + 401: `Not Authenticated`, + 403: `Not Authorized`, + 404: `Entity not Found`, + 422: `Validation Error`, + }, + }); + } +} diff --git a/src/client/services/WorkflowCredentialsService.ts b/src/client/services/WorkflowCredentialsService.ts index 4d3b74cb483295567066b646fbc2e683753c0e6e..01e4e44bec76bf5ee746fa2d9edfab0e5f49a688 100644 --- a/src/client/services/WorkflowCredentialsService.ts +++ b/src/client/services/WorkflowCredentialsService.ts @@ -70,7 +70,7 @@ export class WorkflowCredentialsService { * Delete the credentials of a workflow * Delete the credentials for the repository of a workflow. * - * Permission `workflow:delete` required if the developer of the workflow is the same as the the current user, + * Permission `workflow:delete` required if the developer of the workflow is the same as the current user, * other `workflow:delete_any`. * @param wid ID of a workflow * @returns void diff --git a/src/components/AppHeader.vue b/src/components/AppHeader.vue index e8799490aeb9b59ad9ce9dc4575ab055f0b2012b..4312813b0e10c45c3bd1845a9b7f52ea93c8b66e 100644 --- a/src/components/AppHeader.vue +++ b/src/components/AppHeader.vue @@ -1,18 +1,18 @@ <script setup lang="ts"> import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { useUserStore } from "@/stores/users"; -import { useRoute } from "vue-router"; +import { useRoute, useRouter } from "vue-router"; import { watch, ref, computed } from "vue"; import BootstrapModal from "@/components/modals/BootstrapModal.vue"; import { OpenAPI } from "@/client"; -import CopyToClipboardIcon from "@/components/CopyToClipboardIcon.vue"; -import dayjs from "dayjs"; const userRepository = useUserStore(); const route = useRoute(); +const router = useRouter(); function logout() { userRepository.logout(); + router.push({ name: "login" }); } const activeRoute = ref(""); @@ -136,7 +136,7 @@ watch( <li v-if=" userRepository.workflowDev || - userRepository.rewiewer || + userRepository.reviewer || userRepository.admin " > @@ -149,7 +149,7 @@ watch( >My Workflows </router-link> </li> - <li v-if="userRepository.rewiewer || userRepository.admin"> + <li v-if="userRepository.reviewer || userRepository.admin"> <router-link class="dropdown-item" :to="{ name: 'workflows-reviewer' }" @@ -183,7 +183,7 @@ watch( <li v-if=" userRepository.resourceMaintainer || - userRepository.rewiewer || + userRepository.reviewer || userRepository.admin " > @@ -198,7 +198,7 @@ watch( >My Resources </router-link> </li> - <li v-if="userRepository.rewiewer || userRepository.admin"> + <li v-if="userRepository.reviewer || userRepository.admin"> <router-link class="dropdown-item" :to="{ name: 'resource-review' }" @@ -265,8 +265,14 @@ watch( data-bs-toggle="dropdown" aria-expanded="false" > - <strong class="me-2">{{ userRepository.user?.display_name }}</strong> - <font-awesome-icon icon="fa-solid fa-circle-user" class="fs-5" /> + <strong class="me-2">{{ userRepository.user.display_name }}</strong> + <img + :src="userRepository.user.gravatar_url + '?d=mp&s=32'" + class="rounded-circle" + height="32" + width="32" + alt="profile picture" + /> </a> <ul class="dropdown-menu text-small shadow" @@ -333,29 +339,6 @@ watch( </tr> </tbody> </table> - <div class="mt-4"> - <label for="clowm-jwt" class="form-label" - >JWT for Services (expires at - {{ - dayjs - .unix(userRepository.decodedToken!.exp) - .format("DD.MM.YYYY HH:mm") - }})</label - > - <div class="input-group"> - <input - type="text" - readonly - class="form-control text-truncate" - id="clowm-jwt" - :value="userRepository.token" - aria-describedby="clowm-jwt-copy" - /> - <span class="input-group-text" id="clowm-jwt-copy" - ><copy-to-clipboard-icon :text="userRepository.token ?? ''" - /></span> - </div> - </div> </template> <template v-slot:footer> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal"> diff --git a/src/stores/users.ts b/src/stores/users.ts index 259749fe1e00891ec6a8f38397f7680ee29609ba..de3c95da90d614f00428b41ced312af99f1e1ea5 100644 --- a/src/stores/users.ts +++ b/src/stores/users.ts @@ -1,6 +1,6 @@ import { defineStore } from "pinia"; import type { UserOutExtended, UserOut, UserIn } from "@/client"; -import { OpenAPI, UserService, RoleEnum } from "@/client"; +import { UserService, RoleEnum } from "@/client"; import { useWorkflowExecutionStore } from "@/stores/workflowExecutions"; import { useBucketStore } from "@/stores/buckets"; import { useWorkflowStore } from "@/stores/workflows"; @@ -35,56 +35,64 @@ export const useUserStore = defineStore({ id: "user", state: () => ({ - token: null, - decodedToken: null, user: null, + token: null, + roles: [], }) as { - token: string | null; - decodedToken: DecodedToken | null; user: UserOutExtended | null; + token: DecodedToken | null; + roles: RoleEnum[]; }, getters: { roles(): string[] { - return this.user?.roles?.map((role) => role.toString()) ?? []; + return ( + this.user?.roles?.map((role) => role.toString()) ?? + JSON.parse(localStorage.getItem("roles") ?? "[]") + ); + }, + authenticated(): boolean { + return this.token != null || this.user != null; }, - authenticated: (state) => state.token != null, currentUID(): string { - return this.user?.uid ?? this.decodedToken?.["sub"] ?? ""; - }, - foreignUser: (state) => (state.user?.roles ?? []).length == 0, - normalUser: (state) => state.user?.roles.includes(RoleEnum.USER) ?? false, - rewiewer: (state) => state.user?.roles.includes(RoleEnum.REVIEWER) ?? false, - workflowDev: (state) => - state.user?.roles.includes(RoleEnum.DEVELOPER) ?? false, - resourceMaintainer: (state) => - state.user?.roles.includes(RoleEnum.DB_MAINTAINER) ?? false, - admin: (state) => - state.user?.roles.includes(RoleEnum.ADMINISTRATOR) ?? false, + return this.user?.uid ?? this.token?.sub ?? ""; + }, + foreignUser(): boolean { + return this.roles.length === 0; + }, + normalUser(): boolean { + return this.roles.includes(RoleEnum.USER); + }, + reviewer(): boolean { + return this.roles.includes(RoleEnum.REVIEWER); + }, + workflowDev(): boolean { + return this.roles.includes(RoleEnum.DEVELOPER); + }, + resourceMaintainer(): boolean { + return this.roles.includes(RoleEnum.DB_MAINTAINER); + }, + admin(): boolean { + return this.roles.includes(RoleEnum.ADMINISTRATOR); + }, }, actions: { - setToken(token: string | null) { - if (token != null) { - this.token = token; - this.decodedToken = parseJwt(token); - OpenAPI.TOKEN = token; - UserService.userGetLoggedInUser() - .then((user) => { - this.updateUser(user); - }) - .catch(() => { - this.token = null; - }); - } else { - this.logout(); - } + getCurrentUser(): Promise<UserOutExtended> { + return UserService.userGetLoggedInUser().then((user) => { + this.updateUser(user); + return user; + }); + }, + updateJWT(jwt: string | null) { + this.token = jwt != null ? parseJwt(jwt) : null; }, updateUser(user: UserOutExtended) { this.user = user; + localStorage.setItem("currentUser", user.uid); + localStorage.setItem("roles", JSON.stringify(user.roles)); useNameStore().addNameToMapping(user.uid, user.display_name); }, logout() { window._paq.push(["resetUserId"]); - OpenAPI.TOKEN = undefined; this.$reset(); localStorage.clear(); dbclear(); diff --git a/src/views/workflows/WorkflowView.vue b/src/views/workflows/WorkflowView.vue index f99d1d2d2741ca39d5bda18b3e8b4c6fded9e789..f0c7afda308dd9f4482e4180b9babe66b9f8469c 100644 --- a/src/views/workflows/WorkflowView.vue +++ b/src/views/workflows/WorkflowView.vue @@ -98,7 +98,7 @@ const gitIcon = computed<string>(() => const allowVersionDeprecation = computed<boolean>(() => { if (activeVersion.value?.status === WorkflowVersionStatus.PUBLISHED) { - if (userRepository.rewiewer || userRepository.admin) { + if (userRepository.reviewer || userRepository.admin) { return true; } else if ( userRepository.workflowDev &&