Added token authentication, organization module. Moved server bootstrapping code to server.ts file
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"bcrypt": "^5.1.1",
|
||||
"fastify": "^5.2.0",
|
||||
"fastify-type-provider-zod": "^4.0.2",
|
||||
"fastify-zod": "^1.4.0",
|
||||
@@ -19,6 +20,7 @@
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/node": "^22.10.2",
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
|
||||
389
pnpm-lock.yaml
generated
389
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
||||
'@paralleldrive/cuid2':
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
bcrypt:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
fastify:
|
||||
specifier: ^5.2.0
|
||||
version: 5.2.0
|
||||
@@ -27,6 +30,9 @@ importers:
|
||||
specifier: ^3.24.1
|
||||
version: 3.24.1
|
||||
devDependencies:
|
||||
'@types/bcrypt':
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2
|
||||
'@types/node':
|
||||
specifier: ^22.10.2
|
||||
version: 22.10.2
|
||||
@@ -68,6 +74,10 @@ packages:
|
||||
resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
'@mapbox/node-pre-gyp@1.0.11':
|
||||
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
|
||||
hasBin: true
|
||||
|
||||
'@mongodb-js/saslprep@1.1.9':
|
||||
resolution: {integrity: sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==}
|
||||
|
||||
@@ -78,6 +88,9 @@ packages:
|
||||
'@paralleldrive/cuid2@2.2.2':
|
||||
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||
|
||||
'@types/bcrypt@5.0.2':
|
||||
resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==}
|
||||
|
||||
'@types/js-yaml@4.0.9':
|
||||
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
|
||||
|
||||
@@ -90,9 +103,16 @@ packages:
|
||||
'@types/whatwg-url@11.0.5':
|
||||
resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==}
|
||||
|
||||
abbrev@1.1.1:
|
||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||
|
||||
abstract-logging@2.0.1:
|
||||
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
|
||||
|
||||
agent-base@6.0.2:
|
||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
|
||||
ajv-formats@3.0.1:
|
||||
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
|
||||
peerDependencies:
|
||||
@@ -104,6 +124,18 @@ packages:
|
||||
ajv@8.17.1:
|
||||
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
aproba@2.0.0:
|
||||
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
|
||||
|
||||
are-we-there-yet@2.0.0:
|
||||
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
|
||||
engines: {node: '>=10'}
|
||||
deprecated: This package is no longer supported.
|
||||
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
@@ -117,6 +149,13 @@ packages:
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
bcrypt@5.1.1:
|
||||
resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
|
||||
brace-expansion@1.1.11:
|
||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
|
||||
@@ -133,6 +172,20 @@ packages:
|
||||
change-case@4.1.2:
|
||||
resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==}
|
||||
|
||||
chownr@2.0.0:
|
||||
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
color-support@1.1.3:
|
||||
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
|
||||
hasBin: true
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
console-control-strings@1.1.0:
|
||||
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
|
||||
|
||||
constant-case@3.0.4:
|
||||
resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
|
||||
|
||||
@@ -153,13 +206,23 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
delegates@1.0.0:
|
||||
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
||||
|
||||
depd@2.0.0:
|
||||
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
detect-libc@2.0.3:
|
||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
dot-case@3.0.4:
|
||||
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
escape-html@1.0.3:
|
||||
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||
|
||||
@@ -213,14 +276,30 @@ packages:
|
||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
fs-minipass@2.1.0:
|
||||
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
gauge@3.0.2:
|
||||
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
|
||||
engines: {node: '>=10'}
|
||||
deprecated: This package is no longer supported.
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
|
||||
glob@8.1.0:
|
||||
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
|
||||
engines: {node: '>=12'}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
|
||||
has-unicode@2.0.1:
|
||||
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
|
||||
|
||||
header-case@2.0.4:
|
||||
resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==}
|
||||
|
||||
@@ -228,6 +307,10 @@ packages:
|
||||
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
https-proxy-agent@5.0.1:
|
||||
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
|
||||
@@ -239,6 +322,10 @@ packages:
|
||||
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
@@ -263,6 +350,10 @@ packages:
|
||||
lower-case@2.0.2:
|
||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||
|
||||
make-dir@3.1.0:
|
||||
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
memory-pager@1.5.0:
|
||||
resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==}
|
||||
|
||||
@@ -271,10 +362,30 @@ packages:
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
minimatch@5.1.6:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minipass@3.3.6:
|
||||
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
minipass@5.0.0:
|
||||
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
minizlib@2.1.2:
|
||||
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
mkdirp@1.0.4:
|
||||
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
mongodb-connection-string-url@3.0.1:
|
||||
resolution: {integrity: sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==}
|
||||
|
||||
@@ -323,6 +434,31 @@ packages:
|
||||
no-case@3.0.4:
|
||||
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
||||
|
||||
node-addon-api@5.1.0:
|
||||
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
|
||||
|
||||
node-fetch@2.7.0:
|
||||
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
peerDependencies:
|
||||
encoding: ^0.1.0
|
||||
peerDependenciesMeta:
|
||||
encoding:
|
||||
optional: true
|
||||
|
||||
nopt@5.0.0:
|
||||
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
npmlog@5.0.1:
|
||||
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
|
||||
deprecated: This package is no longer supported.
|
||||
|
||||
object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
on-exit-leak-free@2.1.2:
|
||||
resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@@ -346,6 +482,10 @@ packages:
|
||||
path-case@3.0.4:
|
||||
resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==}
|
||||
|
||||
path-is-absolute@1.0.1:
|
||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
pino-abstract-transport@2.0.0:
|
||||
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
|
||||
|
||||
@@ -370,6 +510,10 @@ packages:
|
||||
quick-format-unescaped@4.0.4:
|
||||
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
||||
|
||||
readable-stream@3.6.2:
|
||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
real-require@0.2.0:
|
||||
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
|
||||
engines: {node: '>= 12.13.0'}
|
||||
@@ -389,6 +533,11 @@ packages:
|
||||
rfdc@1.4.1:
|
||||
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
|
||||
|
||||
rimraf@3.0.2:
|
||||
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
|
||||
deprecated: Rimraf versions prior to v4 are no longer supported
|
||||
hasBin: true
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
@@ -402,6 +551,10 @@ packages:
|
||||
secure-json-parse@3.0.1:
|
||||
resolution: {integrity: sha512-9QR7G96th4QJ2+dJwvZB+JoXyt8PN+DbEjOr6kL2/JU4KH8Eb2sFdU+gt8EDdzWDWoWH0uocDdfCoFzdVSixUA==}
|
||||
|
||||
semver@6.3.1:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
|
||||
semver@7.6.3:
|
||||
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -410,6 +563,9 @@ packages:
|
||||
sentence-case@3.0.4:
|
||||
resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
|
||||
|
||||
set-blocking@2.0.0:
|
||||
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||
|
||||
set-cookie-parser@2.7.1:
|
||||
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
|
||||
|
||||
@@ -419,6 +575,9 @@ packages:
|
||||
sift@17.1.3:
|
||||
resolution: {integrity: sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==}
|
||||
|
||||
signal-exit@3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
|
||||
snake-case@3.0.4:
|
||||
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
|
||||
|
||||
@@ -436,6 +595,21 @@ packages:
|
||||
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
string_decoder@1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
tar@6.2.1:
|
||||
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
thread-stream@3.1.0:
|
||||
resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==}
|
||||
|
||||
@@ -447,6 +621,9 @@ packages:
|
||||
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
tr46@0.0.3:
|
||||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
|
||||
tr46@4.1.1:
|
||||
resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -471,6 +648,12 @@ packages:
|
||||
uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
webidl-conversions@3.0.1:
|
||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||
|
||||
webidl-conversions@7.0.0:
|
||||
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -479,9 +662,18 @@ packages:
|
||||
resolution: {integrity: sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
wide-align@1.1.5:
|
||||
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
|
||||
|
||||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
yallist@4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
|
||||
yaml@2.6.1:
|
||||
resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -556,6 +748,21 @@ snapshots:
|
||||
|
||||
'@lukeed/ms@2.0.2': {}
|
||||
|
||||
'@mapbox/node-pre-gyp@1.0.11':
|
||||
dependencies:
|
||||
detect-libc: 2.0.3
|
||||
https-proxy-agent: 5.0.1
|
||||
make-dir: 3.1.0
|
||||
node-fetch: 2.7.0
|
||||
nopt: 5.0.0
|
||||
npmlog: 5.0.1
|
||||
rimraf: 3.0.2
|
||||
semver: 7.6.3
|
||||
tar: 6.2.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
|
||||
'@mongodb-js/saslprep@1.1.9':
|
||||
dependencies:
|
||||
sparse-bitfield: 3.0.3
|
||||
@@ -566,6 +773,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@noble/hashes': 1.6.1
|
||||
|
||||
'@types/bcrypt@5.0.2':
|
||||
dependencies:
|
||||
'@types/node': 22.10.2
|
||||
|
||||
'@types/js-yaml@4.0.9': {}
|
||||
|
||||
'@types/node@22.10.2':
|
||||
@@ -578,8 +789,16 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/webidl-conversions': 7.0.3
|
||||
|
||||
abbrev@1.1.1: {}
|
||||
|
||||
abstract-logging@2.0.1: {}
|
||||
|
||||
agent-base@6.0.2:
|
||||
dependencies:
|
||||
debug: 4.4.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
ajv-formats@3.0.1(ajv@8.17.1):
|
||||
optionalDependencies:
|
||||
ajv: 8.17.1
|
||||
@@ -591,6 +810,15 @@ snapshots:
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
aproba@2.0.0: {}
|
||||
|
||||
are-we-there-yet@2.0.0:
|
||||
dependencies:
|
||||
delegates: 1.0.0
|
||||
readable-stream: 3.6.2
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
atomic-sleep@1.0.0: {}
|
||||
@@ -602,6 +830,19 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
bcrypt@5.1.1:
|
||||
dependencies:
|
||||
'@mapbox/node-pre-gyp': 1.0.11
|
||||
node-addon-api: 5.1.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
|
||||
brace-expansion@1.1.11:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
@@ -634,6 +875,14 @@ snapshots:
|
||||
snake-case: 3.0.4
|
||||
tslib: 2.8.1
|
||||
|
||||
chownr@2.0.0: {}
|
||||
|
||||
color-support@1.1.3: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
||||
console-control-strings@1.1.0: {}
|
||||
|
||||
constant-case@3.0.4:
|
||||
dependencies:
|
||||
no-case: 3.0.4
|
||||
@@ -650,13 +899,19 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
delegates@1.0.0: {}
|
||||
|
||||
depd@2.0.0: {}
|
||||
|
||||
detect-libc@2.0.3: {}
|
||||
|
||||
dot-case@3.0.4:
|
||||
dependencies:
|
||||
no-case: 3.0.4
|
||||
tslib: 2.8.1
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
escape-html@1.0.3: {}
|
||||
|
||||
fast-decode-uri-component@1.0.1: {}
|
||||
@@ -737,8 +992,33 @@ snapshots:
|
||||
|
||||
forwarded@0.2.0: {}
|
||||
|
||||
fs-minipass@2.1.0:
|
||||
dependencies:
|
||||
minipass: 3.3.6
|
||||
|
||||
fs.realpath@1.0.0: {}
|
||||
|
||||
gauge@3.0.2:
|
||||
dependencies:
|
||||
aproba: 2.0.0
|
||||
color-support: 1.1.3
|
||||
console-control-strings: 1.1.0
|
||||
has-unicode: 2.0.1
|
||||
object-assign: 4.1.1
|
||||
signal-exit: 3.0.7
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wide-align: 1.1.5
|
||||
|
||||
glob@7.2.3:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 3.1.2
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
|
||||
glob@8.1.0:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
@@ -747,6 +1027,8 @@ snapshots:
|
||||
minimatch: 5.1.6
|
||||
once: 1.4.0
|
||||
|
||||
has-unicode@2.0.1: {}
|
||||
|
||||
header-case@2.0.4:
|
||||
dependencies:
|
||||
capital-case: 1.0.4
|
||||
@@ -760,6 +1042,13 @@ snapshots:
|
||||
statuses: 2.0.1
|
||||
toidentifier: 1.0.1
|
||||
|
||||
https-proxy-agent@5.0.1:
|
||||
dependencies:
|
||||
agent-base: 6.0.2
|
||||
debug: 4.4.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
inflight@1.0.6:
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
@@ -769,6 +1058,8 @@ snapshots:
|
||||
|
||||
ipaddr.js@1.9.1: {}
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
@@ -799,14 +1090,35 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
make-dir@3.1.0:
|
||||
dependencies:
|
||||
semver: 6.3.1
|
||||
|
||||
memory-pager@1.5.0: {}
|
||||
|
||||
mime@3.0.0: {}
|
||||
|
||||
minimatch@3.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
|
||||
minimatch@5.1.6:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minipass@3.3.6:
|
||||
dependencies:
|
||||
yallist: 4.0.0
|
||||
|
||||
minipass@5.0.0: {}
|
||||
|
||||
minizlib@2.1.2:
|
||||
dependencies:
|
||||
minipass: 3.3.6
|
||||
yallist: 4.0.0
|
||||
|
||||
mkdirp@1.0.4: {}
|
||||
|
||||
mongodb-connection-string-url@3.0.1:
|
||||
dependencies:
|
||||
'@types/whatwg-url': 11.0.5
|
||||
@@ -852,6 +1164,25 @@ snapshots:
|
||||
lower-case: 2.0.2
|
||||
tslib: 2.8.1
|
||||
|
||||
node-addon-api@5.1.0: {}
|
||||
|
||||
node-fetch@2.7.0:
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
|
||||
nopt@5.0.0:
|
||||
dependencies:
|
||||
abbrev: 1.1.1
|
||||
|
||||
npmlog@5.0.1:
|
||||
dependencies:
|
||||
are-we-there-yet: 2.0.0
|
||||
console-control-strings: 1.1.0
|
||||
gauge: 3.0.2
|
||||
set-blocking: 2.0.0
|
||||
|
||||
object-assign@4.1.1: {}
|
||||
|
||||
on-exit-leak-free@2.1.2: {}
|
||||
|
||||
once@1.4.0:
|
||||
@@ -879,6 +1210,8 @@ snapshots:
|
||||
dot-case: 3.0.4
|
||||
tslib: 2.8.1
|
||||
|
||||
path-is-absolute@1.0.1: {}
|
||||
|
||||
pino-abstract-transport@2.0.0:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
@@ -910,6 +1243,12 @@ snapshots:
|
||||
|
||||
quick-format-unescaped@4.0.4: {}
|
||||
|
||||
readable-stream@3.6.2:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
string_decoder: 1.3.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
real-require@0.2.0: {}
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
@@ -920,6 +1259,10 @@ snapshots:
|
||||
|
||||
rfdc@1.4.1: {}
|
||||
|
||||
rimraf@3.0.2:
|
||||
dependencies:
|
||||
glob: 7.2.3
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
safe-regex2@4.0.0:
|
||||
@@ -930,6 +1273,8 @@ snapshots:
|
||||
|
||||
secure-json-parse@3.0.1: {}
|
||||
|
||||
semver@6.3.1: {}
|
||||
|
||||
semver@7.6.3: {}
|
||||
|
||||
sentence-case@3.0.4:
|
||||
@@ -938,12 +1283,16 @@ snapshots:
|
||||
tslib: 2.8.1
|
||||
upper-case-first: 2.0.2
|
||||
|
||||
set-blocking@2.0.0: {}
|
||||
|
||||
set-cookie-parser@2.7.1: {}
|
||||
|
||||
setprototypeof@1.2.0: {}
|
||||
|
||||
sift@17.1.3: {}
|
||||
|
||||
signal-exit@3.0.7: {}
|
||||
|
||||
snake-case@3.0.4:
|
||||
dependencies:
|
||||
dot-case: 3.0.4
|
||||
@@ -961,6 +1310,29 @@ snapshots:
|
||||
|
||||
statuses@2.0.1: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
string_decoder@1.3.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
tar@6.2.1:
|
||||
dependencies:
|
||||
chownr: 2.0.0
|
||||
fs-minipass: 2.1.0
|
||||
minipass: 5.0.0
|
||||
minizlib: 2.1.2
|
||||
mkdirp: 1.0.4
|
||||
yallist: 4.0.0
|
||||
|
||||
thread-stream@3.1.0:
|
||||
dependencies:
|
||||
real-require: 0.2.0
|
||||
@@ -969,6 +1341,8 @@ snapshots:
|
||||
|
||||
toidentifier@1.0.1: {}
|
||||
|
||||
tr46@0.0.3: {}
|
||||
|
||||
tr46@4.1.1:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
@@ -991,6 +1365,10 @@ snapshots:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
webidl-conversions@3.0.1: {}
|
||||
|
||||
webidl-conversions@7.0.0: {}
|
||||
|
||||
whatwg-url@13.0.0:
|
||||
@@ -998,8 +1376,19 @@ snapshots:
|
||||
tr46: 4.1.1
|
||||
webidl-conversions: 7.0.0
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
dependencies:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
wide-align@1.1.5:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
yallist@4.0.0: {}
|
||||
|
||||
yaml@2.6.1: {}
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
26
src/auth.ts
Normal file
26
src/auth.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import bcrypt from "bcrypt";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
import { getToken } from "./tokens/token.service";
|
||||
import { Claim } from "./utils/claims";
|
||||
|
||||
export type AuthenticatedUser = {
|
||||
userId?: String;
|
||||
claims: Array<Claim>;
|
||||
};
|
||||
|
||||
export async function authHandler(req: FastifyRequest, res: FastifyReply) {
|
||||
if (!req.headers.authorization) return res.code(401).send();
|
||||
|
||||
const [tokenId, token] = req.headers.authorization.split(" ")[1].split(".");
|
||||
if (!tokenId || !token) return res.code(401).send({ error: "invalid token" });
|
||||
|
||||
const tokenInDb = await getToken(tokenId);
|
||||
if (tokenInDb === null) return res.code(401).send({ error: "invalid token" });
|
||||
|
||||
const valid = await bcrypt.compare(token, tokenInDb.hash);
|
||||
if (!valid) return res.code(401).send({ error: "invalid token" });
|
||||
|
||||
req.user = {
|
||||
claims: tokenInDb.claims as Array<Claim>,
|
||||
};
|
||||
}
|
||||
20
src/index.ts
20
src/index.ts
@@ -1,28 +1,10 @@
|
||||
import mongoose from "mongoose";
|
||||
import fastify from "fastify";
|
||||
|
||||
import routes from "./routes";
|
||||
import { userSchemas } from "./user/user.schema";
|
||||
import { orgSchemas } from "./organization/organization.schema";
|
||||
import { errorHandler } from "./utils/errors";
|
||||
|
||||
const app = fastify({ logger: true });
|
||||
|
||||
app.get("/health", (req, res) => {
|
||||
return { status: "OK" };
|
||||
});
|
||||
|
||||
app.register(routes, { prefix: "/api/v1" });
|
||||
app.setErrorHandler(errorHandler);
|
||||
import app from "./server";
|
||||
|
||||
(async () => {
|
||||
const PORT = parseInt(process.env.PORT ?? "8000");
|
||||
const DB_URI = process.env.DB_URI ?? "";
|
||||
|
||||
for (const schema of [...userSchemas, ...orgSchemas]) {
|
||||
app.addSchema(schema);
|
||||
}
|
||||
|
||||
await mongoose.connect(DB_URI);
|
||||
await app.listen({ port: PORT });
|
||||
})().catch((err) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FastifyRequest, FastifyReply } from "fastify";
|
||||
import { CreateOrgInput } from "./organization.schema";
|
||||
import { createOrg } from "./organization.service";
|
||||
import { createOrg, getOrg } from "./organization.service";
|
||||
|
||||
export async function createOrgHandler(
|
||||
req: FastifyRequest<{ Body: CreateOrgInput }>,
|
||||
@@ -15,3 +15,20 @@ export async function createOrgHandler(
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getOrgHandler(
|
||||
req: FastifyRequest<{ Params: { orgId: string } }>,
|
||||
res: FastifyReply
|
||||
) {
|
||||
const { orgId } = req.params;
|
||||
|
||||
try {
|
||||
const org = await getOrg(orgId);
|
||||
if (org === null)
|
||||
return res.code(404).send({ error: "resource not found" });
|
||||
|
||||
return res.code(200).send(org);
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { $org } from "./organization.schema";
|
||||
import { createOrgHandler } from "./organization.controller";
|
||||
import { createOrgHandler, getOrgHandler } from "./organization.controller";
|
||||
|
||||
export default function organizationRoutes(fastify: FastifyInstance) {
|
||||
fastify.post(
|
||||
@@ -15,4 +15,19 @@ export default function organizationRoutes(fastify: FastifyInstance) {
|
||||
},
|
||||
createOrgHandler
|
||||
);
|
||||
|
||||
fastify.get(
|
||||
"/:orgId",
|
||||
{
|
||||
schema: {
|
||||
params: {
|
||||
type: "object",
|
||||
properties: {
|
||||
orgId: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getOrgHandler
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,3 +11,7 @@ export async function createOrg(input: CreateOrgInput) {
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
export async function getOrg(orgId: string) {
|
||||
return await orgModel.findOne({ pid: orgId });
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import userRoutes from "./user/user.route";
|
||||
import organizationRoutes from "./organization/organization.route";
|
||||
import { tokenRoutes } from "./tokens/token.route";
|
||||
|
||||
export default async function routes(fastify: FastifyInstance) {
|
||||
fastify.register(userRoutes, { prefix: "/users" });
|
||||
fastify.register(organizationRoutes, { prefix: "/orgs" });
|
||||
fastify.register(tokenRoutes, { prefix: "/tokens" });
|
||||
}
|
||||
|
||||
31
src/server.ts
Normal file
31
src/server.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import mongoose from "mongoose";
|
||||
import fastify from "fastify";
|
||||
|
||||
import routes from "./routes";
|
||||
import { userSchemas } from "./user/user.schema";
|
||||
import { orgSchemas } from "./organization/organization.schema";
|
||||
import { tokenSchemas } from "./tokens/token.schema";
|
||||
import { errorHandler } from "./utils/errors";
|
||||
import { AuthenticatedUser, authHandler } from "./auth";
|
||||
|
||||
declare module "fastify" {
|
||||
export interface FastifyRequest {
|
||||
user: AuthenticatedUser;
|
||||
}
|
||||
}
|
||||
|
||||
const app = fastify({ logger: true });
|
||||
|
||||
app.get("/health", (req, res) => {
|
||||
return { status: "OK" };
|
||||
});
|
||||
|
||||
app.register(routes, { prefix: "/api/v1" });
|
||||
app.setErrorHandler(errorHandler);
|
||||
app.addHook("onRequest", authHandler);
|
||||
|
||||
for (const schema of [...userSchemas, ...orgSchemas, ...tokenSchemas]) {
|
||||
app.addSchema(schema);
|
||||
}
|
||||
|
||||
export default app;
|
||||
33
src/tokens/token.controller.ts
Normal file
33
src/tokens/token.controller.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
import { CreateTokenInput } from "./token.schema";
|
||||
import { createToken, getToken } from "./token.service";
|
||||
|
||||
export async function createTokenHandler(
|
||||
req: FastifyRequest<{ Body: CreateTokenInput }>,
|
||||
res: FastifyReply
|
||||
) {
|
||||
const input = req.body;
|
||||
|
||||
try {
|
||||
const result = await createToken(input);
|
||||
return res.code(201).send(result);
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getTokenHandler(
|
||||
req: FastifyRequest<{ Params: { tokenId: string } }>,
|
||||
res: FastifyReply
|
||||
) {
|
||||
const { tokenId } = req.params;
|
||||
|
||||
try {
|
||||
const token = await getToken(tokenId);
|
||||
if (token === null) return res.code(404).send();
|
||||
|
||||
return res.code(200).send(token);
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
24
src/tokens/token.route.ts
Normal file
24
src/tokens/token.route.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { createTokenHandler, getTokenHandler } from "./token.controller";
|
||||
import { $token } from "./token.schema";
|
||||
|
||||
export async function tokenRoutes(fastify: FastifyInstance) {
|
||||
fastify.post(
|
||||
"/",
|
||||
{
|
||||
schema: {
|
||||
body: $token("createTokenInput"),
|
||||
response: {
|
||||
201: $token("createTokenResponse"),
|
||||
},
|
||||
},
|
||||
},
|
||||
createTokenHandler
|
||||
);
|
||||
|
||||
fastify.get(
|
||||
"/:tokenId",
|
||||
{ schema: { response: { 200: $token("getTokenResponse") } } },
|
||||
getTokenHandler
|
||||
);
|
||||
}
|
||||
52
src/tokens/token.schema.ts
Normal file
52
src/tokens/token.schema.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { buildJsonSchemas } from "fastify-zod";
|
||||
import mongoose from "mongoose";
|
||||
import { z } from "zod";
|
||||
import { Claim } from "../utils/claims";
|
||||
|
||||
export const tokenModel = mongoose.model(
|
||||
"token",
|
||||
new mongoose.Schema({
|
||||
tenantId: String,
|
||||
pid: {
|
||||
type: String,
|
||||
unique: true,
|
||||
},
|
||||
name: String,
|
||||
claims: [],
|
||||
userId: mongoose.Types.ObjectId,
|
||||
hash: { type: String, required: true },
|
||||
createdAt: Date,
|
||||
})
|
||||
);
|
||||
|
||||
const tokenCore = {
|
||||
name: z.string().max(30),
|
||||
claims: z.array(z.string()).nonempty(),
|
||||
};
|
||||
|
||||
const createTokenInput = z.object({
|
||||
...tokenCore,
|
||||
});
|
||||
|
||||
const createTokenResponse = z.object({
|
||||
pid: z.string(),
|
||||
token: z.string(),
|
||||
...tokenCore,
|
||||
});
|
||||
|
||||
const getTokenResponse = z.object({
|
||||
pid: z.string(),
|
||||
name: z.string(),
|
||||
createdAt: z.string(),
|
||||
});
|
||||
|
||||
export type CreateTokenInput = z.infer<typeof createTokenInput>;
|
||||
|
||||
export const { schemas: tokenSchemas, $ref: $token } = buildJsonSchemas(
|
||||
{
|
||||
createTokenInput,
|
||||
createTokenResponse,
|
||||
getTokenResponse,
|
||||
},
|
||||
{ $id: "token" }
|
||||
);
|
||||
27
src/tokens/token.service.ts
Normal file
27
src/tokens/token.service.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import bcrypt from "bcrypt";
|
||||
import { generateId, generateToken } from "../utils/id";
|
||||
import { CreateTokenInput, tokenModel } from "./token.schema";
|
||||
|
||||
export async function createToken(input: CreateTokenInput) {
|
||||
const tokenId = generateId();
|
||||
const newToken = await generateToken();
|
||||
const tokenHash = await bcrypt.hash(newToken, 10);
|
||||
|
||||
const tokenInDb = await tokenModel.create({
|
||||
pid: tokenId,
|
||||
hash: tokenHash,
|
||||
createdAt: new Date(),
|
||||
...input,
|
||||
});
|
||||
|
||||
return {
|
||||
pid: tokenInDb.pid,
|
||||
name: tokenInDb.name,
|
||||
claims: tokenInDb.claims,
|
||||
token: `${tokenInDb.pid}.${newToken}`,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getToken(tokenId: string) {
|
||||
return await tokenModel.findOne({ pid: tokenId });
|
||||
}
|
||||
@@ -26,7 +26,8 @@ export async function getUserHandler(
|
||||
|
||||
try {
|
||||
const user = await getUser(userId);
|
||||
if (user == null) return res.code(404).send({ error: "user not found" });
|
||||
if (user == null)
|
||||
return res.code(404).send({ error: "resource not found" });
|
||||
|
||||
return res.code(200).send(user);
|
||||
} catch (err) {
|
||||
|
||||
15
src/utils/claims.ts
Normal file
15
src/utils/claims.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export type Claim =
|
||||
| "user:read"
|
||||
| "user:write"
|
||||
| "user:delete"
|
||||
| "org:read"
|
||||
| "org:write"
|
||||
| "org:delete"
|
||||
| "permit:read"
|
||||
| "permit:write"
|
||||
| "permit:delete"
|
||||
| "file:upload"
|
||||
| "file:download"
|
||||
| "api:read"
|
||||
| "api:write"
|
||||
| "api:delete";
|
||||
@@ -1,4 +1,5 @@
|
||||
import { init } from "@paralleldrive/cuid2";
|
||||
import crypto from "crypto";
|
||||
|
||||
const id = init({
|
||||
length: 15,
|
||||
@@ -7,3 +8,12 @@ const id = init({
|
||||
export function generateId(perfix?: string) {
|
||||
return perfix ? perfix + id() : id();
|
||||
}
|
||||
|
||||
export async function generateToken(): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
crypto.generateKey("aes", { length: 256 }, (err, key) => {
|
||||
if (err) reject(err);
|
||||
resolve(key.export().toString("base64url"));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user