From 171de4104d3af3391ed4da617801e4b919310b2a Mon Sep 17 00:00:00 2001 From: gibbyb Date: Wed, 9 Oct 2024 10:27:12 -0500 Subject: [PATCH] update backend for appleauth --- src/app/api/users/changePassword/route.ts | 33 ---- src/app/api/users/createUser/route.ts | 31 ++- .../route.ts | 6 +- src/app/api/users/login/route.ts | 39 ---- src/app/api/users/logout/route.ts | 25 --- src/app/api/users/refreshToken/route.ts | 22 --- src/app/api/users/updatePFP/route.ts | 2 +- src/app/api/users/updatePushToken/route.ts | 2 +- src/app/users/changePassword/page.tsx | 87 --------- src/app/users/createUser/page.tsx | 51 ++--- .../page.tsx | 8 +- src/app/users/login/page.tsx | 74 ------- src/app/users/logout/page.tsx | 60 ------ src/app/users/refreshToken/page.tsx | 60 ------ src/server/db/schema.ts | 9 +- src/server/functions.ts | 180 ++---------------- 16 files changed, 57 insertions(+), 632 deletions(-) delete mode 100644 src/app/api/users/changePassword/route.ts rename src/app/api/users/{getUserByUsername => getUserByAppleEmail}/route.ts (74%) delete mode 100644 src/app/api/users/login/route.ts delete mode 100644 src/app/api/users/logout/route.ts delete mode 100644 src/app/api/users/refreshToken/route.ts delete mode 100644 src/app/users/changePassword/page.tsx rename src/app/users/{getUserByUsername => getUserByAppleEmail}/page.tsx (86%) delete mode 100644 src/app/users/login/page.tsx delete mode 100644 src/app/users/logout/page.tsx delete mode 100644 src/app/users/refreshToken/page.tsx diff --git a/src/app/api/users/changePassword/route.ts b/src/app/api/users/changePassword/route.ts deleted file mode 100644 index 861f68c..0000000 --- a/src/app/api/users/changePassword/route.ts +++ /dev/null @@ -1,33 +0,0 @@ -"use server"; -import { NextResponse } from "next/server"; -import type { NextRequest } from "next/server"; -import { changePassword } from "~/server/functions"; -import { middleware } from "~/middleware"; - -type Data = { - userId: number; - oldPassword: string; - newPassword: string; -}; - -export const POST = async (request: NextRequest) => { - const middlewareResponse = await middleware(request); - if (middlewareResponse) return middlewareResponse; - try { - const { userId, oldPassword, newPassword } = await request.json() as Data; - console.log("Received request:", { userId, oldPassword, newPassword }); - - console.log("Changing password for user:", userId); - if (oldPassword === newPassword) { - return NextResponse.json( - { message: "New password cannot be the same as the old password" }, - { status: 400 } - ); - } - await changePassword(userId, oldPassword, newPassword); - return NextResponse.json({ message: "Password changed successfully" }); - } catch (error) { - console.error("Error in changePassword:", error); - return NextResponse.json({ message: "Error changing password" }, { status: 500 }); - } -}; diff --git a/src/app/api/users/createUser/route.ts b/src/app/api/users/createUser/route.ts index 52a9184..27fadc6 100644 --- a/src/app/api/users/createUser/route.ts +++ b/src/app/api/users/createUser/route.ts @@ -5,12 +5,11 @@ import { createUser } from "~/server/functions"; import { middleware } from "~/middleware"; type CreateUserRequest = { - username: string; - email: string; - passwordHash: string; - name: string; + appleId: string; + appleEmail: string; + fullName: string; + pushToken: string; pfpURL?: string; - pushToken?: string; }; export async function POST(request: NextRequest) { @@ -18,16 +17,15 @@ export async function POST(request: NextRequest) { if (middlewareResponse) return middlewareResponse; try { const { - username, - email, - passwordHash, - name, + appleId, + appleEmail, + fullName, + pushToken, pfpURL = "", - pushToken = "" } = await request.json() as CreateUserRequest; // Validate required fields - if (!username || !email || !passwordHash || !name) { + if (!appleId || !appleEmail || !fullName || !pushToken) { return NextResponse.json( { message: "Missing required fields" }, { status: 400 } @@ -35,12 +33,11 @@ export async function POST(request: NextRequest) { } const user = await createUser( - username, - email, - passwordHash, - name, - pfpURL, - pushToken + appleId, + appleEmail, + fullName, + pushToken, + pfpURL ); return NextResponse.json(user, { status: 201 }); diff --git a/src/app/api/users/getUserByUsername/route.ts b/src/app/api/users/getUserByAppleEmail/route.ts similarity index 74% rename from src/app/api/users/getUserByUsername/route.ts rename to src/app/api/users/getUserByAppleEmail/route.ts index 285e01e..8b0b6ba 100644 --- a/src/app/api/users/getUserByUsername/route.ts +++ b/src/app/api/users/getUserByAppleEmail/route.ts @@ -1,7 +1,7 @@ "use server"; import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; -import { getUserByUsername } from "~/server/functions"; +import { getUserByAppleEmail } from "~/server/functions"; import { middleware } from "~/middleware"; export const GET = async (request: NextRequest) => { @@ -9,8 +9,8 @@ export const GET = async (request: NextRequest) => { if (middlewareResponse) return middlewareResponse; try { const url = new URL(request.url); - const username = url.searchParams.get("username") ?? "2"; - const user = await getUserByUsername(username); + const appleEmail = url.searchParams.get("appleEmail") ?? ""; + const user = await getUserByAppleEmail(appleEmail); return NextResponse.json(user); } catch (error) { console.error(error); diff --git a/src/app/api/users/login/route.ts b/src/app/api/users/login/route.ts deleted file mode 100644 index 3516472..0000000 --- a/src/app/api/users/login/route.ts +++ /dev/null @@ -1,39 +0,0 @@ -"use server"; -import { NextResponse } from "next/server"; -import type { NextRequest } from "next/server"; -import { login } from "~/server/functions"; -import { middleware } from "~/middleware"; - -type LoginRequest = { - username: string; - password: string; -} - -export async function POST(request: NextRequest) { - const middlewareResponse = await middleware(request); - if (middlewareResponse) return middlewareResponse; - try { - const { username, password } = await request.json() as LoginRequest; - console.log("Received request:", { username, password }); - - if (!username || !password) { - return NextResponse.json({ message: "Missing required fields" }, { status: 400 }); - } - - console.log("Logging in user:", username); - const result = await login(username, password); - - if (result) { - console.log("User logged in successfully"); - return NextResponse.json({ result }, { status: 200 }); - } else { - throw new Error("Failed to log in user"); - } - } catch (error) { - console.error("Error in login:", error); - if (error instanceof Error) { - return NextResponse.json({ message: error.message }, { status: 400 }); - } - return NextResponse.json({ message: "Error logging in user" }, { status: 500 }); - } -} diff --git a/src/app/api/users/logout/route.ts b/src/app/api/users/logout/route.ts deleted file mode 100644 index aaa7be4..0000000 --- a/src/app/api/users/logout/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -"use server"; -import { NextResponse } from "next/server"; -import type { NextRequest } from "next/server"; -import { logout } from "~/server/functions"; -import { middleware } from "~/middleware"; - -export const POST = async (request: NextRequest) => { - const middlewareResponse = await middleware(request); - if (middlewareResponse) return middlewareResponse; - - try { - const { refreshToken } = await request.json() as { refreshToken: string }; - if (!refreshToken) - return NextResponse.json({ message: "Refresh token is required" }, { status: 400 }); - - await logout(refreshToken); - return NextResponse.json({ message: "Logged out successfully" }); - } catch (error) { - console.error('Logout error:', error); - if (error instanceof Error) - return NextResponse.json({ message: error.message }, { status: 400 }); - else - return NextResponse.json({ message: "Unknown error occurred" }, { status: 500 }); - } -} diff --git a/src/app/api/users/refreshToken/route.ts b/src/app/api/users/refreshToken/route.ts deleted file mode 100644 index f0f9e83..0000000 --- a/src/app/api/users/refreshToken/route.ts +++ /dev/null @@ -1,22 +0,0 @@ -"use server"; -import { NextResponse } from "next/server"; -import type { NextRequest } from "next/server"; -import { refreshToken } from "~/server/functions"; -import { middleware } from "~/middleware"; - -export async function POST(request: NextRequest) { - const middlewareResponse = await middleware(request); - if (middlewareResponse) return middlewareResponse; - try { - const { refreshToken: token } = await request.json() as { refreshToken: string }; - if (!token) - return NextResponse.json({ message: "Refresh token is required" },{ status: 400 }); - const tokens = await refreshToken(token); - return NextResponse.json(tokens); - } catch (error) { - if (error instanceof Error) - return NextResponse.json({ message: error.message }, { status: 400 }); - else - return NextResponse.json({ message: "Unknown error occurred" }, { status: 500 }); - } -} diff --git a/src/app/api/users/updatePFP/route.ts b/src/app/api/users/updatePFP/route.ts index 9641323..a4a3b9f 100644 --- a/src/app/api/users/updatePFP/route.ts +++ b/src/app/api/users/updatePFP/route.ts @@ -4,7 +4,7 @@ import type { NextRequest } from "next/server"; import { updateUserPFP } from "~/server/functions"; import { middleware } from "~/middleware"; -interface UpdatePfpRequest { +type UpdatePfpRequest = { userId: number; pfpURL: string; } diff --git a/src/app/api/users/updatePushToken/route.ts b/src/app/api/users/updatePushToken/route.ts index cf299de..1364094 100644 --- a/src/app/api/users/updatePushToken/route.ts +++ b/src/app/api/users/updatePushToken/route.ts @@ -4,7 +4,7 @@ import type { NextRequest } from "next/server"; import { updateUserPushToken } from "~/server/functions"; import { middleware } from "~/middleware"; -interface UpdatePushTokenRequest { +type UpdatePushTokenRequest = { userId: number; pushToken: string; } diff --git a/src/app/users/changePassword/page.tsx b/src/app/users/changePassword/page.tsx deleted file mode 100644 index a6b877c..0000000 --- a/src/app/users/changePassword/page.tsx +++ /dev/null @@ -1,87 +0,0 @@ -"use client"; - -import React, { useState } from 'react'; - -export default function ChangePasswordPage() { - const [userId, setUserId] = useState(""); - const [oldPassword, setOldPassword] = useState(""); - const [newPassword, setNewPassword] = useState(""); - const [result, setResult] = useState(null); - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setResult(null); - - try { - const response = await fetch('/api/users/changePassword', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'x-api-key': process.env.NEXT_PUBLIC_API_KEY ?? '', - }, - body: JSON.stringify({ - userId, - oldPassword, - newPassword - }) - }); - const data = await response.json() as {message: string} - setResult(JSON.stringify(data, null, 2)); - } catch (error) { - console.error('Error:', error); - setResult('An error occurred'); - } - }; - - return ( -
-
-

Test Change Password

-
-
- - setUserId(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
-
- - setOldPassword(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
-
- - setNewPassword(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
- -
- {result && ( -
-
{result}
-
- )} -
-
- ); -}; diff --git a/src/app/users/createUser/page.tsx b/src/app/users/createUser/page.tsx index 40beeef..8de19e0 100644 --- a/src/app/users/createUser/page.tsx +++ b/src/app/users/createUser/page.tsx @@ -3,12 +3,11 @@ import React, { useState } from 'react'; export default function CreateUserPage() { - const [username, setUsername] = useState(""); - const [email, setEmail] = useState(""); - const [passwordHash, setPasswordHash] = useState(""); - const [name, setName] = useState(""); - const [pfpURL, setPfpURL] = useState(""); + const [appleId, setAppleId] = useState(""); + const [appleEmail, setAppleEmail] = useState(""); + const [fullName, setFullName] = useState(""); const [pushToken, setPushToken] = useState(""); + const [pfpURL, setPfpURL] = useState(""); const [result, setResult] = useState(null); const handleSubmit = async (e: React.FormEvent) => { @@ -23,10 +22,9 @@ export default function CreateUserPage() { 'x-api-key': process.env.NEXT_PUBLIC_API_KEY ?? '', }, body: JSON.stringify({ - username, - email, - passwordHash, - name, + appleId, + appleEmail, + fullName, pfpURL, pushToken }) @@ -46,45 +44,34 @@ export default function CreateUserPage() {

Test Create User

- + setUsername(e.target.value)} + id="appleId" + value={appleId} + onChange={(e) => setAppleId(e.target.value)} className="border p-2 w-full bg-black" required />
- + setEmail(e.target.value)} + id="appleEmail" + value={appleEmail} + onChange={(e) => setAppleEmail(e.target.value)} className="border p-2 w-full bg-black" required />
- + setPasswordHash(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
-
- - setName(e.target.value)} + id="fullName" + value={fullName} + onChange={(e) => setFullName(e.target.value)} className="border p-2 w-full bg-black" required /> diff --git a/src/app/users/getUserByUsername/page.tsx b/src/app/users/getUserByAppleEmail/page.tsx similarity index 86% rename from src/app/users/getUserByUsername/page.tsx rename to src/app/users/getUserByAppleEmail/page.tsx index 2b798e7..3a8dad3 100644 --- a/src/app/users/getUserByUsername/page.tsx +++ b/src/app/users/getUserByAppleEmail/page.tsx @@ -3,7 +3,7 @@ import React, { useState } from 'react'; export default function GetUserByUsernamePage() { - const [userName, setUserName] = useState(''); + const [appleEmail, setAppleEmail] = useState(''); const [result, setResult] = useState(null); const handleSubmit = async (e: React.FormEvent) => { @@ -11,7 +11,7 @@ export default function GetUserByUsernamePage() { setResult(null); try { - const response = await fetch(`/api/users/getUserByUsername?username=${userName}`, { + const response = await fetch(`/api/users/getUserByAppleEmail?appleEmail=${appleEmail}`, { method: 'GET', headers: { 'Content-Type': 'application/json', @@ -37,8 +37,8 @@ export default function GetUserByUsernamePage() { setUserName(e.target.value)} + value={appleEmail} + onChange={(e) => setAppleEmail(e.target.value)} className="border p-2 w-full bg-black" required /> diff --git a/src/app/users/login/page.tsx b/src/app/users/login/page.tsx deleted file mode 100644 index 6fa159c..0000000 --- a/src/app/users/login/page.tsx +++ /dev/null @@ -1,74 +0,0 @@ -'use client'; - -import React, { useState } from 'react'; - -export default function LoginTestPage() { - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); - const [result, setResult] = useState(null); - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setResult(null); - - try { - const response = await fetch('/api/users/login', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'x-api-key': process.env.NEXT_PUBLIC_API_KEY ?? '', - }, - body: JSON.stringify({ - username, - password - }) - }); - const data = await response.json() as {message: string} - setResult(JSON.stringify(data, null, 2)); - } catch (error) { - console.error('Error:', error); - setResult('An error occurred'); - } - }; - - return ( -
-
-

Test Login

- -
- - setUsername(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
-
- - setPassword(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
- - - {result && ( -
-
{result}
-
- )} -
-
- ); -}; diff --git a/src/app/users/logout/page.tsx b/src/app/users/logout/page.tsx deleted file mode 100644 index eaa03a0..0000000 --- a/src/app/users/logout/page.tsx +++ /dev/null @@ -1,60 +0,0 @@ -'use client'; - -import React, { useState } from 'react'; - -export default function TestLogout() { - const [refreshToken, setRefreshToken] = useState(''); - const [result, setResult] = useState(null); - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setResult(null); - - try { - const response = await fetch('/api/users/logout', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'x-api-key': process.env.NEXT_PUBLIC_API_KEY ?? '', - }, - body: JSON.stringify({ - refreshToken - }) - }); - const data = await response.json() as {message: string} - setResult(JSON.stringify(data, null, 2)); - } catch (error) { - console.error('Error:', error); - setResult('An error occurred'); - } - }; - return ( -
-
-

Test Logout

-
-
- - setRefreshToken(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
- -
- {result && ( -
-
{result}
-
- )} -
-
- ); -}; diff --git a/src/app/users/refreshToken/page.tsx b/src/app/users/refreshToken/page.tsx deleted file mode 100644 index cd14381..0000000 --- a/src/app/users/refreshToken/page.tsx +++ /dev/null @@ -1,60 +0,0 @@ -'use client'; - -import React, { useState } from 'react'; - -export default function TestRefreshToken() { - const [refreshToken, setRefreshToken] = useState(''); - const [result, setResult] = useState(null); - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setResult(null); - - try { - const response = await fetch('/api/users/refreshToken', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'x-api-key': process.env.NEXT_PUBLIC_API_KEY ?? '', - }, - body: JSON.stringify({ - refreshToken - }) - }); - const data = await response.json() as {message: string} - setResult(JSON.stringify(data, null, 2)); - } catch (error) { - console.error('Error:', error); - setResult('An error occurred'); - } - }; - return ( -
-
-

Test Refresh Token

-
-
- - setRefreshToken(e.target.value)} - className="border p-2 w-full bg-black" - required - /> -
- -
- {result && ( -
-
{result}
-
- )} -
-
- ); -}; diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts index 0816e3a..11aa78a 100755 --- a/src/server/db/schema.ts +++ b/src/server/db/schema.ts @@ -19,14 +19,11 @@ export const users = createTable( "user", { id: serial("id").primaryKey(), - username: varchar("username", { length: 50 }).unique().notNull(), - email: varchar("email", { length: 255 }).unique().notNull(), - passwordHash: varchar("password_hash", {length: 255}).notNull(), - name: varchar("name", { length: 100 }), + appleId: varchar("apple_id", { length: 255 }).unique(), + appleEmail: varchar("apple_email", { length: 255 }).unique().notNull(), + fullName: varchar("full_name", { length: 100 }), pfpURL: varchar("pfp_url", { length: 255 }), pushToken: varchar("pushToken", { length: 255 }), - refreshToken: varchar("refreshToken", { length: 255 }), - lastLogin: timestamp("last_login", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }) .default(sql`CURRENT_TIMESTAMP`) .notNull(), diff --git a/src/server/functions.ts b/src/server/functions.ts index 8be0045..20c889d 100755 --- a/src/server/functions.ts +++ b/src/server/functions.ts @@ -2,9 +2,9 @@ import 'server-only'; import { db } from '~/server/db'; import * as schema from '~/server/db/schema'; import { eq, and, or, sql } from 'drizzle-orm'; -import { pgEnum } from 'drizzle-orm/pg-core'; import jwt from 'jsonwebtoken'; -import { inArray } from 'drizzle-orm/sql'; +//import { pgEnum } from 'drizzle-orm/pg-core'; +//import { inArray } from 'drizzle-orm/sql'; // --- Helper Functions --- // @@ -63,48 +63,7 @@ export const ensureRelationshipExistsByRelationshipId = async (relationshipId: n * Handles both directions of a relationship (userId => partnerId or partnerId => userId). * Optionally checks relationship status. */ -export const ensureRelationshipExistsOld = async (userId: number, partnerId: number, status?: 'pending' | 'accepted') => { - try { - // Ensure bidirectional relationship (user1 <-> user2 or user2 <-> user1) - const relationship = await db.select({ - relationshipId: schema.userRelationships.relationshipId, - status: schema.relationships.status, - }) - .from(schema.userRelationships) - .leftJoin( - schema.relationships, - eq(schema.userRelationships.relationshipId, schema.relationships.id) - ) - .where(or( - and( - eq(schema.userRelationships.userId, userId), - eq(schema.userRelationships.userId, partnerId) // Check if userId -> partnerId - ), - and( - eq(schema.userRelationships.userId, partnerId), - eq(schema.userRelationships.userId, userId) // Check if partnerId -> userId (reverse relationship) - ) - )); - - if (!relationship.length) { - throw new Error('Relationship does not exist'); - } - - if (status && relationship[0]?.status !== status) { - throw new Error(`Relationship is not in ${status} status`); - } - - return relationship[0]; - } catch (error) { - if (error instanceof Error) { - throw new Error(`Error checking relationship: ${error.message}`); - } else { - throw new Error("Unknown error occurred while checking relationship"); - } - } -}; - -export const ensureRelationshipExists = async (userId: number, partnerId: number) => { +export const ensureRelationshipExistsByUserIds = async (userId: number, partnerId: number) => { try { // Ensure bidirectional relationship (user1 <-> user2 or user2 <-> user1) const relationship = await db.select({ @@ -160,10 +119,10 @@ export const getUserById = async (userId: number) => { } }; -export const getUserByUsername = async (username: string) => { +export const getUserByAppleEmail = async (appleEmail: string) => { try { const user = await db.select().from(schema.users) - .where(eq(schema.users.username, username)); + .where(eq(schema.users.appleEmail, appleEmail)); if (user.length === 0) throw new Error('User not found'); return user[0]; @@ -177,25 +136,24 @@ export const getUserByUsername = async (username: string) => { }; export const createUser = async ( - username: string, email: string, passwordHash: string, - name: string, pfpURL = "", pushToken = "" + appleId: string, appleEmail: string, + fullName: string, pfpURL = "", pushToken = "" ) => { try { - if (!username || !email || !passwordHash || !name) { + if (!appleId || !appleEmail || !fullName || !pushToken) { throw new Error("Error: All required fields must be filled"); } // Check if username or email is already taken const existingUser = await db.select().from(schema.users) - .where(or(eq(schema.users.username, username), eq(schema.users.email, email))); + .where(or(eq(schema.users.appleId, appleId), eq(schema.users.appleEmail, appleEmail))); if (existingUser.length > 0) { throw new Error("Username or email is already in use"); } const newUser = await db.insert(schema.users).values({ - username, email, passwordHash, name, pfpURL, pushToken, - lastLogin: new Date(), + appleId, appleEmail, fullName, pfpURL, pushToken }).returning(); return newUser; @@ -208,37 +166,6 @@ export const createUser = async ( } }; -export const changePassword = async ( - userId: number, oldPasswordHash: string, newPasswordHash: string -) => { - try { - // Ensure all arguments are provided - if (!oldPasswordHash || !newPasswordHash) throw new Error("Password fields are required"); - if (oldPasswordHash === newPasswordHash) - throw new Error("New password cannot be the same as the old password"); - - const user = await ensureUserExists(userId); - - // Validate old password - if (user?.passwordHash !== oldPasswordHash) { - throw new Error("Old password does not match"); - } - - // Update with the new password hash - await db.update(schema.users) - .set({ passwordHash: newPasswordHash }) - .where(eq(schema.users.id, userId)); - - return { success: true }; - } catch (error) { - if (error instanceof Error) { - throw new Error(`Failed to change password: ${error.message}`); - } else { - throw new Error("Unknown error occurred while changing password"); - } - } -}; - export const updateUserPFP = async (userId: number, pfpURL: string) => { try { await db.update(schema.users) @@ -271,88 +198,6 @@ export const updateUserPushToken = async (userId: number, pushToken: string) => } }; -export const login = async (username: string, passwordHash: string) => { - try { - const user = await getUserByUsername(username); - if (user?.passwordHash !== passwordHash) { - throw new Error("Invalid password"); - } - - const accessToken = jwt.sign({ userId: user.id }, process.env.JWT_SECRET!, - {expiresIn: '15m' }); - const refreshToken = jwt.sign({ userId: user.id }, process.env.JWT_REFRESH_SECRET!, - {expiresIn: '7d' }); - - // Update last login timestamp - await db.update(schema.users) - .set({ lastLogin: new Date() }) - .where(eq(schema.users.id, user.id)); - - await db.update(schema.users) - .set({ refreshToken: refreshToken }) - .where(eq(schema.users.id, user.id)); - - return { user, accessToken, refreshToken }; - } catch (error) { - if (error instanceof Error) { - throw new Error(`Failed to Log in: ${error.message}`); - } else { - throw new Error("Unknown error occurred while logging in"); - } - } -}; - -export const refreshToken = async (refreshToken: string) => { - try { - const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET!) as { userId: number }; - if (!decoded.userId) - throw new Error("Invalid refresh token"); - const user = await getUserById(decoded.userId); - if (!user || user.refreshToken !== refreshToken) - throw new Error("Invalid refresh token"); - const newAccessToken = jwt.sign({ userId: user.id }, process.env.JWT_SECRET!, - {expiresIn: '15m' }); - const newRefreshToken = jwt.sign({ userId: user.id }, process.env.JWT_REFRESH_SECRET!, - {expiresIn: '7d' }); - await db.update(schema.users) - .set({ refreshToken: newRefreshToken }) - .where(eq(schema.users.id, user.id)); - - return { accessToken: newAccessToken, refreshToken: newRefreshToken }; - } catch (error) { - if (error instanceof Error) { - throw new Error(`Failed to refresh token: ${error.message}`); - } else { - throw new Error("Unknown error occurred while refreshing token"); - } - } -}; - -export const logout = async (refreshToken: string) => { - try { - const user = await db.select() - .from(schema.users) - .where(eq(schema.users.refreshToken, refreshToken)) - .limit(1); - - if (user.length === 0 || !user[0]?.id) { - throw new Error('No user found with this refresh token'); - } - - await db.update(schema.users) - .set({ refreshToken: null }) - .where(eq(schema.users.id, user[0].id)); - - return { success: true }; - } catch (error) { - if (error instanceof Error) { - throw new Error(`Failed to logout: ${error.message}`); - } else { - throw new Error("Unknown error occurred while logging out"); - } - } -}; - // --- Relationship Management Functions --- // export const createRelationshipRequest = async (requestorId: number, requestedId: number) => { @@ -463,7 +308,7 @@ export const sendMessage = async ( await ensureUserExists(senderId); await ensureUserExists(receiverId); - await ensureRelationshipExists(senderId, receiverId); + await ensureRelationshipExistsByUserIds(senderId, receiverId); // Insert the new message const message = await db.insert(schema.messages).values({ @@ -481,7 +326,6 @@ export const sendMessage = async ( type: mediaType, }); } - return message; } catch (error) { if (error instanceof Error) { @@ -495,7 +339,7 @@ export const sendMessage = async ( export const fetchMessages = async (userId: number, partnerId: number) => { try { await ensureUserExists(userId); - await ensureRelationshipExists(userId, partnerId); + await ensureRelationshipExistsByUserIds(userId, partnerId); const messages = await db.select().from(schema.messages) .where(or(