chore: Separate maximum import size config for document/workspace (#6566)
* chore: Separate maximum import size config for document/workspace * Update .env.sample
This commit is contained in:
12
.env.sample
12
.env.sample
@@ -66,6 +66,14 @@ FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
|
||||
# Maximum allowed size for the uploaded attachment.
|
||||
FILE_STORAGE_UPLOAD_MAX_SIZE=262144000
|
||||
|
||||
# Override the maximum size of document imports, generally this should be lower
|
||||
# than the document attachment maximum size.
|
||||
FILE_STORAGE_IMPORT_MAX_SIZE=
|
||||
|
||||
# Override the maximum size of workspace imports, these can be especially large
|
||||
# and the files are temporary being automatically deleted after a period of time.
|
||||
FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE=
|
||||
|
||||
# –––––––––––––– AUTHENTICATION ––––––––––––––
|
||||
|
||||
# Third party signin credentials, at least ONE OF EITHER Google, Slack,
|
||||
@@ -142,10 +150,6 @@ ENABLE_UPDATES=true
|
||||
# available memory by 512 for a rough estimate
|
||||
WEB_CONCURRENCY=1
|
||||
|
||||
# Override the maximum size of document imports, could be required if you have
|
||||
# especially large Word documents with embedded imagery
|
||||
MAXIMUM_IMPORT_SIZE=5120000
|
||||
|
||||
# You can remove this line if your reverse proxy already logs incoming http
|
||||
# requests and this ends up being duplicative
|
||||
DEBUG=http
|
||||
|
||||
@@ -38,7 +38,7 @@ function DropToImport({ disabled, onSubmit, children, format }: Props) {
|
||||
try {
|
||||
const attachment = await uploadFile(file, {
|
||||
name: file.name,
|
||||
preset: AttachmentPreset.Import,
|
||||
preset: AttachmentPreset.WorkspaceImport,
|
||||
});
|
||||
await collections.import(attachment.id, format);
|
||||
onSubmit();
|
||||
|
||||
@@ -596,10 +596,10 @@ export default class DocumentsStore extends Store<Document> {
|
||||
throw new Error(`The selected file type is not supported (${file.type})`);
|
||||
}
|
||||
|
||||
if (file.size > env.MAXIMUM_IMPORT_SIZE) {
|
||||
if (file.size > env.FILE_STORAGE_IMPORT_MAX_SIZE) {
|
||||
throw new Error(
|
||||
`The selected file was larger than the ${bytesToHumanReadable(
|
||||
env.MAXIMUM_IMPORT_SIZE
|
||||
env.FILE_STORAGE_IMPORT_MAX_SIZE
|
||||
)} maximum size`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ router.post(
|
||||
multipart({
|
||||
maximumFileSize: Math.max(
|
||||
env.FILE_STORAGE_UPLOAD_MAX_SIZE,
|
||||
env.MAXIMUM_IMPORT_SIZE
|
||||
env.FILE_STORAGE_IMPORT_MAX_SIZE
|
||||
),
|
||||
}),
|
||||
async (ctx: APIContext<T.FilesCreateReq>) => {
|
||||
|
||||
@@ -582,7 +582,8 @@ export class Environment {
|
||||
this.toOptionalNumber(process.env.RATE_LIMITER_DURATION_WINDOW) ?? 60;
|
||||
|
||||
/**
|
||||
* @deprecated Set max allowed upload size for file attachments.
|
||||
* Set max allowed upload size for file attachments.
|
||||
* @deprecated Use FILE_STORAGE_UPLOAD_MAX_SIZE instead
|
||||
*/
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@@ -671,17 +672,39 @@ export class Environment {
|
||||
public FILE_STORAGE_UPLOAD_MAX_SIZE =
|
||||
this.toOptionalNumber(process.env.FILE_STORAGE_UPLOAD_MAX_SIZE) ??
|
||||
this.toOptionalNumber(process.env.AWS_S3_UPLOAD_MAX_SIZE) ??
|
||||
100000000;
|
||||
1000000;
|
||||
|
||||
/**
|
||||
* Set max allowed upload size for document imports.
|
||||
*/
|
||||
@IsNumber()
|
||||
public FILE_STORAGE_IMPORT_MAX_SIZE =
|
||||
this.toOptionalNumber(process.env.FILE_STORAGE_IMPORT_MAX_SIZE) ??
|
||||
this.toOptionalNumber(process.env.MAXIMUM_IMPORT_SIZE) ??
|
||||
this.toOptionalNumber(process.env.FILE_STORAGE_UPLOAD_MAX_SIZE) ??
|
||||
1000000;
|
||||
|
||||
/**
|
||||
* Set max allowed upload size for imports at workspace level.
|
||||
*/
|
||||
@IsNumber()
|
||||
public FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE =
|
||||
this.toOptionalNumber(process.env.FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE) ??
|
||||
this.toOptionalNumber(process.env.MAXIMUM_IMPORT_SIZE) ??
|
||||
this.toOptionalNumber(process.env.FILE_STORAGE_UPLOAD_MAX_SIZE) ??
|
||||
1000000;
|
||||
|
||||
/**
|
||||
* Because imports can be much larger than regular file attachments and are
|
||||
* deleted automatically we allow an optional separate limit on the size of
|
||||
* imports.
|
||||
*
|
||||
* @deprecated Use `FILE_STORAGE_IMPORT_MAX_SIZE` or `FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE` instead
|
||||
*/
|
||||
@IsNumber()
|
||||
public MAXIMUM_IMPORT_SIZE = Math.max(
|
||||
this.toOptionalNumber(process.env.MAXIMUM_IMPORT_SIZE) ?? 100000000,
|
||||
this.FILE_STORAGE_UPLOAD_MAX_SIZE
|
||||
@Deprecated("Use FILE_STORAGE_IMPORT_MAX_SIZE instead")
|
||||
public MAXIMUM_IMPORT_SIZE = this.toOptionalNumber(
|
||||
process.env.MAXIMUM_IMPORT_SIZE
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,6 +86,7 @@ export default class AttachmentHelper {
|
||||
static presetToExpiry(preset: AttachmentPreset) {
|
||||
switch (preset) {
|
||||
case AttachmentPreset.Import:
|
||||
case AttachmentPreset.WorkspaceImport:
|
||||
return addHours(new Date(), 24);
|
||||
default:
|
||||
return undefined;
|
||||
@@ -101,7 +102,9 @@ export default class AttachmentHelper {
|
||||
static presetToMaxUploadSize(preset: AttachmentPreset) {
|
||||
switch (preset) {
|
||||
case AttachmentPreset.Import:
|
||||
return env.MAXIMUM_IMPORT_SIZE;
|
||||
return env.FILE_STORAGE_IMPORT_MAX_SIZE;
|
||||
case AttachmentPreset.WorkspaceImport:
|
||||
return env.FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE;
|
||||
case AttachmentPreset.Avatar:
|
||||
case AttachmentPreset.DocumentAttachment:
|
||||
default:
|
||||
|
||||
@@ -24,7 +24,7 @@ export default function present(
|
||||
SENTRY_TUNNEL: env.SENTRY_TUNNEL,
|
||||
SLACK_CLIENT_ID: env.SLACK_CLIENT_ID,
|
||||
SLACK_APP_ID: env.SLACK_APP_ID,
|
||||
MAXIMUM_IMPORT_SIZE: env.MAXIMUM_IMPORT_SIZE,
|
||||
FILE_STORAGE_IMPORT_MAX_SIZE: env.FILE_STORAGE_IMPORT_MAX_SIZE,
|
||||
PDF_EXPORT_ENABLED: false,
|
||||
DEFAULT_LANGUAGE: env.DEFAULT_LANGUAGE,
|
||||
EMAIL_ENABLED: !!env.SMTP_HOST || env.isDevelopment,
|
||||
|
||||
@@ -66,7 +66,7 @@ describe("#attachments.create", () => {
|
||||
name: "test.zip",
|
||||
contentType: "application/zip",
|
||||
size: 10000,
|
||||
preset: AttachmentPreset.Import,
|
||||
preset: AttachmentPreset.WorkspaceImport,
|
||||
token: user.getJwtToken(),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1312,7 +1312,7 @@ router.post(
|
||||
auth(),
|
||||
rateLimiter(RateLimiterStrategy.TwentyFivePerMinute),
|
||||
validate(T.DocumentsImportSchema),
|
||||
multipart({ maximumFileSize: env.MAXIMUM_IMPORT_SIZE }),
|
||||
multipart({ maximumFileSize: env.FILE_STORAGE_IMPORT_MAX_SIZE }),
|
||||
transaction(),
|
||||
async (ctx: APIContext<T.DocumentsImportReq>) => {
|
||||
const { collectionId, parentDocumentId, publish } = ctx.input.body;
|
||||
|
||||
@@ -48,7 +48,7 @@ api.use(
|
||||
formidable: {
|
||||
maxFileSize: Math.max(
|
||||
env.FILE_STORAGE_UPLOAD_MAX_SIZE,
|
||||
env.MAXIMUM_IMPORT_SIZE
|
||||
env.FILE_STORAGE_IMPORT_MAX_SIZE
|
||||
),
|
||||
maxFieldsSize: 10 * 1024 * 1024,
|
||||
},
|
||||
|
||||
@@ -53,7 +53,7 @@ export type PublicEnv = {
|
||||
SENTRY_TUNNEL: string | undefined;
|
||||
SLACK_CLIENT_ID: string | undefined;
|
||||
SLACK_APP_ID: string | undefined;
|
||||
MAXIMUM_IMPORT_SIZE: number;
|
||||
FILE_STORAGE_IMPORT_MAX_SIZE: number;
|
||||
EMAIL_ENABLED: boolean;
|
||||
PDF_EXPORT_ENABLED: boolean;
|
||||
DEFAULT_LANGUAGE: string;
|
||||
@@ -71,6 +71,7 @@ export type PublicEnv = {
|
||||
|
||||
export enum AttachmentPreset {
|
||||
DocumentAttachment = "documentAttachment",
|
||||
WorkspaceImport = "workspaceImport",
|
||||
Import = "import",
|
||||
Avatar = "avatar",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user