refactor: Enhance type safety for database queries in delete and download routes

This commit is contained in:
2025-10-16 11:20:08 +02:00
parent 966450a2de
commit cf72ed90e7
2 changed files with 21 additions and 7 deletions

View File

@@ -1,6 +1,15 @@
import { NextResponse } from 'next/server'; import { NextResponse } from 'next/server';
import pool from '@/lib/db'; import pool from '@/lib/db';
import bcrypt from 'bcrypt'; import bcrypt from 'bcrypt';
import { RowDataPacket, ResultSetHeader } from 'mysql2/promise';
interface FileData extends RowDataPacket {
token_hash: string;
}
interface FilePart extends RowDataPacket {
discord_message_id: string | null;
}
if (!process.env.DISCORD_BOT_TOKEN || !process.env.DISCORD_CHANNEL_ID) { if (!process.env.DISCORD_BOT_TOKEN || !process.env.DISCORD_CHANNEL_ID) {
throw new Error('Discord bot token or channel ID is not configured'); throw new Error('Discord bot token or channel ID is not configured');
@@ -17,8 +26,8 @@ export async function POST(request: Request) {
const connection = await pool.getConnection(); const connection = await pool.getConnection();
try { try {
// 1. Fetch file and validate token // 1. Fetch file and validate token
const [fileRows]: any[] = await connection.query('SELECT * FROM files WHERE id = ? AND deleted = 0', [file_id]); const [fileRows]: [RowDataPacket[], unknown] = await connection.query('SELECT * FROM files WHERE id = ? AND deleted = 0', [file_id]);
const file = fileRows[0]; const file = fileRows[0] as FileData;
if (!file) { if (!file) {
return NextResponse.json({ error: 'File not found' }, { status: 404 }); return NextResponse.json({ error: 'File not found' }, { status: 404 });
@@ -30,13 +39,13 @@ export async function POST(request: Request) {
} }
// 2. Fetch all message IDs for the file parts // 2. Fetch all message IDs for the file parts
const [partsRows]: any[] = await connection.query( const [partsRows]: [RowDataPacket[], unknown] = await connection.query(
'SELECT discord_message_id FROM file_parts WHERE file_id = ?', 'SELECT discord_message_id FROM file_parts WHERE file_id = ?',
[file_id] [file_id]
); );
// 3. Delete each message from Discord sequentially to avoid rate limits // 3. Delete each message from Discord sequentially to avoid rate limits
for (const part of partsRows) { for (const part of partsRows[0] as FilePart[]) {
if (!part.discord_message_id) continue; if (!part.discord_message_id) continue;
const deleteUrl = `https://discord.com/api/v10/channels/${process.env.DISCORD_CHANNEL_ID}/messages/${part.discord_message_id}`; const deleteUrl = `https://discord.com/api/v10/channels/${process.env.DISCORD_CHANNEL_ID}/messages/${part.discord_message_id}`;

View File

@@ -1,11 +1,16 @@
import { NextResponse } from 'next/server'; import { NextResponse } from 'next/server';
import pool from '@/lib/db'; import pool from '@/lib/db';
import { RowDataPacket } from 'mysql2/promise';
interface FilePart extends RowDataPacket {
discord_message_id: string | null;
}
if (!process.env.DISCORD_BOT_TOKEN || !process.env.DISCORD_CHANNEL_ID) { if (!process.env.DISCORD_BOT_TOKEN || !process.env.DISCORD_CHANNEL_ID) {
throw new Error('Discord bot token or channel ID is not configured'); throw new Error('Discord bot token or channel ID is not configured');
} }
export async function GET(request: Request, context: any) { export async function GET(request: Request, { params }: { params: { file_id: string; part_index: string; } }) {
try { try {
const params = await context.params; const params = await context.params;
const file_id = params.file_id as string; const file_id = params.file_id as string;
@@ -19,11 +24,11 @@ export async function GET(request: Request, context: any) {
const connection = await pool.getConnection(); const connection = await pool.getConnection();
let part; let part;
try { try {
const [partsRows]: any[] = await connection.query( const [partsRows]: [RowDataPacket[], unknown] = await connection.query(
'SELECT discord_message_id FROM file_parts WHERE file_id = ? AND part_index = ?', 'SELECT discord_message_id FROM file_parts WHERE file_id = ? AND part_index = ?',
[file_id, part_index] [file_id, part_index]
); );
part = partsRows[0]; part = partsRows[0] as FilePart;
} finally { } finally {
connection.release(); connection.release();
} }