aboutsummaryrefslogtreecommitdiffstats
path: root/packages/web/server/auth.ts
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-03-05 13:11:06 +0000
committerMohamedBassem <me@mbassem.com>2024-03-05 13:11:06 +0000
commit8a46ecb7373d6c5e7300861169ea51a7917cd2b4 (patch)
tree4ad318c3b5fc8b7a74cba6d0e37b6ade24db829a /packages/web/server/auth.ts
parent224aa38d5976523f213e2860b6addc7630d472ba (diff)
downloadkarakeep-8a46ecb7373d6c5e7300861169ea51a7917cd2b4.tar.zst
refactor: Extract trpc logic into its package
Diffstat (limited to 'packages/web/server/auth.ts')
-rw-r--r--packages/web/server/auth.ts100
1 files changed, 1 insertions, 99 deletions
diff --git a/packages/web/server/auth.ts b/packages/web/server/auth.ts
index 1810c87d..950443b9 100644
--- a/packages/web/server/auth.ts
+++ b/packages/web/server/auth.ts
@@ -2,15 +2,13 @@ import NextAuth, { NextAuthOptions, getServerSession } from "next-auth";
import type { Adapter } from "next-auth/adapters";
import AuthentikProvider from "next-auth/providers/authentik";
import serverConfig from "@hoarder/shared/config";
+import { validatePassword } from "@hoarder/trpc/auth";
import { db } from "@hoarder/db";
import { DefaultSession } from "next-auth";
-import * as bcrypt from "bcrypt";
import CredentialsProvider from "next-auth/providers/credentials";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
-import { randomBytes } from "crypto";
import { Provider } from "next-auth/providers/index";
-import { apiKeys } from "@hoarder/db/schema";
declare module "next-auth/jwt" {
export interface JWT {
@@ -96,99 +94,3 @@ export const authOptions: NextAuthOptions = {
export const authHandler = NextAuth(authOptions);
export const getServerAuthSession = () => getServerSession(authOptions);
-
-// API Keys
-
-const BCRYPT_SALT_ROUNDS = 10;
-const API_KEY_PREFIX = "ak1";
-
-export async function generateApiKey(name: string, userId: string) {
- const id = randomBytes(10).toString("hex");
- const secret = randomBytes(10).toString("hex");
- const secretHash = await bcrypt.hash(secret, BCRYPT_SALT_ROUNDS);
-
- const plain = `${API_KEY_PREFIX}_${id}_${secret}`;
-
- const key = (
- await db
- .insert(apiKeys)
- .values({
- name: name,
- userId: userId,
- keyId: id,
- keyHash: secretHash,
- })
- .returning()
- )[0];
-
- return {
- id: key.id,
- name: key.name,
- createdAt: key.createdAt,
- key: plain,
- };
-}
-
-function parseApiKey(plain: string) {
- const parts = plain.split("_");
- if (parts.length != 3) {
- throw new Error(
- `Malformd API key. API keys should have 3 segments, found ${parts.length} instead.`,
- );
- }
- if (parts[0] !== API_KEY_PREFIX) {
- throw new Error(`Malformd API key. Got unexpected key prefix.`);
- }
- return {
- keyId: parts[1],
- keySecret: parts[2],
- };
-}
-
-export async function authenticateApiKey(key: string) {
- const { keyId, keySecret } = parseApiKey(key);
- const apiKey = await db.query.apiKeys.findFirst({
- where: (k, { eq }) => eq(k.keyId, keyId),
- with: {
- user: true,
- },
- });
-
- if (!apiKey) {
- throw new Error("API key not found");
- }
-
- const hash = apiKey.keyHash;
-
- const validation = await bcrypt.compare(keySecret, hash);
- if (!validation) {
- throw new Error("Invalid API Key");
- }
-
- 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 db.query.users.findFirst({
- where: (u, { eq }) => eq(u.email, 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;
-}