Rate limits!
This commit is contained in:
parent
bd7b7dea66
commit
572455b2f2
5 changed files with 93 additions and 55 deletions
|
@ -14,13 +14,14 @@
|
|||
"dependencies": {
|
||||
"@ably-labs/react-hooks": "^2.1.1",
|
||||
"@auth/prisma-adapter": "^1.0.0",
|
||||
"@prisma/client": "4.15.0",
|
||||
"@prisma/client": "4.16.0",
|
||||
"@react-email/components": "^0.0.7",
|
||||
"@tanstack/react-query": "^4.29.14",
|
||||
"@tanstack/react-query": "^4.29.15",
|
||||
"@trpc/client": "10.31.0",
|
||||
"@trpc/next": "10.31.0",
|
||||
"@trpc/react-query": "10.31.0",
|
||||
"@trpc/server": "10.31.0",
|
||||
"@upstash/ratelimit": "^0.4.3",
|
||||
"@upstash/redis": "^1.21.0",
|
||||
"ably": "^1.2.40",
|
||||
"autoprefixer": "^10.4.14",
|
||||
|
@ -47,7 +48,7 @@
|
|||
"daisyui": "^3.1.1",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-next": "^13.4.6",
|
||||
"prisma": "4.15.0",
|
||||
"prisma": "4.16.0",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
|
|
106
pnpm-lock.yaml
generated
106
pnpm-lock.yaml
generated
|
@ -10,28 +10,31 @@ dependencies:
|
|||
version: 2.1.1(react-dom@18.2.0)(react@18.2.0)
|
||||
'@auth/prisma-adapter':
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0(@prisma/client@4.15.0)
|
||||
version: 1.0.0(@prisma/client@4.16.0)
|
||||
'@prisma/client':
|
||||
specifier: 4.15.0
|
||||
version: 4.15.0(prisma@4.15.0)
|
||||
specifier: 4.16.0
|
||||
version: 4.16.0(prisma@4.16.0)
|
||||
'@react-email/components':
|
||||
specifier: ^0.0.7
|
||||
version: 0.0.7
|
||||
'@tanstack/react-query':
|
||||
specifier: ^4.29.14
|
||||
version: 4.29.14(react-dom@18.2.0)(react@18.2.0)
|
||||
specifier: ^4.29.15
|
||||
version: 4.29.15(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/client':
|
||||
specifier: 10.31.0
|
||||
version: 10.31.0(@trpc/server@10.31.0)
|
||||
'@trpc/next':
|
||||
specifier: 10.31.0
|
||||
version: 10.31.0(@tanstack/react-query@4.29.14)(@trpc/client@10.31.0)(@trpc/react-query@10.31.0)(@trpc/server@10.31.0)(next@13.4.6)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 10.31.0(@tanstack/react-query@4.29.15)(@trpc/client@10.31.0)(@trpc/react-query@10.31.0)(@trpc/server@10.31.0)(next@13.4.6)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/react-query':
|
||||
specifier: 10.31.0
|
||||
version: 10.31.0(@tanstack/react-query@4.29.14)(@trpc/client@10.31.0)(@trpc/server@10.31.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 10.31.0(@tanstack/react-query@4.29.15)(@trpc/client@10.31.0)(@trpc/server@10.31.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/server':
|
||||
specifier: 10.31.0
|
||||
version: 10.31.0
|
||||
'@upstash/ratelimit':
|
||||
specifier: ^0.4.3
|
||||
version: 0.4.3
|
||||
'@upstash/redis':
|
||||
specifier: ^1.21.0
|
||||
version: 1.21.0
|
||||
|
@ -107,8 +110,8 @@ devDependencies:
|
|||
specifier: ^13.4.6
|
||||
version: 13.4.6(eslint@8.43.0)(typescript@5.1.3)
|
||||
prisma:
|
||||
specifier: 4.15.0
|
||||
version: 4.15.0
|
||||
specifier: 4.16.0
|
||||
version: 4.16.0
|
||||
tailwindcss:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
|
@ -159,13 +162,13 @@ packages:
|
|||
preact-render-to-string: 5.2.3(preact@10.11.3)
|
||||
dev: false
|
||||
|
||||
/@auth/prisma-adapter@1.0.0(@prisma/client@4.15.0):
|
||||
/@auth/prisma-adapter@1.0.0(@prisma/client@4.16.0):
|
||||
resolution: {integrity: sha512-+x+s5dgpNmqrcQC2ZRAXZIM6yhkWP/EXjIUgqUyMepLiX1OHi2AXIUAAbXsW4oG9OpYr/rvPIzPBpuGt6sPFwQ==}
|
||||
peerDependencies:
|
||||
'@prisma/client': '>=2.26.0 || >=3 || >=4'
|
||||
dependencies:
|
||||
'@auth/core': 0.8.1
|
||||
'@prisma/client': 4.15.0(prisma@4.15.0)
|
||||
'@prisma/client': 4.16.0(prisma@4.16.0)
|
||||
transitivePeerDependencies:
|
||||
- nodemailer
|
||||
dev: false
|
||||
|
@ -763,8 +766,8 @@ packages:
|
|||
tslib: 2.5.3
|
||||
dev: true
|
||||
|
||||
/@prisma/client@4.15.0(prisma@4.15.0):
|
||||
resolution: {integrity: sha512-xnROvyABcGiwqRNdrObHVZkD9EjkJYHOmVdlKy1yGgI+XOzvMzJ4tRg3dz1pUlsyhKxXGCnjIQjWW+2ur+YXuw==}
|
||||
/@prisma/client@4.16.0(prisma@4.16.0):
|
||||
resolution: {integrity: sha512-CBD+5IdZPiavhLkQokvsz1uz4r9ppixaqY/ajybWs4WXNnsDVMBKEqN3BiPzpSo79jiy22VKj/67pqt4VwIg9w==}
|
||||
engines: {node: '>=14.17'}
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
|
@ -773,16 +776,16 @@ packages:
|
|||
prisma:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@prisma/engines-version': 4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944
|
||||
prisma: 4.15.0
|
||||
'@prisma/engines-version': 4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c
|
||||
prisma: 4.16.0
|
||||
dev: false
|
||||
|
||||
/@prisma/engines-version@4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944:
|
||||
resolution: {integrity: sha512-sVOig4tjGxxlYaFcXgE71f/rtFhzyYrfyfNFUsxCIEJyVKU9rdOWIlIwQ2NQ7PntvGnn+x0XuFo4OC1jvPJKzg==}
|
||||
/@prisma/engines-version@4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c:
|
||||
resolution: {integrity: sha512-tMWAF/qF00fbUH1HB4Yjmz6bjh7fzkb7Y3NRoUfMlHu6V+O45MGvqwYxqwBjn1BIUXkl3r04W351D4qdJjrgvA==}
|
||||
dev: false
|
||||
|
||||
/@prisma/engines@4.15.0:
|
||||
resolution: {integrity: sha512-FTaOCGs0LL0OW68juZlGxFtYviZa4xdQj/rQEdat2txw0s3Vu/saAPKjNVXfIgUsGXmQ72HPgNr6935/P8FNAA==}
|
||||
/@prisma/engines@4.16.0:
|
||||
resolution: {integrity: sha512-M6XoMRXnqL0rqZGQS8ZpNiHYG4G1fKBdoqW/oBtHnr1in5UYgerZqal3CXchmd6OBD/770PE9dtjQuqcilZJUA==}
|
||||
requiresBuild: true
|
||||
|
||||
/@radix-ui/react-compose-refs@1.0.0(react@18.2.0):
|
||||
|
@ -995,12 +998,12 @@ packages:
|
|||
defer-to-connect: 2.0.1
|
||||
dev: false
|
||||
|
||||
/@tanstack/query-core@4.29.14:
|
||||
resolution: {integrity: sha512-ElEAahtLWA7Y7c2Haw10KdEf2tx+XZl/Z8dmyWxZehxWK3TPL5qtXtb7kUEhvt/8u2cSP62fLxgh2qqzMMGnDQ==}
|
||||
/@tanstack/query-core@4.29.15:
|
||||
resolution: {integrity: sha512-Recc1d5rjHesKhzlH3Aw66v+vQxtB9OHEXP/vxgEcEJ0DwEpfe3EQ4id20vuBJHY2XRjfgWGmUs6ZgK6PSsTXA==}
|
||||
dev: false
|
||||
|
||||
/@tanstack/react-query@4.29.14(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-wh4bd/QIy85YgTDBtj/7/9ZkpRX41QdZuUL8xKoSzuMCukXvAE1/oJ4p0F15lqQq9W3g2pgcbr2Aa+CNvqABhg==}
|
||||
/@tanstack/react-query@4.29.15(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-1zDkv95ljuJ623hhbYU8YIprPW2x6774kh3IQNEuZav62+S+Zr26uUOrE2zGRp9I1uO5Liw/0uYB3dWXQP5+3Q==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
|
@ -1011,7 +1014,7 @@ packages:
|
|||
react-native:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@tanstack/query-core': 4.29.14
|
||||
'@tanstack/query-core': 4.29.15
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
|
@ -1025,7 +1028,7 @@ packages:
|
|||
'@trpc/server': 10.31.0
|
||||
dev: false
|
||||
|
||||
/@trpc/next@10.31.0(@tanstack/react-query@4.29.14)(@trpc/client@10.31.0)(@trpc/react-query@10.31.0)(@trpc/server@10.31.0)(next@13.4.6)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@trpc/next@10.31.0(@tanstack/react-query@4.29.15)(@trpc/client@10.31.0)(@trpc/react-query@10.31.0)(@trpc/server@10.31.0)(next@13.4.6)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-BZtZr7UKAs0tUTreCsYhy+/HjFNFl5KBwBS+Li6pCv9GwqCDqpoivesQz7LltO4Y4lOLXLm9tXQXtS1gfmF9yg==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^4.18.0
|
||||
|
@ -1036,9 +1039,9 @@ packages:
|
|||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
dependencies:
|
||||
'@tanstack/react-query': 4.29.14(react-dom@18.2.0)(react@18.2.0)
|
||||
'@tanstack/react-query': 4.29.15(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/client': 10.31.0(@trpc/server@10.31.0)
|
||||
'@trpc/react-query': 10.31.0(@tanstack/react-query@4.29.14)(@trpc/client@10.31.0)(@trpc/server@10.31.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/react-query': 10.31.0(@tanstack/react-query@4.29.15)(@trpc/client@10.31.0)(@trpc/server@10.31.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/server': 10.31.0
|
||||
next: 13.4.6(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
|
@ -1046,7 +1049,7 @@ packages:
|
|||
react-ssr-prepass: 1.5.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@trpc/react-query@10.31.0(@tanstack/react-query@4.29.14)(@trpc/client@10.31.0)(@trpc/server@10.31.0)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@trpc/react-query@10.31.0(@tanstack/react-query@4.29.15)(@trpc/client@10.31.0)(@trpc/server@10.31.0)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-+M8sIsbf6e4H5XYvHlzDqhaf+ybfUigA/9OL3wXRp2vXhCedEiIERCnwNuHWFDRASl9vjOcM33AuJ4sbOOINEA==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^4.18.0
|
||||
|
@ -1055,7 +1058,7 @@ packages:
|
|||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
dependencies:
|
||||
'@tanstack/react-query': 4.29.14(react-dom@18.2.0)(react@18.2.0)
|
||||
'@tanstack/react-query': 4.29.15(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/client': 10.31.0(@trpc/server@10.31.0)
|
||||
'@trpc/server': 10.31.0
|
||||
react: 18.2.0
|
||||
|
@ -1277,6 +1280,23 @@ packages:
|
|||
eslint-visitor-keys: 3.4.1
|
||||
dev: true
|
||||
|
||||
/@upstash/core-analytics@0.0.6:
|
||||
resolution: {integrity: sha512-cpPSR0XJAJs4Ddz9nq3tINlPS5aLfWVCqhhtHnXt4p7qr5+/Znlt1Es736poB/9rnl1hAHrOsOvVj46NEXcVqA==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
dependencies:
|
||||
'@upstash/redis': 1.21.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@upstash/ratelimit@0.4.3:
|
||||
resolution: {integrity: sha512-Dsp9Mw09Flg28JRklKgFiCXqr3bqv8bbG0kgpUYoHjcgPPolFFyaYOj/I2HExvYLZiogl77NUavBoNvMOK0zUQ==}
|
||||
dependencies:
|
||||
'@upstash/core-analytics': 0.0.6
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/@upstash/redis@1.21.0:
|
||||
resolution: {integrity: sha512-c6M+cl0LOgGK/7Gp6ooMkIZ1IDAJs8zFR+REPkoSkAq38o7CWFX5FYwYEqGZ6wJpUGBuEOr/7hTmippXGgL25A==}
|
||||
dependencies:
|
||||
|
@ -1462,7 +1482,7 @@ packages:
|
|||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
browserslist: 4.21.9
|
||||
caniuse-lite: 1.0.30001504
|
||||
caniuse-lite: 1.0.30001505
|
||||
fraction.js: 4.2.0
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.0
|
||||
|
@ -1576,8 +1596,8 @@ packages:
|
|||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001504
|
||||
electron-to-chromium: 1.4.434
|
||||
caniuse-lite: 1.0.30001505
|
||||
electron-to-chromium: 1.4.435
|
||||
node-releases: 2.0.12
|
||||
update-browserslist-db: 1.0.11(browserslist@4.21.9)
|
||||
dev: false
|
||||
|
@ -1647,8 +1667,8 @@ packages:
|
|||
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
/caniuse-lite@1.0.30001504:
|
||||
resolution: {integrity: sha512-5uo7eoOp2mKbWyfMXnGO9rJWOGU8duvzEiYITW+wivukL7yHH4gX9yuRaobu6El4jPxo6jKZfG+N6fB621GD/Q==}
|
||||
/caniuse-lite@1.0.30001505:
|
||||
resolution: {integrity: sha512-jaAOR5zVtxHfL0NjZyflVTtXm3D3J9P15zSJ7HmQF8dSKGA6tqzQq+0ZI3xkjyQj46I4/M0K2GbMpcAFOcbr3A==}
|
||||
dev: false
|
||||
|
||||
/chainsaw@0.1.0:
|
||||
|
@ -2060,8 +2080,8 @@ packages:
|
|||
sigmund: 1.0.1
|
||||
dev: false
|
||||
|
||||
/electron-to-chromium@1.4.434:
|
||||
resolution: {integrity: sha512-5Gvm09UZTQRaWrimRtWRO5rvaX6Kpk5WHAPKDa7A4Gj6NIPuJ8w8WNpnxCXdd+CJJt6RBU6tUw0KyULoW6XuHw==}
|
||||
/electron-to-chromium@1.4.435:
|
||||
resolution: {integrity: sha512-B0CBWVFhvoQCW/XtjRzgrmqcgVWg6RXOEM/dK59+wFV93BFGR6AeNKc4OyhM+T3IhJaOOG8o/V+33Y2mwJWtzw==}
|
||||
dev: false
|
||||
|
||||
/emoji-regex@9.2.2:
|
||||
|
@ -3615,7 +3635,7 @@ packages:
|
|||
'@next/env': 13.4.6
|
||||
'@swc/helpers': 0.5.1
|
||||
busboy: 1.6.0
|
||||
caniuse-lite: 1.0.30001504
|
||||
caniuse-lite: 1.0.30001505
|
||||
postcss: 8.4.14
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
|
@ -3958,8 +3978,8 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/pirates@4.0.5:
|
||||
resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==}
|
||||
/pirates@4.0.6:
|
||||
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
|
||||
engines: {node: '>= 6'}
|
||||
dev: true
|
||||
|
||||
|
@ -4176,13 +4196,13 @@ packages:
|
|||
js-beautify: 1.14.8
|
||||
dev: false
|
||||
|
||||
/prisma@4.15.0:
|
||||
resolution: {integrity: sha512-iKZZpobPl48gTcSZVawLMQ3lEy6BnXwtoMj7hluoGFYu2kQ6F9LBuBrUyF95zRVnNo8/3KzLXJXJ5TEnLSJFiA==}
|
||||
/prisma@4.16.0:
|
||||
resolution: {integrity: sha512-kSCwbTm3LCephyGfZMJYqBXpPJXdJStg5xwfzeFmR5C05zfkOURK9pQpJF6uUQvFWm3lI9ZMSNkObmFkAPnB+g==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@prisma/engines': 4.15.0
|
||||
'@prisma/engines': 4.16.0
|
||||
|
||||
/process-nextick-args@2.0.1:
|
||||
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||
|
@ -4737,7 +4757,7 @@ packages:
|
|||
glob: 7.1.6
|
||||
lines-and-columns: 1.2.4
|
||||
mz: 2.7.0
|
||||
pirates: 4.0.5
|
||||
pirates: 4.0.6
|
||||
ts-interface-checker: 0.1.13
|
||||
dev: true
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ const server = z.object({
|
|||
DATABASE_URL: z.string().url(),
|
||||
UPSTASH_REDIS_REST_URL: z.string().url(),
|
||||
UPSTASH_REDIS_REST_TOKEN: z.string(),
|
||||
UPSTASH_RATELIMIT_REQUESTS: z.string(),
|
||||
UPSTASH_RATELIMIT_SECONDS: z.string(),
|
||||
NODE_ENV: z.enum(["development", "test", "production"]),
|
||||
NEXTAUTH_SECRET:
|
||||
process.env.NODE_ENV === "production"
|
||||
|
@ -67,6 +69,8 @@ const processEnv = {
|
|||
DATABASE_URL: process.env.DATABASE_URL,
|
||||
UPSTASH_REDIS_REST_URL: process.env.UPSTASH_REDIS_REST_URL,
|
||||
UPSTASH_REDIS_REST_TOKEN: process.env.UPSTASH_REDIS_REST_TOKEN,
|
||||
UPSTASH_RATELIMIT_REQUESTS: process.env.UPSTASH_RATELIMIT_REQUESTS,
|
||||
UPSTASH_RATELIMIT_SECONDS: process.env.UPSTASH_RATELIMIT_SECONDS,
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
|
||||
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
import { z } from "zod";
|
||||
import { publishToChannel } from "~/server/ably";
|
||||
|
||||
import {
|
||||
createTRPCRouter,
|
||||
publicProcedure,
|
||||
protectedProcedure,
|
||||
} from "~/server/api/trpc";
|
||||
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
|
||||
|
||||
import { env } from "~/env.mjs";
|
||||
import { redis } from "~/server/redis";
|
||||
|
||||
export const roomRouter = createTRPCRouter({
|
||||
// Create
|
||||
create: publicProcedure
|
||||
create: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
|
|
|
@ -20,6 +20,15 @@ import { type Session } from "next-auth";
|
|||
import { getServerAuthSession } from "~/server/auth";
|
||||
import { prisma } from "~/server/db";
|
||||
|
||||
const rateLimit = new Ratelimit({
|
||||
redis,
|
||||
limiter: Ratelimit.slidingWindow(
|
||||
Number(env.UPSTASH_RATELIMIT_REQUESTS),
|
||||
`${Number(env.UPSTASH_RATELIMIT_SECONDS)}s`
|
||||
),
|
||||
analytics: true,
|
||||
});
|
||||
|
||||
type CreateContextOptions = {
|
||||
session: Session | null;
|
||||
};
|
||||
|
@ -65,6 +74,9 @@ export const createTRPCContext = async (opts: CreateNextContextOptions) => {
|
|||
*/
|
||||
import { initTRPC, TRPCError } from "@trpc/server";
|
||||
import superjson from "superjson";
|
||||
import { Ratelimit } from "@upstash/ratelimit";
|
||||
import { redis } from "../redis";
|
||||
import { env } from "~/env.mjs";
|
||||
|
||||
const t = initTRPC.context<typeof createTRPCContext>().create({
|
||||
transformer: superjson,
|
||||
|
@ -97,13 +109,18 @@ export const createTRPCRouter = t.router;
|
|||
export const publicProcedure = t.procedure;
|
||||
|
||||
/** Reusable middleware that enforces users are logged in before running the procedure. */
|
||||
const enforceUserIsAuthed = t.middleware(({ ctx, next }) => {
|
||||
const enforceRouteProtection = t.middleware(async ({ ctx, next }) => {
|
||||
// Auth
|
||||
if (!ctx.session || !ctx.session.user) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
}
|
||||
const { success } = await rateLimit.limit(
|
||||
`${env.APP_ENV}_${ctx.session.user.id}`
|
||||
);
|
||||
if (!success) throw new TRPCError({ code: "TOO_MANY_REQUESTS" });
|
||||
|
||||
return next({
|
||||
ctx: {
|
||||
// infers the `session` as non-nullable
|
||||
session: { ...ctx.session, user: ctx.session.user },
|
||||
},
|
||||
});
|
||||
|
@ -117,4 +134,4 @@ const enforceUserIsAuthed = t.middleware(({ ctx, next }) => {
|
|||
*
|
||||
* @see https://trpc.io/docs/procedures
|
||||
*/
|
||||
export const protectedProcedure = t.procedure.use(enforceUserIsAuthed);
|
||||
export const protectedProcedure = t.procedure.use(enforceRouteProtection);
|
||||
|
|
Loading…
Add table
Reference in a new issue