API updates
This commit is contained in:
parent
1d43aae7b1
commit
7563622d8b
4 changed files with 57 additions and 20 deletions
|
@ -2,6 +2,7 @@ import { roomRouter } from "~/server/api/routers/room";
|
|||
import { createTRPCRouter } from "~/server/api/trpc";
|
||||
import { voteRouter } from "./routers/vote";
|
||||
import { restRouter } from "./routers/rest";
|
||||
import { webhookRouter } from "./routers/webhook";
|
||||
|
||||
/**
|
||||
* This is the primary router for your server.
|
||||
|
@ -12,6 +13,7 @@ export const appRouter = createTRPCRouter({
|
|||
room: roomRouter,
|
||||
vote: voteRouter,
|
||||
rest: restRouter,
|
||||
webhook: webhookRouter,
|
||||
});
|
||||
|
||||
// export type definition of API
|
||||
|
|
|
@ -1,27 +1,11 @@
|
|||
import { validateApiKey } from "~/server/unkey";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { fetchCache, setCache } from "~/server/redis";
|
||||
import { sql } from "drizzle-orm";
|
||||
import { rooms, votes } from "~/server/schema";
|
||||
|
||||
export const restRouter = createTRPCRouter({
|
||||
dbWarmer: publicProcedure
|
||||
.meta({ openapi: { method: "POST", path: "/rest/dbwarmer" } })
|
||||
.input(z.object({ key: z.string() }))
|
||||
.output(z.string())
|
||||
.query(async ({ ctx, input }) => {
|
||||
const isValidKey = await validateApiKey(input.key);
|
||||
if (isValidKey) {
|
||||
await ctx.db.query.votes.findMany();
|
||||
return "Toasted the DB";
|
||||
} else {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
}
|
||||
}),
|
||||
|
||||
voteCount: publicProcedure
|
||||
.meta({ openapi: { method: "GET", path: "/rest/votes/count" } })
|
||||
.input(z.void())
|
||||
|
|
24
src/server/api/routers/webhook.ts
Normal file
24
src/server/api/routers/webhook.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { createTRPCRouter, keyProtectedProcedure } from "~/server/api/trpc";
|
||||
|
||||
export const webhookRouter = createTRPCRouter({
|
||||
onUserDelete: keyProtectedProcedure
|
||||
.meta({ openapi: { method: "POST", path: "/webhook/user/delete" } })
|
||||
.input(
|
||||
z.object({
|
||||
data: z.object({
|
||||
deleted: z.boolean(),
|
||||
id: z.string(),
|
||||
object: z.string(),
|
||||
}),
|
||||
object: z.string(),
|
||||
type: z.string(),
|
||||
})
|
||||
)
|
||||
.output(z.string())
|
||||
.query(({ input }) => {
|
||||
console.log(input.data.deleted);
|
||||
return `Deleted: ${input.data.deleted}`;
|
||||
}),
|
||||
});
|
|
@ -25,8 +25,9 @@ import type {
|
|||
|
||||
import { db } from "../db";
|
||||
|
||||
interface AuthContext {
|
||||
interface ContextType {
|
||||
auth: SignedInAuthObject | SignedOutAuthObject;
|
||||
key: string | null;
|
||||
}
|
||||
/**
|
||||
* This helper generates the "internals" for a tRPC context. If you need to use
|
||||
|
@ -37,8 +38,9 @@ interface AuthContext {
|
|||
* - trpc's `createSSGHelpers` where we don't have req/res
|
||||
* @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts
|
||||
*/
|
||||
const createInnerTRPCContext = ({ auth }: AuthContext) => {
|
||||
const createInnerTRPCContext = ({ auth, key }: ContextType) => {
|
||||
return {
|
||||
key,
|
||||
auth,
|
||||
db,
|
||||
};
|
||||
|
@ -49,8 +51,19 @@ const createInnerTRPCContext = ({ auth }: AuthContext) => {
|
|||
* process every request that goes through your tRPC endpoint
|
||||
* @link https://trpc.io/docs/context
|
||||
*/
|
||||
export const createTRPCContext = (opts: CreateNextContextOptions) => {
|
||||
return createInnerTRPCContext({ auth: getAuth(opts.req) });
|
||||
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
|
||||
let keyValue: string | null = null;
|
||||
|
||||
if (opts.req.headers.authorization) {
|
||||
const key = opts.req.headers.authorization.split("Bearer ").at(1);
|
||||
if (key) {
|
||||
const isValidKey = await validateApiKey(key);
|
||||
if (isValidKey) {
|
||||
keyValue = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
return createInnerTRPCContext({ auth: getAuth(opts.req), key: keyValue });
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -62,6 +75,7 @@ export const createTRPCContext = (opts: CreateNextContextOptions) => {
|
|||
import { initTRPC, TRPCError } from "@trpc/server";
|
||||
import superjson from "superjson";
|
||||
import type { OpenApiMeta } from "trpc-openapi";
|
||||
import { validateApiKey } from "../unkey";
|
||||
|
||||
const t = initTRPC
|
||||
.context<typeof createTRPCContext>()
|
||||
|
@ -85,6 +99,18 @@ const isAuthed = t.middleware(({ next, ctx }) => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
const isKeyAuthed = t.middleware(({ next, ctx }) => {
|
||||
if (!ctx.key) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
}
|
||||
|
||||
return next({
|
||||
ctx: {
|
||||
key: ctx.key,
|
||||
},
|
||||
});
|
||||
});
|
||||
/**
|
||||
* 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)
|
||||
*
|
||||
|
@ -107,3 +133,4 @@ export const createTRPCRouter = t.router;
|
|||
*/
|
||||
export const publicProcedure = t.procedure;
|
||||
export const protectedProcedure = t.procedure.use(isAuthed);
|
||||
export const keyProtectedProcedure = t.procedure.use(isKeyAuthed);
|
||||
|
|
Loading…
Add table
Reference in a new issue