diff --git a/bun.lockb b/bun.lockb
index 47b9e14..5043618 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index 5655ad7..1b22df7 100644
--- a/package.json
+++ b/package.json
@@ -51,6 +51,7 @@
"@trpc/react-query": "^11.0.0-rc.446",
"@trpc/server": "^11.0.0-rc.446",
"@types/bcrypt": "^5.0.2",
+ "@types/lodash": "^4.17.7",
"@types/loglevel": "^1.6.3",
"@types/react-copy-to-clipboard": "^5.0.7",
"bcrypt": "^5.1.1",
diff --git a/src/app/(site)/(auth)/register/page.tsx b/src/app/(site)/(auth)/register/page.tsx
index e497c07..7824faf 100644
--- a/src/app/(site)/(auth)/register/page.tsx
+++ b/src/app/(site)/(auth)/register/page.tsx
@@ -49,113 +49,3 @@ const RegisterPage: React.FC = () => {
};
export default RegisterPage;
-
-// const SignUpPage = () => {
-// const router = useRouter();
-//
-// const signup = api.auth.create.useMutation({
-// onSuccess: () => router.push("/auth/signin"),
-// onError: (error) => {
-// logger.error("signup", "error", error);
-// },
-// });
-// const [userInfo, setUserInfo] = React.useState({
-// email: "fergal.moran+opengifame@gmail.com",
-// password: "secret",
-// repeatPassword: "secret",
-// });
-//
-// return (
-//
-//
-//
-// Create new account
-//
-//
-//
-//
-//
-// );
-// };
-//
-// export default SignUpPage;
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index d920f48..57b2271 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,27 +1,30 @@
import { Inter as FontSans } from "next/font/google";
import "@/styles/globals.css";
-import { type Metadata } from "next";
+import { type Metadata, Viewport } from "next";
import { TRPCReactProvider } from "@/trpc/react";
import { cn } from "@/lib/utils";
import { ThemeProvider } from "next-themes";
import { TailwindIndicator } from "@/components/tailwind-indicator";
import { Toaster } from "@/components/ui/toaster";
+import React from "react";
const fontSans = FontSans({
subsets: ["latin"],
variable: "--font-sans",
});
+export const viewport: Viewport = {
+ themeColor: [
+ { media: "(prefers-color-scheme: light)", color: "white" },
+ { media: "(prefers-color-scheme: dark)", color: "black" },
+ ],
+};
export const metadata: Metadata = {
title: "Open Gifame",
description: "Contains traces of gifs",
icons: [{ rel: "icon", url: "/favicon.ico" }],
- themeColor: [
- { media: "(prefers-color-scheme: light)", color: "white" },
- { media: "(prefers-color-scheme: dark)", color: "black" },
- ],
};
export default function RootLayout({
diff --git a/src/components/forms/auth/RegistrationForm.tsx b/src/components/forms/auth/RegistrationForm.tsx
index 98b22d5..9cb37ba 100644
--- a/src/components/forms/auth/RegistrationForm.tsx
+++ b/src/components/forms/auth/RegistrationForm.tsx
@@ -19,6 +19,8 @@ import { logger } from "@/lib/logger";
import { Icons } from "@/components/icons";
import { cn } from "@/lib/utils";
import { toast } from "sonner";
+import { useRouter } from "next/navigation";
+
const registrationSchema = z
.object({
email: z.string().email({ message: "Invalid email address" }),
@@ -41,6 +43,7 @@ type RegistrationFormValues = z.infer;
const RegistrationForm: React.FC = () => {
const [isLoading, setIsLoading] = React.useState(false);
+ const router = useRouter();
const form = useForm({
resolver: zodResolver(registrationSchema),
});
@@ -52,6 +55,7 @@ const RegistrationForm: React.FC = () => {
try {
await createUser.mutateAsync(data);
toast("User registered successfully");
+ router.push("/signin");
} catch (error) {
logger.error("RegistrationForm", "error", error);
toast("Failed to register user");
@@ -68,6 +72,7 @@ const RegistrationForm: React.FC = () => {
(
Email
@@ -85,6 +90,7 @@ const RegistrationForm: React.FC = () => {
(
Password
@@ -102,6 +108,7 @@ const RegistrationForm: React.FC = () => {
(
Confirm password
diff --git a/src/server/api/routers/auth.ts b/src/server/api/routers/auth.ts
index e6259f0..6802220 100644
--- a/src/server/api/routers/auth.ts
+++ b/src/server/api/routers/auth.ts
@@ -2,6 +2,7 @@ import { createTRPCRouter, publicProcedure } from "../trpc";
import { z } from "zod";
import { users } from "@/server/db/schema";
import bcrypt from "bcrypt";
+import { and, eq } from "drizzle-orm";
export const authRouter = createTRPCRouter({
create: publicProcedure
@@ -14,4 +15,19 @@ export const authRouter = createTRPCRouter({
});
return user;
}),
+
+ login: publicProcedure
+ .input(z.object({ email: z.string().email(), password: z.string().min(5) }))
+ .query(async ({ ctx, input }) => {
+ const hashedPassword = await bcrypt.hash(input.password, 10);
+ const user = await ctx.db
+ .select()
+ .from(users)
+ .where(
+ and(eq(users.email, input.email), eq(users.password, hashedPassword)),
+ )
+ .limit(1);
+
+ return user[0];
+ }),
});
diff --git a/src/server/auth.ts b/src/server/auth.ts
index 41fd773..cdd6ba5 100644
--- a/src/server/auth.ts
+++ b/src/server/auth.ts
@@ -4,9 +4,9 @@ import {
getServerSession,
type DefaultSession,
type NextAuthOptions,
+ RequestInternal,
} from "next-auth";
import { type Adapter } from "next-auth/adapters";
-import { db } from "@/server/db";
import {
accounts,
sessions,
@@ -15,33 +15,18 @@ import {
} from "@/server/db/schema";
import { api } from "@/trpc/server";
import { env } from "@/env";
+import { db } from "@/server/db";
+
+import Credentials from "next-auth/providers/credentials";
-/**
- * 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;
- // ...other properties
- // role: UserRole;
} & DefaultSession["user"];
}
-
- // interface User {
- // // ...other properties
- // // role: UserRole;
- // }
}
-/**
- * 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 }) => ({
@@ -59,13 +44,13 @@ export const authOptions: NextAuthOptions = {
verificationTokensTable: verificationTokens,
}) as Adapter,
providers: [
- CredentialsProvider({
- type: "credentials",
+ Credentials({
+ name: "credentials",
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Password", type: "password" },
},
- authorize: async (credentials, request) => {
+ authorize: async (credentials, _request) => {
if (!credentials) {
return null;
}
@@ -73,30 +58,14 @@ export const authOptions: NextAuthOptions = {
email: credentials.email,
password: credentials.password,
});
- // const user = await prisma.users.findUnique({
- // where: { email: credentials.email },
- // select: {
- // id: true,
- // email: true,
- // password: true,
- // },
- // });
- // if (user && user.password) {
- // const hashed = await confirmPassword(
- // credentials.password,
- // user.password,
- // );
- // if (hashed) {
- // return omit(user, "password");
- // }
- // }
- return null;
+ if (!result) {
+ return null;
+ }
+ return { id: result.id, email: result.email };
},
}),
],
- session: {
- strategy: "jwt",
- },
+
secret: env.NEXTAUTH_SECRET,
debug: env.NODE_ENV === "development",
pages: {