mirror of
https://github.com/arthur-pbty/binouz.git
synced 2026-06-16 15:55:43 +02:00
feat: add authentication and user management features
- Implemented AuthButton component for Discord sign-in and sign-out functionality. - Created CopyButton component for copying server IP addresses. - Developed EventCard and GradeCard components for displaying events and grades. - Added Footer and Navbar components for site navigation and information. - Introduced PurchaseButton for handling grade purchases with Stripe integration. - Created SectionHeader component for consistent section titles. - Implemented session management with SessionProvider for NextAuth. - Set up PostgreSQL database with Docker and Prisma for data management. - Added admin guard functionality to restrict access to certain routes. - Configured NextAuth with Discord provider for user authentication. - Defined Prisma schema for user, admin, grade, event, and purchase models. - Seeded database with initial grades and events data. - Added SVG hero image for the landing page. - Extended NextAuth types to include additional user properties.
This commit is contained in:
+99
@@ -0,0 +1,99 @@
|
||||
import type { NextAuthOptions } from "next-auth";
|
||||
import DiscordProvider from "next-auth/providers/discord";
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||
import { db } from "@/lib/db";
|
||||
|
||||
const adminDiscordId = process.env.ADMIN_DISCORD_ID;
|
||||
const discordRedirectUrl = process.env.DISCORD_REDIRECT_URL;
|
||||
|
||||
const resolveAdmin = async (discordId?: string) => {
|
||||
if (!discordId) return false;
|
||||
if (adminDiscordId && discordId === adminDiscordId) return true;
|
||||
const admin = await db.admin.findUnique({ where: { discordId } });
|
||||
return Boolean(admin);
|
||||
};
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
adapter: PrismaAdapter(db),
|
||||
session: {
|
||||
strategy: "jwt",
|
||||
},
|
||||
providers: [
|
||||
DiscordProvider({
|
||||
clientId: process.env.DISCORD_CLIENT_ID ?? "",
|
||||
clientSecret: process.env.DISCORD_CLIENT_SECRET ?? "",
|
||||
authorization: {
|
||||
params: {
|
||||
scope: "identify email",
|
||||
...(discordRedirectUrl
|
||||
? { redirect_uri: discordRedirectUrl }
|
||||
: {}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
callbacks: {
|
||||
async jwt({ token, account, profile }) {
|
||||
if (account && profile) {
|
||||
const discordProfile = profile as {
|
||||
id?: string;
|
||||
username?: string;
|
||||
avatar?: string;
|
||||
};
|
||||
token.discordId = discordProfile.id;
|
||||
token.discordUsername = discordProfile.username;
|
||||
token.discordAvatar = discordProfile.avatar;
|
||||
}
|
||||
|
||||
token.isAdmin = await resolveAdmin(token.discordId as string | undefined);
|
||||
|
||||
return token;
|
||||
},
|
||||
async session({ session, token }) {
|
||||
if (session.user) {
|
||||
session.user.id = token.sub ?? "";
|
||||
session.user.discordId = (token.discordId as string | undefined) ?? "";
|
||||
session.user.discordUsername =
|
||||
(token.discordUsername as string | undefined) ?? "";
|
||||
session.user.discordAvatar =
|
||||
(token.discordAvatar as string | undefined) ?? "";
|
||||
session.user.isAdmin = token.isAdmin === true;
|
||||
}
|
||||
return session;
|
||||
},
|
||||
},
|
||||
events: {
|
||||
async signIn({ user, account, profile }) {
|
||||
if (!account || account.provider !== "discord" || !profile) return;
|
||||
|
||||
const discordId = (profile as { id?: string }).id;
|
||||
const discordUsername = (profile as { username?: string }).username;
|
||||
const discordAvatar = (profile as { avatar?: string }).avatar;
|
||||
|
||||
if (!discordId) return;
|
||||
|
||||
await db.user.update({
|
||||
where: { id: user.id },
|
||||
data: {
|
||||
discordId,
|
||||
discordUsername,
|
||||
discordAvatar,
|
||||
},
|
||||
});
|
||||
|
||||
if (adminDiscordId && discordId === adminDiscordId) {
|
||||
await db.admin.upsert({
|
||||
where: { discordId },
|
||||
update: {},
|
||||
create: {
|
||||
discordId,
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
pages: {
|
||||
signIn: "/auth/signin",
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user