mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01: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": {
 | 
			
		||||
        "axios": "^0.27.2",
 | 
			
		||||
        "express": "^4.17.1",
 | 
			
		||||
        "express-session": "^1.17.3",
 | 
			
		||||
        "graceful-fs": "^4.2.10",
 | 
			
		||||
        "htmlparser2": "^8.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",
 | 
			
		||||
        "xml2js": "^0.4.23"
 | 
			
		||||
      },
 | 
			
		||||
@ -111,6 +116,14 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "2.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
 | 
			
		||||
@ -165,6 +178,11 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "3.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
 | 
			
		||||
@ -357,6 +375,14 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "1.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
 | 
			
		||||
@ -492,6 +518,32 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "7.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
 | 
			
		||||
@ -754,6 +806,75 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "0.3.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
 | 
			
		||||
@ -902,6 +1023,11 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "4.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
 | 
			
		||||
@ -929,6 +1055,14 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "1.3.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
 | 
			
		||||
@ -937,11 +1071,91 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "0.1.7",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "2.3.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 | 
			
		||||
@ -986,6 +1200,14 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "1.2.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
 | 
			
		||||
@ -1278,6 +1500,22 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "2.0.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
 | 
			
		||||
@ -1347,6 +1585,11 @@
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "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": {
 | 
			
		||||
@ -1428,6 +1671,11 @@
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "2.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
 | 
			
		||||
@ -1472,6 +1720,11 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "3.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
 | 
			
		||||
@ -1604,6 +1857,14 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "1.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
 | 
			
		||||
@ -1709,6 +1970,28 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "7.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
 | 
			
		||||
@ -1889,6 +2172,64 @@
 | 
			
		||||
      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "0.3.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
 | 
			
		||||
@ -1996,6 +2337,11 @@
 | 
			
		||||
      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "4.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
 | 
			
		||||
@ -2014,16 +2360,78 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "1.3.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "0.1.7",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
 | 
			
		||||
      "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": {
 | 
			
		||||
      "version": "2.3.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 | 
			
		||||
@ -2053,6 +2461,11 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "1.2.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
 | 
			
		||||
@ -2272,6 +2685,19 @@
 | 
			
		||||
        "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": {
 | 
			
		||||
      "version": "2.0.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
 | 
			
		||||
@ -2312,6 +2738,11 @@
 | 
			
		||||
      "version": "11.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
 | 
			
		||||
      "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": {
 | 
			
		||||
    "axios": "^0.27.2",
 | 
			
		||||
    "express": "^4.17.1",
 | 
			
		||||
    "express-session": "^1.17.3",
 | 
			
		||||
    "graceful-fs": "^4.2.10",
 | 
			
		||||
    "htmlparser2": "^8.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",
 | 
			
		||||
    "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 jwt = require('./libs/jsonwebtoken')
 | 
			
		||||
const requestIp = require('./libs/requestIp')
 | 
			
		||||
const Logger = require('./Logger')
 | 
			
		||||
const LocalStrategy = require('passport-local')
 | 
			
		||||
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 {
 | 
			
		||||
 | 
			
		||||
  constructor(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() {
 | 
			
		||||
    return this.db.users
 | 
			
		||||
    // Load the JwtStrategy (always) -> for bearer token auth 
 | 
			
		||||
    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', '*')
 | 
			
		||||
    res.header("Access-Control-Allow-Methods", 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
 | 
			
		||||
    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
 | 
			
		||||
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Range, Authorization")
 | 
			
		||||
    res.header('Access-Control-Allow-Credentials', true)
 | 
			
		||||
    if (req.method === 'OPTIONS') {
 | 
			
		||||
      res.sendStatus(200)
 | 
			
		||||
    } else {
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates all (express) routes required for authentication.
 | 
			
		||||
   * @param {express.Router} router 
 | 
			
		||||
   */
 | 
			
		||||
  initAuthRoutes(router) {
 | 
			
		||||
    // just a route saying "you need to login" where we redirect e.g. after logout
 | 
			
		||||
    // TODO: replace with a 401?
 | 
			
		||||
    router.get('/login', function (req, res) {
 | 
			
		||||
      res.send('please login')
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    // 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()
 | 
			
		||||
    } 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() {
 | 
			
		||||
    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
 | 
			
		||||
    } else {
 | 
			
		||||
      Logger.debug(`[Auth] Setting token secret - using random bytes`)
 | 
			
		||||
      this.db.serverSettings.tokenSecret = require('crypto').randomBytes(256).toString('base64')
 | 
			
		||||
    }
 | 
			
		||||
    await this.db.updateServerSettings()
 | 
			
		||||
@ -46,46 +147,70 @@ class Auth {
 | 
			
		||||
    if (this.db.users.length) {
 | 
			
		||||
      for (const user of this.db.users) {
 | 
			
		||||
        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)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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 (req.method === 'GET' && req.query && req.query.token) {
 | 
			
		||||
      token = req.query.token
 | 
			
		||||
    } else {
 | 
			
		||||
      const authHeader = req.headers['authorization']
 | 
			
		||||
      token = authHeader && authHeader.split(' ')[1]
 | 
			
		||||
    if (!user || !user.isActive) {
 | 
			
		||||
      done(null, null)
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    done(null, user)
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    if (token == null) {
 | 
			
		||||
      Logger.error('Api called without a token', req.path)
 | 
			
		||||
      return res.sendStatus(401)
 | 
			
		||||
  /**
 | 
			
		||||
   * Checks if a username and passpword touple is valid and the user active.
 | 
			
		||||
   * @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)
 | 
			
		||||
    if (!user) {
 | 
			
		||||
      Logger.error('Verify Token User Not Found', token)
 | 
			
		||||
      return res.sendStatus(404)
 | 
			
		||||
    // Check passwordless root user
 | 
			
		||||
    if (user.id === 'root' && (!user.pash || user.pash === '')) {
 | 
			
		||||
      if (password) {
 | 
			
		||||
        done(null, null)
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
    if (!user.isActive) {
 | 
			
		||||
      Logger.error('Verify Token User is disabled', token, user.username)
 | 
			
		||||
      return res.sendStatus(403)
 | 
			
		||||
    }
 | 
			
		||||
    req.user = user
 | 
			
		||||
    next()
 | 
			
		||||
      done(null, user)
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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) {
 | 
			
		||||
    return new Promise((resolve) => {
 | 
			
		||||
      bcrypt.hash(password, 8, (err, hash) => {
 | 
			
		||||
        if (err) {
 | 
			
		||||
          Logger.error('Hash failed', err)
 | 
			
		||||
          resolve(null)
 | 
			
		||||
        } else {
 | 
			
		||||
          resolve(hash)
 | 
			
		||||
@ -94,28 +219,14 @@ class Auth {
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  generateAccessToken(payload) {
 | 
			
		||||
    return jwt.sign(payload, global.ServerSettings.tokenSecret);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  authenticateUser(token) {
 | 
			
		||||
    return this.verifyToken(token)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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 the login info payload for a user.
 | 
			
		||||
   * @param {string} username 
 | 
			
		||||
   * @returns {string} jsonPayload
 | 
			
		||||
   */
 | 
			
		||||
  getUserLoginResponsePayload(username) {
 | 
			
		||||
    var user = this.db.users.find(u => u.username.toLowerCase() === username.toLowerCase())
 | 
			
		||||
    user = new User(user)
 | 
			
		||||
    return {
 | 
			
		||||
      user: user.toJSONForBrowser(),
 | 
			
		||||
      userDefaultLibraryId: user.getDefaultLibraryId(this.db.libraries),
 | 
			
		||||
@ -123,101 +234,6 @@ class Auth {
 | 
			
		||||
      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
 | 
			
		||||
@ -37,6 +37,11 @@ const CronManager = require('./managers/CronManager')
 | 
			
		||||
const TaskManager = require('./managers/TaskManager')
 | 
			
		||||
const EBookManager = require('./managers/EBookManager')
 | 
			
		||||
 | 
			
		||||
//Import the main Passport and Express-Session library
 | 
			
		||||
const passport = require('passport')
 | 
			
		||||
const expressSession = require('express-session')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Server {
 | 
			
		||||
  constructor(SOURCE, PORT, HOST, UID, GID, CONFIG_PATH, METADATA_PATH, ROUTER_BASE_PATH) {
 | 
			
		||||
    this.Port = PORT
 | 
			
		||||
@ -48,7 +53,7 @@ class Server {
 | 
			
		||||
    global.ConfigPath = fileUtils.filePathToPOSIX(Path.normalize(CONFIG_PATH))
 | 
			
		||||
    global.MetadataPath = fileUtils.filePathToPOSIX(Path.normalize(METADATA_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)) {
 | 
			
		||||
      fs.mkdirSync(global.ConfigPath)
 | 
			
		||||
@ -92,7 +97,7 @@ class Server {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  authMiddleware(req, res, next) {
 | 
			
		||||
    this.auth.authMiddleware(req, res, next)
 | 
			
		||||
    this.auth.isAuthenticated(req, res, next)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async init() {
 | 
			
		||||
@ -141,13 +146,33 @@ class Server {
 | 
			
		||||
    await this.init()
 | 
			
		||||
 | 
			
		||||
    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()
 | 
			
		||||
    app.use(global.RouterBasePath, router)
 | 
			
		||||
    app.disable('x-powered-by')
 | 
			
		||||
 | 
			
		||||
    this.server = http.createServer(app)
 | 
			
		||||
 | 
			
		||||
    router.use(this.auth.cors)
 | 
			
		||||
    // router.use(this.auth.cors)
 | 
			
		||||
    router.use(fileUpload())
 | 
			
		||||
    router.use(express.urlencoded({ extended: true, 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('/s', this.authMiddleware.bind(this), this.staticRouter.router)
 | 
			
		||||
 | 
			
		||||
    // Auth routes
 | 
			
		||||
    this.auth.initAuthRoutes(router)
 | 
			
		||||
 | 
			
		||||
    // EBook static file routes
 | 
			
		||||
    router.get('/ebook/:library/:folder/*', (req, res) => {
 | 
			
		||||
      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'))))
 | 
			
		||||
 | 
			
		||||
    router.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res))
 | 
			
		||||
    router.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
 | 
			
		||||
    // 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('/init', (req, res) => {
 | 
			
		||||
      if (this.db.hasRootUser) {
 | 
			
		||||
        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.pash = await this.auth.hashPass(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()
 | 
			
		||||
    var newUser = new User(account)
 | 
			
		||||
    var success = await this.db.insertEntity('user', newUser)
 | 
			
		||||
@ -85,7 +85,7 @@ class UserController {
 | 
			
		||||
    var hasUpdated = user.update(account)
 | 
			
		||||
    if (hasUpdated) {
 | 
			
		||||
      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`)
 | 
			
		||||
      }
 | 
			
		||||
      await this.db.updateEntity('user', user)
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,16 @@ class ServerSettings {
 | 
			
		||||
 | 
			
		||||
    this.version = null
 | 
			
		||||
 | 
			
		||||
    // Auth settings
 | 
			
		||||
    // Active auth methodes
 | 
			
		||||
    this.authActiveAuthMethods = ['local']
 | 
			
		||||
 | 
			
		||||
    // google-oauth20 settings
 | 
			
		||||
    this.authGoogleOauth20ClientID = ''
 | 
			
		||||
    this.authGoogleOauth20ClientSecret = ''
 | 
			
		||||
    this.authGoogleOauth20CallbackURL = ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (settings) {
 | 
			
		||||
      this.construct(settings)
 | 
			
		||||
    }
 | 
			
		||||
@ -100,6 +110,30 @@ class ServerSettings {
 | 
			
		||||
    this.logLevel = settings.logLevel || Logger.logLevel
 | 
			
		||||
    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
 | 
			
		||||
    if (settings.storeCoverWithBook != undefined) { // storeCoverWithBook was renamed to storeCoverWithItem in 2.0.0
 | 
			
		||||
      this.storeCoverWithItem = !!settings.storeCoverWithBook
 | 
			
		||||
@ -148,13 +182,19 @@ class ServerSettings {
 | 
			
		||||
      dateFormat: this.dateFormat,
 | 
			
		||||
      language: this.language,
 | 
			
		||||
      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() {
 | 
			
		||||
    const json = this.toJSON()
 | 
			
		||||
    delete json.tokenSecret
 | 
			
		||||
    delete json.authGoogleOauth20ClientID
 | 
			
		||||
    delete json.authGoogleOauth20ClientSecret
 | 
			
		||||
    return json
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user