diff options
Diffstat (limited to 'front-end')
-rw-r--r-- | front-end/package-lock.json | 370 | ||||
-rw-r--r-- | front-end/package.json | 6 | ||||
-rw-r--r-- | front-end/src/buttons.scss | 10 | ||||
-rw-r--r-- | front-end/src/components/Bookmarks.vue | 1 | ||||
-rw-r--r-- | front-end/src/components/Boomarks/AddOrUpdateForm.vue | 118 | ||||
-rw-r--r-- | front-end/src/components/Settings.vue | 8 | ||||
-rw-r--r-- | front-end/src/components/Settings/Bookmarks.vue | 84 | ||||
-rw-r--r-- | front-end/src/components/Settings/PkiSettings.vue | 5 | ||||
-rw-r--r-- | front-end/src/components/Settings/Registation.vue | 2 | ||||
-rw-r--r-- | front-end/src/main.ts | 4 | ||||
-rw-r--r-- | front-end/src/store/bookmarks.ts | 4 | ||||
-rw-r--r-- | front-end/src/store/socialMfaPlugin.ts | 74 | ||||
-rw-r--r-- | front-end/src/store/websiteLookup.ts | 76 |
13 files changed, 453 insertions, 309 deletions
diff --git a/front-end/package-lock.json b/front-end/package-lock.json index 9231ae5..856b959 100644 --- a/front-end/package-lock.json +++ b/front-end/package-lock.json @@ -10,7 +10,7 @@ "license": "agpl3", "dependencies": { "@headlessui/vue": "^1.7.17", - "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/eb9752ab262522271ccaf1ff127658b7202289a4/@vnuge-vnlib.browser/release.tgz", + "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/f2ac807486a00db4ba8486133d567e392f0fe98a/@vnuge-vnlib.browser/release.tgz", "@vuelidate/core": "^2.0.2", "@vuelidate/validators": "^2.0.2", "@vueuse/core": "^10.3.x", @@ -62,9 +62,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -588,14 +588,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", - "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -611,9 +611,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" @@ -625,9 +625,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", - "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -686,9 +686,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", - "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.1.tgz", + "integrity": "sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==", "cpu": [ "arm" ], @@ -699,9 +699,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", - "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.1.tgz", + "integrity": "sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==", "cpu": [ "arm64" ], @@ -712,9 +712,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", - "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.1.tgz", + "integrity": "sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==", "cpu": [ "arm64" ], @@ -725,9 +725,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", - "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.1.tgz", + "integrity": "sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==", "cpu": [ "x64" ], @@ -738,9 +738,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", - "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.1.tgz", + "integrity": "sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==", "cpu": [ "arm" ], @@ -751,9 +751,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", - "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.1.tgz", + "integrity": "sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==", "cpu": [ "arm64" ], @@ -764,9 +764,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", - "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.1.tgz", + "integrity": "sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==", "cpu": [ "arm64" ], @@ -777,9 +777,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", - "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.1.tgz", + "integrity": "sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==", "cpu": [ "riscv64" ], @@ -790,9 +790,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", - "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.1.tgz", + "integrity": "sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==", "cpu": [ "x64" ], @@ -803,9 +803,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", - "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.1.tgz", + "integrity": "sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==", "cpu": [ "x64" ], @@ -816,9 +816,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", - "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.1.tgz", + "integrity": "sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==", "cpu": [ "arm64" ], @@ -829,9 +829,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", - "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.1.tgz", + "integrity": "sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==", "cpu": [ "ia32" ], @@ -842,9 +842,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", - "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.1.tgz", + "integrity": "sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==", "cpu": [ "x64" ], @@ -855,20 +855,20 @@ ] }, "node_modules/@tanstack/virtual-core": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.1.2.tgz", - "integrity": "sha512-DATZJs8iejkIUqXZe6ruDAnjFo78BKnIIgqQZrc7CmEFqfLEN/TPD91n4hRfo6hpRB6xC00bwKxv7vdjFNEmOg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.1.3.tgz", + "integrity": "sha512-Y5B4EYyv1j9V8LzeAoOVeTg0LI7Fo5InYKgAjkY1Pu9GjtUwX/EKxNcU7ng3sKr99WEf+bPTcktAeybyMOYo+g==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/vue-virtual": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.1.2.tgz", - "integrity": "sha512-RmUnhsFtRw9p4Ti/+rG2Hr3y4yFhs8Xdsn7x9tkPoKINbVya/5RSCoNUCCAg2iXNjOI5a55iBNzNV0SVwxMwKA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.1.3.tgz", + "integrity": "sha512-OoRCSgp8Bc85Te3pg4OHFUukbWZeB25/O5rNd7MgMtrYIfJjNOaicZeJcvwqK6lDVTMpzohWUMVK/loqR1H8ig==", "dependencies": { - "@tanstack/virtual-core": "3.1.2" + "@tanstack/virtual-core": "3.1.3" }, "funding": { "type": "github", @@ -930,8 +930,8 @@ }, "node_modules/@vnuge/vnlib.browser": { "version": "0.1.13", - "resolved": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/eb9752ab262522271ccaf1ff127658b7202289a4/@vnuge-vnlib.browser/release.tgz", - "integrity": "sha512-yqJXL0H8g27KoCijlPXSG75ZxfWab4cFVdT2t2b+iodpHeytZHemlNteTubzMurA8WRg95WW3Z3mf5R184UnZA==", + "resolved": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/f2ac807486a00db4ba8486133d567e392f0fe98a/@vnuge-vnlib.browser/release.tgz", + "integrity": "sha512-j3BwCdXWJ46Q7GohS+rZg7M5k1/AS+uuycP7wY8RWI2YBKS80uTE6jbWZ0OuCybclBrCufvW7SlTTpfsbf33mw==", "license": "MIT", "peerDependencies": { "@vueuse/core": "^10.x", @@ -940,8 +940,7 @@ "jose": "^5.x", "lodash-es": "^4.x", "universal-cookie": "^7.0.x", - "vue": "^3.x", - "vue-router": "^4.x" + "vue": "^3.x" } }, "node_modules/@volar/language-core": { @@ -973,49 +972,49 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", - "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", "dependencies": { "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.19", + "@vue/shared": "3.4.21", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", - "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", + "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", "dependencies": { - "@vue/compiler-core": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz", - "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", + "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", "dependencies": { "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.19", - "@vue/compiler-dom": "3.4.19", - "@vue/compiler-ssr": "3.4.19", - "@vue/shared": "3.4.19", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21", "estree-walker": "^2.0.2", - "magic-string": "^0.30.6", - "postcss": "^8.4.33", + "magic-string": "^0.30.7", + "postcss": "^8.4.35", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", - "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", + "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", "dependencies": { - "@vue/compiler-dom": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/devtools-api": { @@ -1073,48 +1072,48 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz", - "integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz", + "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", "dependencies": { - "@vue/shared": "3.4.19" + "@vue/shared": "3.4.21" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz", - "integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz", + "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", "dependencies": { - "@vue/reactivity": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/reactivity": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz", - "integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", + "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", "dependencies": { - "@vue/runtime-core": "3.4.19", - "@vue/shared": "3.4.19", + "@vue/runtime-core": "3.4.21", + "@vue/shared": "3.4.21", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz", - "integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz", + "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", "dependencies": { - "@vue/compiler-ssr": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21" }, "peerDependencies": { - "vue": "3.4.19" + "vue": "3.4.21" } }, "node_modules/@vue/shared": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", - "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", + "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==" }, "node_modules/@vuelidate/core": { "version": "2.0.3", @@ -1201,13 +1200,13 @@ } }, "node_modules/@vueuse/core": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.8.0.tgz", - "integrity": "sha512-G9Ok9fjx10TkNIPn8V1dJmK1NcdJCtYmDRyYiTMUyJ1p0Tywc1zmOoCQ2xhHYyz8ULBU4KjIJQ9n+Lrty74iVw==", + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", + "integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==", "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.8.0", - "@vueuse/shared": "10.8.0", + "@vueuse/metadata": "10.9.0", + "@vueuse/shared": "10.9.0", "vue-demi": ">=0.14.7" }, "funding": { @@ -1240,17 +1239,17 @@ } }, "node_modules/@vueuse/metadata": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.8.0.tgz", - "integrity": "sha512-Nim/Vle5OgXcXhAvGOgkJQXB1Yb+Kq/fMbLuv3YYDYbiQrwr39ljuD4k9fPeq4yUyokYRo2RaNQmbbIMWB/9+w==", + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz", + "integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.8.0.tgz", - "integrity": "sha512-dUdy6zwHhULGxmr9YUg8e+EnB39gcM4Fe2oKBSrh3cOsV30JcMPtsyuspgFCUo5xxFNaeMf/W2yyKfST7Bg8oQ==", + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz", + "integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==", "dependencies": { "vue-demi": ">=0.14.7" }, @@ -1377,9 +1376,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", + "version": "10.4.18", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", + "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", "dev": true, "funding": [ { @@ -1396,8 +1395,8 @@ } ], "dependencies": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001591", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -1521,9 +1520,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001589", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", - "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", + "version": "1.0.30001597", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", + "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", "dev": true, "funding": [ { @@ -1757,9 +1756,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.681", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz", - "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==", + "version": "1.4.700", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.700.tgz", + "integrity": "sha512-40dqKQ3F7C8fbBEmjSeJ+qEHCKzPyrP9SkeIBZ3wSCUH9nhWStrDz030XlDzlhNhlul1Z0fz7TpDFnsIzo4Jtg==", "dev": true }, "node_modules/emoji-regex": { @@ -2254,9 +2253,9 @@ } }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { "function-bind": "^1.1.2" @@ -2433,9 +2432,9 @@ } }, "node_modules/jose": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/jose/-/jose-5.2.2.tgz", - "integrity": "sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.2.3.tgz", + "integrity": "sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -2560,9 +2559,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", - "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -3224,9 +3223,9 @@ } }, "node_modules/rollup": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", - "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.1.tgz", + "integrity": "sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -3239,19 +3238,19 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.12.0", - "@rollup/rollup-android-arm64": "4.12.0", - "@rollup/rollup-darwin-arm64": "4.12.0", - "@rollup/rollup-darwin-x64": "4.12.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", - "@rollup/rollup-linux-arm64-gnu": "4.12.0", - "@rollup/rollup-linux-arm64-musl": "4.12.0", - "@rollup/rollup-linux-riscv64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-musl": "4.12.0", - "@rollup/rollup-win32-arm64-msvc": "4.12.0", - "@rollup/rollup-win32-ia32-msvc": "4.12.0", - "@rollup/rollup-win32-x64-msvc": "4.12.0", + "@rollup/rollup-android-arm-eabi": "4.12.1", + "@rollup/rollup-android-arm64": "4.12.1", + "@rollup/rollup-darwin-arm64": "4.12.1", + "@rollup/rollup-darwin-x64": "4.12.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.1", + "@rollup/rollup-linux-arm64-gnu": "4.12.1", + "@rollup/rollup-linux-arm64-musl": "4.12.1", + "@rollup/rollup-linux-riscv64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-musl": "4.12.1", + "@rollup/rollup-win32-arm64-msvc": "4.12.1", + "@rollup/rollup-win32-ia32-msvc": "4.12.1", + "@rollup/rollup-win32-x64-msvc": "4.12.1", "fsevents": "~2.3.2" } }, @@ -3656,9 +3655,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "devOptional": true, "bin": { "tsc": "bin/tsc", @@ -3723,9 +3722,9 @@ "dev": true }, "node_modules/vite": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz", - "integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", + "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", "dev": true, "dependencies": { "esbuild": "^0.19.3", @@ -3778,15 +3777,15 @@ } }, "node_modules/vue": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz", - "integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz", + "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", "dependencies": { - "@vue/compiler-dom": "3.4.19", - "@vue/compiler-sfc": "3.4.19", - "@vue/runtime-dom": "3.4.19", - "@vue/server-renderer": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-sfc": "3.4.21", + "@vue/runtime-dom": "3.4.21", + "@vue/server-renderer": "3.4.21", + "@vue/shared": "3.4.21" }, "peerDependencies": { "typescript": "*" @@ -3821,21 +3820,6 @@ "eslint": ">=6.0.0" } }, - "node_modules/vue-router": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz", - "integrity": "sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==", - "peer": true, - "dependencies": { - "@vue/devtools-api": "^6.5.1" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "vue": "^3.2.0" - } - }, "node_modules/vue-template-compiler": { "version": "2.7.16", "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", @@ -3864,9 +3848,9 @@ } }, "node_modules/vue3-otp-input": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/vue3-otp-input/-/vue3-otp-input-0.4.1.tgz", - "integrity": "sha512-wVl9i3DcWlO0C7fBI9V+RIP3crm/1tY72fuhvb3YM2JfbLoYofB96aPl5AgFhA0Cse5bQEMYtIvOeiqW3rfbAw==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/vue3-otp-input/-/vue3-otp-input-0.4.4.tgz", + "integrity": "sha512-LI1MeBiiEy59cnjqXzlcz4G4cMxZcHF/xOKilb6sfw4uFHfQ22Luu2ls0Bb51zL0pb3gGp7RuIL5eurEJXkoBg==", "engines": { "node": ">=16.0.0", "npm": ">=8.0.0" @@ -3996,9 +3980,9 @@ "dev": true }, "node_modules/yaml": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz", - "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", "dev": true, "bin": { "yaml": "bin.mjs" diff --git a/front-end/package.json b/front-end/package.json index 30accd8..0631eae 100644 --- a/front-end/package.json +++ b/front-end/package.json @@ -14,11 +14,13 @@ "dev": "vite", "watch": "vite build --watch --mode development --minify false", "build": "vite build", - "preview": "vite preview" + "preview": "vite preview", + "update": "npm update", + "oudated": "npm outdated" }, "dependencies": { "@headlessui/vue": "^1.7.17", - "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/eb9752ab262522271ccaf1ff127658b7202289a4/@vnuge-vnlib.browser/release.tgz", + "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/f2ac807486a00db4ba8486133d567e392f0fe98a/@vnuge-vnlib.browser/release.tgz", "@vuelidate/core": "^2.0.2", "@vuelidate/validators": "^2.0.2", "@vueuse/core": "^10.3.x", diff --git a/front-end/src/buttons.scss b/front-end/src/buttons.scss index 7088deb..44df2c2 100644 --- a/front-end/src/buttons.scss +++ b/front-end/src/buttons.scss @@ -1,5 +1,13 @@ .btn{ - @apply focus:ring-2 focus:outline-none font-medium rounded text-sm px-4 py-2 text-center text-white; + @apply focus:ring-2 focus:outline-none font-medium rounded text-sm px-2.5 py-2 text-center text-white; + + &.sm{ + @apply text-xs px-2 py-1; + } + + &.lg{ + @apply text-lg px-4 py-3; + } &.round{ @apply rounded-full; diff --git a/front-end/src/components/Bookmarks.vue b/front-end/src/components/Bookmarks.vue index cc3cd6a..274b0b4 100644 --- a/front-end/src/components/Bookmarks.vue +++ b/front-end/src/components/Bookmarks.vue @@ -387,7 +387,6 @@ const upload = (() => { <span class="sr-only">Search</span> </button> </form> - </div> <div class="relative ml-3 md:ml-10"> diff --git a/front-end/src/components/Boomarks/AddOrUpdateForm.vue b/front-end/src/components/Boomarks/AddOrUpdateForm.vue index a4a3f1d..0370e0c 100644 --- a/front-end/src/components/Boomarks/AddOrUpdateForm.vue +++ b/front-end/src/components/Boomarks/AddOrUpdateForm.vue @@ -1,6 +1,8 @@ <script setup lang="ts"> import { computed, toRefs } from 'vue'; -import { join, split } from 'lodash-es'; +import { isEmpty, join, split } from 'lodash-es'; +import { useStore } from '../../store'; +import { useWait } from '@vnuge/vnlib.browser'; const emit = defineEmits(['submit']) const props = defineProps<{ @@ -15,54 +17,110 @@ const tags = computed({ set: (value:string) => v$.value.Tags.$model = split(value, ',') }) +const { websiteLookup:lookup } = useStore() +const { setWaiting, waiting } = useWait() + +const execLookup = async () => { + //url must be valid before searching + if(v$.value.Url.$invalid) return + + setWaiting(true) + + try{ + const { title, description, keywords } = await lookup.execLookup(v$.value.Url.$model); + + //Set the title and description + if(title){ + v$.value.Name.$model = title; + v$.value.Name.$dirty = true; + } + + if(description){ + v$.value.Description.$model = description; + v$.value.Description.$dirty = true; + } + + if(!isEmpty(keywords)){ + v$.value.Tags.$model = keywords; + v$.value.Tags.$dirty = true; + } + } + catch(e){ + //Mostly ignore errors + console.error(e) + } + finally{ + setWaiting(false) + } +} + +const showSearchButton = computed(() => lookup.isSupported && !isEmpty(v$.value.Url.$model)) + </script> <template> - <form class="grid grid-cols-1 gap-4 p-4" @submit.prevent="emit('submit')"> + <form id="bm-add-or-update-form" class="grid grid-cols-1 gap-4 p-4" @submit.prevent="emit('submit')"> <fieldset> - <label for="url" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">URL</label> - <input type="text" id="url" class="input" placeholder="https://www.example.com" - v-model="v$.Url.$model" - :class="{'dirty': v$.Url.$dirty, 'error': v$.Url.$invalid}" - required - > + <label for="url" class="flex justify-between mb-2 text-sm font-medium text-gray-900 dark:text-white"> + URL + </label> + <div class="flex gap-2"> + <input type="text" id="url" class="input" placeholder="https://www.example.com" v-model="v$.Url.$model" + :class="{'dirty': v$.Url.$dirty, 'error': v$.Url.$invalid}" required> + + <div class=""> + <button + type="button" + :disabled="!showSearchButton || waiting" + @click.self.prevent="execLookup" + id="search-btn" + class="btn blue search-btn" + > + <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" + viewBox="0 0 20 20"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" + d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" /> + </svg> + </button> + </div> + </div> </fieldset> <fieldset> <label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Title</label> - <input type="text" id="Name" class="input" placeholder="Hello World" - v-model="v$.Name.$model" - :class="{'dirty': v$.Name.$dirty, 'error': v$.Name.$invalid}" - required - > + <input type="text" id="Name" class="input" placeholder="Hello World" v-model="v$.Name.$model" + :class="{'dirty': v$.Name.$dirty, 'error': v$.Name.$invalid}" required> </fieldset> - <fieldset> + <fieldset> <label for="tags" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Tags</label> - <input type="text" id="tags" class="input" placeholder="tag1,tag2,tag3" - v-model="tags" - :class="{'dirty': v$.Tags.$dirty, 'error': v$.Tags.$invalid}" - > + <input type="text" id="tags" class="input" placeholder="tag1,tag2,tag3" v-model="tags" + :class="{'dirty': v$.Tags.$dirty, 'error': v$.Tags.$invalid}"> </fieldset> <fieldset> - <label for="description" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Description</label> + <label for="description" + class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Description</label> <textarea type="text" id="description" rows="5" class="input" placeholder="This is a bookmark" v-model="v$.Description.$model" - :class="{'dirty': v$.Description.$dirty, 'error': v$.Description.$invalid}" - /> + :class="{'dirty': v$.Description.$dirty, 'error': v$.Description.$invalid}" /> </fieldset> - + <div class="flex justify-end"> - <button type="submit" class="btn blue"> - Submit + <button id="save-button" type="submit" form="bm-add-or-update-form" class="btn blue"> + Save </button> </div> </form> </template> -<style scoped lang="scss">input.search { - @apply ps-10 p-2.5 border block w-full text-sm rounded; - @apply bg-gray-50 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 border-gray-300 text-gray-900 focus:ring-blue-500 focus:border-blue-500; -} +<style scoped lang="scss"> + +#bm-add-or-update-form { + .search-btn{ -button.search { - @apply p-2.5 ms-2 text-sm font-medium text-white bg-blue-700 rounded border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 + @apply my-auto px-3 py-2.5; + + &:disabled{ + @apply bg-gray-600; + } + } } + </style>
\ No newline at end of file diff --git a/front-end/src/components/Settings.vue b/front-end/src/components/Settings.vue index 83d3f79..504f38a 100644 --- a/front-end/src/components/Settings.vue +++ b/front-end/src/components/Settings.vue @@ -19,7 +19,7 @@ const darkMode = useDark(); <h2 class="text-2xl font-bold">Settings</h2> <div class="flex flex-col w-full max-w-3xl gap-10 mt-3"> - <div class=""> + <div class="mb-6"> <h3 class="text-xl font-bold"> General </h3> @@ -41,7 +41,7 @@ const darkMode = useDark(); </div> </div> - <div class=""> + <div class="mb-6"> <h3 class="text-xl font-bold">Boomarks</h3> <div class="relative mt-4"> @@ -51,7 +51,7 @@ const darkMode = useDark(); <PasswordReset /> - <div class=""> + <div class="mb-8"> <h3 class="text-xl font-bold">Multi Factor Auth</h3> <div class="relative mt-4 py-2.5"> @@ -66,7 +66,7 @@ const darkMode = useDark(); <Oauth2Apps /> </div> - <div v-if="store.registation.status?.can_invite" class="mb-10"> + <div v-if="store.registation.status?.can_invite" class="mt-6 mb-10"> <Registation /> </div> diff --git a/front-end/src/components/Settings/Bookmarks.vue b/front-end/src/components/Settings/Bookmarks.vue index a4ab55a..aa4ed31 100644 --- a/front-end/src/components/Settings/Bookmarks.vue +++ b/front-end/src/components/Settings/Bookmarks.vue @@ -1,13 +1,14 @@ <script setup lang="ts"> import { apiCall, useWait } from '@vnuge/vnlib.browser'; import { useStore, type DownloadContentType, TabId } from '../../store'; -import { ref } from 'vue'; +import { computed, ref } from 'vue'; import { Menu, MenuButton, MenuItems, MenuItem } from '@headlessui/vue' -const { bookmarks } = useStore(); +const { bookmarks, websiteLookup } = useStore(); const downloadAnchor = ref(); const { waiting } = useWait() +const curlSupported = computed(() => websiteLookup.isSupported); const downloadBookmarks = (contentType: DownloadContentType) => { apiCall(async () => { @@ -58,8 +59,10 @@ javascript: (function() { </div> <p class="p-0.5 my-auto text-sm flex flex-row"> <span class=""> - <svg class="w-6 h-5 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12l4-4m-4 4 4 4"/> + <svg class="w-6 h-5 text-gray-800 dark:text-white" aria-hidden="true" + xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" + d="M5 12h14M5 12l4-4m-4 4 4 4" /> </svg> </span> <span> @@ -72,47 +75,66 @@ javascript: (function() { <MenuButton :disabled="waiting" class="flex items-center gap-3 btn light"> <div class="hidden lg:inline">Download</div> <svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"> - <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 13V4M7 14H5a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h14c.6 0 1-.4 1-1v-4c0-.6-.4-1-1-1h-2m-1-5-4 5-4-5m9 8h0"/> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" + d="M12 13V4M7 14H5a1 1 0 0 0-1 1v4c0 .6.4 1 1 1h14c.6 0 1-.4 1-1v-4c0-.6-.4-1-1-1h-2m-1-5-4 5-4-5m9 8h0" /> </svg> </MenuButton> - <transition - enter-active-class="transition duration-100 ease-out" - enter-from-class="transform scale-95 opacity-0" - enter-to-class="transform scale-100 opacity-100" + <transition enter-active-class="transition duration-100 ease-out" + enter-from-class="transform scale-95 opacity-0" enter-to-class="transform scale-100 opacity-100" leave-active-class="transition duration-75 ease-out" - leave-from-class="transform scale-100 opacity-100" - leave-to-class="transform scale-95 opacity-0" - > - <MenuItems class="absolute z-10 bg-white divide-y divide-gray-100 rounded-b shadow right-2 lg:left-0 min-w-32 lg:end-0 dark:bg-gray-700"> - <ul class="py-2 text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownDefaultButton"> + leave-from-class="transform scale-100 opacity-100" leave-to-class="transform scale-95 opacity-0"> + <MenuItems + class="absolute z-10 bg-white divide-y divide-gray-100 rounded-b shadow right-2 lg:left-0 min-w-32 lg:end-0 dark:bg-gray-700"> + <ul class="py-2 text-sm text-gray-700 dark:text-gray-200" + aria-labelledby="dropdownDefaultButton"> <!-- Use the `active` state to conditionally style the active item. --> <MenuItem as="template" v-slot="{ }"> - <li> - <button @click="downloadBookmarks('text/html')" class="block w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> - HTML - </button> - </li> + <li> + <button @click="downloadBookmarks('text/html')" + class="block w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> + HTML + </button> + </li> </MenuItem> <MenuItem as="template" v-slot="{ }"> - <li> - <button @click="downloadBookmarks('text/csv')" class="block w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> - CSV - </button> - </li> + <li> + <button @click="downloadBookmarks('text/csv')" + class="block w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> + CSV + </button> + </li> </MenuItem> - <MenuItem as="template" v-slot="{ }"> - <li> - <button @click="downloadBookmarks('application/json')" class="block w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> - JSON - </button> - </li> + <MenuItem as="template" v-slot="{ }"> + <li> + <button @click="downloadBookmarks('application/json')" + class="block w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> + JSON + </button> + </li> </MenuItem> </ul> </MenuItems> </transition> </Menu> </div> + <div class="mt-3"> + <h4 class="mb-2 font-bold">Features</h4> + <p class="text-sm text-gray-500 dark:text-gray-400"> + Some features for Simple-Bookmark use tools and applications that are already installed on + your server such as curl. + </p> + <div class="flex flex-row gap-2 mt-4"> + <span class="w-3 h-3 my-auto rounded-full" :class="[curlSupported ? 'bg-green-500' : 'bg-amber-500']"></span> + <span class="my-auto font-bold"> + curl + </span> + <span class="my-auto text-sm text-gray-500 ms-4 dark:text-gray-400"> + Curl is used to fetch website details like title, description and tags. + {{ curlSupported ? '(supported)' : '(not supported)' }} + </span> + </div> + </div> </div> - + <a ref="downloadAnchor" class="hidden"></a> </template>
\ No newline at end of file diff --git a/front-end/src/components/Settings/PkiSettings.vue b/front-end/src/components/Settings/PkiSettings.vue index dfa4cad..885b2cb 100644 --- a/front-end/src/components/Settings/PkiSettings.vue +++ b/front-end/src/components/Settings/PkiSettings.vue @@ -32,6 +32,8 @@ const removeKey = async (key: PkiPublicKey) => { title: 'Key Removed', text: `${key.kid} has been successfully removed` }) + + store.mfaRefreshMethods() }) } @@ -117,7 +119,8 @@ const onAddKey = async () => { text: result }) - hideAddKeyDialog() + hideAddKeyDialog(); + store.mfaRefreshMethods(); }) } diff --git a/front-end/src/components/Settings/Registation.vue b/front-end/src/components/Settings/Registation.vue index a0f208e..d0dfaa7 100644 --- a/front-end/src/components/Settings/Registation.vue +++ b/front-end/src/components/Settings/Registation.vue @@ -58,7 +58,7 @@ const onCancel = () => { <div class=""> <div class="flex flex-row justify-between w-full"> - <h3 class="text-xl font-bold">Registation</h3> + <h3 class="text-xl font-bold">Invite Links</h3> <div class="flex flex-row justify-end"> <button class="btn blue" @click="toggleOpen(true)">Invite User</button> diff --git a/front-end/src/main.ts b/front-end/src/main.ts index c5be406..2f2ca8e 100644 --- a/front-end/src/main.ts +++ b/front-end/src/main.ts @@ -30,6 +30,7 @@ import { mfaSettingsPlugin } from './store/mfaSettingsPlugin' import { socialMfaPlugin } from './store/socialMfaPlugin' import { bookmarkPlugin } from './store/bookmarks' import { registationPlugin } from './store/registation'; +import { siteLookupPlugin } from './store/websiteLookup'; //Setup the vnlib api configureApi({ @@ -67,9 +68,10 @@ store.use(profilePlugin('/account/profile')) //Enable mfa with totp settings plugin (optional pki config) .use(mfaSettingsPlugin('/account/mfa', '/account/pki')) //Setup social mfa plugin - .use(socialMfaPlugin()) + .use(socialMfaPlugin("/account/social/portals")) //Add the oauth2 apps plugin .use(bookmarkPlugin('/bookmarks')) + .use(siteLookupPlugin('/lookup', 2000)) .use(registationPlugin('/register')) //Setup oauth apps plugin (disabled for now) //.use(oauth2AppsPlugin('/oauth/apps', '/oauth/scopes')) diff --git a/front-end/src/store/bookmarks.ts b/front-end/src/store/bookmarks.ts index 2af8344..2d12a9a 100644 --- a/front-end/src/store/bookmarks.ts +++ b/front-end/src/store/bookmarks.ts @@ -18,7 +18,7 @@ import { MaybeRef, shallowRef, watch, computed, Ref, ref } from 'vue'; import { apiCall, useAxios, WebMessage } from '@vnuge/vnlib.browser'; import { useToggle, get, set, useOffsetPagination, watchDebounced, syncRef } from '@vueuse/core'; import { PiniaPluginContext, PiniaPlugin, storeToRefs } from 'pinia' -import { isArray, join, map, split, sortBy } from 'lodash-es'; +import { isArray, join, map, split, sortBy, filter, isEmpty } from 'lodash-es'; import { useQuery } from './index'; export interface Bookmark{ @@ -189,7 +189,7 @@ const searchQuery = (search: Ref<string | null>, tags: Ref<string[]>) => { const tagQuery = useQuery('t') const currentTags = computed({ - get: () => split(tagQuery.value, ' '), + get: () => filter(split(tagQuery.value, ' '), p => !isEmpty(p)), set: (value) => set(tagQuery, join(value, ' ')) }) diff --git a/front-end/src/store/socialMfaPlugin.ts b/front-end/src/store/socialMfaPlugin.ts index d8d7bb1..e0ec972 100644 --- a/front-end/src/store/socialMfaPlugin.ts +++ b/front-end/src/store/socialMfaPlugin.ts @@ -1,26 +1,19 @@ -// Copyright (C) 2024 Vaughn Nugent -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. import 'pinia' import { MaybeRef } from 'vue'; -import { useSocialOauthLogin, useUser, SocialOAuthPortal, fromPortals, useAxios } from '@vnuge/vnlib.browser' +import { + useUser, + useOauthLogin, + useSocialDefaultLogout, + fetchSocialPortals, + fromSocialPortals, + fromSocialConnections, +} from '@vnuge/vnlib.browser' import { get } from '@vueuse/core'; import { PiniaPluginContext, PiniaPlugin, storeToRefs } from 'pinia' import { defer } from 'lodash-es'; -type SocialMfaPlugin = ReturnType<typeof useSocialOauthLogin> +type SocialMfaPlugin = ReturnType<typeof useOauthLogin> declare module 'pinia' { export interface PiniaCustomProperties { @@ -35,43 +28,40 @@ export const socialMfaPlugin = (portalEndpoint?: MaybeRef<string>): PiniaPlugin const { } = storeToRefs(store) const { logout } = useUser() - /** - * Override the logout function to default to a social logout, - * if the social logout fails, then we will logout the user - */ - const setLogoutMethod = (socialOauth: SocialMfaPlugin) => { - const logoutFunc = socialOauth.logout; + //Create social login from available portals + const defaultSocial = useSocialDefaultLogout( + useOauthLogin([]), + logout //fallback to default logout + ); - (socialOauth as any).logout = async () => { - if (await logoutFunc() === false) { - await logout() - } - } - } - - const _loadPromise = new Promise<SocialMfaPlugin>((resolve, reject) => { + const _loadPromise = new Promise<SocialMfaPlugin>((resolve, _) => { - if(get(portalEndpoint) == null) { - const socialOauth = useSocialOauthLogin([]) - setLogoutMethod(socialOauth) - return resolve(socialOauth) + if (get(portalEndpoint) == null) { + return resolve(defaultSocial) } + /* + Try to load social methods from server, if it fails, then we will + fall back to default + */ + defer(async () => { + try { - //Get axios instance - const axios = useAxios(null) - //Get all enabled portals - const { data } = await axios.get<SocialOAuthPortal[]>(get(portalEndpoint)!); - //Setup social providers from server portals - const socialOauth = useSocialOauthLogin(fromPortals(data)); - setLogoutMethod(socialOauth); + const portals = await fetchSocialPortals(get(portalEndpoint)!); + const social = fromSocialPortals(portals); + const methods = fromSocialConnections(social); + + //Create social login from available portals + const login = useOauthLogin(methods); + const socialOauth = useSocialDefaultLogout(login, logout); resolve(socialOauth) } catch (error) { - reject(error) + //Let failure fall back to default + resolve(defaultSocial) } }) }) diff --git a/front-end/src/store/websiteLookup.ts b/front-end/src/store/websiteLookup.ts new file mode 100644 index 0000000..560d00f --- /dev/null +++ b/front-end/src/store/websiteLookup.ts @@ -0,0 +1,76 @@ + +import 'pinia' +import { MaybeRef, Ref, shallowRef, watch } from 'vue'; +import { WebMessage, apiCall, useAxios } from '@vnuge/vnlib.browser' +import { get, set } from '@vueuse/core'; +import { PiniaPluginContext, PiniaPlugin, storeToRefs } from 'pinia' +import { defer, filter, isEmpty, noop } from 'lodash-es'; + +export interface WebsiteLookupResult { + readonly title: string | undefined, + readonly description: string | undefined, + keywords: string[] | undefined, +} + +export interface LookupApi{ + isSupported: Ref<boolean>, + timeout: Ref<number>, + execLookup(url:string): Promise<WebsiteLookupResult> +} + +declare module 'pinia' { + export interface PiniaCustomProperties { + websiteLookup:{ + isSupported: boolean, + execLookup(url: string): Promise<WebsiteLookupResult> + } + } +} + +const urlToBase64UrlEncoded = (url: string) => { + return btoa(url) + .replace(/-/g, '+') + .replace(/_/g, '/') + .replace(/\./g, '=') //Fix padding +} + +export const siteLookupPlugin = (lookupEndpoint: MaybeRef<string>, to: number): PiniaPlugin => { + + return ({ store }: PiniaPluginContext) => { + + const { loggedIn } = storeToRefs(store) + const axios = useAxios(null) + + const isSupported = shallowRef(false) + const timeout = shallowRef(to) + + const checkIsSupported = () => { + return apiCall(async () => { + //Execute test with the 'support' query parameter + const { data } = await axios.get<WebMessage>(`${get(lookupEndpoint)}?support`) + set(isSupported, data.success) + }); + } + + const execLookup = async (url:string) => { + const base64Url = urlToBase64UrlEncoded(url) + + //Execute test with the 'support' query parameter + const { data } = await axios.get<WebMessage<WebsiteLookupResult>>(`${get(lookupEndpoint)}?timeout=${get(timeout)}&url=${base64Url}`) + const lookup = data.getResultOrThrow(); + lookup.keywords = filter(lookup.keywords, (k) => !isEmpty(k)) + return lookup + } + + //If login status changes, recheck support + watch([loggedIn], ([li]) => li ? defer(checkIsSupported) : noop(), { immediate: true }) + + return { + websiteLookup: { + isSupported, + execLookup, + timeout + } as LookupApi + } as any + } +}
\ No newline at end of file |