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==", |       "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", | ||||||
|       "dev": true |       "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": { |     "@protobufjs/aspromise": { | ||||||
|       "version": "1.1.2", |       "version": "1.1.2", | ||||||
|       "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", |       "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", | ||||||
| @@ -122,6 +130,15 @@ | |||||||
|         "@types/node": "*" |         "@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": { |     "@types/cookies": { | ||||||
|       "version": "0.7.3", |       "version": "0.7.3", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.3.tgz", |       "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.3.tgz", | ||||||
| @@ -198,11 +215,26 @@ | |||||||
|         "graphql": "^14.5.3" |         "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": { |     "@types/http-assert": { | ||||||
|       "version": "1.5.1", |       "version": "1.5.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", |       "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", | ||||||
|       "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==" |       "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": { |     "@types/keygrip": { | ||||||
|       "version": "1.0.1", |       "version": "1.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz", |       "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz", | ||||||
| @@ -523,6 +555,16 @@ | |||||||
|       "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", |       "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", | ||||||
|       "dev": true |       "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": { |     "argparse": { | ||||||
|       "version": "1.0.10", |       "version": "1.0.10", | ||||||
|       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", |       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", | ||||||
| @@ -607,8 +649,27 @@ | |||||||
|         "qs": "6.7.0", |         "qs": "6.7.0", | ||||||
|         "raw-body": "2.4.0", |         "raw-body": "2.4.0", | ||||||
|         "type-is": "~1.6.17" |         "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": { |     "brace-expansion": { | ||||||
|       "version": "1.1.11", |       "version": "1.1.11", | ||||||
|       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", |       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||||
| @@ -665,6 +726,11 @@ | |||||||
|         "map-obj": "^1.0.0" |         "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": { |     "chalk": { | ||||||
|       "version": "2.4.2", |       "version": "2.4.2", | ||||||
|       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", |       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", | ||||||
| @@ -711,6 +777,11 @@ | |||||||
|         "safe-buffer": "5.1.2" |         "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": { |     "content-type": { | ||||||
|       "version": "1.0.4", |       "version": "1.0.4", | ||||||
|       "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", |       "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", |       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", | ||||||
|       "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" |       "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": { |     "cookie-signature": { | ||||||
|       "version": "1.0.6", |       "version": "1.0.6", | ||||||
|       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", |       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", | ||||||
| @@ -749,6 +836,11 @@ | |||||||
|         "array-find-index": "^1.0.1" |         "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": { |     "dataloader": { | ||||||
|       "version": "1.4.0", |       "version": "1.4.0", | ||||||
|       "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", |       "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", | ||||||
| @@ -821,6 +913,16 @@ | |||||||
|       "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", |       "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", | ||||||
|       "dev": true |       "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": { |     "dotenv": { | ||||||
|       "version": "8.1.0", |       "version": "8.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.1.0.tgz", |       "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", |       "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", | ||||||
|       "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" |       "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": { |     "express": { | ||||||
|       "version": "4.17.1", |       "version": "4.17.1", | ||||||
|       "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", |       "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", |       "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", | ||||||
|       "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" |       "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": { |     "filewatcher": { | ||||||
|       "version": "3.0.1", |       "version": "3.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz", |       "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", |       "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", | ||||||
|       "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" |       "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": { |     "fresh": { | ||||||
|       "version": "0.5.2", |       "version": "0.5.2", | ||||||
|       "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", |       "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", |       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", | ||||||
|       "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" |       "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": { |     "hosted-git-info": { | ||||||
|       "version": "2.8.4", |       "version": "2.8.4", | ||||||
|       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", |       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", | ||||||
|       "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", |       "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", | ||||||
|       "dev": true |       "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": { |     "http-errors": { | ||||||
|       "version": "1.7.2", |       "version": "1.7.3", | ||||||
|       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", |       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", | ||||||
|       "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", |       "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "depd": "~1.1.2", |         "depd": "~1.1.2", | ||||||
|         "inherits": "2.0.3", |         "inherits": "2.0.4", | ||||||
|         "setprototypeof": "1.1.1", |         "setprototypeof": "1.1.1", | ||||||
|         "statuses": ">= 1.5.0 < 2", |         "statuses": ">= 1.5.0 < 2", | ||||||
|         "toidentifier": "1.0.0" |         "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": { |     "iconv-lite": { | ||||||
| @@ -1178,6 +1372,11 @@ | |||||||
|         "safer-buffer": ">= 2.1.2 < 3" |         "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": { |     "indent-string": { | ||||||
|       "version": "2.1.0", |       "version": "2.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", |       "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", |       "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", | ||||||
|       "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" |       "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": { |     "node-fetch": { | ||||||
|       "version": "2.6.0", |       "version": "2.6.0", | ||||||
|       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", |       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", | ||||||
|       "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" |       "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": { |     "node-notifier": { | ||||||
|       "version": "5.4.3", |       "version": "5.4.3", | ||||||
|       "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", |       "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", | ||||||
| @@ -1843,6 +2057,20 @@ | |||||||
|         "http-errors": "1.7.2", |         "http-errors": "1.7.2", | ||||||
|         "iconv-lite": "0.4.24", |         "iconv-lite": "0.4.24", | ||||||
|         "unpipe": "1.0.0" |         "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": { |     "read-pkg": { | ||||||
| @@ -1887,6 +2115,11 @@ | |||||||
|         "strip-indent": "^1.0.1" |         "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": { |     "repeating": { | ||||||
|       "version": "2.0.1", |       "version": "2.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", |       "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", | ||||||
| @@ -2312,6 +2545,16 @@ | |||||||
|         "tslib": "^1.8.1" |         "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": { |     "type-is": { | ||||||
|       "version": "1.6.18", |       "version": "1.6.18", | ||||||
|       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", |       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", | ||||||
| @@ -2395,6 +2638,11 @@ | |||||||
|         "async-limiter": "~1.0.0" |         "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": { |     "xtend": { | ||||||
|       "version": "4.0.2", |       "version": "4.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", |       "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", |   "license": "AGPL-3.0-or-later", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "apollo-server-express": "^2.9.3", |     "apollo-server-express": "^2.9.3", | ||||||
|  |     "argon2": "^0.24.1", | ||||||
|  |     "cookie-parser": "^1.4.4", | ||||||
|     "dataloader": "^1.4.0", |     "dataloader": "^1.4.0", | ||||||
|     "dotenv": "^8.1.0", |     "dotenv": "^8.1.0", | ||||||
|     "express": "^4.17.1", |     "express": "^4.17.1", | ||||||
|     "express-pino-logger": "^4.0.0", |     "express-pino-logger": "^4.0.0", | ||||||
|     "graphql": "^14.5.7", |     "graphql": "^14.5.7", | ||||||
|  |     "helmet": "^3.21.1", | ||||||
|  |     "http-errors": "^1.7.3", | ||||||
|     "luxon": "^1.19.2", |     "luxon": "^1.19.2", | ||||||
|     "monet": "^0.9.0", |     "monet": "^0.9.0", | ||||||
|     "pg-promise": "^9.2.1", |     "pg-promise": "^9.2.1", | ||||||
|     "pino": "^5.13.3" |     "pino": "^5.13.3", | ||||||
|  |     "tweetnacl": "^1.0.1", | ||||||
|  |     "tweetnacl-util": "^0.15.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "@types/cookie-parser": "^1.4.2", | ||||||
|     "@types/dotenv": "^6.1.1", |     "@types/dotenv": "^6.1.1", | ||||||
|     "@types/express": "^4.17.1", |     "@types/express": "^4.17.1", | ||||||
|     "@types/express-pino-logger": "^4.0.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/luxon": "^1.15.2", | ||||||
|     "@types/node": "^12.7.5", |     "@types/node": "^12.7.5", | ||||||
|     "@types/pino": "^5.8.10", |     "@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/>. | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
| import pgPromise, { IDatabase, IInitOptions } from "pg-promise"; | import pgPromise, { IDatabase, IInitOptions } from "pg-promise"; | ||||||
| import { Extensions, MigrationRepository } from "./repos"; | import { Extensions, MigrationRepository, UserRepository } from "./repos"; | ||||||
|  |  | ||||||
| type ExtendedProtocol = IDatabase<Extensions> & Extensions; | type ExtendedProtocol = IDatabase<Extensions> & Extensions; | ||||||
|  |  | ||||||
| const initOptions: IInitOptions<Extensions> = { | const initOptions: IInitOptions<Extensions> = { | ||||||
|   extend(obj: ExtendedProtocol, dc: any) { |   extend(obj: ExtendedProtocol, dc: any) { | ||||||
|     obj.migrations = new MigrationRepository(obj, pgp); |     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/>. | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
| import { MigrationRepository } from "./migrations"; | import { MigrationRepository } from "./migrations"; | ||||||
|  | import { UserRepository } from "./users"; | ||||||
|  |  | ||||||
| export interface Extensions { | export interface Extensions { | ||||||
|   migrations: MigrationRepository; |   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 */ | /** Helper for linking to external query files */ | ||||||
| function sql(file: string): QueryFile { | 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 | // 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/>. | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | import cookieParser from "cookie-parser"; | ||||||
| import express from "express"; | import express from "express"; | ||||||
| import pinoExpress from "express-pino-logger"; | import pinoExpress from "express-pino-logger"; | ||||||
|  | import helmet from "helmet"; | ||||||
|  | import createHttpError from "http-errors"; | ||||||
| import { db } from "./db"; | import { db } from "./db"; | ||||||
| import { server as graphqlServer } from "./graphql"; | import { server as graphqlServer } from "./graphql"; | ||||||
| import logger from "./logger"; | import logger from "./logger"; | ||||||
|  | import authRouter from "./routes/auth"; | ||||||
|  | import indexRouter from "./routes/index"; | ||||||
|  |  | ||||||
| async function main() { | async function main() { | ||||||
|   await db.migrations.create(); |   await db.tx(async t => { | ||||||
|   await db.migrations.apply(); |     await t.migrations.create(); | ||||||
|  |     await t.migrations.apply(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   const server = graphqlServer(); |   const server = graphqlServer(); | ||||||
|   const app = express(); |   const app = express(); | ||||||
|   const expressPino = pinoExpress({ logger }); |   const expressPino = pinoExpress({ logger }); | ||||||
|  |   app.use(helmet()); | ||||||
|   app.use(expressPino); |   app.use(expressPino); | ||||||
|   server.applyMiddleware({ app, path: "/graphql" }); |   app.use(express.json()); | ||||||
|   const port = 3000; |   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, () => |   app.listen(port, () => | ||||||
|     logger.info("Example app listening", { |     logger.info("Example app listening", { | ||||||
|       uri: `http://localhost:${port}${server.graphqlPath}` |       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