mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-14 06:39:08 +02:00
Add verify middleware
This commit is contained in:
parent
e89ee4042a
commit
a8f944fc78
17 changed files with 1230 additions and 40 deletions
843
package-lock.json
generated
843
package-lock.json
generated
|
@ -10,6 +10,7 @@
|
|||
"dependencies": {
|
||||
"@lucia-auth/adapter-drizzle": "1.1.0",
|
||||
"@node-rs/argon2": "1.8.3",
|
||||
"@node-rs/argon2-linux-x64-gnu": "1.8.3",
|
||||
"@react-email/components": "0.0.25",
|
||||
"@react-email/tailwind": "0.1.0",
|
||||
"axios": "1.7.7",
|
||||
|
@ -23,6 +24,7 @@
|
|||
"http-errors": "2.0.0",
|
||||
"lucia": "3.2.0",
|
||||
"next": "14.2.13",
|
||||
"node-fetch": "3.3.2",
|
||||
"nodemailer": "6.9.15",
|
||||
"oslo": "1.2.1",
|
||||
"react": "^18",
|
||||
|
@ -2569,6 +2571,33 @@
|
|||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "0.45.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-0.45.0.tgz",
|
||||
"integrity": "sha512-DPWjcUDQkCeEM4VnljEOEcXdAD7pp8zSZsgOujk/LGIwCXWbXJngin+MO4zbH429lzeC3WbYLGjE2MaUOwzpyw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "0.45.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.45.0.tgz",
|
||||
"integrity": "sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz",
|
||||
"integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild-kit/core-utils": {
|
||||
"version": "3.3.2",
|
||||
"dev": true,
|
||||
|
@ -2853,6 +2882,27 @@
|
|||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/cli/node_modules/picomatch": {
|
||||
"version": "3.0.1",
|
||||
"license": "MIT",
|
||||
|
@ -3207,6 +3257,27 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/image-utils/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/image-utils/node_modules/resolve-from": {
|
||||
"version": "5.0.0",
|
||||
"license": "MIT",
|
||||
|
@ -3540,6 +3611,27 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/rudder-sdk-node/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/sdk-runtime-versions": {
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
|
@ -3746,6 +3838,45 @@
|
|||
"lucia": "3.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.5.tgz",
|
||||
"integrity": "sha512-kwUxR7J9WLutBbulqg1dfOrMTwhMdXLdcGUhcbCcGwnPLt3gz19uHVdwH1syKVDbE022ZS2vZxOWflFLS0YTjw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.1.0",
|
||||
"@emnapi/runtime": "^1.1.0",
|
||||
"@tybys/wasm-util": "^0.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime/node_modules/@emnapi/core": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.2.0.tgz",
|
||||
"integrity": "sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.0.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime/node_modules/@emnapi/runtime": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz",
|
||||
"integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime/node_modules/@tybys/wasm-util": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
|
||||
"integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "14.2.13",
|
||||
"license": "MIT"
|
||||
|
@ -3831,6 +3962,36 @@
|
|||
"@node-rs/argon2-win32-x64-msvc": "1.8.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-android-arm-eabi": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-1.7.0.tgz",
|
||||
"integrity": "sha512-udDqkr5P9E+wYX1SZwAVPdyfYvaF4ry9Tm+R9LkfSHbzWH0uhU6zjIwNRp7m+n4gx691rk+lqqDAIP8RLKwbhg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-android-arm64": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-1.7.0.tgz",
|
||||
"integrity": "sha512-s9j/G30xKUx8WU50WIhF0fIl1EdhBGq0RQ06lEhZ0Gi0ap8lhqbE2Bn5h3/G2D1k0Dx+yjeVVNmt/xOQIRG38A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-darwin-arm64": {
|
||||
"version": "1.8.3",
|
||||
"cpu": [
|
||||
|
@ -3845,6 +4006,353 @@
|
|||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-darwin-x64": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-1.7.0.tgz",
|
||||
"integrity": "sha512-5oi/pxqVhODW/pj1+3zElMTn/YukQeywPHHYDbcAW3KsojFjKySfhcJMd1DjKTc+CHQI+4lOxZzSUzK7mI14Hw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-freebsd-x64": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-1.7.0.tgz",
|
||||
"integrity": "sha512-Ify08683hA4QVXYoIm5SUWOY5DPIT/CMB0CQT+IdxQAg/F+qp342+lUkeAtD5bvStQuCx/dFO3bnnzoe2clMhA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-linux-arm-gnueabihf": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-1.7.0.tgz",
|
||||
"integrity": "sha512-7DjDZ1h5AUHAtRNjD19RnQatbhL+uuxBASuuXIBu4/w6Dx8n7YPxwTP4MXfsvuRgKuMWiOb/Ub/HJ3kXVCXRkg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-linux-arm64-gnu": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-1.7.0.tgz",
|
||||
"integrity": "sha512-nJDoMP4Y3YcqGswE4DvP080w6O24RmnFEDnL0emdI8Nou17kNYBzP2546Nasx9GCyLzRcYQwZOUjrtUuQ+od2g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-linux-arm64-musl": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-1.7.0.tgz",
|
||||
"integrity": "sha512-BKWS8iVconhE3jrb9mj6t1J9vwUqQPpzCbUKxfTGJfc+kNL58F1SXHBoe2cDYGnHrFEHTY0YochzXoAfm4Dm/A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-linux-x64-gnu": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-1.8.3.tgz",
|
||||
"integrity": "sha512-OBH+EFG7BGjFyldaao2H2gSCLmjtrrwf420B1L+lFn7JLW9UAjsIPFKAcWsYwPa/PwYzIge9Y7SGcpqlsSEX0w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-linux-x64-musl": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-1.7.0.tgz",
|
||||
"integrity": "sha512-/o1efYCYIxjfuoRYyBTi2Iy+1iFfhqHCvvVsnjNSgO1xWiWrX0Rrt/xXW5Zsl7vS2Y+yu8PL8KFWRzZhaVxfKA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-wasm32-wasi": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-1.7.0.tgz",
|
||||
"integrity": "sha512-Evmk9VcxqnuwQftfAfYEr6YZYSPLzmKUsbFIMep5nTt9PT4XYRFAERj7wNYp+rOcBenF3X4xoB+LhwcOMTNE5w==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^0.45.0",
|
||||
"@emnapi/runtime": "^0.45.0",
|
||||
"@tybys/wasm-util": "^0.8.1",
|
||||
"memfs-browser": "^3.4.13000"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-win32-arm64-msvc": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-1.7.0.tgz",
|
||||
"integrity": "sha512-qgsU7T004COWWpSA0tppDqDxbPLgg8FaU09krIJ7FBl71Sz8SFO40h7fDIjfbTT5w7u6mcaINMQ5bSHu75PCaA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-win32-ia32-msvc": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-1.7.0.tgz",
|
||||
"integrity": "sha512-JGafwWYQ/HpZ3XSwP4adQ6W41pRvhcdXvpzIWtKvX+17+xEXAe2nmGWM6s27pVkg1iV2ZtoYLRDkOUoGqZkCcg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2-win32-x64-msvc": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-1.7.0.tgz",
|
||||
"integrity": "sha512-9oq4ShyFakw8AG3mRls0AoCpxBFcimYx7+jvXeAf2OqKNO+mSA6eZ9z7KQeVCi0+SOEUYxMGf5UiGiDb9R6+9Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-android-arm-eabi": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-1.8.3.tgz",
|
||||
"integrity": "sha512-JFZPlNM0A8Og+Tncb8UZsQrhEMlbHBXPsT3hRoKImzVmTmq28Os0ucFWow0AACp2coLHBSydXH3Dh0lZup3rWw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-android-arm64": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-1.8.3.tgz",
|
||||
"integrity": "sha512-zaf8P3T92caeW2xnMA7P1QvRA4pIt/04oilYP44XlTCtMye//vwXDMeK53sl7dvYiJKnzAWDRx41k8vZvpZazg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-darwin-x64": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-1.8.3.tgz",
|
||||
"integrity": "sha512-YMjmBGFZhLfYjfQ2gll9A+BZu/zAMV7lWZIbKxb7ZgEofILQwuGmExjDtY3Jplido/6leCEdpmlk2oIsME00LA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-freebsd-x64": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-1.8.3.tgz",
|
||||
"integrity": "sha512-Hq3Rj5Yb2RolTG/luRPnv+XiGCbi5nAK25Pc8ou/tVapwX+iktEm/NXbxc5zsMxraYVkCvfdwBjweC5O+KqCGw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-linux-arm-gnueabihf": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-1.8.3.tgz",
|
||||
"integrity": "sha512-x49l8RgzKoG0/V0IXa5rrEl1TcJEc936ctlYFvqcunSOyowZ6kiWtrp1qrbOR8gbaNILl11KTF52vF6+h8UlEQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-linux-arm64-gnu": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-1.8.3.tgz",
|
||||
"integrity": "sha512-gJesam/qA63reGkb9qJ2TjFSLBtY41zQh2oei7nfnYsmVQPuHHWItJxEa1Bm21SPW53gZex4jFJbDIgj0+PxIw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-linux-arm64-musl": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-1.8.3.tgz",
|
||||
"integrity": "sha512-7O6kQdSKzB4Tjx/EBa8zKIxnmLkQE8VdJgPm6Ksrpn+ueo0mx2xf76fIDnbbTCtm3UbB+y+FkTo2wLA7tOqIKg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-linux-x64-musl": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-1.8.3.tgz",
|
||||
"integrity": "sha512-bDbMuyekIxZaN7NaX+gHVkOyABB8bcMEJYeRPW1vCXKHj3brJns1wiUFSxqeUXreupifNVJlQfPt1Y5B/vFXgQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-wasm32-wasi": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-1.8.3.tgz",
|
||||
"integrity": "sha512-NBf2cMCDbNKMzp13Pog8ZPmI0M9U4Ak5b95EUjkp17kdKZFds12dwW67EMnj7Zy+pRqby2QLECaWebDYfNENTg==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^0.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-win32-arm64-msvc": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-1.8.3.tgz",
|
||||
"integrity": "sha512-AHpPo7UbdW5WWjwreVpgFSY0o1RY4A7cUFaqDXZB2OqEuyrhMxBdZct9PX7PQKI18D85pLsODnR+gvVuTwJ6rQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-win32-ia32-msvc": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-1.8.3.tgz",
|
||||
"integrity": "sha512-bqzn2rcQkEwCINefhm69ttBVVkgHJb/V03DdBKsPFtiX6H47axXKz62d1imi26zFXhOEYxhKbu3js03GobJOLw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/argon2/node_modules/@node-rs/argon2-win32-x64-msvc": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-1.8.3.tgz",
|
||||
"integrity": "sha512-ILlrRThdbp5xNR5gwYM2ic1n/vG5rJ8dQZ+YMRqksl+lnTJ/6FDe5BOyIhiPtiDwlCiCtUA+1NxpDB9KlUCAIA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt": {
|
||||
"version": "1.9.0",
|
||||
"license": "MIT",
|
||||
|
@ -4346,6 +4854,27 @@
|
|||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@react-native/dev-middleware/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/dev-middleware/node_modules/open": {
|
||||
"version": "7.4.2",
|
||||
"license": "MIT",
|
||||
|
@ -4468,6 +4997,15 @@
|
|||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.8.3.tgz",
|
||||
"integrity": "sha512-Z96T/L6dUFFxgFJ+pQtkPpne9q7i6kIPYCFnQBHSgSPV9idTsKfIhCss0h5iM9irweZCatkrdeP8yi5uM1eX6Q==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/better-sqlite3": {
|
||||
"version": "7.6.11",
|
||||
"devOptional": true,
|
||||
|
@ -6203,6 +6741,27 @@
|
|||
"node-fetch": "^2.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"license": "MIT",
|
||||
|
@ -6260,6 +6819,14 @@
|
|||
"dev": true,
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/data-uri-to-buffer": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/data-view-buffer": {
|
||||
"version": "1.0.1",
|
||||
"devOptional": true,
|
||||
|
@ -8118,6 +8685,28 @@
|
|||
"version": "4.2.3",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fetch-blob": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"node-domexception": "^1.0.0",
|
||||
"web-streams-polyfill": "^3.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20 || >= 14.13"
|
||||
}
|
||||
},
|
||||
"node_modules/fetch-retry": {
|
||||
"version": "4.1.1",
|
||||
"license": "MIT",
|
||||
|
@ -8319,6 +8908,17 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||
"dependencies": {
|
||||
"fetch-blob": "^3.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
|
@ -8372,6 +8972,12 @@
|
|||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-monkey": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz",
|
||||
"integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"devOptional": true,
|
||||
|
@ -10046,6 +10652,21 @@
|
|||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/lucia/node_modules/@node-rs/argon2-linux-x64-gnu": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-1.7.0.tgz",
|
||||
"integrity": "sha512-EmgqZOlf4Jurk/szW1iTsVISx25bKksVC5uttJDUloTgsAgIGReCpUUO1R24pBhu9ESJa47iv8NSf3yAfGv6jQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/lucia/node_modules/oslo": {
|
||||
"version": "1.2.0",
|
||||
"license": "MIT",
|
||||
|
@ -10150,6 +10771,27 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/memfs": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
|
||||
"integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"fs-monkey": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/memfs-browser": {
|
||||
"version": "3.5.10302",
|
||||
"resolved": "https://registry.npmjs.org/memfs-browser/-/memfs-browser-3.5.10302.tgz",
|
||||
"integrity": "sha512-JJTc/nh3ig05O0gBBGZjTCPOyydaTxNF0uHYBrcc1gHNnO+KIHIvo0Y1FKCJsaei6FCl8C6xfQomXqu+cuzkIw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"memfs": "3.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/memory-cache": {
|
||||
"version": "0.2.0",
|
||||
"license": "BSD-2-Clause",
|
||||
|
@ -10546,24 +11188,39 @@
|
|||
"node": ">= 0.10.5"
|
||||
}
|
||||
},
|
||||
"node_modules/node-domexception": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jimmywarting"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://paypal.me/jimmywarting"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-fetch"
|
||||
}
|
||||
},
|
||||
"node_modules/node-forge": {
|
||||
|
@ -11046,6 +11703,21 @@
|
|||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/oslo/node_modules/@node-rs/argon2-linux-x64-gnu": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-1.7.0.tgz",
|
||||
"integrity": "sha512-EmgqZOlf4Jurk/szW1iTsVISx25bKksVC5uttJDUloTgsAgIGReCpUUO1R24pBhu9ESJa47iv8NSf3yAfGv6jQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/p-finally": {
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
|
@ -12139,6 +12811,134 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-darwin-x64": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz",
|
||||
"integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz",
|
||||
"integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz",
|
||||
"integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz",
|
||||
"integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz",
|
||||
"integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz",
|
||||
"integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-win32-ia32-msvc": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz",
|
||||
"integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/next/node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz",
|
||||
"integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-email/node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"dev": true,
|
||||
|
@ -13806,7 +14606,8 @@
|
|||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
|
@ -14342,15 +15143,25 @@
|
|||
"defaults": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/web-streams-polyfill": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
|
||||
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"license": "BSD-2-Clause",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -10,11 +10,12 @@
|
|||
"db:studio": "drizzle-kit studio",
|
||||
"build": "next build && tsc --project tsconfig.server.json && tsc-alias -p tsconfig.server.json",
|
||||
"start": "ENVIRONMENT=prod node dist/server/index.js",
|
||||
"email": "email dev --dir emailTemplates --port 3002"
|
||||
"email": "email dev --dir server/emails/templates --port 3002"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lucia-auth/adapter-drizzle": "1.1.0",
|
||||
"@node-rs/argon2": "1.8.3",
|
||||
"@node-rs/argon2-linux-x64-gnu": "1.8.3",
|
||||
"@react-email/components": "0.0.25",
|
||||
"@react-email/tailwind": "0.1.0",
|
||||
"axios": "1.7.7",
|
||||
|
@ -28,6 +29,7 @@
|
|||
"http-errors": "2.0.0",
|
||||
"lucia": "3.2.0",
|
||||
"next": "14.2.13",
|
||||
"node-fetch": "3.3.2",
|
||||
"nodemailer": "6.9.15",
|
||||
"oslo": "1.2.1",
|
||||
"react": "^18",
|
||||
|
|
1
server/db/.gitignore
vendored
Normal file
1
server/db/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
names.json
|
|
@ -89,6 +89,16 @@ export const sessions = sqliteTable("session", {
|
|||
expiresAt: integer("expiresAt").notNull(),
|
||||
});
|
||||
|
||||
export const userOrgs = sqliteTable("userOrgs", {
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users.id),
|
||||
orgId: integer("orgId")
|
||||
.notNull()
|
||||
.references(() => orgs.orgId),
|
||||
role: text("role").notNull(), // e.g., 'admin', 'member', etc.
|
||||
});
|
||||
|
||||
// Define the model types for type inference
|
||||
export type Org = InferSelectModel<typeof orgs>;
|
||||
export type User = InferSelectModel<typeof users>;
|
||||
|
|
|
@ -73,6 +73,8 @@ declare global {
|
|||
namespace Express {
|
||||
interface Request {
|
||||
user?: User;
|
||||
userOrgRole?: string;
|
||||
userOrgs?: number[];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
33
server/routers/auth/getUserOrgs.ts
Normal file
33
server/routers/auth/getUserOrgs.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { Request, Response, NextFunction } from 'express';
|
||||
import { db } from '@server/db';
|
||||
import { userOrgs, orgs } from '@server/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import createHttpError from 'http-errors';
|
||||
import HttpCode from '@server/types/HttpCode';
|
||||
|
||||
export async function getUserOrgs(req: Request, res: Response, next: NextFunction) {
|
||||
const userId = req.user?.id; // Assuming you have user information in the request
|
||||
|
||||
if (!userId) {
|
||||
return next(createHttpError(HttpCode.UNAUTHORIZED, 'User not authenticated'));
|
||||
}
|
||||
|
||||
try {
|
||||
const userOrganizations = await db.select({
|
||||
orgId: userOrgs.orgId,
|
||||
role: userOrgs.role,
|
||||
})
|
||||
.from(userOrgs)
|
||||
.where(eq(userOrgs.userId, userId));
|
||||
|
||||
req.userOrgs = userOrganizations.map(org => org.orgId);
|
||||
// req.userOrgRoles = userOrganizations.reduce((acc, org) => {
|
||||
// acc[org.orgId] = org.role;
|
||||
// return acc;
|
||||
// }, {} as Record<number, string>);
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
next(createHttpError(HttpCode.INTERNAL_SERVER_ERROR, 'Error retrieving user organizations'));
|
||||
}
|
||||
}
|
|
@ -4,3 +4,8 @@ export * from "./logout";
|
|||
export * from "./verifyTotp";
|
||||
export * from "./requestTotpSecret";
|
||||
export * from "./disable2fa";
|
||||
export * from "./verifyOrgAccess";
|
||||
export * from "./getUserOrgs";
|
||||
export * from "./verifySiteAccess";
|
||||
export * from "./verifyResourceAccess";
|
||||
export * from "./verifyTargetAccess";
|
36
server/routers/auth/verifyOrgAccess.ts
Normal file
36
server/routers/auth/verifyOrgAccess.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { Request, Response, NextFunction } from 'express';
|
||||
import { db } from '@server/db';
|
||||
import { userOrgs } from '@server/db/schema';
|
||||
import { and, eq } from 'drizzle-orm';
|
||||
import createHttpError from 'http-errors';
|
||||
import HttpCode from '@server/types/HttpCode';
|
||||
import { AuthenticatedRequest } from '@server/types/Auth';
|
||||
|
||||
export function verifyOrgAccess(req: Request, res: Response, next: NextFunction) {
|
||||
const userId = req.user.id; // Assuming you have user information in the request
|
||||
const orgId = parseInt(req.params.orgId);
|
||||
|
||||
if (!userId) {
|
||||
return next(createHttpError(HttpCode.UNAUTHORIZED, 'User not authenticated'));
|
||||
}
|
||||
|
||||
if (isNaN(orgId)) {
|
||||
return next(createHttpError(HttpCode.BAD_REQUEST, 'Invalid organization ID'));
|
||||
}
|
||||
|
||||
db.select()
|
||||
.from(userOrgs)
|
||||
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, orgId)))
|
||||
.then((result) => {
|
||||
if (result.length === 0) {
|
||||
next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
||||
} else {
|
||||
// User has access, attach the user's role to the request for potential future use
|
||||
req.userOrgRole = result[0].role;
|
||||
next();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
next(createHttpError(HttpCode.INTERNAL_SERVER_ERROR, 'Error verifying organization access'));
|
||||
});
|
||||
}
|
54
server/routers/auth/verifyResourceAccess.ts
Normal file
54
server/routers/auth/verifyResourceAccess.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { Request, Response, NextFunction } from 'express';
|
||||
import { db } from '@server/db';
|
||||
import { resources, userOrgs } from '@server/db/schema';
|
||||
import { and, eq } from 'drizzle-orm';
|
||||
import createHttpError from 'http-errors';
|
||||
import HttpCode from '@server/types/HttpCode';
|
||||
|
||||
export async function verifyResourceAccess(req: Request, res: Response, next: NextFunction) {
|
||||
const userId = req.user!.id; // Assuming you have user information in the request
|
||||
const resourceId = req.params.resourceId;
|
||||
|
||||
if (!userId) {
|
||||
return next(createHttpError(HttpCode.UNAUTHORIZED, 'User not authenticated'));
|
||||
}
|
||||
|
||||
const resource = await db.select()
|
||||
.from(resources)
|
||||
.where(eq(resources.resourceId, resourceId))
|
||||
.limit(1);
|
||||
|
||||
if (resource.length === 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
`resource with ID ${resourceId} not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!resource[0].orgId) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
`resource with ID ${resourceId} does not have an organization ID`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
db.select()
|
||||
.from(userOrgs)
|
||||
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, resource[0].orgId)))
|
||||
.then((result) => {
|
||||
if (result.length === 0) {
|
||||
next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
||||
} else {
|
||||
// User has access, attach the user's role to the request for potential future use
|
||||
req.userOrgRole = result[0].role;
|
||||
next();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
next(createHttpError(HttpCode.INTERNAL_SERVER_ERROR, 'Error verifying organization access'));
|
||||
});
|
||||
}
|
58
server/routers/auth/verifySiteAccess.ts
Normal file
58
server/routers/auth/verifySiteAccess.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { Request, Response, NextFunction } from 'express';
|
||||
import { db } from '@server/db';
|
||||
import { sites, userOrgs } from '@server/db/schema';
|
||||
import { and, eq } from 'drizzle-orm';
|
||||
import createHttpError from 'http-errors';
|
||||
import HttpCode from '@server/types/HttpCode';
|
||||
|
||||
export async function verifySiteAccess(req: Request, res: Response, next: NextFunction) {
|
||||
const userId = req.user!.id; // Assuming you have user information in the request
|
||||
const siteId = parseInt(req.params.siteId);
|
||||
|
||||
if (!userId) {
|
||||
return next(createHttpError(HttpCode.UNAUTHORIZED, 'User not authenticated'));
|
||||
}
|
||||
|
||||
if (isNaN(siteId)) {
|
||||
return next(createHttpError(HttpCode.BAD_REQUEST, 'Invalid organization ID'));
|
||||
}
|
||||
|
||||
const site = await db.select()
|
||||
.from(sites)
|
||||
.where(eq(sites.siteId, siteId))
|
||||
.limit(1);
|
||||
|
||||
if (site.length === 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
`Site with ID ${siteId} not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!site[0].orgId) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
`Site with ID ${siteId} does not have an organization ID`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
db.select()
|
||||
.from(userOrgs)
|
||||
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, site[0].orgId)))
|
||||
.then((result) => {
|
||||
if (result.length === 0) {
|
||||
next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
||||
} else {
|
||||
// User has access, attach the user's role to the request for potential future use
|
||||
req.userOrgRole = result[0].role;
|
||||
next();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
next(createHttpError(HttpCode.INTERNAL_SERVER_ERROR, 'Error verifying organization access'));
|
||||
});
|
||||
}
|
83
server/routers/auth/verifyTargetAccess.ts
Normal file
83
server/routers/auth/verifyTargetAccess.ts
Normal file
|
@ -0,0 +1,83 @@
|
|||
import { Request, Response, NextFunction } from 'express';
|
||||
import { db } from '@server/db';
|
||||
import { resources, targets, userOrgs } from '@server/db/schema';
|
||||
import { and, eq } from 'drizzle-orm';
|
||||
import createHttpError from 'http-errors';
|
||||
import HttpCode from '@server/types/HttpCode';
|
||||
|
||||
export async function verifyTargetAccess(req: Request, res: Response, next: NextFunction) {
|
||||
const userId = req.user!.id; // Assuming you have user information in the request
|
||||
const targetId = parseInt(req.params.targetId);
|
||||
|
||||
if (!userId) {
|
||||
return next(createHttpError(HttpCode.UNAUTHORIZED, 'User not authenticated'));
|
||||
}
|
||||
|
||||
if (isNaN(targetId)) {
|
||||
return next(createHttpError(HttpCode.BAD_REQUEST, 'Invalid organization ID'));
|
||||
}
|
||||
|
||||
const target = await db.select()
|
||||
.from(targets)
|
||||
.where(eq(targets.targetId, targetId))
|
||||
.limit(1);
|
||||
|
||||
if (target.length === 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
`target with ID ${targetId} not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const resourceId = target[0].resourceId;
|
||||
|
||||
if (resourceId) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
`target with ID ${targetId} does not have a resource ID`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const resource = await db.select()
|
||||
.from(resources)
|
||||
.where(eq(resources.resourceId, resourceId!))
|
||||
.limit(1);
|
||||
|
||||
if (resource.length === 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
`resource with ID ${resourceId} not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!resource[0].orgId) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
`resource with ID ${resourceId} does not have an organization ID`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
db.select()
|
||||
.from(userOrgs)
|
||||
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, resource[0].orgId)))
|
||||
.then((result) => {
|
||||
if (result.length === 0) {
|
||||
next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
||||
} else {
|
||||
// User has access, attach the user's role to the request for potential future use
|
||||
req.userOrgRole = result[0].role;
|
||||
next();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
next(createHttpError(HttpCode.INTERNAL_SERVER_ERROR, 'Error verifying organization access'));
|
||||
});
|
||||
}
|
|
@ -7,6 +7,7 @@ import * as user from "./user";
|
|||
import * as auth from "./auth";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import { verifySessionMiddleware } from "@server/middlewares";
|
||||
import { verifyOrgAccess, getUserOrgs, verifySiteAccess, verifyResourceAccess, verifyTargetAccess } from "./auth";
|
||||
|
||||
// Root routes
|
||||
export const unauthenticated = Router();
|
||||
|
@ -19,30 +20,30 @@ unauthenticated.get("/", (_, res) => {
|
|||
export const authenticated = Router();
|
||||
authenticated.use(verifySessionMiddleware);
|
||||
|
||||
authenticated.put("/org", org.createOrg);
|
||||
authenticated.get("/orgs", org.listOrgs);
|
||||
authenticated.get("/org/:orgId", org.getOrg);
|
||||
authenticated.post("/org/:orgId", org.updateOrg);
|
||||
authenticated.delete("/org/:orgId", org.deleteOrg);
|
||||
authenticated.put("/org", getUserOrgs, org.createOrg);
|
||||
authenticated.get("/orgs", getUserOrgs, org.listOrgs); // TODO we need to check the orgs here
|
||||
authenticated.get("/org/:orgId", verifyOrgAccess, org.getOrg);
|
||||
authenticated.post("/org/:orgId", verifyOrgAccess, org.updateOrg);
|
||||
authenticated.delete("/org/:orgId", verifyOrgAccess, org.deleteOrg);
|
||||
|
||||
authenticated.put("/org/:orgId/site", site.createSite);
|
||||
authenticated.get("/org/:orgId/sites", site.listSites);
|
||||
authenticated.get("/site/:siteId", site.getSite);
|
||||
authenticated.post("/site/:siteId", site.updateSite);
|
||||
authenticated.delete("/site/:siteId", site.deleteSite);
|
||||
authenticated.put("/org/:orgId/site", verifyOrgAccess, site.createSite);
|
||||
authenticated.get("/org/:orgId/sites", verifyOrgAccess, site.listSites);
|
||||
authenticated.get("/site/:siteId", verifySiteAccess, site.getSite);
|
||||
authenticated.post("/site/:siteId", verifySiteAccess, site.updateSite);
|
||||
authenticated.delete("/site/:siteId", verifySiteAccess, site.deleteSite);
|
||||
|
||||
authenticated.put("/org/:orgId/site/:siteId/resource", resource.createResource);
|
||||
authenticated.put("/org/:orgId/site/:siteId/resource", verifyOrgAccess, resource.createResource);
|
||||
authenticated.get("/site/:siteId/resources", resource.listResources);
|
||||
authenticated.get("/org/:orgId/resources", resource.listResources);
|
||||
authenticated.get("/resource/:resourceId", resource.getResource);
|
||||
authenticated.post("/resource/:resourceId", resource.updateResource);
|
||||
authenticated.delete("/resource/:resourceId", resource.deleteResource);
|
||||
authenticated.get("/org/:orgId/resources", verifyOrgAccess, resource.listResources);
|
||||
authenticated.get("/resource/:resourceId", verifyResourceAccess, resource.getResource);
|
||||
authenticated.post("/resource/:resourceId", verifyResourceAccess, resource.updateResource);
|
||||
authenticated.delete("/resource/:resourceId", verifyResourceAccess, resource.deleteResource);
|
||||
|
||||
authenticated.put("/resource/:resourceId/target", target.createTarget);
|
||||
authenticated.get("/resource/:resourceId/targets", target.listTargets);
|
||||
authenticated.get("/target/:targetId", target.getTarget);
|
||||
authenticated.post("/target/:targetId", target.updateTarget);
|
||||
authenticated.delete("/target/:targetId", target.deleteTarget);
|
||||
authenticated.put("/resource/:resourceId/target", verifyResourceAccess, target.createTarget);
|
||||
authenticated.get("/resource/:resourceId/targets", verifyResourceAccess, target.listTargets);
|
||||
authenticated.get("/target/:targetId", verifyTargetAccess, target.getTarget);
|
||||
authenticated.post("/target/:targetId", verifyTargetAccess, target.updateTarget);
|
||||
authenticated.delete("/target/:targetId", verifyTargetAccess, target.deleteTarget);
|
||||
|
||||
authenticated.get("/users", user.listUsers);
|
||||
// authenticated.get("/org/:orgId/users", user.???); // TODO: Implement this
|
||||
|
|
|
@ -11,6 +11,8 @@ const createOrgSchema = z.object({
|
|||
domain: z.string().min(1).max(255),
|
||||
});
|
||||
|
||||
const MAX_ORGS = 5;
|
||||
|
||||
export async function createOrg(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
try {
|
||||
const parsedBody = createOrgSchema.safeParse(req.body);
|
||||
|
@ -23,6 +25,16 @@ export async function createOrg(req: Request, res: Response, next: NextFunction)
|
|||
);
|
||||
}
|
||||
|
||||
const userOrgIds = req.userOrgs;
|
||||
if (userOrgIds && userOrgIds.length > MAX_ORGS) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.FORBIDDEN,
|
||||
`Maximum number of organizations reached.`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const { name, domain } = parsedBody.data;
|
||||
|
||||
const newOrg = await db.insert(orgs).values({
|
||||
|
|
|
@ -5,7 +5,7 @@ import { orgs } from '@server/db/schema';
|
|||
import response from "@server/utils/response";
|
||||
import HttpCode from '@server/types/HttpCode';
|
||||
import createHttpError from 'http-errors';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { sql, inArray } from 'drizzle-orm';
|
||||
|
||||
const listOrgsSchema = z.object({
|
||||
limit: z.string().optional().transform(Number).pipe(z.number().int().positive().default(10)),
|
||||
|
@ -26,15 +26,45 @@ export async function listOrgs(req: Request, res: Response, next: NextFunction):
|
|||
|
||||
const { limit, offset } = parsedQuery.data;
|
||||
|
||||
// Use the userOrgs passed from the middleware
|
||||
const userOrgIds = req.userOrgs;
|
||||
|
||||
if (!userOrgIds || userOrgIds.length === 0) {
|
||||
return res.status(HttpCode.OK).send(
|
||||
response(res, {
|
||||
data: {
|
||||
organizations: [],
|
||||
pagination: {
|
||||
total: 0,
|
||||
limit,
|
||||
offset,
|
||||
},
|
||||
},
|
||||
success: true,
|
||||
error: false,
|
||||
message: "No organizations found for the user",
|
||||
status: HttpCode.OK,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const organizations = await db.select()
|
||||
.from(orgs)
|
||||
.where(inArray(orgs.orgId, userOrgIds))
|
||||
.limit(limit)
|
||||
.offset(offset);
|
||||
|
||||
const totalCountResult = await db.select({ count: sql<number>`cast(count(*) as integer)` })
|
||||
.from(orgs);
|
||||
.from(orgs)
|
||||
.where(inArray(orgs.orgId, userOrgIds));
|
||||
const totalCount = totalCountResult[0].count;
|
||||
|
||||
// // Add the user's role for each organization
|
||||
// const organizationsWithRoles = organizations.map(org => ({
|
||||
// ...org,
|
||||
// userRole: req.userOrgRoles[org.orgId],
|
||||
// }));
|
||||
|
||||
return res.status(HttpCode.OK).send(
|
||||
response(res, {
|
||||
data: {
|
||||
|
|
|
@ -5,6 +5,9 @@ import { sites } from '@server/db/schema';
|
|||
import response from "@server/utils/response";
|
||||
import HttpCode from '@server/types/HttpCode';
|
||||
import createHttpError from 'http-errors';
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const API_BASE_URL = "http://localhost:3000";
|
||||
|
||||
const createSiteParamsSchema = z.object({
|
||||
orgId: z.number().int().positive(),
|
||||
|
@ -68,3 +71,28 @@ export async function createSite(req: Request, res: Response, next: NextFunction
|
|||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function addPeer(peer: string) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/peer`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(peer),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data: any = await response.json();
|
||||
console.log('Peer added successfully:', data.status);
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error('Error adding peer:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ import response from "@server/utils/response";
|
|||
import HttpCode from '@server/types/HttpCode';
|
||||
import createHttpError from 'http-errors';
|
||||
|
||||
|
||||
const API_BASE_URL = "http://localhost:3000";
|
||||
|
||||
// Define Zod schema for request parameters validation
|
||||
const deleteSiteSchema = z.object({
|
||||
siteId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
|
@ -54,3 +57,23 @@ export async function deleteSite(req: Request, res: Response, next: NextFunction
|
|||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function removePeer(publicKey: string) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/peer?public_key=${encodeURIComponent(publicKey)}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('Peer removed successfully:', data.status);
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error('Error removing peer:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,4 +5,5 @@ import { Session } from "lucia";
|
|||
export interface AuthenticatedRequest extends Request {
|
||||
user: User;
|
||||
session: Session;
|
||||
userOrgRole?: string;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue