1
1
import { v4 as uuidv4 } from 'uuid' ;
2
2
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' ;
4
10
import mongoose from 'mongoose' ;
5
11
import { getProjectsForUserId } from './project.controller' ;
6
12
import User from '../models/user' ;
7
13
8
14
const { ObjectId } = mongoose . Types ;
9
15
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
21
22
} ) ;
22
23
23
24
const s3Bucket =
@@ -39,34 +40,34 @@ export function getObjectKey(url) {
39
40
return objectKey ;
40
41
}
41
42
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 ) {
45
47
const params = {
46
- Bucket : `${ process . env . S3_BUCKET } ` ,
47
- Delete : {
48
- Objects : keys
49
- }
48
+ Bucket : process . env . S3_BUCKET ,
49
+ Delete : { Objects : objectsToDelete }
50
50
} ;
51
- const del = client . deleteObjects ( params ) ;
52
- del . on ( 'end' , ( ) => {
51
+
52
+ try {
53
+ await s3Client . send ( new DeleteObjectsCommand ( params ) ) ;
53
54
if ( callback ) {
54
55
callback ( ) ;
55
56
}
56
- } ) ;
57
+ } catch ( error ) {
58
+ console . error ( 'Error deleting objects from S3: ' , error ) ;
59
+ if ( callback ) {
60
+ callback ( error ) ;
61
+ }
62
+ }
57
63
} else if ( callback ) {
58
64
callback ( ) ;
59
65
}
60
66
}
61
67
62
68
export function deleteObjectFromS3 ( req , res ) {
63
69
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 ;
70
71
deleteObjectsFromS3 ( [ fullObjectKey ] , ( ) => {
71
72
res . json ( { success : true } ) ;
72
73
} ) ;
@@ -96,143 +97,120 @@ export function signS3(req, res) {
96
97
res . json ( policy ) ;
97
98
}
98
99
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
+ }
132
125
}
133
126
134
- export function copyObjectInS3RequestHandler ( req , res ) {
127
+ export async function copyObjectInS3RequestHandler ( req , res ) {
135
128
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 } ) ;
139
131
}
140
132
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 {
146
139
const headParams = {
147
- Bucket : ` ${ process . env . S3_BUCKET } ` ,
148
- Key : ` ${ objectKey } `
140
+ Bucket : process . env . S3_BUCKET ,
141
+ Key : objectKey
149
142
} ;
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 } ` ;
174
159
}
175
160
176
- export function listObjectsInS3ForUser ( userId ) {
177
- let assets = [ ] ;
178
- return new Promise ( ( resolve ) => {
161
+ export async function listObjectsInS3ForUser ( userId ) {
162
+ try {
163
+ let assets = [ ] ;
179
164
const params = {
180
- s3Params : {
181
- Bucket : `${ process . env . S3_BUCKET } ` ,
182
- Prefix : `${ userId } /`
183
- }
165
+ Bucket : process . env . S3_BUCKET ,
166
+ Prefix : `${ userId } /`
184
167
} ;
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 ;
227
203
} ) ;
228
- projectAssets . push ( foundAsset ) ;
204
+ return found ;
229
205
} ) ;
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 ) ;
235
207
} ) ;
208
+
209
+ return { assets : projectAssets , totalSize } ;
210
+ } catch ( error ) {
211
+ console . log ( 'Got an error:' , error ) ;
212
+ throw error ;
213
+ }
236
214
}
237
215
238
216
export function listObjectsInS3ForUserRequestHandler ( req , res ) {
0 commit comments