Skip to content

Commit

Permalink
Improve loading of uploaded files in draft field
Browse files Browse the repository at this point in the history
  • Loading branch information
hdiniz committed Jan 13, 2025
1 parent 8d491b0 commit 78d7331
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 22 deletions.
8 changes: 8 additions & 0 deletions server/controllers/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ export async function getFile(req: Request, res: Response) {

const actualUrl = uploadedFile.getDataValue('url');

if (uploadedFile.isPublicFile()) {
if (isJsonAccepted) {
return res.send({ url: actualUrl });
} else {
return res.redirect(307, actualUrl);
}
}

if (
!(await hasUploadedFilePermission(req, uploadedFile, {
expenseId: expenseId ? idDecode(expenseId as string, IDENTIFIER_TYPES.EXPENSE) : null,
Expand Down
16 changes: 8 additions & 8 deletions server/graphql/common/expenses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1508,14 +1508,14 @@ export async function prepareAttachedFiles(req: Request, attachedFiles: ExpenseD
return [];
}

const mapItemUrlToUploadedFile: Record<string, string> = {};
const mapItemUrlToUploadedFileUrl: Record<string, string> = {};
for (const item of attachedFiles) {
if (!item.url) {
continue;
}

if (!UploadedFile.isUploadedFileURL(item.url)) {
mapItemUrlToUploadedFile[item.url] = item.url;
mapItemUrlToUploadedFileUrl[item.url] = item.url;
continue;
}

Expand All @@ -1525,12 +1525,12 @@ export async function prepareAttachedFiles(req: Request, attachedFiles: ExpenseD

const uploadedFile = await UploadedFile.getFromURL(item.url);

mapItemUrlToUploadedFile[item.url] = uploadedFile.getDataValue('url');
mapItemUrlToUploadedFileUrl[item.url] = uploadedFile.getDataValue('url');
}

return attachedFiles.map(file => ({
...file,
url: mapItemUrlToUploadedFile[file.url],
url: mapItemUrlToUploadedFileUrl[file.url],
}));
}

Expand Down Expand Up @@ -1568,14 +1568,14 @@ export const prepareExpenseItemInputs = async (
);
}

const mapItemUrlToUploadedFile: Record<string, string> = {};
const mapItemUrlToUploadedFileUrl: Record<string, string> = {};
for (const item of itemsInput) {
if (!item.url) {
continue;
}

if (!UploadedFile.isUploadedFileURL(item.url)) {
mapItemUrlToUploadedFile[item.url] = item.url;
mapItemUrlToUploadedFileUrl[item.url] = item.url;
continue;
}

Expand All @@ -1584,7 +1584,7 @@ export const prepareExpenseItemInputs = async (
}

const uploadedFile = await UploadedFile.getFromURL(item.url);
mapItemUrlToUploadedFile[item.url] = uploadedFile.getDataValue('url');
mapItemUrlToUploadedFileUrl[item.url] = uploadedFile.getDataValue('url');
}

// Prepare items
Expand All @@ -1593,7 +1593,7 @@ export const prepareExpenseItemInputs = async (
const values: Partial<ExpenseItem> = pick(itemInput, fieldsToPick);

if (values.url) {
values.url = mapItemUrlToUploadedFile[values.url];
values.url = mapItemUrlToUploadedFileUrl[values.url];
}

if (itemInput['amount'] && itemInput['amountV2']) {
Expand Down
12 changes: 4 additions & 8 deletions server/graphql/common/uploaded-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,11 @@ export async function hasUploadedFilePermission(
include: { model: Expense, include: [{ association: 'fromCollective' }] },
});

const expense = expenseItem?.Expense;

if (!expense) {
if (!expenseItem) {
return req.remoteUser?.id === uploadedFile.CreatedByUserId;
}

if (await canSeeExpenseAttachments(req, expense)) {
if (await canSeeExpenseAttachments(req, expenseItem?.Expense)) {
return true;
}
break;
Expand All @@ -92,13 +90,11 @@ export async function hasUploadedFilePermission(
include: { model: Expense, include: [{ model: Collective, as: 'fromCollective' }] },
});

const expense = expenseAttachedFile?.Expense;

if (!expense) {
if (!expenseAttachedFile) {
return req.remoteUser?.id === uploadedFile.CreatedByUserId;
}

if (await canSeeExpenseAttachments(req, expense)) {
if (await canSeeExpenseAttachments(req, expenseAttachedFile?.Expense)) {
return true;
}

Expand Down
17 changes: 13 additions & 4 deletions server/graphql/v2/object/Expense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
GraphQLString,
} from 'graphql';
import { GraphQLDateTime, GraphQLJSON } from 'graphql-scalars';
import { findLast, pick, round, takeRightWhile, toString, uniq } from 'lodash';
import { findLast, keyBy, pick, round, takeRightWhile, toString, uniq } from 'lodash';
import { WhereOptions } from 'sequelize';

import ActivityTypes from '../../../constants/activities';
Expand Down Expand Up @@ -554,9 +554,19 @@ export const GraphQLExpense = new GraphQLObjectType<ExpenseModel, express.Reques

const draftData = pick(expense.data, draftFields);
const items = ((expense.data.items as { url?: string }[]) || []).map(item => pick(item, itemsFields));
const attachedFiles = (draftData.attachedFiles as { url?: string }[]) || [];

const uploadedFiles = keyBy(
(await req.loaders.UploadedFile.byUrl.loadMany([
...items.filter(item => item.url).map(item => item.url),
...attachedFiles.filter(attachedFile => attachedFile.url),
])) as UploadedFile[],
uploadedFile => uploadedFile.getDataValue('url'),
);

for (const item of items) {
if (item.url) {
const uploadedFile = await req.loaders.UploadedFile.byUrl.load(item.url);
const uploadedFile = uploadedFiles[item.url];
item.url = uploadedFile
? UploadedFile.getProtectedURLFromOpenCollectiveS3Bucket(uploadedFile, {
expenseId: expense.id,
Expand All @@ -570,10 +580,9 @@ export const GraphQLExpense = new GraphQLObjectType<ExpenseModel, express.Reques
draftData.items = items;
}

const attachedFiles = (draftData.attachedFiles as { url?: string }[]) || [];
for (const attachedFile of attachedFiles) {
if (attachedFile.url) {
const uploadedFile = await req.loaders.UploadedFile.byUrl.load(attachedFile.url);
const uploadedFile = uploadedFiles[attachedFile.url];

attachedFile.url = uploadedFile
? UploadedFile.getProtectedURLFromOpenCollectiveS3Bucket(uploadedFile, {
Expand Down
6 changes: 6 additions & 0 deletions server/models/UploadedFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ class UploadedFile extends Model<InferAttributes<UploadedFile>, InferCreationAtt
// S3 limits file names to 1024 characters. We're using 900 to be safe and give some room for the kind + uuid + extension.
return `${parsedFileName.name.slice(0, 900)}${expectedExtension}`;
}

public isPublicFile(): boolean {
return ['ACCOUNT_AVATAR', 'ACCOUNT_BANNER', 'ACCOUNT_LONG_DESCRIPTION', 'TIER_LONG_DESCRIPTION'].includes(
this.kind,
);
}
}

UploadedFile.init(
Expand Down
4 changes: 2 additions & 2 deletions test/test-helpers/fake-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,9 @@ export const fakeUploadedFile = async (fileData: Partial<InferCreationAttributes
const fileType = sample(SUPPORTED_FILE_TYPES);
const extension = SUPPORTED_FILE_EXTENSIONS[fileType];
const fileName = `${randStr()}${extension}`;
const kind = sample(SUPPORTED_FILE_KINDS);
const kind = fileData?.kind || sample(SUPPORTED_FILE_KINDS);
return models.UploadedFile.create({
url: fakeUploadedFileURL(fileData?.kind || kind, fileName),
url: fakeUploadedFileURL(kind, fileName),
kind,
fileSize: randNumber(100, 100000),
fileName,
Expand Down

0 comments on commit 78d7331

Please sign in to comment.