diff --git a/apps/dashboard/lib/env.ts b/apps/dashboard/lib/env.ts index 235e0f75f9..259f629e50 100644 --- a/apps/dashboard/lib/env.ts +++ b/apps/dashboard/lib/env.ts @@ -31,6 +31,12 @@ export const env = () => AGENT_TOKEN: z.string(), GITHUB_KEYS_URI: z.string().optional(), + + // This key is used for ratelimiting our trpc procedures + // It requires the following permissions: + // - `ratelimit.*.create_namespace` + // - `ratelimit.*.limit` + UNKEY_ROOT_KEY: z.string().optional(), }) .parse(process.env); diff --git a/apps/dashboard/lib/trpc/ratelimitProcedure.ts b/apps/dashboard/lib/trpc/ratelimitProcedure.ts new file mode 100644 index 0000000000..ae822ace2a --- /dev/null +++ b/apps/dashboard/lib/trpc/ratelimitProcedure.ts @@ -0,0 +1,48 @@ +import { TRPCError } from "@trpc/server"; +import { Ratelimit } from "@unkey/ratelimit"; +import { env } from "../env"; +// Values for route types +import { auth, protectedProcedure } from "./trpc"; + +export const ratelimit = env().UNKEY_ROOT_KEY + ? { + create: new Ratelimit({ + rootKey: env().UNKEY_ROOT_KEY ?? "", + namespace: "trpc_create", + limit: 5, + duration: "3s", + }), + + update: new Ratelimit({ + rootKey: env().UNKEY_ROOT_KEY ?? "", + namespace: "trpc_update", + limit: 25, + duration: "5s", + }), + delete: new Ratelimit({ + rootKey: env().UNKEY_ROOT_KEY ?? "", + namespace: "trpc_delete", + limit: 5, + duration: "5s", + }), + } + : {}; +export const rateLimitedProcedure = (ratelimit: Ratelimit | undefined) => + ratelimit + ? protectedProcedure.use(async (opts) => { + const response = await ratelimit.limit(opts.ctx.user.id); + + if (!response.success) { + throw new TRPCError({ + code: "TOO_MANY_REQUESTS", + message: "Too many requests in the allowed duration. Please try again", + }); + } + + return opts.next({ + ctx: { + ...opts.ctx, + }, + }); + }) + : protectedProcedure; diff --git a/apps/dashboard/lib/trpc/routers/api/create.ts b/apps/dashboard/lib/trpc/routers/api/create.ts index b14ba004cc..6748756dd2 100644 --- a/apps/dashboard/lib/trpc/routers/api/create.ts +++ b/apps/dashboard/lib/trpc/routers/api/create.ts @@ -3,16 +3,15 @@ import { z } from "zod"; import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { newId } from "@unkey/id"; -import { auth, t } from "../../trpc"; -export const createApi = t.procedure - .use(auth) +export const createApi = rateLimitedProcedure(ratelimit.create) .input( z.object({ name: z .string() - .min(1, "workspace names must contain at least 3 characters") + .min(3, "workspace names must contain at least 3 characters") .max(50, "workspace names must contain at most 50 characters"), }), ) diff --git a/apps/dashboard/lib/trpc/routers/api/delete.ts b/apps/dashboard/lib/trpc/routers/api/delete.ts index dd325e15e1..93f0d4ac07 100644 --- a/apps/dashboard/lib/trpc/routers/api/delete.ts +++ b/apps/dashboard/lib/trpc/routers/api/delete.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const deleteApi = t.procedure - .use(auth) +export const deleteApi = rateLimitedProcedure(ratelimit.delete) .input( z.object({ apiId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts b/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts index 12781ce712..e3f48f50f2 100644 --- a/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts +++ b/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const updateAPIDeleteProtection = t.procedure - .use(auth) +export const updateAPIDeleteProtection = rateLimitedProcedure(ratelimit.update) .input( z.object({ apiId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts b/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts index 1c679ba2e2..ad746d178e 100644 --- a/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts +++ b/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const updateApiIpWhitelist = t.procedure - .use(auth) +export const updateApiIpWhitelist = rateLimitedProcedure(ratelimit.update) .input( z.object({ ipWhitelist: z diff --git a/apps/dashboard/lib/trpc/routers/api/updateName.ts b/apps/dashboard/lib/trpc/routers/api/updateName.ts index 37352acb2a..7d6c85ba9b 100644 --- a/apps/dashboard/lib/trpc/routers/api/updateName.ts +++ b/apps/dashboard/lib/trpc/routers/api/updateName.ts @@ -3,11 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { th } from "@faker-js/faker"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const updateApiName = t.procedure - .use(auth) +export const updateApiName = rateLimitedProcedure(ratelimit.update) .input( z.object({ name: z.string().min(3, "API names must contain at least 3 characters"), diff --git a/apps/dashboard/lib/trpc/routers/gateway/create.ts b/apps/dashboard/lib/trpc/routers/gateway/create.ts index 6a4bb304ed..f714ff15e4 100644 --- a/apps/dashboard/lib/trpc/routers/gateway/create.ts +++ b/apps/dashboard/lib/trpc/routers/gateway/create.ts @@ -1,11 +1,10 @@ import { db } from "@/lib/db"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const createGateway = t.procedure - .use(auth) +export const createGateway = rateLimitedProcedure(ratelimit.create) .input( z.object({ subdomain: z diff --git a/apps/dashboard/lib/trpc/routers/key/create.ts b/apps/dashboard/lib/trpc/routers/key/create.ts index fd1b4b0bed..5c5c34a66d 100644 --- a/apps/dashboard/lib/trpc/routers/key/create.ts +++ b/apps/dashboard/lib/trpc/routers/key/create.ts @@ -1,13 +1,12 @@ import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { newKey } from "@unkey/keys"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const createKey = t.procedure - .use(auth) +export const createKey = rateLimitedProcedure(ratelimit.create) .input( z.object({ prefix: z.string().optional(), diff --git a/apps/dashboard/lib/trpc/routers/key/createRootKey.ts b/apps/dashboard/lib/trpc/routers/key/createRootKey.ts index f6aaa08a93..4f23f3dbc4 100644 --- a/apps/dashboard/lib/trpc/routers/key/createRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/key/createRootKey.ts @@ -1,16 +1,16 @@ import { type Permission, db, eq, schema } from "@/lib/db"; import { env } from "@/lib/env"; import { type UnkeyAuditLog, ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { newKey } from "@unkey/keys"; import { unkeyPermissionValidation } from "@unkey/rbac"; import { z } from "zod"; -import { auth, t } from "../../trpc"; + import { upsertPermissions } from "../rbac"; -export const createRootKey = t.procedure - .use(auth) +export const createRootKey = rateLimitedProcedure(ratelimit.create) .input( z.object({ name: z.string().optional(), diff --git a/apps/dashboard/lib/trpc/routers/key/delete.ts b/apps/dashboard/lib/trpc/routers/key/delete.ts index 716e415250..51348260dd 100644 --- a/apps/dashboard/lib/trpc/routers/key/delete.ts +++ b/apps/dashboard/lib/trpc/routers/key/delete.ts @@ -1,11 +1,10 @@ import { and, db, eq, inArray, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const deleteKeys = t.procedure - .use(auth) +export const deleteKeys = rateLimitedProcedure(ratelimit.delete) .input( z.object({ keyIds: z.array(z.string()), diff --git a/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts b/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts index b8317c20ae..1c08336b19 100644 --- a/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts @@ -1,12 +1,11 @@ -import { and, db, eq, inArray, isNotNull, schema } from "@/lib/db"; +import { db, inArray, schema } from "@/lib/db"; import { env } from "@/lib/env"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const deleteRootKeys = t.procedure - .use(auth) +export const deleteRootKeys = rateLimitedProcedure(ratelimit.delete) .input( z.object({ keyIds: z.array(z.string()), diff --git a/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts b/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts index d5b0029200..b14bfe94c2 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const updateKeyEnabled = t.procedure - .use(auth) +export const updateKeyEnabled = rateLimitedProcedure(ratelimit.update) .input( z.object({ keyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts b/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts index 507a68c5b7..7886b4731c 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const updateKeyExpiration = t.procedure - .use(auth) +export const updateKeyExpiration = rateLimitedProcedure(ratelimit.update) .input( z.object({ keyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts b/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts index 9edee16c99..4bc208d5f1 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const updateKeyMetadata = t.procedure - .use(auth) +export const updateKeyMetadata = rateLimitedProcedure(ratelimit.update) .input( z.object({ keyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/key/updateName.ts b/apps/dashboard/lib/trpc/routers/key/updateName.ts index 9fc6b11413..0929d7d8dc 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateName.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateName.ts @@ -1,10 +1,11 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { auth, t } from "../../trpc"; -export const updateKeyName = t.procedure +export const updateKeyName = rateLimitedProcedure(ratelimit.update) .use(auth) .input( z.object({ diff --git a/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts b/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts index 8d78aa50fd..2745763dcc 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts @@ -1,11 +1,11 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { auth, t } from "../../trpc"; -export const updateKeyOwnerId = t.procedure - .use(auth) +export const updateKeyOwnerId = rateLimitedProcedure(ratelimit.update) .input( z.object({ keyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts b/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts index e409a247c4..b02b61d598 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const updateKeyRatelimit = t.procedure - .use(auth) +export const updateKeyRatelimit = rateLimitedProcedure(ratelimit.update) .input( z.object({ keyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts b/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts index 53dd7dec15..6aecf13657 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const updateKeyRemaining = t.procedure - .use(auth) +export const updateKeyRemaining = rateLimitedProcedure(ratelimit.update) .input( z.object({ keyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/llmGateway/create.ts b/apps/dashboard/lib/trpc/routers/llmGateway/create.ts index 5ce844376f..eb2ee39c8f 100644 --- a/apps/dashboard/lib/trpc/routers/llmGateway/create.ts +++ b/apps/dashboard/lib/trpc/routers/llmGateway/create.ts @@ -1,13 +1,12 @@ import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { DatabaseError } from "@planetscale/database"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const createLlmGateway = t.procedure - .use(auth) +export const createLlmGateway = rateLimitedProcedure(ratelimit.create) .input( z.object({ subdomain: z.string().min(1).max(50), diff --git a/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts b/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts index 0a64a2b2ad..3a1fec218f 100644 --- a/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts +++ b/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const deleteLlmGateway = t.procedure - .use(auth) +export const deleteLlmGateway = rateLimitedProcedure(ratelimit.delete) .input(z.object({ gatewayId: z.string() })) .mutation(async ({ ctx, input }) => { const llmGateway = await db.query.llmGateways.findFirst({ diff --git a/apps/dashboard/lib/trpc/routers/monitor/verification/create.ts b/apps/dashboard/lib/trpc/routers/monitor/verification/create.ts index 6d8fe85728..b66754a1e2 100644 --- a/apps/dashboard/lib/trpc/routers/monitor/verification/create.ts +++ b/apps/dashboard/lib/trpc/routers/monitor/verification/create.ts @@ -1,13 +1,12 @@ import { type Webhook, db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError, createCallerFactory } from "@trpc/server"; import { newId } from "@unkey/id"; import { z } from "zod"; import { router } from "../.."; -import { auth, t } from "../../../trpc"; -export const createVerificationMonitor = t.procedure - .use(auth) +export const createVerificationMonitor = rateLimitedProcedure(ratelimit.create) .input( z.object({ interval: z diff --git a/apps/dashboard/lib/trpc/routers/plain.ts b/apps/dashboard/lib/trpc/routers/plain.ts index 6604d1905b..d98f4c846a 100644 --- a/apps/dashboard/lib/trpc/routers/plain.ts +++ b/apps/dashboard/lib/trpc/routers/plain.ts @@ -1,14 +1,13 @@ import { env } from "@/lib/env"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { clerkClient } from "@clerk/nextjs"; import { PlainClient, uiComponent } from "@team-plain/typescript-sdk"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../trpc"; const issueType = z.enum(["bug", "feature", "security", "question", "payment"]); const severity = z.enum(["p0", "p1", "p2", "p3"]); -export const createPlainIssue = t.procedure - .use(auth) +export const createPlainIssue = rateLimitedProcedure(ratelimit.create) .input( z.object({ issueType, diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts b/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts index c6d0107e38..6438b49a1e 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts @@ -3,12 +3,11 @@ import { z } from "zod"; import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { DatabaseError } from "@planetscale/database"; import { newId } from "@unkey/id"; -import { auth, t } from "../../trpc"; -export const createNamespace = t.procedure - .use(auth) +export const createNamespace = rateLimitedProcedure(ratelimit.create) .input( z.object({ name: z.string().min(1).max(50), diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts b/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts index c9435743d6..69ce306c62 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts @@ -3,11 +3,10 @@ import { z } from "zod"; import { and, db, eq, isNull, schema, sql } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { newId } from "@unkey/id"; -import { auth, t } from "../../trpc"; -export const createOverride = t.procedure - .use(auth) +export const createOverride = rateLimitedProcedure(ratelimit.create) .input( z.object({ namespaceId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts b/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts index 8fe135ce42..8c939c0349 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const deleteNamespace = t.procedure - .use(auth) +export const deleteNamespace = rateLimitedProcedure(ratelimit.delete) .input( z.object({ namespaceId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts b/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts index 15aeb8a83f..1698fdc2a1 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const deleteOverride = t.procedure - .use(auth) +export const deleteOverride = rateLimitedProcedure(ratelimit.create) .input( z.object({ id: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts b/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts index 6573fdad63..703a090850 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const updateNamespaceName = t.procedure - .use(auth) +export const updateNamespaceName = rateLimitedProcedure(ratelimit.update) .input( z.object({ name: z.string().min(3, "namespace names must contain at least 3 characters"), diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts b/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts index 03cc5b8cb5..c2f3f23cd8 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts @@ -3,10 +3,9 @@ import { z } from "zod"; import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; -import { auth, t } from "../../trpc"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; -export const updateOverride = t.procedure - .use(auth) +export const updateOverride = rateLimitedProcedure(ratelimit.update) .input( z.object({ id: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac.ts b/apps/dashboard/lib/trpc/routers/rbac.ts index e343031476..6e6b1980c7 100644 --- a/apps/dashboard/lib/trpc/routers/rbac.ts +++ b/apps/dashboard/lib/trpc/routers/rbac.ts @@ -1,11 +1,13 @@ import { type Permission, and, db, eq, schema } from "@/lib/db"; + import { type UnkeyAuditLog, ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { unkeyPermissionValidation } from "@unkey/rbac"; import { z } from "zod"; import type { Context } from "../context"; -import { auth, t } from "../trpc"; +import { t } from "../trpc"; const nameSchema = z .string() @@ -16,8 +18,7 @@ const nameSchema = z }); export const rbacRouter = t.router({ - addPermissionToRootKey: t.procedure - .use(auth) + addPermissionToRootKey: rateLimitedProcedure(ratelimit.update) .input( z.object({ rootKeyId: z.string(), @@ -75,8 +76,7 @@ export const rbacRouter = t.router({ .onDuplicateKeyUpdate({ set: { permissionId: permissions[0].id } }); await ingestAuditLogs(auditLogs); }), - removePermissionFromRootKey: t.procedure - .use(auth) + removePermissionFromRootKey: rateLimitedProcedure(ratelimit.update) .input( z.object({ rootKeyId: z.string(), @@ -133,8 +133,7 @@ export const rbacRouter = t.router({ ), ); }), - connectPermissionToRole: t.procedure - .use(auth) + connectPermissionToRole: rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), @@ -187,8 +186,7 @@ export const rbacRouter = t.router({ set: { ...tuple, updatedAt: new Date() }, }); }), - disconnectPermissionToRole: t.procedure - .use(auth) + disconnectPermissionToRole: rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), @@ -216,8 +214,7 @@ export const rbacRouter = t.router({ ), ); }), - connectRoleToKey: t.procedure - .use(auth) + connectRoleToKey: rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), @@ -270,8 +267,7 @@ export const rbacRouter = t.router({ set: { ...tuple, updatedAt: new Date() }, }); }), - disconnectRoleFromKey: t.procedure - .use(auth) + disconnectRoleFromKey: rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), @@ -299,8 +295,7 @@ export const rbacRouter = t.router({ ), ); }), - createRole: t.procedure - .use(auth) + createRole: rateLimitedProcedure(ratelimit.create) .input( z.object({ name: nameSchema, @@ -382,8 +377,7 @@ export const rbacRouter = t.router({ } return { roleId }; }), - updateRole: t.procedure - .use(auth) + updateRole: rateLimitedProcedure(ratelimit.update) .input( z.object({ id: z.string(), @@ -416,8 +410,7 @@ export const rbacRouter = t.router({ } await db.update(schema.roles).set(input).where(eq(schema.roles.id, input.id)); }), - deleteRole: t.procedure - .use(auth) + deleteRole: rateLimitedProcedure(ratelimit.delete) .input( z.object({ roleId: z.string(), @@ -450,8 +443,7 @@ export const rbacRouter = t.router({ .delete(schema.roles) .where(and(eq(schema.roles.id, input.roleId), eq(schema.roles.workspaceId, workspace.id))); }), - createPermission: t.procedure - .use(auth) + createPermission: rateLimitedProcedure(ratelimit.create) .input( z.object({ name: nameSchema, @@ -500,8 +492,7 @@ export const rbacRouter = t.router({ return { permissionId }; }), - updatePermission: t.procedure - .use(auth) + updatePermission: rateLimitedProcedure(ratelimit.update) .input( z.object({ id: z.string(), @@ -541,8 +532,7 @@ export const rbacRouter = t.router({ }) .where(eq(schema.permissions.id, input.id)); }), - deletePermission: t.procedure - .use(auth) + deletePermission: rateLimitedProcedure(ratelimit.delete) .input( z.object({ permissionId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts b/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts index 2ff9505a4b..f08810b0fd 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts @@ -1,13 +1,12 @@ import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { unkeyPermissionValidation } from "@unkey/rbac"; import { z } from "zod"; -import { auth, t } from "../../trpc"; import { upsertPermissions } from "../rbac"; -export const addPermissionToRootKey = t.procedure - .use(auth) +export const addPermissionToRootKey = rateLimitedProcedure(ratelimit.create) .input( z.object({ rootKeyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/connectPermissionToRole.ts b/apps/dashboard/lib/trpc/routers/rbac/connectPermissionToRole.ts index 5aaee899c3..abad5c9dc4 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/connectPermissionToRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/connectPermissionToRole.ts @@ -1,10 +1,9 @@ import { db, schema } from "@/lib/db"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const connectPermissionToRole = t.procedure - .use(auth) +export const connectPermissionToRole = rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts b/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts index b73ad212cb..a7997ac333 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts @@ -1,11 +1,10 @@ import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const connectRoleToKey = t.procedure - .use(auth) +export const connectRoleToKey = rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts b/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts index 712296712f..809f35d96c 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts @@ -1,9 +1,9 @@ import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { z } from "zod"; -import { auth, t } from "../../trpc"; const nameSchema = z .string() @@ -13,8 +13,7 @@ const nameSchema = z "Must be at least 3 characters long and only contain alphanumeric, colons, periods, dashes and underscores", }); -export const createPermission = t.procedure - .use(auth) +export const createPermission = rateLimitedProcedure(ratelimit.create) .input( z.object({ name: nameSchema, diff --git a/apps/dashboard/lib/trpc/routers/rbac/createRole.ts b/apps/dashboard/lib/trpc/routers/rbac/createRole.ts index 58641c7413..e30504ea88 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/createRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/createRole.ts @@ -1,9 +1,9 @@ import { db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { z } from "zod"; -import { auth, t } from "../../trpc"; const nameSchema = z .string() @@ -13,8 +13,7 @@ const nameSchema = z "Must be at least 3 characters long and only contain alphanumeric, colons, periods, dashes and underscores", }); -export const createRole = t.procedure - .use(auth) +export const createRole = rateLimitedProcedure(ratelimit.create) .input( z.object({ name: nameSchema, diff --git a/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts b/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts index 3d5630cd96..b3293c7d3b 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts @@ -1,11 +1,10 @@ import { and, db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const deletePermission = t.procedure - .use(auth) +export const deletePermission = rateLimitedProcedure(ratelimit.delete) .input( z.object({ permissionId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts b/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts index 76f6830768..ec40236405 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts @@ -1,11 +1,10 @@ import { and, db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const deleteRole = t.procedure - .use(auth) +export const deleteRole = rateLimitedProcedure(ratelimit.delete) .input( z.object({ roleId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts b/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts index d9e1156adf..2596111431 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts @@ -1,11 +1,10 @@ import { and, db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const disconnectPermissionFromRole = t.procedure - .use(auth) +export const disconnectPermissionFromRole = rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts b/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts index 36ec640554..1d27092af6 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts @@ -1,11 +1,10 @@ import { and, db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const disconnectRoleFromKey = t.procedure - .use(auth) +export const disconnectRoleFromKey = rateLimitedProcedure(ratelimit.update) .input( z.object({ roleId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts b/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts index 467ddc6736..6628d1daff 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts @@ -1,11 +1,10 @@ import { and, db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const removePermissionFromRootKey = t.procedure - .use(auth) +export const removePermissionFromRootKey = rateLimitedProcedure(ratelimit.update) .input( z.object({ rootKeyId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts b/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts index 79c8077490..db19d599d6 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts @@ -1,8 +1,8 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; const nameSchema = z .string() @@ -12,8 +12,7 @@ const nameSchema = z "Must be at least 3 characters long and only contain alphanumeric, colons, periods, dashes and underscores", }); -export const updatePermission = t.procedure - .use(auth) +export const updatePermission = rateLimitedProcedure(ratelimit.update) .input( z.object({ id: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts b/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts index 95fb7ac02f..89fc880140 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts @@ -1,8 +1,8 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; const nameSchema = z .string() @@ -12,8 +12,7 @@ const nameSchema = z "Must be at least 3 characters long and only contain alphanumeric, colons, periods, dashes and underscores", }); -export const updateRole = t.procedure - .use(auth) +export const updateRole = rateLimitedProcedure(ratelimit.update) .input( z.object({ id: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/secrets/create.ts b/apps/dashboard/lib/trpc/routers/secrets/create.ts index b818e319b3..750fd1fc1f 100644 --- a/apps/dashboard/lib/trpc/routers/secrets/create.ts +++ b/apps/dashboard/lib/trpc/routers/secrets/create.ts @@ -1,15 +1,14 @@ import { db, schema } from "@/lib/db"; import { env } from "@/lib/env"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { DatabaseError } from "@planetscale/database"; import { TRPCError } from "@trpc/server"; import { AesGCM } from "@unkey/encryption"; import { newId } from "@unkey/id"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const createSecret = t.procedure - .use(auth) +export const createSecret = rateLimitedProcedure(ratelimit.create) .input( z.object({ name: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/secrets/decrypt.ts b/apps/dashboard/lib/trpc/routers/secrets/decrypt.ts index 90f726cec6..d50861674d 100644 --- a/apps/dashboard/lib/trpc/routers/secrets/decrypt.ts +++ b/apps/dashboard/lib/trpc/routers/secrets/decrypt.ts @@ -1,11 +1,10 @@ import { db } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const decryptSecret = t.procedure - .use(auth) +export const decryptSecret = rateLimitedProcedure(ratelimit.update) .input( z.object({ secretId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/secrets/update.ts b/apps/dashboard/lib/trpc/routers/secrets/update.ts index d0bf065a63..f93d89993b 100644 --- a/apps/dashboard/lib/trpc/routers/secrets/update.ts +++ b/apps/dashboard/lib/trpc/routers/secrets/update.ts @@ -1,12 +1,11 @@ import { type Secret, db, eq, schema } from "@/lib/db"; import { env } from "@/lib/env"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const updateSecret = t.procedure - .use(auth) +export const updateSecret = rateLimitedProcedure(ratelimit.update) .input( z.object({ secretId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/webhook/create.ts b/apps/dashboard/lib/trpc/routers/webhook/create.ts index 97a5569a05..50b59f7578 100644 --- a/apps/dashboard/lib/trpc/routers/webhook/create.ts +++ b/apps/dashboard/lib/trpc/routers/webhook/create.ts @@ -1,16 +1,15 @@ import { db, schema } from "@/lib/db"; import { env } from "@/lib/env"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { AesGCM } from "@unkey/encryption"; import { sha256 } from "@unkey/hash"; import { newId } from "@unkey/id"; import { KeyV1, newKey } from "@unkey/keys"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const createWebhook = t.procedure - .use(auth) +export const createWebhook = rateLimitedProcedure(ratelimit.create) .input( z.object({ destination: z.string().url(), diff --git a/apps/dashboard/lib/trpc/routers/webhook/delete.ts b/apps/dashboard/lib/trpc/routers/webhook/delete.ts index 6bb16353c0..3f9c303d43 100644 --- a/apps/dashboard/lib/trpc/routers/webhook/delete.ts +++ b/apps/dashboard/lib/trpc/routers/webhook/delete.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const deleteWebhook = t.procedure - .use(auth) +export const deleteWebhook = rateLimitedProcedure(ratelimit.delete) .input( z.object({ webhookId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/webhook/toggle.ts b/apps/dashboard/lib/trpc/routers/webhook/toggle.ts index e17eedf0df..164bb288a4 100644 --- a/apps/dashboard/lib/trpc/routers/webhook/toggle.ts +++ b/apps/dashboard/lib/trpc/routers/webhook/toggle.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const toggleWebhook = t.procedure - .use(auth) +export const toggleWebhook = rateLimitedProcedure(ratelimit.update) .input( z.object({ webhookId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/workspace/changeName.ts b/apps/dashboard/lib/trpc/routers/workspace/changeName.ts index 2b2806f2d7..577762c253 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/changeName.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/changeName.ts @@ -1,12 +1,11 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { clerkClient } from "@clerk/nextjs"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const changeWorkspaceName = t.procedure - .use(auth) +export const changeWorkspaceName = rateLimitedProcedure(ratelimit.update) .input( z.object({ name: z.string().min(3, "workspace names must contain at least 3 characters"), diff --git a/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts b/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts index 2ecc60250d..2f6303e468 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts @@ -1,14 +1,13 @@ import { db, eq, schema } from "@/lib/db"; import { stripeEnv } from "@/lib/env"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { defaultProSubscriptions } from "@unkey/billing"; import Stripe from "stripe"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const changeWorkspacePlan = t.procedure - .use(auth) +export const changeWorkspacePlan = rateLimitedProcedure(ratelimit.update) .input( z.object({ workspaceId: z.string(), diff --git a/apps/dashboard/lib/trpc/routers/workspace/create.ts b/apps/dashboard/lib/trpc/routers/workspace/create.ts index 741a402e6f..f12562fede 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/create.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/create.ts @@ -1,14 +1,13 @@ import { type Workspace, db, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { clerkClient } from "@clerk/nextjs"; import { TRPCError } from "@trpc/server"; import { defaultProSubscriptions } from "@unkey/billing"; import { newId } from "@unkey/id"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const createWorkspace = t.procedure - .use(auth) +export const createWorkspace = rateLimitedProcedure(ratelimit.create) .input( z.object({ name: z.string().min(1).max(50), diff --git a/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts b/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts index 19296d7d29..7ffa2b6ae1 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts @@ -1,11 +1,10 @@ import { db, eq, schema } from "@/lib/db"; import { ingestAuditLogs } from "@/lib/tinybird"; +import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; -import { auth, t } from "../../trpc"; -export const optWorkspaceIntoBeta = t.procedure - .use(auth) +export const optWorkspaceIntoBeta = rateLimitedProcedure(ratelimit.update) .input( z.object({ feature: z.enum(["rbac", "ratelimit", "identities"]), diff --git a/apps/dashboard/lib/trpc/trpc.ts b/apps/dashboard/lib/trpc/trpc.ts index 33a4eefac9..2191cdd76e 100644 --- a/apps/dashboard/lib/trpc/trpc.ts +++ b/apps/dashboard/lib/trpc/trpc.ts @@ -1,6 +1,8 @@ import { TRPCError, initTRPC } from "@trpc/server"; import superjson from "superjson"; +import { Ratelimit } from "@unkey/ratelimit"; +import { env } from "../env"; import type { Context } from "./context"; export const t = initTRPC.context().create({ transformer: superjson }); @@ -17,3 +19,5 @@ export const auth = t.middleware(({ next, ctx }) => { }, }); }); + +export const protectedProcedure = t.procedure.use(auth);