port-nimara-client-portal/server/api/files/rename.ts

106 lines
3.4 KiB
TypeScript

import { requireAuth } from '~/server/utils/auth';
import { renameFile, renameFolder } from '~/server/utils/minio';
export default defineEventHandler(async (event) => {
// Check authentication (x-tag header OR Keycloak session)
await requireAuth(event);
try {
const body = await readBody(event);
const { oldName, newName, isFolder } = body;
if (!oldName || !newName) {
throw createError({
statusCode: 400,
statusMessage: 'Both old and new names are required',
});
}
// Protect EOIs folder from renaming
if (oldName === 'EOIs/' || oldName === 'EOIs') {
throw createError({
statusCode: 403,
statusMessage: 'The EOIs folder is protected and cannot be renamed',
});
}
// Validate new name doesn't contain invalid characters
const invalidChars = /[<>:"|?*\\]/g;
if (invalidChars.test(newName)) {
throw createError({
statusCode: 400,
statusMessage: 'File name contains invalid characters',
});
}
// For files, we need to preserve the timestamp prefix and path
let oldPath = oldName;
let newPath = '';
if (!isFolder) {
// Extract the directory path and filename
const lastSlash = oldName.lastIndexOf('/');
const directory = lastSlash > -1 ? oldName.substring(0, lastSlash + 1) : '';
const oldFilename = lastSlash > -1 ? oldName.substring(lastSlash + 1) : oldName;
// Extract timestamp prefix if present
const timestampMatch = oldFilename.match(/^(\d{10,})-(.+)$/);
let timestamp = '';
if (timestampMatch) {
timestamp = timestampMatch[1] + '-';
}
// Preserve file extension
const oldExtIndex = oldFilename.lastIndexOf('.');
const extension = oldExtIndex > -1 ? oldFilename.substring(oldExtIndex) : '';
// Remove extension from new name if user included it
let cleanNewName = newName;
if (newName.endsWith(extension)) {
cleanNewName = newName.substring(0, newName.length - extension.length);
}
// Construct new path with preserved timestamp and extension
newPath = directory + timestamp + cleanNewName + extension;
} else {
// For folders, handle the path construction
const lastSlash = oldName.lastIndexOf('/', oldName.length - 2);
const directory = lastSlash > -1 ? oldName.substring(0, lastSlash + 1) : '';
// Ensure folder name ends with /
const folderName = newName.endsWith('/') ? newName : newName + '/';
newPath = directory + folderName;
}
// Check if new name already exists (you might want to implement this check)
// const exists = await checkFileExists(newPath);
// if (exists) {
// throw createError({
// statusCode: 409,
// statusMessage: 'A file or folder with this name already exists',
// });
// }
// Perform the rename
if (isFolder) {
await renameFolder(oldPath, newPath);
} else {
await renameFile(oldPath, newPath);
}
return {
success: true,
oldPath,
newPath,
message: `Successfully renamed ${isFolder ? 'folder' : 'file'}`,
};
} catch (error: any) {
console.error('Failed to rename:', error);
throw createError({
statusCode: 500,
statusMessage: error.message || 'Failed to rename',
});
}
});