missions s3
This commit is contained in:
parent
2be6e130e9
commit
f5d719ecc1
@ -2,6 +2,7 @@ import { NextResponse } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from "@/app/api/auth/options";
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { getPublicUrl, S3_CONFIG } from '@/lib/s3';
|
||||
|
||||
// Helper function to check authentication
|
||||
async function checkAuth(request: Request) {
|
||||
@ -60,7 +61,13 @@ export async function GET(request: Request, props: { params: Promise<{ missionId
|
||||
}
|
||||
});
|
||||
|
||||
return NextResponse.json(attachments);
|
||||
// Add public URLs to attachments
|
||||
const attachmentsWithUrls = attachments.map(attachment => ({
|
||||
...attachment,
|
||||
publicUrl: getPublicUrl(attachment.filePath, S3_CONFIG.missionsBucket)
|
||||
}));
|
||||
|
||||
return NextResponse.json(attachmentsWithUrls);
|
||||
} catch (error) {
|
||||
console.error('Error fetching mission attachments:', error);
|
||||
return NextResponse.json({
|
||||
|
||||
@ -3,7 +3,7 @@ import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from "@/app/api/auth/options";
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { deleteMissionLogo } from '@/lib/mission-uploads';
|
||||
import { getPublicUrl } from '@/lib/s3';
|
||||
import { getPublicUrl, S3_CONFIG } from '@/lib/s3';
|
||||
|
||||
// Helper function to check authentication
|
||||
async function checkAuth(request: Request) {
|
||||
@ -82,10 +82,10 @@ export async function GET(request: Request, props: { params: Promise<{ missionId
|
||||
// Add public URLs to mission logo and attachments
|
||||
const missionWithUrls = {
|
||||
...mission,
|
||||
logoUrl: mission.logo ? getPublicUrl(mission.logo) : null,
|
||||
logoUrl: mission.logo ? getPublicUrl(mission.logo, S3_CONFIG.missionsBucket) : null,
|
||||
attachments: mission.attachments.map((attachment: { id: string; filename: string; filePath: string; fileType: string; fileSize: number; createdAt: Date }) => ({
|
||||
...attachment,
|
||||
publicUrl: getPublicUrl(attachment.filePath)
|
||||
publicUrl: getPublicUrl(attachment.filePath, S3_CONFIG.missionsBucket)
|
||||
}))
|
||||
};
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from "@/app/api/auth/options";
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { getPublicUrl } from '@/lib/s3';
|
||||
import { S3_CONFIG } from '@/lib/s3';
|
||||
|
||||
// Helper function to check authentication
|
||||
async function checkAuth(request: Request) {
|
||||
@ -86,7 +87,7 @@ export async function GET(request: Request) {
|
||||
// Transform logo paths to public URLs
|
||||
const missionsWithPublicUrls = missions.map(mission => ({
|
||||
...mission,
|
||||
logo: mission.logo ? getPublicUrl(mission.logo) : null
|
||||
logo: mission.logo ? getPublicUrl(mission.logo, S3_CONFIG.missionsBucket) : null
|
||||
}));
|
||||
|
||||
return NextResponse.json({
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
generateMissionLogoUploadUrl,
|
||||
generateMissionAttachmentUploadUrl
|
||||
} from '@/lib/mission-uploads';
|
||||
import { getPublicUrl } from '@/lib/s3';
|
||||
import { getPublicUrl, S3_CONFIG } from '@/lib/s3';
|
||||
|
||||
// Helper function to check authentication
|
||||
async function checkAuth(request: Request) {
|
||||
@ -148,7 +148,7 @@ export async function POST(request: Request) {
|
||||
console.log('Logo uploaded successfully to path:', filePath);
|
||||
|
||||
// Generate public URL
|
||||
const publicUrl = getPublicUrl(filePath);
|
||||
const publicUrl = getPublicUrl(filePath, S3_CONFIG.missionsBucket);
|
||||
console.log('Public URL for logo:', publicUrl);
|
||||
|
||||
// Update mission record with logo path
|
||||
@ -184,7 +184,7 @@ export async function POST(request: Request) {
|
||||
console.log('Attachment uploaded successfully to path:', filePath);
|
||||
|
||||
// Generate public URL
|
||||
const publicUrl = getPublicUrl(filePath);
|
||||
const publicUrl = getPublicUrl(filePath, S3_CONFIG.missionsBucket);
|
||||
console.log('Public URL for attachment:', publicUrl);
|
||||
|
||||
// Create attachment record in database
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { s3Client, putObject, generatePresignedUrl, S3_CONFIG, deleteObject } from '@/lib/s3';
|
||||
import { PutObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
||||
|
||||
/**
|
||||
* Utilities for mission-related file uploads using Minio
|
||||
@ -39,18 +40,18 @@ export async function uploadMissionLogo(
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
console.log('Buffer created, size:', buffer.length);
|
||||
|
||||
// Upload to Minio
|
||||
console.log('Creating S3 command with bucket:', S3_CONFIG.bucket);
|
||||
// Upload to Minio using the missions bucket
|
||||
console.log('Creating S3 command with bucket:', S3_CONFIG.missionsBucket);
|
||||
console.log('S3 config:', {
|
||||
endpoint: S3_CONFIG.endpoint || 'MISSING!',
|
||||
region: S3_CONFIG.region || 'MISSING!',
|
||||
bucket: S3_CONFIG.bucket || 'MISSING!',
|
||||
bucket: S3_CONFIG.missionsBucket || 'MISSING!',
|
||||
hasAccessKey: !!S3_CONFIG.accessKey || 'MISSING!',
|
||||
hasSecretKey: !!S3_CONFIG.secretKey || 'MISSING!'
|
||||
});
|
||||
|
||||
const command = new PutObjectCommand({
|
||||
Bucket: S3_CONFIG.bucket,
|
||||
Bucket: S3_CONFIG.missionsBucket,
|
||||
Key: filePath,
|
||||
Body: buffer,
|
||||
ContentType: file.type,
|
||||
@ -92,9 +93,9 @@ export async function uploadMissionAttachment(
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const buffer = Buffer.from(arrayBuffer);
|
||||
|
||||
// Upload to Minio
|
||||
// Upload to Minio using missions bucket
|
||||
const command = new PutObjectCommand({
|
||||
Bucket: S3_CONFIG.bucket,
|
||||
Bucket: S3_CONFIG.missionsBucket,
|
||||
Key: filePath,
|
||||
Body: buffer,
|
||||
ContentType: file.type,
|
||||
@ -114,6 +115,21 @@ export async function uploadMissionAttachment(
|
||||
}
|
||||
}
|
||||
|
||||
// Generate presigned URL for missions bucket
|
||||
async function generateMissionPresignedUrl(key: string, expiresIn = 3600): Promise<string> {
|
||||
try {
|
||||
const command = new PutObjectCommand({
|
||||
Bucket: S3_CONFIG.missionsBucket,
|
||||
Key: key
|
||||
});
|
||||
|
||||
return await getSignedUrl(s3Client, command, { expiresIn });
|
||||
} catch (error) {
|
||||
console.error('Error generating presigned URL for missions bucket:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate presigned URL for direct browser upload of mission logo
|
||||
export async function generateMissionLogoUploadUrl(
|
||||
userId: string,
|
||||
@ -126,7 +142,7 @@ export async function generateMissionLogoUploadUrl(
|
||||
}> {
|
||||
try {
|
||||
const filePath = getMissionLogoPath(userId, missionId, fileExtension);
|
||||
const uploadUrl = await generatePresignedUrl(filePath, expiresIn);
|
||||
const uploadUrl = await generateMissionPresignedUrl(filePath, expiresIn);
|
||||
|
||||
return { uploadUrl, filePath };
|
||||
} catch (error) {
|
||||
@ -147,7 +163,7 @@ export async function generateMissionAttachmentUploadUrl(
|
||||
}> {
|
||||
try {
|
||||
const filePath = getMissionAttachmentPath(userId, missionId, filename);
|
||||
const uploadUrl = await generatePresignedUrl(filePath, expiresIn);
|
||||
const uploadUrl = await generateMissionPresignedUrl(filePath, expiresIn);
|
||||
|
||||
return { uploadUrl, filePath };
|
||||
} catch (error) {
|
||||
@ -156,10 +172,26 @@ export async function generateMissionAttachmentUploadUrl(
|
||||
}
|
||||
}
|
||||
|
||||
// Delete object from missions bucket
|
||||
async function deleteMissionObject(key: string): Promise<boolean> {
|
||||
try {
|
||||
const command = new DeleteObjectCommand({
|
||||
Bucket: S3_CONFIG.missionsBucket,
|
||||
Key: key
|
||||
});
|
||||
|
||||
await s3Client.send(command);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error deleting mission object:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete mission attachment from Minio
|
||||
export async function deleteMissionAttachment(filePath: string): Promise<boolean> {
|
||||
try {
|
||||
await deleteObject(filePath);
|
||||
await deleteMissionObject(filePath);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error deleting mission attachment:', error);
|
||||
@ -170,7 +202,7 @@ export async function deleteMissionAttachment(filePath: string): Promise<boolean
|
||||
// Delete mission logo from Minio
|
||||
export async function deleteMissionLogo(filePath: string): Promise<boolean> {
|
||||
try {
|
||||
await deleteObject(filePath);
|
||||
await deleteMissionObject(filePath);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error deleting mission logo:', error);
|
||||
|
||||
@ -20,6 +20,7 @@ export const S3_CONFIG = {
|
||||
endpoint: process.env.MINIO_S3_UPLOAD_BUCKET_URL,
|
||||
region: process.env.MINIO_AWS_REGION,
|
||||
bucket: process.env.MINIO_AWS_S3_UPLOAD_BUCKET_NAME,
|
||||
missionsBucket: process.env.MINIO_MISSIONS_BUCKET || 'missions',
|
||||
accessKey: process.env.MINIO_ACCESS_KEY || process.env.AWS_ACCESS_KEY_ID,
|
||||
secretKey: process.env.MINIO_SECRET_KEY || process.env.AWS_SECRET_ACCESS_KEY,
|
||||
}
|
||||
@ -247,7 +248,7 @@ export async function generatePresignedUrl(key: string, expiresIn = 3600) {
|
||||
}
|
||||
|
||||
// Generate a public URL for a file stored in Minio/S3
|
||||
export function getPublicUrl(filePath: string): string {
|
||||
export function getPublicUrl(filePath: string, bucketName?: string): string {
|
||||
if (!filePath) return '';
|
||||
if (filePath.startsWith('http')) return filePath; // Already a full URL
|
||||
|
||||
@ -269,9 +270,11 @@ export function getPublicUrl(filePath: string): string {
|
||||
}
|
||||
}
|
||||
|
||||
// Determine which bucket to use
|
||||
const bucket = bucketName || S3_CONFIG.bucket;
|
||||
|
||||
// Construct the full URL using the standard approach
|
||||
const endpoint = S3_CONFIG.endpoint?.replace(/\/$/, ''); // Remove trailing slash if present
|
||||
const bucket = S3_CONFIG.bucket;
|
||||
|
||||
console.log('S3 Config for URL generation:', {
|
||||
endpoint,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user