mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-09 03:04:08 -04:00
Inital passportjs integration
This commit is contained in:
parent
911c854365
commit
e1ddb95250
431
package-lock.json
generated
431
package-lock.json
generated
@ -11,9 +11,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"express-session": "^1.17.3",
|
||||||
"graceful-fs": "^4.2.10",
|
"graceful-fs": "^4.2.10",
|
||||||
"htmlparser2": "^8.0.1",
|
"htmlparser2": "^8.0.1",
|
||||||
"node-tone": "^1.0.1",
|
"node-tone": "^1.0.1",
|
||||||
|
"passport": "^0.6.0",
|
||||||
|
"passport-google-oauth20": "^2.0.0",
|
||||||
|
"passport-jwt": "^4.0.1",
|
||||||
|
"passport-local": "^1.0.0",
|
||||||
"socket.io": "^4.5.4",
|
"socket.io": "^4.5.4",
|
||||||
"xml2js": "^0.4.23"
|
"xml2js": "^0.4.23"
|
||||||
},
|
},
|
||||||
@ -111,6 +116,14 @@
|
|||||||
"node": "^4.5.0 || >= 5.9"
|
"node": "^4.5.0 || >= 5.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/base64url": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
@ -165,6 +178,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/buffer-equal-constant-time": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@ -357,6 +375,14 @@
|
|||||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ecdsa-sig-formatter": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ee-first": {
|
"node_modules/ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
@ -492,6 +518,32 @@
|
|||||||
"node": ">= 0.10.0"
|
"node": ">= 0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/express-session": {
|
||||||
|
"version": "1.17.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz",
|
||||||
|
"integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==",
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": "0.4.2",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"on-headers": "~1.0.2",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"safe-buffer": "5.2.1",
|
||||||
|
"uid-safe": "~2.1.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express-session/node_modules/cookie": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||||
|
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
@ -754,6 +806,75 @@
|
|||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsonwebtoken": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
|
||||||
|
"dependencies": {
|
||||||
|
"jws": "^3.2.2",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"ms": "^2.1.1",
|
||||||
|
"semver": "^7.3.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12",
|
||||||
|
"npm": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jsonwebtoken/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
},
|
||||||
|
"node_modules/jsonwebtoken/node_modules/semver": {
|
||||||
|
"version": "7.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jwa": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-equal-constant-time": "1.0.1",
|
||||||
|
"ecdsa-sig-formatter": "1.0.11",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jws": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
||||||
|
"dependencies": {
|
||||||
|
"jwa": "^1.4.1",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
|
},
|
||||||
|
"node_modules/lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/media-typer": {
|
"node_modules/media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@ -902,6 +1023,11 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/oauth": {
|
||||||
|
"version": "0.9.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
|
||||||
|
"integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@ -929,6 +1055,14 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/on-headers": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/parseurl": {
|
"node_modules/parseurl": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
@ -937,11 +1071,91 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/passport": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
|
||||||
|
"dependencies": {
|
||||||
|
"passport-strategy": "1.x.x",
|
||||||
|
"pause": "0.0.1",
|
||||||
|
"utils-merge": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jaredhanson"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/passport-google-oauth20": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"passport-oauth2": "1.x.x"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/passport-jwt": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"jsonwebtoken": "^9.0.0",
|
||||||
|
"passport-strategy": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/passport-local": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==",
|
||||||
|
"dependencies": {
|
||||||
|
"passport-strategy": "1.x.x"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/passport-oauth2": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"base64url": "3.x.x",
|
||||||
|
"oauth": "0.9.x",
|
||||||
|
"passport-strategy": "1.x.x",
|
||||||
|
"uid2": "0.0.x",
|
||||||
|
"utils-merge": "1.x.x"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jaredhanson"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/passport-strategy": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/pause": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="
|
||||||
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"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",
|
||||||
@ -986,6 +1200,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/random-bytes": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/range-parser": {
|
"node_modules/range-parser": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
@ -1278,6 +1500,22 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uid-safe": {
|
||||||
|
"version": "2.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
|
||||||
|
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
|
||||||
|
"dependencies": {
|
||||||
|
"random-bytes": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uid2": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz",
|
||||||
|
"integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA=="
|
||||||
|
},
|
||||||
"node_modules/undefsafe": {
|
"node_modules/undefsafe": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||||
@ -1347,6 +1585,11 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -1428,6 +1671,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||||
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||||
},
|
},
|
||||||
|
"base64url": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="
|
||||||
|
},
|
||||||
"binary-extensions": {
|
"binary-extensions": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
@ -1472,6 +1720,11 @@
|
|||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"buffer-equal-constant-time": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
|
||||||
|
},
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@ -1604,6 +1857,14 @@
|
|||||||
"domhandler": "^5.0.1"
|
"domhandler": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ecdsa-sig-formatter": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ee-first": {
|
"ee-first": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
@ -1709,6 +1970,28 @@
|
|||||||
"vary": "~1.1.2"
|
"vary": "~1.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"express-session": {
|
||||||
|
"version": "1.17.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz",
|
||||||
|
"integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==",
|
||||||
|
"requires": {
|
||||||
|
"cookie": "0.4.2",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"on-headers": "~1.0.2",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"safe-buffer": "5.2.1",
|
||||||
|
"uid-safe": "~2.1.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
|
||||||
|
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
@ -1889,6 +2172,64 @@
|
|||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"jsonwebtoken": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
|
||||||
|
"requires": {
|
||||||
|
"jws": "^3.2.2",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"ms": "^2.1.1",
|
||||||
|
"semver": "^7.3.8"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "7.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jwa": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
|
||||||
|
"requires": {
|
||||||
|
"buffer-equal-constant-time": "1.0.1",
|
||||||
|
"ecdsa-sig-formatter": "1.0.11",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jws": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
||||||
|
"requires": {
|
||||||
|
"jwa": "^1.4.1",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
|
},
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@ -1996,6 +2337,11 @@
|
|||||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"oauth": {
|
||||||
|
"version": "0.9.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
|
||||||
|
"integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="
|
||||||
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@ -2014,16 +2360,78 @@
|
|||||||
"ee-first": "1.1.1"
|
"ee-first": "1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"on-headers": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
|
||||||
|
},
|
||||||
"parseurl": {
|
"parseurl": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||||
},
|
},
|
||||||
|
"passport": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
|
||||||
|
"requires": {
|
||||||
|
"passport-strategy": "1.x.x",
|
||||||
|
"pause": "0.0.1",
|
||||||
|
"utils-merge": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passport-google-oauth20": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==",
|
||||||
|
"requires": {
|
||||||
|
"passport-oauth2": "1.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passport-jwt": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ==",
|
||||||
|
"requires": {
|
||||||
|
"jsonwebtoken": "^9.0.0",
|
||||||
|
"passport-strategy": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passport-local": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==",
|
||||||
|
"requires": {
|
||||||
|
"passport-strategy": "1.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passport-oauth2": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==",
|
||||||
|
"requires": {
|
||||||
|
"base64url": "3.x.x",
|
||||||
|
"oauth": "0.9.x",
|
||||||
|
"passport-strategy": "1.x.x",
|
||||||
|
"uid2": "0.0.x",
|
||||||
|
"utils-merge": "1.x.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passport-strategy": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA=="
|
||||||
|
},
|
||||||
"path-to-regexp": {
|
"path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||||
},
|
},
|
||||||
|
"pause": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="
|
||||||
|
},
|
||||||
"picomatch": {
|
"picomatch": {
|
||||||
"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",
|
||||||
@ -2053,6 +2461,11 @@
|
|||||||
"side-channel": "^1.0.4"
|
"side-channel": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"random-bytes": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ=="
|
||||||
|
},
|
||||||
"range-parser": {
|
"range-parser": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
@ -2272,6 +2685,19 @@
|
|||||||
"mime-types": "~2.1.24"
|
"mime-types": "~2.1.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"uid-safe": {
|
||||||
|
"version": "2.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
|
||||||
|
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
|
||||||
|
"requires": {
|
||||||
|
"random-bytes": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uid2": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz",
|
||||||
|
"integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA=="
|
||||||
|
},
|
||||||
"undefsafe": {
|
"undefsafe": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||||
@ -2312,6 +2738,11 @@
|
|||||||
"version": "11.0.1",
|
"version": "11.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
|
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,9 +32,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"express-session": "^1.17.3",
|
||||||
"graceful-fs": "^4.2.10",
|
"graceful-fs": "^4.2.10",
|
||||||
"htmlparser2": "^8.0.1",
|
"htmlparser2": "^8.0.1",
|
||||||
"node-tone": "^1.0.1",
|
"node-tone": "^1.0.1",
|
||||||
|
"passport": "^0.6.0",
|
||||||
|
"passport-google-oauth20": "^2.0.0",
|
||||||
|
"passport-jwt": "^4.0.1",
|
||||||
|
"passport-local": "^1.0.0",
|
||||||
"socket.io": "^4.5.4",
|
"socket.io": "^4.5.4",
|
||||||
"xml2js": "^0.4.23"
|
"xml2js": "^0.4.23"
|
||||||
},
|
},
|
||||||
|
336
server/Auth.js
336
server/Auth.js
@ -1,43 +1,144 @@
|
|||||||
|
const passport = require('passport')
|
||||||
const bcrypt = require('./libs/bcryptjs')
|
const bcrypt = require('./libs/bcryptjs')
|
||||||
const jwt = require('./libs/jsonwebtoken')
|
const jwt = require('./libs/jsonwebtoken')
|
||||||
const requestIp = require('./libs/requestIp')
|
const LocalStrategy = require('passport-local')
|
||||||
const Logger = require('./Logger')
|
const JwtStrategy = require('passport-jwt').Strategy;
|
||||||
|
const ExtractJwt = require('passport-jwt').ExtractJwt;
|
||||||
|
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
||||||
|
const User = require('./objects/user/User.js')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Class for handling all the authentication related functionality.
|
||||||
|
*/
|
||||||
class Auth {
|
class Auth {
|
||||||
|
|
||||||
constructor(db) {
|
constructor(db) {
|
||||||
this.db = db
|
this.db = db
|
||||||
|
|
||||||
this.user = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get username() {
|
/**
|
||||||
return this.user ? this.user.username : 'nobody'
|
* Inializes all passportjs stragegies and other passportjs ralated initialization.
|
||||||
|
*/
|
||||||
|
initPassportJs() {
|
||||||
|
// Check if we should load the local strategy
|
||||||
|
if (global.ServerSettings.authActiveAuthMethods.includes("local")) {
|
||||||
|
passport.use(new LocalStrategy(this.localAuthCheckUserPw.bind(this)))
|
||||||
|
}
|
||||||
|
// Check if we should load the google-oauth20 strategy
|
||||||
|
if (global.ServerSettings.authActiveAuthMethods.includes("google-oauth20")) {
|
||||||
|
passport.use(new GoogleStrategy({
|
||||||
|
clientID: global.ServerSettings.authGoogleOauth20ClientID,
|
||||||
|
clientSecret: global.ServerSettings.authGoogleOauth20ClientSecret,
|
||||||
|
callbackURL: global.ServerSettings.authGoogleOauth20CallbackURL
|
||||||
|
}, function (accessToken, refreshToken, profile, done) {
|
||||||
|
// TODO: what to use as username
|
||||||
|
// TODO: do we want to create the users which does not exist?
|
||||||
|
return done(null, { username: profile.emails[0].value })
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
get users() {
|
// Load the JwtStrategy (always) -> for bearer token auth
|
||||||
return this.db.users
|
passport.use(new JwtStrategy({
|
||||||
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
|
secretOrKey: global.ServerSettings.tokenSecret
|
||||||
|
}, this.jwtAuthCheck.bind(this)))
|
||||||
|
|
||||||
|
// define how to seralize a user (to be put into the session)
|
||||||
|
passport.serializeUser(function (user, cb) {
|
||||||
|
process.nextTick(function () {
|
||||||
|
// only store username and id to session
|
||||||
|
// TODO: do we want to store more info in the session?
|
||||||
|
return cb(null, {
|
||||||
|
"username": user.username,
|
||||||
|
"id": user.id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// define how to deseralize a user (use the username to get it from the database)
|
||||||
|
passport.deserializeUser(function (user, cb) {
|
||||||
|
process.nextTick(function () {
|
||||||
|
parsedUserInfo = JSON.parse(user)
|
||||||
|
// TODO: do the matching on username or better on id?
|
||||||
|
var dbUser = this.db.users.find(u => u.username.toLowerCase() === parsedUserInfo.username.toLowerCase())
|
||||||
|
return cb(null, new User(dbUser));
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cors(req, res, next) {
|
/**
|
||||||
res.header('Access-Control-Allow-Origin', '*')
|
* Creates all (express) routes required for authentication.
|
||||||
res.header("Access-Control-Allow-Methods", 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
|
* @param {express.Router} router
|
||||||
res.header('Access-Control-Allow-Headers', '*')
|
*/
|
||||||
// TODO: Make sure allowing all headers is not a security concern. It is required for adding custom headers for SSO
|
initAuthRoutes(router) {
|
||||||
// res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Range, Authorization")
|
// just a route saying "you need to login" where we redirect e.g. after logout
|
||||||
res.header('Access-Control-Allow-Credentials', true)
|
// TODO: replace with a 401?
|
||||||
if (req.method === 'OPTIONS') {
|
router.get('/login', function (req, res) {
|
||||||
res.sendStatus(200)
|
res.send('please login')
|
||||||
} else {
|
})
|
||||||
|
|
||||||
|
// Local strategy login route (takes username and password)
|
||||||
|
router.post('/login', passport.authenticate('local', {
|
||||||
|
failureRedirect: '/login'
|
||||||
|
}),
|
||||||
|
(function (req, res) {
|
||||||
|
// return the user login response json if the login was successfull
|
||||||
|
res.json(this.getUserLoginResponsePayload(req.user.username))
|
||||||
|
}).bind(this)
|
||||||
|
)
|
||||||
|
|
||||||
|
// google-oauth20 strategy login route (this redirects to the google login)
|
||||||
|
router.get('/auth/google', passport.authenticate('google', { scope: ['email'] }))
|
||||||
|
|
||||||
|
// google-oauth20 strategy callback route (this receives the token from google)
|
||||||
|
router.get('/auth/google/callback',
|
||||||
|
passport.authenticate('google', { failureRedirect: '/login' }),
|
||||||
|
(function (req, res) {
|
||||||
|
// return the user login response json if the login was successfull
|
||||||
|
res.json(this.getUserLoginResponsePayload(req.user.username))
|
||||||
|
}).bind(this)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Logout route
|
||||||
|
router.get('/logout', function (req, res) {
|
||||||
|
// TODO: invalidate possible JWTs
|
||||||
|
req.logout()
|
||||||
|
res.redirect('/login')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* middleware to use in express to only allow authenticated users.
|
||||||
|
* @param {express.Request} req
|
||||||
|
* @param {express.Response} res
|
||||||
|
* @param {express.NextFunction} next
|
||||||
|
*/
|
||||||
|
isAuthenticated(req, res, next) {
|
||||||
|
// check if session cookie says that we are authenticated
|
||||||
|
if (req.isAuthenticated()) {
|
||||||
next()
|
next()
|
||||||
|
} else {
|
||||||
|
// try JWT to authenticate
|
||||||
|
passport.authenticate("jwt")(req, res, next)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to generate a jwt token for a given user.
|
||||||
|
* @param {Object} user
|
||||||
|
* @returns the token.
|
||||||
|
*/
|
||||||
|
generateAccessToken(user) {
|
||||||
|
return jwt.sign({ userId: user.id, username: user.username }, global.ServerSettings.tokenSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a token for each user.
|
||||||
|
*/
|
||||||
async initTokenSecret() {
|
async initTokenSecret() {
|
||||||
if (process.env.TOKEN_SECRET) { // User can supply their own token secret
|
if (process.env.TOKEN_SECRET) { // User can supply their own token secret
|
||||||
Logger.debug(`[Auth] Setting token secret - using user passed in TOKEN_SECRET env var`)
|
|
||||||
this.db.serverSettings.tokenSecret = process.env.TOKEN_SECRET
|
this.db.serverSettings.tokenSecret = process.env.TOKEN_SECRET
|
||||||
} else {
|
} else {
|
||||||
Logger.debug(`[Auth] Setting token secret - using random bytes`)
|
|
||||||
this.db.serverSettings.tokenSecret = require('crypto').randomBytes(256).toString('base64')
|
this.db.serverSettings.tokenSecret = require('crypto').randomBytes(256).toString('base64')
|
||||||
}
|
}
|
||||||
await this.db.updateServerSettings()
|
await this.db.updateServerSettings()
|
||||||
@ -46,46 +147,70 @@ class Auth {
|
|||||||
if (this.db.users.length) {
|
if (this.db.users.length) {
|
||||||
for (const user of this.db.users) {
|
for (const user of this.db.users) {
|
||||||
user.token = await this.generateAccessToken({ userId: user.id, username: user.username })
|
user.token = await this.generateAccessToken({ userId: user.id, username: user.username })
|
||||||
Logger.warn(`[Auth] User ${user.username} api token has been updated using new token secret`)
|
|
||||||
}
|
}
|
||||||
await this.db.updateEntities('user', this.db.users)
|
await this.db.updateEntities('user', this.db.users)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async authMiddleware(req, res, next) {
|
/**
|
||||||
var token = null
|
* Checks if the user in the validated jwt_payload really exists and is active.
|
||||||
|
* @param {Object} jwt_payload
|
||||||
|
* @param {function} done
|
||||||
|
*/
|
||||||
|
jwtAuthCheck(jwt_payload, done) {
|
||||||
|
var user = this.db.users.find(u => u.username.toLowerCase() === jwt_payload.username.toLowerCase())
|
||||||
|
|
||||||
// If using a get request, the token can be passed as a query string
|
if (!user || !user.isActive) {
|
||||||
if (req.method === 'GET' && req.query && req.query.token) {
|
done(null, null)
|
||||||
token = req.query.token
|
return
|
||||||
} else {
|
}
|
||||||
const authHeader = req.headers['authorization']
|
done(null, user)
|
||||||
token = authHeader && authHeader.split(' ')[1]
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == null) {
|
/**
|
||||||
Logger.error('Api called without a token', req.path)
|
* Checks if a username and passpword touple is valid and the user active.
|
||||||
return res.sendStatus(401)
|
* @param {string} username
|
||||||
|
* @param {string} password
|
||||||
|
* @param {function} done
|
||||||
|
*/
|
||||||
|
localAuthCheckUserPw(username, password, done) {
|
||||||
|
var user = this.db.users.find(u => u.username.toLowerCase() === username.toLowerCase())
|
||||||
|
|
||||||
|
if (!user || !user.isActive) {
|
||||||
|
done(null, null)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = await this.verifyToken(token)
|
// Check passwordless root user
|
||||||
if (!user) {
|
if (user.id === 'root' && (!user.pash || user.pash === '')) {
|
||||||
Logger.error('Verify Token User Not Found', token)
|
if (password) {
|
||||||
return res.sendStatus(404)
|
done(null, null)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (!user.isActive) {
|
done(null, user)
|
||||||
Logger.error('Verify Token User is disabled', token, user.username)
|
return
|
||||||
return res.sendStatus(403)
|
|
||||||
}
|
|
||||||
req.user = user
|
|
||||||
next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check password match
|
||||||
|
var compare = bcrypt.compareSync(password, user.pash)
|
||||||
|
if (compare) {
|
||||||
|
done(null, user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
done(null, null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashes a password with bcrypt.
|
||||||
|
* @param {string} password
|
||||||
|
* @returns {string} hash
|
||||||
|
*/
|
||||||
hashPass(password) {
|
hashPass(password) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
bcrypt.hash(password, 8, (err, hash) => {
|
bcrypt.hash(password, 8, (err, hash) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
Logger.error('Hash failed', err)
|
|
||||||
resolve(null)
|
resolve(null)
|
||||||
} else {
|
} else {
|
||||||
resolve(hash)
|
resolve(hash)
|
||||||
@ -94,28 +219,14 @@ class Auth {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
generateAccessToken(payload) {
|
/**
|
||||||
return jwt.sign(payload, global.ServerSettings.tokenSecret);
|
* Return the login info payload for a user.
|
||||||
}
|
* @param {string} username
|
||||||
|
* @returns {string} jsonPayload
|
||||||
authenticateUser(token) {
|
*/
|
||||||
return this.verifyToken(token)
|
getUserLoginResponsePayload(username) {
|
||||||
}
|
var user = this.db.users.find(u => u.username.toLowerCase() === username.toLowerCase())
|
||||||
|
user = new User(user)
|
||||||
verifyToken(token) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
jwt.verify(token, global.ServerSettings.tokenSecret, (err, payload) => {
|
|
||||||
if (!payload || err) {
|
|
||||||
Logger.error('JWT Verify Token Failed', err)
|
|
||||||
return resolve(null)
|
|
||||||
}
|
|
||||||
const user = this.users.find(u => u.id === payload.userId && u.username === payload.username)
|
|
||||||
resolve(user || null)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserLoginResponsePayload(user) {
|
|
||||||
return {
|
return {
|
||||||
user: user.toJSONForBrowser(),
|
user: user.toJSONForBrowser(),
|
||||||
userDefaultLibraryId: user.getDefaultLibraryId(this.db.libraries),
|
userDefaultLibraryId: user.getDefaultLibraryId(this.db.libraries),
|
||||||
@ -123,101 +234,6 @@ class Auth {
|
|||||||
Source: global.Source
|
Source: global.Source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(req, res) {
|
|
||||||
const ipAddress = requestIp.getClientIp(req)
|
|
||||||
var username = (req.body.username || '').toLowerCase()
|
|
||||||
var password = req.body.password || ''
|
|
||||||
|
|
||||||
var user = this.users.find(u => u.username.toLowerCase() === username)
|
|
||||||
|
|
||||||
if (!user || !user.isActive) {
|
|
||||||
Logger.warn(`[Auth] Failed login attempt ${req.rateLimit.current} of ${req.rateLimit.limit} from ${ipAddress}`)
|
|
||||||
if (req.rateLimit.remaining <= 2) {
|
|
||||||
Logger.error(`[Auth] Failed login attempt for username ${username} from ip ${ipAddress}. Attempts: ${req.rateLimit.current}`)
|
|
||||||
return res.status(401).send(`Invalid user or password (${req.rateLimit.remaining === 0 ? '1 attempt remaining' : `${req.rateLimit.remaining + 1} attempts remaining`})`)
|
|
||||||
}
|
|
||||||
return res.status(401).send('Invalid user or password')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check passwordless root user
|
|
||||||
if (user.id === 'root' && (!user.pash || user.pash === '')) {
|
|
||||||
if (password) {
|
|
||||||
return res.status(401).send('Invalid root password (hint: there is none)')
|
|
||||||
} else {
|
|
||||||
return res.json(this.getUserLoginResponsePayload(user))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check password match
|
|
||||||
var compare = await bcrypt.compare(password, user.pash)
|
|
||||||
if (compare) {
|
|
||||||
res.json(this.getUserLoginResponsePayload(user))
|
|
||||||
} else {
|
|
||||||
Logger.warn(`[Auth] Failed login attempt ${req.rateLimit.current} of ${req.rateLimit.limit} from ${ipAddress}`)
|
|
||||||
if (req.rateLimit.remaining <= 2) {
|
|
||||||
Logger.error(`[Auth] Failed login attempt for user ${user.username} from ip ${ipAddress}. Attempts: ${req.rateLimit.current}`)
|
|
||||||
return res.status(401).send(`Invalid user or password (${req.rateLimit.remaining === 0 ? '1 attempt remaining' : `${req.rateLimit.remaining + 1} attempts remaining`})`)
|
|
||||||
}
|
|
||||||
return res.status(401).send('Invalid user or password')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not in use now
|
|
||||||
lockUser(user) {
|
|
||||||
user.isLocked = true
|
|
||||||
return this.db.updateEntity('user', user).catch((error) => {
|
|
||||||
Logger.error('[Auth] Failed to lock user', user.username, error)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
comparePassword(password, user) {
|
|
||||||
if (user.type === 'root' && !password && !user.pash) return true
|
|
||||||
if (!password || !user.pash) return false
|
|
||||||
return bcrypt.compare(password, user.pash)
|
|
||||||
}
|
|
||||||
|
|
||||||
async userChangePassword(req, res) {
|
|
||||||
var { password, newPassword } = req.body
|
|
||||||
newPassword = newPassword || ''
|
|
||||||
var matchingUser = this.users.find(u => u.id === req.user.id)
|
|
||||||
|
|
||||||
// Only root can have an empty password
|
|
||||||
if (matchingUser.type !== 'root' && !newPassword) {
|
|
||||||
return res.json({
|
|
||||||
error: 'Invalid new password - Only root can have an empty password'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var compare = await this.comparePassword(password, matchingUser)
|
|
||||||
if (!compare) {
|
|
||||||
return res.json({
|
|
||||||
error: 'Invalid password'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var pw = ''
|
|
||||||
if (newPassword) {
|
|
||||||
pw = await this.hashPass(newPassword)
|
|
||||||
if (!pw) {
|
|
||||||
return res.json({
|
|
||||||
error: 'Hash failed'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
matchingUser.pash = pw
|
|
||||||
var success = await this.db.updateEntity('user', matchingUser)
|
|
||||||
if (success) {
|
|
||||||
res.json({
|
|
||||||
success: true
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
res.json({
|
|
||||||
error: 'Unknown error'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module.exports = Auth
|
module.exports = Auth
|
@ -37,6 +37,11 @@ const CronManager = require('./managers/CronManager')
|
|||||||
const TaskManager = require('./managers/TaskManager')
|
const TaskManager = require('./managers/TaskManager')
|
||||||
const EBookManager = require('./managers/EBookManager')
|
const EBookManager = require('./managers/EBookManager')
|
||||||
|
|
||||||
|
//Import the main Passport and Express-Session library
|
||||||
|
const passport = require('passport')
|
||||||
|
const expressSession = require('express-session')
|
||||||
|
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
constructor(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, ROUTER_BASE_PATH) {
|
constructor(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, ROUTER_BASE_PATH) {
|
||||||
this.Port = PORT
|
this.Port = PORT
|
||||||
@ -48,7 +53,7 @@ class Server {
|
|||||||
global.ConfigPath = fileUtils.filePathToPOSIX(Path.normalize(CONFIG_PATH))
|
global.ConfigPath = fileUtils.filePathToPOSIX(Path.normalize(CONFIG_PATH))
|
||||||
global.MetadataPath = fileUtils.filePathToPOSIX(Path.normalize(METADATA_PATH))
|
global.MetadataPath = fileUtils.filePathToPOSIX(Path.normalize(METADATA_PATH))
|
||||||
global.RouterBasePath = ROUTER_BASE_PATH
|
global.RouterBasePath = ROUTER_BASE_PATH
|
||||||
global.XAccel = process.env.USE_X_ACCEL
|
global.XAccel = process.env.USE_X_ACCELAuth
|
||||||
|
|
||||||
if (!fs.pathExistsSync(global.ConfigPath)) {
|
if (!fs.pathExistsSync(global.ConfigPath)) {
|
||||||
fs.mkdirSync(global.ConfigPath)
|
fs.mkdirSync(global.ConfigPath)
|
||||||
@ -92,7 +97,7 @@ class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
authMiddleware(req, res, next) {
|
authMiddleware(req, res, next) {
|
||||||
this.auth.authMiddleware(req, res, next)
|
this.auth.isAuthenticated(req, res, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
@ -141,13 +146,33 @@ class Server {
|
|||||||
await this.init()
|
await this.init()
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
|
// enable express-session
|
||||||
|
app.use(expressSession({
|
||||||
|
secret: global.ServerSettings.tokenSecret,
|
||||||
|
resave: false,
|
||||||
|
saveUninitialized: false,
|
||||||
|
cookie: {
|
||||||
|
// also send the cookie if were hare not on https
|
||||||
|
secure: false
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
// init passport.js
|
||||||
|
app.use(passport.initialize())
|
||||||
|
// register passport in express-session
|
||||||
|
app.use(passport.session())
|
||||||
|
// config passport.js
|
||||||
|
this.auth.initPassportJs()
|
||||||
|
// use auth on all routes - not used now
|
||||||
|
// app.use(passport.authenticate('session'));
|
||||||
|
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
app.use(global.RouterBasePath, router)
|
app.use(global.RouterBasePath, router)
|
||||||
app.disable('x-powered-by')
|
app.disable('x-powered-by')
|
||||||
|
|
||||||
this.server = http.createServer(app)
|
this.server = http.createServer(app)
|
||||||
|
|
||||||
router.use(this.auth.cors)
|
// router.use(this.auth.cors)
|
||||||
router.use(fileUpload())
|
router.use(fileUpload())
|
||||||
router.use(express.urlencoded({ extended: true, limit: "5mb" }));
|
router.use(express.urlencoded({ extended: true, limit: "5mb" }));
|
||||||
router.use(express.json({ limit: "5mb" }))
|
router.use(express.json({ limit: "5mb" }))
|
||||||
@ -166,6 +191,9 @@ class Server {
|
|||||||
router.use('/hls', this.authMiddleware.bind(this), this.hlsRouter.router)
|
router.use('/hls', this.authMiddleware.bind(this), this.hlsRouter.router)
|
||||||
router.use('/s', this.authMiddleware.bind(this), this.staticRouter.router)
|
router.use('/s', this.authMiddleware.bind(this), this.staticRouter.router)
|
||||||
|
|
||||||
|
// Auth routes
|
||||||
|
this.auth.initAuthRoutes(router)
|
||||||
|
|
||||||
// EBook static file routes
|
// EBook static file routes
|
||||||
router.get('/ebook/:library/:folder/*', (req, res) => {
|
router.get('/ebook/:library/:folder/*', (req, res) => {
|
||||||
const library = this.db.libraries.find(lib => lib.id === req.params.library)
|
const library = this.db.libraries.find(lib => lib.id === req.params.library)
|
||||||
@ -213,8 +241,8 @@ class Server {
|
|||||||
]
|
]
|
||||||
dyanimicRoutes.forEach((route) => router.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
|
dyanimicRoutes.forEach((route) => router.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
|
||||||
|
|
||||||
router.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res))
|
// router.post('/login', passport.authenticate('local', this.auth.login), this.auth.loginResult.bind(this))
|
||||||
router.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
|
// router.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
|
||||||
router.post('/init', (req, res) => {
|
router.post('/init', (req, res) => {
|
||||||
if (this.db.hasRootUser) {
|
if (this.db.hasRootUser) {
|
||||||
Logger.error(`[Server] attempt to init server when server already has a root user`)
|
Logger.error(`[Server] attempt to init server when server already has a root user`)
|
||||||
|
@ -43,7 +43,7 @@ class UserController {
|
|||||||
account.id = getId('usr')
|
account.id = getId('usr')
|
||||||
account.pash = await this.auth.hashPass(account.password)
|
account.pash = await this.auth.hashPass(account.password)
|
||||||
delete account.password
|
delete account.password
|
||||||
account.token = await this.auth.generateAccessToken({ userId: account.id, username })
|
account.token = await this.auth.generateAccessToken(account)
|
||||||
account.createdAt = Date.now()
|
account.createdAt = Date.now()
|
||||||
var newUser = new User(account)
|
var newUser = new User(account)
|
||||||
var success = await this.db.insertEntity('user', newUser)
|
var success = await this.db.insertEntity('user', newUser)
|
||||||
@ -85,7 +85,7 @@ class UserController {
|
|||||||
var hasUpdated = user.update(account)
|
var hasUpdated = user.update(account)
|
||||||
if (hasUpdated) {
|
if (hasUpdated) {
|
||||||
if (shouldUpdateToken) {
|
if (shouldUpdateToken) {
|
||||||
user.token = await this.auth.generateAccessToken({ userId: user.id, username: user.username })
|
user.token = await this.auth.generateAccessToken(user)
|
||||||
Logger.info(`[UserController] User ${user.username} was generated a new api token`)
|
Logger.info(`[UserController] User ${user.username} was generated a new api token`)
|
||||||
}
|
}
|
||||||
await this.db.updateEntity('user', user)
|
await this.db.updateEntity('user', user)
|
||||||
|
@ -57,6 +57,16 @@ class ServerSettings {
|
|||||||
|
|
||||||
this.version = null
|
this.version = null
|
||||||
|
|
||||||
|
// Auth settings
|
||||||
|
// Active auth methodes
|
||||||
|
this.authActiveAuthMethods = ['local']
|
||||||
|
|
||||||
|
// google-oauth20 settings
|
||||||
|
this.authGoogleOauth20ClientID = ''
|
||||||
|
this.authGoogleOauth20ClientSecret = ''
|
||||||
|
this.authGoogleOauth20CallbackURL = ''
|
||||||
|
|
||||||
|
|
||||||
if (settings) {
|
if (settings) {
|
||||||
this.construct(settings)
|
this.construct(settings)
|
||||||
}
|
}
|
||||||
@ -100,6 +110,30 @@ class ServerSettings {
|
|||||||
this.logLevel = settings.logLevel || Logger.logLevel
|
this.logLevel = settings.logLevel || Logger.logLevel
|
||||||
this.version = settings.version || null
|
this.version = settings.version || null
|
||||||
|
|
||||||
|
this.authActiveAuthMethods = settings.authActiveAuthMethods || ['local']
|
||||||
|
this.authGoogleOauth20ClientID = settings.authGoogleOauth20ClientID || ''
|
||||||
|
this.authGoogleOauth20ClientSecret = settings.authGoogleOauth20ClientSecret || ''
|
||||||
|
this.authGoogleOauth20CallbackURL = settings.authGoogleOauth20CallbackURL || ''
|
||||||
|
|
||||||
|
if (!Array.isArray(this.authActiveAuthMethods)) {
|
||||||
|
this.authActiveAuthMethods = ['local']
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove uninitialized methods
|
||||||
|
// GoogleOauth20
|
||||||
|
if (this.authActiveAuthMethods.includes('google-oauth20') && (
|
||||||
|
this.authGoogleOauth20ClientID === '' ||
|
||||||
|
this.authGoogleOauth20ClientSecret === '' ||
|
||||||
|
this.authGoogleOauth20CallbackURL === ''
|
||||||
|
)) {
|
||||||
|
this.authActiveAuthMethods.splice(this.authActiveAuthMethods.indexOf('google-oauth20', 0), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to local
|
||||||
|
if (!Array.isArray(this.authActiveAuthMethods) || this.authActiveAuthMethods.length == 0) {
|
||||||
|
this.authActiveAuthMethods = ['local']
|
||||||
|
}
|
||||||
|
|
||||||
// Migrations
|
// Migrations
|
||||||
if (settings.storeCoverWithBook != undefined) { // storeCoverWithBook was renamed to storeCoverWithItem in 2.0.0
|
if (settings.storeCoverWithBook != undefined) { // storeCoverWithBook was renamed to storeCoverWithItem in 2.0.0
|
||||||
this.storeCoverWithItem = !!settings.storeCoverWithBook
|
this.storeCoverWithItem = !!settings.storeCoverWithBook
|
||||||
@ -148,13 +182,19 @@ class ServerSettings {
|
|||||||
dateFormat: this.dateFormat,
|
dateFormat: this.dateFormat,
|
||||||
language: this.language,
|
language: this.language,
|
||||||
logLevel: this.logLevel,
|
logLevel: this.logLevel,
|
||||||
version: this.version
|
version: this.version,
|
||||||
|
authActiveAuthMethods: this.authActiveAuthMethods,
|
||||||
|
authGoogleOauth20ClientID: this.authGoogleOauth20ClientID, // Do not return to client
|
||||||
|
authGoogleOauth20ClientSecret: this.authGoogleOauth20ClientSecret, // Do not return to client
|
||||||
|
authGoogleOauth20CallbackURL: this.authGoogleOauth20CallbackURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSONForBrowser() {
|
toJSONForBrowser() {
|
||||||
const json = this.toJSON()
|
const json = this.toJSON()
|
||||||
delete json.tokenSecret
|
delete json.tokenSecret
|
||||||
|
delete json.authGoogleOauth20ClientID
|
||||||
|
delete json.authGoogleOauth20ClientSecret
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user