Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions apps/app/src/actions/files/upload-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,35 @@ const uploadAttachmentSchema = z.object({
export const uploadFile = async (input: z.infer<typeof uploadAttachmentSchema>) => {
logger.info(`[uploadFile] Starting upload for ${input.fileName}`);
try {
// Check if S3 client is available
if (!s3Client) {
logger.error('[uploadFile] S3 client not initialized - check environment variables');
return {
success: false,
error: 'File upload service is currently unavailable. Please contact support.',
} as const;
}

if (!BUCKET_NAME) {
logger.error('[uploadFile] S3 bucket name not configured');
return {
success: false,
error: 'File upload service is not properly configured.',
} as const;
}

const { fileName, fileType, fileData, entityId, entityType, pathToRevalidate } =
uploadAttachmentSchema.parse(input);

const session = await auth.api.getSession({ headers: await headers() });
const organizationId = session?.session.activeOrganizationId;

if (!organizationId) {
throw new Error('Not authorized - no organization found');
logger.error('[uploadFile] Not authorized - no organization found');
return {
success: false,
error: 'Not authorized - no organization found',
} as const;
}

logger.info(`[uploadFile] Starting upload for ${fileName} in org ${organizationId}`);
Expand All @@ -59,7 +80,13 @@ export const uploadFile = async (input: z.infer<typeof uploadAttachmentSchema>)
const MAX_FILE_SIZE_MB = 10;
const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
if (fileBuffer.length > MAX_FILE_SIZE_BYTES) {
throw new Error(`File exceeds the ${MAX_FILE_SIZE_MB}MB limit.`);
logger.warn(
`[uploadFile] File size ${fileBuffer.length} exceeds the ${MAX_FILE_SIZE_MB}MB limit.`,
);
return {
success: false,
error: `File exceeds the ${MAX_FILE_SIZE_MB}MB limit.`,
} as const;
}

const timestamp = Date.now();
Expand Down
29 changes: 19 additions & 10 deletions apps/app/src/app/s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,42 @@ const redact = (value?: string) => {
};

try {
console.log('[S3] Initializing S3 Client');
console.error('--- Provided Configuration ---');
console.error(`APP_AWS_REGION: ${APP_AWS_REGION}`);
console.error(`APP_AWS_ACCESS_KEY_ID: ${redact(APP_AWS_ACCESS_KEY_ID)}`);
console.error(`APP_AWS_SECRET_ACCESS_KEY: ${redact(APP_AWS_SECRET_ACCESS_KEY)}`);
console.error(`APP_AWS_BUCKET_NAME: ${BUCKET_NAME}`);
console.error('-----------------------------');

if (!APP_AWS_ACCESS_KEY_ID || !APP_AWS_SECRET_ACCESS_KEY || !BUCKET_NAME || !APP_AWS_REGION) {
console.error('[S3] AWS S3 credentials or configuration missing. Check environment variables.');
throw new Error('AWS S3 credentials or configuration missing. Check environment variables.');
}

console.log('[S3] AWS S3 credentials or configuration found. Initializing S3 Client');

s3ClientInstance = new S3Client({
region: APP_AWS_REGION,
credentials: {
accessKeyId: APP_AWS_ACCESS_KEY_ID,
secretAccessKey: APP_AWS_SECRET_ACCESS_KEY,
},
});

console.log('[S3] S3 Client initialized successfully');
} catch (error) {
console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
console.error('!!! FAILED TO INITIALIZE S3 CLIENT !!!');
console.error('!!! This is likely due to missing or invalid environment variables. !!!');
console.error('--- Provided Configuration ---');
console.error(`APP_AWS_REGION: ${APP_AWS_REGION}`);
console.error(`APP_AWS_ACCESS_KEY_ID: ${redact(APP_AWS_ACCESS_KEY_ID)}`);
console.error(`APP_AWS_SECRET_ACCESS_KEY: ${redact(APP_AWS_SECRET_ACCESS_KEY)}`);
console.error(`APP_AWS_BUCKET_NAME: ${BUCKET_NAME}`);
console.error('-----------------------------');
console.error('Error:', error);
console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
// Prevent the app from continuing without a valid S3 client
// In a real-world scenario, you might have a fallback or a dummy client.
// For now, we re-throw to make the crash explicit.
throw error;

// Create a dummy client that will fail gracefully at runtime instead of crashing during initialization
s3ClientInstance = null as any;
console.error(
'[S3] Creating dummy S3 client - file uploads will fail until credentials are fixed',
);
}

export const s3Client = s3ClientInstance;
Expand Down
Loading