fix(medusa, medusa-file-*): Protected uploads for file services (#2433)
This commit is contained in:
1 parent
7d77d91a3d
commit
3c5e31c645
11 files changed
+196
-20
No files matched your search
@@ -0,0 +1,89 @@
|
||||
import fs from "fs"
|
||||
import { IFileService } from "../../../../interfaces"
|
||||
|
||||
/**
|
||||
* @oas [post] /uploads/protected
|
||||
* operationId: "PostUploadsProtected"
|
||||
* summary: "Upload files with acl or in a non-public bucket"
|
||||
* description: "Uploads at least one file to the specific fileservice that is installed in Medusa."
|
||||
* x-authenticated: true
|
||||
* requestBody:
|
||||
* content:
|
||||
* multipart/form-data:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* files:
|
||||
* type: string
|
||||
* format: binary
|
||||
* x-codeSamples:
|
||||
* - lang: JavaScript
|
||||
* label: JS Client
|
||||
* source: |
|
||||
* import Medusa from "@medusajs/medusa-js"
|
||||
* const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
|
||||
* // must be previously logged in or use api token
|
||||
* medusa.admin.uploads.createProtected(file)
|
||||
* .then(({ uploads }) => {
|
||||
* console.log(uploads.length);
|
||||
* });
|
||||
* - lang: Shell
|
||||
* label: cURL
|
||||
* source: |
|
||||
* curl --location --request POST 'https://medusa-url.com/admin/uploads/protected' \
|
||||
* --header 'Authorization: Bearer {api_token}' \
|
||||
* --header 'Content-Type: image/jpeg' \
|
||||
* --form 'files=@"<FILE_PATH_1>"' \
|
||||
* --form 'files=@"<FILE_PATH_1>"'
|
||||
* security:
|
||||
* - api_token: []
|
||||
* - cookie_auth: []
|
||||
* tags:
|
||||
* - Upload
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OK
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* properties:
|
||||
* uploads:
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* properties:
|
||||
* url:
|
||||
* type: string
|
||||
* description: The URL of the uploaded file.
|
||||
* format: uri
|
||||
* "400":
|
||||
* $ref: "#/components/responses/400_error"
|
||||
* "401":
|
||||
* $ref: "#/components/responses/unauthorized"
|
||||
* "404":
|
||||
* $ref: "#/components/responses/not_found_error"
|
||||
* "409":
|
||||
* $ref: "#/components/responses/invalid_state_error"
|
||||
* "422":
|
||||
* $ref: "#/components/responses/invalid_request_error"
|
||||
* "500":
|
||||
* $ref: "#/components/responses/500_error"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
const fileService: IFileService = req.scope.resolve("fileService")
|
||||
|
||||
const result = await Promise.all(
|
||||
req.files.map(async (f) => {
|
||||
return fileService.uploadProtected(f).then((result) => {
|
||||
fs.unlinkSync(f.path)
|
||||
return result
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
res.status(200).json({ uploads: result })
|
||||
}
|
||||
export class IAdminPostUploadsFileReq {
|
||||
originalName: string
|
||||
path: string
|
||||
}
|
||||
@@ -69,23 +69,18 @@ import fs from "fs"
|
||||
* $ref: "#/components/responses/500_error"
|
||||
*/
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
const fileService = req.scope.resolve("fileService")
|
||||
const fileService = req.scope.resolve("fileService")
|
||||
|
||||
const result = await Promise.all(
|
||||
req.files.map(async (f) => {
|
||||
return fileService.upload(f).then((result) => {
|
||||
fs.unlinkSync(f.path)
|
||||
return result
|
||||
})
|
||||
const result = await Promise.all(
|
||||
req.files.map(async (f) => {
|
||||
return fileService.upload(f).then((result) => {
|
||||
fs.unlinkSync(f.path)
|
||||
return result
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
res.status(200).json({ uploads: result })
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
}
|
||||
res.status(200).json({ uploads: result })
|
||||
}
|
||||
|
||||
export class IAdminPostUploadsFileReq {
|
||||
|
||||
@@ -18,6 +18,12 @@ export default (app) => {
|
||||
middlewares.wrap(require("./create-upload").default)
|
||||
)
|
||||
|
||||
route.post(
|
||||
"/protected",
|
||||
upload.array("files"),
|
||||
middlewares.wrap(require("./create-protected-upload").default)
|
||||
)
|
||||
|
||||
route.delete(
|
||||
"/",
|
||||
transformBody(AdminDeleteUploadsReq),
|
||||
|
||||
@@ -37,6 +37,12 @@ export interface IFileService extends TransactionBaseService {
|
||||
* */
|
||||
upload(file: Express.Multer.File): Promise<FileServiceUploadResult>
|
||||
|
||||
/**
|
||||
* upload private file to fileservice
|
||||
* @param file Multer file from express multipart/form-data
|
||||
* */
|
||||
uploadProtected(file: Express.Multer.File): Promise<FileServiceUploadResult>
|
||||
|
||||
/**
|
||||
* remove file from fileservice
|
||||
* @param fileData Remove file described by record
|
||||
@@ -76,6 +82,10 @@ export abstract class AbstractFileService
|
||||
fileData: Express.Multer.File
|
||||
): Promise<FileServiceUploadResult>
|
||||
|
||||
abstract uploadProtected(
|
||||
fileData: Express.Multer.File
|
||||
): Promise<FileServiceUploadResult>
|
||||
|
||||
abstract delete(fileData: DeleteFileType): Promise<void>
|
||||
|
||||
abstract getUploadStreamDescriptor(
|
||||
|
||||
@@ -17,6 +17,14 @@ class DefaultFileService extends AbstractFileService {
|
||||
"Please add a file service plugin in order to manipulate files in Medusa"
|
||||
)
|
||||
}
|
||||
async uploadProtected(
|
||||
fileData: Express.Multer.File
|
||||
): Promise<FileServiceUploadResult> {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
"Please add a file service plugin in order to manipulate files in Medusa"
|
||||
)
|
||||
}
|
||||
async delete(fileData: Record<string, any>): Promise<void> {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
|
||||
Reference in new issue
Block a user