Add documentation, clean repository templating

This commit is contained in:
2025-07-18 01:38:43 -04:00
parent 1a503d818b
commit 4f8402c5e6
33 changed files with 8178 additions and 152 deletions

View File

@@ -1,4 +1,5 @@
import { postRouter } from "~/server/api/routers/post";
import { authRouter } from "~/server/api/routers/auth";
import { createCallerFactory, createTRPCRouter } from "~/server/api/trpc";
/**
@@ -8,6 +9,7 @@ import { createCallerFactory, createTRPCRouter } from "~/server/api/trpc";
*/
export const appRouter = createTRPCRouter({
post: postRouter,
auth: authRouter,
});
// export type definition of API

View File

@@ -0,0 +1,59 @@
import { z } from "zod";
import bcrypt from "bcryptjs";
import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm";
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
import { users } from "~/server/db/schema";
export const authRouter = createTRPCRouter({
register: publicProcedure
.input(
z.object({
name: z.string().min(1, "Name is required"),
email: z.string().email("Invalid email address"),
password: z.string().min(6, "Password must be at least 6 characters"),
}),
)
.mutation(async ({ ctx, input }) => {
const { name, email, password } = input;
// Check if user already exists
const existingUser = await ctx.db.query.users.findFirst({
where: eq(users.email, email),
});
if (existingUser) {
throw new TRPCError({
code: "CONFLICT",
message: "User with this email already exists",
});
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 12);
try {
// Create user
const [newUser] = await ctx.db
.insert(users)
.values({
name,
email,
password: hashedPassword,
})
.returning({
id: users.id,
name: users.name,
email: users.email,
});
return newUser;
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Failed to create user",
});
}
}),
});

View File

@@ -1,6 +1,8 @@
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { type DefaultSession, type NextAuthConfig } from "next-auth";
import DiscordProvider from "next-auth/providers/discord";
import Credentials from "next-auth/providers/credentials";
import bcrypt from "bcryptjs";
import { eq } from "drizzle-orm";
import { db } from "~/server/db";
import {
@@ -38,29 +40,57 @@ declare module "next-auth" {
*/
export const authConfig = {
providers: [
DiscordProvider,
/**
* ...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
*/
Credentials({
name: "credentials",
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
if (!credentials?.email || !credentials?.password) {
return null;
}
const user = await db.query.users.findFirst({
where: eq(users.email, credentials.email as string),
});
if (!user || !user.password) {
return null;
}
const isValidPassword = await bcrypt.compare(
credentials.password as string,
user.password,
);
if (!isValidPassword) {
return null;
}
return {
id: user.id,
email: user.email,
name: user.name,
};
},
}),
],
adapter: DrizzleAdapter(db, {
usersTable: users,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
session: {
strategy: "jwt",
},
callbacks: {
session: ({ session, user }) => ({
jwt: ({ token, user }) => {
if (user) {
token.id = user.id;
}
return token;
},
session: ({ session, token }) => ({
...session,
user: {
...session.user,
id: user.id,
id: token.id as string,
},
}),
},