mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-07 12:33:36 +09:00
Add sanitize
This commit is contained in:
1 parent
d0dbf9938a
commit
279e2ec093
5 files changed
+62
-6
No files matched your search
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* TEMPORARY: This function is a temporary fix for https://github.com/remix-run/remix/issues/4443
|
||||
*
|
||||
* Based on this: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
|
||||
* Characters that might require special handling
|
||||
* ASCII character ranges 00–1F hex (0–31 decimal) and 7F (127 decimal)
|
||||
* "&","$", "@", "=", ";" "/", ":", "+", Significant sequences of spaces might be lost in some uses (especially multiple spaces)
|
||||
* ",", "?"
|
||||
* Characters to avoid
|
||||
* Non-printable ASCII characters (128–255 decimal characters)
|
||||
* "\", "{", "^", "}", "%", "`", "]", ', ", “, ”, ">", "[", "~", "<", "#", "|"
|
||||
**/
|
||||
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const specialRegexps = [/[\x00-\x1F\x7F]+/g, /[&$@=;/:+\s,?]+/g];
|
||||
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const avoidRegexps = [/[\x80-\xFF]+/g, /[\\{^}%`\]'"“”>[~<#|]+/g];
|
||||
|
||||
const allRegexps = [...specialRegexps, ...avoidRegexps];
|
||||
|
||||
const REPLACE_CHAR = "_";
|
||||
|
||||
export const sanitizeS3Key = (str: string): string => {
|
||||
return allRegexps.reduce((r, reg) => r.replace(reg, REPLACE_CHAR), str);
|
||||
};
|
||||
@@ -10,6 +10,7 @@ import ObjectID from "bson-objectid";
|
||||
import { useMemo } from "react";
|
||||
import { restAssetsPath } from "~/shared/router-utils";
|
||||
import { useAssets as useAssetsState, useProject } from "../nano-states";
|
||||
import { sanitizeS3Key } from "./sanitize-s3-key";
|
||||
import { PreviewAsset } from "./types";
|
||||
|
||||
const toPreviewAssets = (formData: FormData): Promise<PreviewAsset[]> => {
|
||||
@@ -54,7 +55,9 @@ const toFormData = (type: AssetType, input: HTMLInputElement) => {
|
||||
);
|
||||
continue;
|
||||
}
|
||||
formData.append(type, file, file.name);
|
||||
|
||||
// sanitizeS3Key here is just because of https://github.com/remix-run/remix/issues/4443
|
||||
formData.append(type, file, sanitizeS3Key(file.name));
|
||||
}
|
||||
return formData;
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ import { createMany } from "../../db";
|
||||
import type { Asset } from "../../types";
|
||||
import { getUniqueFilename } from "../../utils/get-unique-filename";
|
||||
import { getS3Client } from "./client";
|
||||
import { sanitizeS3Key } from "../../utils/sanitize-s3-key";
|
||||
|
||||
const AssetsUploadedSuccess = z.object({
|
||||
Location: z.string(),
|
||||
@@ -72,7 +73,9 @@ const uploadHandler = async ({
|
||||
throw new Error("Filename is required");
|
||||
}
|
||||
|
||||
const uniqueFilename = getUniqueFilename(file.filename);
|
||||
const fileName = sanitizeS3Key(file.filename);
|
||||
|
||||
const uniqueFilename = getUniqueFilename(fileName);
|
||||
|
||||
const s3Env = S3Env.parse(process.env);
|
||||
|
||||
@@ -82,12 +85,12 @@ const uploadHandler = async ({
|
||||
const params: PutObjectCommandInput = {
|
||||
...ACL,
|
||||
Bucket: s3Env.S3_BUCKET,
|
||||
Key: encodeURIComponent(uniqueFilename),
|
||||
Key: uniqueFilename,
|
||||
Body: data,
|
||||
ContentType: file.contentType,
|
||||
Metadata: {
|
||||
// encodeURIComponent is needed to support special characters like Cyrillic
|
||||
filename: "meta", // encodeURIComponent(file.filename) || "unnamed",
|
||||
filename: encodeURIComponent(fileName) || "unnamed",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@ export const getAssetPath = (asset: DbAsset) => {
|
||||
// see /packages/asset-uploader/src/targets/s3/upload.ts "Key: encodeURIComponent(uniqueFilename)"
|
||||
// here we need to encode file name, i.e cndUrl.pathname = encodeURIComponent(fileName)
|
||||
// but having that fileName = encodeURIComponent(asset.name) we are doing double encoding
|
||||
cndUrl.pathname = encodeURIComponent(encodeURIComponent(asset.name));
|
||||
cndUrl.pathname = asset.name;
|
||||
return cndUrl.toString();
|
||||
}
|
||||
const s3Url = new URL(s3Envs.data.S3_ENDPOINT);
|
||||
s3Url.hostname = `${s3Envs.data.S3_BUCKET}.${s3Url.hostname}`;
|
||||
// See above comment about double encoding
|
||||
s3Url.pathname = encodeURIComponent(encodeURIComponent(asset.name));
|
||||
s3Url.pathname = asset.name;
|
||||
return s3Url.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Based on this: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
|
||||
* Characters that might require special handling
|
||||
* ASCII character ranges 00–1F hex (0–31 decimal) and 7F (127 decimal)
|
||||
* "&","$", "@", "=", ";" "/", ":", "+", Significant sequences of spaces might be lost in some uses (especially multiple spaces)
|
||||
* ",", "?"
|
||||
* Characters to avoid
|
||||
* Non-printable ASCII characters (128–255 decimal characters)
|
||||
* "\", "{", "^", "}", "%", "`", "]", ', ", “, ”, ">", "[", "~", "<", "#", "|"
|
||||
**/
|
||||
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const specialRegexps = [/[\x00-\x1F\x7F]+/g, /[&$@=;/:+\s,?]+/g];
|
||||
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const avoidRegexps = [/[\x80-\xFF]+/g, /[\\{^}%`\]'"“”>[~<#|]+/g];
|
||||
|
||||
const allRegexps = [...specialRegexps, ...avoidRegexps];
|
||||
|
||||
const REPLACE_CHAR = "_";
|
||||
|
||||
export const sanitizeS3Key = (str: string): string => {
|
||||
return allRegexps.reduce((r, reg) => r.replace(reg, REPLACE_CHAR), str);
|
||||
};
|
||||
Reference in new issue
Block a user