From 06c151ba9f82b77a4702632c0a1d42c6cf5b1ab1 Mon Sep 17 00:00:00 2001 From: gibbyb Date: Fri, 11 Oct 2024 15:52:25 -0500 Subject: [PATCH] update apis. a complete mess now. will refactor or maybe even rewrite later --- package.json | 1 + pnpm-lock.yaml | 10 ++ ...87c84c17a4d360c75b9.0102_1728672056503.jpg | Bin 0 -> 40338 bytes public/uploads/profile-pictures/madeline.jpg | Bin 0 -> 17391 bytes .../checkStatusByAppleId/route.ts | 27 +++++ src/app/api/users/updatePFP/route.ts | 38 ------- src/app/api/users/updatePfp/route.ts | 92 +++++++++++++++++ .../users/{updatePFP => updatePfp}/page.tsx | 48 +++++---- src/env.js | 10 +- src/server/functions.ts | 97 +++++++++++++++++- undotree_2 | 3 + 11 files changed, 262 insertions(+), 64 deletions(-) create mode 100644 public/uploads/profile-pictures/001048.90e6fe2945c1487c84c17a4d360c75b9.0102_1728672056503.jpg create mode 100755 public/uploads/profile-pictures/madeline.jpg create mode 100644 src/app/api/relationships/checkStatusByAppleId/route.ts delete mode 100644 src/app/api/users/updatePFP/route.ts create mode 100644 src/app/api/users/updatePfp/route.ts rename src/app/users/{updatePFP => updatePfp}/page.tsx (59%) create mode 100644 undotree_2 diff --git a/package.json b/package.json index b3fb943..73abd81 100755 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@t3-oss/env-nextjs": "^0.10.1", + "@types/formidable": "^3.4.5", "drizzle-orm": "^0.33.0", "geist": "^1.3.1", "jsonwebtoken": "^9.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 247ce92..aeedb9a 100755 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@t3-oss/env-nextjs': specifier: ^0.10.1 version: 0.10.1(typescript@5.6.2)(zod@3.23.8) + '@types/formidable': + specifier: ^3.4.5 + version: 3.4.5 drizzle-orm: specifier: ^0.33.0 version: 0.33.0(@types/react@18.3.11)(postgres@3.4.4)(react@18.3.1) @@ -541,6 +544,9 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/formidable@3.4.5': + resolution: {integrity: sha512-s7YPsNVfnsng5L8sKnG/Gbb2tiwwJTY1conOkJzTMRvJAlLFW1nEua+ADsJQu8N1c0oTHx9+d5nqg10WuT9gHQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -2413,6 +2419,10 @@ snapshots: '@types/estree@1.0.6': {} + '@types/formidable@3.4.5': + dependencies: + '@types/node': 20.16.10 + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} diff --git a/public/uploads/profile-pictures/001048.90e6fe2945c1487c84c17a4d360c75b9.0102_1728672056503.jpg b/public/uploads/profile-pictures/001048.90e6fe2945c1487c84c17a4d360c75b9.0102_1728672056503.jpg new file mode 100644 index 0000000000000000000000000000000000000000..126a57fe2f34398cb89b5355fc80e38b13b4161d GIT binary patch literal 40338 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�DrkfC~Z@{ z=-wr~dtVh>X;%w;(7`6hmIdguN0MWi0SkUqXfAbA3(RGXFqaZMYn%{)M4_>UR|UrmjmFme z=KY(rc|1qrSTw2MY;usGV3x@^0|VUP*XsAdkJ_{0PsINK0sjEPabbRtT0n)b1i9Z6 zp~C_`@jieI@+;x7@vGrZtMSD?A$&5^qtoNLna#^2i6m1tK}o#41&UM2a2SK%4U%?( zcWOxDqgHW?roKj}?Mv{!&%%OR3zUgbq5yRH$6OWb^gWG!D|pYs@!0AzJ&?dGPBUM# z-?lHrOJ5#A1@unYiZFy0CkotxJ9j-R@_$_h@>Uc70IV6o{_r2xsn&F7c%9U!eP)V< zWvSrJYjqGg9DCJA`$%jQ{&m~kz)2*1;oH`;OG19|Ij>3;)RoT~wiZ-hERX-x{D{{P zCDLb&doF(?ny29znoT7FoNZ?Qb*bS6wUEnjSF0kCm0xrBN4WyLsZ>y=C>)b$Ks5O3r62aT^RAb<1a<_wV$tW$~xPeP_ga zyc&eB_9!eP`!<_nZ;>6PxENTY1F0Z<%z0yy-Emyq?~6P|;^;+|yhZ3t5hU2$yl`Zf z?=T*Ok?mgxo8#3g;DZ+IyZ{3Zp5;fkuS(UiQ+0V`6bH;( zl2I7v1m|utd*mAC?ye<{?FO4GN>dGl7>JR`>M(KG9&7E-fZq-Dy=%a5_>BJ)MOEZ@|gp9dHck+IP1%nE>|f&#`(=?#+q{I&KFhEAK~}H$h2p|-Rl=E zEW^K+xBz}w{LOMUDRU=;bqi?KpX~C(DFC0kLk1We9!j2iSKo)>2Z4NFqDA6A9o@(o zqS~-VRd%T?RIXIE;tqJ|Lf4@9bK%Fr{{Rf>62+nD(um}YmX`Kjfr@?fW<5fJK?Byi zuyiWUnyEFcwfp}7;2$l8##5yWy=2|b%v}TEPP_4kQIo?Af(ug+^JSS`B8-*Zo0$P_ zahxuHoq2zaKVUzL{s&jqtn4i{-7+@$q|+uh44`$)P8LFO)GDzR`!{QU{k7v8O)_|` zVYHIz14RMhm0@6`0|bOBN$fuw?rnTwd#$z7!DhVPMQE+MpE8R1uhjl%wZDZHT1LNbac6Yk%E>kgfDq&`P<_6Y=)N?!xzhYY zDT|b5+@J0@BlI=&$L)z};k$p@0_qm=2@;;CRQkW5hX4g_mU<(sRBQ6Tb!ZQ*;P#By8k&tol z--di6FO5814vVAPJAI<*ZP8?P3^x*TK*7R*N%S3Shc2CYxhYX`v+LK;RjSaolRcyM zVfZ=VZD+)jc>ew*?EkrJ)EW9CJcLd9fd<1By@zWunbudX!PU$mdI>M;%cD3u&= zImy5ynvcT&01vd^h8hgM8_}X^WW9ej>SuGyEBn>Jd=#)X$pJ)0G!sDzlBv%9ERrsaf}W#+dq%3d9u&3G0`RWf5AFF zr3PjH0KyGvJ>xdDt=mTOWs1hFAi?SZ%JlkIqxgTp9v9QC3=>`(+e?*iHa0+EWI0v^ zTR8+AFg#CJPWoeKFgf^^Ege zRQH{|3s_ofq4EC!#h>^m{{Vxgmg~h|3*{E}vBfO%Y14U**-%(5yCEkHfƮ_xr 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∾Veh75A7(r%Y3*l)dqj1hus@=_o8 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 literal 0 HcmV?d00001 diff --git a/public/uploads/profile-pictures/madeline.jpg b/public/uploads/profile-pictures/madeline.jpg new file mode 100755 index 0000000000000000000000000000000000000000..396d7b68f719f109d7e10e6a6288f3724d719f1f GIT binary patch literal 17391 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 { + const middlewareResponse = await middleware(request); + if (middlewareResponse) return middlewareResponse; + + const appleId = request.nextUrl.searchParams.get('appleId'); + + if (!appleId) { + return NextResponse.json({ message: "Missing required fields" }, { status: 400 }); + } + + try { + const relationship = await checkRelationshipStatusByAppleId(appleId); + const partner = await getPartnerByAppleId(appleId); + + return NextResponse.json({ relationship, partner }); + } catch (error) { + if (error instanceof Error) { + return NextResponse.json({ message: error.message }, { status: 404 }); + } + return NextResponse.json({ message: "Error fetching relationship status" }, { status: 500 }); + } +}; diff --git a/src/app/api/users/updatePFP/route.ts b/src/app/api/users/updatePFP/route.ts deleted file mode 100644 index a4a3b9f..0000000 --- a/src/app/api/users/updatePFP/route.ts +++ /dev/null @@ -1,38 +0,0 @@ -"use server"; -import { NextResponse } from "next/server"; -import type { NextRequest } from "next/server"; -import { updateUserPFP } from "~/server/functions"; -import { middleware } from "~/middleware"; - -type UpdatePfpRequest = { - userId: number; - pfpURL: string; -} - -export async function POST(request: NextRequest) { - const middlewareResponse = await middleware(request); - if (middlewareResponse) return middlewareResponse; - try { - const { userId, pfpURL } = await request.json() as UpdatePfpRequest; - console.log("Received request:", { userId, pfpURL }); - - if (!userId || !pfpURL || isNaN(userId)) - return NextResponse.json({ message: "Missing required fields" }, { status: 400 }); - - console.log("Updating profile picture for user:", userId); - const result = await updateUserPFP(userId, pfpURL); - - if (result.success) { - console.log("Profile picture updated successfully"); - return NextResponse.json({ message: "Profile picture updated successfully" }); - } else { - throw new Error("Failed to update profile picture"); - } - } catch (error) { - console.error("Error in updatePFP:", error); - if (error instanceof Error) { - return NextResponse.json({ message: error.message }, { status: 400 }); - } - return NextResponse.json({ message: "Error updating profile picture" }, { status: 500 }); - } -} diff --git a/src/app/api/users/updatePfp/route.ts b/src/app/api/users/updatePfp/route.ts new file mode 100644 index 0000000..5944612 --- /dev/null +++ b/src/app/api/users/updatePfp/route.ts @@ -0,0 +1,92 @@ +import { NextResponse } from "next/server"; +import type { NextRequest } from "next/server"; +import { updateUserPfpUrl, getUserPfpUrl } from "~/server/functions"; +import { middleware } from "~/middleware"; +import fs from "fs/promises"; +import path from "path"; + +const UPLOAD_DIR = path.resolve(process.cwd(), "public/uploads/profile-pictures"); + +export async function POST(request: NextRequest) { + console.log("Received POST request to /api/users/updatePfp"); + + // Apply middleware + const middlewareResponse = await middleware(request); + if (middlewareResponse) { + console.log("Middleware rejected the request"); + return middlewareResponse; + } + + try { + console.log("Parsing form data..."); + const formData = await request.formData(); + console.log("Form data parsed successfully"); + + const file = formData.get('file') as File | null; + const appleId = formData.get('appleId') as string | null; + + console.log("Received file:", file ? "Yes" : "No"); + console.log("Received appleId:", appleId); + + if (!file || !appleId) { + console.log("File or appleId missing"); + return NextResponse.json({ message: "File or appleId missing." }, { status: 400 }); + } + + // Validate file type + console.log("File type:", file.type); + if (!file.type.startsWith('image/')) { + console.log("Invalid file type"); + return NextResponse.json({ message: "Invalid file type. Only images are allowed." }, { status: 400 }); + } + + // Ensure upload directory exists + console.log("Creating upload directory if it doesn't exist"); + await fs.mkdir(UPLOAD_DIR, { recursive: true }); + + // Generate a unique filename + const fileExtension = path.extname(file.name); + const fileName = `${appleId}_${Date.now()}${fileExtension}`; + const filePath = path.join(UPLOAD_DIR, fileName); + console.log("Generated file path:", filePath); + + // Write file to disk + console.log("Writing file to disk..."); + const buffer = Buffer.from(await file.arrayBuffer()); + await fs.writeFile(filePath, buffer); + console.log("File written successfully"); + + // Get the relative URL for the uploaded file + const pfpURL = `/uploads/profile-pictures/${fileName}`; + console.log("New pfpURL:", pfpURL); + + // Get old pfpURL and remove the old file if it exists + console.log("Fetching old pfpURL..."); + const oldPfpURL = await getUserPfpUrl(appleId); + if (oldPfpURL) { + console.log("Old pfpURL found:", oldPfpURL); + const oldFilePath = path.join(process.cwd(), 'public', oldPfpURL); + console.log("Attempting to delete old file:", oldFilePath); + await fs.unlink(oldFilePath).catch((err) => { + console.log("Error deleting old file:", err.message); + }); + } else { + console.log("No old pfpURL found"); + } + + // Update the user's pfpURL in the database + console.log("Updating user's pfpURL in the database..."); + await updateUserPfpUrl(appleId, pfpURL); + console.log("Database updated successfully"); + + console.log("Sending successful response"); + return NextResponse.json({ message: "Profile picture updated successfully", pfpURL }); + } catch (error) { + console.error("Error in updatePFP:", error); + if (error instanceof Error) { + console.error("Error details:", error.message); + return NextResponse.json({ message: error.message }, { status: 500 }); + } + return NextResponse.json({ message: "Error updating profile picture" }, { status: 500 }); + } +} diff --git a/src/app/users/updatePFP/page.tsx b/src/app/users/updatePfp/page.tsx similarity index 59% rename from src/app/users/updatePFP/page.tsx rename to src/app/users/updatePfp/page.tsx index 448d57c..1ce5bac 100644 --- a/src/app/users/updatePFP/page.tsx +++ b/src/app/users/updatePfp/page.tsx @@ -3,33 +3,45 @@ import React, { useState } from 'react'; export default function TestUpdatePFP() { - const [userId, setUserId] = useState(''); - const [pfpURL, setPfpURL] = useState(''); + const [appleId, setAppleId] = useState(''); + const [file, setFile] = useState(null); const [result, setResult] = useState(null); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setResult(null); + if (!file) { + setResult('Please select a file'); + return; + } + try { - const response = await fetch('/api/users/updatePFP', { + const formData = new FormData(); + formData.append('appleId', appleId); + formData.append('file', file); + + const response = await fetch('/api/users/updatePfp', { method: 'POST', headers: { - 'Content-Type': 'application/json', 'x-api-key': process.env.NEXT_PUBLIC_API_KEY ?? '', }, - body: JSON.stringify({ - userId, - pfpURL - }) + body: formData }); - const data = await response.json() as {message: string} + const data = await response.json(); setResult(JSON.stringify(data, null, 2)); } catch (error) { console.error('Error:', error); setResult('An error occurred'); } }; + + const handleFileChange = (e: React.ChangeEvent) => { + if (e.target.files && e.target.files.length > 0) { + setFile(e.target.files[0]); + } + }; + return (
@@ -37,24 +49,24 @@ export default function TestUpdatePFP() {

Test Update PFP

- + setUserId(e.target.value)} + id="appleId" + value={appleId} + onChange={(e) => setAppleId(e.target.value)} className="border p-2 w-full bg-black" required />
- + setPfpURL(e.target.value)} + type="file" + id="profilepic" + onChange={handleFileChange} className="border p-2 w-full bg-black" + accept="image/*" required />
diff --git a/src/env.js b/src/env.js index 6b80db4..3a65873 100755 --- a/src/env.js +++ b/src/env.js @@ -9,9 +9,10 @@ export const env = createEnv({ NODE_ENV: z .enum(["development", "test", "production"]) .default("development"), - JWT_SECRET: z.string(), - JWT_REFRESH_SECRET: z.string(), + //JWT_SECRET: z.string(), + //JWT_REFRESH_SECRET: z.string(), SKIP_ENV_VALIDATION: z.boolean().optional(), + ROOT_PATH: z.string(), }, client: { @@ -22,10 +23,11 @@ export const env = createEnv({ DATABASE_URL: process.env.DATABASE_URL, API_KEY: process.env.API_KEY, NODE_ENV: process.env.NODE_ENV, - JWT_SECRET: process.env.JWT_SECRET, - JWT_REFRESH_SECRET: process.env.JWT_REFRESH_SECRET, + //JWT_SECRET: process.env.JWT_SECRET, + //JWT_REFRESH_SECRET: process.env.JWT_REFRESH_SECRET, NEXT_PUBLIC_API_KEY: process.env.NEXT_PUBLIC_API_KEY, SKIP_ENV_VALIDATION: process.env.SKIP_ENV_VALIDATION, + ROOT_PATH: process.env.ROOT_PATH, }, skipValidation: !!process.env.SKIP_ENV_VALIDATION, diff --git a/src/server/functions.ts b/src/server/functions.ts index 553e823..d0c0dab 100755 --- a/src/server/functions.ts +++ b/src/server/functions.ts @@ -1,7 +1,7 @@ import 'server-only'; import { db } from '~/server/db'; import * as schema from '~/server/db/schema'; -import { eq, and, or, sql } from 'drizzle-orm'; +import { eq, and, or, sql, not } from 'drizzle-orm'; // --- Helper Functions --- // @@ -20,6 +20,21 @@ export const ensureUserExists = async (userId: number) => { } }; +export const ensureUserExistsByAppleId = async (appleId: string) => { + try { + const user = await db.select().from(schema.users) + .where(eq(schema.users.appleId, appleId)); + + return (user.length > 0) ? user[0] : null; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Error checking user: ${error.message}`); + } else { + throw new Error("Unknown error occurred while checking user"); + } + } +}; + export const ensureRelationshipExistsByRelationshipId = async (relationshipId: number) => { try { const relationship = await db.select({ @@ -168,12 +183,11 @@ export const createUser = async ( } }; -export const updateUserPFP = async (userId: number, pfpURL: string) => { +export const updateUserPfpUrl = async (appleId: string, pfpURL: string) => { try { await db.update(schema.users) .set({ pfpURL }) - .where(eq(schema.users.id, userId)); - + .where(eq(schema.users.appleId, appleId)); return { success: true }; } catch (error) { if (error instanceof Error) { @@ -184,6 +198,20 @@ export const updateUserPFP = async (userId: number, pfpURL: string) => { } }; +export const getUserPfpUrl = async (appleId: string) => { + try { + const user = await db.select().from(schema.users) + .where(eq(schema.users.appleId, appleId)); + return (user.length > 0) ? user[0]?.pfpURL : null; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to fetch user by appleId: ${error.message}`); + } else { + throw new Error("Unknown error occurred while fetching user by appleId"); + } + } +}; + export const updateUserPushToken = async (userId: number, pushToken: string) => { try { await db.update(schema.users) @@ -218,6 +246,67 @@ export const updateUserPushTokenByAppleId = async (appleId: string, pushToken: s // --- Relationship Management Functions --- // +export const checkRelationshipStatusByAppleId = async (appleId: string) => { + try { + await ensureUserExistsByAppleId(appleId); + const user = await getUserByAppleId(appleId); + if (!user) throw new Error("User not found"); + // Check and see if this user is in any relationships + const relationships = await db.select().from(schema.userRelationships) + .where(eq(schema.userRelationships.userId, user.id)); + if (!relationships.length) throw new Error("No relationships found for this user"); + // User can only be in one relationship at a time + const relationship = relationships[0]; + if (!relationship) throw new Error("No relationship found for this user"); + // Check if the relationship is accepted + const relationshipStatus = await db.select().from(schema.relationships) + .where(eq(schema.relationships.id, relationship.relationshipId)); + if (!relationshipStatus.length) throw new Error("Relationship not found"); + if (!relationshipStatus[0]) throw new Error("Relationship not found"); + if (relationshipStatus[0].status !== "accepted") throw new Error("Relationship not accepted"); + else return relationshipStatus[0]; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to check relationship status: ${error.message}`); + } else { + throw new Error("Unknown error occurred while checking relationship status"); + } + } +}; + +export const getPartnerByAppleId = async (appleId: string) => { + try { + const user = await getUserByAppleId(appleId); + if (!user) throw new Error("User not found"); + + const relationship = await checkRelationshipStatusByAppleId(appleId); + if (!relationship) throw new Error("User is not in a relationship"); + + const partnerRelation = await db.select() + .from(schema.userRelationships) + .where( + and( + eq(schema.userRelationships.relationshipId, relationship.id), + not(eq(schema.userRelationships.userId, user.id)) + ) + ); + + if (!partnerRelation.length) throw new Error("Partner not found"); + if (!partnerRelation[0]) throw new Error("Partner not found"); + + const partner = await getUserById(partnerRelation[0].userId); + if (!partner) throw new Error("Partner not found"); + + return partner; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to get partner: ${error.message}`); + } else { + throw new Error("Unknown error occurred while getting partner"); + } + } +}; + export const createRelationshipRequest = async (requestorId: number, requestedId: number) => { try { await ensureUserExists(requestorId); diff --git a/undotree_2 b/undotree_2 new file mode 100644 index 0000000..555f636 --- /dev/null +++ b/undotree_2 @@ -0,0 +1,3 @@ +" Press ? for help. + + * >0< (Original)