Lets simplify tRPC
This commit is contained in:
parent
78aa16cded
commit
96565d573b
5 changed files with 32 additions and 44 deletions
|
@ -1,16 +1,16 @@
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { publishToChannel } from "~/server/ably";
|
import { publishToChannel } from "~/server/ably";
|
||||||
import {
|
import {
|
||||||
adminRateLimitedProcedure,
|
|
||||||
createTRPCRouter,
|
createTRPCRouter,
|
||||||
protectedRateLimitedProcedure,
|
protectedProcedure,
|
||||||
|
adminProcedure,
|
||||||
} from "~/server/api/trpc";
|
} from "~/server/api/trpc";
|
||||||
|
|
||||||
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
|
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
|
||||||
|
|
||||||
export const roomRouter = createTRPCRouter({
|
export const roomRouter = createTRPCRouter({
|
||||||
// Create
|
// Create
|
||||||
create: protectedRateLimitedProcedure
|
create: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
|
@ -46,7 +46,7 @@ export const roomRouter = createTRPCRouter({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Get One
|
// Get One
|
||||||
get: protectedRateLimitedProcedure
|
get: protectedProcedure
|
||||||
.input(z.object({ id: z.string() }))
|
.input(z.object({ id: z.string() }))
|
||||||
.query(({ ctx, input }) => {
|
.query(({ ctx, input }) => {
|
||||||
return ctx.prisma.room.findUnique({
|
return ctx.prisma.room.findUnique({
|
||||||
|
@ -67,7 +67,7 @@ export const roomRouter = createTRPCRouter({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Get All
|
// Get All
|
||||||
getAll: protectedRateLimitedProcedure.query(async ({ ctx }) => {
|
getAll: protectedProcedure.query(async ({ ctx }) => {
|
||||||
const cachedResult = await fetchCache<
|
const cachedResult = await fetchCache<
|
||||||
{
|
{
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -96,7 +96,7 @@ export const roomRouter = createTRPCRouter({
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
countAll: adminRateLimitedProcedure.query(async ({ ctx }) => {
|
countAll: adminProcedure.query(async ({ ctx }) => {
|
||||||
const cachedResult = await fetchCache<number>(`kv_roomcount_admin`);
|
const cachedResult = await fetchCache<number>(`kv_roomcount_admin`);
|
||||||
|
|
||||||
if (cachedResult) {
|
if (cachedResult) {
|
||||||
|
@ -111,7 +111,7 @@ export const roomRouter = createTRPCRouter({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Update One
|
// Update One
|
||||||
set: protectedRateLimitedProcedure
|
set: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
|
@ -212,7 +212,7 @@ export const roomRouter = createTRPCRouter({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Delete One
|
// Delete One
|
||||||
delete: protectedRateLimitedProcedure
|
delete: protectedProcedure
|
||||||
.input(z.object({ id: z.string() }))
|
.input(z.object({ id: z.string() }))
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const deletedRoom = await ctx.prisma.room.delete({
|
const deletedRoom = await ctx.prisma.room.delete({
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { adminRateLimitedProcedure, createTRPCRouter } from "~/server/api/trpc";
|
import { adminProcedure, createTRPCRouter } from "~/server/api/trpc";
|
||||||
import { invalidateCache } from "~/server/redis";
|
import { invalidateCache } from "~/server/redis";
|
||||||
|
|
||||||
export const sessionRouter = createTRPCRouter({
|
export const sessionRouter = createTRPCRouter({
|
||||||
deleteAllByUserId: adminRateLimitedProcedure
|
deleteAllByUserId: adminProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
|
@ -22,7 +22,7 @@ export const sessionRouter = createTRPCRouter({
|
||||||
|
|
||||||
return !!sessions;
|
return !!sessions;
|
||||||
}),
|
}),
|
||||||
deleteAll: adminRateLimitedProcedure.mutation(async ({ ctx }) => {
|
deleteAll: adminProcedure.mutation(async ({ ctx }) => {
|
||||||
const sessions = await ctx.prisma.session.deleteMany();
|
const sessions = await ctx.prisma.session.deleteMany();
|
||||||
|
|
||||||
if (!!sessions) {
|
if (!!sessions) {
|
||||||
|
|
|
@ -4,9 +4,9 @@ import { z } from "zod";
|
||||||
import { Goodbye } from "~/components/templates/Goodbye";
|
import { Goodbye } from "~/components/templates/Goodbye";
|
||||||
import { env } from "~/env.mjs";
|
import { env } from "~/env.mjs";
|
||||||
import {
|
import {
|
||||||
adminRateLimitedProcedure,
|
adminProcedure,
|
||||||
createTRPCRouter,
|
createTRPCRouter,
|
||||||
protectedRateLimitedProcedure,
|
protectedProcedure,
|
||||||
} from "~/server/api/trpc";
|
} from "~/server/api/trpc";
|
||||||
|
|
||||||
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
|
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
|
||||||
|
@ -14,7 +14,7 @@ import { fetchCache, invalidateCache, setCache } from "~/server/redis";
|
||||||
const resend = new Resend(process.env.RESEND_API_KEY);
|
const resend = new Resend(process.env.RESEND_API_KEY);
|
||||||
|
|
||||||
export const userRouter = createTRPCRouter({
|
export const userRouter = createTRPCRouter({
|
||||||
countAll: adminRateLimitedProcedure.query(async ({ ctx }) => {
|
countAll: adminProcedure.query(async ({ ctx }) => {
|
||||||
const cachedResult = await fetchCache<number>(`kv_usercount_admin`);
|
const cachedResult = await fetchCache<number>(`kv_usercount_admin`);
|
||||||
|
|
||||||
if (cachedResult) {
|
if (cachedResult) {
|
||||||
|
@ -28,7 +28,7 @@ export const userRouter = createTRPCRouter({
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getProviders: protectedRateLimitedProcedure.query(async ({ ctx }) => {
|
getProviders: protectedProcedure.query(async ({ ctx }) => {
|
||||||
const providers = await ctx.prisma.user.findUnique({
|
const providers = await ctx.prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: ctx.session.user.id,
|
id: ctx.session.user.id,
|
||||||
|
@ -46,7 +46,7 @@ export const userRouter = createTRPCRouter({
|
||||||
return account.provider;
|
return account.provider;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
getAll: protectedRateLimitedProcedure.query(async ({ ctx }) => {
|
getAll: protectedProcedure.query(async ({ ctx }) => {
|
||||||
const cachedResult = await fetchCache<
|
const cachedResult = await fetchCache<
|
||||||
{
|
{
|
||||||
accounts: {
|
accounts: {
|
||||||
|
@ -98,7 +98,7 @@ export const userRouter = createTRPCRouter({
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
delete: protectedRateLimitedProcedure
|
delete: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z
|
z
|
||||||
.object({
|
.object({
|
||||||
|
@ -136,7 +136,7 @@ export const userRouter = createTRPCRouter({
|
||||||
|
|
||||||
return !!user;
|
return !!user;
|
||||||
}),
|
}),
|
||||||
save: protectedRateLimitedProcedure
|
save: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
|
@ -154,7 +154,7 @@ export const userRouter = createTRPCRouter({
|
||||||
|
|
||||||
return !!user;
|
return !!user;
|
||||||
}),
|
}),
|
||||||
setAdmin: adminRateLimitedProcedure
|
setAdmin: adminProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
|
@ -176,7 +176,7 @@ export const userRouter = createTRPCRouter({
|
||||||
return !!user;
|
return !!user;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setVIP: adminRateLimitedProcedure
|
setVIP: adminProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
|
|
|
@ -3,14 +3,14 @@ import { publishToChannel } from "~/server/ably";
|
||||||
|
|
||||||
import type { Room } from "@prisma/client";
|
import type { Room } from "@prisma/client";
|
||||||
import {
|
import {
|
||||||
adminRateLimitedProcedure,
|
adminProcedure,
|
||||||
createTRPCRouter,
|
createTRPCRouter,
|
||||||
protectedRateLimitedProcedure,
|
protectedProcedure,
|
||||||
} from "~/server/api/trpc";
|
} from "~/server/api/trpc";
|
||||||
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
|
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
|
||||||
|
|
||||||
export const voteRouter = createTRPCRouter({
|
export const voteRouter = createTRPCRouter({
|
||||||
countAll: adminRateLimitedProcedure
|
countAll: adminProcedure
|
||||||
.input(z.void())
|
.input(z.void())
|
||||||
.output(z.number())
|
.output(z.number())
|
||||||
.meta({ openapi: { method: "GET", path: "/votes/count" } })
|
.meta({ openapi: { method: "GET", path: "/votes/count" } })
|
||||||
|
@ -27,7 +27,7 @@ export const voteRouter = createTRPCRouter({
|
||||||
return votesCount;
|
return votesCount;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
getAllByRoomId: protectedRateLimitedProcedure
|
getAllByRoomId: protectedProcedure
|
||||||
.input(z.object({ roomId: z.string() }))
|
.input(z.object({ roomId: z.string() }))
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const cachedResult = await fetchCache<
|
const cachedResult = await fetchCache<
|
||||||
|
@ -71,7 +71,7 @@ export const voteRouter = createTRPCRouter({
|
||||||
return votesByRoomId;
|
return votesByRoomId;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
set: protectedRateLimitedProcedure
|
set: protectedProcedure
|
||||||
.input(z.object({ value: z.string(), roomId: z.string() }))
|
.input(z.object({ value: z.string(), roomId: z.string() }))
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const vote = await ctx.prisma.vote.upsert({
|
const vote = await ctx.prisma.vote.upsert({
|
||||||
|
|
|
@ -113,14 +113,6 @@ const enforceUserIsAuthed = t.middleware(async ({ ctx, next }) => {
|
||||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||||
}
|
}
|
||||||
|
|
||||||
return next({
|
|
||||||
ctx: {
|
|
||||||
session: { ...ctx.session, user: ctx.session.user },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const enforceRateLimit = t.middleware(async ({ ctx, next }) => {
|
|
||||||
const rateLimit = new Ratelimit({
|
const rateLimit = new Ratelimit({
|
||||||
redis: Redis.fromEnv(),
|
redis: Redis.fromEnv(),
|
||||||
limiter: Ratelimit.slidingWindow(
|
limiter: Ratelimit.slidingWindow(
|
||||||
|
@ -129,15 +121,18 @@ const enforceRateLimit = t.middleware(async ({ ctx, next }) => {
|
||||||
),
|
),
|
||||||
analytics: true,
|
analytics: true,
|
||||||
});
|
});
|
||||||
console.log(`${env.APP_ENV}_${ctx.session?.user.id || ctx.ip}`);
|
|
||||||
console.log(ctx.ip);
|
|
||||||
const { success } = await rateLimit.limit(
|
const { success } = await rateLimit.limit(
|
||||||
`${env.APP_ENV}_${ctx.session?.user.id || ctx.ip}`
|
`${env.APP_ENV}_${ctx.session?.user.id}`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!success) throw new TRPCError({ code: "TOO_MANY_REQUESTS" });
|
if (!success) throw new TRPCError({ code: "TOO_MANY_REQUESTS" });
|
||||||
|
|
||||||
return next();
|
return next({
|
||||||
|
ctx: {
|
||||||
|
session: { ...ctx.session, user: ctx.session.user },
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const enforceAdminRole = t.middleware(async ({ ctx, next }) => {
|
const enforceAdminRole = t.middleware(async ({ ctx, next }) => {
|
||||||
|
@ -161,11 +156,4 @@ const enforceAdminRole = t.middleware(async ({ ctx, next }) => {
|
||||||
*/
|
*/
|
||||||
export const protectedProcedure = t.procedure.use(enforceUserIsAuthed);
|
export const protectedProcedure = t.procedure.use(enforceUserIsAuthed);
|
||||||
|
|
||||||
export const protectedRateLimitedProcedure =
|
|
||||||
protectedProcedure.use(enforceRateLimit);
|
|
||||||
|
|
||||||
export const publicRateLimitedProcedure = publicProcedure.use(enforceRateLimit);
|
|
||||||
|
|
||||||
export const adminProcedure = t.procedure.use(enforceAdminRole);
|
export const adminProcedure = t.procedure.use(enforceAdminRole);
|
||||||
|
|
||||||
export const adminRateLimitedProcedure = adminProcedure.use(enforceAdminRole);
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue