Compare commits
24 Commits
imp/settin
...
chore/adde
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abc923a95e | ||
|
|
097c281051 | ||
|
|
a1aaf9bd59 | ||
|
|
66edec201f | ||
|
|
7ce4ba12ab | ||
|
|
0959f3f926 | ||
|
|
cc68a5e9cc | ||
|
|
3ebf262b8e | ||
|
|
57c71357da | ||
|
|
3cb44e8dc8 | ||
|
|
11a31e5a6d | ||
|
|
5b00d83847 | ||
|
|
8e5d55ce7d | ||
|
|
7bb020d448 | ||
|
|
84f96b7db2 | ||
|
|
f87fba96d8 | ||
|
|
81d5c8559c | ||
|
|
945c52b770 | ||
|
|
f84d834295 | ||
|
|
01ce34f3d8 | ||
|
|
210a9a7aba | ||
|
|
6e37208f62 | ||
|
|
8188b5c381 | ||
|
|
0e21eacd52 |
473
worklenz-backend/package-lock.json
generated
473
worklenz-backend/package-lock.json
generated
@@ -33,7 +33,6 @@
|
|||||||
"express-rate-limit": "^6.8.0",
|
"express-rate-limit": "^6.8.0",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
"express-validator": "^6.15.0",
|
"express-validator": "^6.15.0",
|
||||||
"grunt-cli": "^1.5.0",
|
|
||||||
"helmet": "^6.2.0",
|
"helmet": "^6.2.0",
|
||||||
"hpp": "^0.2.3",
|
"hpp": "^0.2.3",
|
||||||
"http-errors": "^2.0.0",
|
"http-errors": "^2.0.0",
|
||||||
@@ -46,6 +45,7 @@
|
|||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"nanoid": "^3.3.6",
|
"nanoid": "^3.3.6",
|
||||||
"passport": "^0.7.0",
|
"passport": "^0.7.0",
|
||||||
|
"passport-custom": "^1.1.1",
|
||||||
"passport-google-oauth2": "^0.2.0",
|
"passport-google-oauth2": "^0.2.0",
|
||||||
"passport-google-oauth20": "^2.0.0",
|
"passport-google-oauth20": "^2.0.0",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
@@ -73,6 +73,7 @@
|
|||||||
"@types/compression": "^1.7.2",
|
"@types/compression": "^1.7.2",
|
||||||
"@types/connect-flash": "^0.0.37",
|
"@types/connect-flash": "^0.0.37",
|
||||||
"@types/cookie-parser": "^1.4.3",
|
"@types/cookie-parser": "^1.4.3",
|
||||||
|
"@types/cookie-signature": "^1.1.2",
|
||||||
"@types/cron": "^2.0.1",
|
"@types/cron": "^2.0.1",
|
||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/csurf": "^1.11.2",
|
"@types/csurf": "^1.11.2",
|
||||||
@@ -126,7 +127,7 @@
|
|||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.13.0",
|
"node": ">=20.0.0",
|
||||||
"npm": ">=8.11.0",
|
"npm": ">=8.11.0",
|
||||||
"yarn": "WARNING: Please use npm package manager instead of yarn"
|
"yarn": "WARNING: Please use npm package manager instead of yarn"
|
||||||
}
|
}
|
||||||
@@ -5445,6 +5446,16 @@
|
|||||||
"@types/express": "*"
|
"@types/express": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/cookie-signature": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cookie-signature/-/cookie-signature-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-2OhrZV2LVnUAXklUFwuYUTokalh/dUb8rqt70OW6ByMSxYpauPZ+kfNLknX3aJyjY5iu8i3cUyoLZP9Fn37tTg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/cors": {
|
"node_modules/@types/cors": {
|
||||||
"version": "2.8.19",
|
"version": "2.8.19",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
|
||||||
@@ -6455,30 +6466,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Python-2.0"
|
"license": "Python-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/array-each": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/array-flatten": {
|
"node_modules/array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/array-slice": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/array-union": {
|
"node_modules/array-union": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||||
@@ -6951,6 +6944,7 @@
|
|||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fill-range": "^7.1.1"
|
"fill-range": "^7.1.1"
|
||||||
@@ -8056,15 +8050,6 @@
|
|||||||
"npm": "1.2.8000 || >= 1.4.16"
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/detect-file": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/detect-libc": {
|
"node_modules/detect-libc": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
|
||||||
@@ -8924,18 +8909,6 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/expand-tilde": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
|
|
||||||
"integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"homedir-polyfill": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/expect": {
|
"node_modules/expect": {
|
||||||
"version": "28.1.3",
|
"version": "28.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz",
|
||||||
@@ -9088,12 +9061,6 @@
|
|||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/extend": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/fast-csv": {
|
"node_modules/fast-csv": {
|
||||||
"version": "4.3.6",
|
"version": "4.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz",
|
||||||
@@ -9222,6 +9189,7 @@
|
|||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
@@ -9287,46 +9255,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/findup-sync": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"detect-file": "^1.0.0",
|
|
||||||
"is-glob": "^4.0.0",
|
|
||||||
"micromatch": "^4.0.2",
|
|
||||||
"resolve-dir": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fined": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"expand-tilde": "^2.0.2",
|
|
||||||
"is-plain-object": "^2.0.3",
|
|
||||||
"object.defaults": "^1.1.0",
|
|
||||||
"object.pick": "^1.2.0",
|
|
||||||
"parse-filepath": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/flagged-respawn": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/flat-cache": {
|
"node_modules/flat-cache": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
|
||||||
@@ -9427,27 +9355,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/for-in": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/for-own": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"for-in": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/foreground-child": {
|
"node_modules/foreground-child": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||||
@@ -9845,48 +9752,6 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/global-modules": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"global-prefix": "^1.0.1",
|
|
||||||
"is-windows": "^1.0.1",
|
|
||||||
"resolve-dir": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/global-prefix": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"expand-tilde": "^2.0.2",
|
|
||||||
"homedir-polyfill": "^1.0.1",
|
|
||||||
"ini": "^1.3.4",
|
|
||||||
"is-windows": "^1.0.1",
|
|
||||||
"which": "^1.2.14"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/global-prefix/node_modules/which": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"isexe": "^2.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"which": "bin/which"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "11.12.0",
|
"version": "11.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||||
@@ -9943,34 +9808,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/grunt-cli": {
|
|
||||||
"version": "1.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.5.0.tgz",
|
|
||||||
"integrity": "sha512-rILKAFoU0dzlf22SUfDtq2R1fosChXXlJM5j7wI6uoW8gwmXDXzbUvirlKZSYCdXl3LXFbR+8xyS+WFo+b6vlA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"grunt-known-options": "~2.0.0",
|
|
||||||
"interpret": "~1.1.0",
|
|
||||||
"liftup": "~3.0.1",
|
|
||||||
"nopt": "~5.0.0",
|
|
||||||
"v8flags": "^4.0.1"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"grunt": "bin/grunt"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/grunt-known-options": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/has-flag": {
|
"node_modules/has-flag": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
@@ -10042,18 +9879,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "https://www.highcharts.com/license"
|
"license": "https://www.highcharts.com/license"
|
||||||
},
|
},
|
||||||
"node_modules/homedir-polyfill": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"parse-passwd": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/hpp": {
|
"node_modules/hpp": {
|
||||||
"version": "0.2.3",
|
"version": "0.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/hpp/-/hpp-0.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/hpp/-/hpp-0.2.3.tgz",
|
||||||
@@ -10263,12 +10088,6 @@
|
|||||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/interpret": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-CLM8SNMDu7C5psFCn6Wg/tgpj/bKAg7hc2gWqcuR9OD5Ft9PhBpIu8PLicPeis+xDd6YX2ncI8MCA64I9tftIA==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/ipaddr.js": {
|
"node_modules/ipaddr.js": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
@@ -10278,19 +10097,6 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-absolute": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"is-relative": "^1.0.0",
|
|
||||||
"is-windows": "^1.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-arrayish": {
|
"node_modules/is-arrayish": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||||
@@ -10352,6 +10158,7 @@
|
|||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
@@ -10380,6 +10187,7 @@
|
|||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-extglob": "^2.1.1"
|
"is-extglob": "^2.1.1"
|
||||||
@@ -10392,6 +10200,7 @@
|
|||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
@@ -10407,18 +10216,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-plain-object": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"isobject": "^3.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-promise": {
|
"node_modules/is-promise": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
|
||||||
@@ -10443,18 +10240,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-relative": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"is-unc-path": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-stream": {
|
"node_modules/is-stream": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
@@ -10467,27 +10252,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-unc-path": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"unc-path-regex": "^0.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-windows": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/isarray": {
|
"node_modules/isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
@@ -10498,17 +10262,9 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/isobject": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/istanbul-lib-coverage": {
|
"node_modules/istanbul-lib-coverage": {
|
||||||
"version": "3.2.2",
|
"version": "3.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
|
||||||
@@ -11526,15 +11282,6 @@
|
|||||||
"json-buffer": "3.0.1"
|
"json-buffer": "3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/kind-of": {
|
|
||||||
"version": "6.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
|
||||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/kleur": {
|
"node_modules/kleur": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
|
||||||
@@ -11626,25 +11373,6 @@
|
|||||||
"immediate": "~3.0.5"
|
"immediate": "~3.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/liftup": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"extend": "^3.0.2",
|
|
||||||
"findup-sync": "^4.0.0",
|
|
||||||
"fined": "^1.2.0",
|
|
||||||
"flagged-respawn": "^1.0.1",
|
|
||||||
"is-plain-object": "^2.0.4",
|
|
||||||
"object.map": "^1.0.1",
|
|
||||||
"rechoir": "^0.7.0",
|
|
||||||
"resolve": "^1.19.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/lines-and-columns": {
|
"node_modules/lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
@@ -11883,18 +11611,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/make-iterator": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"kind-of": "^6.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/makeerror": {
|
"node_modules/makeerror": {
|
||||||
"version": "1.0.12",
|
"version": "1.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
|
||||||
@@ -11905,15 +11621,6 @@
|
|||||||
"tmpl": "1.0.5"
|
"tmpl": "1.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/map-cache": {
|
|
||||||
"version": "0.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
|
|
||||||
"integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/math-intrinsics": {
|
"node_modules/math-intrinsics": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
@@ -11971,6 +11678,7 @@
|
|||||||
"version": "4.0.8",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"braces": "^3.0.3",
|
"braces": "^3.0.3",
|
||||||
@@ -12418,46 +12126,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/object.defaults": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"array-each": "^1.0.1",
|
|
||||||
"array-slice": "^1.0.0",
|
|
||||||
"for-own": "^1.0.0",
|
|
||||||
"isobject": "^3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object.map": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"for-own": "^1.0.0",
|
|
||||||
"make-iterator": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object.pick": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"isobject": "^3.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/on-finished": {
|
"node_modules/on-finished": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
@@ -12620,20 +12288,6 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/parse-filepath": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"is-absolute": "^1.0.0",
|
|
||||||
"map-cache": "^0.2.0",
|
|
||||||
"path-root": "^0.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/parse-json": {
|
"node_modules/parse-json": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
|
||||||
@@ -12653,15 +12307,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/parse-passwd": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/parse-srcset": {
|
"node_modules/parse-srcset": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
|
||||||
@@ -12695,6 +12340,18 @@
|
|||||||
"url": "https://github.com/sponsors/jaredhanson"
|
"url": "https://github.com/sponsors/jaredhanson"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/passport-custom": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-custom/-/passport-custom-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-/2m7jUGxmCYvoqenLB9UrmkCgPt64h8ZtV+UtuQklZ/Tn1NpKBeOorCYkB/8lMRoiZ5hUrCoMmDtxCS/d38mlg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"passport-strategy": "1.x.x"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/passport-google-oauth2": {
|
"node_modules/passport-google-oauth2": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/passport-google-oauth2/-/passport-google-oauth2-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/passport-google-oauth2/-/passport-google-oauth2-0.2.0.tgz",
|
||||||
@@ -12800,27 +12457,6 @@
|
|||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/path-root": {
|
|
||||||
"version": "0.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
|
|
||||||
"integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"path-root-regex": "^0.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path-root-regex": {
|
|
||||||
"version": "0.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
|
|
||||||
"integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path-scurry": {
|
"node_modules/path-scurry": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||||
@@ -12968,6 +12604,7 @@
|
|||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
@@ -13563,18 +13200,6 @@
|
|||||||
"node": ">=8.10.0"
|
"node": ">=8.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rechoir": {
|
|
||||||
"version": "0.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
|
|
||||||
"integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"resolve": "^1.9.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/redis": {
|
"node_modules/redis": {
|
||||||
"version": "4.7.1",
|
"version": "4.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/redis/-/redis-4.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/redis/-/redis-4.7.1.tgz",
|
||||||
@@ -13726,19 +13351,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/resolve-dir": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"expand-tilde": "^2.0.0",
|
|
||||||
"global-modules": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/resolve-from": {
|
"node_modules/resolve-from": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
@@ -14974,6 +14586,7 @@
|
|||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-number": "^7.0.0"
|
"is-number": "^7.0.0"
|
||||||
@@ -15494,15 +15107,6 @@
|
|||||||
"integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==",
|
"integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/unc-path-regex": {
|
|
||||||
"version": "0.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
|
|
||||||
"integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.26.5",
|
"version": "5.26.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
@@ -15732,15 +15336,6 @@
|
|||||||
"node": ">=10.12.0"
|
"node": ">=10.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/v8flags": {
|
|
||||||
"version": "4.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz",
|
|
||||||
"integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10.13.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/validator": {
|
"node_modules/validator": {
|
||||||
"version": "13.15.15",
|
"version": "13.15.15",
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz",
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz",
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"nanoid": "^3.3.6",
|
"nanoid": "^3.3.6",
|
||||||
"passport": "^0.7.0",
|
"passport": "^0.7.0",
|
||||||
|
"passport-custom": "^1.1.1",
|
||||||
"passport-google-oauth2": "^0.2.0",
|
"passport-google-oauth2": "^0.2.0",
|
||||||
"passport-google-oauth20": "^2.0.0",
|
"passport-google-oauth20": "^2.0.0",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
@@ -107,6 +108,7 @@
|
|||||||
"@types/compression": "^1.7.2",
|
"@types/compression": "^1.7.2",
|
||||||
"@types/connect-flash": "^0.0.37",
|
"@types/connect-flash": "^0.0.37",
|
||||||
"@types/cookie-parser": "^1.4.3",
|
"@types/cookie-parser": "^1.4.3",
|
||||||
|
"@types/cookie-signature": "^1.1.2",
|
||||||
"@types/cron": "^2.0.1",
|
"@types/cron": "^2.0.1",
|
||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/csurf": "^1.11.2",
|
"@types/csurf": "^1.11.2",
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import bcrypt from "bcrypt";
|
import bcrypt from "bcrypt";
|
||||||
|
import passport from "passport";
|
||||||
|
import {NextFunction} from "express";
|
||||||
|
|
||||||
import {sendResetEmail, sendResetSuccessEmail} from "../shared/email-templates";
|
import {sendResetEmail, sendResetSuccessEmail} from "../shared/email-templates";
|
||||||
|
|
||||||
@@ -181,4 +183,162 @@ export default class AuthController extends WorklenzControllerBase {
|
|||||||
res.status(500).send(new ServerResponse(false, null, DEFAULT_ERROR_MESSAGE));
|
res.status(500).send(new ServerResponse(false, null, DEFAULT_ERROR_MESSAGE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static googleMobileAuthPassport(req: IWorkLenzRequest, res: IWorkLenzResponse, next: NextFunction) {
|
||||||
|
|
||||||
|
const mobileOptions = {
|
||||||
|
session: true,
|
||||||
|
failureFlash: true,
|
||||||
|
failWithError: false
|
||||||
|
};
|
||||||
|
|
||||||
|
passport.authenticate("google-mobile", mobileOptions, (err: any, user: any, info: any) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).send({
|
||||||
|
done: false,
|
||||||
|
message: "Authentication failed",
|
||||||
|
body: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return res.status(400).send({
|
||||||
|
done: false,
|
||||||
|
message: info?.message || "Authentication failed",
|
||||||
|
body: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Log the user in (create session)
|
||||||
|
req.login(user, (loginErr) => {
|
||||||
|
if (loginErr) {
|
||||||
|
return res.status(500).send({
|
||||||
|
done: false,
|
||||||
|
message: "Session creation failed",
|
||||||
|
body: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add build version
|
||||||
|
user.build_v = FileConstants.getRelease();
|
||||||
|
|
||||||
|
// Ensure session is saved and cookie is set
|
||||||
|
req.session.save((saveErr) => {
|
||||||
|
if (saveErr) {
|
||||||
|
return res.status(500).send({
|
||||||
|
done: false,
|
||||||
|
message: "Session save failed",
|
||||||
|
body: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get session cookie details
|
||||||
|
const sessionName = process.env.SESSION_NAME || 'connect.sid';
|
||||||
|
|
||||||
|
// Return response with session info for mobile app to handle
|
||||||
|
res.setHeader('X-Session-ID', req.sessionID);
|
||||||
|
res.setHeader('X-Session-Name', sessionName);
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
done: true,
|
||||||
|
message: "Login successful",
|
||||||
|
user,
|
||||||
|
authenticated: true,
|
||||||
|
sessionId: req.sessionID,
|
||||||
|
sessionName: sessionName,
|
||||||
|
newSessionId: req.sessionID
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}); // Close login callback
|
||||||
|
})(req, res, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@HandleExceptions({logWithError: "body"})
|
||||||
|
public static async googleMobileAuth(req: IWorkLenzRequest, res: IWorkLenzResponse) {
|
||||||
|
const {idToken} = req.body;
|
||||||
|
|
||||||
|
if (!idToken) {
|
||||||
|
return res.status(400).send(new ServerResponse(false, null, "ID token is required"));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`https://oauth2.googleapis.com/tokeninfo?id_token=${idToken}`);
|
||||||
|
const profile = response.data;
|
||||||
|
|
||||||
|
// Validate token audience (client ID) - accept web, Android, and iOS client IDs
|
||||||
|
const allowedClientIds = [
|
||||||
|
process.env.GOOGLE_CLIENT_ID, // Web client ID
|
||||||
|
process.env.GOOGLE_ANDROID_CLIENT_ID, // Android client ID
|
||||||
|
process.env.GOOGLE_IOS_CLIENT_ID, // iOS client ID
|
||||||
|
].filter(Boolean); // Remove undefined values
|
||||||
|
|
||||||
|
console.log("Token audience (aud):", profile.aud);
|
||||||
|
console.log("Allowed client IDs:", allowedClientIds);
|
||||||
|
console.log("Environment variables check:");
|
||||||
|
console.log("- GOOGLE_CLIENT_ID:", process.env.GOOGLE_CLIENT_ID ? "Set" : "Not set");
|
||||||
|
console.log("- GOOGLE_ANDROID_CLIENT_ID:", process.env.GOOGLE_ANDROID_CLIENT_ID ? "Set" : "Not set");
|
||||||
|
console.log("- GOOGLE_IOS_CLIENT_ID:", process.env.GOOGLE_IOS_CLIENT_ID ? "Set" : "Not set");
|
||||||
|
|
||||||
|
if (!allowedClientIds.includes(profile.aud)) {
|
||||||
|
return res.status(400).send(new ServerResponse(false, null, "Invalid token audience"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate token issuer
|
||||||
|
if (!["https://accounts.google.com", "accounts.google.com"].includes(profile.iss)) {
|
||||||
|
return res.status(400).send(new ServerResponse(false, null, "Invalid token issuer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check token expiry
|
||||||
|
if (Date.now() >= profile.exp * 1000) {
|
||||||
|
return res.status(400).send(new ServerResponse(false, null, "Token expired"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!profile.email_verified) {
|
||||||
|
return res.status(400).send(new ServerResponse(false, null, "Email not verified"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for existing local account
|
||||||
|
const localAccountResult = await db.query("SELECT 1 FROM users WHERE email = $1 AND password IS NOT NULL AND is_deleted IS FALSE;", [profile.email]);
|
||||||
|
if (localAccountResult.rowCount) {
|
||||||
|
return res.status(400).send(new ServerResponse(false, null, `No Google account exists for email ${profile.email}.`));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user exists
|
||||||
|
const userResult = await db.query(
|
||||||
|
"SELECT id, google_id, name, email, active_team FROM users WHERE google_id = $1 OR email = $2;",
|
||||||
|
[profile.sub, profile.email]
|
||||||
|
);
|
||||||
|
|
||||||
|
let user: any;
|
||||||
|
if (userResult.rowCount) {
|
||||||
|
// Existing user - login
|
||||||
|
user = userResult.rows[0];
|
||||||
|
} else {
|
||||||
|
// New user - register
|
||||||
|
const googleUserData = {
|
||||||
|
id: profile.sub,
|
||||||
|
displayName: profile.name,
|
||||||
|
email: profile.email,
|
||||||
|
picture: profile.picture
|
||||||
|
};
|
||||||
|
|
||||||
|
const registerResult = await db.query("SELECT register_google_user($1) AS user;", [JSON.stringify(googleUserData)]);
|
||||||
|
user = registerResult.rows[0].user;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create session
|
||||||
|
req.login(user, (err) => {
|
||||||
|
if (err) {
|
||||||
|
log_error(err);
|
||||||
|
return res.status(500).send(new ServerResponse(false, null, "Authentication failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
user.build_v = FileConstants.getRelease();
|
||||||
|
return res.status(200).send(new AuthResponse("Login Successful!", true, user, null, "User successfully logged in"));
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
log_error(error);
|
||||||
|
return res.status(400).send(new ServerResponse(false, null, "Invalid ID token"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import db from "../config/db";
|
|||||||
import {ServerResponse} from "../models/server-response";
|
import {ServerResponse} from "../models/server-response";
|
||||||
import WorklenzControllerBase from "./worklenz-controller-base";
|
import WorklenzControllerBase from "./worklenz-controller-base";
|
||||||
import HandleExceptions from "../decorators/handle-exceptions";
|
import HandleExceptions from "../decorators/handle-exceptions";
|
||||||
import {TASK_PRIORITY_COLOR_ALPHA, WorklenzColorCodes} from "../shared/constants";
|
import {TASK_PRIORITY_COLOR_ALPHA, WorklenzColorCodes, WorklenzColorShades} from "../shared/constants";
|
||||||
|
|
||||||
export default class LabelsController extends WorklenzControllerBase {
|
export default class LabelsController extends WorklenzControllerBase {
|
||||||
@HandleExceptions()
|
@HandleExceptions()
|
||||||
@@ -73,7 +73,7 @@ export default class LabelsController extends WorklenzControllerBase {
|
|||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
AND team_id = $2;`;
|
AND team_id = $2;`;
|
||||||
|
|
||||||
if (!WorklenzColorCodes.includes(req.body.color))
|
if (!Object.values(WorklenzColorShades).flat().includes(req.body.color))
|
||||||
return res.status(400).send(new ServerResponse(false, null));
|
return res.status(400).send(new ServerResponse(false, null));
|
||||||
|
|
||||||
const result = await db.query(q, [req.params.id, req.user?.team_id, req.body.color]);
|
const result = await db.query(q, [req.params.id, req.user?.team_id, req.body.color]);
|
||||||
@@ -92,7 +92,7 @@ export default class LabelsController extends WorklenzControllerBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req.body.color) {
|
if (req.body.color) {
|
||||||
if (!WorklenzColorCodes.includes(req.body.color))
|
if (!Object.values(WorklenzColorShades).flat().includes(req.body.color))
|
||||||
return res.status(400).send(new ServerResponse(false, null));
|
return res.status(400).send(new ServerResponse(false, null));
|
||||||
updates.push(`color_code = $${paramIndex++}`);
|
updates.push(`color_code = $${paramIndex++}`);
|
||||||
values.push(req.body.color);
|
values.push(req.body.color);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export default class TaskCommentsController extends WorklenzControllerBase {
|
|||||||
const q = `
|
const q = `
|
||||||
INSERT INTO task_comment_attachments (name, type, size, task_id, comment_id, team_id, project_id)
|
INSERT INTO task_comment_attachments (name, type, size, task_id, comment_id, team_id, project_id)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||||
RETURNING id, name, type, task_id, comment_id, created_at,
|
RETURNING id, name, type, task_id, comment_id, created_at,
|
||||||
CONCAT($8::TEXT, '/', team_id, '/', project_id, '/', task_id, '/', comment_id, '/', id, '.', type) AS url;
|
CONCAT($8::TEXT, '/', team_id, '/', project_id, '/', task_id, '/', comment_id, '/', id, '.', type) AS url;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -217,7 +217,43 @@ export default class TaskCommentsController extends WorklenzControllerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(200).send(new ServerResponse(true, data.comment));
|
// Get user avatar URL from database
|
||||||
|
const avatarQuery = `SELECT avatar_url FROM users WHERE id = $1`;
|
||||||
|
const avatarResult = await db.query(avatarQuery, [req.user?.id]);
|
||||||
|
const avatarUrl = avatarResult.rows[0]?.avatar_url || "";
|
||||||
|
|
||||||
|
// Get comment details including created_at
|
||||||
|
const commentQuery = `SELECT created_at FROM task_comments WHERE id = $1`;
|
||||||
|
const commentResult = await db.query(commentQuery, [response.id]);
|
||||||
|
const commentData = commentResult.rows[0];
|
||||||
|
|
||||||
|
// Get attachments if any
|
||||||
|
const attachmentsQuery = `SELECT id, name, type, size FROM task_comment_attachments WHERE comment_id = $1`;
|
||||||
|
const attachmentsResult = await db.query(attachmentsQuery, [response.id]);
|
||||||
|
const commentAttachments = attachmentsResult.rows.map(att => ({
|
||||||
|
id: att.id,
|
||||||
|
name: att.name,
|
||||||
|
type: att.type,
|
||||||
|
size: att.size
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
const commentdata = {
|
||||||
|
attachments: commentAttachments,
|
||||||
|
avatar_url: avatarUrl,
|
||||||
|
content: req.body.content,
|
||||||
|
created_at: commentData?.created_at || new Date().toISOString(),
|
||||||
|
edit: false,
|
||||||
|
id: response.id,
|
||||||
|
member_name: req.user?.name || "",
|
||||||
|
mentions: mentions || [],
|
||||||
|
rawContent: req.body.content,
|
||||||
|
reactions: { likes: {} },
|
||||||
|
team_member_id: req.user?.team_member_id || "",
|
||||||
|
user_id: req.user?.id || ""
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(200).send(new ServerResponse(true, commentdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
@HandleExceptions()
|
@HandleExceptions()
|
||||||
@@ -530,17 +566,17 @@ export default class TaskCommentsController extends WorklenzControllerBase {
|
|||||||
for (const attachment of attachments) {
|
for (const attachment of attachments) {
|
||||||
if (req.user?.subscription_status === "free" && req.user?.owner_id) {
|
if (req.user?.subscription_status === "free" && req.user?.owner_id) {
|
||||||
const limits = await getFreePlanSettings();
|
const limits = await getFreePlanSettings();
|
||||||
|
|
||||||
const usedStorage = await getUsedStorage(req.user?.owner_id);
|
const usedStorage = await getUsedStorage(req.user?.owner_id);
|
||||||
if ((parseInt(usedStorage) + attachment.size) > megabytesToBytes(parseInt(limits.free_tier_storage))) {
|
if ((parseInt(usedStorage) + attachment.size) > megabytesToBytes(parseInt(limits.free_tier_storage))) {
|
||||||
return res.status(200).send(new ServerResponse(false, [], `Sorry, the free plan cannot exceed ${limits.free_tier_storage}MB of storage.`));
|
return res.status(200).send(new ServerResponse(false, [], `Sorry, the free plan cannot exceed ${limits.free_tier_storage}MB of storage.`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const q = `
|
const q = `
|
||||||
INSERT INTO task_comment_attachments (name, type, size, task_id, comment_id, team_id, project_id)
|
INSERT INTO task_comment_attachments (name, type, size, task_id, comment_id, team_id, project_id)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||||
RETURNING id, name, type, task_id, comment_id, created_at,
|
RETURNING id, name, type, task_id, comment_id, created_at,
|
||||||
CONCAT($8::TEXT, '/', team_id, '/', project_id, '/', task_id, '/', comment_id, '/', id, '.', type) AS url;
|
CONCAT($8::TEXT, '/', team_id, '/', project_id, '/', task_id, '/', comment_id, '/', id, '.', type) AS url;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import session from "express-session";
|
import session from "express-session";
|
||||||
import db from "../config/db";
|
import db from "../config/db";
|
||||||
import { isProduction } from "../shared/utils";
|
import { isProduction } from "../shared/utils";
|
||||||
|
import * as cookieSignature from "cookie-signature";
|
||||||
|
import { randomBytes } from "crypto";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const pgSession = require("connect-pg-simple")(session);
|
const pgSession = require("connect-pg-simple")(session);
|
||||||
|
|
||||||
export default session({
|
const sessionConfig = {
|
||||||
name: process.env.SESSION_NAME,
|
name: process.env.SESSION_NAME,
|
||||||
secret: process.env.SESSION_SECRET || "development-secret-key",
|
secret: process.env.SESSION_SECRET || "development-secret-key",
|
||||||
proxy: false,
|
proxy: false,
|
||||||
@@ -18,10 +20,56 @@ export default session({
|
|||||||
}),
|
}),
|
||||||
cookie: {
|
cookie: {
|
||||||
path: "/",
|
path: "/",
|
||||||
// secure: isProduction(),
|
httpOnly: true,
|
||||||
// httpOnly: isProduction(),
|
// For mobile app support in production, use "none", for local development use "lax"
|
||||||
// sameSite: "none",
|
sameSite: "lax" as const,
|
||||||
// domain: isProduction() ? ".worklenz.com" : undefined,
|
// Secure only in production (HTTPS required for sameSite: "none")
|
||||||
|
secure: false,
|
||||||
|
domain: undefined,
|
||||||
maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days
|
maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days
|
||||||
|
},
|
||||||
|
// Custom session ID handling for mobile apps
|
||||||
|
genid: () => {
|
||||||
|
return randomBytes(24).toString("base64url");
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const sessionMiddleware = session(sessionConfig);
|
||||||
|
|
||||||
|
// Enhanced session middleware that supports both cookies and headers for mobile apps
|
||||||
|
export default (req: any, res: any, next: any) => {
|
||||||
|
// Check if mobile app is sending session ID via header (fallback for cookie issues)
|
||||||
|
const headerSessionId = req.headers["x-session-id"];
|
||||||
|
const headerSessionName = req.headers["x-session-name"];
|
||||||
|
|
||||||
|
// Only process headers if they exist AND there's no existing valid session cookie
|
||||||
|
if (headerSessionId && headerSessionName) {
|
||||||
|
const secret = process.env.SESSION_SECRET || "development-secret-key";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create a signed cookie using the session secret
|
||||||
|
const signedSessionId = `s:${cookieSignature.sign(headerSessionId, secret)}`;
|
||||||
|
const encodedSignedId = encodeURIComponent(signedSessionId);
|
||||||
|
const sessionCookie = `${headerSessionName}=${encodedSignedId}`;
|
||||||
|
|
||||||
|
if (req.headers.cookie) {
|
||||||
|
// Replace existing session cookie while keeping other cookies
|
||||||
|
req.headers.cookie = req.headers.cookie
|
||||||
|
.split(";")
|
||||||
|
.filter((cookie: string) => !cookie.trim().startsWith(headerSessionName))
|
||||||
|
.concat(sessionCookie)
|
||||||
|
.join(";");
|
||||||
|
} else {
|
||||||
|
// Set the session cookie from header
|
||||||
|
req.headers.cookie = sessionCookie;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Fallback to the old method
|
||||||
|
const sessionCookie = `${headerSessionName}=s%3A${headerSessionId}`;
|
||||||
|
req.headers.cookie = sessionCookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always call the original session middleware (handles both cookie and header-converted cases)
|
||||||
|
sessionMiddleware(req, res, next);
|
||||||
|
};
|
||||||
@@ -8,7 +8,7 @@ import {PASSWORD_POLICY} from "../../shared/constants";
|
|||||||
function isStrongPassword(password: string) {
|
function isStrongPassword(password: string) {
|
||||||
if (!isProduction()) return true;
|
if (!isProduction()) return true;
|
||||||
const strength = PasswordStrengthChecker.validate(password);
|
const strength = PasswordStrengthChecker.validate(password);
|
||||||
return strength.value >= 2 && strength.length < 32;
|
return strength.value >= 2 && strength.length <= 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function (req: Request, res: Response, next: NextFunction) {
|
export default function (req: Request, res: Response, next: NextFunction) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {deserialize} from "./deserialize";
|
|||||||
import {serialize} from "./serialize";
|
import {serialize} from "./serialize";
|
||||||
|
|
||||||
import GoogleLogin from "./passport-strategies/passport-google";
|
import GoogleLogin from "./passport-strategies/passport-google";
|
||||||
|
import GoogleMobileLogin from "./passport-strategies/passport-google-mobile";
|
||||||
import LocalLogin from "./passport-strategies/passport-local-login";
|
import LocalLogin from "./passport-strategies/passport-local-login";
|
||||||
import LocalSignup from "./passport-strategies/passport-local-signup";
|
import LocalSignup from "./passport-strategies/passport-local-signup";
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ export default (passport: PassportStatic) => {
|
|||||||
passport.use("local-login", LocalLogin);
|
passport.use("local-login", LocalLogin);
|
||||||
passport.use("local-signup", LocalSignup);
|
passport.use("local-signup", LocalSignup);
|
||||||
passport.use(GoogleLogin);
|
passport.use(GoogleLogin);
|
||||||
|
passport.use("google-mobile", GoogleMobileLogin);
|
||||||
passport.serializeUser(serialize);
|
passport.serializeUser(serialize);
|
||||||
passport.deserializeUser(deserialize);
|
passport.deserializeUser(deserialize);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
import { Strategy as CustomStrategy } from "passport-custom";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Request } from "express";
|
||||||
|
import db from "../../config/db";
|
||||||
|
import { log_error } from "../../shared/utils";
|
||||||
|
import { ERROR_KEY } from "./passport-constants";
|
||||||
|
|
||||||
|
interface GoogleTokenProfile {
|
||||||
|
sub: string;
|
||||||
|
email: string;
|
||||||
|
name: string;
|
||||||
|
picture: string;
|
||||||
|
email_verified: boolean;
|
||||||
|
aud: string;
|
||||||
|
iss: string;
|
||||||
|
exp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleMobileGoogleAuth(req: Request, done: any) {
|
||||||
|
try {
|
||||||
|
const { idToken } = req.body;
|
||||||
|
|
||||||
|
if (!idToken) {
|
||||||
|
return done(null, false, { message: "ID token is required" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify Google ID token
|
||||||
|
const response = await axios.get(
|
||||||
|
`https://oauth2.googleapis.com/tokeninfo?id_token=${idToken}`
|
||||||
|
);
|
||||||
|
const profile: GoogleTokenProfile = response.data;
|
||||||
|
|
||||||
|
// Validate token audience (client ID)
|
||||||
|
const allowedClientIds = [
|
||||||
|
process.env.GOOGLE_CLIENT_ID,
|
||||||
|
process.env.GOOGLE_ANDROID_CLIENT_ID,
|
||||||
|
process.env.GOOGLE_IOS_CLIENT_ID,
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
|
if (!allowedClientIds.includes(profile.aud)) {
|
||||||
|
return done(null, false, { message: "Invalid token audience" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate token issuer
|
||||||
|
if (
|
||||||
|
!["https://accounts.google.com", "accounts.google.com"].includes(
|
||||||
|
profile.iss
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return done(null, false, { message: "Invalid token issuer" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check token expiry
|
||||||
|
if (Date.now() >= profile.exp * 1000) {
|
||||||
|
return done(null, false, { message: "Token expired" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!profile.email_verified) {
|
||||||
|
return done(null, false, { message: "Email not verified" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for existing local account
|
||||||
|
const localAccountResult = await db.query(
|
||||||
|
"SELECT 1 FROM users WHERE email = $1 AND password IS NOT NULL AND is_deleted IS FALSE;",
|
||||||
|
[profile.email]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (localAccountResult.rowCount) {
|
||||||
|
const message = `No Google account exists for email ${profile.email}.`;
|
||||||
|
return done(null, false, { message });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user exists
|
||||||
|
const userResult = await db.query(
|
||||||
|
"SELECT id, google_id, name, email, active_team FROM users WHERE google_id = $1 OR email = $2;",
|
||||||
|
[profile.sub, profile.email]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (userResult.rowCount) {
|
||||||
|
// Existing user - login
|
||||||
|
const user = userResult.rows[0];
|
||||||
|
return done(null, user, { message: "User successfully logged in" });
|
||||||
|
}
|
||||||
|
// New user - register
|
||||||
|
const googleUserData = {
|
||||||
|
id: profile.sub,
|
||||||
|
displayName: profile.name,
|
||||||
|
email: profile.email,
|
||||||
|
picture: profile.picture,
|
||||||
|
};
|
||||||
|
|
||||||
|
const registerResult = await db.query(
|
||||||
|
"SELECT register_google_user($1) AS user;",
|
||||||
|
[JSON.stringify(googleUserData)]
|
||||||
|
);
|
||||||
|
const { user } = registerResult.rows[0];
|
||||||
|
|
||||||
|
return done(null, user, {
|
||||||
|
message: "User successfully registered and logged in",
|
||||||
|
});
|
||||||
|
} catch (error: any) {
|
||||||
|
log_error(error);
|
||||||
|
if (error.response?.status === 400) {
|
||||||
|
return done(null, false, { message: "Invalid ID token" });
|
||||||
|
}
|
||||||
|
return done(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new CustomStrategy(handleMobileGoogleAuth);
|
||||||
@@ -8,6 +8,7 @@ import resetEmailValidator from "../../middlewares/validators/reset-email-valida
|
|||||||
import updatePasswordValidator from "../../middlewares/validators/update-password-validator";
|
import updatePasswordValidator from "../../middlewares/validators/update-password-validator";
|
||||||
import passwordValidator from "../../middlewares/validators/password-validator";
|
import passwordValidator from "../../middlewares/validators/password-validator";
|
||||||
import safeControllerFunction from "../../shared/safe-controller-function";
|
import safeControllerFunction from "../../shared/safe-controller-function";
|
||||||
|
import FileConstants from "../../shared/file-constants";
|
||||||
|
|
||||||
const authRouter = express.Router();
|
const authRouter = express.Router();
|
||||||
|
|
||||||
@@ -55,6 +56,9 @@ authRouter.get("/google/verify", (req, res) => {
|
|||||||
})(req, res);
|
})(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mobile Google Sign-In using Passport strategy
|
||||||
|
authRouter.post("/google/mobile", AuthController.googleMobileAuthPassport);
|
||||||
|
|
||||||
// Passport logout
|
// Passport logout
|
||||||
authRouter.get("/logout", AuthController.logout);
|
authRouter.get("/logout", AuthController.logout);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user