This commit is contained in:
Atridad Lahiji 2023-08-06 14:09:03 -06:00 committed by atridadl
parent ec00693e34
commit ef8f82b1a0
No known key found for this signature in database
11 changed files with 77 additions and 37 deletions

View file

@ -27,6 +27,9 @@ NEXT_PUBLIC_ABLY_PUBLIC_KEY=""
# Email
RESEND_API_KEY=""
# Unkey
UNKEY_ROOT_KEY=""
# Misc
APP_ENV=""
NEXT_PUBLIC_APP_ENV=""

View file

@ -21,6 +21,7 @@
"@trpc/next": "10.37.1",
"@trpc/react-query": "10.37.1",
"@trpc/server": "10.37.1",
"@unkey/api": "^0.5.0",
"@upstash/ratelimit": "^0.4.3",
"@upstash/redis": "^1.22.0",
"ably": "^1.2.42",

7
pnpm-lock.yaml generated
View file

@ -32,6 +32,9 @@ dependencies:
'@trpc/server':
specifier: 10.37.1
version: 10.37.1
'@unkey/api':
specifier: ^0.5.0
version: 0.5.0
'@upstash/ratelimit':
specifier: ^0.4.3
version: 0.4.3
@ -1359,6 +1362,10 @@ packages:
eslint-visitor-keys: 3.4.2
dev: true
/@unkey/api@0.5.0:
resolution: {integrity: sha512-C3q2ITvBR5jpK68KNAhhqcR+BzRhXW9ppubdrbaXawEnwxE+F+I2qMU+KqkCM1MbP+ZUv4/E1gX8cobH4X0sWg==}
dev: false
/@upstash/core-analytics@0.0.6:
resolution: {integrity: sha512-cpPSR0XJAJs4Ddz9nq3tINlPS5aLfWVCqhhtHnXt4p7qr5+/Znlt1Es736poB/9rnl1hAHrOsOvVj46NEXcVqA==}
engines: {node: '>=16.0.0'}

View file

@ -30,6 +30,7 @@ const server = z.object({
ABLY_PRIVATE_KEY: z.string(),
APP_ENV: z.string(),
RESEND_API_KEY: z.string(),
UNKEY_ROOT_KEY: z.string(),
});
/**
@ -66,6 +67,7 @@ const processEnv = {
APP_ENV: process.env.APP_ENV,
NEXT_PUBLIC_APP_ENV: process.env.NEXT_PUBLIC_APP_ENV,
RESEND_API_KEY: process.env.RESEND_API_KEY,
UNKEY_ROOT_KEY: process.env.UNKEY_ROOT_KEY,
};
// Don't touch the part below

View file

@ -1,13 +0,0 @@
import { prisma } from "~/server/db";
import type { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
console.log("Cron Request: ", req);
// the most useless call... nothing exists here
await prisma.verificationToken.findMany();
res.status(200);
}

View file

@ -3,6 +3,7 @@ import { createTRPCRouter } from "~/server/api/trpc";
import { sessionRouter } from "./routers/session";
import { userRouter } from "./routers/user";
import { voteRouter } from "./routers/vote";
import { hookRouter } from "./routers/hook";
/**
* This is the primary router for your server.
@ -14,6 +15,7 @@ export const appRouter = createTRPCRouter({
vote: voteRouter,
user: userRouter,
session: sessionRouter,
hook: hookRouter,
});
// export type definition of API

View file

@ -0,0 +1,21 @@
import { validateApiKey } from "~/server/unkey";
import { z } from "zod";
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
import { TRPCError } from "@trpc/server";
export const hookRouter = createTRPCRouter({
dbWarmer: publicProcedure
.meta({ openapi: { method: "GET", path: "/rest/test" } })
.input(z.object({ key: z.string() }))
.output(z.string())
.query(async ({ ctx, input }) => {
const isValidKey = await validateApiKey(input.key);
if (isValidKey) {
await ctx.prisma.verificationToken.findMany();
return "Toasted the DB";
} else {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
}),
});

View file

@ -10,23 +10,19 @@ import {
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
export const voteRouter = createTRPCRouter({
countAll: adminProcedure
.input(z.void())
.output(z.number())
.meta({ openapi: { method: "GET", path: "/votes/count" } })
.query(async ({ ctx }) => {
const cachedResult = await fetchCache<number>(`kv_votecount_admin`);
countAll: adminProcedure.query(async ({ ctx }) => {
const cachedResult = await fetchCache<number>(`kv_votecount_admin`);
if (cachedResult) {
return cachedResult;
} else {
const votesCount = await ctx.prisma.vote.count();
if (cachedResult) {
return cachedResult;
} else {
const votesCount = await ctx.prisma.vote.count();
await setCache(`kv_votecount_admin`, votesCount);
await setCache(`kv_votecount_admin`, votesCount);
return votesCount;
}
}),
return votesCount;
}
}),
getAllByRoomId: protectedProcedure
.input(z.object({ roomId: z.string() }))
.query(async ({ ctx, input }) => {

View file

@ -107,7 +107,7 @@ 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(async ({ ctx, next }) => {
const enforceAuthSession = t.middleware(async ({ ctx, next }) => {
// Auth
if (!ctx.session || !ctx.session.user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
@ -146,6 +146,20 @@ const enforceAdminRole = t.middleware(async ({ ctx, next }) => {
});
});
// const enforceApiToken = t.middleware(async ({ ctx, next, path }) => {
// const res = await unkey.keys.verify({
// key: ""
// })
// if (!ctx.session || !ctx.session.user || !ctx.session?.user.isAdmin)
// throw new TRPCError({ code: "UNAUTHORIZED" });
// return next({
// ctx: {
// session: { ...ctx.session, user: ctx.session.user },
// },
// });
// });
/**
* Protected (authenticated) procedure
*
@ -154,6 +168,6 @@ const enforceAdminRole = t.middleware(async ({ ctx, next }) => {
*
* @see https://trpc.io/docs/procedures
*/
export const protectedProcedure = t.procedure.use(enforceUserIsAuthed);
export const protectedProcedure = t.procedure.use(enforceAuthSession);
export const adminProcedure = t.procedure.use(enforceAdminRole);

15
src/server/unkey.ts Normal file
View file

@ -0,0 +1,15 @@
import { Unkey } from "@unkey/api";
import { env } from "~/env.mjs";
export const unkey = new Unkey({ token: env.UNKEY_ROOT_KEY });
export const validateApiKey = async (key: string) => {
try {
const res = await unkey.keys.verify({
key,
});
return res.valid;
} catch {
return false;
}
};

View file

@ -1,8 +0,0 @@
{
"crons": [
{
"path": "/api/cron/dbWarmer",
"schedule": "0 0 */6 * *"
}
]
}