+ {isSignedIn && !!roomFromDb && roomFromDb.userId === user.id && (
+ <>
+
+
+
Room Settings
-
+
-
{
- setRoomScale(event.target.value);
- }}
- />
+
{
+ setRoomScale(event.target.value);
+ }}
+ />
-
+
-
{
- setStoryNameText(event.target.value);
- }}
- />
+
{
+ setStoryNameText(event.target.value);
+ }}
+ />
-
-
-
-
-
-
-
-
-
- {votesFromDb &&
- (roomFromDb.logs.length > 0 ||
- votesFromDb.length > 0) && (
-
-
-
+
+
+
+
+
+
+
+
+ {votesFromDb &&
+ (roomFromDb.logs.length > 0 || votesFromDb.length > 0) && (
+
+
+
+ )}
- >
- )}
+
+ >
+ )}
);
// Room does not exist
diff --git a/src/pages/sign-in/[[...index]].tsx b/src/pages/sign-in/[[...index]].tsx
new file mode 100644
index 0000000..f84cb7f
--- /dev/null
+++ b/src/pages/sign-in/[[...index]].tsx
@@ -0,0 +1,17 @@
+import { SignIn } from "@clerk/nextjs";
+
+const SignInPage = () => (
+
+
+
+);
+
+export default SignInPage;
+
+const styles = {
+ width: "100vw",
+ height: "100vh",
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+};
diff --git a/src/pages/sign-up/[[...index]].tsx b/src/pages/sign-up/[[...index]].tsx
new file mode 100644
index 0000000..ce6c5ea
--- /dev/null
+++ b/src/pages/sign-up/[[...index]].tsx
@@ -0,0 +1,17 @@
+import { SignUp } from "@clerk/nextjs";
+
+const SignUpPage = () => (
+
+
+
+);
+
+export default SignUpPage;
+
+const styles = {
+ width: "100vw",
+ height: "100vh",
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+};
diff --git a/src/server/api/root.ts b/src/server/api/root.ts
index 7d5426a..4acf4e6 100644
--- a/src/server/api/root.ts
+++ b/src/server/api/root.ts
@@ -1,7 +1,5 @@
import { roomRouter } from "~/server/api/routers/room";
import { createTRPCRouter } from "~/server/api/trpc";
-import { sessionRouter } from "./routers/session";
-import { userRouter } from "./routers/user";
import { voteRouter } from "./routers/vote";
import { restRouter } from "./routers/rest";
@@ -13,8 +11,6 @@ import { restRouter } from "./routers/rest";
export const appRouter = createTRPCRouter({
room: roomRouter,
vote: voteRouter,
- user: userRouter,
- session: sessionRouter,
rest: restRouter,
});
diff --git a/src/server/api/routers/rest.ts b/src/server/api/routers/rest.ts
index 3d6ff86..0ca0edf 100644
--- a/src/server/api/routers/rest.ts
+++ b/src/server/api/routers/rest.ts
@@ -13,7 +13,7 @@ export const restRouter = createTRPCRouter({
.query(async ({ ctx, input }) => {
const isValidKey = await validateApiKey(input.key);
if (isValidKey) {
- await ctx.prisma.verificationToken.findMany();
+ await ctx.prisma.vote.findMany();
return "Toasted the DB";
} else {
throw new TRPCError({ code: "UNAUTHORIZED" });
@@ -38,24 +38,6 @@ export const restRouter = createTRPCRouter({
}
}),
- userCount: publicProcedure
- .meta({ openapi: { method: "GET", path: "/rest/users/count" } })
- .input(z.void())
- .output(z.number())
- .query(async ({ ctx }) => {
- const cachedResult = await fetchCache
(`kv_usercount`);
-
- if (cachedResult) {
- return cachedResult;
- } else {
- const usersCount = await ctx.prisma.user.count();
-
- await setCache(`kv_usercount`, usersCount);
-
- return usersCount;
- }
- }),
-
roomCount: publicProcedure
.meta({ openapi: { method: "GET", path: "/rest/rooms/count" } })
.input(z.void())
diff --git a/src/server/api/routers/room.ts b/src/server/api/routers/room.ts
index 598b818..44d3189 100644
--- a/src/server/api/routers/room.ts
+++ b/src/server/api/routers/room.ts
@@ -14,38 +14,34 @@ export const roomRouter = createTRPCRouter({
})
)
.mutation(async ({ ctx, input }) => {
- if (ctx.session) {
- const room = await ctx.prisma.room.create({
- data: {
- userId: ctx.session.user.id,
- roomName: input.name,
- storyName: "First Story!",
- scale: "0.5,1,2,3,5,8",
- visible: false,
- },
- });
- if (room) {
- await invalidateCache(`kv_roomcount`);
- await invalidateCache(`kv_roomlist_${ctx.session.user.id}`);
+ const room = await ctx.prisma.room.create({
+ data: {
+ userId: ctx.auth.userId,
+ roomName: input.name,
+ storyName: "First Story!",
+ scale: "0.5,1,2,3,5,8",
+ visible: false,
+ },
+ });
+ if (room) {
+ await invalidateCache(`kv_roomcount`);
+ console.log("PUBLISHED TO ", `kv_roomlist_${ctx.auth.userId}`);
+ await invalidateCache(`kv_roomlist_${ctx.auth.userId}`);
- await publishToChannel(
- `${ctx.session.user.id}`,
- EventTypes.ROOM_LIST_UPDATE,
- JSON.stringify(room)
- );
+ await publishToChannel(
+ `${ctx.auth.userId}`,
+ EventTypes.ROOM_LIST_UPDATE,
+ JSON.stringify(room)
+ );
- await publishToChannel(
- `stats`,
- EventTypes.STATS_UPDATE,
- JSON.stringify(room)
- );
- }
- // happy path
- return !!room;
+ await publishToChannel(
+ `stats`,
+ EventTypes.STATS_UPDATE,
+ JSON.stringify(room)
+ );
}
-
- // clinically depressed path
- return false;
+ // happy path
+ return !!room;
}),
// Get One
@@ -64,7 +60,6 @@ export const roomRouter = createTRPCRouter({
storyName: true,
visible: true,
scale: true,
- owner: true,
},
});
}),
@@ -77,14 +72,14 @@ export const roomRouter = createTRPCRouter({
createdAt: Date;
roomName: string;
}[]
- >(`kv_roomlist_${ctx.session.user.id}`);
+ >(`kv_roomlist_${ctx.auth.userId}`);
if (cachedResult) {
return cachedResult;
} else {
const roomList = await ctx.prisma.room.findMany({
where: {
- userId: ctx.session.user.id,
+ userId: ctx.auth.userId,
},
select: {
id: true,
@@ -93,7 +88,7 @@ export const roomRouter = createTRPCRouter({
},
});
- await setCache(`kv_roomlist_${ctx.session.user.id}`, roomList);
+ await setCache(`kv_roomlist_${ctx.auth.userId}`, roomList);
return roomList;
}
@@ -124,11 +119,7 @@ export const roomRouter = createTRPCRouter({
scale: true,
votes: {
select: {
- owner: {
- select: {
- name: true,
- },
- },
+ userId: true,
value: true,
},
},
@@ -138,12 +129,12 @@ export const roomRouter = createTRPCRouter({
oldRoom &&
(await ctx.prisma.log.create({
data: {
- userId: ctx.session.user.id,
+ userId: ctx.auth.userId,
roomId: input.roomId,
scale: oldRoom.scale,
votes: oldRoom.votes.map((vote) => {
return {
- name: vote.owner.name,
+ name: vote.userId,
value: vote.value,
};
}),
@@ -168,7 +159,7 @@ export const roomRouter = createTRPCRouter({
},
data: {
storyName: input.name,
- userId: ctx.session.user.id,
+ userId: ctx.auth.userId,
visible: input.visible,
scale: [...new Set(input.scale.split(","))]
.filter((item) => item !== "")
@@ -182,11 +173,6 @@ export const roomRouter = createTRPCRouter({
scale: true,
votes: {
select: {
- owner: {
- select: {
- name: true,
- },
- },
value: true,
},
},
@@ -217,10 +203,10 @@ export const roomRouter = createTRPCRouter({
if (deletedRoom) {
await invalidateCache(`kv_roomcount`);
await invalidateCache(`kv_votecount`);
- await invalidateCache(`kv_roomlist_${ctx.session.user.id}`);
+ await invalidateCache(`kv_roomlist_${ctx.auth.userId}`);
await publishToChannel(
- `${ctx.session.user.id}`,
+ `${ctx.auth.userId}`,
EventTypes.ROOM_LIST_UPDATE,
JSON.stringify(deletedRoom)
);
diff --git a/src/server/api/routers/session.ts b/src/server/api/routers/session.ts
deleted file mode 100644
index 7db9918..0000000
--- a/src/server/api/routers/session.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { z } from "zod";
-import { adminProcedure, createTRPCRouter } from "~/server/api/trpc";
-import { invalidateCache } from "~/server/redis";
-
-export const sessionRouter = createTRPCRouter({
- deleteAllByUserId: adminProcedure
- .input(
- z.object({
- userId: z.string(),
- })
- )
- .mutation(async ({ ctx, input }) => {
- const sessions = await ctx.prisma.session.deleteMany({
- where: {
- userId: input.userId,
- },
- });
-
- if (!!sessions) {
- await invalidateCache(`kv_userlist_admin`);
- }
-
- return !!sessions;
- }),
- deleteAll: adminProcedure.mutation(async ({ ctx }) => {
- const sessions = await ctx.prisma.session.deleteMany();
-
- if (!!sessions) {
- await invalidateCache(`kv_userlist_admin`);
- }
-
- return !!sessions;
- }),
-});
diff --git a/src/server/api/routers/user.ts b/src/server/api/routers/user.ts
deleted file mode 100644
index 923d9eb..0000000
--- a/src/server/api/routers/user.ts
+++ /dev/null
@@ -1,194 +0,0 @@
-import type { User } from "@prisma/client";
-import { Resend } from "resend";
-import { z } from "zod";
-import { Goodbye } from "~/components/templates/Goodbye";
-import { env } from "~/env.mjs";
-import { publishToChannel } from "~/server/ably";
-import {
- adminProcedure,
- createTRPCRouter,
- protectedProcedure,
-} from "~/server/api/trpc";
-
-import { fetchCache, invalidateCache, setCache } from "~/server/redis";
-import { EventTypes } from "~/utils/types";
-
-const resend = new Resend(process.env.RESEND_API_KEY);
-
-export const userRouter = createTRPCRouter({
- getProviders: protectedProcedure.query(async ({ ctx }) => {
- const providers = await ctx.prisma.user.findUnique({
- where: {
- id: ctx.session.user.id,
- },
- select: {
- accounts: {
- select: {
- provider: true,
- },
- },
- },
- });
-
- return providers?.accounts.map((account) => {
- return account.provider;
- });
- }),
- getAll: protectedProcedure.query(async ({ ctx }) => {
- const cachedResult = await fetchCache<
- {
- accounts: {
- provider: string;
- }[];
- sessions: {
- id: string;
- }[];
- id: string;
- createdAt: Date;
- isAdmin: boolean;
- isVIP: boolean;
- name: string | null;
- email: string | null;
- }[]
- >(`kv_userlist_admin`);
-
- if (cachedResult) {
- return cachedResult.map((user) => {
- return {
- ...user,
- createdAt: new Date(user.createdAt),
- };
- });
- } else {
- const users = await ctx.prisma.user.findMany({
- select: {
- id: true,
- name: true,
- isAdmin: true,
- isVIP: true,
- createdAt: true,
- email: true,
- sessions: {
- select: {
- id: true,
- },
- },
- accounts: {
- select: {
- provider: true,
- },
- },
- },
- });
-
- await setCache(`${env.APP_ENV}_kv_userlist_admin`, users);
-
- return users;
- }
- }),
- delete: protectedProcedure
- .input(
- z
- .object({
- userId: z.string(),
- })
- .optional()
- )
- .mutation(async ({ ctx, input }) => {
- let user: User;
- if (input?.userId && ctx.session.user.isAdmin) {
- user = await ctx.prisma.user.delete({
- where: {
- id: input.userId,
- },
- });
- } else {
- user = await ctx.prisma.user.delete({
- where: {
- id: ctx.session.user.id,
- },
- });
- }
-
- if (!!user && user.name && user.email) {
- await resend.emails.send({
- from: "Sprint Padawan ",
- to: user.email,
- subject: "Sorry to see you go... 😭",
- react: Goodbye({ name: user.name }),
- });
-
- await invalidateCache(`kv_usercount`);
- await invalidateCache(`kv_userlist_admin`);
-
- await publishToChannel(
- `stats`,
- EventTypes.STATS_UPDATE,
- JSON.stringify(user)
- );
- }
-
- return !!user;
- }),
- save: protectedProcedure
- .input(
- z.object({
- name: z.string(),
- })
- )
- .mutation(async ({ ctx, input }) => {
- const user = await ctx.prisma.user.update({
- where: {
- id: ctx.session.user.id,
- },
- data: {
- name: input.name,
- },
- });
-
- return !!user;
- }),
- setAdmin: adminProcedure
- .input(
- z.object({
- userId: z.string(),
- value: z.boolean(),
- })
- )
- .mutation(async ({ ctx, input }) => {
- const user = await ctx.prisma.user.update({
- where: {
- id: input.userId,
- },
- data: {
- isAdmin: input.value,
- },
- });
-
- await invalidateCache(`kv_userlist_admin`);
-
- return !!user;
- }),
-
- setVIP: adminProcedure
- .input(
- z.object({
- userId: z.string(),
- value: z.boolean(),
- })
- )
- .mutation(async ({ ctx, input }) => {
- const user = await ctx.prisma.user.update({
- where: {
- id: input.userId,
- },
- data: {
- isVIP: input.value,
- },
- });
-
- await invalidateCache(`kv_userlist_admin`);
-
- return !!user;
- }),
-});
diff --git a/src/server/api/routers/vote.ts b/src/server/api/routers/vote.ts
index c3e524b..be20fe3 100644
--- a/src/server/api/routers/vote.ts
+++ b/src/server/api/routers/vote.ts
@@ -17,9 +17,6 @@ export const voteRouter = createTRPCRouter({
id: string;
createdAt: Date;
userId: string;
- owner: {
- name: string | null;
- };
roomId: string;
}[]
>(`kv_votes_${input.roomId}`);
@@ -34,11 +31,6 @@ export const voteRouter = createTRPCRouter({
select: {
id: true,
createdAt: true,
- owner: {
- select: {
- name: true,
- },
- },
room: true,
roomId: true,
userId: true,
@@ -58,17 +50,17 @@ export const voteRouter = createTRPCRouter({
where: {
userId_roomId: {
roomId: input.roomId,
- userId: ctx.session.user.id,
+ userId: ctx.auth.userId,
},
},
create: {
value: input.value,
- userId: ctx.session.user.id,
+ userId: ctx.auth.userId,
roomId: input.roomId,
},
update: {
value: input.value,
- userId: ctx.session.user.id,
+ userId: ctx.auth.userId,
roomId: input.roomId,
},
select: {
@@ -76,11 +68,6 @@ export const voteRouter = createTRPCRouter({
userId: true,
roomId: true,
id: true,
- owner: {
- select: {
- name: true,
- },
- },
},
});
diff --git a/src/server/api/trpc.ts b/src/server/api/trpc.ts
index 2bf95d0..8a49ad7 100644
--- a/src/server/api/trpc.ts
+++ b/src/server/api/trpc.ts
@@ -1,81 +1,71 @@
/**
* YOU PROBABLY DON'T NEED TO EDIT THIS FILE, UNLESS:
- * 1. You want to modify request context (see Part 1).
- * 2. You want to create a new middleware or type of procedure (see Part 3).
+ * 1. You want to modify request context (see Part 1)
+ * 2. You want to create a new middleware or type of procedure (see Part 3)
*
- * TL;DR - This is where all the tRPC server stuff is created and plugged in. The pieces you will
- * need to use are documented accordingly near the end.
+ * tl;dr - this is where all the tRPC server stuff is created and plugged in.
+ * The pieces you will need to use are documented accordingly near the end
*/
/**
* 1. CONTEXT
*
- * This section defines the "contexts" that are available in the backend API.
+ * This section defines the "contexts" that are available in the backend API
+ *
+ * These allow you to access things like the database, the session, etc, when
+ * processing a request
*
- * These allow you to access things when processing a request, like the database, the session, etc.
*/
import { type CreateNextContextOptions } from "@trpc/server/adapters/next";
-import { type Session } from "next-auth";
+import { getAuth } from "@clerk/nextjs/server";
+import type {
+ SignedInAuthObject,
+ SignedOutAuthObject,
+} from "@clerk/nextjs/api";
-import { getServerAuthSession } from "~/server/auth";
-import { prisma } from "~/server/db";
-
-type CreateContextOptions = {
- session: Session | null;
- ip: string | undefined;
-};
+import { prisma } from "../db";
+interface AuthContext {
+ auth: SignedInAuthObject | SignedOutAuthObject;
+}
/**
- * This helper generates the "internals" for a tRPC context. If you need to use it, you can export
- * it from here.
+ * This helper generates the "internals" for a tRPC context. If you need to use
+ * it, you can export it from here
*
* Examples of things you may need it for:
- * - testing, so we don't have to mock Next.js' req/res
- * - tRPC's `createSSGHelpers`, where we don't have req/res
- *
+ * - testing, so we dont have to mock Next.js' req/res
+ * - trpc's `createSSGHelpers` where we don't have req/res
* @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts
*/
-const createInnerTRPCContext = (opts: CreateContextOptions) => {
+const createInnerTRPCContext = ({ auth }: AuthContext) => {
return {
- session: opts.session,
- ip: opts.ip,
+ auth,
prisma,
};
};
/**
- * This is the actual context you will use in your router. It will be used to process every request
- * that goes through your tRPC endpoint.
- *
- * @see https://trpc.io/docs/context
+ * This is the actual context you'll use in your router. It will be used to
+ * process every request that goes through your tRPC endpoint
+ * @link https://trpc.io/docs/context
*/
-export const createTRPCContext = async (opts: CreateNextContextOptions) => {
- const { req, res } = opts;
-
- // Get the session from the server using the getServerSession wrapper function
- const session = await getServerAuthSession({ req, res });
-
- return createInnerTRPCContext({
- ip: req.socket.remoteAddress,
- session,
- });
+export const createTRPCContext = (opts: CreateNextContextOptions) => {
+ return createInnerTRPCContext({ auth: getAuth(opts.req) });
};
/**
* 2. INITIALIZATION
*
- * This is where the tRPC API is initialized, connecting the context and transformer.
+ * This is where the trpc api is initialized, connecting the context and
+ * transformer
*/
import { initTRPC, TRPCError } from "@trpc/server";
-import type { OpenApiMeta } from "trpc-openapi";
-import { Ratelimit } from "@upstash/ratelimit";
import superjson from "superjson";
-import { env } from "~/env.mjs";
-import { Redis } from "@upstash/redis";
+import { OpenApiMeta } from "trpc-openapi";
const t = initTRPC
- .meta()
.context()
+ .meta()
.create({
transformer: superjson,
errorFormatter({ shape }) {
@@ -83,91 +73,37 @@ const t = initTRPC
},
});
+// check if the user is signed in, otherwise through a UNAUTHORIZED CODE
+const isAuthed = t.middleware(({ next, ctx }) => {
+ if (!ctx.auth.userId) {
+ throw new TRPCError({ code: "UNAUTHORIZED" });
+ }
+
+ return next({
+ ctx: {
+ auth: ctx.auth,
+ },
+ });
+});
/**
* 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)
*
- * These are the pieces you use to build your tRPC API. You should import these a lot in the
- * "/src/server/api/routers" directory.
+ * These are the pieces you use to build your tRPC API. You should import these
+ * a lot in the /src/server/api/routers folder
*/
/**
- * This is how you create new routers and sub-routers in your tRPC API.
- *
+ * This is how you create new routers and subrouters in your tRPC API
* @see https://trpc.io/docs/router
*/
export const createTRPCRouter = t.router;
/**
- * Public (unauthenticated) procedure
+ * Public (unauthed) procedure
*
- * This is the base piece you use to build new queries and mutations on your tRPC API. It does not
- * guarantee that a user querying is authorized, but you can still access user session data if they
- * are logged in.
+ * This is the base piece you use to build new queries and mutations on your
+ * tRPC API. It does not guarantee that a user querying is authorized, but you
+ * can still access user session data if they are logged in
*/
export const publicProcedure = t.procedure;
-
-/** Reusable middleware that enforces users are logged in before running the procedure. */
-const enforceAuthSession = t.middleware(async ({ ctx, next }) => {
- // Auth
- if (!ctx.session || !ctx.session.user) {
- throw new TRPCError({ code: "UNAUTHORIZED" });
- }
-
- const rateLimit = new Ratelimit({
- redis: Redis.fromEnv(),
- limiter: Ratelimit.slidingWindow(
- Number(env.UPSTASH_RATELIMIT_REQUESTS),
- `${Number(env.UPSTASH_RATELIMIT_SECONDS)}s`
- ),
- analytics: true,
- });
-
- const { success } = await rateLimit.limit(
- `${env.APP_ENV}_${ctx.session?.user.id}`
- );
-
- if (!success) throw new TRPCError({ code: "TOO_MANY_REQUESTS" });
-
- return next({
- ctx: {
- session: { ...ctx.session, user: ctx.session.user },
- },
- });
-});
-
-const enforceAdminRole = t.middleware(async ({ ctx, next }) => {
- 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 },
- },
- });
-});
-
-// 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
- *
- * If you want a query or mutation to ONLY be accessible to logged in users, use this. It verifies
- * the session is valid and guarantees `ctx.session.user` is not null.
- *
- * @see https://trpc.io/docs/procedures
- */
-export const protectedProcedure = t.procedure.use(enforceAuthSession);
-
-export const adminProcedure = t.procedure.use(enforceAdminRole);
+export const protectedProcedure = t.procedure.use(isAuthed);
diff --git a/src/server/auth.ts b/src/server/auth.ts
deleted file mode 100644
index fc9cf5d..0000000
--- a/src/server/auth.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { PrismaAdapter } from "@auth/prisma-adapter";
-import { type GetServerSidePropsContext } from "next";
-import {
- getServerSession,
- type DefaultSession,
- type NextAuthOptions,
-} from "next-auth";
-import GithubProvider from "next-auth/providers/github";
-import GoogleProvider from "next-auth/providers/google";
-import { Resend } from "resend";
-import { env } from "~/env.mjs";
-import { prisma } from "~/server/db";
-import { Welcome } from "../components/templates/Welcome";
-import { invalidateCache } from "./redis";
-import { publishToChannel } from "./ably";
-import { EventTypes } from "~/utils/types";
-
-const resend = new Resend(process.env.RESEND_API_KEY);
-
-/**
- * Module augmentation for `next-auth` types. Allows us to add custom properties to the `session`
- * object and keep type safety.
- *
- * @see https://next-auth.js.org/getting-started/typescript#module-augmentation
- */
-declare module "next-auth" {
- interface Session extends DefaultSession {
- user: {
- id: string;
- isAdmin: boolean;
- isVIP: boolean;
- } & DefaultSession["user"];
- }
-
- interface User {
- isAdmin: boolean;
- isVIP: boolean;
- }
-}
-
-/**
- * Options for NextAuth.js used to configure adapters, providers, callbacks, etc.
- *
- * @see https://next-auth.js.org/configuration/options
- */
-export const authOptions: NextAuthOptions = {
- callbacks: {
- session({ session, user }) {
- if (session.user) {
- session.user.id = user.id;
- session.user.isAdmin = user.isAdmin;
- session.user.isVIP = user.isVIP;
- }
- return session;
- },
- },
- events: {
- async createUser({ user }) {
- if (user && user.name && user.email) {
- await resend.sendEmail({
- from: "no-reply@sprintpadawan.dev",
- to: user.email,
- subject: "🎉 Welcome to Sprint Padawan! 🎉",
- //@ts-ignore: IDK why this doesn't work...
-
- react: Welcome({ name: user.name }),
- });
- await invalidateCache(`kv_userlist_admin`);
- await invalidateCache(`kv_usercount`);
-
- await publishToChannel(
- `stats`,
- EventTypes.STATS_UPDATE,
- JSON.stringify(user)
- );
- }
- },
- async signIn({}) {
- await invalidateCache(`kv_userlist_admin`);
- },
- async signOut() {
- await invalidateCache(`kv_userlist_admin`);
- },
- },
- // @ts-ignore This adapter should work...
- adapter: PrismaAdapter(prisma),
- providers: [
- GithubProvider({
- clientId: env.GITHUB_CLIENT_ID,
- clientSecret: env.GITHUB_CLIENT_SECRET,
- }),
- GoogleProvider({
- clientId: env.GOOGLE_CLIENT_ID,
- clientSecret: env.GOOGLE_CLIENT_SECRET,
- }),
- /**
- * ...add more providers here.
- *
- * Most other providers require a bit more work than the Discord provider. For example, the
- * GitHub provider requires you to add the `refresh_token_expires_in` field to the Account
- * model. Refer to the NextAuth.js docs for the provider you want to use. Example:
- *
- * @see https://next-auth.js.org/providers/github
- */
- ],
-};
-
-/**
- * Wrapper for `getServerSession` so that you don't need to import the `authOptions` in every file.
- *
- * @see https://next-auth.js.org/configuration/nextjs
- */
-export const getServerAuthSession = (ctx: {
- req: GetServerSidePropsContext["req"];
- res: GetServerSidePropsContext["res"];
-}) => {
- return getServerSession(ctx.req, ctx.res, authOptions);
-};
diff --git a/src/server/redis.ts b/src/server/redis.ts
index f09bb20..c7bbe4e 100644
--- a/src/server/redis.ts
+++ b/src/server/redis.ts
@@ -8,6 +8,7 @@ export const redis = Redis.fromEnv({
export const setCache = async (key: string, value: T) => {
try {
+ console.log("KEY: ", key);
await redis.set(`${env.APP_ENV}_${key}`, value, {
ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS),
});