diff options
author | vnugent <public@vaughnnugent.com> | 2024-03-02 22:45:59 -0500 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2024-03-02 22:45:59 -0500 |
commit | e4b5b937a05a9869249619a3b17a7269648d93bd (patch) | |
tree | c55c9ae5650d3f1fc6d8104bcfed3860e9fe6bfa /extension | |
parent | 2bae750d6a4945e2916f1162d81717a954fd9fac (diff) |
fix: #4 added server discovery, close #6, and fix history view
Diffstat (limited to 'extension')
-rw-r--r-- | extension/.env | 5 | ||||
-rw-r--r-- | extension/package-lock.json | 844 | ||||
-rw-r--r-- | extension/package.json | 2 | ||||
-rw-r--r-- | extension/src/entries/options/components/Activity.vue | 14 | ||||
-rw-r--r-- | extension/src/entries/options/components/EventHistory.vue | 164 | ||||
-rw-r--r-- | extension/src/entries/options/components/Identities.vue | 8 | ||||
-rw-r--r-- | extension/src/entries/options/components/SiteSettings.vue | 167 | ||||
-rw-r--r-- | extension/src/entries/options/index.html | 2 | ||||
-rw-r--r-- | extension/src/entries/options/main.js | 4 | ||||
-rw-r--r-- | extension/src/entries/popup/Components/OtpLogin.vue | 6 | ||||
-rw-r--r-- | extension/src/entries/popup/Components/PageContent.vue | 192 | ||||
-rw-r--r-- | extension/src/entries/popup/Components/PassLogin.vue | 13 | ||||
-rw-r--r-- | extension/src/entries/store/features.ts | 12 | ||||
-rw-r--r-- | extension/src/entries/store/index.ts | 53 | ||||
-rw-r--r-- | extension/src/entries/store/types.ts | 10 | ||||
-rw-r--r-- | extension/src/features/index.ts | 2 | ||||
-rw-r--r-- | extension/src/features/server-api/index.ts | 30 | ||||
-rw-r--r-- | extension/src/features/settings.ts | 111 |
18 files changed, 972 insertions, 667 deletions
diff --git a/extension/.env b/extension/.env index 4e2f1ec..22e5a3e 100644 --- a/extension/.env +++ b/extension/.env @@ -1,12 +1,9 @@ MANIFEST_VERSION=2 -VITE_API_URL="http://localhost:8080" +VITE_DISCOVERY_URL="https://localhost:8080/.well-known/nvault" VITE_CORS_ENABLED=false VITE_WEB_TOKEN_HEADER="X-Web-Token" VITE_LOGIN_COOKIE_ID="li" -VITE_ACCOUNTS_BASE_PATH="/account" - -VITE_NOSTR_ENDPOINT='/nostr' VITE_HEARTBEAT_ENABLED=true
\ No newline at end of file diff --git a/extension/package-lock.json b/extension/package-lock.json index aa48e32..bca214c 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -17,7 +17,7 @@ "@fortawesome/vue-fontawesome": "^3.0.3", "@headlessui/vue": "^1.7.x", "@kyvg/vue3-notification": "^3.0.x", - "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/df7dc615532d3441f527374d18664c1a5a336de6/@vnuge-vnlib.browser/release.tgz", + "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/7f3067b8fc4416d46af9b8b005a18a71770c98fe/@vnuge-vnlib.browser/release.tgz", "@vuelidate/core": "^2.0.0", "@vuelidate/validators": "^2.0.0", "@vueuse/core": "^10.3.2", @@ -239,9 +239,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" }, @@ -706,9 +706,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -774,18 +774,18 @@ } }, "node_modules/@fortawesome/vue-fontawesome": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.5.tgz", - "integrity": "sha512-isZZ4+utQH9qg9cWxWYHQ9GwI3r5FeO7GnmzKYV+gbjxcptQhh+F99iZXi1Y9AvFUEgy8kRpAdvDlbb3drWFrw==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.6.tgz", + "integrity": "sha512-akrL7lTroyNpPkoHtvK2UpsMzJr6jXdHaQ0YdcwqDsB8jdwlpNHZYijpOUd9KJsARr+VB3WXY4EyObepqJ4ytQ==", "peerDependencies": { "@fortawesome/fontawesome-svg-core": "~1 || ~6", "vue": ">= 3.0.0 < 4" } }, "node_modules/@headlessui/vue": { - "version": "1.7.17", - "resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.17.tgz", - "integrity": "sha512-hmJChv8HzKorxd9F70RGnECAwZfkvmmwOqreuKLWY/19d5qbWnSdw+DNbuA/Uo6X5rb4U5B3NrT+qBKPmjhRqw==", + "version": "1.7.19", + "resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.19.tgz", + "integrity": "sha512-VFjKPybogux/5/QYGSq4zgG/x3RcxId15W8uguAJAjPBxelI23dwjOjTx/mIiMkM/Hd3rzFxcf2aIp56eEWRcA==", "dependencies": { "@tanstack/vue-virtual": "^3.0.0-beta.60" }, @@ -871,32 +871,32 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "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" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" } }, "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" @@ -908,9 +908,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "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", @@ -918,9 +918,9 @@ } }, "node_modules/@kyvg/vue3-notification": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@kyvg/vue3-notification/-/vue3-notification-3.1.3.tgz", - "integrity": "sha512-z66zE1b37oZodBjiTiaEumBfEyLzpPnDeqpSHlOomYAqeOWwfMGSSUbWc6GZCOFmlZSlfytFLdMJJmEwQUBbRw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@kyvg/vue3-notification/-/vue3-notification-3.2.0.tgz", + "integrity": "sha512-DKicfzxS6n7oMCkFoUqzb26Orjv8Oo3fhOgSDYM2I1mGDwBW+Tyb/yr2eauho0R+E5chNswZ3AUyAE9DqutXmg==", "peerDependencies": { "vue": "^3.0.0" } @@ -1011,9 +1011,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", - "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", + "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==", "cpu": [ "arm" ], @@ -1023,9 +1023,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", - "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", + "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", "cpu": [ "arm64" ], @@ -1035,9 +1035,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", - "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", + "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==", "cpu": [ "arm64" ], @@ -1047,9 +1047,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", - "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", + "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==", "cpu": [ "x64" ], @@ -1059,9 +1059,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", - "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", + "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==", "cpu": [ "arm" ], @@ -1071,9 +1071,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", - "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", + "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==", "cpu": [ "arm64" ], @@ -1083,9 +1083,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", - "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", + "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==", "cpu": [ "arm64" ], @@ -1095,9 +1095,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", - "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", + "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==", "cpu": [ "riscv64" ], @@ -1107,9 +1107,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", - "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", + "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==", "cpu": [ "x64" ], @@ -1119,9 +1119,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", - "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", + "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==", "cpu": [ "x64" ], @@ -1131,9 +1131,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", - "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", + "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==", "cpu": [ "arm64" ], @@ -1143,9 +1143,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", - "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", + "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==", "cpu": [ "ia32" ], @@ -1155,9 +1155,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", - "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", + "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==", "cpu": [ "x64" ], @@ -1220,20 +1220,20 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.0.0.tgz", - "integrity": "sha512-SYXOBTjJb05rXa2vl55TTwO40A6wKu0R5i1qQwhJYNDIqaIGF7D0HsLw+pJAyi2OvntlEIVusx3xtbbgSUi6zg==", + "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.0.2", - "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.0.2.tgz", - "integrity": "sha512-1iFpX+yZswHuf4wrA6GU9yJ/YzQ/8SacABwqghwCkcwrkZbOPLlRSdOAqZ1WQ50SftmfhZpaiZl2KmpV7cgfMQ==", + "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.0.0" + "@tanstack/virtual-core": "3.1.3" }, "funding": { "type": "github", @@ -1244,9 +1244,9 @@ } }, "node_modules/@types/chrome": { - "version": "0.0.259", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.259.tgz", - "integrity": "sha512-WP1HsLqKgoUwR/4dYiTfmOSUG5B05+xrPLbqboO15nuaUC+aBYxwB9ixVyLPYY9D+vocJK9rzH5g1lpqVrJqhg==", + "version": "0.0.262", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.262.tgz", + "integrity": "sha512-TOoj3dqSYE13PD2fRuMQ6X6pggEvL9rRk/yOYOyWE6sfqRWxsJm4VoVm+wr9pkr4Sht/M5t7FFL4vXato8d1gA==", "dev": true, "dependencies": { "@types/filesystem": "*", @@ -1282,9 +1282,9 @@ } }, "node_modules/@types/filewriter": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.32.tgz", - "integrity": "sha512-Kpi2GXQyYJdjL8mFclL1eDgihn1SIzorMZjD94kdPZh9E4VxGOeyjPxi5LpsM4Zku7P0reqegZTt2GxhmA9VBg==", + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz", + "integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==", "dev": true }, "node_modules/@types/har-format": { @@ -1310,9 +1310,9 @@ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" }, "node_modules/@types/node": { - "version": "20.11.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.10.tgz", - "integrity": "sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==", + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", "dependencies": { "undici-types": "~5.26.4" } @@ -1343,9 +1343,9 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vitejs/plugin-vue": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.3.tgz", - "integrity": "sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz", + "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==", "dev": true, "engines": { "node": "^18.0.0 || >=20.0.0" @@ -1357,8 +1357,8 @@ }, "node_modules/@vnuge/vnlib.browser": { "version": "0.1.13", - "resolved": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/df7dc615532d3441f527374d18664c1a5a336de6/@vnuge-vnlib.browser/release.tgz", - "integrity": "sha512-Ddm0cVV4GeNaO5Dd8ycMklswnXBY4L+7gOSu2W1vOOabc8YDaP2XsTaA+xImFVLXj86hQbBTRUUKF9Ebacx+WQ==", + "resolved": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/7f3067b8fc4416d46af9b8b005a18a71770c98fe/@vnuge-vnlib.browser/release.tgz", + "integrity": "sha512-1ZIfJ/HtUTm0Bm2sNZKZxfmAFIJYnhNgpDAFcJHI9tpRHRdwxlvxCMPC32754DTF8nwMVBHqREJDIAWvr7Q3mw==", "license": "MIT", "peerDependencies": { "@vueuse/core": "^10.x", @@ -1425,55 +1425,55 @@ "dev": true }, "node_modules/@vue/compiler-core": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz", - "integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==", + "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.6", - "@vue/shared": "3.4.15", + "@babel/parser": "^7.23.9", + "@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.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz", - "integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==", + "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.15", - "@vue/shared": "3.4.15" + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz", - "integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==", - "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/compiler-core": "3.4.15", - "@vue/compiler-dom": "3.4.15", - "@vue/compiler-ssr": "3.4.15", - "@vue/shared": "3.4.15", + "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.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.5", - "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.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz", - "integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==", + "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.15", - "@vue/shared": "3.4.15" + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/devtools-api": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", - "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", + "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" }, "node_modules/@vue/language-core": { "version": "1.8.27", @@ -1525,48 +1525,48 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.15.tgz", - "integrity": "sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==", + "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.15" + "@vue/shared": "3.4.21" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.15.tgz", - "integrity": "sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==", + "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.15", - "@vue/shared": "3.4.15" + "@vue/reactivity": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.15.tgz", - "integrity": "sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==", + "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.15", - "@vue/shared": "3.4.15", + "@vue/runtime-core": "3.4.21", + "@vue/shared": "3.4.21", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.15.tgz", - "integrity": "sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==", + "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.15", - "@vue/shared": "3.4.15" + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21" }, "peerDependencies": { - "vue": "3.4.15" + "vue": "3.4.21" } }, "node_modules/@vue/shared": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz", - "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==" + "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", @@ -1653,23 +1653,23 @@ } }, "node_modules/@vueuse/core": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.2.tgz", - "integrity": "sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==", + "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.7.2", - "@vueuse/shared": "10.7.2", - "vue-demi": ">=0.14.6" + "@vueuse/metadata": "10.9.0", + "@vueuse/shared": "10.9.0", + "vue-demi": ">=0.14.7" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -1692,13 +1692,13 @@ } }, "node_modules/@vueuse/integrations": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.7.2.tgz", - "integrity": "sha512-+u3RLPFedjASs5EKPc69Ge49WNgqeMfSxFn+qrQTzblPXZg6+EFzhjarS5edj2qAf6xQ93f95TUxRwKStXj/sQ==", + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.9.0.tgz", + "integrity": "sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q==", "dependencies": { - "@vueuse/core": "10.7.2", - "@vueuse/shared": "10.7.2", - "vue-demi": ">=0.14.6" + "@vueuse/core": "10.9.0", + "@vueuse/shared": "10.9.0", + "vue-demi": ">=0.14.7" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -1757,9 +1757,9 @@ } }, "node_modules/@vueuse/integrations/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -1782,28 +1782,28 @@ } }, "node_modules/@vueuse/metadata": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.2.tgz", - "integrity": "sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==", + "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.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.2.tgz", - "integrity": "sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==", + "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.6" + "vue-demi": ">=0.14.7" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -1902,6 +1902,15 @@ "node": ">=16.0.0" } }, + "node_modules/addons-linter/node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/addons-linter/node_modules/addons-scanner-utils": { "version": "9.9.0", "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.9.0.tgz", @@ -1981,6 +1990,83 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/addons-linter/node_modules/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/addons-linter/node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/addons-linter/node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/addons-linter/node_modules/glob": { "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", @@ -2003,13 +2089,7 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/addons-linter/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/addons-linter/node_modules/minimatch": { + "node_modules/addons-linter/node_modules/glob/node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", @@ -2024,6 +2104,30 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/addons-linter/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/addons-linter/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/addons-linter/node_modules/node-fetch": { "version": "2.6.11", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", @@ -2046,6 +2150,49 @@ } } }, + "node_modules/addons-linter/node_modules/postcss": { + "version": "8.4.33", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", + "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/addons-linter/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/addons-linter/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2292,9 +2439,9 @@ } }, "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": [ { @@ -2311,8 +2458,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", @@ -2482,9 +2629,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", - "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -2501,8 +2648,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001580", - "electron-to-chromium": "^1.4.648", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -2620,14 +2767,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2662,9 +2814,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001581", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz", - "integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==", + "version": "1.0.30001591", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", + "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", "dev": true, "funding": [ { @@ -2758,16 +2910,10 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "devOptional": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2780,6 +2926,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -3298,17 +3447,20 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-lazy-prop": { @@ -3432,15 +3584,15 @@ } }, "node_modules/dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dtrace-provider": { @@ -3481,9 +3633,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.648", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz", - "integrity": "sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg==", + "version": "1.4.690", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.690.tgz", + "integrity": "sha512-+2OAGjUx68xElQhydpcbqH50hE8Vs2K6TkAeLhICYfndb67CVH0UsZaijmRUE3rHlIxU1u0jxwhgVe6fK3YANA==", "dev": true }, "node_modules/emoji-regex": { @@ -3525,6 +3677,27 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -3577,9 +3750,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -3608,15 +3781,15 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -3671,17 +3844,17 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.20.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.20.1.tgz", - "integrity": "sha512-GyCs8K3lkEvoyC1VV97GJhP1SvqsKCiWGHnbn0gVUYiUhaH2+nB+Dv1uekv1THFMPbBfYxukrzQdltw950k+LQ==", + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.22.0.tgz", + "integrity": "sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.13", - "semver": "^7.5.4", - "vue-eslint-parser": "^9.4.0", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.0", + "vue-eslint-parser": "^9.4.2", "xml-name-validator": "^4.0.0" }, "engines": { @@ -3913,9 +4086,9 @@ } }, "node_modules/fastq": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", - "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dependencies": { "reusify": "^1.0.4" } @@ -4053,9 +4226,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" }, "node_modules/follow-redirects": { "version": "1.15.5", @@ -4252,16 +4425,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4452,21 +4629,21 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -4488,12 +4665,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -4514,9 +4691,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "dev": true, "dependencies": { "function-bind": "^1.1.2" @@ -4619,9 +4796,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "engines": { "node": ">= 4" } @@ -5009,9 +5186,9 @@ } }, "node_modules/jose": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/jose/-/jose-5.2.0.tgz", - "integrity": "sha512-oW3PCnvyrcm1HMvGTzqjxxfnEs9EoFOFWi2HsEGhlFVOXxTE3K9GKWVMFoFw06yPUqwpvEWic1BmtUZBI/tIjw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.2.2.tgz", + "integrity": "sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -5366,9 +5543,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "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==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -5625,9 +5802,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.4.tgz", - "integrity": "sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.6.tgz", + "integrity": "sha512-rRq0eMHoGZxlvaFOUdK1Ev83Bd1IgzzR+WJ3IbDJ7QOSdAxYjlurSPqFs9s4lJg29RT6nPwizFtJhQS6V5xgiA==", "funding": [ { "type": "github", @@ -6171,9 +6348,9 @@ } }, "node_modules/pinia/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -6252,9 +6429,9 @@ } }, "node_modules/postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "funding": [ { "type": "opencollective", @@ -6350,12 +6527,15 @@ } }, "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", "dev": true, "engines": { "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/postcss-nested": { @@ -6947,9 +7127,9 @@ } }, "node_modules/rollup": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", - "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", + "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", "dependencies": { "@types/estree": "1.0.5" }, @@ -6961,19 +7141,19 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.6", - "@rollup/rollup-android-arm64": "4.9.6", - "@rollup/rollup-darwin-arm64": "4.9.6", - "@rollup/rollup-darwin-x64": "4.9.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", - "@rollup/rollup-linux-arm64-gnu": "4.9.6", - "@rollup/rollup-linux-arm64-musl": "4.9.6", - "@rollup/rollup-linux-riscv64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-musl": "4.9.6", - "@rollup/rollup-win32-arm64-msvc": "4.9.6", - "@rollup/rollup-win32-ia32-msvc": "4.9.6", - "@rollup/rollup-win32-x64-msvc": "4.9.6", + "@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", "fsevents": "~2.3.2" } }, @@ -7041,9 +7221,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.70.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz", - "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==", + "version": "1.71.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", + "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", "devOptional": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -7063,9 +7243,9 @@ "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -7122,14 +7302,15 @@ "peer": true }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.1" }, @@ -7967,9 +8148,9 @@ } }, "node_modules/universal-cookie": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.0.2.tgz", - "integrity": "sha512-EC9PA+1nojhJtVnKW2Z7WYah01jgYJApqhX+Y8XU97TnFd7KaoxWTHiTZFtfpfV50jEF1L8V5p64ZxIx3Q67dg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.1.0.tgz", + "integrity": "sha512-LCLHwP0whxTqkBYMptW1dzNS0xxIVJmU6c51N5CfPNheVxuJW7fVxPa6MUGX7boUSyOlpMveBO96hMs5Gee6Fg==", "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0" @@ -8097,12 +8278,12 @@ } }, "node_modules/vite": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz", - "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz", + "integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==", "dependencies": { "esbuild": "^0.19.3", - "postcss": "^8.4.32", + "postcss": "^8.4.35", "rollup": "^4.2.0" }, "bin": { @@ -8269,15 +8450,15 @@ "dev": true }, "node_modules/vue": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.15.tgz", - "integrity": "sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==", + "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.15", - "@vue/compiler-sfc": "3.4.15", - "@vue/runtime-dom": "3.4.15", - "@vue/server-renderer": "3.4.15", - "@vue/shared": "3.4.15" + "@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": "*" @@ -8313,11 +8494,11 @@ } }, "node_modules/vue-router": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz", - "integrity": "sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz", + "integrity": "sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==", "dependencies": { - "@vue/devtools-api": "^6.5.0" + "@vue/devtools-api": "^6.5.1" }, "funding": { "url": "https://github.com/sponsors/posva" @@ -8354,9 +8535,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" @@ -8770,9 +8951,9 @@ } }, "node_modules/web-streams-polyfill": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", - "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, "engines": { "node": ">= 8" @@ -9026,9 +9207,12 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz", + "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==", + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } diff --git a/extension/package.json b/extension/package.json index ba5d172..13ee0fd 100644 --- a/extension/package.json +++ b/extension/package.json @@ -44,7 +44,7 @@ "@fortawesome/vue-fontawesome": "^3.0.3", "@headlessui/vue": "^1.7.x", "@kyvg/vue3-notification": "^3.0.x", - "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/df7dc615532d3441f527374d18664c1a5a336de6/@vnuge-vnlib.browser/release.tgz", + "@vnuge/vnlib.browser": "https://www.vaughnnugent.com/public/resources/software/builds/Plugins.Essentials/7f3067b8fc4416d46af9b8b005a18a71770c98fe/@vnuge-vnlib.browser/release.tgz", "@vuelidate/core": "^2.0.0", "@vuelidate/validators": "^2.0.0", "@vueuse/core": "^10.3.2", diff --git a/extension/src/entries/options/components/Activity.vue b/extension/src/entries/options/components/Activity.vue index c62fb83..87ef2ad 100644 --- a/extension/src/entries/options/components/Activity.vue +++ b/extension/src/entries/options/components/Activity.vue @@ -1,5 +1,5 @@ <template> - <div id="ev-history" class="flex flex-col w-full mt-4 sm:px-2"> + <div id="ev-history" class="flex flex-col w-full mt-4 overflow-x-hidden sm:px-2"> <form @submit.prevent=""> <div class="w-full max-w-xl mx-auto"> <h3 class="text-center"> @@ -13,24 +13,26 @@ <div class="flex justify-center"> </div> </div> - + <div class="my-6 "> - <EvHistoryTable :readonly="false" :requests="pending" @deny="deny" @approve="approve" /> + <EvHistoryTable :readonly="false" :requests="pending" @deny="deny" @approve="approve" /> </div> - <AutoRules /> + <div class=""> + <AutoRules /> + </div> <div class="flex flex-row justify-between mt-16"> <div class="font-bold"> History </div> <div class="flex justify-center"> - <pagination :pages="pages" /> + <pagination :pages="pages" /> </div> </div> <div class="mt-1"> - <EvHistoryTable :readonly="true" :requests="permHistory" @deny="deny" @approve="approve" /> + <EvHistoryTable :readonly="true" :requests="permHistory" @deny="deny" @approve="approve" /> </div> <div class="mt-4 ml-auto w-fit"> diff --git a/extension/src/entries/options/components/EventHistory.vue b/extension/src/entries/options/components/EventHistory.vue index b6cd13e..4fa97d4 100644 --- a/extension/src/entries/options/components/EventHistory.vue +++ b/extension/src/entries/options/components/EventHistory.vue @@ -8,13 +8,18 @@ <pagination :pages="pagination" /> </div> </div> - <div class=""> + <div class="mt-2"> <table class="min-w-full text-sm divide-y-2 divide-gray-200 dark:divide-dark-500"> <thead class="text-left bg-gray-50 dark:bg-dark-700"> <tr> - <th class="pl-2"></th> <th class="p-2 font-medium whitespace-nowrap dark:text-white"> - Event + Account + </th> + <th class="p-2 font-medium whitespace-nowrap dark:text-white"> + Kind + </th> + <th class="p-2 font-medium whitespace-nowrap dark:text-white"> + Note </th> <th class="p-2 font-medium whitespace-nowrap dark:text-white"> Time @@ -25,50 +30,30 @@ <tbody class="divide-y divide-gray-200 dark:divide-dark-500"> <tr v-for="event in evHistory" :key="event.Id" class=""> - <td class="pl-2 whitespace-nowrap"> - <div class="flex flex-col items-end gap-0.5"> - <div class=""> - ID: - </div> - <div class=""> - EventId: - </div> - <div class=""> - PubKey: - </div> - <div class=""> - Content: - </div> - </div> + <td class="pl-2 truncate whitespace-nowrap overflow-ellipsis"> + <a href="#" @click="goToKeyView(event)" class="text-blue-500 hover:underline"> + {{ lookupKeyFromLoadedKeys(event.pubkey) }} + </a> </td> <td class="p-2"> - <div class="flex flex-col flex-1 gap-0.5"> - <div class="truncate overflow-ellipsis"> - {{ event.Id }} - </div> - - <div class="truncate overflow-ellipsis"> - {{ event.id }} - </div> - - <div class="truncate overflow-ellipsis"> - <a href="#" @click="goToKeyView(event)" class="text-blue-500 hover:underline"> - {{ event.pubkey }} - </a> - </div> - <div class="truncate overflow-ellipsis"> - {{ event.content }} - </div> + {{ event.kind }} + </td> + <td class="p-2 max-w-40"> + <div class="truncate overflow-ellipsis"> + {{ event.content }} </div> </td> <td class="p-2 whitespace-nowrap"> {{ timeAgo(event, timeStamp) }} </td> - <td class="p-2 text-right whitespace-nowrap"> - <div class="button-group"> - <button class="rounded btn xs" @click="deleteEvent(event)"> + <td class="flex"> + <div class="my-1 button-group"> + <button class="btn xs" @click="deleteEvent(event)"> <fa-icon icon="trash" /> </button> + <button class="w-8 btn xs" @click="showEvent(event)"> + <fa-icon icon="ellipsis-v" /> + </button> </div> </td> </tr> @@ -76,22 +61,103 @@ </table> </div> </div> + + <Dialog :open="openEvent != null" @close="showEvent()"> + + <div class="fixed inset-0 bg-black/40" aria-hidden="true" /> + + <!-- Full-screen container to center the panel --> + <div class="fixed inset-0 flex justify-center w-screen p-4 mt-36"> + <!-- The actual dialog panel --> + <DialogPanel + class="w-full max-w-xl p-3 mb-auto bg-white border border-gray-400 dark:bg-dark-800 dark:text-white dark:border-dark-500"> + <DialogTitle class="text-lg font-bold"> Event Details </DialogTitle> + <div class="mt-2"> + + </div> + <div class=""> + + <div class="grid justify-center grid-flow-row grid-cols-3 text-left"> + + <div class=""> + <h5 class="text-sm font-bold">Kind</h5> + </div> + <div class=""> + <h5 class="text-sm font-bold">Time</h5> + </div> + <div class=""> + <h5 class="text-sm font-bold">User</h5> + </div> + + <div class=""> + <p class="text-sm">{{ openEvent?.kind }}</p> + </div> + <div class=""> + <p class="text-sm">{{ createShortDateAndTime(openEvent!) }}</p> + </div> + <div class=""> + <p class="text-sm"> + {{ lookupKeyFromLoadedKeys(openEvent!.pubkey) }} + </p> + </div> + </div> + <div class="mt-4 "> + <h4 class="text-sm font-bold">Content</h4> + <p + class="p-2 mt-2 text-sm text-gray-600 whitespace-pre-wrap bg-gray-100 dark:bg-dark-700 dark:text-gray-300 max-h-[16rem] overflow-y-auto"> + {{ openEvent?.content }} + </p> + </div> + <div class="mt-4"> + <h4 class="text-sm font-bold">Tags</h4> + <p class="px-2 overflow-x-auto max-w-[100%]"> + <ul class="max-h-[16rem] overflow-y-auto"> + <li v-for="tag in openEvent?.tags" :key="tag" + class="my-1 text-xs text-gray-600 dark:text-gray-400"> + {{ tag }} + </li> + </ul> + </p> + </div> + <div class="mt-4 "> + <h4 class="text-sm font-bold">Event ID</h4> + <p + class="p-2 mt-2 text-sm text-gray-600 whitespace-pre-wrap bg-gray-100 dark:bg-dark-700 dark:text-gray-300 max-h-[16rem] overflow-y-auto"> + {{ openEvent?.id }} + </p> + </div> + <div class="mt-4 "> + <h4 class="text-sm font-bold">Signature</h4> + <p + class="p-2 mt-2 text-sm text-gray-600 whitespace-pre-wrap bg-gray-100 dark:bg-dark-700 dark:text-gray-300 max-h-[16rem] overflow-y-auto"> + {{ openEvent?.sig }} + </p> + </div> + </div> + + </DialogPanel> + </div> + + </Dialog> </template> <script setup lang="ts"> -import { apiCall } from '@vnuge/vnlib.browser'; +import { apiCall, useConfirm } from '@vnuge/vnlib.browser'; import { computed } from 'vue'; import { formatTimeAgo, get, useOffsetPagination, useTimestamp } from '@vueuse/core'; -import { } from '@headlessui/vue' import { useStore } from '../../store'; import { EventEntry, NostrEvent } from '../../../features'; -import { map, slice } from 'lodash'; +import { find, map, slice } from 'lodash'; import { useQuery } from '../../../features/util'; +import { Dialog, DialogPanel, DialogTitle } from '@headlessui/vue' const store = useStore() const tabId = useQuery('t'); const keyId = useQuery('kid'); +const openEvId = useQuery('activeEvent'); + +const { reveal } = useConfirm() const pagination = useOffsetPagination({ pageSize: 10, @@ -115,8 +181,18 @@ const evHistory = computed<Array<NostrEvent & EventEntry>>(() => { }) }) +const openEvent = computed<NostrEvent & EventEntry | undefined>(() => find(evHistory.value, e => e.Id === openEvId.asRef.value)) +const showEvent = (event?: EventEntry) => openEvId.set(event?.Id ?? '') + +const deleteEvent = async (event: EventEntry) => { + + const { isCanceled } = await reveal({ + title: 'Delete Event', + text: 'Are you sure you want to delete this event forever?', + }) + + if(isCanceled) return -const deleteEvent = (event: EventEntry) => { //Call delete event function apiCall(() => store.plugins.history.deleteEvent(event)) } @@ -132,6 +208,10 @@ const createShortDateAndTime = (request: EventEntry) => { return `${month}/${day}/${year} ${hours}:${minutes}:${seconds}` } +const lookupKeyFromLoadedKeys = (pubkey: string) => { + return find(store.allKeys, { PublicKey: pubkey })?.UserName ?? pubkey +} + const timeAgo = (entry: EventEntry, timeStamp: number) => { return formatTimeAgo(new Date(entry.Created), { }, timeStamp) } diff --git a/extension/src/entries/options/components/Identities.vue b/extension/src/entries/options/components/Identities.vue index 8236b83..02c115d 100644 --- a/extension/src/entries/options/components/Identities.vue +++ b/extension/src/entries/options/components/Identities.vue @@ -3,7 +3,7 @@ <div class="flex justify-end gap-2 text-black dark:text-white"> <div class=""> <div class=""> - <button class="rounded btn sm" @click="onNip05Download"> + <button class="btn sm" @click="onNip05Download"> NIP-05 <fa-icon icon="download" class="ml-1" /> </button> @@ -11,7 +11,7 @@ </div> <div class="mb-2"> <Popover class="relative" v-slot="{ open }"> - <PopoverButton class="rounded btn sm">Create</PopoverButton> + <PopoverButton class="btn sm">Create</PopoverButton> <PopoverOverlay v-if="open" class="fixed inset-0 bg-black opacity-50" /> <PopoverPanel class="absolute z-10 mt-2 md:-right-0" v-slot="{ close }"> <div class="p-3 bg-white border border-gray-200 rounded shadow-lg dark:border-dark-600 dark:bg-dark-900"> @@ -30,7 +30,7 @@ </div> </div> <div class="flex justify-end mt-2"> - <button class="rounded sm btn" type="submit">Create</button> + <button class="sm btn" type="submit">Create</button> </div> </form> </div> @@ -40,7 +40,7 @@ </div> <div class=""> <div class=""> - <button class="rounded btn sm" @click="identity.refreshKeys()"> + <button class="btn sm" @click="identity.refreshKeys()"> <fa-icon icon="refresh" class="" /> </button> </div> diff --git a/extension/src/entries/options/components/SiteSettings.vue b/extension/src/entries/options/components/SiteSettings.vue index a2df205..8deac92 100644 --- a/extension/src/entries/options/components/SiteSettings.vue +++ b/extension/src/entries/options/components/SiteSettings.vue @@ -1,8 +1,8 @@ <template> <div class="flex flex-col w-full mt-4 sm:px-2"> - + <form @submit.prevent=""> - <div class="w-full max-w-md mx-auto"> + <div class="w-full max-w-md mx-auto"> <h3 class="text-center"> Extension settings </h3> @@ -11,57 +11,45 @@ <div class=""> <div class="w-full"> <div class="flex flex-row w-full"> - <Switch - v-model="originProtection" + <Switch v-model="originProtection" :class="originProtection ? 'bg-black dark:bg-gray-50' : 'bg-gray-200 dark:bg-dark-600'" - class="relative inline-flex items-center h-5 rounded-full w-11" - > + class="relative inline-flex items-center h-5 rounded-full w-11"> <span class="sr-only">Origin protection</span> - <span - :class="originProtection ? 'translate-x-6' : 'translate-x-1'" - class="inline-block w-4 h-4 transition transform bg-white rounded-full dark:bg-dark-900" - /> + <span :class="originProtection ? 'translate-x-6' : 'translate-x-1'" + class="inline-block w-4 h-4 transition transform bg-white rounded-full dark:bg-dark-900" /> </Switch> <div class="my-auto ml-2 text-sm dark:text-gray-200"> - Tracking protection + Tracking protection </div> </div> </div> </div> - + <div class="mt-3"> <div class="flex flex-row w-fit"> - <Switch - v-model="v$.heartbeat.$model" + <Switch v-model="v$.heartbeat.$model" :class="v$.heartbeat.$model ? 'bg-black dark:bg-white' : 'bg-gray-200 dark:bg-dark-600'" - class="relative inline-flex items-center h-5 mx-auto rounded-full w-11" - > + class="relative inline-flex items-center h-5 mx-auto rounded-full w-11"> <span class="sr-only">Stay logged in</span> - <span - :class="v$.heartbeat.$model ? 'translate-x-6' : 'translate-x-1'" - class="inline-block w-4 h-4 transition transform rounded-full bg-gray-50 dark:bg-dark-900" - /> + <span :class="v$.heartbeat.$model ? 'translate-x-6' : 'translate-x-1'" + class="inline-block w-4 h-4 transition transform rounded-full bg-gray-50 dark:bg-dark-900" /> </Switch> <div class="my-auto ml-2 text-sm dark:text-gray-200"> - Stay logged-in + Stay logged-in </div> </div> </div> <div class="mt-3"> <div class="flex flex-row w-fit"> - <Switch - v-model="v$.authPopup.$model" + <Switch v-model="v$.authPopup.$model" :class="v$.authPopup.$model ? 'bg-black dark:bg-white' : 'bg-gray-200 dark:bg-dark-600'" - class="relative inline-flex items-center h-5 mx-auto rounded-full w-11" - > + class="relative inline-flex items-center h-5 mx-auto rounded-full w-11"> <span class="sr-only">Permissions Popup</span> - <span - :class="v$.authPopup.$model ? 'translate-x-6' : 'translate-x-1'" - class="inline-block w-4 h-4 transition transform rounded-full bg-gray-50 dark:bg-dark-900" - /> + <span :class="v$.authPopup.$model ? 'translate-x-6' : 'translate-x-1'" + class="inline-block w-4 h-4 transition transform rounded-full bg-gray-50 dark:bg-dark-900" /> </Switch> <div class="my-auto ml-2 text-sm dark:text-gray-200"> - Permissions Popup + Permissions Popup </div> </div> </div> @@ -69,6 +57,9 @@ </div> <h3 class="text-center"> Server settings + <span class="my-auto ml-1 text-sm text-green-500" v-show="store.isServerValid"> + (connected) + </span> </h3> <p class="text-xs dark:text-gray-400"> You must be careful when editing these settings as you may loose connection to your vault @@ -77,59 +68,33 @@ <div class="flex justify-end mt-2"> <div class="button-group"> <button class="rounded btn sm" @click="toggleEdit()"> - <fa-icon v-if="editMode" icon="lock-open"/> - <fa-icon v-else icon="lock"/> + <fa-icon v-if="editMode" icon="lock-open" /> + <fa-icon v-else icon="lock" /> </button> - <a :href="data.apiUrl" target="_blank"> + <a :href="store.status.EpConfig.apiBaseUrl" target="_blank"> <button type="button" class="rounded btn sm"> - <fa-icon icon="external-link-alt"/> + <fa-icon icon="external-link-alt" /> </button> </a> </div> </div> <fieldset> <div class="pl-1 mt-2"> - - </div> - <div class="mt-2"> - <label class="pl-1">BaseUrl</label> - <input - class="w-full input" - :class="{'error': v$.apiUrl.$invalid }" - v-model="v$.apiUrl.$model" - :readonly="!editMode" - /> - <p class="pl-1 mt-1 text-xs text-gray-600 dark:text-gray-400"> - * The http path to the vault server (must start with http:// or https://) - </p> - </div> - <div class="mt-2"> - <label class="pl-1">Account endpoint</label> - <input - class="w-full input" - v-model="v$.accountBasePath.$model" - :class="{ 'error': v$.accountBasePath.$invalid }" - :readonly="!editMode" - /> - <p class="pl-1 mt-1 text-xs text-gray-600 dark:text-gray-400"> - * This is the path to the account server endpoint (must start with /) - </p> + </div> <div class="mt-2"> - <label class="pl-1">Nostr endpoint</label> - <input - class="w-full input" - v-model="v$.nostrEndpoint.$model" - :class="{ 'error': v$.nostrEndpoint.$invalid }" - :readonly="!editMode" - /> + <label class="pl-1"> + Server Url + </label> + <input class="w-full input" :class="{'error': v$.discoveryUrl.$invalid }" + v-model="v$.discoveryUrl.$model" :readonly="!editMode" /> <p class="pl-1 mt-1 text-xs text-gray-600 dark:text-gray-400"> - * This is the path to the Nostr plugin endpoint path (must start with /) + * The http path to the vault server (must start with https://) </p> </div> </fieldset> <div class="flex justify-end mt-2"> - <button :disabled="!modified || waiting" class="rounded btn sm" @click="onSave">Save</button> + <button :disabled="!modified || waiting" class="btn sm" @click="onSave">Save</button> </div> </div> </form> @@ -139,25 +104,27 @@ <script setup lang="ts"> import { apiCall, useDataBuffer, useVuelidateWrapper, useWait } from '@vnuge/vnlib.browser'; import { computed, watch } from 'vue'; -import { useToggle, watchDebounced } from '@vueuse/core'; +import { Mutable, useToggle, watchDebounced } from '@vueuse/core'; import { maxLength, helpers, required } from '@vuelidate/validators' import { Switch } from '@headlessui/vue' import { useStore } from '../../store'; import { storeToRefs } from 'pinia'; -import useVuelidate from '@vuelidate/core' +import { useVuelidate } from '@vuelidate/core' +import { PluginConfig } from '../../../features'; const store = useStore() const { settings } = storeToRefs(store) const { waiting } = useWait(); +const { setSiteConfig } = store.plugins.settings const { apply, data, buffer, modified, update } = useDataBuffer(settings.value, async sb =>{ - const newConfig = await store.saveSiteConfig(sb.buffer) + const newConfig = await setSiteConfig(sb.buffer) apply(newConfig) return newConfig; }) //Watch for store settings changes and apply them -watch(settings, v => apply(v)) +watch(settings, apply) const originProtection = computed({ get: () => store.isOriginProtectionOn, @@ -165,24 +132,13 @@ const originProtection = computed({ }) const url = (val : string) => /^https?:\/\/[a-zA-Z0-9\.\:\/-]+$/.test(val); -const path = (val : string) => /^\/[a-zA-Z0-9-_]+$/.test(val); const vRules = { - apiUrl: { + discoveryUrl: { required:helpers.withMessage('Base url is required', required), maxLength: helpers.withMessage('Base url must be less than 100 characters', maxLength(100)), url: helpers.withMessage('You must input a valid url', url) }, - accountBasePath: { - required:helpers.withMessage('Account path is required', required), - maxLength: maxLength(50), - alphaNum: helpers.withMessage('Account path is not a valid endpoint path that begins with /', path) - }, - nostrEndpoint:{ - required: helpers.withMessage('Nostr path is required', required), - maxLength: maxLength(50), - alphaNum: helpers.withMessage('Nostr path is not a valid endpoint path that begins with /', path) - }, authPopup: {}, heartbeat: {}, } @@ -217,21 +173,48 @@ const onSave = async () => { } const testConnection = async () =>{ - return await apiCall(async ({axios, toaster}) =>{ + return await apiCall(async ({ toaster }) =>{ try{ - await axios.get(`${buffer.apiUrl}`); - toaster.general.success({ - title: 'Success', - text: 'Succcesfully connected to the vault server' - }); - return true; + + //See if the discovery url ends with a well-known file path (also checks for well-formatted url) + const url = new URL(buffer.discoveryUrl); + + if (url.pathname === '/'){ + //append the well-known path + url.pathname = '/.well-known/nvault'; + } + + const result = await store.plugins.settings.testServerAddress(url.href); + + if (result){ + + //Safe to update the buffer incase we changed it + (buffer as Mutable<PluginConfig>).discoveryUrl = url.href; + + toaster.form.success({ + title: 'Success', + text: 'Succcesfully discoverted your new Nvault server' + }); + + return true; + } + else{ + toaster.form.error({ + title: 'Invalid Url', + text: 'The address you entered was not a valid discovery url.', + duration: 6000 + }); + } } catch(e){ + console.error(e); toaster.form.error({ title: 'Warning', - text: `Failed to connect to the vault server. Status code: ${(e as any).response?.status}` + text: `Failed to connect to the vault server. Check your url.` }); } + + return false; }) } diff --git a/extension/src/entries/options/index.html b/extension/src/entries/options/index.html index 976e7ea..6c70777 100644 --- a/extension/src/entries/options/index.html +++ b/extension/src/entries/options/index.html @@ -14,7 +14,7 @@ } </style> </head> - <body class="w-full"> + <body class="w-full overflow-x-hidden"> <div id="app"></div> <script type="module" src="./main.js"></script> </body> diff --git a/extension/src/entries/options/main.js b/extension/src/entries/options/main.js index 901dfdd..78fb4df 100644 --- a/extension/src/entries/options/main.js +++ b/extension/src/entries/options/main.js @@ -23,12 +23,12 @@ import Pagination from '../../components/Pagination.vue'; /* FONT AWESOME CONFIG */ import { library } from '@fortawesome/fontawesome-svg-core' -import { faCheck, faChevronLeft, faChevronRight, faCopy, faDownload, faEdit, faExternalLinkAlt, faLock, faLockOpen, faMinusCircle, faMoon, faPlus, faRefresh, faSun, faTrash, faTrashCan } from '@fortawesome/free-solid-svg-icons' +import { faCheck, faChevronLeft, faChevronRight, faCopy, faDownload, faEdit, faEllipsisV, faExternalLinkAlt, faLock, faLockOpen, faMinusCircle, faMoon, faPlus, faRefresh, faSun, faTrash, faTrashCan } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { createPinia } from "pinia"; import { identityPlugin, mfaConfigPlugin, originPlugin, permissionsPlugin, useBackgroundPiniaPlugin } from "../store"; -library.add(faCopy, faEdit, faChevronLeft, faMoon, faSun, faLock, faLockOpen, faExternalLinkAlt, faTrash, faDownload, faChevronRight, faPlus, faRefresh, faTrashCan, faMinusCircle ,faTrashCan, faCheck) +library.add(faCopy, faEdit, faChevronLeft, faMoon, faSun, faLock, faLockOpen, faExternalLinkAlt, faTrash, faDownload, faChevronRight, faPlus, faRefresh, faTrashCan, faMinusCircle ,faTrashCan, faCheck, faEllipsisV) //Create the background feature wiring const bgPlugins = useBackgroundPiniaPlugin('options') diff --git a/extension/src/entries/popup/Components/OtpLogin.vue b/extension/src/entries/popup/Components/OtpLogin.vue index a2b8ac7..2fc95f2 100644 --- a/extension/src/entries/popup/Components/OtpLogin.vue +++ b/extension/src/entries/popup/Components/OtpLogin.vue @@ -6,7 +6,7 @@ </fieldset> <div class="flex justify-end mt-2"> <div class="px-3"> - <button class="w-24 rounded btn sm primary"> + <button class="w-24 btn sm primary"> <fa-icon v-if="waiting" icon="spinner" class="animate-spin" /> <span v-else>Submit</span> </button> @@ -20,7 +20,7 @@ import { apiCall, useWait } from "@vnuge/vnlib.browser"; import { ref } from "vue"; import { useStore } from "../../store"; -const { login } = useStore() +const store = useStore() const { waiting } = useWait() const token = ref('') @@ -28,7 +28,7 @@ const token = ref('') const onSubmit = async () => { await apiCall(async ({ toaster }) => { try{ - await login(token.value) + await store.plugins.user.login(token.value) toaster.form.success({ 'title': 'Login successful', diff --git a/extension/src/entries/popup/Components/PageContent.vue b/extension/src/entries/popup/Components/PageContent.vue index 37e119d..9bc9627 100644 --- a/extension/src/entries/popup/Components/PageContent.vue +++ b/extension/src/entries/popup/Components/PageContent.vue @@ -1,105 +1,117 @@ <template> - <div - id="injected-root" - class="flex flex-col text-left w-[20rem] min-h-[25rem]" - > - - <div class="flex flex-row w-full gap-2 p-1.5 bg-black text-white dark:bg-dark-600 shadow"> - <div class="flex flex-row flex-auto my-auto"> - <div class="my-auto mr-2"> - <img class="h-6" src="/icons/32.png" /> - </div> - <h3 class="block my-auto">NVault</h3> - <div class="px-3 py-.5 m-auto text-sm rounded-full h-fit active-badge" :class="[isTabAllowed ? 'active' : 'inactive']"> - {{ isTabAllowed ? 'Active' : 'Inactive' }} - </div> - </div> - <div class="my-auto" v-if="loggedIn"> - <button class="rounded btn xs" @click.prevent="logout"> - <fa-icon icon="arrow-right-from-bracket" /> - </button> - </div> - <div class="my-auto"> - <button class="rounded btn xs" @click="toggleDark" > - <fa-icon class="w-4" v-if="darkMode" icon="sun"/> - <fa-icon class="w-4" v-else icon="moon" /> - </button> + <div id="injected-root" class="flex flex-col text-left w-[20rem] min-h-[25rem]"> + + <div class="flex flex-row w-full gap-2 p-1.5 bg-black text-white dark:bg-dark-600 shadow"> + <div class="flex flex-row flex-auto my-auto"> + <div class="my-auto mr-2"> + <img class="h-6" src="/icons/32.png" /> </div> - <div class="my-auto"> - <button class="rounded btn xs" @click="openOptions"> - <fa-icon :icon="['fas', 'gear']"/> - </button> + <h3 class="block my-auto">NVault</h3> + <div class="px-3 py-.5 m-auto text-sm rounded-full h-fit active-badge" + :class="[isTabAllowed ? 'active' : 'inactive']"> + {{ isTabAllowed ? 'Active' : 'Inactive' }} </div> </div> - - <div v-if="!loggedIn"> - <Login></Login> + <div class="my-auto" v-if="loggedIn"> + <button class="rounded btn xs" @click.prevent="logout"> + <fa-icon icon="arrow-right-from-bracket" /> + </button> + </div> + <div class="my-auto"> + <button class="rounded btn xs" @click="toggleDark"> + <fa-icon class="w-4" v-if="darkMode" icon="sun" /> + <fa-icon class="w-4" v-else icon="moon" /> + </button> + </div> + <div class="my-auto"> + <button class="rounded btn xs" @click="openOptions"> + <fa-icon :icon="['fas', 'gear']" /> + </button> + </div> + </div> + + <div v-if="!store.isServerValid" class="flex flex-row gap-2 mx-auto mt-2 text-center text-red-500"> + <div class="text-center"> + <svg class="w-6 h-6" 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="M12 13V8m0 8h0m9-4a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" /> + </svg> + </div> + <div class="text-center"> + Not connected to server </div> + </div> - <div v-else class="flex justify-center"> - <div class="w-full px-3 m-auto"> + <div v-if="!loggedIn"> + <Login></Login> + </div> - <div class="text-sm text-center"> - {{ userName }} - </div> - - <div class=""> - <label class="mb-0.5 text-sm"> - Identity - </label> - <IdentitySelection></IdentitySelection> - </div> - - <div class="w-full mt-1"> - <div class="flex flex-col"> - <div class="flex flex-row gap-2 p-1.5 bg-gray-100 border border-gray-200 dark:bg-dark-800 dark:border-dark-400"> - <div class="text-sm break-all"> - {{ pubKey ?? 'No key selected' }} - </div> - <div class="my-auto ml-auto cursor-pointer" :class="{'text-primary-500': copied }"> - <fa-icon class="mr-1" icon="copy" @click="copy(pubKey!)"/> - </div> - </div> + <div v-else class="flex justify-center"> + <div class="w-full px-3 m-auto"> + + <div class="text-sm text-center"> + {{ userName }} + </div> + + <div class=""> + <label class="mb-0.5 text-sm"> + Identity + </label> + <IdentitySelection></IdentitySelection> + </div> + + <div class="w-full mt-1"> + <div class="flex flex-col"> + <div + class="flex flex-row gap-2 p-1.5 bg-gray-100 border border-gray-200 dark:bg-dark-800 dark:border-dark-400"> + <div class="text-sm break-all"> + {{ pubKey ?? 'No key selected' }} + </div> + <div class="my-auto ml-auto cursor-pointer" :class="{'text-primary-500': copied }"> + <fa-icon class="mr-1" icon="copy" @click="copy(pubKey!)" /> </div> </div> + </div> + </div> - <div class="mt-4"> - <label class="block mb-1 text-xs text-left " > - Current origin - </label> - - <div v-if="isOriginProtectionOn" class="flex flex-row w-full gap-2"> - <input :value="currentOrigin" class="flex-1 p-1 mx-0 text-sm input dark:text-dark-100" readonly/> - - <button v-if="isTabAllowed" class="btn xs" @click="store.dissallowOrigin()"> - <fa-icon icon="minus" /> - </button> - <button v-else class="btn xs" @click="store.allowOrigin()"> - <fa-icon icon="plus" /> - </button> - </div> - - <div v-else class="text-xs text-center dark:text-dark-100"> - <span class="">Tracking protection disabled</span> - </div> - </div> - <div class="mt-4"> - <label class="block mb-1 text-xs text-left " > - Permissions - </label> - <ul class="flex flex-row flex-wrap gap-2 dark:text-dark-100"> - <li v-for="rule in ruleTypes" :key="rule" class="text-xs"> - {{ rule }} - </li> - </ul> - </div> - + <div class="mt-4"> + <label class="block mb-1 text-xs text-left "> + Current origin + </label> + + <div v-if="isOriginProtectionOn" class="flex flex-row w-full gap-2"> + <input :value="currentOrigin" class="flex-1 p-1 mx-0 text-sm input dark:text-dark-100" readonly /> + + <button v-if="isTabAllowed" class="btn xs" @click="store.dissallowOrigin()"> + <fa-icon icon="minus" /> + </button> + <button v-else class="btn xs" @click="store.allowOrigin()"> + <fa-icon icon="plus" /> + </button> + </div> + + <div v-else class="text-xs text-center dark:text-dark-100"> + <span class="">Tracking protection disabled</span> + </div> </div> + <div class="mt-4"> + <label class="block mb-1 text-xs text-left "> + Permissions + </label> + <ul class="flex flex-row flex-wrap gap-2 dark:text-dark-100"> + <li v-for="rule in ruleTypes" :key="rule" class="text-xs"> + {{ rule }} + </li> + </ul> + </div> + </div> + </div> - <notifications class="toaster" group="form" position="top-right" /> + <notifications class="toaster" group="form" position="top-right" /> - </div> + </div> </template> <script setup lang="ts"> @@ -108,11 +120,11 @@ import { storeToRefs } from "pinia"; import { useStore } from "../../store"; import { apiCall, configureNotifier } from "@vnuge/vnlib.browser"; import { useClipboard } from '@vueuse/core' +import { map } from "lodash"; import { notify } from "@kyvg/vue3-notification"; import { runtime } from "webextension-polyfill"; import Login from "./Login.vue"; import IdentitySelection from "./IdentitySelection.vue"; -import { map } from "lodash"; configureNotifier({notify, close:notify.close}) @@ -132,7 +144,7 @@ watchEffect(() => darkMode.value ? document.body.classList.add('dark') : documen const logout = () =>{ apiCall(async ({ toaster }) =>{ - await store.logout() + await store.plugins.user.logout() toaster.general.success({ 'title':'Success', 'text': 'You have been logged out' diff --git a/extension/src/entries/popup/Components/PassLogin.vue b/extension/src/entries/popup/Components/PassLogin.vue index 29aeeb6..bf32a7f 100644 --- a/extension/src/entries/popup/Components/PassLogin.vue +++ b/extension/src/entries/popup/Components/PassLogin.vue @@ -23,17 +23,17 @@ <form class="" @submit.prevent="onSubmit()"> <fieldset class="px-4 input-container"> <div class=""> - <label class="">Username</label> + <label class="text-sm">Username</label> <input type="text" name="username" class="w-full input" v-model="username" /> </div> <div class="mt-1"> - <label class="">Password</label> + <label class="text-sm">Password</label> <input type="password" name="password" class="w-full input" v-model="password" /> </div> </fieldset> <div class="flex justify-end mt-2"> <div class="px-3"> - <button class="w-24 rounded btn sm primary"> + <button class="w-24 btn sm primary"> <fa-icon v-if="waiting" icon="spinner" class="animate-spin" /> <span v-else>Submit</span> </button> @@ -52,6 +52,7 @@ import VOtpInput from "vue3-otp-input"; const { waiting } = useWait() const store = useStore(); +const { user } = store.plugins const showTotp = computed(() => store.mfaStatus?.type === 'totp') @@ -71,19 +72,19 @@ const onSubmit = () => { return } - await store.login(username.value, password.value) + await user.login(username.value, password.value) }); }; const onSubmitTotp = (code: string) => { //Invoke totp login - apiCall(() => store.plugins.user.submitMfa({ code: toNumber(code) })); + apiCall(() => user.submitMfa({ code: toNumber(code) })); }; </script> <style lang="scss"> #totp-login .otp-input input { - @apply w-10 p-0.5 rounded text-center text-lg mx-1 focus:border-primary-500; + @apply w-10 p-0.5 text-center text-lg mx-1 focus:border-primary-500; } </style>
\ No newline at end of file diff --git a/extension/src/entries/store/features.ts b/extension/src/entries/store/features.ts index d714ac6..fd2a3f2 100644 --- a/extension/src/entries/store/features.ts +++ b/extension/src/entries/store/features.ts @@ -16,6 +16,7 @@ import 'pinia' import { } from 'lodash' import { PiniaPluginContext } from 'pinia' +import { computed } from 'vue' import type { IMfaFlowContinuiation } from '@vnuge/vnlib.browser' import { @@ -34,7 +35,7 @@ import { usePermissionApi } from "../../features" -import { ChannelContext } from '../../messaging' +import type { ChannelContext } from '../../messaging' export type BgPlugins = ReturnType<typeof usePlugins> export type BgPluginState<T> = { plugins: BgPlugins } & T @@ -43,6 +44,8 @@ declare module 'pinia' { export interface PiniaCustomProperties { plugins: BgPlugins mfaStatus: Partial<IMfaFlowContinuiation> | null + isServerValid: boolean + toggleDarkMode: () => void } } @@ -87,16 +90,19 @@ export const useBackgroundPiniaPlugin = (context: ChannelContext) => { onWatchableChange(settings, async () => { //Update settings and dark mode on change store.settings = await settings.getSiteConfig(); - store.darkMode = await settings.getDarkMode(); + store.status = await settings.getStatus(); }, { immediate: true }) onWatchableChange(history, async () => { //Load event history store.eventHistory = await history.getEvents(); }, { immediate: true }) - + return{ plugins, + isServerValid: computed(() => store.status.isValid), + //Main api functions + toggleDarkMode: () => settings.setDarkMode(!store.darkMode) } } }
\ No newline at end of file diff --git a/extension/src/entries/store/index.ts b/extension/src/entries/store/index.ts index 0b4d3cd..abfba75 100644 --- a/extension/src/entries/store/index.ts +++ b/extension/src/entries/store/index.ts @@ -16,44 +16,31 @@ import 'pinia' import { } from 'lodash' import { defineStore } from 'pinia' -import { PluginConfig } from '../../features/' -import { NostrStoreState } from './types' +import { PluginConfig, EventEntry, ConfigStatus } from '../../features/' +import { computed, shallowRef } from 'vue' +import { get } from '@vueuse/core' -export type * from './types' export * from './allowedOrigins' export * from './features' export * from './identity' export * from './mfaconfig' export * from './permissions' -export const useStore = defineStore({ - id: 'main', - state: (): NostrStoreState =>({ - loggedIn: false, - userName: '', - settings: {} as any, - darkMode: false, - eventHistory: [], - }), - actions: { +export const useStore = defineStore('main', () => { - async login (usernameOrToken: string, password?: string) { - await this.plugins.user.login(usernameOrToken, password); - }, - - async logout () { - await this.plugins.user.logout(); - }, - - saveSiteConfig(config: PluginConfig) { - return this.plugins.settings.setSiteConfig(config) - }, - - async toggleDarkMode(){ - await this.plugins.settings.setDarkMode(this.darkMode === false) - }, - }, - getters:{ - - }, -})
\ No newline at end of file + const loggedIn = shallowRef<boolean>(false) + const userName = shallowRef<string>('') + const settings = shallowRef<PluginConfig>({} as PluginConfig) + const eventHistory = shallowRef<EventEntry[]>([]) + const status = shallowRef<ConfigStatus>({} as ConfigStatus) + const darkMode = computed<boolean>(() => get(status).isDarkMode) + + return{ + loggedIn, + userName, + settings, + status, + darkMode, + eventHistory + } +}) diff --git a/extension/src/entries/store/types.ts b/extension/src/entries/store/types.ts deleted file mode 100644 index 536cf04..0000000 --- a/extension/src/entries/store/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { } from "webextension-polyfill"; -import type { PluginConfig, EventEntry } from "../../features"; - -export interface NostrStoreState { - loggedIn: boolean; - userName: string | null; - settings: PluginConfig; - darkMode: boolean; - eventHistory: EventEntry[]; -}
\ No newline at end of file diff --git a/extension/src/features/index.ts b/extension/src/features/index.ts index d7e1b05..6f235ad 100644 --- a/extension/src/features/index.ts +++ b/extension/src/features/index.ts @@ -16,7 +16,7 @@ //Export all shared types export type { NostrPubKey, LoginMessage, NostrEvent, NostrRelay, EventEntry } from './types' export type * from './framework' -export type { PluginConfig } from './settings' +export type { PluginConfig, ConfigStatus } from './settings' export type { PkiPubKey, EcKeyParams, LocalPkiApi as PkiApi } from './pki-api' export type { NostrApi } from './nostr-api' export type { UserApi } from './auth-api' diff --git a/extension/src/features/server-api/index.ts b/extension/src/features/server-api/index.ts index 35bed6f..f6d7123 100644 --- a/extension/src/features/server-api/index.ts +++ b/extension/src/features/server-api/index.ts @@ -20,6 +20,7 @@ import { type WebMessage, type UserProfile } from "@vnuge/vnlib.browser" import { initEndponts } from "./endpoints" import { cloneDeep } from "lodash" import type { EncryptionRequest, EventEntry, NostrEvent, NostrPubKey, NostrRelay } from "../types" +import type { EndpointConfig } from "../settings" export enum Endpoints { GetKeys = 'getKeys', @@ -55,13 +56,16 @@ export interface ServerApi{ execRequest: ExecRequestHandler } -export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): ServerApi => { +export const useServerApi = (endpoints: Ref<EndpointConfig>): ServerApi => { const { registerEndpoint, execRequest } = initEndponts() + const nostrUrl = () => get(endpoints).nostrBasePath + const accUrl = () => get(endpoints).accountBasePath + registerEndpoint({ id: Endpoints.GetKeys, method: 'GET', - path: () => `${get(nostrUrl)}?type=getKeys`, + path: () => `${nostrUrl()}?type=getKeys`, onRequest: () => Promise.resolve(), onResponse: (response) => Promise.resolve(response) }) @@ -69,7 +73,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.DeleteKey, method: 'DELETE', - path: (key: NostrPubKey) => `${get(nostrUrl)}?type=identity&id=${key.Id}`, + path: (key: NostrPubKey) => `${nostrUrl()}?type=identity&id=${key.Id}`, onRequest: () => Promise.resolve(), onResponse: async (response: WebMessage) => response.getResultOrThrow() }) @@ -77,7 +81,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.SignEvent, method: 'POST', - path: () => `${get(nostrUrl)}?type=signEvent`, + path: () => `${nostrUrl()}?type=signEvent`, onRequest: (event) => Promise.resolve(event), onResponse: async (response: WebMessage<NostrEvent>) => { const res = response.getResultOrThrow() @@ -89,7 +93,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.GetRelays, method: 'GET', - path: () => `${get(nostrUrl)}?type=getRelays`, + path: () => `${nostrUrl()}?type=getRelays`, onRequest: () => Promise.resolve(), onResponse: (response) => Promise.resolve(response) }) @@ -97,7 +101,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.SetRelay, method: 'POST', - path: () => `${get(nostrUrl)}?type=relay`, + path: () => `${nostrUrl()}?type=relay`, onRequest: (relay:NostrRelay) => Promise.resolve(relay), onResponse: (response) => Promise.resolve(response) }) @@ -105,7 +109,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.CreateId, method: 'PUT', - path: () => `${get(nostrUrl)}?type=identity`, + path: () => `${nostrUrl()}?type=identity`, onRequest: (identity: NostrPubKey) => Promise.resolve(identity), onResponse: async (response: WebMessage<NostrEvent>) => response.getResultOrThrow() }) @@ -113,7 +117,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.UpdateId, method: 'PATCH', - path: () => `${get(nostrUrl)}?type=identity`, + path: () => `${nostrUrl()}?type=identity`, onRequest: (identity:NostrPubKey) => { const id = cloneDeep(identity) as any; delete id.Created; @@ -126,7 +130,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.UpdateProfile, method: 'POST', - path: () => `${get(accUrl)}`, + path: () => `${accUrl()}`, onRequest: (profile: UserProfile) => Promise.resolve(cloneDeep(profile)), onResponse: async (response: WebMessage<string>) => response.getResultOrThrow() }) @@ -135,7 +139,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id:Endpoints.Encrypt, method:'POST', - path: () => `${get(nostrUrl)}?type=encrypt`, + path: () => `${nostrUrl()}?type=encrypt`, onRequest: (data: EncryptionRequest) => Promise.resolve(data), onResponse: async (response: WebMessage<{ ciphertext:string, iv:string }>) =>{ const { ciphertext, iv } = response.getResultOrThrow() @@ -146,7 +150,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id:Endpoints.Decrypt, method:'POST', - path: () => `${get(nostrUrl)}?type=decrypt`, + path: () => `${nostrUrl()}?type=decrypt`, onRequest: (data: EncryptionRequest) => Promise.resolve(data), onResponse: async (response: WebMessage<string>) => response.getResultOrThrow() }) @@ -155,7 +159,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.GetHistory, method: 'GET', - path: () => `${get(nostrUrl)}?type=getEvents`, + path: () => `${nostrUrl()}?type=getEvents`, onRequest: () => Promise.resolve(), onResponse: (response : EventEntry[]) => Promise.resolve(response) //Pass through response, should be an array of events or an error }) @@ -163,7 +167,7 @@ export const useServerApi = (nostrUrl: Ref<string>, accUrl: Ref<string>): Server registerEndpoint({ id: Endpoints.DeleteSingleEvent, method: 'DELETE', - path: (evnt: EventEntry) => `${get(nostrUrl)}?type=event&id=${evnt.Id}`, + path: (evnt: EventEntry) => `${nostrUrl()}?type=event&id=${evnt.Id}`, onRequest: () => Promise.resolve(), onResponse: (response) => Promise.resolve(response) }) diff --git a/extension/src/features/settings.ts b/extension/src/features/settings.ts index 0bd7101..ad6c2f4 100644 --- a/extension/src/features/settings.ts +++ b/extension/src/features/settings.ts @@ -14,41 +14,53 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. import { storage } from "webextension-polyfill" -import { defaultsDeep } from 'lodash' +import { defaultsDeep, defer, find, isArray, isEmpty } from 'lodash' import { configureApi, debugLog } from '@vnuge/vnlib.browser' -import { MaybeRefOrGetter, readonly, Ref, shallowRef, watch } from "vue"; +import { computed, MaybeRefOrGetter, readonly, Ref, shallowRef, watch } from "vue"; import { JsonObject } from "type-fest"; import { Watchable } from "./types"; import { BgRuntime, FeatureApi, optionsOnly, IFeatureExport, exportForegroundApi, popupAndOptionsOnly } from './framework' -import { get, set, toRefs } from "@vueuse/core"; +import { get, set } from "@vueuse/core"; import { waitForChangeFn, useStorage } from "./util"; import { ServerApi, useServerApi } from "./server-api"; export interface PluginConfig extends JsonObject { - readonly apiUrl: string; - readonly accountBasePath: string; - readonly nostrEndpoint: string; + readonly discoveryUrl: string; readonly heartbeat: boolean; readonly maxHistory: number; readonly tagFilter: boolean; readonly authPopup: boolean; + readonly darkMode: boolean; } //Default storage config const defaultConfig : PluginConfig = Object.freeze({ - apiUrl: import.meta.env.VITE_API_URL, - accountBasePath: import.meta.env.VITE_ACCOUNTS_BASE_PATH, - nostrEndpoint: import.meta.env.VITE_NOSTR_ENDPOINT, + discoveryUrl: import.meta.env.VITE_DISCOVERY_URL, heartbeat: import.meta.env.VITE_HEARTBEAT_ENABLED === 'true', maxHistory: 50, tagFilter: true, authPopup: true, + darkMode: false, }); +export interface EndpointConfig extends JsonObject { + readonly apiBaseUrl: string; + readonly accountBasePath: string; + readonly nostrBasePath: string; +} + +export interface ConfigStatus { + readonly EpConfig: EndpointConfig; + readonly isDarkMode: boolean; + readonly isValid: boolean; +} + export interface AppSettings{ saveConfig(config: PluginConfig): void; useStorageSlot<T>(slot: string, defaultValue: MaybeRefOrGetter<T>): Ref<T>; useServerApi(): ServerApi, + setDarkMode(darkMode: boolean): void; + readonly status: Readonly<Ref<ConfigStatus>>; readonly currentConfig: Readonly<Ref<PluginConfig>>; } @@ -56,18 +68,55 @@ export interface SettingsApi extends FeatureApi, Watchable { getSiteConfig: () => Promise<PluginConfig>; setSiteConfig: (config: PluginConfig) => Promise<PluginConfig>; setDarkMode: (darkMode: boolean) => Promise<void>; - getDarkMode: () => Promise<boolean>; + getStatus: () => Promise<ConfigStatus>; + testServerAddress: (address: string) => Promise<boolean>; +} + +interface ServerDiscoveryResult{ + readonly endpoints: { + readonly name: string; + readonly path: string; + }[] +} + +const discoverAndSetEndpoints = async (discoveryUrl: string, epConfig: Ref<EndpointConfig | undefined>) => { + const res = await fetch(discoveryUrl) + const { endpoints } = await res.json() as ServerDiscoveryResult; + + const urls: EndpointConfig = { + apiBaseUrl: new URL(discoveryUrl).origin, + accountBasePath: find(endpoints, p => p.name == "account")?.path || "/account", + nostrBasePath: find(endpoints, p => p.name == "nostr")?.path || "/nostr", + }; + + //Set once the urls are discovered + set(epConfig, urls); } export const useAppSettings = (): AppSettings => { const _storageBackend = storage.local; + const _darkMode = shallowRef(false); const store = useStorage<PluginConfig>(_storageBackend, 'siteConfig', defaultConfig); + const endpointConfig = shallowRef<EndpointConfig>({nostrBasePath: '', accountBasePath: '', apiBaseUrl: ''}) + + const status = computed<ConfigStatus>(() => { + return{ + EpConfig: get(endpointConfig), + isDarkMode: get(_darkMode), + isValid: !isEmpty(get(endpointConfig).nostrBasePath) + } + }) //Merge the default config for nullables with the current config on startyup defaultsDeep(store.value, defaultConfig); - watch(store, (config, _) => { + //Watch for changes to the discovery url, then cause a discovery + watch([store], ([{ discoveryUrl }]) => { + defer(() => discoverAndSetEndpoints(discoveryUrl, endpointConfig)) + }, { immediate: true }) //alaways run on startup + + watch([endpointConfig], ([epconf]) => { //Configure the vnlib api configureApi({ session: { @@ -75,10 +124,10 @@ export const useAppSettings = (): AppSettings => { browserIdSize: 32, }, user: { - accountBasePath: config.accountBasePath, + accountBasePath: epconf?.accountBasePath, }, axios: { - baseURL: config.apiUrl, + baseURL: epconf?.apiBaseUrl, tokenHeader: import.meta.env.VITE_WEB_TOKEN_HEADER, }, storage: localStorage @@ -88,18 +137,19 @@ export const useAppSettings = (): AppSettings => { //Save the config and update the current config const saveConfig = (config: PluginConfig) => set(store, config); - - //Reactive urls for server api - const { accountBasePath, nostrEndpoint } = toRefs(store) - const serverApi = useServerApi(nostrEndpoint, accountBasePath) + + //Local reactive server api + const serverApi = useServerApi(endpointConfig) return { saveConfig, + status, currentConfig: readonly(store), useStorageSlot: <T>(slot: string, defaultValue: MaybeRefOrGetter<T>) => { return useStorage<T>(_storageBackend, slot, defaultValue) }, - useServerApi: () => serverApi + useServerApi: () => serverApi, + setDarkMode: (darkMode: boolean) => set(_darkMode, darkMode) } } @@ -108,10 +158,8 @@ export const useSettingsApi = () : IFeatureExport<AppSettings, SettingsApi> =>{ return{ background: ({ state }: BgRuntime<AppSettings>) => { - const _darkMode = shallowRef(false); - return { - waitForChange: waitForChangeFn([state.currentConfig, _darkMode]), + waitForChange: waitForChangeFn([state.currentConfig, state.status]), getSiteConfig: () => Promise.resolve(state.currentConfig.value), setSiteConfig: optionsOnly(async (config: PluginConfig): Promise<PluginConfig> => { @@ -123,18 +171,29 @@ export const useSettingsApi = () : IFeatureExport<AppSettings, SettingsApi> =>{ //Return the config return get(state.currentConfig) }), - setDarkMode: popupAndOptionsOnly(async (darkMode: boolean) => { - _darkMode.value = darkMode + setDarkMode: popupAndOptionsOnly((darkMode: boolean) => { + state.setDarkMode(darkMode); + return Promise.resolve(); }), - getDarkMode: async () => get(_darkMode), + getStatus: () => { + //Since value is computed it needs to be manually unwrapped + const { isDarkMode, isValid, EpConfig } = get(state.status); + return Promise.resolve({ isDarkMode, isValid, EpConfig }) + }, + testServerAddress: optionsOnly(async (url: string) => { + const res = await fetch(url); + const data = await res.json() as ServerDiscoveryResult; + return isArray(data?.endpoints) && !isEmpty(data.endpoints); + }) } }, foreground: exportForegroundApi([ 'getSiteConfig', 'setSiteConfig', 'setDarkMode', - 'getDarkMode', - 'waitForChange' + 'waitForChange', + 'getStatus', + 'testServerAddress' ]) } }
\ No newline at end of file |