Skip to content

Commit 5269329

Browse files
authored
Merge branch 'develop' into fix/oauths
2 parents 833c3bc + 25067be commit 5269329

File tree

5 files changed

+228
-236
lines changed

5 files changed

+228
-236
lines changed

client/modules/IDE/actions/assets.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ export function getAssets() {
1010
dispatch(startLoader());
1111
try {
1212
const response = await apiClient.get('/S3/objects');
13-
dispatch(setAssets(response.data.assets, response.data.totalSize));
13+
14+
const assetData = {
15+
assets: response.data.assets,
16+
totalSize: response.data.totalSize
17+
};
18+
19+
dispatch(setAssets(assetData));
1420
dispatch(stopLoader());
1521
} catch (error) {
1622
dispatch({

client/modules/IDE/reducers/assets.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ const assetsSlice = createSlice({
99
name: 'assets',
1010
initialState,
1111
reducers: {
12-
setAssets: (state, action) => action.payload,
12+
setAssets: (state, action) => {
13+
state.list = action.payload.assets;
14+
state.totalSize = action.payload.totalSize;
15+
},
1316
deleteAsset: (state, action) => {
1417
const key = action.payload;
1518
const index = state.list.findIndex((asset) => asset.key === key);

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
},
155155
"dependencies": {
156156
"@auth0/s3": "^1.0.0",
157+
"@aws-sdk/client-s3": "^3.412.0",
157158
"@babel/core": "^7.14.6",
158159
"@babel/register": "^7.14.5",
159160
"@emmetio/codemirror-plugin": "^1.2.4",

server/controllers/aws.controller.js

+129-151
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
import { v4 as uuidv4 } from 'uuid';
22
import S3Policy from 's3-policy-v4';
3-
import s3 from '@auth0/s3';
3+
import {
4+
S3Client,
5+
HeadObjectCommand,
6+
CopyObjectCommand,
7+
ListObjectsCommand,
8+
DeleteObjectsCommand
9+
} from '@aws-sdk/client-s3';
410
import mongoose from 'mongoose';
511
import { getProjectsForUserId } from './project.controller';
612
import User from '../models/user';
713

814
const { ObjectId } = mongoose.Types;
915

10-
const client = s3.createClient({
11-
maxAsyncS3: 20,
12-
s3RetryCount: 3,
13-
s3RetryDelay: 1000,
14-
multipartUploadThreshold: 20971520, // this is the default (20 MB)
15-
multipartUploadSize: 15728640, // this is the default (15 MB)
16-
s3Options: {
17-
accessKeyId: `${process.env.AWS_ACCESS_KEY}`,
18-
secretAccessKey: `${process.env.AWS_SECRET_KEY}`,
19-
region: `${process.env.AWS_REGION}`
20-
}
16+
const s3Client = new S3Client({
17+
credentials: {
18+
accessKeyId: process.env.AWS_ACCESS_KEY,
19+
secretAccessKey: process.env.AWS_SECRET_KEY
20+
},
21+
region: process.env.AWS_REGION
2122
});
2223

2324
const s3Bucket =
@@ -39,34 +40,34 @@ export function getObjectKey(url) {
3940
return objectKey;
4041
}
4142

42-
export function deleteObjectsFromS3(keyList, callback) {
43-
const keys = keyList.map((key) => { return { Key: key }; }); // eslint-disable-line
44-
if (keyList.length > 0) {
43+
export async function deleteObjectsFromS3(keyList, callback) {
44+
const objectsToDelete = keyList.map((key) => ({ Key: key }));
45+
46+
if (objectsToDelete.length > 0) {
4547
const params = {
46-
Bucket: `${process.env.S3_BUCKET}`,
47-
Delete: {
48-
Objects: keys
49-
}
48+
Bucket: process.env.S3_BUCKET,
49+
Delete: { Objects: objectsToDelete }
5050
};
51-
const del = client.deleteObjects(params);
52-
del.on('end', () => {
51+
52+
try {
53+
await s3Client.send(new DeleteObjectsCommand(params));
5354
if (callback) {
5455
callback();
5556
}
56-
});
57+
} catch (error) {
58+
console.error('Error deleting objects from S3: ', error);
59+
if (callback) {
60+
callback(error);
61+
}
62+
}
5763
} else if (callback) {
5864
callback();
5965
}
6066
}
6167

6268
export function deleteObjectFromS3(req, res) {
6369
const { objectKey, userId } = req.params;
64-
let fullObjectKey;
65-
if (userId) {
66-
fullObjectKey = `${userId}/${objectKey}`;
67-
} else {
68-
fullObjectKey = objectKey;
69-
}
70+
const fullObjectKey = userId ? `${userId}/${objectKey}` : objectKey;
7071
deleteObjectsFromS3([fullObjectKey], () => {
7172
res.json({ success: true });
7273
});
@@ -96,143 +97,120 @@ export function signS3(req, res) {
9697
res.json(policy);
9798
}
9899

99-
export function copyObjectInS3(url, userId) {
100-
return new Promise((resolve, reject) => {
101-
const objectKey = getObjectKey(url);
102-
const fileExtension = getExtension(objectKey);
103-
const newFilename = uuidv4() + fileExtension;
104-
const headParams = {
105-
Bucket: `${process.env.S3_BUCKET}`,
106-
Key: `${objectKey}`
107-
};
108-
client.s3.headObject(headParams, (headErr) => {
109-
if (headErr) {
110-
reject(
111-
new Error(
112-
`Object with key ${process.env.S3_BUCKET}/${objectKey} does not exist.`
113-
)
114-
);
115-
return;
116-
}
117-
const params = {
118-
Bucket: `${process.env.S3_BUCKET}`,
119-
CopySource: `${process.env.S3_BUCKET}/${objectKey}`,
120-
Key: `${userId}/${newFilename}`,
121-
ACL: 'public-read'
122-
};
123-
const copy = client.copyObject(params);
124-
copy.on('err', (err) => {
125-
reject(err);
126-
});
127-
copy.on('end', (data) => {
128-
resolve(`${s3Bucket}${userId}/${newFilename}`);
129-
});
130-
});
131-
});
100+
export async function copyObjectInS3(url, userId) {
101+
const objectKey = getObjectKey(url);
102+
const fileExtension = getExtension(objectKey);
103+
const newFilename = uuidv4() + fileExtension;
104+
const headParams = {
105+
Bucket: process.env.S3_BUCKET,
106+
Key: objectKey
107+
};
108+
109+
await s3Client.send(new HeadObjectCommand(headParams));
110+
111+
const params = {
112+
Bucket: process.env.S3_BUCKET,
113+
CopySource: `${process.env.S3_BUCKET}/${objectKey}`,
114+
Key: `${userId}/${newFilename}`,
115+
ACL: 'public-read'
116+
};
117+
118+
try {
119+
await s3Client.send(new CopyObjectCommand(params));
120+
return `${s3Bucket}${userId}/${newFilename}`;
121+
} catch (error) {
122+
console.error('Error copying object in S3:', error);
123+
throw error;
124+
}
132125
}
133126

134-
export function copyObjectInS3RequestHandler(req, res) {
127+
export async function copyObjectInS3RequestHandler(req, res) {
135128
const { url } = req.body;
136-
copyObjectInS3(url, req.user.id).then((newUrl) => {
137-
res.json({ url: newUrl });
138-
});
129+
const newUrl = await copyObjectInS3(url, req.user.id);
130+
res.json({ url: newUrl });
139131
}
140132

141-
export function moveObjectToUserInS3(url, userId) {
142-
return new Promise((resolve, reject) => {
143-
const objectKey = getObjectKey(url);
144-
const fileExtension = getExtension(objectKey);
145-
const newFilename = uuidv4() + fileExtension;
133+
export async function moveObjectToUserInS3(url, userId) {
134+
const objectKey = getObjectKey(url);
135+
const fileExtension = getExtension(objectKey);
136+
const newFilename = uuidv4() + fileExtension;
137+
138+
try {
146139
const headParams = {
147-
Bucket: `${process.env.S3_BUCKET}`,
148-
Key: `${objectKey}`
140+
Bucket: process.env.S3_BUCKET,
141+
Key: objectKey
149142
};
150-
client.s3.headObject(headParams, (headErr) => {
151-
if (headErr) {
152-
reject(
153-
new Error(
154-
`Object with key ${process.env.S3_BUCKET}/${objectKey} does not exist.`
155-
)
156-
);
157-
return;
158-
}
159-
const params = {
160-
Bucket: `${process.env.S3_BUCKET}`,
161-
CopySource: `${process.env.S3_BUCKET}/${objectKey}`,
162-
Key: `${userId}/${newFilename}`,
163-
ACL: 'public-read'
164-
};
165-
const move = client.moveObject(params);
166-
move.on('err', (err) => {
167-
reject(err);
168-
});
169-
move.on('end', (data) => {
170-
resolve(`${s3Bucket}${userId}/${newFilename}`);
171-
});
172-
});
173-
});
143+
await s3Client.send(new HeadObjectCommand(headParams));
144+
} catch (headErr) {
145+
throw new Error(
146+
`Object with key ${process.env.S3_BUCKET}/${objectKey} does not exist.`
147+
);
148+
}
149+
150+
const params = {
151+
Bucket: process.env.S3_BUCKET,
152+
CopySource: `${process.env.S3_BUCKET}/${objectKey}`,
153+
Key: `${userId}/${newFilename}`,
154+
ACL: 'public-read'
155+
};
156+
157+
await s3Client.send(new CopyObjectCommand(params));
158+
return `${s3Bucket}${userId}/${newFilename}`;
174159
}
175160

176-
export function listObjectsInS3ForUser(userId) {
177-
let assets = [];
178-
return new Promise((resolve) => {
161+
export async function listObjectsInS3ForUser(userId) {
162+
try {
163+
let assets = [];
179164
const params = {
180-
s3Params: {
181-
Bucket: `${process.env.S3_BUCKET}`,
182-
Prefix: `${userId}/`
183-
}
165+
Bucket: process.env.S3_BUCKET,
166+
Prefix: `${userId}/`
184167
};
185-
client
186-
.listObjects(params)
187-
.on('data', (data) => {
188-
assets = assets.concat(
189-
data.Contents.map((object) => ({
190-
key: object.Key,
191-
size: object.Size
192-
}))
193-
);
194-
})
195-
.on('end', () => {
196-
resolve();
197-
});
198-
})
199-
.then(() => getProjectsForUserId(userId))
200-
.then((projects) => {
201-
const projectAssets = [];
202-
let totalSize = 0;
203-
assets.forEach((asset) => {
204-
const name = asset.key.split('/').pop();
205-
const foundAsset = {
206-
key: asset.key,
207-
name,
208-
size: asset.size,
209-
url: `${process.env.S3_BUCKET_URL_BASE}${asset.key}`
210-
};
211-
totalSize += asset.size;
212-
projects.some((project) => {
213-
let found = false;
214-
project.files.some((file) => {
215-
if (!file.url) return false;
216-
if (file.url.includes(asset.key)) {
217-
found = true;
218-
foundAsset.name = file.name;
219-
foundAsset.sketchName = project.name;
220-
foundAsset.sketchId = project.id;
221-
foundAsset.url = file.url;
222-
return true;
223-
}
224-
return false;
225-
});
226-
return found;
168+
169+
const data = await s3Client.send(new ListObjectsCommand(params));
170+
171+
assets = data.Contents.map((object) => ({
172+
key: object.Key,
173+
size: object.Size
174+
}));
175+
176+
const projects = await getProjectsForUserId(userId);
177+
const projectAssets = [];
178+
let totalSize = 0;
179+
180+
assets.forEach((asset) => {
181+
const name = asset.key.split('/').pop();
182+
const foundAsset = {
183+
key: asset.key,
184+
name,
185+
size: asset.size,
186+
url: `${process.env.S3_BUCKET_URL_BASE}${asset.key}`
187+
};
188+
totalSize += asset.size;
189+
190+
projects.some((project) => {
191+
let found = false;
192+
project.files.some((file) => {
193+
if (!file.url) return false;
194+
if (file.url.includes(asset.key)) {
195+
found = true;
196+
foundAsset.name = file.name;
197+
foundAsset.sketchName = project.name;
198+
foundAsset.sketchId = project.id;
199+
foundAsset.url = file.url;
200+
return true;
201+
}
202+
return false;
227203
});
228-
projectAssets.push(foundAsset);
204+
return found;
229205
});
230-
return Promise.resolve({ assets: projectAssets, totalSize });
231-
})
232-
.catch((err) => {
233-
console.log('got an error');
234-
console.log(err);
206+
projectAssets.push(foundAsset);
235207
});
208+
209+
return { assets: projectAssets, totalSize };
210+
} catch (error) {
211+
console.log('Got an error:', error);
212+
throw error;
213+
}
236214
}
237215

238216
export function listObjectsInS3ForUserRequestHandler(req, res) {

0 commit comments

Comments
 (0)