Skip to content

Commit

Permalink
S3 eco (#170)
Browse files Browse the repository at this point in the history
add endpoints and services for uploading and downloading resumes specific to each user into S3 buckets
  • Loading branch information
ericke8 authored Feb 13, 2021
1 parent b92cb81 commit 38e3cea
Show file tree
Hide file tree
Showing 13 changed files with 610 additions and 9 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ dist
.env
.DS_Store
.eslintignore
.eslintcache
.eslintcache
local_fs/
113 changes: 113 additions & 0 deletions guides/storage/StorageController.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
Here is an example of a storage controller, using the storage service to upload
and download files from a storage filesystem.

```js
import {
JsonController,
Get,
Post,
Res,
QueryParam,
UploadedFile,
BadRequestError,
UseBefore,
} from 'routing-controllers';
import { Response } from 'express';
import multer from 'multer';

import { AppUserService, AppUserServiceImpl, StorageService, StorageServiceImpl } from '@Services';
import { OfficerAuthMiddleware } from '@Middlewares';
import { OpenAPI } from 'routing-controllers-openapi';

/**
* File filter object, which checks the file's attributes then does a callback
* depending on whether the file is accepted.
*
* @param req incoming request
* @param file file object from multer
* @param cb callback to accept/reject file
*/
const fileFilter = (req: Express.Request, file: Express.Multer.File, cb: Function) => {
if (
file.mimetype.includes('image') ||
file.mimetype.includes('pdf') ||
file.mimetype.includes('word')
) {
cb(null, true);
} else {
console.log('Invalid file type');
cb(null, false);
}
};

/**
* File upload options for multer:
* memoryStorage - (where to store files) store in memory as Buffer
* fileFilter - (filter to accept/reject files) see above
* limits - limits on size of file and file name, etc
*/
const fileUploadOptions = {
storage: multer.memoryStorage(),
fileFilter: fileFilter,
limits: {
fieldNameSize: 255,
fileSize: 1024 * 1024 * 50,
},
};

@JsonController('/api/storage')
export class StorageController {
constructor(private storageService: StorageService, private appUserService: AppUserService) {}

@Post('/upload')
@UseBefore(OfficerAuthMiddleware)
@OpenAPI({ security: [{ TokenAuth: [] }] })
async uploadFile(
@UploadedFile('file', {
options: fileUploadOptions,
})
file: Express.Multer.File
): Promise<string | null> {
if (!file) {
throw new BadRequestError('Invalid file');
}
const name =
Date.now() + '-' + file.originalname.substring(0, file.originalname.lastIndexOf('.'));
try {
return await this.storageService.uploadFile(name, file);
} catch (e) {
throw new BadRequestError(`Error uploading to storage: ${e.message}`);
}
}

@Get('/download')
@UseBefore(OfficerAuthMiddleware)
@OpenAPI({ security: [{ TokenAuth: [] }] })
async downloadFile(
@QueryParam('fileName') fileName: string,
@Res() res: Response
): Promise<Buffer | null> {
if (fileName) {
try {
return await this.storageService.downloadFile(fileName, res);
} catch (e) {
throw new BadRequestError(`Error loading from storage: ${e.message}`);
}
}
throw new BadRequestError('Invalid file path');
}

@Get('/index')
@UseBefore(OfficerAuthMiddleware)
@OpenAPI({ security: [{ TokenAuth: [] }] })
async getFileIndex(): Promise<Array<string> | null> {
try {
return await this.storageService.getFileIndex();
} catch (e) {
throw new BadRequestError(`Error loading from storage: ${e.message}`);
}
}
}

export const StorageControllerImpl = new StorageController(StorageServiceImpl, AppUserServiceImpl);
```
187 changes: 182 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 38e3cea

Please sign in to comment.