From feeec4eb149e9a47e5a52320d1fc95243bf5eb15 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Mon, 28 Feb 2022 22:34:18 +0500 Subject: [PATCH] fix(upload): added query param as well for filepath --- api/public/swagger.yaml | 13 +++++++++---- api/src/controllers/drive.ts | 7 ++++--- api/src/routes/api/drive.ts | 21 ++++++++++++++++----- api/src/routes/api/spec/drive.spec.ts | 15 ++++++++++++++- api/src/utils/validation.ts | 13 +++++++++++++ 5 files changed, 56 insertions(+), 13 deletions(-) diff --git a/api/public/swagger.yaml b/api/public/swagger.yaml index ad4dde2..ff8c054 100644 --- a/api/public/swagger.yaml +++ b/api/public/swagger.yaml @@ -669,7 +669,13 @@ paths: security: - bearerAuth: [] - parameters: [] + parameters: + - + in: query + name: _filePath + required: false + schema: + type: string requestBody: required: true content: @@ -677,13 +683,12 @@ paths: schema: type: object properties: - filePath: - type: string file: type: string format: binary + filePath: + type: string required: - - filePath - file patch: operationId: UpdateFile diff --git a/api/src/controllers/drive.ts b/api/src/controllers/drive.ts index bab541b..a59b90f 100644 --- a/api/src/controllers/drive.ts +++ b/api/src/controllers/drive.ts @@ -129,10 +129,11 @@ export class DriveController { }) @Post('/file') public async saveFile( - @FormField() filePath: string, - @UploadedFile() file: Express.Multer.File + @UploadedFile() file: Express.Multer.File, + @Query() _filePath?: string, + @FormField() filePath?: string ): Promise { - return saveFile(filePath, file) + return saveFile((_filePath ?? filePath)!, file) } /** diff --git a/api/src/routes/api/drive.ts b/api/src/routes/api/drive.ts index fb4bc7c..2a533f9 100644 --- a/api/src/routes/api/drive.ts +++ b/api/src/routes/api/drive.ts @@ -3,7 +3,12 @@ import { deleteFile } from '@sasjs/utils' import { multerSingle } from '../../middlewares/multer' import { DriveController } from '../../controllers/' -import { getFileDriveValidation, updateFileDriveValidation } from '../../utils' +import { + getFileDriveValidation, + updateFileDriveValidation, + uploadFileBodyValidation, + uploadFileParamValidation +} from '../../utils' const controller = new DriveController() @@ -42,16 +47,22 @@ driveRouter.post( '/file', (...arg) => multerSingle('file', arg), async (req, res) => { - const { error, value: body } = updateFileDriveValidation(req.body) - if (error) { + const { error: errQ, value: query } = uploadFileParamValidation(req.query) + const { error: errB, value: body } = uploadFileBodyValidation(req.body) + + if (errQ && errB) { if (req.file) await deleteFile(req.file.path) - return res.status(400).send(error.details[0].message) + return res.status(400).send(errB.details[0].message) } if (!req.file) return res.status(400).send('"file" is not present.') try { - const response = await controller.saveFile(body.filePath, req.file) + const response = await controller.saveFile( + req.file, + query._filePath, + body.filePath + ) res.send(response) } catch (err: any) { await deleteFile(req.file.path) diff --git a/api/src/routes/api/spec/drive.spec.ts b/api/src/routes/api/spec/drive.spec.ts index aa6d9b1..1f70a56 100644 --- a/api/src/routes/api/spec/drive.spec.ts +++ b/api/src/routes/api/spec/drive.spec.ts @@ -172,7 +172,7 @@ describe('files', () => { describe('file', () => { describe('create', () => { - it('should create a SAS file on drive', async () => { + it('should create a SAS file on drive having filePath as form field', async () => { const res = await request(app) .post('/SASjsApi/drive/file') .auth(accessToken, { type: 'bearer' }) @@ -185,6 +185,19 @@ describe('files', () => { }) }) + it('should create a SAS file on drive having _filePath as query param', async () => { + const res = await request(app) + .post('/SASjsApi/drive/file') + .auth(accessToken, { type: 'bearer' }) + .query({ _filePath: '/my/path/code1.sas' }) + .attach('file', path.join(__dirname, 'files', 'sample.sas')) + + expect(res.statusCode).toEqual(200) + expect(res.body).toEqual({ + status: 'success' + }) + }) + it('should respond with Unauthorized if access token is not present', async () => { const res = await request(app) .post('/SASjsApi/drive/file') diff --git a/api/src/utils/validation.ts b/api/src/utils/validation.ts index 8f1f0cb..1bd1c31 100644 --- a/api/src/utils/validation.ts +++ b/api/src/utils/validation.ts @@ -72,12 +72,25 @@ export const getFileDriveValidation = (data: any): Joi.ValidationResult => }).validate(data) export const updateFileDriveValidation = (data: any): Joi.ValidationResult => + Joi.object({ + filePath: Joi.string().required(), + fileContent: Joi.string().required() + }).validate(data) + +export const uploadFileBodyValidation = (data: any): Joi.ValidationResult => Joi.object({ filePath: Joi.string().pattern(/.sas$/).required().messages({ 'string.pattern.base': `Valid extensions for filePath: .sas` }) }).validate(data) +export const uploadFileParamValidation = (data: any): Joi.ValidationResult => + Joi.object({ + _filePath: Joi.string().pattern(/.sas$/).required().messages({ + 'string.pattern.base': `Valid extensions for filePath: .sas` + }) + }).validate(data) + export const runSASValidation = (data: any): Joi.ValidationResult => Joi.object({ code: Joi.string().required()