mirror of
https://github.com/unraid/api.git
synced 2026-01-02 14:40:01 -06:00
Compare commits
36 Commits
v3.5.0
...
feat/serve
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
533927c692 | ||
|
|
985ed5bad4 | ||
|
|
21123f39a6 | ||
|
|
fd6f4eccf4 | ||
|
|
2ce62bf789 | ||
|
|
b33c86c99c | ||
|
|
cd0248e4c9 | ||
|
|
ecb3ed5003 | ||
|
|
0569339a41 | ||
|
|
3e9faead43 | ||
|
|
6e700b2385 | ||
|
|
464fc4993c | ||
|
|
4316c72809 | ||
|
|
ce0cebe09c | ||
|
|
23b90a0d56 | ||
|
|
3f8b3536b5 | ||
|
|
0dcf785b45 | ||
|
|
8cf4aff622 | ||
|
|
cefda7c42b | ||
|
|
0393b2382c | ||
|
|
23e900f7fd | ||
|
|
2d6aafc257 | ||
|
|
b191efece1 | ||
|
|
2a7f0043f5 | ||
|
|
607c7e3704 | ||
|
|
c246a443c5 | ||
|
|
fd495e1f5c | ||
|
|
621a06cafa | ||
|
|
f890b05151 | ||
|
|
567d8fdd6d | ||
|
|
7d996906ad | ||
|
|
b5ec076279 | ||
|
|
de8dfe3dba | ||
|
|
7249956d40 | ||
|
|
e6eb56466e | ||
|
|
8954700bcb |
6
.github/workflows/pull-request.yml
vendored
6
.github/workflows/pull-request.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
# network=host driver-opt needed to push to local registry
|
||||
driver-opts: network=host
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
# network=host driver-opt needed to push to local registry
|
||||
driver-opts: network=host
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
# network=host driver-opt needed to push to local registry
|
||||
driver-opts: network=host
|
||||
|
||||
@@ -1 +1 @@
|
||||
18.17.1
|
||||
18.19.1
|
||||
@@ -2,6 +2,43 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [3.5.3](https://github.com/unraid/api/compare/v3.5.2...v3.5.3) (2024-03-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* regDevs usage to allow more flexibility for STARTER ([#860](https://github.com/unraid/api/issues/860)) ([92a9600](https://github.com/unraid/api/commit/92a9600f3a242c5f263f1672eab81054b9cf4fae))
|
||||
|
||||
### [3.5.2](https://github.com/unraid/api/compare/v3.5.1...v3.5.2) (2024-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency vue-i18n to v9.10.1 ([#813](https://github.com/unraid/api/issues/813)) ([69b599c](https://github.com/unraid/api/commit/69b599c5ed8d44864201a32b4d952427d454dc74))
|
||||
* **deps:** update dependency wretch to v2.8.0 ([#814](https://github.com/unraid/api/issues/814)) ([66900b4](https://github.com/unraid/api/commit/66900b495b82b923264897d38b1529a22b10aa1c))
|
||||
* update os check modal button conditionals ([282a836](https://github.com/unraid/api/commit/282a83625f417ccefe090b65cc6b73a084727a87))
|
||||
* update os check modal ineligible date format ([83083de](https://github.com/unraid/api/commit/83083de1e698f73a35635ae6047dcf49fd4b8114))
|
||||
|
||||
### [3.5.1](https://github.com/unraid/api/compare/v3.5.0...v3.5.1) (2024-02-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* build docker command updated to use dc.sh script ([0b40886](https://github.com/unraid/api/commit/0b40886e84f27a94dbf67ef4ca0cd8539ef3913e))
|
||||
* date format in UnraidCheck.php ([#852](https://github.com/unraid/api/issues/852)) ([6465f2d](https://github.com/unraid/api/commit/6465f2d7b2394090f35e29cdd680d98ce37f3728))
|
||||
* **deps:** update dependency @apollo/client to v3.9.5 ([#785](https://github.com/unraid/api/issues/785)) ([75b98bc](https://github.com/unraid/api/commit/75b98bc1cbca5b66ae72f52a0b6f5f58230a2473))
|
||||
* **deps:** update dependency @heroicons/vue to v2.1.1 ([#804](https://github.com/unraid/api/issues/804)) ([a0eb7ee](https://github.com/unraid/api/commit/a0eb7ee3ec459dbe1992a7f85bf194da30395a74))
|
||||
* **deps:** update dependency focus-trap to v7.5.4 ([#788](https://github.com/unraid/api/issues/788)) ([fe000e8](https://github.com/unraid/api/commit/fe000e83825e82cac558d3277664a440e59c0e4a))
|
||||
* **deps:** update dependency graphql-ws to v5.15.0 ([#790](https://github.com/unraid/api/issues/790)) ([4773b13](https://github.com/unraid/api/commit/4773b132167d740d4c996efe22e0f1b99576fb9b))
|
||||
* display dropdown for pro key no connect installed ([#848](https://github.com/unraid/api/issues/848)) ([b559604](https://github.com/unraid/api/commit/b55960429895b46627f1cd3ed1683ee527e62944))
|
||||
* dropdown reboot link text ([#849](https://github.com/unraid/api/issues/849)) ([a8ed5e5](https://github.com/unraid/api/commit/a8ed5e5628bc71fb783a03c3db92d21805243738))
|
||||
* os updates rc to stable ([bf1bd88](https://github.com/unraid/api/commit/bf1bd887d60ac085bf4aeae90f11be3b45ee1182))
|
||||
* state connect values without connect installed ([e47de6c](https://github.com/unraid/api/commit/e47de6c2c5db7a2a1a9b24099feb02023b3a7bbf))
|
||||
* state php breaking with double quotes in server description ([c6e92aa](https://github.com/unraid/api/commit/c6e92aa3157c9fe9e7b83580881ebcc1cbd03658))
|
||||
* state php special chars for html attributes ([#853](https://github.com/unraid/api/issues/853)) ([dd4139c](https://github.com/unraid/api/commit/dd4139cf1a7ae5c6f9b00111c33ae124bb17e630))
|
||||
* unraid-api missing start command + var defaults ([ceb4c58](https://github.com/unraid/api/commit/ceb4c587d20c7527f2b36a3278c310b0e657bfba))
|
||||
* unraid-api.php $param1 fallback ([909c79c](https://github.com/unraid/api/commit/909c79c8c82500aea1a0d4d00766f788103c5fe3))
|
||||
|
||||
## [3.5.0](https://github.com/unraid/api/compare/v3.4.0...v3.5.0) (2024-02-07)
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
###########################################################
|
||||
# Development/Build Image
|
||||
###########################################################
|
||||
FROM node:18.17.1-bookworm-slim As development
|
||||
FROM node:18.19.1-bookworm-slim As development
|
||||
|
||||
# Install build tools and dependencies
|
||||
RUN apt-get update -y && apt-get install -y \
|
||||
|
||||
381
api/package-lock.json
generated
381
api/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@unraid/api",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@unraid/api",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.3",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.8.9",
|
||||
@@ -192,17 +192,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@apollo/client": {
|
||||
"version": "3.8.9",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.8.9.tgz",
|
||||
"integrity": "sha512-IcQDFEEPc9+PEQsxhxQvsoQ04BRarOzi/Ila5PcniRSDeKJWgY22dnp6+V1i1fWXRDVd1ybdvze4sFESDVQUCQ==",
|
||||
"version": "3.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.9.5.tgz",
|
||||
"integrity": "sha512-7y+c8MTPU+hhTwvcGVtMMGIgWduzrvG1mz5yJMRyqYbheBkkky3Lki6ADWVSBXG1lZoOtPYvB2zDgVfKb2HSsw==",
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.1.1",
|
||||
"@wry/caches": "^1.0.0",
|
||||
"@wry/equality": "^0.5.6",
|
||||
"@wry/trie": "^0.5.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"optimism": "^0.18.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"rehackt": "0.0.5",
|
||||
"response-iterator": "^0.2.6",
|
||||
"symbol-observable": "^4.0.0",
|
||||
"ts-invariant": "^0.10.3",
|
||||
@@ -210,7 +212,7 @@
|
||||
"zen-observable-ts": "^1.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
||||
"graphql": "^15.0.0 || ^16.0.0",
|
||||
"graphql-ws": "^5.5.5",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
@@ -2173,9 +2175,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==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -3427,13 +3429,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.13",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
||||
"integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^2.0.1",
|
||||
"debug": "^4.1.1",
|
||||
"@humanwhocodes/object-schema": "^2.0.2",
|
||||
"debug": "^4.3.1",
|
||||
"minimatch": "^3.0.5"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3453,9 +3455,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/object-schema": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
|
||||
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@hutson/parse-repository-url": {
|
||||
@@ -5810,9 +5812,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.2.0.tgz",
|
||||
"integrity": "sha512-YvX8ULTUm1+zkvkl14IqXYGxE1h13OXKPoDsxazARKlp4YLrP28hHEBdplaU7ZTN/Yn6zy6Z3JadWNRJwcmyrQ==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.3.1.tgz",
|
||||
"integrity": "sha512-UuBnkSJUNE9rdHjDCPyJ4fYuMkoMtnghes1XohYa4At0MS3OQSAo97FrbwSLRshYsXThMZy1+ybD/byK5llyIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.1",
|
||||
@@ -5823,7 +5825,7 @@
|
||||
"istanbul-lib-source-maps": "^4.0.1",
|
||||
"istanbul-reports": "^3.1.6",
|
||||
"magic-string": "^0.30.5",
|
||||
"magicast": "^0.3.2",
|
||||
"magicast": "^0.3.3",
|
||||
"picocolors": "^1.0.0",
|
||||
"std-env": "^3.5.0",
|
||||
"test-exclude": "^6.0.0",
|
||||
@@ -5833,17 +5835,17 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vitest": "^1.0.0"
|
||||
"vitest": "1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.0.tgz",
|
||||
"integrity": "sha512-H+2bHzhyvgp32o7Pgj2h9RTHN0pgYaoi26Oo3mE+dCi1PAqV31kIIVfTbqMO3Bvshd5mIrJLc73EwSRrbol9Lw==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz",
|
||||
"integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/spy": "1.2.0",
|
||||
"@vitest/utils": "1.2.0",
|
||||
"@vitest/spy": "1.3.1",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"chai": "^4.3.10"
|
||||
},
|
||||
"funding": {
|
||||
@@ -5851,12 +5853,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/runner": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.0.tgz",
|
||||
"integrity": "sha512-vaJkDoQaNUTroT70OhM0NPznP7H3WyRwt4LvGwCVYs/llLaqhoSLnlIhUClZpbF5RgAee29KRcNz0FEhYcgxqA==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.3.1.tgz",
|
||||
"integrity": "sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/utils": "1.2.0",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"p-limit": "^5.0.0",
|
||||
"pathe": "^1.1.1"
|
||||
},
|
||||
@@ -5892,9 +5894,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/snapshot": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.0.tgz",
|
||||
"integrity": "sha512-P33EE7TrVgB3HDLllrjK/GG6WSnmUtWohbwcQqmm7TAk9AVHpdgf7M3F3qRHKm6vhr7x3eGIln7VH052Smo6Kw==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.3.1.tgz",
|
||||
"integrity": "sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"magic-string": "^0.30.5",
|
||||
@@ -5906,9 +5908,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/spy": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.0.tgz",
|
||||
"integrity": "sha512-MNxSAfxUaCeowqyyGwC293yZgk7cECZU9wGb8N1pYQ0yOn/SIr8t0l9XnGRdQZvNV/ZHBYu6GO/W3tj5K3VN1Q==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz",
|
||||
"integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tinyspy": "^2.2.0"
|
||||
@@ -5918,12 +5920,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/ui": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.2.0.tgz",
|
||||
"integrity": "sha512-AFU8FBiSioYacEd0b8+2R/4GJJhxseD6bNIiEVntb505u1B/mcNMTVRepZql7r3RQJZQ7uijY9QyLdhlbh4XvA==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.3.1.tgz",
|
||||
"integrity": "sha512-2UrFLJ62c/eJGPHcclstMKlAR7E1WB1ITe1isuowEPJJHi3HfqofvsUqQ1cGrEF7kitG1DJuwURUA3HLDtQkXA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/utils": "1.2.0",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"fast-glob": "^3.3.2",
|
||||
"fflate": "^0.8.1",
|
||||
"flatted": "^3.2.9",
|
||||
@@ -5935,13 +5937,13 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vitest": "^1.0.0"
|
||||
"vitest": "1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/utils": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.0.tgz",
|
||||
"integrity": "sha512-FyD5bpugsXlwVpTcGLDf3wSPYy8g541fQt14qtzo8mJ4LdEpDKZ9mQy2+qdJm2TZRpjY5JLXihXCgIxiRJgi5g==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz",
|
||||
"integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"diff-sequences": "^29.6.3",
|
||||
@@ -8881,16 +8883,16 @@
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"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",
|
||||
"@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",
|
||||
@@ -9317,9 +9319,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/globals": {
|
||||
"version": "13.23.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
|
||||
"integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
|
||||
"version": "13.24.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.20.2"
|
||||
@@ -10892,9 +10894,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/graphql-ws": {
|
||||
"version": "5.14.3",
|
||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.14.3.tgz",
|
||||
"integrity": "sha512-F/i2xNIVbaEF2xWggID0X/UZQa2V8kqKDPO8hwmu53bVOcTL7uNkxnexeEgSCVxYBQUTUNEI8+e4LO1FOhKPKQ==",
|
||||
"version": "5.15.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.15.0.tgz",
|
||||
"integrity": "sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -12514,13 +12516,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/magicast": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.2.tgz",
|
||||
"integrity": "sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==",
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.3.tgz",
|
||||
"integrity": "sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.23.3",
|
||||
"@babel/types": "^7.23.3",
|
||||
"@babel/parser": "^7.23.6",
|
||||
"@babel/types": "^7.23.6",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
@@ -15182,6 +15184,23 @@
|
||||
"jsesc": "bin/jsesc"
|
||||
}
|
||||
},
|
||||
"node_modules/rehackt": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.0.5.tgz",
|
||||
"integrity": "sha512-BI1rV+miEkaHj8zd2n+gaMgzu/fKz7BGlb4zZ6HAiY9adDmJMkaDcmuXlJFv0eyKUob+oszs3/2gdnXUrzx2Tg==",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/relay-runtime": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz",
|
||||
@@ -16450,17 +16469,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/strip-literal": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz",
|
||||
"integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz",
|
||||
"integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.10.0"
|
||||
"js-tokens": "^8.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-literal/node_modules/js-tokens": {
|
||||
"version": "8.0.3",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz",
|
||||
"integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/strnum": {
|
||||
"version": "1.0.5",
|
||||
"license": "MIT"
|
||||
@@ -16832,18 +16857,18 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tinypool": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz",
|
||||
"integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==",
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz",
|
||||
"integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyspy": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz",
|
||||
"integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
|
||||
"integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -17886,9 +17911,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite-node": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.0.tgz",
|
||||
"integrity": "sha512-ETnQTHeAbbOxl7/pyBck9oAPZZZo+kYnFt1uQDD+hPReOc+wCjXw4r4jHriBRuVDB5isHmPXxrfc1yJnfBERqg==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.3.1.tgz",
|
||||
"integrity": "sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cac": "^6.7.14",
|
||||
@@ -17977,18 +18002,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vitest": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.0.tgz",
|
||||
"integrity": "sha512-Ixs5m7BjqvLHXcibkzKRQUvD/XLw0E3rvqaCMlrm/0LMsA0309ZqYvTlPzkhh81VlEyVZXFlwWnkhb6/UMtcaQ==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.3.1.tgz",
|
||||
"integrity": "sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/expect": "1.2.0",
|
||||
"@vitest/runner": "1.2.0",
|
||||
"@vitest/snapshot": "1.2.0",
|
||||
"@vitest/spy": "1.2.0",
|
||||
"@vitest/utils": "1.2.0",
|
||||
"acorn-walk": "^8.3.1",
|
||||
"cac": "^6.7.14",
|
||||
"@vitest/expect": "1.3.1",
|
||||
"@vitest/runner": "1.3.1",
|
||||
"@vitest/snapshot": "1.3.1",
|
||||
"@vitest/spy": "1.3.1",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"acorn-walk": "^8.3.2",
|
||||
"chai": "^4.3.10",
|
||||
"debug": "^4.3.4",
|
||||
"execa": "^8.0.1",
|
||||
@@ -17997,11 +18021,11 @@
|
||||
"pathe": "^1.1.1",
|
||||
"picocolors": "^1.0.0",
|
||||
"std-env": "^3.5.0",
|
||||
"strip-literal": "^1.3.0",
|
||||
"strip-literal": "^2.0.0",
|
||||
"tinybench": "^2.5.1",
|
||||
"tinypool": "^0.8.1",
|
||||
"tinypool": "^0.8.2",
|
||||
"vite": "^5.0.0",
|
||||
"vite-node": "1.2.0",
|
||||
"vite-node": "1.3.1",
|
||||
"why-is-node-running": "^2.2.2"
|
||||
},
|
||||
"bin": {
|
||||
@@ -18016,8 +18040,8 @@
|
||||
"peerDependencies": {
|
||||
"@edge-runtime/vm": "*",
|
||||
"@types/node": "^18.0.0 || >=20.0.0",
|
||||
"@vitest/browser": "^1.0.0",
|
||||
"@vitest/ui": "^1.0.0",
|
||||
"@vitest/browser": "1.3.1",
|
||||
"@vitest/ui": "1.3.1",
|
||||
"happy-dom": "*",
|
||||
"jsdom": "*"
|
||||
},
|
||||
@@ -18654,17 +18678,19 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@apollo/client": {
|
||||
"version": "3.8.9",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.8.9.tgz",
|
||||
"integrity": "sha512-IcQDFEEPc9+PEQsxhxQvsoQ04BRarOzi/Ila5PcniRSDeKJWgY22dnp6+V1i1fWXRDVd1ybdvze4sFESDVQUCQ==",
|
||||
"version": "3.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.9.5.tgz",
|
||||
"integrity": "sha512-7y+c8MTPU+hhTwvcGVtMMGIgWduzrvG1mz5yJMRyqYbheBkkky3Lki6ADWVSBXG1lZoOtPYvB2zDgVfKb2HSsw==",
|
||||
"requires": {
|
||||
"@graphql-typed-document-node/core": "^3.1.1",
|
||||
"@wry/caches": "^1.0.0",
|
||||
"@wry/equality": "^0.5.6",
|
||||
"@wry/trie": "^0.5.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"optimism": "^0.18.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"rehackt": "0.0.5",
|
||||
"response-iterator": "^0.2.6",
|
||||
"symbol-observable": "^4.0.0",
|
||||
"ts-invariant": "^0.10.3",
|
||||
@@ -19923,9 +19949,9 @@
|
||||
}
|
||||
},
|
||||
"@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==",
|
||||
"dev": true
|
||||
},
|
||||
"@fastify/ajv-compiler": {
|
||||
@@ -20894,13 +20920,13 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
"version": "0.11.13",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
||||
"integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@humanwhocodes/object-schema": "^2.0.1",
|
||||
"debug": "^4.1.1",
|
||||
"@humanwhocodes/object-schema": "^2.0.2",
|
||||
"debug": "^4.3.1",
|
||||
"minimatch": "^3.0.5"
|
||||
}
|
||||
},
|
||||
@@ -20909,9 +20935,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@humanwhocodes/object-schema": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
|
||||
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
||||
"dev": true
|
||||
},
|
||||
"@hutson/parse-repository-url": {
|
||||
@@ -22487,9 +22513,9 @@
|
||||
}
|
||||
},
|
||||
"@vitest/coverage-v8": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.2.0.tgz",
|
||||
"integrity": "sha512-YvX8ULTUm1+zkvkl14IqXYGxE1h13OXKPoDsxazARKlp4YLrP28hHEBdplaU7ZTN/Yn6zy6Z3JadWNRJwcmyrQ==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.3.1.tgz",
|
||||
"integrity": "sha512-UuBnkSJUNE9rdHjDCPyJ4fYuMkoMtnghes1XohYa4At0MS3OQSAo97FrbwSLRshYsXThMZy1+ybD/byK5llyIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@ampproject/remapping": "^2.2.1",
|
||||
@@ -22500,7 +22526,7 @@
|
||||
"istanbul-lib-source-maps": "^4.0.1",
|
||||
"istanbul-reports": "^3.1.6",
|
||||
"magic-string": "^0.30.5",
|
||||
"magicast": "^0.3.2",
|
||||
"magicast": "^0.3.3",
|
||||
"picocolors": "^1.0.0",
|
||||
"std-env": "^3.5.0",
|
||||
"test-exclude": "^6.0.0",
|
||||
@@ -22508,23 +22534,23 @@
|
||||
}
|
||||
},
|
||||
"@vitest/expect": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.0.tgz",
|
||||
"integrity": "sha512-H+2bHzhyvgp32o7Pgj2h9RTHN0pgYaoi26Oo3mE+dCi1PAqV31kIIVfTbqMO3Bvshd5mIrJLc73EwSRrbol9Lw==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz",
|
||||
"integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vitest/spy": "1.2.0",
|
||||
"@vitest/utils": "1.2.0",
|
||||
"@vitest/spy": "1.3.1",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"chai": "^4.3.10"
|
||||
}
|
||||
},
|
||||
"@vitest/runner": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.0.tgz",
|
||||
"integrity": "sha512-vaJkDoQaNUTroT70OhM0NPznP7H3WyRwt4LvGwCVYs/llLaqhoSLnlIhUClZpbF5RgAee29KRcNz0FEhYcgxqA==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.3.1.tgz",
|
||||
"integrity": "sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vitest/utils": "1.2.0",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"p-limit": "^5.0.0",
|
||||
"pathe": "^1.1.1"
|
||||
},
|
||||
@@ -22547,9 +22573,9 @@
|
||||
}
|
||||
},
|
||||
"@vitest/snapshot": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.0.tgz",
|
||||
"integrity": "sha512-P33EE7TrVgB3HDLllrjK/GG6WSnmUtWohbwcQqmm7TAk9AVHpdgf7M3F3qRHKm6vhr7x3eGIln7VH052Smo6Kw==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.3.1.tgz",
|
||||
"integrity": "sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"magic-string": "^0.30.5",
|
||||
@@ -22558,21 +22584,21 @@
|
||||
}
|
||||
},
|
||||
"@vitest/spy": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.0.tgz",
|
||||
"integrity": "sha512-MNxSAfxUaCeowqyyGwC293yZgk7cECZU9wGb8N1pYQ0yOn/SIr8t0l9XnGRdQZvNV/ZHBYu6GO/W3tj5K3VN1Q==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz",
|
||||
"integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tinyspy": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@vitest/ui": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.2.0.tgz",
|
||||
"integrity": "sha512-AFU8FBiSioYacEd0b8+2R/4GJJhxseD6bNIiEVntb505u1B/mcNMTVRepZql7r3RQJZQ7uijY9QyLdhlbh4XvA==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.3.1.tgz",
|
||||
"integrity": "sha512-2UrFLJ62c/eJGPHcclstMKlAR7E1WB1ITe1isuowEPJJHi3HfqofvsUqQ1cGrEF7kitG1DJuwURUA3HLDtQkXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vitest/utils": "1.2.0",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"fast-glob": "^3.3.2",
|
||||
"fflate": "^0.8.1",
|
||||
"flatted": "^3.2.9",
|
||||
@@ -22582,9 +22608,9 @@
|
||||
}
|
||||
},
|
||||
"@vitest/utils": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.0.tgz",
|
||||
"integrity": "sha512-FyD5bpugsXlwVpTcGLDf3wSPYy8g541fQt14qtzo8mJ4LdEpDKZ9mQy2+qdJm2TZRpjY5JLXihXCgIxiRJgi5g==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz",
|
||||
"integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"diff-sequences": "^29.6.3",
|
||||
@@ -24534,16 +24560,16 @@
|
||||
"dev": true
|
||||
},
|
||||
"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==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@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",
|
||||
@@ -24617,9 +24643,9 @@
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "13.23.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
|
||||
"integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
|
||||
"version": "13.24.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.20.2"
|
||||
@@ -25945,9 +25971,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"graphql-ws": {
|
||||
"version": "5.14.3",
|
||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.14.3.tgz",
|
||||
"integrity": "sha512-F/i2xNIVbaEF2xWggID0X/UZQa2V8kqKDPO8hwmu53bVOcTL7uNkxnexeEgSCVxYBQUTUNEI8+e4LO1FOhKPKQ==",
|
||||
"version": "5.15.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.15.0.tgz",
|
||||
"integrity": "sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw==",
|
||||
"requires": {}
|
||||
},
|
||||
"handlebars": {
|
||||
@@ -26989,13 +27015,13 @@
|
||||
}
|
||||
},
|
||||
"magicast": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.2.tgz",
|
||||
"integrity": "sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==",
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.3.tgz",
|
||||
"integrity": "sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.23.3",
|
||||
"@babel/types": "^7.23.3",
|
||||
"@babel/parser": "^7.23.6",
|
||||
"@babel/types": "^7.23.6",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
@@ -28730,6 +28756,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"rehackt": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.0.5.tgz",
|
||||
"integrity": "sha512-BI1rV+miEkaHj8zd2n+gaMgzu/fKz7BGlb4zZ6HAiY9adDmJMkaDcmuXlJFv0eyKUob+oszs3/2gdnXUrzx2Tg==",
|
||||
"requires": {}
|
||||
},
|
||||
"relay-runtime": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz",
|
||||
@@ -29605,12 +29637,20 @@
|
||||
"version": "3.1.1"
|
||||
},
|
||||
"strip-literal": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz",
|
||||
"integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz",
|
||||
"integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^8.10.0"
|
||||
"js-tokens": "^8.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-tokens": {
|
||||
"version": "8.0.3",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz",
|
||||
"integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"strnum": {
|
||||
@@ -29859,15 +29899,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"tinypool": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz",
|
||||
"integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==",
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz",
|
||||
"integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tinyspy": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz",
|
||||
"integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
|
||||
"integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
|
||||
"dev": true
|
||||
},
|
||||
"title-case": {
|
||||
@@ -30494,9 +30534,9 @@
|
||||
}
|
||||
},
|
||||
"vite-node": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.0.tgz",
|
||||
"integrity": "sha512-ETnQTHeAbbOxl7/pyBck9oAPZZZo+kYnFt1uQDD+hPReOc+wCjXw4r4jHriBRuVDB5isHmPXxrfc1yJnfBERqg==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.3.1.tgz",
|
||||
"integrity": "sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cac": "^6.7.14",
|
||||
@@ -30558,18 +30598,17 @@
|
||||
}
|
||||
},
|
||||
"vitest": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.0.tgz",
|
||||
"integrity": "sha512-Ixs5m7BjqvLHXcibkzKRQUvD/XLw0E3rvqaCMlrm/0LMsA0309ZqYvTlPzkhh81VlEyVZXFlwWnkhb6/UMtcaQ==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-1.3.1.tgz",
|
||||
"integrity": "sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vitest/expect": "1.2.0",
|
||||
"@vitest/runner": "1.2.0",
|
||||
"@vitest/snapshot": "1.2.0",
|
||||
"@vitest/spy": "1.2.0",
|
||||
"@vitest/utils": "1.2.0",
|
||||
"acorn-walk": "^8.3.1",
|
||||
"cac": "^6.7.14",
|
||||
"@vitest/expect": "1.3.1",
|
||||
"@vitest/runner": "1.3.1",
|
||||
"@vitest/snapshot": "1.3.1",
|
||||
"@vitest/spy": "1.3.1",
|
||||
"@vitest/utils": "1.3.1",
|
||||
"acorn-walk": "^8.3.2",
|
||||
"chai": "^4.3.10",
|
||||
"debug": "^4.3.4",
|
||||
"execa": "^8.0.1",
|
||||
@@ -30578,11 +30617,11 @@
|
||||
"pathe": "^1.1.1",
|
||||
"picocolors": "^1.0.0",
|
||||
"std-env": "^3.5.0",
|
||||
"strip-literal": "^1.3.0",
|
||||
"strip-literal": "^2.0.0",
|
||||
"tinybench": "^2.5.1",
|
||||
"tinypool": "^0.8.1",
|
||||
"tinypool": "^0.8.2",
|
||||
"vite": "^5.0.0",
|
||||
"vite-node": "1.2.0",
|
||||
"vite-node": "1.3.1",
|
||||
"why-is-node-running": "^2.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@unraid/api",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.3",
|
||||
"main": "dist/index.js",
|
||||
"bin": "dist/unraid-api.cjs",
|
||||
"type": "module",
|
||||
@@ -26,7 +26,7 @@
|
||||
"compile": "tsup --config ./tsup.config.ts",
|
||||
"bundle": "pkg . --public",
|
||||
"build": "npm run compile && npm run bundle",
|
||||
"build:docker": "GIT_SHA=$(git rev-parse --short HEAD) IS_TAGGED=$(git describe --tags --abbrev=0 --exact-match || echo '') docker-compose run --rm builder",
|
||||
"build:docker": "./scripts/dc.sh run --rm builder",
|
||||
"build-pkg": "./scripts/build.mjs",
|
||||
"codegen": "MOTHERSHIP_GRAPHQL_LINK='https://staging.mothership.unraid.net/ws' graphql-codegen --config codegen.yml -r dotenv/config './.env.staging'",
|
||||
"codegen:watch": "DOTENV_CONFIG_PATH='./.env.staging' graphql-codegen-esm --config codegen.yml --watch -r dotenv/config",
|
||||
|
||||
@@ -140,7 +140,7 @@ function registerServer(button) {
|
||||
button.form.submit();
|
||||
});
|
||||
<?else:?>
|
||||
// give the unraid-api time to call rc.nginx and UpdateDNS before refreshing the page
|
||||
// give the unraid-api time to call rc.nginx before refreshing the page
|
||||
const delay = 4000;
|
||||
setTimeout(function() {
|
||||
button.form.submit();
|
||||
|
||||
@@ -30,8 +30,7 @@ if (!document.getElementsByTagName(modalsWebComponent).length) {
|
||||
$i18nHost.appendChild($modals);
|
||||
}
|
||||
</script>
|
||||
<?
|
||||
echo "
|
||||
|
||||
<unraid-i18n-host>
|
||||
<unraid-user-profile server='" . $serverState->getServerStateJson() . "'></unraid-user-profile>
|
||||
</unraid-i18n-host>";
|
||||
<unraid-user-profile server="<?= $serverState->getServerStateJsonForHtmlAttr() ?>"></unraid-user-profile>
|
||||
</unraid-i18n-host>
|
||||
|
||||
@@ -34,11 +34,20 @@ class ServerState
|
||||
protected $webguiGlobals;
|
||||
|
||||
private $var;
|
||||
private $flashbackupCfg;
|
||||
private $apiKey = '';
|
||||
private $apiVersion = '';
|
||||
private $avatar = '';
|
||||
private $email = '';
|
||||
private $extraOrigins = [];
|
||||
private $flashBackupActivated = '';
|
||||
private $hasRemoteApikey = false;
|
||||
private $registeredTime = '';
|
||||
private $username = '';
|
||||
private $connectPluginInstalled = '';
|
||||
private $connectPluginVersion;
|
||||
private $configErrorEnum = [
|
||||
"error" => 'UNKNOWN_ERROR',
|
||||
"ineligible" => 'INELIGIBLE',
|
||||
"invalid" => 'INVALID',
|
||||
"nokeyserver" => 'NO_KEY_SERVER',
|
||||
"withdrawn" => 'WITHDRAWN',
|
||||
@@ -58,9 +67,9 @@ class ServerState
|
||||
public $host = 'unknown';
|
||||
public $combinedKnownOrigins = [];
|
||||
|
||||
public $nginxCfg;
|
||||
public $flashbackupStatus;
|
||||
public $registered;
|
||||
public $nginxCfg = [];
|
||||
public $flashbackupStatus = [];
|
||||
public $registered = false;
|
||||
public $myServersMiniGraphConnected = false;
|
||||
public $keyfileBase64 = '';
|
||||
|
||||
@@ -78,11 +87,42 @@ class ServerState
|
||||
// echo "<pre>" . json_encode($this->webguiGlobals, JSON_PRETTY_PRINT) . "</pre>";
|
||||
|
||||
$this->var = (array)parse_ini_file('state/var.ini');
|
||||
$this->nginxCfg = parse_ini_file('/var/local/emhttp/nginx.ini');
|
||||
$this->nginxCfg = @parse_ini_file('/var/local/emhttp/nginx.ini') ?? [];
|
||||
|
||||
$this->flashbackupCfg = '/var/local/emhttp/flashbackup.ini';
|
||||
$this->flashbackupStatus = (file_exists($this->flashbackupCfg)) ? @parse_ini_file($this->flashbackupCfg) : [];
|
||||
$this->osVersion = $this->var['version'];
|
||||
$this->osVersionBranch = trim(@exec('plugin category /var/log/plugins/unRAIDServer.plg') ?? 'stable');
|
||||
|
||||
$caseModelFile = '/boot/config/plugins/dynamix/case-model.cfg';
|
||||
$this->caseModel = file_exists($caseModelFile) ? file_get_contents($caseModelFile) : '';
|
||||
|
||||
$this->rebootDetails = new RebootDetails();
|
||||
|
||||
$this->keyfileBase64 = empty($this->var['regFILE']) ? null : @file_get_contents($this->var['regFILE']);
|
||||
if ($this->keyfileBase64 !== false) {
|
||||
$this->keyfileBase64 = @base64_encode($this->keyfileBase64);
|
||||
$this->keyfileBase64UrlSafe = str_replace(['+', '/', '='], ['-', '_', ''], trim($this->keyfileBase64));
|
||||
}
|
||||
|
||||
$this->updateOsCheck = new UnraidOsCheck();
|
||||
$this->updateOsIgnoredReleases = $this->updateOsCheck->getIgnoredReleases();
|
||||
$this->updateOsNotificationsEnabled = !empty(@$this->getWebguiGlobal('notify', 'unraidos'));
|
||||
$this->updateOsResponse = $this->updateOsCheck->getUnraidOSCheckResult();
|
||||
|
||||
$this->setConnectValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value of a webgui global setting.
|
||||
*/
|
||||
public function getWebguiGlobal(string $key, string $subkey = null) {
|
||||
if (!$subkey) {
|
||||
return _var($this->webguiGlobals, $key, '');
|
||||
}
|
||||
$keyArray = _var($this->webguiGlobals, $key, []);
|
||||
return _var($keyArray, $subkey, '');
|
||||
}
|
||||
|
||||
private function setConnectValues() {
|
||||
if (file_exists('/var/lib/pkgtools/packages/dynamix.unraid.net')) {
|
||||
$this->connectPluginInstalled = 'dynamix.unraid.net.plg';
|
||||
}
|
||||
@@ -93,11 +133,29 @@ class ServerState
|
||||
$this->connectPluginInstalled .= '_installFailed';
|
||||
}
|
||||
|
||||
// exit early if the plugin is not installed
|
||||
if (!$this->connectPluginInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->connectPluginVersion = file_exists('/var/log/plugins/dynamix.unraid.net.plg')
|
||||
? trim(@exec('/usr/local/sbin/plugin version /var/log/plugins/dynamix.unraid.net.plg 2>/dev/null'))
|
||||
: (file_exists('/var/log/plugins/dynamix.unraid.net.staging.plg')
|
||||
? trim(@exec('/usr/local/sbin/plugin version /var/log/plugins/dynamix.unraid.net.staging.plg 2>/dev/null'))
|
||||
: 'base-' . $this->var['version']);
|
||||
|
||||
$this->getMyServersCfgValues();
|
||||
$this->getConnectKnownOrigins();
|
||||
$this->getFlashBackupStatus();
|
||||
}
|
||||
|
||||
private function getFlashBackupStatus() {
|
||||
$flashbackupCfg = '/var/local/emhttp/flashbackup.ini';
|
||||
$this->flashbackupStatus = (file_exists($flashbackupCfg)) ? @parse_ini_file($flashbackupCfg) : [];
|
||||
$this->flashBackupActivated = empty($this->flashbackupStatus['activated']) ? '' : 'true';
|
||||
}
|
||||
|
||||
private function getMyServersCfgValues() {
|
||||
/**
|
||||
* @todo can we read this from somewhere other than the flash? Connect page uses this path and /boot/config/plugins/dynamix.my.servers/myservers.cfg…
|
||||
* - $myservers_memory_cfg_path ='/var/local/emhttp/myservers.cfg';
|
||||
@@ -122,15 +180,17 @@ class ServerState
|
||||
$this->myServersFlashCfg['remote']['dynamicRemoteAccessType'] = "DISABLED";
|
||||
}
|
||||
|
||||
$this->osVersion = $this->var['version'];
|
||||
$this->osVersionBranch = trim(@exec('plugin category /var/log/plugins/unRAIDServer.plg') ?? 'stable');
|
||||
$this->apiKey = $this->myServersFlashCfg['upc']['apikey'] ?? '';
|
||||
$this->apiVersion = $this->myServersFlashCfg['api']['version'] ?? '';
|
||||
$this->avatar = (!empty($this->myServersFlashCfg['remote']['avatar']) && $this->connectPluginInstalled) ? $this->myServersFlashCfg['remote']['avatar'] : '';
|
||||
$this->email = $this->myServersFlashCfg['remote']['email'] ?? '';
|
||||
$this->hasRemoteApikey = !empty($this->myServersFlashCfg['remote']['apikey']);
|
||||
$this->registered = !empty($this->myServersFlashCfg['remote']['apikey']) && $this->connectPluginInstalled;
|
||||
$this->registeredTime = $this->myServersFlashCfg['remote']['regWizTime'] ?? '';
|
||||
$this->username = $this->myServersFlashCfg['remote']['username'] ?? '';
|
||||
}
|
||||
|
||||
$caseModelFile = '/boot/config/plugins/dynamix/case-model.cfg';
|
||||
$this->caseModel = file_exists($caseModelFile) ? file_get_contents($caseModelFile) : '';
|
||||
|
||||
$this->rebootDetails = new RebootDetails();
|
||||
|
||||
private function getConnectKnownOrigins() {
|
||||
/**
|
||||
* Allowed origins warning displayed when the current webGUI URL is NOT included in the known lists of allowed origins.
|
||||
* Include localhost in the test, but only display HTTP(S) URLs that do not include localhost.
|
||||
@@ -145,6 +205,11 @@ class ServerState
|
||||
$combinedOrigins = $allowedOrigins . "," . $extraOrigins; // combine the two strings for easier searching
|
||||
$combinedOrigins = str_replace(" ", "", $combinedOrigins); // replace any spaces with nothing
|
||||
$hostNotKnown = stripos($combinedOrigins, $this->host) === false; // check if the current host is in the combined list of origins
|
||||
|
||||
if ($extraOrigins) {
|
||||
$this->extraOrigins = explode(",", $extraOrigins);
|
||||
}
|
||||
|
||||
if ($hostNotKnown) {
|
||||
$this->combinedKnownOrigins = explode(",", $combinedOrigins);
|
||||
|
||||
@@ -161,29 +226,8 @@ class ServerState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->keyfileBase64 = empty($this->var['regFILE']) ? null : @file_get_contents($this->var['regFILE']);
|
||||
if ($this->keyfileBase64 !== false) {
|
||||
$this->keyfileBase64 = @base64_encode($this->keyfileBase64);
|
||||
$this->keyfileBase64UrlSafe = str_replace(['+', '/', '='], ['-', '_', ''], trim($this->keyfileBase64));
|
||||
}
|
||||
|
||||
$this->updateOsCheck = new UnraidOsCheck();
|
||||
$this->updateOsIgnoredReleases = $this->updateOsCheck->getIgnoredReleases();
|
||||
$this->updateOsNotificationsEnabled = !empty(@$this->getWebguiGlobal('notify', 'unraidos'));
|
||||
$this->updateOsResponse = $this->updateOsCheck->getUnraidOSCheckResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value of a webgui global setting.
|
||||
*/
|
||||
public function getWebguiGlobal(string $key, string $subkey = null) {
|
||||
if (!$subkey) {
|
||||
return _var($this->webguiGlobals, $key, '');
|
||||
}
|
||||
$keyArray = _var($this->webguiGlobals, $key, []);
|
||||
return _var($keyArray, $subkey, '');
|
||||
}
|
||||
/**
|
||||
* Retrieve the server information as an associative array
|
||||
*
|
||||
@@ -192,13 +236,13 @@ class ServerState
|
||||
public function getServerState()
|
||||
{
|
||||
$serverState = [
|
||||
"apiKey" => $this->myServersFlashCfg['upc']['apikey'] ?? '',
|
||||
"apiVersion" => $this->myServersFlashCfg['api']['version'] ?? '',
|
||||
"avatar" => (!empty($this->myServersFlashCfg['remote']['avatar']) && $this->connectPluginInstalled) ? $this->myServersFlashCfg['remote']['avatar'] : '',
|
||||
"apiKey" => $this->apiKey,
|
||||
"apiVersion" => $this->apiVersion,
|
||||
"avatar" => $this->avatar,
|
||||
"caseModel" => $this->caseModel,
|
||||
"config" => [
|
||||
'valid' => ($this->var['configValid'] === 'yes'),
|
||||
'error' => isset($this->configErrorEnum[$this->var['configValid']]) ? $this->configErrorEnum[$this->var['configValid']] : 'UNKNOWN_ERROR',
|
||||
'error' => isset($this->configErrorEnum[$this->var['configValid']]) ? $this->configErrorEnum[$this->var['configValid']] : null,
|
||||
],
|
||||
"connectPluginInstalled" => $this->connectPluginInstalled,
|
||||
"connectPluginVersion" => $this->connectPluginVersion,
|
||||
@@ -207,35 +251,35 @@ class ServerState
|
||||
"date" => @$this->getWebguiGlobal('display', 'date') ?? '',
|
||||
"time" => @$this->getWebguiGlobal('display', 'time') ?? '',
|
||||
],
|
||||
"description" => $this->var['COMMENT'] ? htmlspecialchars($this->var['COMMENT']) : '',
|
||||
"description" => $this->var['COMMENT'] ? htmlspecialchars($this->var['COMMENT'], ENT_HTML5, 'UTF-8') : '',
|
||||
"deviceCount" => $this->var['deviceCount'],
|
||||
"email" => $this->myServersFlashCfg['remote']['email'] ?? '',
|
||||
"email" => $this->email,
|
||||
"expireTime" => 1000 * (($this->var['regTy'] === 'Trial' || strstr($this->var['regTy'], 'expired')) ? $this->var['regTm2'] : 0),
|
||||
"extraOrigins" => explode(',', $this->myServersFlashCfg['api']['extraOrigins'] ?? ''),
|
||||
"extraOrigins" => $this->extraOrigins,
|
||||
"flashProduct" => $this->var['flashProduct'],
|
||||
"flashVendor" => $this->var['flashVendor'],
|
||||
"flashBackupActivated" => empty($this->flashbackupStatus['activated']) ? '' : 'true',
|
||||
"flashBackupActivated" => $this->flashBackupActivated,
|
||||
"guid" => $this->var['flashGUID'],
|
||||
"hasRemoteApikey" => !empty($this->myServersFlashCfg['remote']['apikey']),
|
||||
"hasRemoteApikey" => $this->hasRemoteApikey,
|
||||
"internalPort" => _var($_SERVER, 'SERVER_PORT'),
|
||||
"keyfile" => $this->keyfileBase64UrlSafe,
|
||||
"lanIp" => ipaddr(),
|
||||
"locale" => (!empty($_SESSION) && $_SESSION['locale']) ? $_SESSION['locale'] : 'en_US',
|
||||
"model" => $this->var['SYS_MODEL'],
|
||||
"name" => htmlspecialchars($this->var['NAME']),
|
||||
"model" => $this->var['SYS_MODEL'] ? htmlspecialchars($this->var['SYS_MODEL'], ENT_HTML5, 'UTF-8') : '',
|
||||
"name" => htmlspecialchars($this->var['NAME'], ENT_HTML5, 'UTF-8'),
|
||||
"osVersion" => $this->osVersion,
|
||||
"osVersionBranch" => $this->osVersionBranch,
|
||||
"protocol" => _var($_SERVER, 'REQUEST_SCHEME'),
|
||||
"rebootType" => $this->rebootDetails->getRebootType(),
|
||||
"regDev" => @(int)$this->var['regDev'] ?? 0,
|
||||
"regDevs" => @(int)$this->var['regDevs'] ?? 0,
|
||||
"regGen" => @(int)$this->var['regGen'],
|
||||
"regGuid" => @$this->var['regGUID'] ?? '',
|
||||
"regTo" => @htmlspecialchars($this->var['regTo']) ?? '',
|
||||
"regTo" => @htmlspecialchars($this->var['regTo'], ENT_HTML5, 'UTF-8') ?? '',
|
||||
"regTm" => $this->var['regTm'] ? @$this->var['regTm'] * 1000 : '', // JS expects milliseconds
|
||||
"regTy" => @$this->var['regTy'] ?? '',
|
||||
"regExp" => $this->var['regExp'] ? @$this->var['regExp'] * 1000 : '', // JS expects milliseconds
|
||||
"registered" => $this->registered,
|
||||
"registeredTime" => $this->myServersFlashCfg['remote']['regWizTime'] ?? '',
|
||||
"registeredTime" => $this->registeredTime,
|
||||
"site" => _var($_SERVER, 'REQUEST_SCHEME') . "://" . _var($_SERVER, 'HTTP_HOST'),
|
||||
"state" => strtoupper(empty($this->var['regCheck']) ? $this->var['regTy'] : $this->var['regCheck']),
|
||||
"theme" => [
|
||||
@@ -249,8 +293,8 @@ class ServerState
|
||||
],
|
||||
"ts" => time(),
|
||||
"uptime" => 1000 * (time() - round(strtok(exec("cat /proc/uptime"), ' '))),
|
||||
"username" => $this->myServersFlashCfg['remote']['username'] ?? '',
|
||||
"wanFQDN" => $this->nginxCfg['NGINX_WANFQDN'] ?? '',
|
||||
"username" => $this->username,
|
||||
"wanFQDN" => @$this->nginxCfg['NGINX_WANFQDN'] ?? '',
|
||||
];
|
||||
|
||||
if ($this->combinedKnownOrigins) {
|
||||
@@ -273,11 +317,21 @@ class ServerState
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the server information as a JSON string
|
||||
* Retrieve the server information as JSON
|
||||
*
|
||||
* @return string A JSON string containing server information.
|
||||
* @return string
|
||||
*/
|
||||
public function getServerStateJson() {
|
||||
return json_encode($this->getServerState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the server information as JSON string with converted special characters to HTML entities
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServerStateJsonForHtmlAttr() {
|
||||
$json = json_encode($this->getServerState());
|
||||
return htmlspecialchars($json, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,16 +49,20 @@ if ($cli) {
|
||||
if ($argc > 2) $param1 = $argv[2];
|
||||
} else {
|
||||
$command = $_POST['command'];
|
||||
$param1 = $_POST['param1'];
|
||||
$param1 = $_POST['param1'] ?? '';
|
||||
}
|
||||
if (!in_array($command, $validCommands)) $command = 'none';
|
||||
|
||||
if (!file_exists('/usr/local/sbin/unraid-api') || !file_exists('/usr/local/bin/unraid-api/unraid-api')) {
|
||||
response_complete(406, array('error' => 'Please reinstall the My Servers plugin'));
|
||||
response_complete(406, array('error' => 'Please reinstall the Unraid Connect plugin'));
|
||||
}
|
||||
|
||||
$output = [];
|
||||
$retval = null;
|
||||
|
||||
switch ($command) {
|
||||
case 'start':
|
||||
exec('unraid-api start 2>/dev/null', $output, $retval);
|
||||
$output = implode(PHP_EOL, $output);
|
||||
response_complete(200, array('result' => $output), $output);
|
||||
break;
|
||||
|
||||
@@ -115,7 +115,7 @@ class UnraidOsCheck
|
||||
$params = [];
|
||||
$params['branch'] = plugin('category', self::PLG_PATH, 'stable');
|
||||
$params['current_version'] = plugin('version', self::PLG_PATH) ?: _var($var,'version');
|
||||
if (_var($var,'regExp')) $params['update_exp'] = date('m-d-Y', _var($var,'regExp')*1);
|
||||
if (_var($var,'regExp')) $params['update_exp'] = date('Y-m-d', _var($var,'regExp')*1);
|
||||
$defaultUrl = self::BASE_RELEASES_URL;
|
||||
// pass a param of altUrl to use the provided url instead of the default
|
||||
$parsedAltUrl = (array_key_exists('altUrl',$_GET) && $_GET['altUrl']) ? $_GET['altUrl'] : null;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
/* Copyright 2005-2024, Lime Technology
|
||||
* Copyright 2012-2024, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,429 +11,12 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'settings';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
|
||||
function host_lookup_ip($host) {
|
||||
$result = @dns_get_record($host, DNS_A);
|
||||
$ip = ($result) ? $result[0]['ip']??'' : '';
|
||||
return($ip);
|
||||
}
|
||||
function rebindDisabled() {
|
||||
global $isLegacyCert;
|
||||
$rebindtesturl = $isLegacyCert ? "rebindtest.unraid.net" : "rebindtest.myunraid.net";
|
||||
// DNS Rebind Protection - this checks the server but clients could still have issues
|
||||
$validResponse = array("192.168.42.42", "fd42");
|
||||
$response = host_lookup_ip($rebindtesturl);
|
||||
return in_array(explode('::',$response)[0], $validResponse);
|
||||
}
|
||||
function format_port($port) {
|
||||
return ($port != 80 && $port != 443) ? ':'.$port : '';
|
||||
}
|
||||
function anonymize_host($host) {
|
||||
global $anon;
|
||||
if ($anon) {
|
||||
$host = preg_replace('/.*\.myunraid\.net/', '*.hash.myunraid.net', $host);
|
||||
$host = preg_replace('/.*\.unraid\.net/', 'hash.unraid.net', $host);
|
||||
}
|
||||
return $host;
|
||||
}
|
||||
function anonymize_ip($ip) {
|
||||
global $anon;
|
||||
if ($anon && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
|
||||
$ip = "[redacted]";
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
function generate_internal_host($host, $ip) {
|
||||
if (strpos($host,'.myunraid.net') !== false) {
|
||||
$host = str_replace('*', str_replace('.', '-', $ip), $host);
|
||||
}
|
||||
return $host;
|
||||
}
|
||||
function generate_external_host($host, $ip) {
|
||||
if (strpos($host,'.myunraid.net') !== false) {
|
||||
$host = str_replace('*', str_replace('.', '-', $ip), $host);
|
||||
} elseif (strpos($host,'.unraid.net') !== false) {
|
||||
$host = "www.".$host;
|
||||
}
|
||||
return $host;
|
||||
}
|
||||
function verbose_output($httpcode, $result) {
|
||||
global $cli, $verbose, $anon, $plgversion, $post, $var, $isRegistered, $myservers, $reloadNginx, $nginx, $isLegacyCert;
|
||||
global $remoteaccess;
|
||||
global $icon_warn, $icon_ok;
|
||||
if (!$cli || !$verbose) return;
|
||||
|
||||
if ($anon) echo "(Output is anonymized, use '-vv' to see full details)".PHP_EOL;
|
||||
echo "Unraid OS {$var['version']}".((strpos($plgversion, "base-") === false) ? " with My Servers plugin version {$plgversion}" : '').PHP_EOL;
|
||||
echo ($isRegistered) ? "{$icon_ok}Signed in to Unraid.net as {$myservers['remote']['username']}".PHP_EOL : "{$icon_warn}Not signed in to Unraid.net".PHP_EOL ;
|
||||
echo "Use SSL is {$nginx['NGINX_USESSL']}".PHP_EOL;
|
||||
echo (rebindDisabled()) ? "{$icon_ok}Rebind protection is disabled" : "{$icon_warn}Rebind protection is enabled";
|
||||
echo " for ".($isLegacyCert ? "unraid.net" : "myunraid.net").PHP_EOL;
|
||||
if ($post) {
|
||||
$wanip = trim(@file_get_contents("https://wanip4.unraid.net/"));
|
||||
// check the data
|
||||
$certhostname = $nginx['NGINX_CERTNAME'];
|
||||
if ($certhostname) {
|
||||
// $certhostname is $nginx['NGINX_CERTNAME'] (certificate_bundle.pem)
|
||||
$certhostip = host_lookup_ip(generate_internal_host($certhostname, $post['internalip']));
|
||||
$certhosterr = ($certhostip != $post['internalip']);
|
||||
}
|
||||
if ($post['internalhostname'] != $certhostname) {
|
||||
// $post['internalhostname'] is $nginx['NGINX_LANMDNS'] (no cert, or Server_unraid_bundle.pem) || $nginx['NGINX_CERTNAME'] (certificate_bundle.pem)
|
||||
$internalhostip = host_lookup_ip(generate_internal_host($post['internalhostname'], $post['internalip']));
|
||||
$internalhosterr = ($internalhostip != $post['internalip']);
|
||||
}
|
||||
if (!empty($post['externalhostname'])) {
|
||||
// $post['externalhostname'] is $nginx['NGINX_CERTNAME'] (certificate_bundle.pem)
|
||||
$externalhostip = host_lookup_ip(generate_external_host($post['externalhostname'], $wanip));
|
||||
$externalhosterr = ($externalhostip != $wanip);
|
||||
}
|
||||
// anonymize data. no caclulations can be done with this data beyond this point.
|
||||
if ($anon) {
|
||||
if (!empty($certhostip)) $certhostip = anonymize_ip($certhostip);
|
||||
if (!empty($certhostname)) $certhostname = anonymize_host($certhostname);
|
||||
if (!empty($internalhostip)) $internalhostip = anonymize_ip($internalhostip);
|
||||
if (!empty($externalhostip)) $externalhostip = anonymize_ip($externalhostip);
|
||||
if (!empty($wanip)) $wanip = anonymize_ip($wanip);
|
||||
if (!empty($post['internalip'])) $post['internalip'] = anonymize_ip($post['internalip']);
|
||||
if (!empty($post['internalhostname'])) $post['internalhostname'] = anonymize_host($post['internalhostname']);
|
||||
if (!empty($post['externalhostname'])) $post['externalhostname'] = anonymize_host($post['externalhostname']);
|
||||
if (!empty($post['externalport'])) $post['externalport'] = "[redacted]";
|
||||
}
|
||||
// always anonymize the keyfile
|
||||
if (!empty($post['keyfile'])) $post['keyfile'] = "[redacted]";
|
||||
// output notes
|
||||
if (!empty($post['internalprotocol']) && !empty($post['internalhostname']) && !empty($post['internalport'])) {
|
||||
$localurl = $post['internalprotocol']."://".generate_internal_host($post['internalhostname'], $post['internalip']).format_port($post['internalport']);
|
||||
echo 'Local Access url: '.$localurl.PHP_EOL;
|
||||
if ($internalhostip) {
|
||||
// $internalhostip will not be defined for .local domains, ok to skip
|
||||
echo ($internalhosterr) ? $icon_warn : $icon_ok;
|
||||
echo generate_internal_host($post['internalhostname'], $post['internalip'])." resolves to {$internalhostip}";
|
||||
echo ($internalhosterr) ? ", it should resolve to {$post['internalip']}" : "";
|
||||
echo PHP_EOL;
|
||||
}
|
||||
if ($certhostname) {
|
||||
echo ($certhosterr) ? $icon_warn : $icon_ok;
|
||||
echo generate_internal_host($certhostname, $post['internalip']).' ';
|
||||
echo ($certhostip) ? "resolves to {$certhostip}" : "does not resolve to an IP address";
|
||||
echo ($certhosterr) ? ", it should resolve to {$post['internalip']}" : "";
|
||||
echo PHP_EOL;
|
||||
}
|
||||
if ($remoteaccess == 'yes' && !empty($post['externalprotocol']) && !empty($post['externalhostname']) && !empty($post['externalport'])) {
|
||||
$remoteurl = $post['externalprotocol']."://".generate_external_host($post['externalhostname'], $wanip).format_port($post['externalport']);
|
||||
echo 'Remote Access url: '.$remoteurl.PHP_EOL;
|
||||
echo ($externalhosterr) ? $icon_warn : $icon_ok;
|
||||
echo generate_external_host($post['externalhostname'], $wanip).' ';
|
||||
echo ($externalhosterr) ? "does not resolve to an IP address" : "resolves to {$externalhostip}";
|
||||
echo PHP_EOL;
|
||||
}
|
||||
if ($reloadNginx) {
|
||||
echo "IP address changes were detected, nginx was reloaded".PHP_EOL;
|
||||
}
|
||||
}
|
||||
// output post data
|
||||
echo PHP_EOL.'Request:'.PHP_EOL;
|
||||
echo @json_encode($post, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;
|
||||
}
|
||||
if ($result) {
|
||||
echo "Response (HTTP $httpcode):".PHP_EOL;
|
||||
$mutatedResult = is_array($result) ? json_encode($result) : $result;
|
||||
echo @json_encode(@json_decode($mutatedResult, true), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @name response_complete
|
||||
* @param {HTTP Response Status Code} $httpcode https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
|
||||
* @param {String|Array} $result - strings are assumed to be encoded JSON. Arrays will be encoded to JSON.
|
||||
* @param {String} $cli_success_msg
|
||||
*/
|
||||
function response_complete($httpcode, $result, $cli_success_msg='') {
|
||||
global $cli, $verbose;
|
||||
$mutatedResult = is_array($result) ? json_encode($result) : $result;
|
||||
if ($cli) {
|
||||
if ($verbose) verbose_output($httpcode, $result);
|
||||
$json = @json_decode($mutatedResult,true);
|
||||
if (!empty($json['error'])) {
|
||||
echo 'Error: '.$json['error'].PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
exit($cli_success_msg.PHP_EOL);
|
||||
}
|
||||
header('Content-Type: application/json');
|
||||
http_response_code($httpcode);
|
||||
exit((string)$mutatedResult);
|
||||
}
|
||||
|
||||
// This is a stub, does nothing but return success
|
||||
$cli = php_sapi_name()=='cli';
|
||||
$verbose = $anon = false;
|
||||
if ($cli && ($argc > 1) && $argv[1] == "-v") {
|
||||
$verbose = true;
|
||||
$anon = true;
|
||||
}
|
||||
if ($cli && ($argc > 1) && $argv[1] == "-vv") {
|
||||
$verbose = true;
|
||||
}
|
||||
$var = parse_ini_file('/var/local/emhttp/var.ini');
|
||||
$nginx = parse_ini_file('/var/local/emhttp/nginx.ini');
|
||||
$is69 = version_compare($var['version'],"6.9.9","<");
|
||||
$reloadNginx = false;
|
||||
$dnserr = false;
|
||||
$icon_warn = "⚠️ ";
|
||||
$icon_ok = "✅ ";
|
||||
|
||||
$myservers_flash_cfg_path='/boot/config/plugins/dynamix.my.servers/myservers.cfg';
|
||||
$myservers = file_exists($myservers_flash_cfg_path) ? @parse_ini_file($myservers_flash_cfg_path,true) : [];
|
||||
// ensure some vars are defined here so we don't have to test them later
|
||||
if (empty($myservers['remote']['apikey'])) {
|
||||
$myservers['remote']['apikey'] = "";
|
||||
}
|
||||
if (empty($myservers['remote']['wanaccess'])) {
|
||||
$myservers['remote']['wanaccess'] = "no";
|
||||
}
|
||||
if (empty($myservers['remote']['wanport'])) {
|
||||
$myservers['remote']['wanport'] = 443;
|
||||
}
|
||||
// remoteaccess, externalport
|
||||
if ($cli) {
|
||||
$remoteaccess = (empty($nginx['NGINX_WANFQDN'])) ? 'no' : 'yes';
|
||||
$externalport = $myservers['remote']['wanport'];
|
||||
} else {
|
||||
$remoteaccess = $_POST['remoteaccess']??'no';
|
||||
$externalport = intval($_POST['externalport']??443);
|
||||
|
||||
if ($remoteaccess != 'yes') {
|
||||
$remoteaccess = 'no';
|
||||
}
|
||||
|
||||
if ($externalport < 1 || $externalport > 65535) {
|
||||
$externalport = 443;
|
||||
}
|
||||
|
||||
if ($myservers['remote']['wanaccess'] != $remoteaccess) {
|
||||
// update the wanaccess ini value
|
||||
$orig = file_exists($myservers_flash_cfg_path) ? parse_ini_file($myservers_flash_cfg_path,true) : [];
|
||||
if (!$orig) {
|
||||
$orig = ['remote' => $myservers['remote']];
|
||||
}
|
||||
$orig['remote']['wanaccess'] = $remoteaccess;
|
||||
$text = '';
|
||||
foreach ($orig as $section => $block) {
|
||||
$pairs = "";
|
||||
foreach ($block as $key => $value) if (strlen($value)) $pairs .= "$key=\"$value\"\n";
|
||||
if ($pairs) $text .= "[$section]\n".$pairs;
|
||||
}
|
||||
if ($text) file_put_contents($myservers_flash_cfg_path, $text);
|
||||
// need nginx reload
|
||||
$reloadNginx = true;
|
||||
}
|
||||
exit("success".PHP_EOL);
|
||||
}
|
||||
$isRegistered = !empty($myservers['remote']['username']);
|
||||
|
||||
// protocols, hostnames, ports
|
||||
$internalprotocol = 'http';
|
||||
$internalport = $nginx['NGINX_PORT'];
|
||||
$internalhostname = $nginx['NGINX_LANMDNS'];
|
||||
$externalprotocol = 'https';
|
||||
// keyserver will expand *.hash.myunraid.net or add www to hash.unraid.net as needed
|
||||
$externalhostname = $nginx['NGINX_CERTNAME'];
|
||||
$isLegacyCert = preg_match('/.*\.unraid\.net$/', $nginx['NGINX_CERTNAME']);
|
||||
$isWildcardCert = preg_match('/.*\.myunraid\.net$/', $nginx['NGINX_CERTNAME']);
|
||||
$internalip = $nginx['NGINX_LANIP'];
|
||||
|
||||
if ($nginx['NGINX_USESSL']=='yes') {
|
||||
// When NGINX_USESSL is 'yes' in 6.9, it could be using either Server_unraid_bundle.pem or certificate_bundle.pem
|
||||
// When NGINX_USESSL is 'yes' in 6.10, it is is using Server_unraid_bundle.pem
|
||||
$internalprotocol = 'https';
|
||||
$internalport = $nginx['NGINX_PORTSSL'];
|
||||
if ($is69 && $nginx['NGINX_CERTNAME']) {
|
||||
// this is from certificate_bundle.pem
|
||||
$internalhostname = $nginx['NGINX_CERTNAME'];
|
||||
}
|
||||
}
|
||||
if ($nginx['NGINX_USESSL']=='auto') {
|
||||
// NGINX_USESSL cannot be 'auto' in 6.9, it is either 'yes' or 'no'
|
||||
// When NGINX_USESSL is 'auto' in 6.10, it is using certificate_bundle.pem
|
||||
$internalprotocol = 'https';
|
||||
$internalport = $nginx['NGINX_PORTSSL'];
|
||||
// keyserver will expand *.hash.myunraid.net as needed
|
||||
$internalhostname = $nginx['NGINX_CERTNAME'];
|
||||
}
|
||||
|
||||
// My Servers version
|
||||
$plgversion = file_exists("/var/log/plugins/dynamix.unraid.net.plg") ? trim(@exec('/usr/local/sbin/plugin version /var/log/plugins/dynamix.unraid.net.plg 2>/dev/null'))
|
||||
: ( file_exists("/var/log/plugins/dynamix.unraid.net.staging.plg") ? trim(@exec('/usr/local/sbin/plugin version /var/log/plugins/dynamix.unraid.net.staging.plg 2>/dev/null'))
|
||||
: 'base-'.$var['version'] );
|
||||
|
||||
// only proceed when when signed in or when legacy unraid.net SSL certificate exists
|
||||
if (!$isRegistered && !$isLegacyCert) {
|
||||
response_complete(406, array('error' => _('Nothing to do')));
|
||||
}
|
||||
|
||||
// keyfile
|
||||
$keyfile = empty($var['regFILE']) ? false : @file_get_contents($var['regFILE']);
|
||||
if ($keyfile === false) {
|
||||
response_complete(406, array('error' => _('Registration key required')));
|
||||
}
|
||||
$keyfile = @base64_encode($keyfile);
|
||||
|
||||
// build post array
|
||||
$post = [
|
||||
'keyfile' => $keyfile,
|
||||
'plgversion' => $plgversion
|
||||
];
|
||||
if ($isLegacyCert) {
|
||||
// sign in not required to maintain local ddns for unraid.net cert
|
||||
// enable local ddns regardless of use_ssl value
|
||||
$post['internalip'] = $internalip;
|
||||
// if host.unraid.net does not resolve to the internalip and DNS Rebind Protection is disabled, disable caching
|
||||
if (host_lookup_ip(generate_internal_host($nginx['NGINX_CERTNAME'], $post['internalip'])) != $post['internalip'] && rebindDisabled()) $dnserr = true;
|
||||
}
|
||||
if ($isRegistered) {
|
||||
// if signed in, send data needed to maintain My Servers Dashboard
|
||||
$post['internalhostname'] = $internalhostname;
|
||||
$post['internalport'] = $internalport;
|
||||
$post['internalprotocol'] = $internalprotocol;
|
||||
$post['remoteaccess'] = $remoteaccess;
|
||||
$post['servercomment'] = $var['COMMENT'];
|
||||
$post['servername'] = $var['NAME'];
|
||||
if ($isWildcardCert) {
|
||||
// keyserver needs the internalip to generate the local access url
|
||||
$post['internalip'] = $internalip;
|
||||
}
|
||||
if ($remoteaccess == 'yes') {
|
||||
// include wanip in the cache file so we can track if it changes
|
||||
$post['_wanip'] = trim(@file_get_contents("https://wanip4.unraid.net/"));
|
||||
$post['externalhostname'] = $externalhostname;
|
||||
$post['externalport'] = $externalport;
|
||||
$post['externalprotocol'] = $externalprotocol;
|
||||
// if wanip.hash.myunraid.net or www.hash.unraid.net does not resolve to the wanip, disable caching
|
||||
if (host_lookup_ip(generate_external_host($post['externalhostname'], $post['_wanip'])) != $post['_wanip']) $dnserr = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Include unraid-api report
|
||||
$unraidreport = [];
|
||||
if (file_exists('/usr/local/sbin/unraid-api')) {
|
||||
$jsonString = trim(@exec("/usr/local/sbin/unraid-api report --json 2>/dev/null"));
|
||||
$unraidreport = @json_decode($jsonString, true);
|
||||
if ($unraidreport === false) {
|
||||
$post['unraidreport'] = $jsonString;
|
||||
} else {
|
||||
// remove fields we don't need to submit
|
||||
unset($unraidreport['servers']);
|
||||
}
|
||||
} elseif (strpos($plgversion, "base-") === false) {
|
||||
// The plugin is installed but the api doesn't exist. This is a failed install. Generate basic troubleshooting data.
|
||||
if (file_exists('/boot/config/plugins/dynamix.my.servers/env')) {
|
||||
@extract(parse_ini_file('/boot/config/plugins/dynamix.my.servers/env',true));
|
||||
}
|
||||
if (empty($env)) {
|
||||
$env = "production";
|
||||
}
|
||||
$unraidreport['os']['version'] = $var['version'];
|
||||
$unraidreport['api']['version'] = "failed install";
|
||||
$unraidreport['api']['status'] = "missing";
|
||||
$unraidreport['api']['environment'] = $env;
|
||||
$unraidreport['relay']['status'] = "disconnected";
|
||||
$unraidreport['minigraph']['status'] = "disconnected";
|
||||
if ($isRegistered) {
|
||||
$unraidreport['myServers']['status'] = "authenticated";
|
||||
$unraidreport['myServers']['myServersUsername'] = $myservers['remote']['username'];
|
||||
} else {
|
||||
$unraidreport['myServers']['status'] = "signed out";
|
||||
}
|
||||
$unraidreport['apiKey'] = (empty($myservers['remote']['apikey'])) ? "invalid" : "exists";
|
||||
}
|
||||
|
||||
if (!empty($unraidreport)) {
|
||||
// include unraid-api crash logs
|
||||
$crashLog = '/var/log/unraid-api/crash.json';
|
||||
$crashAge = 0;
|
||||
if (file_exists($crashLog)) {
|
||||
$crashTime = filemtime($crashLog);
|
||||
$crashAge = time() - $crashTime; // age of crashLog in seconds
|
||||
$crashDetails = @json_decode(@file_get_contents($crashLog), true);
|
||||
if (empty($crashDetails['apiVersion']) && $crashAge < 30*60) {
|
||||
// found a recent crash log without an apiVersion, assume was created by current version of api
|
||||
$crashDetails['apiVersion'] = $unraidreport['api']['version'];
|
||||
// overwrite the crash log so it will always have the apiVersion
|
||||
file_put_contents($crashLog, json_encode($crashDetails, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
// reset to original timestamp so crashAge remains accurate
|
||||
touch($crashLog, $crashTime);
|
||||
}
|
||||
$unraidreport['crashAge'] = $crashAge;
|
||||
$unraidreport['crashLogs'] = $crashDetails;
|
||||
}
|
||||
|
||||
// add flash backup status
|
||||
$flashbackup_ini = '/var/local/emhttp/flashbackup.ini';
|
||||
$flashbackup_status = (file_exists($flashbackup_ini)) ? @parse_ini_file($flashbackup_ini) : [];
|
||||
if (empty($flashbackup_status['activated'])) {
|
||||
$flashbackup_status['activated'] = "";
|
||||
}
|
||||
if (empty($flashbackup_status['error'])) {
|
||||
$flashbackup_status['error'] = "";
|
||||
}
|
||||
$unraidreport['flashbackup']['activated'] = ($flashbackup_status['activated']) ? "yes" : "no";
|
||||
$unraidreport['flashbackup']['error'] = ($flashbackup_status['error']) ? $flashbackup_status['error'] : "no";
|
||||
|
||||
// add unraidreport to payload
|
||||
$post['unraidreport'] = json_encode($unraidreport);
|
||||
|
||||
// if the api is stopped and there are no crashLogs, or any crashLogs are more than maxCrashAge, start the api
|
||||
$maxCrashAge = 1*60*60; // 1 hour
|
||||
if ($unraidreport['api']['status'] == 'stopped' && (empty($unraidreport['crashLogs']) || $crashAge > $maxCrashAge)) {
|
||||
exec("echo \"/usr/local/sbin/unraid-api start\" | at -M now >/dev/null 2>&1");
|
||||
}
|
||||
}
|
||||
|
||||
// if remoteaccess is enabled in 6.10.0-rc3+ and WANIP has changed since nginx started, reload nginx
|
||||
if (isset($post['_wanip']) && ($post['_wanip'] != $nginx['NGINX_WANIP']) && version_compare($var['version'],"6.10.0-rc2",">")) $reloadNginx = true;
|
||||
// if remoteaccess is currently disabled (perhaps because a wanip was not available when nginx was started)
|
||||
// BUT the system is configured to have it enabled AND a wanip is now available
|
||||
// then reload nginx
|
||||
if ($remoteaccess == 'no' && $nginx['NGINX_WANACCESS'] == 'yes' && !empty(trim(@file_get_contents("https://wanip4.unraid.net/")))) $reloadNginx = true;
|
||||
if ($reloadNginx) {
|
||||
exec("/etc/rc.d/rc.nginx reload &>/dev/null");
|
||||
}
|
||||
|
||||
// maxage is 36 hours
|
||||
$maxage = 36*60*60;
|
||||
if ($dnserr || $verbose) $maxage = 0;
|
||||
$datafile = "/tmp/UpdateDNS.txt";
|
||||
$datafiletmp = "/tmp/UpdateDNS.txt.new";
|
||||
$dataprev = @file_get_contents($datafile) ?: '';
|
||||
$datanew = implode("\n",$post)."\n";
|
||||
if ($datanew == $dataprev && (time()-filemtime($datafile) < $maxage)) {
|
||||
response_complete(204, null, _('No change to report'));
|
||||
}
|
||||
file_put_contents($datafiletmp,$datanew);
|
||||
rename($datafiletmp, $datafile);
|
||||
|
||||
// do not submit the wanip, it will be captured from the submission if needed for remote access
|
||||
unset($post['_wanip']);
|
||||
|
||||
// report necessary server details to limetech for DNS updates
|
||||
$ch = curl_init('https://keys.lime-technology.com/account/server/register');
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$result = curl_exec($ch);
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ( ($result === false) || ($httpcode != "200") ) {
|
||||
// delete cache file to retry submission on next run
|
||||
@unlink($datafile);
|
||||
response_complete($httpcode ?? "500", array('error' => $error));
|
||||
}
|
||||
|
||||
response_complete($httpcode, $result, _('success'));
|
||||
header('Content-Type: application/json');
|
||||
http_response_code(204);
|
||||
exit(0);
|
||||
?>
|
||||
|
||||
@@ -1 +1 @@
|
||||
18.17.1
|
||||
18.19.1
|
||||
@@ -24,8 +24,32 @@ import type {
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// ENOKEYFILE
|
||||
// TRIAL
|
||||
// BASIC
|
||||
// PLUS
|
||||
// PRO
|
||||
// STARTER
|
||||
// UNLEASHED
|
||||
// LIFETIME
|
||||
// EEXPIRED
|
||||
// EGUID
|
||||
// EGUID1
|
||||
// ETRIAL
|
||||
// ENOKEYFILE2
|
||||
// ENOKEYFILE1
|
||||
// ENOFLASH
|
||||
// EBLACKLISTED
|
||||
// EBLACKLISTED1
|
||||
// EBLACKLISTED2
|
||||
// ENOCONN
|
||||
|
||||
// '1111-1111-5GDB-123412341234' Starter.key = TkJCrVyXMLWWGKZF6TCEvf0C86UYI9KfUDSOm7JoFP19tOMTMgLKcJ6QIOt9_9Psg_t0yF-ANmzSgZzCo94ljXoPm4BESFByR0K7nyY9KVvU8szLEUcBUT3xC2adxLrAXFNxiPeK-mZqt34n16uETKYvLKL_Sr5_JziG5L5lJFBqYZCPmfLMiguFo1vp0xL8pnBH7q8bYoBnePrAcAVb9mAGxFVPEInSPkMBfC67JLHz7XY1Y_K5bYIq3go9XPtLltJ53_U4BQiMHooXUBJCKXodpqoGxq0eV0IhNEYdauAhnTsG90qmGZig0hZalQ0soouc4JZEMiYEcZbn9mBxPg
|
||||
const staticGuid = '1111-1111-5GDB-123412341234';
|
||||
|
||||
const state: ServerState = 'STARTER';
|
||||
const currentFlashGuid = '1111-1111-SDDD-TEST1234ZACK '; // this is the flash drive that's been booted from
|
||||
const regGuid = '1111-1111-SDDD-TEST1234ZACK '; // this guid is registered in key server
|
||||
const keyfileBase64 = ''; // @todo raycast download key to base64
|
||||
|
||||
// const randomGuid = `1111-1111-${makeid(4)}-123412341234`; // this guid is registered in key server
|
||||
// const newGuid = `1234-1234-${makeid(4)}-123412341234`; // this is a new USB, not registered
|
||||
@@ -42,24 +66,7 @@ const oneHourFromNow = Date.now() + 60 * 60 * 1000; // 1 hour from now
|
||||
let expireTime = 0;
|
||||
let regExp: number | undefined;
|
||||
|
||||
// ENOKEYFILE
|
||||
// TRIAL
|
||||
// BASIC
|
||||
// PLUS
|
||||
// PRO
|
||||
// EEXPIRED
|
||||
// EGUID
|
||||
// EGUID1
|
||||
// ETRIAL
|
||||
// ENOKEYFILE2
|
||||
// ENOKEYFILE1
|
||||
// ENOFLASH
|
||||
// EBLACKLISTED
|
||||
// EBLACKLISTED1
|
||||
// EBLACKLISTED2
|
||||
// ENOCONN
|
||||
const state: ServerState = 'STARTER';
|
||||
let regDev = 0;
|
||||
let regDevs = 0;
|
||||
let regTy = '';
|
||||
switch (state) {
|
||||
// @ts-ignore
|
||||
@@ -73,15 +80,15 @@ switch (state) {
|
||||
regTy = 'Trial';
|
||||
// @ts-ignore
|
||||
case 'BASIC':
|
||||
regDev = 6;
|
||||
regDevs = 6;
|
||||
// @ts-ignore
|
||||
case 'PLUS':
|
||||
regDev = 12;
|
||||
regDevs = 12;
|
||||
// @ts-ignore
|
||||
case 'PRO':
|
||||
// @ts-ignore
|
||||
case 'STARTER':
|
||||
regDev = 4;
|
||||
regDevs = 6;
|
||||
// regExp = oneHourFromNow;
|
||||
// regExp = oneDayFromNow;
|
||||
regExp = ninetyDaysAgo;
|
||||
@@ -96,15 +103,15 @@ switch (state) {
|
||||
// regExp = 1696363920000; // nori.local's expiration
|
||||
// @ts-ignore
|
||||
case 'LIFETIME':
|
||||
if (regDev === 0) { regDev = 99999; }
|
||||
if (regDevs === 0) { regDevs = -1; }
|
||||
if (regTy === '') { regTy = state.charAt(0).toUpperCase() + state.substring(1).toLowerCase(); } // title case
|
||||
break;
|
||||
}
|
||||
|
||||
const connectPluginInstalled = 'dynamix.unraid.net.staging.plg';
|
||||
// const connectPluginInstalled = '';
|
||||
// const connectPluginInstalled = 'dynamix.unraid.net.staging.plg';
|
||||
const connectPluginInstalled = '';
|
||||
|
||||
const osVersion = '6.12.5';
|
||||
const osVersion = '6.12.8';
|
||||
const osVersionBranch = 'stable';
|
||||
// const parsedRegExp = regExp ? dayjs(regExp).format('YYYY-MM-DD') : undefined;
|
||||
|
||||
@@ -133,21 +140,21 @@ export const serverState: Server = {
|
||||
apiKey: 'unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810',
|
||||
avatar: 'https://source.unsplash.com/300x300/?portrait',
|
||||
config: {
|
||||
// error: 'INVALID',
|
||||
valid: true,
|
||||
error: null,
|
||||
valid: false,
|
||||
},
|
||||
connectPluginInstalled,
|
||||
description: 'DevServer9000',
|
||||
deviceCount: 3,
|
||||
deviceCount: 4,
|
||||
expireTime,
|
||||
flashBackupActivated: !!connectPluginInstalled,
|
||||
flashProduct: 'SanDisk_3.2Gen1',
|
||||
flashVendor: 'USB',
|
||||
guid: staticGuid,
|
||||
guid: currentFlashGuid,
|
||||
// "guid": "0781-5583-8355-81071A2B0211",
|
||||
inIframe: false,
|
||||
// keyfile: 'DUMMY_KEYFILE',
|
||||
keyfile: 'TkJCrVyXMLWWGKZF6TCEvf0C86UYI9KfUDSOm7JoFP19tOMTMgLKcJ6QIOt9_9Psg_t0yF-ANmzSgZzCo94ljXoPm4BESFByR0K7nyY9KVvU8szLEUcBUT3xC2adxLrAXFNxiPeK-mZqt34n16uETKYvLKL_Sr5_JziG5L5lJFBqYZCPmfLMiguFo1vp0xL8pnBH7q8bYoBnePrAcAVb9mAGxFVPEInSPkMBfC67JLHz7XY1Y_K5bYIq3go9XPtLltJ53_U4BQiMHooXUBJCKXodpqoGxq0eV0IhNEYdauAhnTsG90qmGZig0hZalQ0soouc4JZEMiYEcZbn9mBxPg',
|
||||
keyfile: keyfileBase64,
|
||||
lanIp: '192.168.254.36',
|
||||
license: '',
|
||||
locale: 'en_US', // en_US, ja
|
||||
@@ -161,7 +168,7 @@ export const serverState: Server = {
|
||||
regTo: 'Zack Spear',
|
||||
regTy,
|
||||
regExp,
|
||||
// "regGuid": "0781-5583-8355-81071A2B0211",
|
||||
regGuid,
|
||||
site: 'http://localhost:4321',
|
||||
state,
|
||||
theme: {
|
||||
@@ -173,15 +180,15 @@ export const serverState: Server = {
|
||||
name: 'white',
|
||||
textColor: ''
|
||||
},
|
||||
updateOsResponse: {
|
||||
version: '6.12.6',
|
||||
name: 'Unraid 6.12.6',
|
||||
date: '2023-12-13',
|
||||
isNewer: true,
|
||||
isEligible: false,
|
||||
changelog: 'https://docs.unraid.net/unraid-os/release-notes/6.12.6/',
|
||||
sha256: '2f5debaf80549029cf6dfab0db59180e7e3391c059e6521aace7971419c9c4bf',
|
||||
},
|
||||
// updateOsResponse: {
|
||||
// version: '6.12.6',
|
||||
// name: 'Unraid 6.12.6',
|
||||
// date: '2023-12-13',
|
||||
// isNewer: true,
|
||||
// isEligible: false,
|
||||
// changelog: 'https://docs.unraid.net/unraid-os/release-notes/6.12.6/',
|
||||
// sha256: '2f5debaf80549029cf6dfab0db59180e7e3391c059e6521aace7971419c9c4bf',
|
||||
// },
|
||||
uptime,
|
||||
username: 'zspearmint',
|
||||
wanFQDN: ''
|
||||
|
||||
@@ -47,6 +47,7 @@ const {
|
||||
flashProduct,
|
||||
keyActions,
|
||||
keyfile,
|
||||
computedRegDevs,
|
||||
regGuid,
|
||||
regTm,
|
||||
regTo,
|
||||
@@ -56,6 +57,7 @@ const {
|
||||
state,
|
||||
stateData,
|
||||
stateDataError,
|
||||
tooManyDevices,
|
||||
} = storeToRefs(serverStore);
|
||||
|
||||
const formattedRegTm = ref<any>();
|
||||
@@ -76,24 +78,6 @@ onBeforeMount(() => {
|
||||
setFormattedRegTm();
|
||||
});
|
||||
|
||||
const devicesAvailable = computed((): number => {
|
||||
switch (regTy.value) {
|
||||
case 'Starter':
|
||||
return 4;
|
||||
case 'Basic':
|
||||
return 6;
|
||||
case 'Plus':
|
||||
return 12;
|
||||
case 'Unleashed':
|
||||
case 'Lifetime':
|
||||
case 'Pro':
|
||||
case 'Trial':
|
||||
return 9999;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
const showTrialExpiration = computed((): boolean => state.value === 'TRIAL' || state.value === 'EEXPIRED');
|
||||
const showUpdateEligibility = computed((): boolean => !!(regExp.value));
|
||||
const keyInstalled = computed((): boolean => !!(!stateDataError.value && state.value !== 'ENOKEYFILE'));
|
||||
@@ -169,11 +153,11 @@ const items = computed((): RegistrationItemProps[] => {
|
||||
: []),
|
||||
...(keyInstalled.value
|
||||
? [{
|
||||
error: deviceCount.value > devicesAvailable.value,
|
||||
error: tooManyDevices.value,
|
||||
label: t('Attached Storage Devices'),
|
||||
text: deviceCount.value > devicesAvailable.value
|
||||
? t('{0} out of {1} allowed devices – upgrade your key to support more devices', [deviceCount.value, devicesAvailable.value > 12 ? t('unlimited') : devicesAvailable.value])
|
||||
: t('{0} out of {1} devices', [deviceCount.value, devicesAvailable.value > 12 ? t('unlimited') : devicesAvailable.value]),
|
||||
text: tooManyDevices.value
|
||||
? t('{0} out of {1} allowed devices – upgrade your key to support more devices', [deviceCount.value, computedRegDevs.value])
|
||||
: t('{0} out of {1} devices', [deviceCount.value, computedRegDevs.value === -1 ? t('unlimited') : computedRegDevs.value]),
|
||||
}]
|
||||
: []),
|
||||
...(showTransferStatus.value
|
||||
|
||||
@@ -49,9 +49,20 @@ const {
|
||||
checkForUpdatesLoading,
|
||||
} = storeToRefs(updateOsStore);
|
||||
|
||||
const {
|
||||
outputDateTimeFormatted: formattedRegExp,
|
||||
} = useDateTimeHelper(dateTimeFormat.value, props.t, true, regExp.value);
|
||||
/**
|
||||
* regExp may not have a value until we get a response from the refreshServerState action
|
||||
* So we need to watch for this value to be able to format it based on the user's date time preferences.
|
||||
*/
|
||||
const formattedRegExp = ref<any>();
|
||||
const setFormattedRegExp = () => { // ran in watch on regExp and onBeforeMount
|
||||
if (!regExp.value) { return; }
|
||||
|
||||
const { outputDateTimeFormatted } = useDateTimeHelper(dateTimeFormat.value, props.t, true, regExp.value);
|
||||
formattedRegExp.value = outputDateTimeFormatted.value;
|
||||
};
|
||||
watch(regExp, (_newV) => {
|
||||
setFormattedRegExp();
|
||||
});
|
||||
|
||||
const ignoreThisRelease = ref(false);
|
||||
// if we had a release ignored and now we don't set ignoreThisRelease to false
|
||||
@@ -136,7 +147,8 @@ const actionButtons = computed((): ButtonProps[] | null => {
|
||||
const buttons: ButtonProps[] = [];
|
||||
|
||||
// update available but not stable branch - should link out to account update callback
|
||||
if (availableRequiresAuth.value) {
|
||||
// if availableWithRenewal.value is true, then we need to renew the license before we can update so don't show the verify button
|
||||
if (availableRequiresAuth.value && !availableWithRenewal.value) {
|
||||
buttons.push({
|
||||
click: async () => await accountStore.updateOs(),
|
||||
icon: IdentificationIcon,
|
||||
@@ -147,7 +159,7 @@ const actionButtons = computed((): ButtonProps[] | null => {
|
||||
}
|
||||
|
||||
// update available - open changelog to commence update
|
||||
if (available.value) {
|
||||
if (available.value && updateOsResponse.value?.changelog) {
|
||||
buttons.push({
|
||||
btnStyle: availableWithRenewal.value
|
||||
? 'outline'
|
||||
@@ -208,6 +220,7 @@ onBeforeMount(() => {
|
||||
if (availableReleaseDate.value) {
|
||||
setUserFormattedReleaseDate();
|
||||
}
|
||||
setFormattedRegExp();
|
||||
});
|
||||
|
||||
const modalWidth = computed(() => {
|
||||
|
||||
@@ -31,13 +31,9 @@ const {
|
||||
guid,
|
||||
keyfile,
|
||||
lanIp,
|
||||
state,
|
||||
connectPluginInstalled,
|
||||
} = storeToRefs(serverStore);
|
||||
const { bannerGradient, theme } = storeToRefs(useThemeStore());
|
||||
|
||||
const hideDropdown = computed(() => state.value === 'PRO' && !connectPluginInstalled.value);
|
||||
|
||||
/**
|
||||
* Close dropdown when clicking outside
|
||||
* @note If in testing you have two variants of the component on a page the clickOutside will fire twice making it seem like it doesn't work
|
||||
@@ -114,7 +110,7 @@ onBeforeMount(() => {
|
||||
<div class="relative z-10 flex flex-row items-center justify-end gap-x-16px h-full">
|
||||
<h1 class="text-14px sm:text-18px relative flex flex-col-reverse items-end md:flex-row border-0">
|
||||
<template v-if="description && theme?.descriptionShow">
|
||||
<span class="text-right text-12px sm:text-18px hidden 2xs:block">{{ description }}</span>
|
||||
<span class="text-right text-12px sm:text-18px hidden 2xs:block" v-html="description" />
|
||||
<span class="text-gamma hidden md:inline-block px-8px">•</span>
|
||||
</template>
|
||||
<button :title="t('Click to Copy LAN IP {0}', [lanIp])" class="opacity-100 hover:opacity-75 focus:opacity-75 transition-opacity" @click="copyLanIp()">
|
||||
@@ -129,14 +125,12 @@ onBeforeMount(() => {
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<template v-if="!hideDropdown">
|
||||
<div class="block w-2px h-24px bg-gamma" />
|
||||
<div class="block w-2px h-24px bg-gamma" />
|
||||
|
||||
<OnClickOutside class="flex items-center justify-end h-full" :options="{ ignore: [clickOutsideIgnoreTarget] }" @trigger="outsideDropdown">
|
||||
<UpcDropdownTrigger ref="clickOutsideIgnoreTarget" :t="t" />
|
||||
<UpcDropdown ref="clickOutsideTarget" :t="t" />
|
||||
</OnClickOutside>
|
||||
</template>
|
||||
<OnClickOutside class="flex items-center justify-end h-full" :options="{ ignore: [clickOutsideIgnoreTarget] }" @trigger="outsideDropdown">
|
||||
<UpcDropdownTrigger ref="clickOutsideIgnoreTarget" :t="t" />
|
||||
<UpcDropdown ref="clickOutsideTarget" :t="t" />
|
||||
</OnClickOutside>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -87,8 +87,8 @@ const updateOsToolsUpdatePageButton = computed(() => {
|
||||
href: WEBGUI_TOOLS_REGISTRATION.toString(),
|
||||
icon: KeyIcon,
|
||||
text: rebootType.value === 'downgrade'
|
||||
? props.t('Reboot Now to Downgrade to {0}', [rebootVersion])
|
||||
: props.t('Reboot Now to Update to {0}', [rebootVersion]),
|
||||
? props.t('Reboot Now to Downgrade to {0}', [rebootVersion.value])
|
||||
: props.t('Reboot Now to Update to {0}', [rebootVersion.value]),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -20,7 +20,10 @@ const showExpireTime = computed(() => (state.value === 'TRIAL' || state.value ==
|
||||
<div class="flex flex-col gap-y-24px w-full min-w-300px md:min-w-[500px] max-w-xl p-16px">
|
||||
<header>
|
||||
<h2 class="text-24px text-center font-semibold" v-html="t(stateData.heading)" />
|
||||
<div class="flex flex-col gap-y-8px" v-html="t(stateData.message)" />
|
||||
<div
|
||||
class="text-center prose text-16px leading-relaxed whitespace-normal opacity-75 gap-y-8px"
|
||||
v-html="t(stateData.message)"
|
||||
/>
|
||||
<UpcUptimeExpire
|
||||
v-if="showExpireTime"
|
||||
class="text-center opacity-75 mt-12px"
|
||||
|
||||
@@ -35,6 +35,8 @@ const title = computed((): string => {
|
||||
if (showErrorIcon.value) { return props.t('Learn more about the error'); }
|
||||
return dropdownVisible.value ? props.t('Close Dropdown') : props.t('Open Dropdown');
|
||||
});
|
||||
|
||||
// const hideAvatar = computed(() => state.value === 'PRO' && !connectPluginInstalled.value);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -33,6 +33,22 @@ const timeFormatOptions: TimeFormatOption[] = [
|
||||
];
|
||||
|
||||
/**
|
||||
* the provided ref may not have a value until we get a response from the refreshServerState action
|
||||
* So we need to watch for this value to be able to format it based on the user's date time preferences.
|
||||
* @example below is how to use this composable
|
||||
* const formattedRegExp = ref<any>();
|
||||
* const setFormattedRegExp = () => { // ran in watch on regExp and onBeforeMount
|
||||
* if (!regExp.value) { return; }
|
||||
* const { outputDateTimeFormatted } = useDateTimeHelper(dateTimeFormat.value, props.t, true, regExp.value);
|
||||
* formattedRegExp.value = outputDateTimeFormatted.value;
|
||||
* };
|
||||
* watch(regExp, (_newV) => {
|
||||
* setFormattedRegExp();
|
||||
* });
|
||||
* onBeforeMount(() => {
|
||||
* setFormattedRegExp();
|
||||
* });
|
||||
*
|
||||
* @param format provided by Unraid server's state.php and set in the server store
|
||||
* @param t translations
|
||||
* @param hideMinutesSeconds true will hide minutes and seconds from the output
|
||||
|
||||
@@ -242,6 +242,7 @@ export type Config = {
|
||||
};
|
||||
|
||||
export enum ConfigErrorState {
|
||||
Ineligible = 'INELIGIBLE',
|
||||
Invalid = 'INVALID',
|
||||
NoKeyServer = 'NO_KEY_SERVER',
|
||||
UnknownError = 'UNKNOWN_ERROR',
|
||||
|
||||
@@ -15,7 +15,7 @@ const useInstallPlugin = () => {
|
||||
console.debug('[installPlugin]', { installString, plgUrl });
|
||||
// @ts-ignore
|
||||
openPlugin(
|
||||
`plugin ${payload.update ? 'update' : 'install'} ${payload.pluginUrl}`, // command
|
||||
`plugin ${payload.update ? 'update' : 'install'} ${payload.pluginUrl}${payload.update ? '' : ' forced'}`, // command – `forced` is used to bypass the strcmp check in the plugin manager script being wrong for OS versions
|
||||
payload.modalTitle, // title
|
||||
installString, // plg
|
||||
'refresh', // function defined in DefaultPageLayout.php
|
||||
|
||||
@@ -21,16 +21,6 @@ export const WebguiInstallKey = request.url('/webGui/include/InstallKey.php');
|
||||
* @param {string} username
|
||||
*/
|
||||
export const WebguiUpdate = request.url('/update.php');
|
||||
/**
|
||||
* @name WebguiUpdateDns
|
||||
* @dataForm formUrl
|
||||
* @description Used after Sign In to ensure URLs will work correctly
|
||||
* @note this request is delayed by 500ms to allow server to process key install fully
|
||||
* @todo potentially remove delay
|
||||
* @param csrf_token
|
||||
* @type POST
|
||||
*/
|
||||
export const WebguiUpdateDns = request.url('/webGui/include/UpdateDNS.php');
|
||||
/**
|
||||
* @name WebguiState
|
||||
* @description used to get current state of server via PHP rather than unraid-api
|
||||
|
||||
174
web/package-lock.json
generated
174
web/package-lock.json
generated
@@ -91,18 +91,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@apollo/client": {
|
||||
"version": "3.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.8.7.tgz",
|
||||
"integrity": "sha512-DnQtFkQrCyxHTSa9gR84YRLmU/al6HeXcLZazVe+VxKBmx/Hj4rV8xWtzfWYX5ijartsqDR7SJgV037MATEecA==",
|
||||
"version": "3.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.9.5.tgz",
|
||||
"integrity": "sha512-7y+c8MTPU+hhTwvcGVtMMGIgWduzrvG1mz5yJMRyqYbheBkkky3Lki6ADWVSBXG1lZoOtPYvB2zDgVfKb2HSsw==",
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.1.1",
|
||||
"@wry/context": "^0.7.3",
|
||||
"@wry/caches": "^1.0.0",
|
||||
"@wry/equality": "^0.5.6",
|
||||
"@wry/trie": "^0.4.3",
|
||||
"@wry/trie": "^0.5.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"optimism": "^0.17.5",
|
||||
"optimism": "^0.18.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"rehackt": "0.0.5",
|
||||
"response-iterator": "^0.2.6",
|
||||
"symbol-observable": "^4.0.0",
|
||||
"ts-invariant": "^0.10.3",
|
||||
@@ -110,7 +111,7 @@
|
||||
"zen-observable-ts": "^1.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
||||
"graphql": "^15.0.0 || ^16.0.0",
|
||||
"graphql-ws": "^5.5.5",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
@@ -131,6 +132,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@apollo/client/node_modules/@wry/trie": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz",
|
||||
"integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@ardatan/relay-compiler": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz",
|
||||
@@ -1857,9 +1869,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz",
|
||||
"integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==",
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
|
||||
"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
@@ -1895,9 +1907,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.53.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz",
|
||||
"integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==",
|
||||
"version": "8.57.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
|
||||
"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -2931,21 +2943,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@heroicons/vue": {
|
||||
"version": "2.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-2.0.18.tgz",
|
||||
"integrity": "sha512-BcTC9nq2TkwNSfQuqo96J7ehx4etezypc2YeTq7KsXWxrcrerhkgjLrxGRBnStN0wrXo0Gv4BInybqz5uBG6Cw==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-2.1.1.tgz",
|
||||
"integrity": "sha512-Yi5nh/89L193ALgHyJUQUdNLsKXPrrE3yj5yiR8WAlo7nZyXGxGauQcEAmBsa2XJGMhBMuEdoOiuZ8wEwTBxVQ==",
|
||||
"peerDependencies": {
|
||||
"vue": ">= 3"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.13",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
||||
"integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^2.0.1",
|
||||
"debug": "^4.1.1",
|
||||
"@humanwhocodes/object-schema": "^2.0.2",
|
||||
"debug": "^4.3.1",
|
||||
"minimatch": "^3.0.5"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2966,18 +2978,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/object-schema": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
|
||||
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@intlify/core-base": {
|
||||
"version": "9.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.6.5.tgz",
|
||||
"integrity": "sha512-LzbGXiZkMWPIHnHI0g6q554S87Cmh2mmCmjytK/3pDQfjI84l+dgGoeQuKj02q7EbULRuUUgYVZVqAwEUawXGg==",
|
||||
"version": "9.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.10.1.tgz",
|
||||
"integrity": "sha512-0+Wtjj04GIyglh5KKiNjRwgjpHrhqqGZhaKY/QVjjogWKZq5WHROrTi84pNVsRN18QynyPmjtsVUWqFKPQ45xQ==",
|
||||
"dependencies": {
|
||||
"@intlify/message-compiler": "9.6.5",
|
||||
"@intlify/shared": "9.6.5"
|
||||
"@intlify/message-compiler": "9.10.1",
|
||||
"@intlify/shared": "9.10.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
@@ -2987,11 +2999,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/message-compiler": {
|
||||
"version": "9.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.6.5.tgz",
|
||||
"integrity": "sha512-WeJ499thIj0p7JaIO1V3JaJbqdqfBykS5R8fElFs5hNeotHtPAMBs4IiA+8/KGFkAbjJusgFefCq6ajP7F7+4Q==",
|
||||
"version": "9.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.10.1.tgz",
|
||||
"integrity": "sha512-b68UTmRhgZfswJZI7VAgW6BXZK5JOpoi5swMLGr4j6ss2XbFY13kiw+Hu+xYAfulMPSapcHzdWHnq21VGnMCnA==",
|
||||
"dependencies": {
|
||||
"@intlify/shared": "9.6.5",
|
||||
"@intlify/shared": "9.10.1",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3002,9 +3014,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/shared": {
|
||||
"version": "9.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.6.5.tgz",
|
||||
"integrity": "sha512-gD7Ey47Xi4h/t6P+S04ymMSoA3wVRxGqjxuIMglwRO8POki9h164Epu2N8wk/GHXM/hR6ZGcsx2HArCCENjqSQ==",
|
||||
"version": "9.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.10.1.tgz",
|
||||
"integrity": "sha512-liyH3UMoglHBUn70iCYcy9CQlInx/lp50W2aeSxqqrvmG+LDj/Jj7tBJhBoQL4fECkldGhbmW0g2ommHfL6Wmw==",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
@@ -6006,6 +6018,17 @@
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@wry/caches": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz",
|
||||
"integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@wry/context": {
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.3.tgz",
|
||||
@@ -8838,16 +8861,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.53.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz",
|
||||
"integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==",
|
||||
"version": "8.57.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
|
||||
"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.6.1",
|
||||
"@eslint/eslintrc": "^2.1.3",
|
||||
"@eslint/js": "8.53.0",
|
||||
"@humanwhocodes/config-array": "^0.11.13",
|
||||
"@eslint/eslintrc": "^2.1.4",
|
||||
"@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",
|
||||
@@ -9348,9 +9371,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/globals": {
|
||||
"version": "13.23.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
|
||||
"integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
|
||||
"version": "13.24.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.20.2"
|
||||
@@ -9732,9 +9755,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/focus-trap": {
|
||||
"version": "7.5.2",
|
||||
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz",
|
||||
"integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==",
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz",
|
||||
"integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==",
|
||||
"dependencies": {
|
||||
"tabbable": "^6.2.0"
|
||||
}
|
||||
@@ -10241,9 +10264,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/graphql-ws": {
|
||||
"version": "5.14.2",
|
||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.14.2.tgz",
|
||||
"integrity": "sha512-LycmCwhZ+Op2GlHz4BZDsUYHKRiiUz+3r9wbhBATMETNlORQJAaFlAgTFoeRh6xQoQegwYwIylVD1Qns9/DA3w==",
|
||||
"version": "5.15.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.15.0.tgz",
|
||||
"integrity": "sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw==",
|
||||
"workspaces": [
|
||||
"website"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -14794,10 +14820,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/optimism": {
|
||||
"version": "0.17.5",
|
||||
"resolved": "https://registry.npmjs.org/optimism/-/optimism-0.17.5.tgz",
|
||||
"integrity": "sha512-TEcp8ZwK1RczmvMnvktxHSF2tKgMWjJ71xEFGX5ApLh67VsMSTy1ZUlipJw8W+KaqgOmQ+4pqwkeivY89j+4Vw==",
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0.tgz",
|
||||
"integrity": "sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ==",
|
||||
"dependencies": {
|
||||
"@wry/caches": "^1.0.0",
|
||||
"@wry/context": "^0.7.0",
|
||||
"@wry/trie": "^0.4.3",
|
||||
"tslib": "^2.3.0"
|
||||
@@ -16629,6 +16656,23 @@
|
||||
"url": "https://github.com/sponsors/mysticatea"
|
||||
}
|
||||
},
|
||||
"node_modules/rehackt": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.0.5.tgz",
|
||||
"integrity": "sha512-BI1rV+miEkaHj8zd2n+gaMgzu/fKz7BGlb4zZ6HAiY9adDmJMkaDcmuXlJFv0eyKUob+oszs3/2gdnXUrzx2Tg==",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/relateurl": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
|
||||
@@ -18309,9 +18353,9 @@
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.24.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz",
|
||||
"integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==",
|
||||
"version": "5.28.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz",
|
||||
"integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
@@ -19622,12 +19666,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vue-i18n": {
|
||||
"version": "9.6.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.6.5.tgz",
|
||||
"integrity": "sha512-dpUEjKHg7pEsaS7ZPPxp1CflaR7bGmsvZJEhnszHPKl9OTNyno5j/DvMtMSo41kpddq4felLA7GK2prjpnXVlw==",
|
||||
"version": "9.10.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.10.1.tgz",
|
||||
"integrity": "sha512-37HVJQZ/pZaRXGzFmmMomM1u1k7kndv3xCBPYHKEVfv5W3UVK67U/TpBug71ILYLNmjHLHdvTUPRF81pFT5fFg==",
|
||||
"dependencies": {
|
||||
"@intlify/core-base": "9.6.5",
|
||||
"@intlify/shared": "9.6.5",
|
||||
"@intlify/core-base": "9.10.1",
|
||||
"@intlify/shared": "9.10.1",
|
||||
"@vue/devtools-api": "^6.5.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -20055,9 +20099,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/wretch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/wretch/-/wretch-2.7.0.tgz",
|
||||
"integrity": "sha512-IOjqi9SlQ8FEWp1X3KJ74wLNqpDVBoJIJvC7ZDHxPhzriNJd84+7RAhFBTl2sHiqnzBhzfqs1sznaB0Ik/3Ngw==",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/wretch/-/wretch-2.8.0.tgz",
|
||||
"integrity": "sha512-MNYh+lukFfFgcmVpvxv0KsQt2LtAPvKFfLNcLGpCMiHTD3ndSoQ3/k5fGOCPI1J7CgN1mYAbp9mhPFFUGTzUeg==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { defineStore, createPinia, setActivePinia } from 'pinia';
|
||||
import { delay } from 'wretch/middlewares';
|
||||
import { WebguiInstallKey, WebguiUpdateDns } from '~/composables/services/webgui';
|
||||
import { WebguiInstallKey } from '~/composables/services/webgui';
|
||||
import { useErrorsStore } from '~/store/errors';
|
||||
import { useServerStore } from '~/store/server';
|
||||
import type { ExternalKeyActions } from '~/store/callback';
|
||||
/**
|
||||
* @see https://stackoverflow.com/questions/73476371/using-pinia-with-vue-js-web-components
|
||||
@@ -12,7 +10,6 @@ setActivePinia(createPinia());
|
||||
|
||||
export const useInstallKeyStore = defineStore('installKey', () => {
|
||||
const errorsStore = useErrorsStore();
|
||||
const serverStore = useServerStore();
|
||||
|
||||
const keyInstallStatus = ref<'failed' | 'installing' | 'ready' | 'success'>('ready');
|
||||
|
||||
@@ -45,18 +42,6 @@ export const useInstallKeyStore = defineStore('installKey', () => {
|
||||
console.log('[install] WebguiInstallKey installResponse', installResponse);
|
||||
|
||||
keyInstallStatus.value = 'success';
|
||||
|
||||
try {
|
||||
const updateDnsResponse = await WebguiUpdateDns
|
||||
.middlewares([
|
||||
delay(1500)
|
||||
])
|
||||
.formUrl({ csrf_token: serverStore.csrf })
|
||||
.post();
|
||||
console.log('[install] WebguiUpdateDns updateDnsResponse', updateDnsResponse);
|
||||
} catch (error) {
|
||||
console.error('[install] WebguiUpdateDns error', error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[install] WebguiInstallKey error', error);
|
||||
let errorMessage = 'Unknown error';
|
||||
|
||||
@@ -5,6 +5,7 @@ import dayjs from 'dayjs';
|
||||
import { defineStore, createPinia, setActivePinia } from 'pinia';
|
||||
import prerelease from 'semver/functions/prerelease';
|
||||
import {
|
||||
ArrowPathIcon,
|
||||
ArrowRightOnRectangleIcon,
|
||||
CogIcon,
|
||||
GlobeAltIcon,
|
||||
@@ -17,7 +18,11 @@ import { useQuery } from '@vue/apollo-composable';
|
||||
import { SERVER_CLOUD_FRAGMENT, SERVER_STATE_QUERY } from './server.fragment';
|
||||
import { useFragment } from '~/composables/gql/fragment-masking';
|
||||
import { WebguiState, WebguiUpdateIgnore } from '~/composables/services/webgui';
|
||||
import { WEBGUI_SETTINGS_MANAGMENT_ACCESS } from '~/helpers/urls';
|
||||
import {
|
||||
WEBGUI_SETTINGS_MANAGMENT_ACCESS,
|
||||
WEBGUI_TOOLS_REGISTRATION,
|
||||
WEBGUI_TOOLS_UPDATE,
|
||||
} from '~/helpers/urls';
|
||||
import { useAccountStore } from '~/store/account';
|
||||
import { useErrorsStore, type Error } from '~/store/errors';
|
||||
import { usePurchaseStore } from '~/store/purchase';
|
||||
@@ -95,7 +100,27 @@ export const useServerStore = defineStore('server', () => {
|
||||
const rebootType = ref<'thirdPartyDriversDownloading' | 'downgrade' | 'update' | ''>('');
|
||||
const rebootVersion = ref<string | undefined>();
|
||||
const registered = ref<boolean>();
|
||||
const regDev = ref<number>(0);
|
||||
const regDevs = ref<number>(0); // use computedRegDevs to ensure it includes Basic, Plus, and Pro
|
||||
const computedRegDevs = computed(() => {
|
||||
if (regDevs.value > 0) {
|
||||
return regDevs.value;
|
||||
}
|
||||
|
||||
switch (regTy.value) {
|
||||
case 'Starter':
|
||||
case 'Basic':
|
||||
return 6;
|
||||
case 'Plus':
|
||||
return 12;
|
||||
case 'Unleashed':
|
||||
case 'Lifetime':
|
||||
case 'Pro':
|
||||
case 'Trial':
|
||||
return -1; // unlimited
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
const regGen = ref<number>(0);
|
||||
const regGuid = ref<string>('');
|
||||
const regTm = ref<number>(0);
|
||||
@@ -164,7 +189,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
osVersion: osVersion.value,
|
||||
osVersionBranch: osVersionBranch.value,
|
||||
registered: registered.value,
|
||||
regDev: regDev.value,
|
||||
regDevs: computedRegDevs.value,
|
||||
regGen: regGen.value,
|
||||
regGuid: regGuid.value,
|
||||
regExp: regExp.value,
|
||||
@@ -415,12 +440,12 @@ export const useServerStore = defineStore('server', () => {
|
||||
return {
|
||||
actions: [
|
||||
...(!registered.value && connectPluginInstalled.value ? [signInAction.value] : []),
|
||||
...([purchaseAction.value, redeemAction.value, trialStartAction.value, recoverAction.value]),
|
||||
...([trialStartAction.value, purchaseAction.value, redeemAction.value, recoverAction.value]),
|
||||
...(registered.value && connectPluginInstalled.value ? [signOutAction.value] : []),
|
||||
],
|
||||
humanReadable: 'No Keyfile',
|
||||
heading: 'Let\'s Unleash your Hardware!',
|
||||
message: '<p>Your server will not be usable until you purchase a Registration key or install a free 30 day <em>Trial</em> key. A <em>Trial</em> key provides all the functionality of a Pro Registration key.</p><p>Registration keys are bound to your USB Flash boot device serial number (GUID). Please use a high quality name brand device at least 1GB in size.</p><p>Note: USB memory card readers are generally not supported because most do not present unique serial numbers.</p><p><strong>Important:</strong></p><ul class=\'list-disc pl-16px\'><li>Please make sure your server time is accurate to within 5 minutes</li><li>Please make sure there is a DNS server specified</li></ul>',
|
||||
heading: 'Let\'s Unleash Your Hardware',
|
||||
message: '<p>Choose an option below, then use our <a href="https://unraid.net/getting-started" target="_blank" rel="noreffer noopener">Getting Started Guide</a> to configure your array in less than 15 minutes.</p>',
|
||||
};
|
||||
case 'TRIAL':
|
||||
return {
|
||||
@@ -487,6 +512,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
actions: [
|
||||
...(!registered.value && connectPluginInstalled.value ? [signInAction.value] : []),
|
||||
...(regUpdatesExpired.value ? [renewAction.value] : []),
|
||||
...(state.value === 'UNLEASHED' ? [upgradeAction.value] : []),
|
||||
...(registered.value && connectPluginInstalled.value ? [signOutAction.value] : []),
|
||||
],
|
||||
humanReadable: state.value === 'PRO'
|
||||
@@ -662,24 +688,73 @@ export const useServerStore = defineStore('server', () => {
|
||||
});
|
||||
const trialExtensionEligible = computed(() => !regGen.value || regGen.value < 2);
|
||||
|
||||
const tooManyDevices = computed((): Error | undefined => {
|
||||
if ((deviceCount.value !== 0 && regDev.value !== 0 && deviceCount.value > regDev.value) ||
|
||||
(!config.value?.valid && config.value?.error === 'INVALID')) {
|
||||
return {
|
||||
heading: 'Too Many Devices',
|
||||
level: 'error',
|
||||
message: 'You have exceeded the number of devices allowed for your license. Please remove a device before adding another.',
|
||||
ref: 'tooManyDevices',
|
||||
type: 'server',
|
||||
};
|
||||
const serverConfigError = computed((): Error | undefined => {
|
||||
if (!config.value?.valid && config.value?.error) {
|
||||
switch (config.value?.error) {
|
||||
// case 'UNKNOWN_ERROR':
|
||||
// return {
|
||||
// heading: 'Unknown Error',
|
||||
// level: 'error',
|
||||
// message: 'An unknown internal error occurred.',
|
||||
// ref: 'configError',
|
||||
// type: 'server',
|
||||
// };
|
||||
case 'INELIGIBLE':
|
||||
return {
|
||||
heading: 'Ineligible for OS Version',
|
||||
level: 'error',
|
||||
message: 'Your License Key does not support this OS Version. OS build date greater than key expiration.',
|
||||
actions: [{
|
||||
href: WEBGUI_TOOLS_REGISTRATION.toString(),
|
||||
icon: CogIcon,
|
||||
text: 'Learn More at Tools > Registration',
|
||||
}],
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
case 'INVALID':
|
||||
return {
|
||||
heading: 'Too Many Devices',
|
||||
level: 'error',
|
||||
message: 'You have exceeded the number of devices allowed for your license. Please remove a device before starting the array or upgrade your key to support more devices.',
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
case 'NO_KEY_SERVER':
|
||||
return {
|
||||
heading: 'Check Network Connection',
|
||||
level: 'error',
|
||||
message: 'Unable to validate your trial key. Please check your network connection.',
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
case 'WITHDRAWN':
|
||||
return {
|
||||
heading: 'OS Version Withdrawn',
|
||||
level: 'error',
|
||||
message: 'This OS release should not be run. OS Update Required.',
|
||||
actions: [{
|
||||
href: WEBGUI_TOOLS_UPDATE.toString(),
|
||||
icon: ArrowPathIcon,
|
||||
text: 'Check for Update',
|
||||
}],
|
||||
ref: 'configError',
|
||||
type: 'server',
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
watch(tooManyDevices, (newVal, oldVal) => {
|
||||
watch(serverConfigError, (newVal, oldVal) => {
|
||||
if (oldVal && oldVal.ref) { errorsStore.removeErrorByRef(oldVal.ref); }
|
||||
if (newVal) { errorsStore.setError(newVal); }
|
||||
});
|
||||
|
||||
const tooManyDevices = computed((): boolean => {
|
||||
return ((deviceCount.value !== 0 && computedRegDevs.value > 0 && deviceCount.value > computedRegDevs.value) ||
|
||||
(!config.value?.valid && config.value?.error === 'INVALID'));
|
||||
});
|
||||
|
||||
const pluginInstallFailed = computed((): Error | undefined => {
|
||||
if (connectPluginInstalled.value && connectPluginInstalled.value.includes('_installFailed')) {
|
||||
return {
|
||||
@@ -776,7 +851,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
const serverErrors = computed(() => {
|
||||
return [
|
||||
stateDataError.value,
|
||||
tooManyDevices.value,
|
||||
serverConfigError.value,
|
||||
pluginInstallFailed.value,
|
||||
deprecatedUnraidSSL.value,
|
||||
cloudError.value,
|
||||
@@ -1022,7 +1097,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
rebootType,
|
||||
rebootVersion,
|
||||
registered,
|
||||
regDev,
|
||||
computedRegDevs,
|
||||
regGen,
|
||||
regGuid,
|
||||
regTm,
|
||||
@@ -1056,6 +1131,7 @@ export const useServerStore = defineStore('server', () => {
|
||||
stateDataError,
|
||||
serverErrors,
|
||||
tooManyDevices,
|
||||
serverConfigError,
|
||||
// actions
|
||||
setServer,
|
||||
setUpdateOsResponse,
|
||||
|
||||
@@ -91,7 +91,7 @@ export interface Server {
|
||||
rebootType?: ServerRebootType;
|
||||
rebootVersion?: string;
|
||||
registered?: boolean;
|
||||
regDev?: number;
|
||||
regDevs?: number;
|
||||
regGen?: number;
|
||||
regGuid?: string;
|
||||
regTm?: number;
|
||||
|
||||
Reference in New Issue
Block a user