aboutsummaryrefslogtreecommitdiffstats
path: root/packages/web/server/auth.ts
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-02-22 15:32:40 +0000
committerMohamedBassem <me@mbassem.com>2024-02-22 15:32:40 +0000
commit942aac691225f4895c159a0260890ad2c576e0c9 (patch)
tree06a055fcd59c2753531f498ab58d0af4c7e8464c /packages/web/server/auth.ts
parent08e7cbcfcb5e0b992d10ada324712c224b7a4d07 (diff)
downloadkarakeep-942aac691225f4895c159a0260890ad2c576e0c9.tar.zst
feature: Add support for credentials registration and sign in
Diffstat (limited to 'packages/web/server/auth.ts')
-rw-r--r--packages/web/server/auth.ts81
1 files changed, 77 insertions, 4 deletions
diff --git a/packages/web/server/auth.ts b/packages/web/server/auth.ts
index b7391848..a63bcac4 100644
--- a/packages/web/server/auth.ts
+++ b/packages/web/server/auth.ts
@@ -5,8 +5,18 @@ import serverConfig from "@hoarder/shared/config";
import { prisma } from "@hoarder/db";
import { DefaultSession } from "next-auth";
import * as bcrypt from "bcrypt";
+import CredentialsProvider from "next-auth/providers/credentials";
import { randomBytes } from "crypto";
+import { Provider } from "next-auth/providers/index";
+
+declare module "next-auth/jwt" {
+ export interface JWT {
+ user: {
+ id: string;
+ } & DefaultSession["user"];
+ }
+}
declare module "next-auth" {
/**
@@ -19,19 +29,55 @@ declare module "next-auth" {
}
}
-const providers = [];
+const providers: Provider[] = [
+ CredentialsProvider({
+ // The name to display on the sign in form (e.g. "Sign in with...")
+ name: "Credentials",
+ credentials: {
+ email: { label: "Email", type: "email", placeholder: "Email" },
+ password: { label: "Password", type: "password" },
+ },
+ async authorize(credentials) {
+ if (!credentials) {
+ return null;
+ }
+
+ try {
+ return await validatePassword(
+ credentials?.email,
+ credentials?.password,
+ );
+ } catch (e) {
+ return null;
+ }
+ },
+ }),
+];
if (serverConfig.auth.authentik) {
providers.push(AuthentikProvider(serverConfig.auth.authentik));
}
export const authOptions: NextAuthOptions = {
- // Configure one or more authentication providers
adapter: PrismaAdapter(prisma),
providers: providers,
+ session: {
+ strategy: "jwt",
+ },
callbacks: {
- session({ session, user }) {
- session.user = { ...user };
+ async jwt({ token, user }) {
+ if (user) {
+ token.user = {
+ id: user.id,
+ name: user.name,
+ email: user.email,
+ image: user.image,
+ };
+ }
+ return token;
+ },
+ async session({ session, token }) {
+ session.user = { ...token.user };
return session;
},
},
@@ -110,3 +156,30 @@ export async function authenticateApiKey(key: string) {
return apiKey.user;
}
+
+export async function hashPassword(password: string) {
+ return bcrypt.hash(password, BCRYPT_SALT_ROUNDS);
+}
+
+export async function validatePassword(email: string, password: string) {
+ const user = await prisma.user.findUnique({
+ where: {
+ email,
+ },
+ });
+
+ if (!user) {
+ throw new Error("User not found");
+ }
+
+ if (!user.password) {
+ throw new Error("This user doesn't have a password defined");
+ }
+
+ const validation = await bcrypt.compare(password, user.password);
+ if (!validation) {
+ throw new Error("Wrong password");
+ }
+
+ return user;
+}