mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2026-08-31 19:03:45 +02:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41758c32f2 | ||
|
|
38b113c9e8 | ||
|
|
83619eb98e | ||
|
|
89e9b85bda | ||
|
|
f5198c7c0b | ||
|
|
9b8caccfbd | ||
|
|
747be7cf7d | ||
|
|
fe1ce74ff3 |
Generated
+78
-106
@@ -23,7 +23,7 @@
|
||||
"pg": "^8.5.1",
|
||||
"pg-hstore": "^2.3.3",
|
||||
"rate-limiter-flexible": "^2.1.15",
|
||||
"sequelize": "^6.11.0",
|
||||
"sequelize": "^6.25.5",
|
||||
"socket.io": "^4.0.1",
|
||||
"sqlite3": "^4.0.0",
|
||||
"umzug": "^2.3.0"
|
||||
@@ -237,13 +237,10 @@
|
||||
"integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@socket.io/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
"node_modules/@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.8",
|
||||
@@ -294,11 +291,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/component-emitter": {
|
||||
"version": "1.2.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
|
||||
"integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ=="
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
|
||||
@@ -474,8 +466,7 @@
|
||||
"node_modules/@types/validator": {
|
||||
"version": "13.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.1.tgz",
|
||||
"integrity": "sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q=="
|
||||
},
|
||||
"node_modules/@types/webidl-conversions": {
|
||||
"version": "6.1.1",
|
||||
@@ -1100,11 +1091,6 @@
|
||||
"integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -1380,9 +1366,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.2.tgz",
|
||||
"integrity": "sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz",
|
||||
"integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==",
|
||||
"dependencies": {
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/cors": "^2.8.12",
|
||||
@@ -1392,7 +1378,7 @@
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~5.0.0",
|
||||
"engine.io-parser": "~5.0.3",
|
||||
"ws": "~8.2.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1400,12 +1386,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io-parser": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz",
|
||||
"integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==",
|
||||
"dependencies": {
|
||||
"@socket.io/base64-arraybuffer": "~1.0.2"
|
||||
},
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
|
||||
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
@@ -2195,9 +2178,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/inflection": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz",
|
||||
"integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==",
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz",
|
||||
"integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==",
|
||||
"engines": [
|
||||
"node >= 0.4.0"
|
||||
]
|
||||
@@ -4116,9 +4099,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/retry-as-promised": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz",
|
||||
"integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA=="
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-6.1.0.tgz",
|
||||
"integrity": "sha512-Hj/jY+wFC+SB9SDlIIFWiGOHnNG0swYbGYsOj2BJ8u2HKUaobNKab0OIC0zOLYzDy0mb7A4xA5BMo4LMz5YtEA=="
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
@@ -4290,9 +4273,9 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/sequelize": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.14.0.tgz",
|
||||
"integrity": "sha512-rgfJFixBwnrxdouIlYS1G0nTo2xj+Gyn7EDn/miE6r5xCzN3EdjtbNrDXapLHNZxgKfu7hZHLzZvwl3DbfhM6g==",
|
||||
"version": "6.25.5",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.25.5.tgz",
|
||||
"integrity": "sha512-QwA2kL4lSNy4mYTv1Zm4DjvloZLaYajuYF5QMOv0O7FameMUEl8Q5zOWRD+FNKGCLzyOJ28gQCo3HX0N9mcssA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -4301,14 +4284,15 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/validator": "^13.7.1",
|
||||
"debug": "^4.3.3",
|
||||
"dottie": "^2.0.2",
|
||||
"inflection": "^1.13.1",
|
||||
"inflection": "^1.13.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"pg-connection-string": "^2.5.0",
|
||||
"retry-as-promised": "^5.0.0",
|
||||
"retry-as-promised": "^6.1.0",
|
||||
"semver": "^7.3.5",
|
||||
"sequelize-pool": "^7.1.0",
|
||||
"toposort-class": "^1.0.1",
|
||||
@@ -4329,6 +4313,9 @@
|
||||
"mysql2": {
|
||||
"optional": true
|
||||
},
|
||||
"oracledb": {
|
||||
"optional": true
|
||||
},
|
||||
"pg": {
|
||||
"optional": true
|
||||
},
|
||||
@@ -4426,33 +4413,32 @@
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz",
|
||||
"integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==",
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
|
||||
"integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.2",
|
||||
"engine.io": "~6.1.0",
|
||||
"socket.io-adapter": "~2.3.3",
|
||||
"socket.io-parser": "~4.0.4"
|
||||
"engine.io": "~6.2.1",
|
||||
"socket.io-adapter": "~2.4.0",
|
||||
"socket.io-parser": "~4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io-adapter": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz",
|
||||
"integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ=="
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz",
|
||||
"integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg=="
|
||||
},
|
||||
"node_modules/socket.io-parser": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz",
|
||||
"integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
|
||||
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
|
||||
"dependencies": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -5481,10 +5467,10 @@
|
||||
"integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==",
|
||||
"dev": true
|
||||
},
|
||||
"@socket.io/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ=="
|
||||
"@socket.io/component-emitter": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
||||
},
|
||||
"@tsconfig/node10": {
|
||||
"version": "1.0.8",
|
||||
@@ -5535,11 +5521,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/component-emitter": {
|
||||
"version": "1.2.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
|
||||
"integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ=="
|
||||
},
|
||||
"@types/connect": {
|
||||
"version": "3.4.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
|
||||
@@ -5715,8 +5696,7 @@
|
||||
"@types/validator": {
|
||||
"version": "13.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.1.tgz",
|
||||
"integrity": "sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q=="
|
||||
},
|
||||
"@types/webidl-conversions": {
|
||||
"version": "6.1.1",
|
||||
@@ -6140,11 +6120,6 @@
|
||||
"integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==",
|
||||
"dev": true
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -6345,9 +6320,9 @@
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.2.tgz",
|
||||
"integrity": "sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz",
|
||||
"integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/cors": "^2.8.12",
|
||||
@@ -6357,17 +6332,14 @@
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~5.0.0",
|
||||
"engine.io-parser": "~5.0.3",
|
||||
"ws": "~8.2.3"
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz",
|
||||
"integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==",
|
||||
"requires": {
|
||||
"@socket.io/base64-arraybuffer": "~1.0.2"
|
||||
}
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz",
|
||||
"integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg=="
|
||||
},
|
||||
"es2015-i18n-tag": {
|
||||
"version": "1.6.1",
|
||||
@@ -6985,9 +6957,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"inflection": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz",
|
||||
"integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA=="
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz",
|
||||
"integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
@@ -8346,9 +8318,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"retry-as-promised": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz",
|
||||
"integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA=="
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-6.1.0.tgz",
|
||||
"integrity": "sha512-Hj/jY+wFC+SB9SDlIIFWiGOHnNG0swYbGYsOj2BJ8u2HKUaobNKab0OIC0zOLYzDy0mb7A4xA5BMo4LMz5YtEA=="
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
@@ -8476,19 +8448,20 @@
|
||||
}
|
||||
},
|
||||
"sequelize": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.14.0.tgz",
|
||||
"integrity": "sha512-rgfJFixBwnrxdouIlYS1G0nTo2xj+Gyn7EDn/miE6r5xCzN3EdjtbNrDXapLHNZxgKfu7hZHLzZvwl3DbfhM6g==",
|
||||
"version": "6.25.5",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.25.5.tgz",
|
||||
"integrity": "sha512-QwA2kL4lSNy4mYTv1Zm4DjvloZLaYajuYF5QMOv0O7FameMUEl8Q5zOWRD+FNKGCLzyOJ28gQCo3HX0N9mcssA==",
|
||||
"requires": {
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/validator": "^13.7.1",
|
||||
"debug": "^4.3.3",
|
||||
"dottie": "^2.0.2",
|
||||
"inflection": "^1.13.1",
|
||||
"inflection": "^1.13.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"pg-connection-string": "^2.5.0",
|
||||
"retry-as-promised": "^5.0.0",
|
||||
"retry-as-promised": "^6.1.0",
|
||||
"semver": "^7.3.5",
|
||||
"sequelize-pool": "^7.1.0",
|
||||
"toposort-class": "^1.0.1",
|
||||
@@ -8558,30 +8531,29 @@
|
||||
"dev": true
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz",
|
||||
"integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==",
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
|
||||
"integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.2",
|
||||
"engine.io": "~6.1.0",
|
||||
"socket.io-adapter": "~2.3.3",
|
||||
"socket.io-parser": "~4.0.4"
|
||||
"engine.io": "~6.2.1",
|
||||
"socket.io-adapter": "~2.4.0",
|
||||
"socket.io-parser": "~4.2.1"
|
||||
}
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz",
|
||||
"integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ=="
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz",
|
||||
"integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg=="
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz",
|
||||
"integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
|
||||
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.1"
|
||||
}
|
||||
},
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@
|
||||
"pg": "^8.5.1",
|
||||
"pg-hstore": "^2.3.3",
|
||||
"rate-limiter-flexible": "^2.1.15",
|
||||
"sequelize": "^6.11.0",
|
||||
"sequelize": "^6.25.5",
|
||||
"socket.io": "^4.0.1",
|
||||
"sqlite3": "^4.0.0",
|
||||
"umzug": "^2.3.0"
|
||||
|
||||
+43
-11
@@ -17,8 +17,6 @@
|
||||
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { AddDeviceTokenModelStatic, createAddDeviceTokenModel } from './adddevicetoken'
|
||||
import { AppModelStatic, createAppModel } from './app'
|
||||
import { AppActivityModelStatic, createAppActivityModel } from './appactivity'
|
||||
import { AuthTokenModelStatic, createAuthtokenModel } from './authtoken'
|
||||
import { CategoryModelStatic, createCategoryModel } from './category'
|
||||
import { CategoryAppModelStatic, createCategoryAppModel } from './categoryapp'
|
||||
@@ -42,14 +40,13 @@ import { createU2fKeyModel, U2fKeyModelStatic } from './u2fkey'
|
||||
import { createUsedTimeModel, UsedTimeModelStatic } from './usedtime'
|
||||
import { createUserModel, UserModelStatic } from './user'
|
||||
import { createUserLimitLoginCategoryModel, UserLimitLoginCategoryModelStatic } from './userlimitlogincategory'
|
||||
import { shouldRetryWithException } from './utils/serialized'
|
||||
|
||||
export type Transaction = Sequelize.Transaction
|
||||
|
||||
export interface Database {
|
||||
addDeviceToken: AddDeviceTokenModelStatic
|
||||
authtoken: AuthTokenModelStatic
|
||||
app: AppModelStatic
|
||||
appActivity: AppActivityModelStatic
|
||||
category: CategoryModelStatic
|
||||
categoryApp: CategoryAppModelStatic
|
||||
categoryNetworkId: CategoryNetworkIdModelStatic
|
||||
@@ -71,15 +68,21 @@ export interface Database {
|
||||
usedTime: UsedTimeModelStatic
|
||||
user: UserModelStatic
|
||||
userLimitLoginCategory: UserLimitLoginCategoryModelStatic
|
||||
transaction: <T> (autoCallback: (t: Transaction) => Promise<T>, options?: { transaction: Transaction }) => Promise<T>
|
||||
transaction: <T> (
|
||||
autoCallback: (t: Transaction) => Promise<T>,
|
||||
options?: TransactionOptions
|
||||
) => Promise<T>
|
||||
dialect: string
|
||||
}
|
||||
|
||||
interface TransactionOptions {
|
||||
transaction?: Transaction
|
||||
disableRetry?: boolean
|
||||
}
|
||||
|
||||
const createDatabase = (sequelize: Sequelize.Sequelize): Database => ({
|
||||
addDeviceToken: createAddDeviceTokenModel(sequelize),
|
||||
authtoken: createAuthtokenModel(sequelize),
|
||||
app: createAppModel(sequelize),
|
||||
appActivity: createAppActivityModel(sequelize),
|
||||
category: createCategoryModel(sequelize),
|
||||
categoryApp: createCategoryAppModel(sequelize),
|
||||
childTask: createChildTaskModel(sequelize),
|
||||
@@ -101,10 +104,39 @@ const createDatabase = (sequelize: Sequelize.Sequelize): Database => ({
|
||||
usedTime: createUsedTimeModel(sequelize),
|
||||
user: createUserModel(sequelize),
|
||||
userLimitLoginCategory: createUserLimitLoginCategoryModel(sequelize),
|
||||
transaction: <T> (autoCallback: (transaction: Transaction) => Promise<T>, options?: { transaction: Transaction }) => (sequelize.transaction({
|
||||
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE,
|
||||
transaction: options?.transaction
|
||||
}, autoCallback)) as Promise<T>,
|
||||
async transaction<T>(
|
||||
autoCallback: (transaction: Transaction) => Promise<T>,
|
||||
options?: TransactionOptions
|
||||
): Promise<T> {
|
||||
const runAttempt = () => sequelize.transaction({
|
||||
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE,
|
||||
transaction: options?.transaction
|
||||
}, autoCallback)
|
||||
|
||||
const delay = (time: number) => new Promise((resolve) => setTimeout(resolve, time))
|
||||
|
||||
try {
|
||||
return await runAttempt()
|
||||
} catch (ex) {
|
||||
if (
|
||||
options?.disableRetry ||
|
||||
options?.transaction ||
|
||||
!shouldRetryWithException(this, ex)
|
||||
) throw ex
|
||||
}
|
||||
|
||||
await delay(10 * (1 + Math.random()))
|
||||
|
||||
try {
|
||||
return await runAttempt()
|
||||
} catch (ex) {
|
||||
if (!shouldRetryWithException(this, ex)) throw ex
|
||||
}
|
||||
|
||||
await delay(100 * (1 + Math.random()))
|
||||
|
||||
return await runAttempt()
|
||||
},
|
||||
dialect: sequelize.getDialect()
|
||||
})
|
||||
|
||||
|
||||
+10
-19
@@ -15,26 +15,17 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { RemoveInstalledAppsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { QueryInterface, Sequelize, Transaction } from 'sequelize'
|
||||
|
||||
export async function dispatchRemoveInstalledApps ({ deviceId, action, cache }: {
|
||||
deviceId: string
|
||||
action: RemoveInstalledAppsAction
|
||||
cache: Cache
|
||||
}) {
|
||||
await cache.database.app.destroy({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId,
|
||||
packageName: {
|
||||
[Sequelize.Op.in]: action.packageNames
|
||||
}
|
||||
},
|
||||
transaction: cache.transaction
|
||||
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
|
||||
await sequelize.transaction({
|
||||
type: Transaction.TYPES.EXCLUSIVE
|
||||
}, async (transaction) => {
|
||||
await queryInterface.dropTable('Apps', { transaction })
|
||||
await queryInterface.dropTable('AppActivities', { transaction })
|
||||
})
|
||||
}
|
||||
|
||||
cache.devicesWithModifiedInstalledApps.add(deviceId)
|
||||
cache.incrementTriggeredSyncLevel(1)
|
||||
export async function down() {
|
||||
throw new Error('not possible')
|
||||
}
|
||||
@@ -86,8 +86,8 @@ export async function assertSerializeableTransactionsAreWorking (database: Datab
|
||||
await database.config.update({ value: 'd' }, { where: { id: configItemIds.secondSelfTestData }, transaction: transactionTwo })
|
||||
})()
|
||||
])
|
||||
})
|
||||
})
|
||||
}, { disableRetry: true })
|
||||
}, { disableRetry: true })
|
||||
|
||||
throw new SerializationFeatureCheckException()
|
||||
} catch (ex) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -29,26 +29,6 @@ export async function deleteFamilies ({ database, familiyIds }: {
|
||||
}
|
||||
|
||||
await database.transaction(async (transaction) => {
|
||||
// app
|
||||
await database.app.destroy({
|
||||
where: {
|
||||
familyId: {
|
||||
[Sequelize.Op.in]: familiyIds
|
||||
}
|
||||
},
|
||||
transaction
|
||||
})
|
||||
|
||||
// app activity
|
||||
await database.appActivity.destroy({
|
||||
where: {
|
||||
familyId: {
|
||||
[Sequelize.Op.in]: familiyIds
|
||||
}
|
||||
},
|
||||
transaction
|
||||
})
|
||||
|
||||
// category
|
||||
await database.category.destroy({
|
||||
where: {
|
||||
|
||||
@@ -40,23 +40,6 @@ export async function removeDevice ({ database, familyId, deviceId, websocket, t
|
||||
throw new Conflict()
|
||||
}
|
||||
|
||||
// remove app entries
|
||||
await database.app.destroy({
|
||||
where: {
|
||||
familyId,
|
||||
deviceId
|
||||
},
|
||||
transaction
|
||||
})
|
||||
|
||||
await database.appActivity.destroy({
|
||||
where: {
|
||||
familyId,
|
||||
deviceId
|
||||
},
|
||||
transaction
|
||||
})
|
||||
|
||||
// remove as current device
|
||||
await database.user.update({
|
||||
currentDevice: ''
|
||||
|
||||
@@ -40,7 +40,6 @@ export class Cache {
|
||||
categoriesWithModifiedUsedTimes = new Set<string>()
|
||||
categoriesWithModifiedTasks = new Set<string>()
|
||||
|
||||
devicesWithModifiedInstalledApps = new Set<string>()
|
||||
devicesWithModifiedShowDeviceConnected = new Map<string, boolean>()
|
||||
|
||||
invalidiateUserList = false
|
||||
@@ -241,22 +240,6 @@ export class Cache {
|
||||
this.categoriesWithModifiedUsedTimes.clear()
|
||||
}
|
||||
|
||||
if (this.devicesWithModifiedInstalledApps.size > 0) {
|
||||
await database.device.update({
|
||||
installedAppsVersion: generateVersionId()
|
||||
}, {
|
||||
where: {
|
||||
familyId,
|
||||
deviceId: {
|
||||
[Sequelize.Op.in]: setToList(this.devicesWithModifiedInstalledApps)
|
||||
}
|
||||
},
|
||||
transaction
|
||||
})
|
||||
|
||||
this.devicesWithModifiedInstalledApps.clear()
|
||||
}
|
||||
|
||||
if (this.invalidiateUserList) {
|
||||
await database.family.update({
|
||||
userListVersion: generateVersionId()
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { AddInstalledAppsAction } from '../../../../action'
|
||||
import { AppAttributes, maxPackageNameLength } from '../../../../database/app'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception'
|
||||
|
||||
export async function dispatchAddInstalledApps ({ deviceId, action, cache }: {
|
||||
deviceId: string
|
||||
action: AddInstalledAppsAction
|
||||
cache: Cache
|
||||
}) {
|
||||
action.apps.forEach((app) => {
|
||||
if (app.packageName.length > maxPackageNameLength) {
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'package name too long',
|
||||
dynamicMessage: 'package name too long: ' + app.packageName
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
await cache.database.app.destroy({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId,
|
||||
packageName: {
|
||||
[Sequelize.Op.in]: action.apps.map((app) => app.packageName)
|
||||
}
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
await cache.database.app.bulkCreate(
|
||||
action.apps.map((app): AppAttributes => ({
|
||||
familyId: cache.familyId,
|
||||
deviceId,
|
||||
packageName: app.packageName,
|
||||
title: app.title,
|
||||
isLaunchable: app.isLaunchable,
|
||||
recommendation: app.recommendation
|
||||
})),
|
||||
{ transaction: cache.transaction }
|
||||
)
|
||||
|
||||
cache.devicesWithModifiedInstalledApps.add(deviceId)
|
||||
cache.incrementTriggeredSyncLevel(1)
|
||||
}
|
||||
@@ -36,18 +36,15 @@ import {
|
||||
import { EventHandler } from '../../../../monitoring/eventhandler'
|
||||
import { Cache } from '../cache'
|
||||
import { ActionObjectTypeNotHandledException } from '../exception/illegal-state'
|
||||
import { dispatchAddInstalledApps } from './addinstalledapps'
|
||||
import { dispatchAddUsedTime } from './addusedtime'
|
||||
import { dispatchAddUsedTimeVersion2 } from './addusedtime2'
|
||||
import { dispatchFinishKeyRequestAction } from './finishkeyrequest'
|
||||
import { dispatchForceSyncAction } from './forcesync'
|
||||
import { dispatchMarkTaskPendingAction } from './marktaskpendingaction'
|
||||
import { dispatchReplyToKeyRequestAction } from './replytokeyrequest'
|
||||
import { dispatchRemoveInstalledApps } from './removeinstalledapps'
|
||||
import { dispatchSendKeyRequestAction } from './sendkeyrequest'
|
||||
import { dispatchSignOutAtDevice } from './signoutatdevice'
|
||||
import { dispatchTriedDisablingDeviceAdmin } from './trieddisablingdeviceadmin'
|
||||
import { dispatchUpdateAppActivities } from './updateappactivities'
|
||||
import { dispatchUpdateDeviceStatus } from './updatedevicestatus'
|
||||
import { dispatchUpdateInstalledApps } from './updateinstalledapps'
|
||||
import { dispatchUploadDevicePublicKeyAction } from './uploaddevicepublickey'
|
||||
@@ -59,7 +56,7 @@ export const dispatchAppLogicAction = async ({ action, deviceId, cache, eventHan
|
||||
eventHandler: EventHandler
|
||||
}) => {
|
||||
if (action instanceof AddInstalledAppsAction) {
|
||||
await dispatchAddInstalledApps({ deviceId, action, cache })
|
||||
// do nothing
|
||||
} else if (action instanceof AddUsedTimeAction) {
|
||||
await dispatchAddUsedTime({ deviceId, action, cache })
|
||||
} else if (action instanceof AddUsedTimeActionVersion2) {
|
||||
@@ -73,7 +70,7 @@ export const dispatchAppLogicAction = async ({ action, deviceId, cache, eventHan
|
||||
} else if (action instanceof ReplyToKeyRequestAction) {
|
||||
await dispatchReplyToKeyRequestAction({ deviceId, action, cache, eventHandler })
|
||||
} else if (action instanceof RemoveInstalledAppsAction) {
|
||||
await dispatchRemoveInstalledApps({ deviceId, action, cache })
|
||||
// do nothing
|
||||
} else if (action instanceof SendKeyRequestAction) {
|
||||
await dispatchSendKeyRequestAction({ deviceId, action, cache })
|
||||
} else if (action instanceof SignOutAtDeviceAction) {
|
||||
@@ -81,7 +78,7 @@ export const dispatchAppLogicAction = async ({ action, deviceId, cache, eventHan
|
||||
} else if (action instanceof UpdateDeviceStatusAction) {
|
||||
await dispatchUpdateDeviceStatus({ deviceId, action, cache })
|
||||
} else if (action instanceof UpdateAppActivitiesAction) {
|
||||
await dispatchUpdateAppActivities({ deviceId, action, cache })
|
||||
// do nothing
|
||||
} else if (action instanceof TriedDisablingDeviceAdminAction) {
|
||||
await dispatchTriedDisablingDeviceAdmin({ deviceId, action, cache })
|
||||
} else if (action instanceof UpdateInstalledAppsAction) {
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { chunk } from 'lodash'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { UpdateAppActivitiesAction } from '../../../../action'
|
||||
import { AppActivityAttributes, maxActivityNameLength, maxPackageNameLength } from '../../../../database/appactivity'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception'
|
||||
|
||||
export async function dispatchUpdateAppActivities ({ deviceId, action, cache }: {
|
||||
deviceId: string
|
||||
action: UpdateAppActivitiesAction
|
||||
cache: Cache
|
||||
}) {
|
||||
action.updatedOrAdded.forEach((app) => {
|
||||
if (app.packageName.length > maxPackageNameLength) {
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'package name too long',
|
||||
dynamicMessage: 'package name too long: ' + app.packageName
|
||||
})
|
||||
}
|
||||
|
||||
if (app.activityName.length > maxActivityNameLength) {
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'activity name too long',
|
||||
dynamicMessage: 'activity name too long: ' + app.activityName
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (action.updatedOrAdded.length > 0) {
|
||||
const chuncks = chunk(action.updatedOrAdded, 500)
|
||||
|
||||
for (const items of chuncks) {
|
||||
await cache.database.appActivity.destroy({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId,
|
||||
[Sequelize.Op.or]: (
|
||||
items.map((item) => ({
|
||||
packageName: item.packageName,
|
||||
activityName: item.activityName
|
||||
}))
|
||||
)
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
}
|
||||
|
||||
await cache.database.appActivity.bulkCreate(
|
||||
action.updatedOrAdded.map((item): AppActivityAttributes => ({
|
||||
familyId: cache.familyId,
|
||||
deviceId,
|
||||
packageName: item.packageName,
|
||||
activityName: item.activityName,
|
||||
title: item.title
|
||||
})),
|
||||
{ transaction: cache.transaction }
|
||||
)
|
||||
}
|
||||
|
||||
if (action.removed.length > 0) {
|
||||
const chunks = chunk(action.removed, 500)
|
||||
|
||||
for (const items of chunks) {
|
||||
await cache.database.appActivity.destroy({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId,
|
||||
[Sequelize.Op.or]: (
|
||||
items.map((item) => ({
|
||||
packageName: item.packageName,
|
||||
activityName: item.activityName
|
||||
}))
|
||||
)
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
cache.devicesWithModifiedInstalledApps.add(deviceId)
|
||||
cache.incrementTriggeredSyncLevel(1)
|
||||
}
|
||||
@@ -43,17 +43,5 @@ export async function dispatchUpdateInstalledApps ({ deviceId, action, cache }:
|
||||
await upsert({ type: types.diff, data: action.diff })
|
||||
}
|
||||
|
||||
if (action.wipe) {
|
||||
await cache.database.app.destroy({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
cache.devicesWithModifiedInstalledApps.add(deviceId)
|
||||
}
|
||||
|
||||
cache.incrementTriggeredSyncLevel(1)
|
||||
}
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { difference, filter } from 'lodash'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { Database } from '../../../database'
|
||||
import { ClientDataStatusApps } from '../../../object/clientdatastatus'
|
||||
import { ServerInstalledAppsData } from '../../../object/serverdatastatus'
|
||||
import { GetServerDataStatusIllegalStateException } from './exception'
|
||||
import { FamilyEntry } from './family-entry'
|
||||
|
||||
export async function getAppList ({ database, transaction, familyEntry, appsStatus }: {
|
||||
database: Database
|
||||
transaction: Sequelize.Transaction
|
||||
familyEntry: FamilyEntry
|
||||
appsStatus: ClientDataStatusApps
|
||||
}): Promise<Array<ServerInstalledAppsData> | null> {
|
||||
const serverInstalledAppsVersions = (await database.device.findAll({
|
||||
where: {
|
||||
familyId: familyEntry.familyId
|
||||
},
|
||||
attributes: ['deviceId', 'installedAppsVersion'],
|
||||
transaction
|
||||
})).map((item) => ({
|
||||
deviceId: item.deviceId,
|
||||
installedAppsVersion: item.installedAppsVersion
|
||||
}))
|
||||
|
||||
const getServerInstalledAppsVersionByDeviceId = (deviceId: string) => {
|
||||
const entry = serverInstalledAppsVersions.find((item) => item.deviceId === deviceId)
|
||||
|
||||
if (!entry) {
|
||||
throw new GetServerDataStatusIllegalStateException({ staticMessage: 'could not find device entry' })
|
||||
}
|
||||
|
||||
return entry.installedAppsVersion
|
||||
}
|
||||
|
||||
const serverDeviceIds = serverInstalledAppsVersions.map((item) => item.deviceId)
|
||||
const clientDeviceIds = Object.keys(appsStatus)
|
||||
const addedDeviceIds = difference(serverDeviceIds, clientDeviceIds)
|
||||
const deviceIdsWhereInstalledAppsHaveChanged = filter(Object.keys(appsStatus), (deviceId) => {
|
||||
const installedAppsVersion = appsStatus[deviceId]
|
||||
|
||||
const serverEntry = serverInstalledAppsVersions.find((item) => item.deviceId === deviceId)
|
||||
|
||||
return !!serverEntry && serverEntry.installedAppsVersion !== installedAppsVersion
|
||||
})
|
||||
const idsOfDevicesWhereInstalledAppsMustBeSynced = [...addedDeviceIds, ...deviceIdsWhereInstalledAppsHaveChanged]
|
||||
|
||||
if (idsOfDevicesWhereInstalledAppsMustBeSynced.length > 0) {
|
||||
const [appsToSync, activitiesToSync] = await Promise.all([
|
||||
(async () => {
|
||||
return (await database.app.findAll({
|
||||
where: {
|
||||
familyId: familyEntry.familyId,
|
||||
deviceId: {
|
||||
[Sequelize.Op.in]: idsOfDevicesWhereInstalledAppsMustBeSynced
|
||||
}
|
||||
},
|
||||
attributes: [
|
||||
'deviceId',
|
||||
'packageName',
|
||||
'title',
|
||||
'isLaunchable',
|
||||
'recommendation'
|
||||
],
|
||||
transaction
|
||||
})).map((item) => ({
|
||||
deviceId: item.deviceId,
|
||||
packageName: item.packageName,
|
||||
title: item.title,
|
||||
isLaunchable: item.isLaunchable,
|
||||
recommendation: item.recommendation
|
||||
}))
|
||||
})(),
|
||||
(async () => {
|
||||
return (await database.appActivity.findAll({
|
||||
where: {
|
||||
familyId: familyEntry.familyId,
|
||||
deviceId: {
|
||||
[Sequelize.Op.in]: idsOfDevicesWhereInstalledAppsMustBeSynced
|
||||
}
|
||||
},
|
||||
attributes: [
|
||||
'deviceId',
|
||||
'packageName',
|
||||
'title',
|
||||
'activityName'
|
||||
],
|
||||
transaction
|
||||
})).map((item) => ({
|
||||
deviceId: item.deviceId,
|
||||
packageName: item.packageName,
|
||||
activityName: item.activityName,
|
||||
title: item.title
|
||||
}))
|
||||
})()
|
||||
])
|
||||
|
||||
return idsOfDevicesWhereInstalledAppsMustBeSynced.map((deviceId): ServerInstalledAppsData => ({
|
||||
deviceId,
|
||||
apps: appsToSync.filter((item) => item.deviceId === deviceId).map((item) => ({
|
||||
packageName: item.packageName,
|
||||
title: item.title,
|
||||
isLaunchable: item.isLaunchable,
|
||||
recommendation: item.recommendation
|
||||
})),
|
||||
activities: activitiesToSync.filter((item) => item.deviceId === deviceId).map((item) => ({
|
||||
p: item.packageName,
|
||||
c: item.activityName,
|
||||
t: item.title
|
||||
})),
|
||||
version: getServerInstalledAppsVersionByDeviceId(deviceId)
|
||||
}))
|
||||
} else return null // no changes
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import { getStatusMessage } from '../../../function/statusmessage'
|
||||
import { ClientDataStatus } from '../../../object/clientdatastatus'
|
||||
import { ServerDataStatus } from '../../../object/serverdatastatus'
|
||||
import { EventHandler } from '../../../monitoring/eventhandler'
|
||||
import { getAppList } from './app-list'
|
||||
import {
|
||||
getCategoryAssignedApps, getCategoryBaseDatas, getCategoryDataToSync,
|
||||
getRules, getTasks, getUsedTimes
|
||||
@@ -70,8 +69,6 @@ export const generateServerDataStatus = async ({
|
||||
result.users = await getUserList({ database, transaction, familyEntry })
|
||||
}
|
||||
|
||||
result.apps = await getAppList({ database, transaction, familyEntry, appsStatus: clientStatus.apps }) || undefined
|
||||
|
||||
const categoryDataToSync = await getCategoryDataToSync({ database, transaction, familyEntry, categoriesStatus: clientStatus.categories })
|
||||
|
||||
if (categoryDataToSync.removedCategoryIds.length > 0) {
|
||||
|
||||
+18
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Server } from 'http'
|
||||
import { pid } from 'process'
|
||||
import { createApi } from './api'
|
||||
import { config } from './config'
|
||||
import { VisibleConnectedDevicesManager } from './connected-devices'
|
||||
@@ -61,7 +62,22 @@ async function main () {
|
||||
pingInterval: config.pingInterval
|
||||
})
|
||||
|
||||
server.listen(process.env.PORT || 8080)
|
||||
const port = process.env.PORT || 8080
|
||||
|
||||
if (port === 'socketactivation') {
|
||||
if (process.env.LISTEN_FDS !== '1') {
|
||||
console.warn('expecting exactly one file descriptor for the socket activation')
|
||||
process.exit(1)
|
||||
} else if (process.env.LISTEN_PID !== pid.toString(10)) {
|
||||
console.warn('expecting handover of file descriptors to this process for the socket activation')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// the sockets are passed using fd 3 + index (with index = 0 in this case)
|
||||
server.listen({ fd: 3 })
|
||||
} else {
|
||||
server.listen(port)
|
||||
}
|
||||
|
||||
console.log('ready')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user