fix: more fixes related to object name encoding (#1128)
- removing limitation of characters for paths/folders - fixed object names with international characters inside paths Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
This commit is contained in:
@@ -584,9 +584,17 @@ export const representationNumber = (number: number | undefined) => {
|
||||
};
|
||||
|
||||
export const encodeFileName = (name: string) => {
|
||||
return btoa(unescape(encodeURIComponent(name)));
|
||||
try {
|
||||
return btoa(unescape(encodeURIComponent(name)));
|
||||
} catch (err) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
export const decodeFileName = (text: string) => {
|
||||
return decodeURIComponent(escape(window.atob(text)));
|
||||
try {
|
||||
return decodeURIComponent(escape(window.atob(text)));
|
||||
} catch (err) {
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,7 +55,6 @@ const CreateFolderModal = ({
|
||||
classes,
|
||||
}: ICreateFolder) => {
|
||||
const [pathUrl, setPathUrl] = useState("");
|
||||
const [nameInputError, setNameInputError] = useState<string>("");
|
||||
const [isFormValid, setIsFormValid] = useState<boolean>(false);
|
||||
|
||||
const currentPath = `${bucketName}/${decodeFileName(folderName)}`;
|
||||
@@ -80,21 +79,9 @@ const CreateFolderModal = ({
|
||||
onClose();
|
||||
};
|
||||
|
||||
const validPathURL = useCallback(() => {
|
||||
const patternAgainst = /^[a-zA-Z0-9*'#-\[\]_/&.@\s()]+$/; // Only allow uppercase, numbers, dashes and underscores
|
||||
if (patternAgainst.test(pathUrl)) {
|
||||
setNameInputError("");
|
||||
return true;
|
||||
}
|
||||
setNameInputError(
|
||||
"Please verify the folder path contains valid characters only (letters, numbers and some special characters)."
|
||||
);
|
||||
return false;
|
||||
}, [pathUrl]);
|
||||
|
||||
useEffect(() => {
|
||||
let valid = true;
|
||||
if (pathUrl.trim().length === 0 || !validPathURL()) {
|
||||
if (pathUrl.trim().length === 0) {
|
||||
valid = false;
|
||||
}
|
||||
setIsFormValid(valid);
|
||||
@@ -120,7 +107,6 @@ const CreateFolderModal = ({
|
||||
setPathUrl(e.target.value);
|
||||
}}
|
||||
required
|
||||
error={nameInputError}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import { setErrorSnackMessage } from "../../../../../../actions";
|
||||
import { ErrorResponseHandler } from "../../../../../../common/types";
|
||||
import api from "../../../../../../common/api";
|
||||
import { decodeFileName } from "../../../../../../common/utils";
|
||||
|
||||
interface IDeleteObjectProps {
|
||||
closeDeleteModalAndRefresh: (refresh: boolean) => void;
|
||||
@@ -50,13 +51,8 @@ const DeleteObject = ({
|
||||
if (deleteLoading) {
|
||||
return;
|
||||
}
|
||||
let recursive = false;
|
||||
if (selectedObject.endsWith("/")) {
|
||||
recursive = true;
|
||||
}
|
||||
// Escape object name
|
||||
selectedObject = encodeURIComponent(selectedObject);
|
||||
|
||||
const decodedSelectedObject = decodeFileName(selectedObject);
|
||||
const recursive = decodedSelectedObject.endsWith("/");
|
||||
api
|
||||
.invoke(
|
||||
"DELETE",
|
||||
@@ -85,7 +81,8 @@ const DeleteObject = ({
|
||||
<DialogContent>
|
||||
{deleteLoading && <LinearProgress />}
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Are you sure you want to delete: <b>{selectedObject}</b>?{" "}
|
||||
Are you sure you want to delete:{" "}
|
||||
<b>{decodeFileName(selectedObject)}</b>?{" "}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
|
||||
@@ -897,12 +897,8 @@ const ListObjects = ({
|
||||
},
|
||||
];
|
||||
|
||||
const ccPath = internalPaths.split("/").pop();
|
||||
|
||||
const pageTitle = ccPath !== "" ? decodeFileName(ccPath) : "/";
|
||||
// console.log("pageTitle", pageTitle);
|
||||
const pageTitle = decodeFileName(internalPaths);
|
||||
const currentPath = pageTitle.split("/").filter((i: string) => i !== "");
|
||||
// console.log("currentPath", currentPath);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -922,7 +918,7 @@ const ListObjects = ({
|
||||
<DeleteObject
|
||||
deleteOpen={deleteOpen}
|
||||
selectedBucket={bucketName}
|
||||
selectedObject={selectedObject}
|
||||
selectedObject={encodeFileName(selectedObject)}
|
||||
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -77,7 +77,7 @@ import EditIcon from "../../../../../../icons/EditIcon";
|
||||
import SearchIcon from "../../../../../../icons/SearchIcon";
|
||||
import ObjectBrowserIcon from "../../../../../../icons/ObjectBrowserIcon";
|
||||
import PreviewFileContent from "../Preview/PreviewFileContent";
|
||||
import { decodeFileName } from "../../../../../../common/utils";
|
||||
import { decodeFileName, encodeFileName } from "../../../../../../common/utils";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -420,7 +420,9 @@ const ObjectDetails = ({
|
||||
if (redirectBack) {
|
||||
const newPath = allPathData.join("/");
|
||||
history.push(
|
||||
`/buckets/${bucketName}/browse${newPath === "" ? "" : `/${newPath}`}`
|
||||
`/buckets/${bucketName}/browse${
|
||||
newPath === "" ? "" : `/${encodeFileName(newPath)}`
|
||||
}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -328,7 +328,16 @@ func downloadObject(ctx context.Context, client MCClient, versionID *string) (io
|
||||
// getDeleteObjectResponse returns whether there was an error on deletion of object
|
||||
func getDeleteObjectResponse(session *models.Principal, params user_api.DeleteObjectParams) *models.Error {
|
||||
ctx := context.Background()
|
||||
s3Client, err := newS3BucketClient(session, params.BucketName, params.Path)
|
||||
var prefix string
|
||||
if params.Path != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Path)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return prepareError(err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
s3Client, err := newS3BucketClient(session, params.BucketName, prefix)
|
||||
if err != nil {
|
||||
return prepareError(err)
|
||||
}
|
||||
@@ -343,7 +352,7 @@ func getDeleteObjectResponse(session *models.Principal, params user_api.DeleteOb
|
||||
if params.VersionID != nil {
|
||||
version = *params.VersionID
|
||||
}
|
||||
err = deleteObjects(ctx, mcClient, params.BucketName, params.Path, version, rec)
|
||||
err = deleteObjects(ctx, mcClient, params.BucketName, prefix, version, rec)
|
||||
if err != nil {
|
||||
return prepareError(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user