mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Limit total attachment file size per document
Summary: - Add a new parameter `Features.baseMaxAttachmentsBytesPerDocument` and set it to 1GB for the free team product. - Add a method to DocStorage to calculate the total size of existing and used attachments. - Add a migration to DocStorage adding an index to make the query in the above method fast. - Check in ActiveDoc if uploading attachment(s) would exceed the product limit on that document. Test Plan: Added test in `limits.ts` testing enforcement of the attachment limit. Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3374
This commit is contained in:
@@ -47,6 +47,8 @@ export interface Features {
|
||||
// Actual max for a document may be higher.
|
||||
baseMaxApiUnitsPerDocumentPerDay?: number; // Similar for api calls.
|
||||
baseMaxDataSizePerDocument?: number; // Similar maximum for number of bytes of 'normal' data in a document
|
||||
baseMaxAttachmentsBytesPerDocument?: number; // Similar maximum for total number of bytes used
|
||||
// for attached files in a document
|
||||
|
||||
gracePeriodDays?: number; // Duration of the grace period in days, before entering delete-only mode
|
||||
}
|
||||
|
||||
@@ -394,6 +394,9 @@ export interface DocAPI {
|
||||
* @param title Name of the spreadsheet that will be created (should use a Grist document's title)
|
||||
*/
|
||||
sendToDrive(code: string, title: string): Promise<{url: string}>;
|
||||
// Upload a single attachment and return the resulting metadata row ID.
|
||||
// The arguments are passed to FormData.append.
|
||||
uploadAttachment(value: string | Blob, filename?: string): Promise<number>;
|
||||
}
|
||||
|
||||
// Operations that are supported by a doc worker.
|
||||
@@ -869,6 +872,20 @@ export class DocAPIImpl extends BaseAPI implements DocAPI {
|
||||
return this.requestJson(url.href);
|
||||
}
|
||||
|
||||
public async uploadAttachment(value: string | Blob, filename?: string): Promise<number> {
|
||||
const formData = this.newFormData();
|
||||
formData.append('upload', value, filename);
|
||||
const response = await this.requestAxios(`${this._url}/attachments`, {
|
||||
method: 'POST',
|
||||
data: formData,
|
||||
// On browser, it is important not to set Content-Type so that the browser takes care
|
||||
// of setting HTTP headers appropriately. Outside browser, requestAxios has logic
|
||||
// for setting the HTTP headers.
|
||||
headers: {...this.defaultHeadersWithoutContentType()},
|
||||
});
|
||||
return response.data[0];
|
||||
}
|
||||
|
||||
private _getRecords(tableId: string, endpoint: 'data' | 'records', options?: GetRowsParams): Promise<any> {
|
||||
const url = new URL(`${this._url}/tables/${tableId}/${endpoint}`);
|
||||
if (options?.filters) {
|
||||
|
||||
Reference in New Issue
Block a user