This commit is contained in:
parent
c264d45927
commit
91abcdf8ef
@ -8,6 +8,7 @@
|
|||||||
"lib": "lib"
|
"lib": "lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/bcrypt": "^5.0.0",
|
||||||
"@types/busboy": "^0.2.3",
|
"@types/busboy": "^0.2.3",
|
||||||
"@types/mkdirp": "^1.0.1",
|
"@types/mkdirp": "^1.0.1",
|
||||||
"@types/negotiator": "^0.6.1",
|
"@types/negotiator": "^0.6.1",
|
||||||
@ -18,6 +19,7 @@
|
|||||||
"@types/rimraf": "^3.0.0",
|
"@types/rimraf": "^3.0.0",
|
||||||
"@types/ssh2": "^0.5.46",
|
"@types/ssh2": "^0.5.46",
|
||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
|
"bcrypt": "^5.0.1",
|
||||||
"busboy": "^0.3.1",
|
"busboy": "^0.3.1",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
|
285
pnpm-lock.yaml
285
pnpm-lock.yaml
@ -1,4 +1,5 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
|
'@types/bcrypt': 5.0.0
|
||||||
'@types/busboy': 0.2.3
|
'@types/busboy': 0.2.3
|
||||||
'@types/mkdirp': 1.0.1
|
'@types/mkdirp': 1.0.1
|
||||||
'@types/negotiator': 0.6.1
|
'@types/negotiator': 0.6.1
|
||||||
@ -9,6 +10,7 @@ dependencies:
|
|||||||
'@types/rimraf': 3.0.0
|
'@types/rimraf': 3.0.0
|
||||||
'@types/ssh2': 0.5.46
|
'@types/ssh2': 0.5.46
|
||||||
'@types/uuid': 8.3.0
|
'@types/uuid': 8.3.0
|
||||||
|
bcrypt: 5.0.1
|
||||||
busboy: 0.3.1
|
busboy: 0.3.1
|
||||||
colors: 1.4.0
|
colors: 1.4.0
|
||||||
dotenv: 8.2.0
|
dotenv: 8.2.0
|
||||||
@ -85,6 +87,21 @@ packages:
|
|||||||
node: ^10.12.0 || >=12.0.0
|
node: ^10.12.0 || >=12.0.0
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==
|
integrity: sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==
|
||||||
|
/@mapbox/node-pre-gyp/1.0.5:
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 1.0.3
|
||||||
|
https-proxy-agent: 5.0.0
|
||||||
|
make-dir: 3.1.0
|
||||||
|
node-fetch: 2.6.1
|
||||||
|
nopt: 5.0.0
|
||||||
|
npmlog: 4.1.2
|
||||||
|
rimraf: 3.0.2
|
||||||
|
semver: 7.3.5
|
||||||
|
tar: 6.1.0
|
||||||
|
dev: false
|
||||||
|
hasBin: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==
|
||||||
/@nodelib/fs.scandir/2.1.4:
|
/@nodelib/fs.scandir/2.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nodelib/fs.stat': 2.0.4
|
'@nodelib/fs.stat': 2.0.4
|
||||||
@ -109,6 +126,12 @@ packages:
|
|||||||
node: '>= 8'
|
node: '>= 8'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==
|
integrity: sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==
|
||||||
|
/@types/bcrypt/5.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 14.17.2
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==
|
||||||
/@types/busboy/0.2.3:
|
/@types/busboy/0.2.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 14.14.37
|
'@types/node': 14.14.37
|
||||||
@ -148,6 +171,10 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw==
|
integrity: sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw==
|
||||||
|
/@types/node/14.17.2:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-sld7b/xmFum66AAKuz/rp/CUO8+98fMpyQ3SBfzzBNGMd/1iHBTAg9oyAvcYlAj46bpc74r91jSw2iFdnx29nw==
|
||||||
/@types/pg/8.6.0:
|
/@types/pg/8.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 14.17.1
|
'@types/node': 14.17.1
|
||||||
@ -293,6 +320,10 @@ packages:
|
|||||||
node: ^8.10.0 || ^10.13.0 || >=11.10.1
|
node: ^8.10.0 || ^10.13.0 || >=11.10.1
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg==
|
integrity: sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg==
|
||||||
|
/abbrev/1.1.1:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
|
||||||
/acorn-jsx/5.3.1_acorn@7.4.1:
|
/acorn-jsx/5.3.1_acorn@7.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
acorn: 7.4.1
|
acorn: 7.4.1
|
||||||
@ -307,6 +338,14 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||||
|
/agent-base/6.0.2:
|
||||||
|
dependencies:
|
||||||
|
debug: 4.3.1
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>= 6.0.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
|
||||||
/ajv/6.12.6:
|
/ajv/6.12.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal: 3.1.3
|
fast-deep-equal: 3.1.3
|
||||||
@ -331,6 +370,12 @@ packages:
|
|||||||
node: '>=6'
|
node: '>=6'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
||||||
|
/ansi-regex/2.1.1:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.10.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
||||||
/ansi-regex/5.0.0:
|
/ansi-regex/5.0.0:
|
||||||
dev: true
|
dev: true
|
||||||
engines:
|
engines:
|
||||||
@ -353,6 +398,17 @@ packages:
|
|||||||
node: '>=8'
|
node: '>=8'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||||
|
/aproba/1.2.0:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
|
||||||
|
/are-we-there-yet/1.1.5:
|
||||||
|
dependencies:
|
||||||
|
delegates: 1.0.0
|
||||||
|
readable-stream: 2.3.7
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
|
||||||
/arg/4.1.3:
|
/arg/4.1.3:
|
||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
@ -412,6 +468,16 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
|
integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
|
||||||
|
/bcrypt/5.0.1:
|
||||||
|
dependencies:
|
||||||
|
'@mapbox/node-pre-gyp': 1.0.5
|
||||||
|
node-addon-api: 3.2.1
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>= 10.0.0'
|
||||||
|
requiresBuild: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==
|
||||||
/brace-expansion/1.1.11:
|
/brace-expansion/1.1.11:
|
||||||
dependencies:
|
dependencies:
|
||||||
balanced-match: 1.0.2
|
balanced-match: 1.0.2
|
||||||
@ -482,6 +548,18 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-x84o821LzZdE5f/CxfzeHHMmH8A=
|
integrity: sha1-x84o821LzZdE5f/CxfzeHHMmH8A=
|
||||||
|
/chownr/2.0.0:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=10'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
|
||||||
|
/code-point-at/1.1.0:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.10.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||||
/color-convert/1.9.3:
|
/color-convert/1.9.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
color-name: 1.1.3
|
color-name: 1.1.3
|
||||||
@ -517,6 +595,10 @@ packages:
|
|||||||
/concat-map/0.0.1:
|
/concat-map/0.0.1:
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
/console-control-strings/1.1.0:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
|
||||||
/constantinople/4.0.1:
|
/constantinople/4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.13.13
|
'@babel/parser': 7.13.13
|
||||||
@ -524,6 +606,10 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==
|
integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==
|
||||||
|
/core-util-is/1.0.2:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||||
/cpu-features/0.0.2:
|
/cpu-features/0.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
nan: 2.14.2
|
nan: 2.14.2
|
||||||
@ -551,7 +637,6 @@ packages:
|
|||||||
/debug/4.3.1:
|
/debug/4.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.2
|
ms: 2.1.2
|
||||||
dev: true
|
|
||||||
engines:
|
engines:
|
||||||
node: '>=6.0'
|
node: '>=6.0'
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -565,6 +650,17 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||||
|
/delegates/1.0.0:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
|
||||||
|
/detect-libc/1.0.3:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.10'
|
||||||
|
hasBin: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
|
||||||
/dicer/0.3.0:
|
/dicer/0.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
streamsearch: 0.1.2
|
streamsearch: 0.1.2
|
||||||
@ -838,6 +934,14 @@ packages:
|
|||||||
node: '>=10'
|
node: '>=10'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
|
integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
|
||||||
|
/fs-minipass/2.1.0:
|
||||||
|
dependencies:
|
||||||
|
minipass: 3.1.3
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>= 8'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
|
||||||
/fs.realpath/1.0.0:
|
/fs.realpath/1.0.0:
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||||
@ -849,6 +953,19 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||||
|
/gauge/2.7.4:
|
||||||
|
dependencies:
|
||||||
|
aproba: 1.2.0
|
||||||
|
console-control-strings: 1.1.0
|
||||||
|
has-unicode: 2.0.1
|
||||||
|
object-assign: 4.1.1
|
||||||
|
signal-exit: 3.0.3
|
||||||
|
string-width: 1.0.2
|
||||||
|
strip-ansi: 3.0.1
|
||||||
|
wide-align: 1.1.3
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
|
||||||
/get-intrinsic/1.1.1:
|
/get-intrinsic/1.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind: 1.1.1
|
function-bind: 1.1.1
|
||||||
@ -940,6 +1057,10 @@ packages:
|
|||||||
node: '>= 0.4'
|
node: '>= 0.4'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
|
integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
|
||||||
|
/has-unicode/2.0.1:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
|
||||||
/has/1.0.3:
|
/has/1.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind: 1.1.1
|
function-bind: 1.1.1
|
||||||
@ -948,6 +1069,15 @@ packages:
|
|||||||
node: '>= 0.4.0'
|
node: '>= 0.4.0'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||||
|
/https-proxy-agent/5.0.0:
|
||||||
|
dependencies:
|
||||||
|
agent-base: 6.0.2
|
||||||
|
debug: 4.3.1
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>= 6'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
|
||||||
/ignore/4.0.6:
|
/ignore/4.0.6:
|
||||||
dev: true
|
dev: true
|
||||||
engines:
|
engines:
|
||||||
@ -1009,6 +1139,14 @@ packages:
|
|||||||
node: '>=0.10.0'
|
node: '>=0.10.0'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||||
|
/is-fullwidth-code-point/1.0.0:
|
||||||
|
dependencies:
|
||||||
|
number-is-nan: 1.0.1
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.10.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
|
||||||
/is-fullwidth-code-point/3.0.0:
|
/is-fullwidth-code-point/3.0.0:
|
||||||
dev: true
|
dev: true
|
||||||
engines:
|
engines:
|
||||||
@ -1042,6 +1180,10 @@ packages:
|
|||||||
node: '>= 0.4'
|
node: '>= 0.4'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==
|
integrity: sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==
|
||||||
|
/isarray/1.0.0:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||||
/isexe/2.0.0:
|
/isexe/2.0.0:
|
||||||
dev: true
|
dev: true
|
||||||
resolution:
|
resolution:
|
||||||
@ -1122,7 +1264,6 @@ packages:
|
|||||||
/lru-cache/6.0.0:
|
/lru-cache/6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
dev: true
|
|
||||||
engines:
|
engines:
|
||||||
node: '>=10'
|
node: '>=10'
|
||||||
resolution:
|
resolution:
|
||||||
@ -1131,6 +1272,14 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
|
integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
|
||||||
|
/make-dir/3.1.0:
|
||||||
|
dependencies:
|
||||||
|
semver: 6.3.0
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=8'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
|
||||||
/make-error/1.3.6:
|
/make-error/1.3.6:
|
||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
@ -1166,6 +1315,23 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||||
|
/minipass/3.1.3:
|
||||||
|
dependencies:
|
||||||
|
yallist: 4.0.0
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=8'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==
|
||||||
|
/minizlib/2.1.2:
|
||||||
|
dependencies:
|
||||||
|
minipass: 3.1.3
|
||||||
|
yallist: 4.0.0
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>= 8'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
|
||||||
/mkdirp/1.0.4:
|
/mkdirp/1.0.4:
|
||||||
dev: false
|
dev: false
|
||||||
engines:
|
engines:
|
||||||
@ -1174,7 +1340,6 @@ packages:
|
|||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
/ms/2.1.2:
|
/ms/2.1.2:
|
||||||
dev: true
|
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
/nan/2.14.2:
|
/nan/2.14.2:
|
||||||
@ -1196,6 +1361,40 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||||
|
/node-addon-api/3.2.1:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==
|
||||||
|
/node-fetch/2.6.1:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: 4.x || >=6.0.0
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||||
|
/nopt/5.0.0:
|
||||||
|
dependencies:
|
||||||
|
abbrev: 1.1.1
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=6'
|
||||||
|
hasBin: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==
|
||||||
|
/npmlog/4.1.2:
|
||||||
|
dependencies:
|
||||||
|
are-we-there-yet: 1.1.5
|
||||||
|
console-control-strings: 1.1.0
|
||||||
|
gauge: 2.7.4
|
||||||
|
set-blocking: 2.0.0
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
|
||||||
|
/number-is-nan/1.0.1:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.10.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
||||||
/object-assign/4.1.1:
|
/object-assign/4.1.1:
|
||||||
dev: false
|
dev: false
|
||||||
engines:
|
engines:
|
||||||
@ -1362,6 +1561,10 @@ packages:
|
|||||||
node: '>= 0.8.0'
|
node: '>= 0.8.0'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||||
|
/process-nextick-args/2.0.1:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||||
/progress/2.0.3:
|
/progress/2.0.3:
|
||||||
engines:
|
engines:
|
||||||
node: '>=0.4.0'
|
node: '>=0.4.0'
|
||||||
@ -1474,6 +1677,18 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||||
|
/readable-stream/2.3.7:
|
||||||
|
dependencies:
|
||||||
|
core-util-is: 1.0.2
|
||||||
|
inherits: 2.0.4
|
||||||
|
isarray: 1.0.0
|
||||||
|
process-nextick-args: 2.0.1
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
string_decoder: 1.1.1
|
||||||
|
util-deprecate: 1.0.2
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||||
/readable-stream/3.6.0:
|
/readable-stream/3.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
inherits: 2.0.4
|
inherits: 2.0.4
|
||||||
@ -1540,6 +1755,10 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
|
integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
|
||||||
|
/safe-buffer/5.1.2:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||||
/safe-buffer/5.2.1:
|
/safe-buffer/5.2.1:
|
||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
@ -1548,15 +1767,23 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
|
/semver/6.3.0:
|
||||||
|
dev: false
|
||||||
|
hasBin: true
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||||
/semver/7.3.5:
|
/semver/7.3.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache: 6.0.0
|
lru-cache: 6.0.0
|
||||||
dev: true
|
|
||||||
engines:
|
engines:
|
||||||
node: '>=10'
|
node: '>=10'
|
||||||
hasBin: true
|
hasBin: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||||
|
/set-blocking/2.0.0:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||||
/shebang-command/2.0.0:
|
/shebang-command/2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
shebang-regex: 3.0.0
|
shebang-regex: 3.0.0
|
||||||
@ -1589,6 +1816,10 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA==
|
integrity: sha512-NEjg1mVbAUrzRv2eIcUt3TG7X9svX7l3n3F5/3OdFq+/BxUdmBOeKGiH4icZJBLHy354Shnj6sfBTemea2e7XA==
|
||||||
|
/signal-exit/3.0.3:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||||
/slash/3.0.0:
|
/slash/3.0.0:
|
||||||
dev: true
|
dev: true
|
||||||
engines:
|
engines:
|
||||||
@ -1647,6 +1878,16 @@ packages:
|
|||||||
node: '>=0.8.0'
|
node: '>=0.8.0'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
|
integrity: sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
|
||||||
|
/string-width/1.0.2:
|
||||||
|
dependencies:
|
||||||
|
code-point-at: 1.1.0
|
||||||
|
is-fullwidth-code-point: 1.0.0
|
||||||
|
strip-ansi: 3.0.1
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.10.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
|
||||||
/string-width/4.2.2:
|
/string-width/4.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
emoji-regex: 8.0.0
|
emoji-regex: 8.0.0
|
||||||
@ -1657,12 +1898,26 @@ packages:
|
|||||||
node: '>=8'
|
node: '>=8'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
|
integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
|
||||||
|
/string_decoder/1.1.1:
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
|
||||||
/string_decoder/1.3.0:
|
/string_decoder/1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer: 5.2.1
|
safe-buffer: 5.2.1
|
||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||||
|
/strip-ansi/3.0.1:
|
||||||
|
dependencies:
|
||||||
|
ansi-regex: 2.1.1
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.10.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
|
||||||
/strip-ansi/6.0.0:
|
/strip-ansi/6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex: 5.0.0
|
ansi-regex: 5.0.0
|
||||||
@ -1706,6 +1961,19 @@ packages:
|
|||||||
node: '>=10.0.0'
|
node: '>=10.0.0'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==
|
integrity: sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==
|
||||||
|
/tar/6.1.0:
|
||||||
|
dependencies:
|
||||||
|
chownr: 2.0.0
|
||||||
|
fs-minipass: 2.1.0
|
||||||
|
minipass: 3.1.3
|
||||||
|
minizlib: 2.1.2
|
||||||
|
mkdirp: 1.0.4
|
||||||
|
yallist: 4.0.0
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>= 10'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
|
||||||
/text-table/0.2.0:
|
/text-table/0.2.0:
|
||||||
dev: true
|
dev: true
|
||||||
resolution:
|
resolution:
|
||||||
@ -1894,6 +2162,12 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||||
|
/wide-align/1.1.3:
|
||||||
|
dependencies:
|
||||||
|
string-width: 1.0.2
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
|
||||||
/with/7.0.2:
|
/with/7.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.13.13
|
'@babel/parser': 7.13.13
|
||||||
@ -1929,7 +2203,6 @@ packages:
|
|||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
|
integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
|
||||||
/yallist/4.0.0:
|
/yallist/4.0.0:
|
||||||
dev: true
|
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||||
/yn/3.1.1:
|
/yn/3.1.1:
|
||||||
@ -1939,6 +2212,7 @@ packages:
|
|||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||||
specifiers:
|
specifiers:
|
||||||
|
'@types/bcrypt': ^5.0.0
|
||||||
'@types/busboy': ^0.2.3
|
'@types/busboy': ^0.2.3
|
||||||
'@types/mkdirp': ^1.0.1
|
'@types/mkdirp': ^1.0.1
|
||||||
'@types/negotiator': ^0.6.1
|
'@types/negotiator': ^0.6.1
|
||||||
@ -1951,6 +2225,7 @@ specifiers:
|
|||||||
'@types/uuid': ^8.3.0
|
'@types/uuid': ^8.3.0
|
||||||
'@typescript-eslint/eslint-plugin': ^4.26.0
|
'@typescript-eslint/eslint-plugin': ^4.26.0
|
||||||
'@typescript-eslint/parser': ^4.26.0
|
'@typescript-eslint/parser': ^4.26.0
|
||||||
|
bcrypt: ^5.0.1
|
||||||
busboy: ^0.3.1
|
busboy: ^0.3.1
|
||||||
colors: ^1.4.0
|
colors: ^1.4.0
|
||||||
dotenv: ^8.2.0
|
dotenv: ^8.2.0
|
||||||
|
16
src/auth/Authentication.ts
Normal file
16
src/auth/Authentication.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import {Inject, Injectable} from '../di'
|
||||||
|
import {Unit} from '../lifecycle/Unit'
|
||||||
|
import {Logging} from '../service/Logging'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit class that bootstraps the authentication framework.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class Authentication extends Unit {
|
||||||
|
@Inject()
|
||||||
|
protected readonly logging!: Logging
|
||||||
|
|
||||||
|
async up(): Promise<void> {
|
||||||
|
this.container()
|
||||||
|
}
|
||||||
|
}
|
122
src/auth/SecurityContext.ts
Normal file
122
src/auth/SecurityContext.ts
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import {Inject, Injectable} from '../di'
|
||||||
|
import {EventBus} from '../event/EventBus'
|
||||||
|
import {Awaitable, Maybe} from '../util'
|
||||||
|
import {Authenticatable, AuthenticatableRepository} from './types'
|
||||||
|
import {UserAuthenticatedEvent} from './event/UserAuthenticatedEvent'
|
||||||
|
import {UserFlushedEvent} from './event/UserFlushedEvent'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base-class for a context that authenticates users and manages security.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export abstract class SecurityContext {
|
||||||
|
@Inject()
|
||||||
|
protected readonly bus!: EventBus
|
||||||
|
|
||||||
|
/** The currently authenticated user, if one exists. */
|
||||||
|
private authenticatedUser?: Authenticatable
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
/** The repository from which to draw users. */
|
||||||
|
protected readonly repository: AuthenticatableRepository,
|
||||||
|
|
||||||
|
/** The name of this context. */
|
||||||
|
public readonly name: string,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the context is created. Can be used by child-classes to do setup work.
|
||||||
|
*/
|
||||||
|
initialize(): Awaitable<void> {} // eslint-disable-line @typescript-eslint/no-empty-function
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate the given user, without persisting the authentication.
|
||||||
|
* That is, when the lifecycle ends, the user will be unauthenticated implicitly.
|
||||||
|
* @param user
|
||||||
|
*/
|
||||||
|
async authenticateOnce(user: Authenticatable): Promise<void> {
|
||||||
|
this.authenticatedUser = user
|
||||||
|
await this.bus.dispatch(new UserAuthenticatedEvent(user, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate the given user and persist the authentication.
|
||||||
|
* @param user
|
||||||
|
*/
|
||||||
|
async authenticate(user: Authenticatable): Promise<void> {
|
||||||
|
this.authenticatedUser = user
|
||||||
|
await this.persist()
|
||||||
|
await this.bus.dispatch(new UserAuthenticatedEvent(user, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to authenticate a user based on their credentials.
|
||||||
|
* If the credentials are valid, the user will be authenticated, but the authentication
|
||||||
|
* will not be persisted. That is, when the lifecycle ends, the user will be
|
||||||
|
* unauthenticated implicitly.
|
||||||
|
* @param credentials
|
||||||
|
*/
|
||||||
|
async attemptOnce(credentials: Record<string, string>): Promise<Maybe<Authenticatable>> {
|
||||||
|
const user = await this.repository.getByCredentials(credentials)
|
||||||
|
if ( user ) {
|
||||||
|
await this.authenticateOnce(user)
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to authenticate a user based on their credentials.
|
||||||
|
* If the credentials are valid, the user will be authenticated and the
|
||||||
|
* authentication will be persisted.
|
||||||
|
* @param credentials
|
||||||
|
*/
|
||||||
|
async attempt(credentials: Record<string, string>): Promise<Maybe<Authenticatable>> {
|
||||||
|
const user = await this.repository.getByCredentials(credentials)
|
||||||
|
if ( user ) {
|
||||||
|
await this.authenticate(user)
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unauthenticate the current user, if one exists, but do not persist the change.
|
||||||
|
*/
|
||||||
|
async flushOnce(): Promise<void> {
|
||||||
|
const user = this.authenticatedUser
|
||||||
|
if ( user ) {
|
||||||
|
this.authenticatedUser = undefined
|
||||||
|
await this.bus.dispatch(new UserFlushedEvent(user, this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unauthenticate the current user, if one exists, and persist the change.
|
||||||
|
*/
|
||||||
|
async flush(): Promise<void> {
|
||||||
|
const user = this.authenticatedUser
|
||||||
|
if ( user ) {
|
||||||
|
this.authenticatedUser = undefined
|
||||||
|
await this.persist()
|
||||||
|
await this.bus.dispatch(new UserFlushedEvent(user, this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the current state of the security context to whatever storage
|
||||||
|
* medium the context's host provides.
|
||||||
|
*/
|
||||||
|
abstract persist(): Awaitable<void>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the credentials for the current user from whatever storage medium
|
||||||
|
* the context's host provides.
|
||||||
|
*/
|
||||||
|
abstract getCredentials(): Awaitable<Record<string, string>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently authenticated user, if one exists.
|
||||||
|
*/
|
||||||
|
getUser(): Maybe<Authenticatable> {
|
||||||
|
return this.authenticatedUser
|
||||||
|
}
|
||||||
|
}
|
23
src/auth/contexts/SessionSecurityContext.ts
Normal file
23
src/auth/contexts/SessionSecurityContext.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import {SecurityContext} from '../SecurityContext'
|
||||||
|
import {Inject, Injectable} from '../../di'
|
||||||
|
import {Session} from '../../http/session/Session'
|
||||||
|
import {Awaitable} from '../../util'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security context implementation that uses the session as storage.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class SessionSecurityContext extends SecurityContext {
|
||||||
|
@Inject()
|
||||||
|
protected readonly session!: Session
|
||||||
|
|
||||||
|
getCredentials(): Awaitable<Record<string, string>> {
|
||||||
|
return {
|
||||||
|
securityIdentifier: this.session.get('extollo.auth.securityIdentifier'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
persist(): Awaitable<void> {
|
||||||
|
this.session.set('extollo.auth.securityIdentifier', this.getUser()?.getIdentifier())
|
||||||
|
}
|
||||||
|
}
|
27
src/auth/event/UserAuthenticatedEvent.ts
Normal file
27
src/auth/event/UserAuthenticatedEvent.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import {Event} from '../../event/Event'
|
||||||
|
import {SecurityContext} from '../SecurityContext'
|
||||||
|
import {Awaitable, JSONState} from '../../util'
|
||||||
|
import {Authenticatable} from '../types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event fired when a user is authenticated.
|
||||||
|
*/
|
||||||
|
export class UserAuthenticatedEvent extends Event {
|
||||||
|
constructor(
|
||||||
|
public readonly user: Authenticatable,
|
||||||
|
public readonly context: SecurityContext,
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
|
async dehydrate(): Promise<JSONState> {
|
||||||
|
return {
|
||||||
|
user: await this.user.dehydrate(),
|
||||||
|
contextName: this.context.name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rehydrate(state: JSONState): Awaitable<void> { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
// TODO fill this in
|
||||||
|
}
|
||||||
|
}
|
27
src/auth/event/UserFlushedEvent.ts
Normal file
27
src/auth/event/UserFlushedEvent.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import {Event} from '../../event/Event'
|
||||||
|
import {SecurityContext} from '../SecurityContext'
|
||||||
|
import {Awaitable, JSONState} from '../../util'
|
||||||
|
import {Authenticatable} from '../types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event fired when a user is unauthenticated.
|
||||||
|
*/
|
||||||
|
export class UserFlushedEvent extends Event {
|
||||||
|
constructor(
|
||||||
|
public readonly user: Authenticatable,
|
||||||
|
public readonly context: SecurityContext,
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
|
async dehydrate(): Promise<JSONState> {
|
||||||
|
return {
|
||||||
|
user: await this.user.dehydrate(),
|
||||||
|
contextName: this.context.name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rehydrate(state: JSONState): Awaitable<void> { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
|
// TODO fill this in
|
||||||
|
}
|
||||||
|
}
|
13
src/auth/index.ts
Normal file
13
src/auth/index.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export * from './types'
|
||||||
|
|
||||||
|
export * from './SecurityContext'
|
||||||
|
|
||||||
|
export * from './event/UserAuthenticatedEvent'
|
||||||
|
export * from './event/UserFlushedEvent'
|
||||||
|
|
||||||
|
export * from './contexts/SessionSecurityContext'
|
||||||
|
|
||||||
|
export * from './orm/ORMUser'
|
||||||
|
export * from './orm/ORMUserRepository'
|
||||||
|
|
||||||
|
export * from './Authentication'
|
64
src/auth/orm/ORMUser.ts
Normal file
64
src/auth/orm/ORMUser.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import {Field, FieldType, Model} from '../../orm'
|
||||||
|
import {Authenticatable, AuthenticatableIdentifier} from '../types'
|
||||||
|
import {Injectable} from '../../di'
|
||||||
|
import * as bcrypt from 'bcrypt'
|
||||||
|
import {Awaitable, JSONState} from '../../util'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A basic ORM-driven user class.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class ORMUser extends Model<ORMUser> implements Authenticatable {
|
||||||
|
|
||||||
|
protected static table = 'users'
|
||||||
|
|
||||||
|
protected static key = 'user_id'
|
||||||
|
|
||||||
|
/** The primary key of the user in the table. */
|
||||||
|
@Field(FieldType.serial, 'user_id')
|
||||||
|
public userId!: number
|
||||||
|
|
||||||
|
/** The unique string-identifier of the user. */
|
||||||
|
@Field(FieldType.varchar)
|
||||||
|
public username!: string
|
||||||
|
|
||||||
|
/** The user's first name. */
|
||||||
|
@Field(FieldType.varchar, 'first_name')
|
||||||
|
public firstName!: string
|
||||||
|
|
||||||
|
/** The user's last name. */
|
||||||
|
@Field(FieldType.varchar, 'last_name')
|
||||||
|
public lastName!: string
|
||||||
|
|
||||||
|
/** The hashed and salted password of the user. */
|
||||||
|
@Field(FieldType.varchar, 'password_hash')
|
||||||
|
public passwordHash!: string
|
||||||
|
|
||||||
|
/** Human-readable display name of the user. */
|
||||||
|
getDisplayIdentifier(): string {
|
||||||
|
return `${this.firstName} ${this.lastName}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unique identifier of the user. */
|
||||||
|
getIdentifier(): AuthenticatableIdentifier {
|
||||||
|
return this.username
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if the provided password is valid for the user. */
|
||||||
|
verifyPassword(password: string): Awaitable<boolean> {
|
||||||
|
return bcrypt.compare(password, this.passwordHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Change the user's password, hashing it. */
|
||||||
|
async setPassword(password: string): Promise<void> {
|
||||||
|
this.passwordHash = await bcrypt.hash(password, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
async dehydrate(): Promise<JSONState> {
|
||||||
|
return this.toQueryRow()
|
||||||
|
}
|
||||||
|
|
||||||
|
async rehydrate(state: JSONState): Promise<void> {
|
||||||
|
await this.assumeFromSource(state)
|
||||||
|
}
|
||||||
|
}
|
41
src/auth/orm/ORMUserRepository.ts
Normal file
41
src/auth/orm/ORMUserRepository.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import {Authenticatable, AuthenticatableIdentifier, AuthenticatableRepository} from '../types'
|
||||||
|
import {Awaitable, Maybe} from '../../util'
|
||||||
|
import {ORMUser} from './ORMUser'
|
||||||
|
import {Singleton} from '../../di'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A user repository implementation that looks up users stored in the database.
|
||||||
|
*/
|
||||||
|
@Singleton()
|
||||||
|
export class ORMUserRepository extends AuthenticatableRepository {
|
||||||
|
/** Look up the user by their username. */
|
||||||
|
getByIdentifier(id: AuthenticatableIdentifier): Awaitable<Maybe<Authenticatable>> {
|
||||||
|
return ORMUser.query<ORMUser>()
|
||||||
|
.where('username', '=', id)
|
||||||
|
.first()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to look up a user by the credentials provided.
|
||||||
|
* If a securityIdentifier is specified, look up the user by username.
|
||||||
|
* If username/password are specified, look up the user and verify the password.
|
||||||
|
* @param credentials
|
||||||
|
*/
|
||||||
|
async getByCredentials(credentials: Record<string, string>): Promise<Maybe<Authenticatable>> {
|
||||||
|
if ( credentials.securityIdentifier ) {
|
||||||
|
return ORMUser.query<ORMUser>()
|
||||||
|
.where('username', '=', credentials.securityIdentifier)
|
||||||
|
.first()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( credentials.username && credentials.password ) {
|
||||||
|
const user = await ORMUser.query<ORMUser>()
|
||||||
|
.where('username', '=', credentials.username)
|
||||||
|
.first()
|
||||||
|
|
||||||
|
if ( user && await user.verifyPassword(credentials.password) ) {
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
src/auth/types.ts
Normal file
36
src/auth/types.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import {Awaitable, JSONState, Maybe, Rehydratable} from '../util'
|
||||||
|
|
||||||
|
/** Value that can be used to uniquely identify a user. */
|
||||||
|
export type AuthenticatableIdentifier = string | number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for entities that can be authenticated.
|
||||||
|
*/
|
||||||
|
export abstract class Authenticatable implements Rehydratable {
|
||||||
|
|
||||||
|
/** Get the unique identifier of the user. */
|
||||||
|
abstract getIdentifier(): AuthenticatableIdentifier
|
||||||
|
|
||||||
|
/** Get the human-readable identifier of the user. */
|
||||||
|
abstract getDisplayIdentifier(): string
|
||||||
|
|
||||||
|
abstract dehydrate(): Promise<JSONState>
|
||||||
|
|
||||||
|
abstract rehydrate(state: JSONState): Awaitable<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for a repository that stores and recalls users.
|
||||||
|
*/
|
||||||
|
export abstract class AuthenticatableRepository {
|
||||||
|
|
||||||
|
/** Look up the user by their unique identifier. */
|
||||||
|
abstract getByIdentifier(id: AuthenticatableIdentifier): Awaitable<Maybe<Authenticatable>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to look up and verify a user by their credentials.
|
||||||
|
* Returns the user if the credentials are valid.
|
||||||
|
* @param credentials
|
||||||
|
*/
|
||||||
|
abstract getByCredentials(credentials: Record<string, string>): Awaitable<Maybe<Authenticatable>>
|
||||||
|
}
|
@ -79,3 +79,4 @@ export * from './cli'
|
|||||||
export * from './i18n'
|
export * from './i18n'
|
||||||
export * from './forms'
|
export * from './forms'
|
||||||
export * from './orm'
|
export * from './orm'
|
||||||
|
export * from './auth'
|
||||||
|
@ -1 +1,5 @@
|
|||||||
|
/** Type alias for something that may or may not be wrapped in a promise. */
|
||||||
export type Awaitable<T> = T | Promise<T>
|
export type Awaitable<T> = T | Promise<T>
|
||||||
|
|
||||||
|
/** Type alias for something that may be undefined. */
|
||||||
|
export type Maybe<T> = T | undefined
|
||||||
|
Loading…
Reference in New Issue
Block a user