Basic login
This commit is contained in:
		
							
								
								
									
										256
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										256
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -43,6 +43,14 @@ | ||||
|       "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@phc/format": { | ||||
|       "version": "0.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/@phc/format/-/format-0.5.0.tgz", | ||||
|       "integrity": "sha512-JWtZ5P1bfXU0bAtTzCpOLYHDXuxSVdtL/oqz4+xa97h8w9E5IlVN333wugXVFv8vZ1hbXObKQf1ptXmFFcMByg==", | ||||
|       "requires": { | ||||
|         "safe-buffer": "^5.1.2" | ||||
|       } | ||||
|     }, | ||||
|     "@protobufjs/aspromise": { | ||||
|       "version": "1.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", | ||||
| @@ -122,6 +130,15 @@ | ||||
|         "@types/node": "*" | ||||
|       } | ||||
|     }, | ||||
|     "@types/cookie-parser": { | ||||
|       "version": "1.4.2", | ||||
|       "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.2.tgz", | ||||
|       "integrity": "sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@types/express": "*" | ||||
|       } | ||||
|     }, | ||||
|     "@types/cookies": { | ||||
|       "version": "0.7.3", | ||||
|       "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.3.tgz", | ||||
| @@ -198,11 +215,26 @@ | ||||
|         "graphql": "^14.5.3" | ||||
|       } | ||||
|     }, | ||||
|     "@types/helmet": { | ||||
|       "version": "0.0.44", | ||||
|       "resolved": "https://registry.npmjs.org/@types/helmet/-/helmet-0.0.44.tgz", | ||||
|       "integrity": "sha512-MPZ7HoCGLoajTZhy3hMWHvdiOMHCZJ51U2Bve25oujn3G7KdXy0G3iRS0dUpVtKOGMNcuBF6yLDRpNdm2JH0OQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@types/express": "*" | ||||
|       } | ||||
|     }, | ||||
|     "@types/http-assert": { | ||||
|       "version": "1.5.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", | ||||
|       "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==" | ||||
|     }, | ||||
|     "@types/http-errors": { | ||||
|       "version": "1.6.2", | ||||
|       "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.6.2.tgz", | ||||
|       "integrity": "sha512-mzJX3tIbtadNZQIDbfA9eW+mAjww7GY7WYcfKDGB5SSXMAzI8KD+5fvyX5FqcKtns346+WGwAJJ8cPsDxMz0lw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/keygrip": { | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz", | ||||
| @@ -523,6 +555,16 @@ | ||||
|       "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "argon2": { | ||||
|       "version": "0.24.1", | ||||
|       "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.24.1.tgz", | ||||
|       "integrity": "sha512-2S677iO18I+SQEUONkpvyagF9BJDYdiT82KqSMPQ2zP0oIYagVIPM0Y8T5pJ/4F4CrnN9PTCGA+ye1S0KupW3g==", | ||||
|       "requires": { | ||||
|         "@phc/format": "^0.5.0", | ||||
|         "node-addon-api": "^1.7.1", | ||||
|         "node-gyp-build": "^4.1.0" | ||||
|       } | ||||
|     }, | ||||
|     "argparse": { | ||||
|       "version": "1.0.10", | ||||
|       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", | ||||
| @@ -607,8 +649,27 @@ | ||||
|         "qs": "6.7.0", | ||||
|         "raw-body": "2.4.0", | ||||
|         "type-is": "~1.6.17" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "http-errors": { | ||||
|           "version": "1.7.2", | ||||
|           "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", | ||||
|           "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", | ||||
|           "requires": { | ||||
|             "depd": "~1.1.2", | ||||
|             "inherits": "2.0.3", | ||||
|             "setprototypeof": "1.1.1", | ||||
|             "statuses": ">= 1.5.0 < 2", | ||||
|             "toidentifier": "1.0.0" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "bowser": { | ||||
|       "version": "2.6.1", | ||||
|       "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.6.1.tgz", | ||||
|       "integrity": "sha512-hySGUuLhi0KetfxPZpuJOsjM0kRvCiCgPBygBkzGzJNsq/nbJmaO8QJc6xlWfeFFnMvtd/LeKkhDJGVrmVobUA==" | ||||
|     }, | ||||
|     "brace-expansion": { | ||||
|       "version": "1.1.11", | ||||
|       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||
| @@ -665,6 +726,11 @@ | ||||
|         "map-obj": "^1.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "camelize": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", | ||||
|       "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" | ||||
|     }, | ||||
|     "chalk": { | ||||
|       "version": "2.4.2", | ||||
|       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", | ||||
| @@ -711,6 +777,11 @@ | ||||
|         "safe-buffer": "5.1.2" | ||||
|       } | ||||
|     }, | ||||
|     "content-security-policy-builder": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", | ||||
|       "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==" | ||||
|     }, | ||||
|     "content-type": { | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", | ||||
| @@ -721,6 +792,22 @@ | ||||
|       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", | ||||
|       "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" | ||||
|     }, | ||||
|     "cookie-parser": { | ||||
|       "version": "1.4.4", | ||||
|       "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz", | ||||
|       "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==", | ||||
|       "requires": { | ||||
|         "cookie": "0.3.1", | ||||
|         "cookie-signature": "1.0.6" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "cookie": { | ||||
|           "version": "0.3.1", | ||||
|           "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", | ||||
|           "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "cookie-signature": { | ||||
|       "version": "1.0.6", | ||||
|       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", | ||||
| @@ -749,6 +836,11 @@ | ||||
|         "array-find-index": "^1.0.1" | ||||
|       } | ||||
|     }, | ||||
|     "dasherize": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", | ||||
|       "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" | ||||
|     }, | ||||
|     "dataloader": { | ||||
|       "version": "1.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", | ||||
| @@ -821,6 +913,16 @@ | ||||
|       "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "dns-prefetch-control": { | ||||
|       "version": "0.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", | ||||
|       "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q==" | ||||
|     }, | ||||
|     "dont-sniff-mimetype": { | ||||
|       "version": "1.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", | ||||
|       "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" | ||||
|     }, | ||||
|     "dotenv": { | ||||
|       "version": "8.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.1.0.tgz", | ||||
| @@ -923,6 +1025,11 @@ | ||||
|       "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", | ||||
|       "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" | ||||
|     }, | ||||
|     "expect-ct": { | ||||
|       "version": "0.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", | ||||
|       "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==" | ||||
|     }, | ||||
|     "express": { | ||||
|       "version": "4.17.1", | ||||
|       "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", | ||||
| @@ -983,6 +1090,11 @@ | ||||
|       "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", | ||||
|       "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" | ||||
|     }, | ||||
|     "feature-policy": { | ||||
|       "version": "0.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", | ||||
|       "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==" | ||||
|     }, | ||||
|     "filewatcher": { | ||||
|       "version": "3.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz", | ||||
| @@ -1026,6 +1138,11 @@ | ||||
|       "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", | ||||
|       "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" | ||||
|     }, | ||||
|     "frameguard": { | ||||
|       "version": "3.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", | ||||
|       "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==" | ||||
|     }, | ||||
|     "fresh": { | ||||
|       "version": "0.5.2", | ||||
|       "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", | ||||
| @@ -1152,22 +1269,99 @@ | ||||
|       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", | ||||
|       "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" | ||||
|     }, | ||||
|     "helmet": { | ||||
|       "version": "3.21.1", | ||||
|       "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", | ||||
|       "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", | ||||
|       "requires": { | ||||
|         "depd": "2.0.0", | ||||
|         "dns-prefetch-control": "0.2.0", | ||||
|         "dont-sniff-mimetype": "1.1.0", | ||||
|         "expect-ct": "0.2.0", | ||||
|         "feature-policy": "0.3.0", | ||||
|         "frameguard": "3.1.0", | ||||
|         "helmet-crossdomain": "0.4.0", | ||||
|         "helmet-csp": "2.9.2", | ||||
|         "hide-powered-by": "1.1.0", | ||||
|         "hpkp": "2.0.0", | ||||
|         "hsts": "2.2.0", | ||||
|         "ienoopen": "1.1.0", | ||||
|         "nocache": "2.1.0", | ||||
|         "referrer-policy": "1.2.0", | ||||
|         "x-xss-protection": "1.3.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "depd": { | ||||
|           "version": "2.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", | ||||
|           "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "helmet-crossdomain": { | ||||
|       "version": "0.4.0", | ||||
|       "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz", | ||||
|       "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" | ||||
|     }, | ||||
|     "helmet-csp": { | ||||
|       "version": "2.9.2", | ||||
|       "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", | ||||
|       "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", | ||||
|       "requires": { | ||||
|         "bowser": "^2.6.1", | ||||
|         "camelize": "1.0.0", | ||||
|         "content-security-policy-builder": "2.1.0", | ||||
|         "dasherize": "2.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "hide-powered-by": { | ||||
|       "version": "1.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", | ||||
|       "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" | ||||
|     }, | ||||
|     "hosted-git-info": { | ||||
|       "version": "2.8.4", | ||||
|       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", | ||||
|       "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "hpkp": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", | ||||
|       "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" | ||||
|     }, | ||||
|     "hsts": { | ||||
|       "version": "2.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", | ||||
|       "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", | ||||
|       "requires": { | ||||
|         "depd": "2.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "depd": { | ||||
|           "version": "2.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", | ||||
|           "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "http-errors": { | ||||
|       "version": "1.7.2", | ||||
|       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", | ||||
|       "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", | ||||
|       "version": "1.7.3", | ||||
|       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", | ||||
|       "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", | ||||
|       "requires": { | ||||
|         "depd": "~1.1.2", | ||||
|         "inherits": "2.0.3", | ||||
|         "inherits": "2.0.4", | ||||
|         "setprototypeof": "1.1.1", | ||||
|         "statuses": ">= 1.5.0 < 2", | ||||
|         "toidentifier": "1.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "inherits": { | ||||
|           "version": "2.0.4", | ||||
|           "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", | ||||
|           "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "iconv-lite": { | ||||
| @@ -1178,6 +1372,11 @@ | ||||
|         "safer-buffer": ">= 2.1.2 < 3" | ||||
|       } | ||||
|     }, | ||||
|     "ienoopen": { | ||||
|       "version": "1.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", | ||||
|       "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" | ||||
|     }, | ||||
|     "indent-string": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", | ||||
| @@ -1466,11 +1665,26 @@ | ||||
|       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", | ||||
|       "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" | ||||
|     }, | ||||
|     "nocache": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", | ||||
|       "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" | ||||
|     }, | ||||
|     "node-addon-api": { | ||||
|       "version": "1.7.1", | ||||
|       "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", | ||||
|       "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==" | ||||
|     }, | ||||
|     "node-fetch": { | ||||
|       "version": "2.6.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", | ||||
|       "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" | ||||
|     }, | ||||
|     "node-gyp-build": { | ||||
|       "version": "4.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", | ||||
|       "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==" | ||||
|     }, | ||||
|     "node-notifier": { | ||||
|       "version": "5.4.3", | ||||
|       "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", | ||||
| @@ -1843,6 +2057,20 @@ | ||||
|         "http-errors": "1.7.2", | ||||
|         "iconv-lite": "0.4.24", | ||||
|         "unpipe": "1.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "http-errors": { | ||||
|           "version": "1.7.2", | ||||
|           "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", | ||||
|           "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", | ||||
|           "requires": { | ||||
|             "depd": "~1.1.2", | ||||
|             "inherits": "2.0.3", | ||||
|             "setprototypeof": "1.1.1", | ||||
|             "statuses": ">= 1.5.0 < 2", | ||||
|             "toidentifier": "1.0.0" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "read-pkg": { | ||||
| @@ -1887,6 +2115,11 @@ | ||||
|         "strip-indent": "^1.0.1" | ||||
|       } | ||||
|     }, | ||||
|     "referrer-policy": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", | ||||
|       "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" | ||||
|     }, | ||||
|     "repeating": { | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", | ||||
| @@ -2312,6 +2545,16 @@ | ||||
|         "tslib": "^1.8.1" | ||||
|       } | ||||
|     }, | ||||
|     "tweetnacl": { | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", | ||||
|       "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" | ||||
|     }, | ||||
|     "tweetnacl-util": { | ||||
|       "version": "0.15.0", | ||||
|       "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.0.tgz", | ||||
|       "integrity": "sha1-RXbBzuXi1j0gf+5S8boCgZSAvHU=" | ||||
|     }, | ||||
|     "type-is": { | ||||
|       "version": "1.6.18", | ||||
|       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", | ||||
| @@ -2395,6 +2638,11 @@ | ||||
|         "async-limiter": "~1.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "x-xss-protection": { | ||||
|       "version": "1.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", | ||||
|       "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==" | ||||
|     }, | ||||
|     "xtend": { | ||||
|       "version": "4.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", | ||||
|   | ||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							| @@ -15,20 +15,29 @@ | ||||
|   "license": "AGPL-3.0-or-later", | ||||
|   "dependencies": { | ||||
|     "apollo-server-express": "^2.9.3", | ||||
|     "argon2": "^0.24.1", | ||||
|     "cookie-parser": "^1.4.4", | ||||
|     "dataloader": "^1.4.0", | ||||
|     "dotenv": "^8.1.0", | ||||
|     "express": "^4.17.1", | ||||
|     "express-pino-logger": "^4.0.0", | ||||
|     "graphql": "^14.5.7", | ||||
|     "helmet": "^3.21.1", | ||||
|     "http-errors": "^1.7.3", | ||||
|     "luxon": "^1.19.2", | ||||
|     "monet": "^0.9.0", | ||||
|     "pg-promise": "^9.2.1", | ||||
|     "pino": "^5.13.3" | ||||
|     "pino": "^5.13.3", | ||||
|     "tweetnacl": "^1.0.1", | ||||
|     "tweetnacl-util": "^0.15.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/cookie-parser": "^1.4.2", | ||||
|     "@types/dotenv": "^6.1.1", | ||||
|     "@types/express": "^4.17.1", | ||||
|     "@types/express-pino-logger": "^4.0.1", | ||||
|     "@types/helmet": "0.0.44", | ||||
|     "@types/http-errors": "^1.6.2", | ||||
|     "@types/luxon": "^1.15.2", | ||||
|     "@types/node": "^12.7.5", | ||||
|     "@types/pino": "^5.8.10", | ||||
|   | ||||
							
								
								
									
										24
									
								
								samples.http
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								samples.http
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| # @name: login | ||||
|  | ||||
| POST {{ baseUrl }}/auth/ HTTP/1.1 | ||||
| Content-type: application/json | ||||
|  | ||||
| { | ||||
|     "email": "test@test.com", | ||||
|     "password": "hornyhorny" | ||||
| } | ||||
|  | ||||
| ### | ||||
|  | ||||
| GET {{ baseUrl }}/auth/bootstrap HTTP/1.1 | ||||
|  | ||||
| ### | ||||
|  | ||||
| POST {{ baseUrl }}/auth/bootstrap HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| { | ||||
|     "token": {{ bootstrapToken }}, | ||||
|     "email": "test@test.com", | ||||
|     "password": "hornyhorny" | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/crypto.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/crypto.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| // Copyright (C) 2019 ModZero <modzero@modzero.xyz> | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU Affero General Public License as | ||||
| // published by the Free Software Foundation, either version 3 of the | ||||
| // License, or (at your option) any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| // GNU Affero General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU Affero General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import { randomBytes, secretbox } from "tweetnacl"; | ||||
| import { | ||||
|   decodeBase64, | ||||
|   decodeUTF8, | ||||
|   encodeBase64, | ||||
|   encodeUTF8 | ||||
| } from "tweetnacl-util"; | ||||
|  | ||||
| const secret = decodeBase64(process.env.SECRET); | ||||
| const newNonce = () => randomBytes(secretbox.nonceLength); | ||||
| const secretBoxKey = secret.slice(0, secretbox.keyLength); | ||||
| if (secretBoxKey.length !== secretbox.keyLength) { | ||||
|   throw new Error("Secret too short to encrypt anything"); | ||||
| } | ||||
|  | ||||
| export const box = (json: any, key: Uint8Array = secretBoxKey) => { | ||||
|   const nonce = newNonce(); | ||||
|   const messageUint8 = decodeUTF8(JSON.stringify(json)); | ||||
|   const encrypted = secretbox(messageUint8, nonce, key); | ||||
|   const fullMessage = new Uint8Array(nonce.length + encrypted.length); | ||||
|   fullMessage.set(nonce); | ||||
|   fullMessage.set(encrypted, nonce.length); | ||||
|  | ||||
|   return encodeBase64(fullMessage); | ||||
| }; | ||||
|  | ||||
| export const unbox = ( | ||||
|   messageWithNonce: string, | ||||
|   key: Uint8Array = secretBoxKey | ||||
| ) => { | ||||
|   const fullMessageUint8 = decodeBase64(messageWithNonce); | ||||
|   const nonce = fullMessageUint8.slice(0, secretbox.nonceLength); | ||||
|   const message = fullMessageUint8.slice( | ||||
|     secretbox.nonceLength, | ||||
|     fullMessageUint8.length | ||||
|   ); | ||||
|  | ||||
|   const decrypted = secretbox.open(message, nonce, key); | ||||
|   return JSON.parse(encodeUTF8(decrypted)); | ||||
| }; | ||||
| @@ -14,13 +14,14 @@ | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import pgPromise, { IDatabase, IInitOptions } from "pg-promise"; | ||||
| import { Extensions, MigrationRepository } from "./repos"; | ||||
| import { Extensions, MigrationRepository, UserRepository } from "./repos"; | ||||
|  | ||||
| type ExtendedProtocol = IDatabase<Extensions> & Extensions; | ||||
|  | ||||
| const initOptions: IInitOptions<Extensions> = { | ||||
|   extend(obj: ExtendedProtocol, dc: any) { | ||||
|     obj.migrations = new MigrationRepository(obj, pgp); | ||||
|     obj.users = new UserRepository(obj, pgp); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -14,9 +14,11 @@ | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import { MigrationRepository } from "./migrations"; | ||||
| import { UserRepository } from "./users"; | ||||
|  | ||||
| export interface Extensions { | ||||
|   migrations: MigrationRepository; | ||||
|   users: UserRepository; | ||||
| } | ||||
|  | ||||
| export { MigrationRepository }; | ||||
| export { MigrationRepository, UserRepository }; | ||||
|   | ||||
							
								
								
									
										50
									
								
								src/db/repos/users.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/db/repos/users.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // Copyright (C) 2019 ModZero <modzero@modzero.xyz> | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU Affero General Public License as | ||||
| // published by the Free Software Foundation, either version 3 of the | ||||
| // License, or (at your option) any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| // GNU Affero General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU Affero General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import argon2 from "argon2"; | ||||
| import { Maybe, None, Some } from "monet"; | ||||
| import { IDatabase, IMain } from "pg-promise"; | ||||
| import { users as sql } from "../sql"; | ||||
|  | ||||
| export class UserRepository { | ||||
|   private db: IDatabase<any>; | ||||
|  | ||||
|   constructor(db: IDatabase<any>, pgp: IMain) { | ||||
|     this.db = db; | ||||
|   } | ||||
|  | ||||
|   public async login(email: string, password: string): Promise<Maybe<number>> { | ||||
|     const { id, encryptedPassword } = await this.db | ||||
|       .oneOrNone(sql.login, [email]) | ||||
|       .then(user => ({ | ||||
|         encryptedPassword: user.encrypted_password, | ||||
|         id: +user.id | ||||
|       })); | ||||
|     if (id === null) { | ||||
|       return None(); | ||||
|     } | ||||
|  | ||||
|     return (await argon2.verify(encryptedPassword, password)) | ||||
|       ? Some(id) | ||||
|       : None(); | ||||
|   } | ||||
|  | ||||
|   public async create(email: string, password: string): Promise<number> { | ||||
|     const encryptedPassword = await argon2.hash(password); | ||||
|     return this.db | ||||
|       .one(sql.create, [email, encryptedPassword]) | ||||
|       .then((user: { id: number }) => +user.id); | ||||
|   } | ||||
| } | ||||
| @@ -33,7 +33,12 @@ const migrations = { | ||||
|   })) | ||||
| }; | ||||
|  | ||||
| export { migrations }; | ||||
| const users = { | ||||
|   create: sql("users/create.sql"), | ||||
|   login: sql("users/login.sql") | ||||
| }; | ||||
|  | ||||
| export { migrations, users }; | ||||
|  | ||||
| /** Helper for linking to external query files */ | ||||
| function sql(file: string): QueryFile { | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/db/sql/users/create.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/db/sql/users/create.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| INSERT INTO users (email, encrypted_password) VALUES ($1, $2) RETURNING id | ||||
							
								
								
									
										1
									
								
								src/db/sql/users/login.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/db/sql/users/login.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| SELECT id, encrypted_password FROM users WHERE email=$1 | ||||
							
								
								
									
										26
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/index.ts
									
									
									
									
									
								
							| @@ -13,23 +13,41 @@ | ||||
| // You should have received a copy of the GNU Affero General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import cookieParser from "cookie-parser"; | ||||
| import express from "express"; | ||||
| import pinoExpress from "express-pino-logger"; | ||||
| import helmet from "helmet"; | ||||
| import createHttpError from "http-errors"; | ||||
| import { db } from "./db"; | ||||
| import { server as graphqlServer } from "./graphql"; | ||||
| import logger from "./logger"; | ||||
| import authRouter from "./routes/auth"; | ||||
| import indexRouter from "./routes/index"; | ||||
|  | ||||
| async function main() { | ||||
|   await db.migrations.create(); | ||||
|   await db.migrations.apply(); | ||||
|   await db.tx(async t => { | ||||
|     await t.migrations.create(); | ||||
|     await t.migrations.apply(); | ||||
|   }); | ||||
|  | ||||
|   const server = graphqlServer(); | ||||
|   const app = express(); | ||||
|   const expressPino = pinoExpress({ logger }); | ||||
|   app.use(helmet()); | ||||
|   app.use(expressPino); | ||||
|   server.applyMiddleware({ app, path: "/graphql" }); | ||||
|   const port = 3000; | ||||
|   app.use(express.json()); | ||||
|   app.use(express.urlencoded({ extended: false })); | ||||
|   app.use(cookieParser()); | ||||
|  | ||||
|   app.use("/", indexRouter); | ||||
|   app.use("/auth/", authRouter); | ||||
|   server.applyMiddleware({ app, path: "/graphql" }); | ||||
|  | ||||
|   app.use((req, res, next) => { | ||||
|     next(createHttpError(404)); | ||||
|   }); | ||||
|  | ||||
|   const port = 3000; | ||||
|   app.listen(port, () => | ||||
|     logger.info("Example app listening", { | ||||
|       uri: `http://localhost:${port}${server.graphqlPath}` | ||||
|   | ||||
							
								
								
									
										64
									
								
								src/routes/auth.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/routes/auth.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| // Copyright (C) 2019 ModZero <modzero@modzero.xyz> | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU Affero General Public License as | ||||
| // published by the Free Software Foundation, either version 3 of the | ||||
| // License, or (at your option) any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| // GNU Affero General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU Affero General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import express from "express"; | ||||
| import createHttpError from "http-errors"; | ||||
| import { DateTime } from "luxon"; | ||||
| import { box, unbox } from "../crypto"; | ||||
| import { db } from "../db"; | ||||
|  | ||||
| const router = express.Router(); | ||||
|  | ||||
| router.post("/", async (req, res, next) => { | ||||
|   const userID = await db.users.login(req.body.email, req.body.password); | ||||
|   if (userID.isSome()) { | ||||
|     res.send(`Hi, ${userID.some()}`); | ||||
|   } else { | ||||
|     res.send(`Go away.`); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| interface Token { | ||||
|   expires: string; | ||||
| } | ||||
|  | ||||
| router.get("/bootstrap", async (req, res, next) => { | ||||
|   const token: Token = { | ||||
|     expires: DateTime.local() | ||||
|       .plus({ hours: 2 }) | ||||
|       .toISO() | ||||
|   }; | ||||
|   req.log.info("Token issued", { token: box(token) }); | ||||
| }); | ||||
|  | ||||
| router.post("/bootstrap", async (req, res, next) => { | ||||
|   const token: Token = unbox(req.body.token); | ||||
|   const expired = DateTime.fromISO(token.expires).diffNow(); | ||||
|   if (expired.as("milliseconds") < 0) { | ||||
|     next(createHttpError(401)); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   const email: string = req.body.email; | ||||
|   const password: string = req.body.password; | ||||
|  | ||||
|   if (!email || !password || password.length < 8) { | ||||
|     res.send("Please provide an email and a password longer than 8 characters"); | ||||
|     return; | ||||
|   } | ||||
|   await db.users.create(email, password); | ||||
| }); | ||||
|  | ||||
| export default router; | ||||
							
								
								
									
										24
									
								
								src/routes/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/routes/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| // Copyright (C) 2019 ModZero <modzero@modzero.xyz> | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU Affero General Public License as | ||||
| // published by the Free Software Foundation, either version 3 of the | ||||
| // License, or (at your option) any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| // GNU Affero General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU Affero General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import express from "express"; | ||||
|  | ||||
| const router = express.Router(); | ||||
|  | ||||
| router.get("/", (req, res, next) => { | ||||
|   res.send("Hello, world!"); | ||||
| }); | ||||
|  | ||||
| export default router; | ||||
		Reference in New Issue
	
	Block a user