Compare commits
12 Commits
d8eddafcae
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| c35726bf5c | |||
| e82208fc5e | |||
| 9bdca3317c | |||
| 61abd44328 | |||
| acb9876d9b | |||
| 10d88f53eb | |||
| bba0aa2ee4 | |||
| b7773ec02a | |||
| b9dd6e3ae2 | |||
| f940bcdc9d | |||
| 2ae3c8ba59 | |||
| 97b9c4db4a |
@@ -1,16 +1,17 @@
|
||||
{
|
||||
"types": [
|
||||
{"type": "feat", "section": "🌟 Enhancements"},
|
||||
{"type": "fix", "section": "🐛 Bug fixes"},
|
||||
{"type": "chore", "hidden": false, "section": "📝 Chore"},
|
||||
{"type": "docs", "section": "📚 Documentation"},
|
||||
{"type": "style", "hidden": true},
|
||||
{"type": "refactor", "section": "🛠️ Code Refactor"},
|
||||
{"type": "perf", "hidden": false, "section": "🚀 Performance"},
|
||||
{"type": "test", "section": "📝 Testing Code"},
|
||||
{"type": "ci", "section": "📈 Project changes"}
|
||||
],
|
||||
"commitUrlFormat": "https://git.tuffraid.net/cowch/lstV2/commits/{{hash}}",
|
||||
"compareUrlFormat": "https://git.tuffraid.net/cowch/lstV2/compare/{{previousTag}}...{{currentTag}}",
|
||||
"header": "# All CHanges to LST can be found below.\n"
|
||||
"types": [
|
||||
{ "type": "feat", "section": "🌟 Enhancements" },
|
||||
{ "type": "fix", "section": "🐛 Bug fixes" },
|
||||
{ "type": "chore", "hidden": false, "section": "📝 Chore" },
|
||||
{ "type": "docs", "section": "📚 Documentation" },
|
||||
{ "type": "style", "hidden": true },
|
||||
{ "type": "refactor", "section": "🛠️ Code Refactor" },
|
||||
{ "type": "perf", "hidden": false, "section": "🚀 Performance" },
|
||||
{ "type": "test", "section": "📝 Testing Code" },
|
||||
{ "type": "ci", "hidden": false, "section": "📈 Project changes" },
|
||||
{ "type": "build", "hidden": true, "section": "📈 Project Builds" }
|
||||
],
|
||||
"commitUrlFormat": "https://git.tuffraid.net/cowch/lstV2/commits/{{hash}}",
|
||||
"compareUrlFormat": "https://git.tuffraid.net/cowch/lstV2/compare/{{previousTag}}...{{currentTag}}",
|
||||
"header": "# All CHanges to LST can be found below.\n"
|
||||
}
|
||||
|
||||
125
CHANGELOG.md
125
CHANGELOG.md
@@ -1,5 +1,130 @@
|
||||
# All CHanges to LST can be found below.
|
||||
|
||||
## [2.9.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.8.0...v2.9.0) (2025-03-23)
|
||||
|
||||
|
||||
### 📈 Project changes
|
||||
|
||||
* **frontend:** added ocme as a proxy in the dev ([eb2c34c](https://git.tuffraid.net/cowch/lstV2/commits/eb2c34c557b72c3387b70addac30a4d8291402d4))
|
||||
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
* **install:** added more env params and an install install stuff ([09d3a70](https://git.tuffraid.net/cowch/lstV2/commits/09d3a7041a18283a5add86ea845a8d7249522769))
|
||||
* **install:** removed the super secret key ([357c118](https://git.tuffraid.net/cowch/lstV2/commits/357c1183964be0f3c02207c24bc8f83347282211))
|
||||
* **logs:** changes how logs are put into the db they will be there name vs key ([18daca9](https://git.tuffraid.net/cowch/lstV2/commits/18daca904e0305371c6128988b48d54e3aec9a2a))
|
||||
* **migration:** added more documents on the install md ([0bd217c](https://git.tuffraid.net/cowch/lstV2/commits/0bd217c727d726d62ddf06a0e44e95c4606361cf))
|
||||
|
||||
|
||||
### 📝 Testing Code
|
||||
|
||||
* **ocme:** cycle count intital improvements ([7a22b52](https://git.tuffraid.net/cowch/lstV2/commits/7a22b52c916335c748598b82e78819c325bb8c4c))
|
||||
* **ocp dash:** more work on the dashboard ([f3c4c26](https://git.tuffraid.net/cowch/lstV2/commits/f3c4c26ef957e6fe359a77f139ad36cdacefb8ef))
|
||||
* **ocp:** more work on the dashboard ([8324fff](https://git.tuffraid.net/cowch/lstV2/commits/8324fffeb664bff3751ffc26e988a4a506b658a9))
|
||||
* **returnres:** tryed to make a standard return res but will come back to this later ([58b5842](https://git.tuffraid.net/cowch/lstV2/commits/58b58424abbf98feec0c5442a59f4d055bbd1811))
|
||||
* **rfid:** more work on the rfid service ([21c3749](https://git.tuffraid.net/cowch/lstV2/commits/21c374903b5cba56ced44b7eb2066ee902fc7bc3))
|
||||
* **server:** start/stop/restart buttons added. comment [#14](https://git.tuffraid.net/cowch/lstV2/issues/14) ([76bc0db](https://git.tuffraid.net/cowch/lstV2/commits/76bc0db3dd9c48b69e4f6f571181a1f07c48bdeb))
|
||||
* **streaming logs:** more test but failed again ([08c9b34](https://git.tuffraid.net/cowch/lstV2/commits/08c9b3404f548a167464445ec2f19288a092b0dc))
|
||||
* **streaming logs:** test for streaming logs ([73eb705](https://git.tuffraid.net/cowch/lstV2/commits/73eb70538e36601cf436aaba244f99d5bd873d34))
|
||||
* **streaming logs:** will come back to this later this is killing me inside ([97eb73c](https://git.tuffraid.net/cowch/lstV2/commits/97eb73c6d1aef747ef98f5f666fe47622795746f))
|
||||
* **streaming:** more streaming test ([4db4eea](https://git.tuffraid.net/cowch/lstV2/commits/4db4eea2d12e37809879e96ed4279d6e23e83acc))
|
||||
* **streaming:** more testing on streaming the lofs ([e82ef76](https://git.tuffraid.net/cowch/lstV2/commits/e82ef76316f0562b57124eb977c86fd2c6a3f332))
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **admincheck:** this check is so we dont use stuff on the wrong servers ([3d08398](https://git.tuffraid.net/cowch/lstV2/commits/3d083986aed528c2f881d6f673c0be03b8986c0b))
|
||||
* **auth:** add, update were added for adm account in backend only ([d8eddaf](https://git.tuffraid.net/cowch/lstV2/commits/d8eddafcaea9141e9413a122a320649c7dd325e5))
|
||||
* **auth:** remove all old localstorage if no session ([8fb06c7](https://git.tuffraid.net/cowch/lstV2/commits/8fb06c71d370a27697628077474a261596b567e0))
|
||||
* **db:** logs, manualprints added ([0914b53](https://git.tuffraid.net/cowch/lstV2/commits/0914b5334119fa705eedddc6c9e8303cb82da551))
|
||||
* **installer:** added a check for lstv2 already installed ([4696835](https://git.tuffraid.net/cowch/lstV2/commits/4696835c6557c2eae3be6a292144493be9d98f67))
|
||||
* **logger:** logger service created with its endpoints ([7ec5c5b](https://git.tuffraid.net/cowch/lstV2/commits/7ec5c5beb0a9b02e8b8761908ee75ac2cfd317ee))
|
||||
* **logger:** streaming logs works server side not frontend for now ([e833c48](https://git.tuffraid.net/cowch/lstV2/commits/e833c48cc8f68af40888ea161100e02f6ad19604))
|
||||
* **lst:** added in delay global function ([7497432](https://git.tuffraid.net/cowch/lstV2/commits/74974323f0a7bd7c2eaa22024b7a8e91db2868e2))
|
||||
* **lst:** added prettier config so we have the same formatting across all computers ([132e8d0](https://git.tuffraid.net/cowch/lstV2/commits/132e8d0146318fa9deb673bbcabf0d80c2a6d39f))
|
||||
* **ocme:** added in ocme service so we can utlize 2 ports ([ae7e3fd](https://git.tuffraid.net/cowch/lstV2/commits/ae7e3fd54e5c256fb82e68f2e935e3b914e43d13))
|
||||
* **ocme:** cycle count implemeneted ([74bcd6e](https://git.tuffraid.net/cowch/lstV2/commits/74bcd6e805c34e181f0c48310a799daf3afaee66))
|
||||
* **ocmeserver:** the server was just migrated so it can be upgraded to lstv2 ([e258aae](https://git.tuffraid.net/cowch/lstV2/commits/e258aaead9a56cc4de36c17ed60b0bdaa91019cb))
|
||||
* **ocp:** added in service plus manual print log ([7165c95](https://git.tuffraid.net/cowch/lstV2/commits/7165c959b9d5b37c0d4b01cb3f5bc27b40cec71d))
|
||||
* **ports:** added in production port if in production ([121bed5](https://git.tuffraid.net/cowch/lstV2/commits/121bed59fda04b2ad134feb0895428515a1c56d8))
|
||||
* **scripts:** made moving scripts more proper ([d0a0d08](https://git.tuffraid.net/cowch/lstV2/commits/d0a0d0890255acf890ba402386847b19566c92df))
|
||||
* **serverdata:** added in huston, sherman. and corrected contact info in westbend ([4908d66](https://git.tuffraid.net/cowch/lstV2/commits/4908d6644a392395e660d382536c0fd31e3d0647))
|
||||
* **server:** ocpService and loggerService added ([2d3f308](https://git.tuffraid.net/cowch/lstV2/commits/2d3f30887744bddfe22dc764188cf727a5e476df))
|
||||
* **servers:** added dayton in ([bbd7a17](https://git.tuffraid.net/cowch/lstV2/commits/bbd7a17144e1e1a0faa192139cb1539c2f1ecc5c))
|
||||
* **settings:** added in setting store ([1cd1d3a](https://git.tuffraid.net/cowch/lstV2/commits/1cd1d3a3e9e1ec1bf16ac2552caf24aa299959bf))
|
||||
* **settings:** more seed settings ([e597968](https://git.tuffraid.net/cowch/lstV2/commits/e597968777e88289d361fdc01ec683a1f4c80192))
|
||||
* **trycatch:** added in theo's try catch to reduce the code and love it ([72d52d9](https://git.tuffraid.net/cowch/lstV2/commits/72d52d925677eeeac6d158028114201862b6e2a2))
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **auth:** added in correct bycrptjs ([208cd61](https://git.tuffraid.net/cowch/lstV2/commits/208cd615af8250686745aa5b6779706ae267e423))
|
||||
* **auth:** moved prod back to server as we run 2 instances during migration ([7a15b16](https://git.tuffraid.net/cowch/lstV2/commits/7a15b160ac2393cd66a932e598ffaa5aeda5812f))
|
||||
* **consume materail:** get token from localstorage as the store isnt wokring properly ([354f326](https://git.tuffraid.net/cowch/lstV2/commits/354f3260a55b53bfb461a37db9d64550bacbfe04))
|
||||
* **frontend:** added date-fns into the frontend ([bba0aa2](https://git.tuffraid.net/cowch/lstV2/commits/bba0aa2ee4e9b9be1db184da894ce6e96fd2e38f))
|
||||
* **login:** removed all the data from teh login dropdown as it could cause issues ([5dfece0](https://git.tuffraid.net/cowch/lstV2/commits/5dfece09b7285dda96875bbc740df803d816b92a))
|
||||
* **login:** removed roles from the login to shrink the jwt ([c9aa41a](https://git.tuffraid.net/cowch/lstV2/commits/c9aa41ab0099b7a05d50d9a981cf7e8a42a04733))
|
||||
* **production:** changes ocp to viewwer ([ab5af4d](https://git.tuffraid.net/cowch/lstV2/commits/ab5af4deacbeaf1ed93c6231fb98b187f7540ca4))
|
||||
* **server query:** bumped the refresh from 500ms to 2500ms ([866b6d5](https://git.tuffraid.net/cowch/lstV2/commits/866b6d5120810252b089580d341f3fb1b62e951a))
|
||||
* **serverdata:** remapped the server list to all be on the E drive and deactivated ([8b8c9ac](https://git.tuffraid.net/cowch/lstV2/commits/8b8c9acb6969b63f157ea95b7d61923bf4bb4eae))
|
||||
* **server:** removed the websocket wrapper going wiht normal ws ([bb6d523](https://git.tuffraid.net/cowch/lstV2/commits/bb6d523abbd3c9423eddbaab96e297b4850e2aa8))
|
||||
* **settings:** refactored the admincheck so we can reuse it ([ca0ba7f](https://git.tuffraid.net/cowch/lstV2/commits/ca0ba7fe59f7e19d0de4924a419cce461de4b7a1))
|
||||
* **settings:** removed the need to login to get the settings ([5945ace](https://git.tuffraid.net/cowch/lstV2/commits/5945ace9f259f6ef418c1621c246982b5b572dc1))
|
||||
* **settings:** used the common response function created ([316b27e](https://git.tuffraid.net/cowch/lstV2/commits/316b27e3e011a0c0b4ce88ea579290807b8927c5))
|
||||
* **stores:** added in axios ([3b8f180](https://git.tuffraid.net/cowch/lstV2/commits/3b8f18093ead2a988b2b19d1e8f25db6eaeaaee8))
|
||||
* **view access:** if role [] then allow them to see it ([e17b8e7](https://git.tuffraid.net/cowch/lstV2/commits/e17b8e7bbe94c25c1bd3414b1db31191c87553d6))
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **auth:** added in the correct function for days between logins ([ed11b2b](https://git.tuffraid.net/cowch/lstV2/commits/ed11b2b26ff80fde9f94615f740eb5152b16744d))
|
||||
* **auth:** fixed the getaccess to be getuseraccess as it was orignally ([b9dd6e3](https://git.tuffraid.net/cowch/lstV2/commits/b9dd6e3ae2f5c158dd4827ae0c9db2c6747c57e1))
|
||||
* **calendar:** this component had a bug and needed a lib update ([93ed2e9](https://git.tuffraid.net/cowch/lstV2/commits/93ed2e9ee8c98edd6a8c47d6e7a0caf6a8e93278))
|
||||
* **consume material:** when we consumed material the button was never reenabled ([07e47e6](https://git.tuffraid.net/cowch/lstV2/commits/07e47e64ae2f4ddd325a2fdb34c82143c9adf84b)), closes [#15](https://git.tuffraid.net/cowch/lstV2/issues/15)
|
||||
* **frontend:** removed unwanted import ([10d88f5](https://git.tuffraid.net/cowch/lstV2/commits/10d88f53ebaf670c9f6b3ca59cbbaf4d88f26b9f))
|
||||
* **loginform:** removed the console log that was left by accident ([2ae3c8b](https://git.tuffraid.net/cowch/lstV2/commits/2ae3c8ba5916b5249135b86b374ac1bf32837478))
|
||||
* **login:** if we have a wrong password or username we didnt properly error instead we crashed ([2e5de34](https://git.tuffraid.net/cowch/lstV2/commits/2e5de34cb50c79cd60e038492b2397eee69def11))
|
||||
* **scaler:** fix due to update ([edcfff6](https://git.tuffraid.net/cowch/lstV2/commits/edcfff6cc6cf81e56b5532f0876383659b951a5d))
|
||||
* **serverlist:** corrected the time by removing teh Z at the end of the time ([f940bcd](https://git.tuffraid.net/cowch/lstV2/commits/f940bcdc9df2d3e9989d49feae88036a6f8c7013))
|
||||
* **sqlserver:** if we already have a connection just return we dont want to try a second time ([b7773ec](https://git.tuffraid.net/cowch/lstV2/commits/b7773ec02aa26c01530723dc146e0c9f4dae41d3))
|
||||
|
||||
|
||||
### 📝 Chore
|
||||
|
||||
* **builds:** bummped lstv1 build ([739e6bb](https://git.tuffraid.net/cowch/lstV2/commits/739e6bbe9fa48fae682f9931a2c8bcb763feb636))
|
||||
* bump build number to 20 ([0975f4e](https://git.tuffraid.net/cowch/lstV2/commits/0975f4e499a8a2aec0662352cb4496299292d4ea))
|
||||
* bump build number to 21 ([4e885ce](https://git.tuffraid.net/cowch/lstV2/commits/4e885ce74c02ee1fd95a93402d1d32ecf357b1cb))
|
||||
* bump build number to 22 ([43ca16d](https://git.tuffraid.net/cowch/lstV2/commits/43ca16dc807b9fa3496498e90a871568f0e5f54c))
|
||||
* bump build number to 23 ([bff0e77](https://git.tuffraid.net/cowch/lstV2/commits/bff0e77766b49c72d77fa55cfaab2d347a1a75dc))
|
||||
* bump build number to 24 ([f4433f4](https://git.tuffraid.net/cowch/lstV2/commits/f4433f41926dab72a239fc585ddd1e14acb80c7e))
|
||||
* bump build number to 25 ([f1979f0](https://git.tuffraid.net/cowch/lstV2/commits/f1979f0fc914f3b94bad1816cd405a6431d1ba4a))
|
||||
* bump build number to 26 ([491de26](https://git.tuffraid.net/cowch/lstV2/commits/491de26a0bbe6dfca9e1cb068991789c29a09ac0))
|
||||
* bump build number to 27 ([26ea8d5](https://git.tuffraid.net/cowch/lstV2/commits/26ea8d5e89bb1b44ceb6b205da3ad158c603fca0))
|
||||
* bump build number to 28 ([1e02d4f](https://git.tuffraid.net/cowch/lstV2/commits/1e02d4fa4fc1a007634da49fe2697d63c89cba18))
|
||||
* bump build number to 29 ([9796947](https://git.tuffraid.net/cowch/lstV2/commits/9796947db5443c8b5678d7502037458d680e4018))
|
||||
* bump build number to 30 ([4a48dd2](https://git.tuffraid.net/cowch/lstV2/commits/4a48dd2bb57064953ef6e192c76b91bb844a24de))
|
||||
* bump build number to 31 ([227e2aa](https://git.tuffraid.net/cowch/lstV2/commits/227e2aa00c2a3e5526e0347c76676de345dfea5d))
|
||||
* bump build number to 32 ([f035e6f](https://git.tuffraid.net/cowch/lstV2/commits/f035e6f14a9e2123a10010d4f515f78f0c222599))
|
||||
* bump build number to 33 ([03aa7e5](https://git.tuffraid.net/cowch/lstV2/commits/03aa7e5aeee39b1b390b4da2019f44459487e0a0))
|
||||
* bump build number to 34 ([f4c44fb](https://git.tuffraid.net/cowch/lstV2/commits/f4c44fb02ba857890af66a2747381ef1c3def25b))
|
||||
* bump build number to 35 ([8b72a1b](https://git.tuffraid.net/cowch/lstV2/commits/8b72a1b47e715f4146e586e9fdd6abcabd97743d))
|
||||
* bump build number to 36 ([8a143fb](https://git.tuffraid.net/cowch/lstV2/commits/8a143fbb19d2270b0139a7a4edbce745c477b6b1))
|
||||
* bump build number to 37 ([b0634d9](https://git.tuffraid.net/cowch/lstV2/commits/b0634d9427f6fff3a239680204b5e6daf6163e37))
|
||||
* bump build number to 38 ([751b9d5](https://git.tuffraid.net/cowch/lstV2/commits/751b9d5701cf7e81641f154a02041869e1b80c49))
|
||||
* bump build number to 39 ([6dd5f4b](https://git.tuffraid.net/cowch/lstV2/commits/6dd5f4b61f3a27779980cf14915c4394256eae20))
|
||||
* bump build number to 40 ([d98a659](https://git.tuffraid.net/cowch/lstV2/commits/d98a6592628f36c654039ccea25db163ddf15e8c))
|
||||
* bump build number to 41 ([807a4ca](https://git.tuffraid.net/cowch/lstV2/commits/807a4ca6993b5dfa82a45aaf44a2d661c3e03428))
|
||||
* bump build number to 42 ([196ea00](https://git.tuffraid.net/cowch/lstV2/commits/196ea009720a65c520f5626658ac7885a41796cb))
|
||||
* bump build number to 43 ([34b80cf](https://git.tuffraid.net/cowch/lstV2/commits/34b80cf2368228b70cd6a79d44ba0f95b5c5941a))
|
||||
* bump build number to 44 ([808e3d8](https://git.tuffraid.net/cowch/lstV2/commits/808e3d84efa0889077a12cbf8e28df794a51f2bc))
|
||||
* bump build number to 45 ([38d1043](https://git.tuffraid.net/cowch/lstV2/commits/38d10436069d3db1612a622d9b9e0c7aec04f6dd))
|
||||
* bump build number to 46 ([532a722](https://git.tuffraid.net/cowch/lstV2/commits/532a7227631cf67664ca41133330d8cfa59f429b))
|
||||
* bump build number to 47 ([f665406](https://git.tuffraid.net/cowch/lstV2/commits/f6654067f5f01c3ee4855f0cbe07593f13263ce7))
|
||||
* bump build number to 48 ([97b9c4d](https://git.tuffraid.net/cowch/lstV2/commits/97b9c4db4a67faf68edae4dc1217b28f87d003e8))
|
||||
* bump build number to 49 ([acb9876](https://git.tuffraid.net/cowch/lstV2/commits/acb9876d9b715894481d31d9bb104e54561710d0))
|
||||
* **pkg updates:** updated all pkgs ([fb9ee15](https://git.tuffraid.net/cowch/lstV2/commits/fb9ee15bda89257815012023ed5543ef55b5f379))
|
||||
* **updatescript:** added in so we can do a full install with an env creation for old ([cb3ab66](https://git.tuffraid.net/cowch/lstV2/commits/cb3ab668d866ea9e3428e548d9065a9681174e82))
|
||||
|
||||
## [2.8.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.7.0...v2.8.0) (2025-03-16)
|
||||
|
||||
|
||||
|
||||
10
frontend/package-lock.json
generated
10
frontend/package-lock.json
generated
@@ -28,6 +28,7 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"date-fns-tz": "^3.2.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"hono": "^4.7.5",
|
||||
"js-cookie": "^3.0.5",
|
||||
@@ -3775,6 +3776,15 @@
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns-tz": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-3.2.0.tgz",
|
||||
"integrity": "sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"date-fns": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"date-fns-tz": "^3.2.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"hono": "^4.7.5",
|
||||
"js-cookie": "^3.0.5",
|
||||
|
||||
@@ -1,108 +1,125 @@
|
||||
import {LstCard} from "@/components/extendedUI/LstCard";
|
||||
|
||||
import {Skeleton} from "@/components/ui/skeleton";
|
||||
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
|
||||
import {useSessionStore} from "@/lib/store/sessionStore";
|
||||
import {useModuleStore} from "@/lib/store/useModuleStore";
|
||||
import {getServers} from "@/utils/querys/servers";
|
||||
import {useQuery} from "@tanstack/react-query";
|
||||
import {useRouter} from "@tanstack/react-router";
|
||||
import {format} from "date-fns";
|
||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { useSessionStore } from "@/lib/store/sessionStore";
|
||||
import { useModuleStore } from "@/lib/store/useModuleStore";
|
||||
import { getServers } from "@/utils/querys/servers";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useRouter } from "@tanstack/react-router";
|
||||
import { format } from "date-fns";
|
||||
import UpdateServer from "./UpdateServer";
|
||||
import {adminUrlCheck} from "@/utils/adminUrlCheck";
|
||||
import { adminUrlCheck } from "@/utils/adminUrlCheck";
|
||||
import RestartServer from "./RestartServer";
|
||||
import StopServer from "./StopServer";
|
||||
import StartServer from "./StartServer";
|
||||
|
||||
export type Servers = {
|
||||
server_id?: string;
|
||||
sName?: string;
|
||||
serverDNS?: string;
|
||||
plantToken?: string;
|
||||
idAddress: string;
|
||||
lastUpdated: string;
|
||||
isUpgrading: boolean;
|
||||
server_id?: string;
|
||||
sName?: string;
|
||||
serverDNS?: string;
|
||||
plantToken?: string;
|
||||
idAddress: string;
|
||||
lastUpdated: string;
|
||||
isUpgrading: boolean;
|
||||
};
|
||||
|
||||
export default function ServerPage() {
|
||||
const {user, token} = useSessionStore();
|
||||
const {modules} = useModuleStore();
|
||||
const router = useRouter();
|
||||
const { user, token } = useSessionStore();
|
||||
const { modules } = useModuleStore();
|
||||
const router = useRouter();
|
||||
|
||||
const {data, isError, error, isLoading} = useQuery(getServers(token ?? ""));
|
||||
const { data, isError, error, isLoading } = useQuery(getServers(token ?? ""));
|
||||
|
||||
const adminModule = modules.filter((n) => n.name === "admin");
|
||||
const userLevel = user?.roles?.filter((r) => r.module_id === adminModule[0].module_id) || [];
|
||||
const adminModule = modules.filter((n) => n.name === "admin");
|
||||
const userLevel =
|
||||
user?.roles?.filter((r) => r.module_id === adminModule[0].module_id) || [];
|
||||
|
||||
if (!adminModule[0]?.roles?.includes(userLevel[0]?.role)) {
|
||||
router.navigate({to: "/"});
|
||||
}
|
||||
if (!adminModule[0]?.roles?.includes(userLevel[0]?.role)) {
|
||||
router.navigate({ to: "/" });
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
return <div>{JSON.stringify(error)}</div>;
|
||||
}
|
||||
return (
|
||||
<LstCard className="m-2 flex place-content-center w-dvh">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Server</TableHead>
|
||||
<TableHead>PlantToken</TableHead>
|
||||
<TableHead>IP Address</TableHead>
|
||||
<TableHead>Date Last updated</TableHead>
|
||||
<TableHead>Update Server</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</>
|
||||
) : (
|
||||
<TableBody>
|
||||
{data?.map((server: Servers) => (
|
||||
<TableRow key={server.server_id}>
|
||||
<TableCell className="font-medium">{server.sName}</TableCell>
|
||||
<TableCell className="font-medium">{server.serverDNS}</TableCell>
|
||||
<TableCell className="font-medium">{server.plantToken}</TableCell>
|
||||
<TableCell className="font-medium">{server.idAddress}</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{format(server.lastUpdated, "MM/dd/yyyy hh:mm")}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{adminUrlCheck() && (
|
||||
<div className="flex flex-row">
|
||||
<UpdateServer server={server} token={token as string} />
|
||||
<StartServer />
|
||||
<StopServer />
|
||||
<RestartServer />
|
||||
</div>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
</LstCard>
|
||||
);
|
||||
if (isError) {
|
||||
return <div>{JSON.stringify(error)}</div>;
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
return (
|
||||
<LstCard className="m-2 flex place-content-center w-dvh">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Server</TableHead>
|
||||
<TableHead>PlantToken</TableHead>
|
||||
<TableHead>IP Address</TableHead>
|
||||
<TableHead>Date Last updated</TableHead>
|
||||
<TableHead>Update Server</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</>
|
||||
) : (
|
||||
<TableBody>
|
||||
{data?.map((server: Servers) => {
|
||||
const strippedDate = server.lastUpdated.replace("Z", ""); // Remove Z
|
||||
const formattedDate = format(strippedDate, "MM/dd/yyyy hh:mm a");
|
||||
return (
|
||||
<TableRow key={server.server_id}>
|
||||
<TableCell className="font-medium">{server.sName}</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{server.serverDNS}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{server.plantToken}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{server.idAddress}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">{formattedDate}</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{adminUrlCheck() && (
|
||||
<div className="flex flex-row">
|
||||
<UpdateServer server={server} token={token as string} />
|
||||
<StartServer />
|
||||
<StopServer />
|
||||
<RestartServer />
|
||||
</div>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
</LstCard>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,153 +1,164 @@
|
||||
import {useSessionStore} from "../../lib/store/sessionStore";
|
||||
import {LstCard} from "../extendedUI/LstCard";
|
||||
import {CardHeader} from "../ui/card";
|
||||
import {toast} from "sonner";
|
||||
import {z} from "zod";
|
||||
import {useRouter} from "@tanstack/react-router";
|
||||
import {Controller, useForm} from "react-hook-form";
|
||||
import {zodResolver} from "@hookform/resolvers/zod";
|
||||
import {Label} from "../ui/label";
|
||||
import {Input} from "../ui/input";
|
||||
import {Checkbox} from "../ui/checkbox";
|
||||
import {Button} from "../ui/button";
|
||||
import { useSessionStore } from "../../lib/store/sessionStore";
|
||||
import { LstCard } from "../extendedUI/LstCard";
|
||||
import { CardHeader } from "../ui/card";
|
||||
import { toast } from "sonner";
|
||||
import { z } from "zod";
|
||||
import { useRouter } from "@tanstack/react-router";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Label } from "../ui/label";
|
||||
import { Input } from "../ui/input";
|
||||
import { Checkbox } from "../ui/checkbox";
|
||||
import { Button } from "../ui/button";
|
||||
|
||||
const FormSchema = z.object({
|
||||
username: z.string().min(1, "You must enter a valid username"),
|
||||
password: z.string().min(4, "You must enter a valid password"),
|
||||
rememberMe: z.boolean(),
|
||||
username: z.string().min(1, "You must enter a valid username"),
|
||||
password: z.string().min(4, "You must enter a valid password"),
|
||||
rememberMe: z.boolean(),
|
||||
});
|
||||
|
||||
const LoginForm = () => {
|
||||
const {setSession} = useSessionStore();
|
||||
const rememeberMe = localStorage.getItem("rememberMe") === "true";
|
||||
const username = localStorage.getItem("username") || "";
|
||||
const router = useRouter();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: {errors},
|
||||
} = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
username: username || "",
|
||||
password: "",
|
||||
rememberMe: rememeberMe,
|
||||
const { setSession } = useSessionStore();
|
||||
const rememeberMe = localStorage.getItem("rememberMe") === "true";
|
||||
const username = localStorage.getItem("username") || "";
|
||||
const router = useRouter();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
username: username || "",
|
||||
password: "",
|
||||
rememberMe: rememeberMe,
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmitLogin = async (value: z.infer<typeof FormSchema>) => {
|
||||
// Do something with form data
|
||||
|
||||
// first update the rememberMe incase it was selected
|
||||
if (value.rememberMe) {
|
||||
localStorage.setItem("rememberMe", value.rememberMe.toString());
|
||||
localStorage.setItem("username", value.username);
|
||||
} else {
|
||||
localStorage.removeItem("rememberMe");
|
||||
localStorage.removeItem("username");
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/auth/login", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
body: JSON.stringify({
|
||||
username: value.username,
|
||||
password: value.password,
|
||||
}),
|
||||
});
|
||||
|
||||
const onSubmitLogin = async (value: z.infer<typeof FormSchema>) => {
|
||||
// Do something with form data
|
||||
const data = await response.json();
|
||||
|
||||
// first update the rememberMe incase it was selected
|
||||
if (value.rememberMe) {
|
||||
localStorage.setItem("rememberMe", value.rememberMe.toString());
|
||||
localStorage.setItem("username", value.username);
|
||||
} else {
|
||||
localStorage.removeItem("rememberMe");
|
||||
localStorage.removeItem("username");
|
||||
}
|
||||
// Store token in localStorage
|
||||
// localStorage.setItem("auth_token", data.data.token);
|
||||
if (data.success) {
|
||||
const prod = btoa(`${value.username.toLowerCase()}:${value.password}`);
|
||||
const prodUser = { ...data.user, prod: prod };
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/auth/login", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({username: value.username, password: value.password}),
|
||||
});
|
||||
setSession(prodUser, data.token);
|
||||
toast.success(`You are logged in as ${data.user.username}`);
|
||||
router.navigate({ to: "/" });
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (!data.success) {
|
||||
toast.error(`${data.message}`);
|
||||
}
|
||||
|
||||
// Store token in localStorage
|
||||
// localStorage.setItem("auth_token", data.data.token);
|
||||
if (data.success) {
|
||||
const prod = btoa(`${value.username.toLowerCase()}:${value.password}`);
|
||||
const prodUser = {...data.user, prod: prod};
|
||||
//console.log(data);
|
||||
} catch (err) {
|
||||
toast.error("Invalid credentials");
|
||||
}
|
||||
};
|
||||
|
||||
setSession(prodUser, data.token);
|
||||
toast.success(`You are logged in as ${data.user.username}`);
|
||||
router.navigate({to: "/"});
|
||||
}
|
||||
return (
|
||||
<div className="ml-[25%]">
|
||||
<LstCard className="p-3 w-96">
|
||||
<CardHeader>
|
||||
<div>
|
||||
<p className="text-2xl">Login to LST</p>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<hr className="rounded"></hr>
|
||||
<form onSubmit={handleSubmit(onSubmitLogin)}>
|
||||
<div>
|
||||
<Label htmlFor="username" className="m-1">
|
||||
Username
|
||||
</Label>
|
||||
<Input
|
||||
placeholder="smith001"
|
||||
{...register("username")}
|
||||
className={errors.username ? "border-red-500" : ""}
|
||||
aria-invalid={!!errors.username}
|
||||
/>
|
||||
{errors.username && (
|
||||
<p className="text-red-500 text-sm mt-1">
|
||||
{errors.username.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<>
|
||||
<Label htmlFor={"password"} className="m-1">
|
||||
Password
|
||||
</Label>
|
||||
<Input
|
||||
type="password"
|
||||
{...register("password")}
|
||||
className={errors.password ? "border-red-500" : ""}
|
||||
aria-invalid={!!errors.password}
|
||||
/>
|
||||
{errors.password && (
|
||||
<p className="text-red-500 text-sm mt-1">
|
||||
{errors.password.message}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
<div className="flex justify-between pt-2">
|
||||
<div className="flex">
|
||||
<Controller
|
||||
render={({ field }) => (
|
||||
<>
|
||||
<Checkbox
|
||||
id="remember"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
<label
|
||||
htmlFor="remember"
|
||||
className="pl-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
remember me
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
control={control}
|
||||
name="rememberMe"
|
||||
defaultValue={rememeberMe}
|
||||
/>
|
||||
</div>
|
||||
|
||||
if (!data.success) {
|
||||
toast.error(`${data.message}`);
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
} catch (err) {
|
||||
toast.error("Invalid credentials");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ml-[25%]">
|
||||
<LstCard className="p-3 w-96">
|
||||
<CardHeader>
|
||||
<div>
|
||||
<p className="text-2xl">Login to LST</p>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<hr className="rounded"></hr>
|
||||
<form onSubmit={handleSubmit(onSubmitLogin)}>
|
||||
<div>
|
||||
<Label htmlFor="username" className="m-1">
|
||||
Username
|
||||
</Label>
|
||||
<Input
|
||||
placeholder="smith001"
|
||||
{...register("username")}
|
||||
className={errors.username ? "border-red-500" : ""}
|
||||
aria-invalid={!!errors.username}
|
||||
/>
|
||||
{errors.username && <p className="text-red-500 text-sm mt-1">{errors.username.message}</p>}
|
||||
</div>
|
||||
<div>
|
||||
<>
|
||||
<Label htmlFor={"password"} className="m-1">
|
||||
Password
|
||||
</Label>
|
||||
<Input
|
||||
type="password"
|
||||
{...register("password")}
|
||||
className={errors.password ? "border-red-500" : ""}
|
||||
aria-invalid={!!errors.password}
|
||||
/>
|
||||
{errors.password && <p className="text-red-500 text-sm mt-1">{errors.password.message}</p>}
|
||||
</>
|
||||
</div>
|
||||
<div className="flex justify-between pt-2">
|
||||
<div className="flex">
|
||||
<Controller
|
||||
render={({field}) => (
|
||||
<>
|
||||
<Checkbox
|
||||
id="remember"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
<label
|
||||
htmlFor="remember"
|
||||
className="pl-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
remember me
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
control={control}
|
||||
name="rememberMe"
|
||||
defaultValue={rememeberMe}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit">Submit</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit">Submit</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginForm;
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "lstv2",
|
||||
"version": "2.8.0",
|
||||
"version": "2.9.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "lstv2",
|
||||
"version": "2.8.0",
|
||||
"version": "2.9.0",
|
||||
"dependencies": {
|
||||
"@dotenvx/dotenvx": "^1.39.0",
|
||||
"@hono/node-server": "^1.14.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lstv2",
|
||||
"version": "2.8.0",
|
||||
"version": "2.9.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
},
|
||||
"admConfig": {
|
||||
"build": 47,
|
||||
"build": 50,
|
||||
"oldBuild": "backend-0.1.3.zip"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -78,4 +78,4 @@
|
||||
"ws": "^8.18.1",
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,153 +1,193 @@
|
||||
import AdmZip from "adm-zip";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import {execSync} from "child_process";
|
||||
import {createLog} from "../services/logger/logger.js";
|
||||
import {getAppInfo} from "../globalUtils/appInfo.js";
|
||||
import { execSync } from "child_process";
|
||||
import { createLog } from "../services/logger/logger.js";
|
||||
import { getAppInfo } from "../globalUtils/appInfo.js";
|
||||
|
||||
// create the ignore list
|
||||
const ignoreList = [
|
||||
".git",
|
||||
"builds",
|
||||
"server",
|
||||
"node_modules",
|
||||
"apiDocsLSTV2",
|
||||
"testFiles",
|
||||
".env",
|
||||
".gitignore",
|
||||
".versionrc.json",
|
||||
"drizzle-dev.config.ts",
|
||||
"nssm.exe",
|
||||
"postgresql-17.2-3-windows-x64.exe",
|
||||
// front end ignore
|
||||
"frontend/node_modules",
|
||||
"fonrtend/.env",
|
||||
"frontend/public",
|
||||
"frontend/src",
|
||||
"frontend/.gitignore",
|
||||
"frontend/eslint.config.js",
|
||||
"frontend/index.html",
|
||||
"frontend/package.json",
|
||||
"frontend/package-lock.json",
|
||||
"frontend/README.md",
|
||||
"frontend/tsconfig.json",
|
||||
"frontend/tsconfig.app.json",
|
||||
"frontend/tsconfig.node.json",
|
||||
"frontend/vite.config.ts",
|
||||
"frontend/components.json",
|
||||
".git",
|
||||
"builds",
|
||||
"server",
|
||||
"node_modules",
|
||||
"apiDocsLSTV2",
|
||||
"testFiles",
|
||||
".env",
|
||||
".gitignore",
|
||||
".versionrc.json",
|
||||
"drizzle-dev.config.ts",
|
||||
"nssm.exe",
|
||||
"postgresql-17.2-3-windows-x64.exe",
|
||||
// front end ignore
|
||||
"frontend/node_modules",
|
||||
"fonrtend/.env",
|
||||
"frontend/public",
|
||||
"frontend/src",
|
||||
"frontend/.gitignore",
|
||||
"frontend/eslint.config.js",
|
||||
"frontend/index.html",
|
||||
"frontend/package.json",
|
||||
"frontend/package-lock.json",
|
||||
"frontend/README.md",
|
||||
"frontend/tsconfig.json",
|
||||
"frontend/tsconfig.app.json",
|
||||
"frontend/tsconfig.node.json",
|
||||
"frontend/vite.config.ts",
|
||||
"frontend/components.json",
|
||||
];
|
||||
|
||||
const shouldIgnore = (itemPath: any) => {
|
||||
const normalizedItemPath = itemPath.replace(/\\/g, "/");
|
||||
const normalizedItemPath = itemPath.replace(/\\/g, "/");
|
||||
|
||||
return ignoreList.some((ignorePattern) => {
|
||||
const normalizedIgnorePatther = ignorePattern.replace(/\\/g, "/");
|
||||
return (
|
||||
normalizedItemPath === normalizedIgnorePatther ||
|
||||
normalizedItemPath.startsWith(`${normalizedIgnorePatther}/`)
|
||||
);
|
||||
});
|
||||
return ignoreList.some((ignorePattern) => {
|
||||
const normalizedIgnorePatther = ignorePattern.replace(/\\/g, "/");
|
||||
return (
|
||||
normalizedItemPath === normalizedIgnorePatther ||
|
||||
normalizedItemPath.startsWith(`${normalizedIgnorePatther}/`)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const addToZip = (zip: any, currentPath: string, rootPath: string) => {
|
||||
const items = fs.readdirSync(currentPath);
|
||||
const items = fs.readdirSync(currentPath);
|
||||
|
||||
items.forEach((item) => {
|
||||
const itemPath = path.join(currentPath, item);
|
||||
const relativePath = path.relative(rootPath, itemPath);
|
||||
items.forEach((item) => {
|
||||
const itemPath = path.join(currentPath, item);
|
||||
const relativePath = path.relative(rootPath, itemPath);
|
||||
|
||||
// Skip if the item is in the ignore list
|
||||
if (shouldIgnore(relativePath)) {
|
||||
createLog("info", "lst", "zipUpBuild", `Ignoring: ${relativePath}`);
|
||||
return;
|
||||
}
|
||||
// Skip if the item is in the ignore list
|
||||
if (shouldIgnore(relativePath)) {
|
||||
createLog("info", "lst", "zipUpBuild", `Ignoring: ${relativePath}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const stat = fs.statSync(itemPath);
|
||||
const stat = fs.statSync(itemPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// If it's a directory, recursively add its contents
|
||||
addToZip(zip, itemPath, rootPath);
|
||||
} else {
|
||||
// If it's a file, add it to the zip with the preserved folder structure
|
||||
zip.addLocalFile(itemPath, path.dirname(relativePath));
|
||||
}
|
||||
});
|
||||
if (stat.isDirectory()) {
|
||||
// If it's a directory, recursively add its contents
|
||||
addToZip(zip, itemPath, rootPath);
|
||||
} else {
|
||||
// If it's a file, add it to the zip with the preserved folder structure
|
||||
zip.addLocalFile(itemPath, path.dirname(relativePath));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const updateBuildNumber = (appLock: string) => {
|
||||
const packagePath = path.join(appLock, "package.json"); // Adjust path if necessary
|
||||
const packagePath = path.join(appLock, "package.json"); // Adjust path if necessary
|
||||
|
||||
try {
|
||||
// Read package.json
|
||||
const pkgData = fs.readFileSync(packagePath, "utf8");
|
||||
const pkgJson = JSON.parse(pkgData);
|
||||
try {
|
||||
// Read package.json
|
||||
const pkgData = fs.readFileSync(packagePath, "utf8");
|
||||
const pkgJson = JSON.parse(pkgData);
|
||||
|
||||
// Ensure admConfig exists
|
||||
if (pkgJson.admConfig && typeof pkgJson.admConfig.build === "number") {
|
||||
// Increment the build number
|
||||
pkgJson.admConfig.build += 1;
|
||||
// Ensure admConfig exists
|
||||
if (pkgJson.admConfig && typeof pkgJson.admConfig.build === "number") {
|
||||
// Increment the build number
|
||||
pkgJson.admConfig.build += 1;
|
||||
|
||||
// Write the updated data back
|
||||
fs.writeFileSync(packagePath, JSON.stringify(pkgJson, null, 2), "utf8");
|
||||
// Write the updated data back
|
||||
fs.writeFileSync(packagePath, JSON.stringify(pkgJson, null, 2), "utf8");
|
||||
|
||||
createLog("info", "lst", "zipUpBuild", `Build number updated to: ${pkgJson.admConfig.build}`);
|
||||
// Auto-commit changes
|
||||
execSync("git add package.json");
|
||||
execSync(`git commit -m "chore: bump build number to ${pkgJson.admConfig.build}"`);
|
||||
} else {
|
||||
createLog("error", "lst", "zipUpBuild", "admConfig.build is missing or not a number");
|
||||
}
|
||||
} catch (error) {
|
||||
createLog("error", "lst", "zipUpBuild", `Error updating build number: ${error}`);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"zipUpBuild",
|
||||
`Build number updated to: ${pkgJson.admConfig.build}`
|
||||
);
|
||||
// Auto-commit changes
|
||||
execSync("git add package.json");
|
||||
execSync(
|
||||
`git commit -m "build: bump build number to ${pkgJson.admConfig.build}"`
|
||||
);
|
||||
} else {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"zipUpBuild",
|
||||
"admConfig.build is missing or not a number"
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"zipUpBuild",
|
||||
`Error updating build number: ${error}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const createZip = async (appLock: string) => {
|
||||
const app = await getAppInfo(appLock);
|
||||
const zip = new AdmZip();
|
||||
const app = await getAppInfo(appLock);
|
||||
const zip = new AdmZip();
|
||||
|
||||
//dest path for this app... hard coded for meow will be in db later
|
||||
const destPath = `${process.env.DEVFOLDER}\\builds`;
|
||||
const srcPath = `${process.env.DEVFOLDER}`;
|
||||
//dest path for this app... hard coded for meow will be in db later
|
||||
const destPath = `${process.env.DEVFOLDER}\\builds`;
|
||||
const srcPath = `${process.env.DEVFOLDER}`;
|
||||
|
||||
addToZip(zip, srcPath, srcPath);
|
||||
addToZip(zip, srcPath, srcPath);
|
||||
|
||||
// Write the zip file to disk
|
||||
const outputZipPath = path.join(destPath, `${app.name}-${app.version}-${app.admConfig.build}.zip`);
|
||||
zip.writeZip(outputZipPath);
|
||||
// Write the zip file to disk
|
||||
const outputZipPath = path.join(
|
||||
destPath,
|
||||
`${app.name}-${app.version}-${app.admConfig.build}.zip`
|
||||
);
|
||||
zip.writeZip(outputZipPath);
|
||||
|
||||
createLog("info", "lst", "zipUpBuild", `Zip file created at ${outputZipPath}`);
|
||||
updateBuildNumber(appLock);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"zipUpBuild",
|
||||
`Zip file created at ${outputZipPath}`
|
||||
);
|
||||
updateBuildNumber(appLock);
|
||||
|
||||
// only keep the last 5 builds for the type we have.
|
||||
try {
|
||||
const appFiles = fs
|
||||
.readdirSync(destPath)
|
||||
.filter((file) => file.startsWith(app.name)) // Ensure only backend files are matched
|
||||
.map((file) => ({
|
||||
name: file,
|
||||
time: fs.statSync(path.join(destPath, file)).mtime.getTime(),
|
||||
}))
|
||||
.sort((a, b) => a.time - b.time); // Sort by modification time (oldest first)
|
||||
// only keep the last 5 builds for the type we have.
|
||||
try {
|
||||
const appFiles = fs
|
||||
.readdirSync(destPath)
|
||||
.filter((file) => file.startsWith(app.name)) // Ensure only backend files are matched
|
||||
.map((file) => ({
|
||||
name: file,
|
||||
time: fs.statSync(path.join(destPath, file)).mtime.getTime(),
|
||||
}))
|
||||
.sort((a, b) => a.time - b.time); // Sort by modification time (oldest first)
|
||||
|
||||
createLog("info", "lst", "zipUpBuild", `app Files (sorted by time):", ${JSON.stringify(appFiles)}`);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"zipUpBuild",
|
||||
`app Files (sorted by time):", ${JSON.stringify(appFiles)}`
|
||||
);
|
||||
|
||||
if (appFiles.length > 5) {
|
||||
appFiles.slice(0, -5).forEach((file) => {
|
||||
const filePath = path.join(destPath, file.name);
|
||||
try {
|
||||
fs.unlinkSync(filePath);
|
||||
createLog("info", "lst", "zipUpBuild", `Deleted: ${file.name}`);
|
||||
} catch (error: any) {
|
||||
createLog("error", "lst", "zipUpBuild", `Failed to delete ${file.name}: ${error.message}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
createLog("info", "lst", "zipUpBuild", "No files to delete.");
|
||||
if (appFiles.length > 5) {
|
||||
appFiles.slice(0, -5).forEach((file) => {
|
||||
const filePath = path.join(destPath, file.name);
|
||||
try {
|
||||
fs.unlinkSync(filePath);
|
||||
createLog("info", "lst", "zipUpBuild", `Deleted: ${file.name}`);
|
||||
} catch (error: any) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"zipUpBuild",
|
||||
`Failed to delete ${file.name}: ${error.message}`
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
createLog("error", "lst", "zipUpBuild", `Error reading directory or deleting files:", ${error.message}`);
|
||||
});
|
||||
} else {
|
||||
createLog("info", "lst", "zipUpBuild", "No files to delete.");
|
||||
}
|
||||
} catch (error: any) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"zipUpBuild",
|
||||
`Error reading directory or deleting files:", ${error.message}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
//createZip("C:\\Users\\matthes01\\Documents\\lstv2");
|
||||
@@ -155,16 +195,16 @@ export const createZip = async (appLock: string) => {
|
||||
// Only call `createZip` if the script is executed directly
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
const location = process.argv[2];
|
||||
const location = process.argv[2];
|
||||
|
||||
if (!location) {
|
||||
createLog("error", "lst", "zipUpBuild", "Error: No location provided.");
|
||||
process.exit(1);
|
||||
} else {
|
||||
createLog("info", "lst", "zipUpBuild", "Startiing the zip process.");
|
||||
}
|
||||
|
||||
createZip(location);
|
||||
} else {
|
||||
if (!location) {
|
||||
createLog("error", "lst", "zipUpBuild", "Error: No location provided.");
|
||||
process.exit(1);
|
||||
} else {
|
||||
createLog("info", "lst", "zipUpBuild", "Startiing the zip process.");
|
||||
}
|
||||
|
||||
createZip(location);
|
||||
} else {
|
||||
createLog("error", "lst", "zipUpBuild", "Error: No location provided.");
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { z, createRoute, OpenAPIHono } from "@hono/zod-openapi";
|
||||
import { apiHit } from "../../../../globalUtils/apiHits.js";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import type { CustomJwtPayload } from "../../../../types/jwtToken.js";
|
||||
import { authMiddleware } from "../../middleware/authMiddleware.js";
|
||||
import hasCorrectRole from "../../middleware/roleCheck.js";
|
||||
import { roleCheck } from "../../controllers/userRoles/getUserAccess.js";
|
||||
|
||||
const { verify } = jwt;
|
||||
@@ -16,10 +13,10 @@ const responseSchema = z.object({
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["Auth:user"],
|
||||
tags: ["auth:user"],
|
||||
summary: "returns the users access",
|
||||
method: "get",
|
||||
path: "/getAccess",
|
||||
path: "/getuseraccess",
|
||||
middleware: [authMiddleware],
|
||||
responses: {
|
||||
200: {
|
||||
|
||||
@@ -1,111 +1,198 @@
|
||||
import sql from "mssql";
|
||||
import {prodSqlConfig} from "./utils/prodServerConfig.js";
|
||||
import {createLog} from "../logger/logger.js";
|
||||
import {db} from "../../../database/dbclient.js";
|
||||
import {settings} from "../../../database/schema/settings.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
import {installed} from "../../index.js";
|
||||
import {checkHostnamePort} from "../../globalUtils/pingServer.js";
|
||||
import { prodSqlConfig } from "./utils/prodServerConfig.js";
|
||||
import { createLog } from "../logger/logger.js";
|
||||
import { db } from "../../../database/dbclient.js";
|
||||
import { settings } from "../../../database/schema/settings.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { installed } from "../../index.js";
|
||||
import { checkHostnamePort } from "../../globalUtils/pingServer.js";
|
||||
|
||||
let pool: any;
|
||||
let connected: boolean = false;
|
||||
export const initializeProdPool = async () => {
|
||||
if (!installed) {
|
||||
createLog("info", "lst", "sqlProd", "The server was not installed will reconnect in 5 seconds");
|
||||
setTimeout(() => {
|
||||
initializeProdPool();
|
||||
}, 5 * 1000);
|
||||
if (!installed) {
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
"The server was not installed will reconnect in 5 seconds"
|
||||
);
|
||||
setTimeout(() => {
|
||||
initializeProdPool();
|
||||
}, 5 * 1000);
|
||||
|
||||
return {success: false, message: "The server is not installed."};
|
||||
}
|
||||
const dbServer = await db.select().from(settings).where(eq(settings.name, "dbServer"));
|
||||
const serverUp = await checkHostnamePort(`${dbServer[0].value}:1433`);
|
||||
return { success: false, message: "The server is not installed." };
|
||||
}
|
||||
const dbServer = await db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, "dbServer"));
|
||||
const serverUp = await checkHostnamePort(`${dbServer[0].value}:1433`);
|
||||
|
||||
if (!serverUp) {
|
||||
createLog("error", "lst", "server", `The sql ${dbServer[0].value} is not reachable`);
|
||||
return {success: false, message: `The sql ${dbServer[0].value} is not reachable`};
|
||||
}
|
||||
if (!serverUp) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"server",
|
||||
`The sql ${dbServer[0].value} is not reachable`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `The sql ${dbServer[0].value} is not reachable`,
|
||||
};
|
||||
}
|
||||
|
||||
// make sure the server is not set to localhost this will prevent some weird issues later but can be localhost on the dev
|
||||
const serverLoc = await db.select().from(settings).where(eq(settings.name, "dbServer"));
|
||||
if (serverLoc[0].value === "localhost" && process.env.NODE_ENV !== "development") {
|
||||
createLog("error", "lst", "sqlProd", "The server is set to localhost, and you are not in development mode.");
|
||||
return {success: false, message: "The server is set to localhost, and you are not in development mode."};
|
||||
}
|
||||
// make sure the server is not set to localhost this will prevent some weird issues later but can be localhost on the dev
|
||||
const serverLoc = await db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, "dbServer"));
|
||||
if (
|
||||
serverLoc[0].value === "localhost" &&
|
||||
process.env.NODE_ENV !== "development"
|
||||
) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
"The server is set to localhost, and you are not in development mode."
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
"The server is set to localhost, and you are not in development mode.",
|
||||
};
|
||||
}
|
||||
|
||||
// if you were restarting from the endpoint you get this lovely error
|
||||
if (connected) {
|
||||
createLog("error", "lst", "sqlProd", "There is already a connection.");
|
||||
return {success: false, message: "There is already a connection."};
|
||||
}
|
||||
try {
|
||||
const config = await prodSqlConfig();
|
||||
pool = await sql.connect(config!);
|
||||
// if you were restarting from the endpoint you get this lovely error
|
||||
if (connected) {
|
||||
createLog("error", "lst", "sqlProd", "There is already a connection.");
|
||||
return { success: false, message: "There is already a connection." };
|
||||
}
|
||||
try {
|
||||
const config = await prodSqlConfig();
|
||||
pool = await sql.connect(config!);
|
||||
|
||||
createLog("info", "lst", "sqlProd", `Connected to ${config?.server}, and looking at ${config?.database}`);
|
||||
connected = true;
|
||||
return {success: true, message: "The sql server connection has been closed"};
|
||||
} catch (error) {
|
||||
createLog("error", "lst", "sqlProd", `${JSON.stringify(error)}, "There was an error connecting to the pool."`);
|
||||
throw new Error("There was an error closing the sql connection");
|
||||
}
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
`Connected to ${config?.server}, and looking at ${config?.database}`
|
||||
);
|
||||
connected = true;
|
||||
return {
|
||||
success: true,
|
||||
message: "The sql server connection has been closed",
|
||||
};
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
`${JSON.stringify(error)}, "There was an error connecting to the pool."`
|
||||
);
|
||||
throw new Error("There was an error closing the sql connection");
|
||||
}
|
||||
};
|
||||
|
||||
export const closePool = async () => {
|
||||
try {
|
||||
await pool.close();
|
||||
createLog("info", "lst", "sqlProd", "Connection pool closed");
|
||||
connected = false;
|
||||
return {success: true, message: "The sql server connection has been closed"};
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
`${JSON.stringify(error)}, "There was an error closing the sql connection"`
|
||||
);
|
||||
throw new Error("There was an error closing the sql connection");
|
||||
}
|
||||
if (!connected) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
"There is no connection a connection."
|
||||
);
|
||||
return { success: false, message: "There is already a connection." };
|
||||
}
|
||||
try {
|
||||
await pool.close();
|
||||
createLog("info", "lst", "sqlProd", "Connection pool closed");
|
||||
connected = false;
|
||||
return {
|
||||
success: true,
|
||||
message: "The sql server connection has been closed",
|
||||
};
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
`${JSON.stringify(
|
||||
error
|
||||
)}, "There was an error closing the sql connection"`
|
||||
);
|
||||
throw new Error("There was an error closing the sql connection");
|
||||
}
|
||||
};
|
||||
|
||||
export async function query(queryToRun: string, name: string) {
|
||||
/**
|
||||
* Just an extra catch incase someone tried to run a query while we were not connected to the server or sql server
|
||||
*/
|
||||
const dbServer = await db.select().from(settings).where(eq(settings.name, "dbServer"));
|
||||
const serverUp = await checkHostnamePort(`${dbServer[0].value}:1433`);
|
||||
/**
|
||||
* Just an extra catch incase someone tried to run a query while we were not connected to the server or sql server
|
||||
*/
|
||||
const dbServer = await db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, "dbServer"));
|
||||
const serverUp = await checkHostnamePort(`${dbServer[0].value}:1433`);
|
||||
|
||||
if (!serverUp) {
|
||||
createLog("error", "lst", "server", `The sql ${dbServer[0].value} is not reachable`);
|
||||
return {success: false, message: `The sql ${dbServer[0].value} is not reachable`};
|
||||
if (!serverUp) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"server",
|
||||
`The sql ${dbServer[0].value} is not reachable`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `The sql ${dbServer[0].value} is not reachable`,
|
||||
};
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"server",
|
||||
`The sql ${dbServer[0].value} is not connected`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `The sql ${dbServer[0].value} is not not connected`,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* We no longer need to send over the plant token change as we do it inside the query function.
|
||||
*/
|
||||
const plantToken = await db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, "plantToken"));
|
||||
const query = queryToRun.replaceAll("test1", plantToken[0].value);
|
||||
|
||||
try {
|
||||
const result = await pool.request().query(query);
|
||||
|
||||
return result.recordset;
|
||||
} catch (error: any) {
|
||||
if (error.code === "ETIMEOUT") {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"sqlProd",
|
||||
`${JSON.stringify(error)}, ${name} did not run due to a timeout.`
|
||||
);
|
||||
throw new Error(`${name} query did not run due to a timeout.`);
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
createLog("error", "lst", "server", `The sql ${dbServer[0].value} is not connected`);
|
||||
return {success: false, message: `The sql ${dbServer[0].value} is not not connected`};
|
||||
if (error.code === "EREQUEST") {
|
||||
throw new Error(
|
||||
`${name} encoutnered an error ${error.originalError.info.message}`
|
||||
);
|
||||
}
|
||||
/**
|
||||
* We no longer need to send over the plant token change as we do it inside the query function.
|
||||
*/
|
||||
const plantToken = await db.select().from(settings).where(eq(settings.name, "plantToken"));
|
||||
const query = queryToRun.replaceAll("test1", plantToken[0].value);
|
||||
|
||||
try {
|
||||
const result = await pool.request().query(query);
|
||||
|
||||
return result.recordset;
|
||||
} catch (error: any) {
|
||||
if (error.code === "ETIMEOUT") {
|
||||
createLog("error", "lst", "sqlProd", `${JSON.stringify(error)}, ${name} did not run due to a timeout.`);
|
||||
throw new Error(`${name} query did not run due to a timeout.`);
|
||||
}
|
||||
|
||||
if (error.code === "EREQUEST") {
|
||||
throw new Error(`${name} encoutnered an error ${error.originalError.info.message}`);
|
||||
}
|
||||
|
||||
//console.log(error.originalError.info.message);
|
||||
//EREQUEST
|
||||
//throw new Error(`${name} encoutnered an error ${error.code}`);
|
||||
}
|
||||
//console.log(error.originalError.info.message);
|
||||
//EREQUEST
|
||||
//throw new Error(`${name} encoutnered an error ${error.code}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user