Skip to content

Commit

Permalink
feat: added schemas for upload requests (#252)
Browse files Browse the repository at this point in the history
* feat: added schemas for upload requests

* Update src/presentation/http/http-api.ts

Co-authored-by: Peter Savchenko <[email protected]>

---------

Co-authored-by: Peter Savchenko <[email protected]>
  • Loading branch information
slaveeks and neSpecc authored Apr 17, 2024
1 parent 51ac441 commit ab61c3c
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 25 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@codex-team/config-loader": "^1.0.0",
"@fastify/cookie": "^8.3.0",
"@fastify/cors": "^8.3.0",
"@fastify/multipart": "^8.1.0",
"@fastify/multipart": "^8.2.0",
"@fastify/oauth2": "^7.2.1",
"@fastify/swagger": "^8.8.0",
"@fastify/swagger-ui": "^1.9.3",
Expand Down
12 changes: 10 additions & 2 deletions src/presentation/http/http-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import JoinRouter from '@presentation/http/router/join.js';
import { JoinSchemaParams, JoinSchemaResponse } from './schema/Join.js';
import { DomainError } from '@domain/entities/DomainError.js';
import UploadRouter from './router/upload.js';
import { ajvFilePlugin } from '@fastify/multipart';
import { UploadSchema } from './schema/Upload.js';


const appServerLogger = getLogger('appServer');
Expand Down Expand Up @@ -57,6 +59,12 @@ export default class HttpApi implements Api {
public async init(domainServices: DomainServices): Promise<void> {
this.server = fastify({
logger: appServerLogger as FastifyBaseLogger,
ajv: {
plugins: [
/** Allows to validate files in schema */
ajvFilePlugin
],
},
});

/**
Expand Down Expand Up @@ -84,7 +92,7 @@ export default class HttpApi implements Api {
this.addSchema();
this.addDecorators();

await this.addPoliciesCheckHook(domainServices);
this.addPoliciesCheckHook(domainServices);
await this.addApiRoutes(domainServices);
}

Expand Down Expand Up @@ -292,6 +300,7 @@ export default class HttpApi implements Api {
this.server?.addSchema(NoteSettingsSchema);
this.server?.addSchema(JoinSchemaParams);
this.server?.addSchema(JoinSchemaResponse);
this.server?.addSchema(UploadSchema);
}

/**
Expand Down Expand Up @@ -365,7 +374,6 @@ export default class HttpApi implements Api {

return;
}

/**
* If error is not a domain error, we route it to the default error handler
*/
Expand Down
1 change: 0 additions & 1 deletion src/presentation/http/middlewares/note/useNoteResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ export default function useNoteResolver(noteService: NoteService): {
} catch (error) {
logger.error('Invalid Note public passed');
logger.error(error);

await reply
.code(statusCode)
.send({
Expand Down
43 changes: 41 additions & 2 deletions src/presentation/http/router/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { FastifyPluginCallback } from 'fastify';
import type NoteService from '@domain/service/note.js';
import useNoteResolver from '../middlewares/note/useNoteResolver.js';
import type { NoteAttachmentFileLocation } from '@domain/entities/file.js';
import { StatusCodes } from 'http-status-codes';

/**
* Interface for upload router options
Expand All @@ -25,7 +26,7 @@ interface UploadRouterOptions {
fileSizeLimit: number;
}

const UploadRouter: FastifyPluginCallback<UploadRouterOptions> = (fastify, opts, done) => {
const UploadRouter: FastifyPluginCallback<UploadRouterOptions> = async (fastify, opts, done) => {
const { fileUploaderService } = opts;

/**
Expand All @@ -34,7 +35,7 @@ const UploadRouter: FastifyPluginCallback<UploadRouterOptions> = (fastify, opts,
*/
const { noteResolver } = useNoteResolver(opts.noteService);

void fastify.register(fastifyMultipart, {
await fastify.register(fastifyMultipart, {
limits: {
fieldSize: opts.fileSizeLimit,
},
Expand All @@ -55,8 +56,39 @@ const UploadRouter: FastifyPluginCallback<UploadRouterOptions> = (fastify, opts,
'userCanEdit',
],
},
schema: {
consumes: [ 'multipart/form-data' ],
params: {
notePublicId: {
$ref: 'NoteSchema#/properties/id',
},
},
body: {
type: 'object',
required: [ 'file' ],
properties: {
file: { isFile: true },
},
},
response: {
'2xx': {
type: 'object',
description: 'File key to get it from the API',
key: {
$ref: 'UploadSchema#/properties/key',
},
},
},
},
attachValidation: true,
preHandler: [ noteResolver ],
}, async (request, reply) => {
/**
* @todo solve trouble with crashing app, when validations is not passed
*/
if (request.validationError) {
return reply.code(StatusCodes.BAD_REQUEST).send(request.validationError);
}
const { userId } = request;

const location: NoteAttachmentFileLocation = {
Expand Down Expand Up @@ -90,6 +122,13 @@ const UploadRouter: FastifyPluginCallback<UploadRouterOptions> = (fastify, opts,
'notePublicOrUserInTeam',
],
},
schema: {
params: {
key: {
$ref: 'UploadSchema#/properties/key',
},
},
},
preHandler: [ noteResolver ],
}, async (request, reply) => {
const fileLocation: NoteAttachmentFileLocation = {
Expand Down
10 changes: 10 additions & 0 deletions src/presentation/http/schema/Upload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const UploadSchema = {
$id: 'UploadSchema',
type: 'object',
properties: {
key: {
type: 'string',
pattern: '[a-zA-Z0-9-_]+\.[a-zA-Z0-9]+',
},
},
};
29 changes: 10 additions & 19 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,10 @@ __metadata:
languageName: node
linkType: hard

"@fastify/busboy@npm:^1.0.0":
version: 1.2.1
resolution: "@fastify/busboy@npm:1.2.1"
dependencies:
text-decoding: ^1.0.0
checksum: 6e773a2929fd7732fd8ba8f9e1c1b9d622c6165b6e0bed9268e1785f8fd5e8b0a35d6adfe86f15a701bf7783d09c629f3437b3578d34c0246eb26f973ede20f0
"@fastify/busboy@npm:^2.1.0":
version: 2.1.1
resolution: "@fastify/busboy@npm:2.1.1"
checksum: 42c32ef75e906c9a4809c1e1930a5ca6d4ddc8d138e1a8c8ba5ea07f997db32210617d23b2e4a85fe376316a41a1a0439fc6ff2dedf5126d96f45a9d80754fb2
languageName: node
linkType: hard

Expand Down Expand Up @@ -357,17 +355,17 @@ __metadata:
languageName: node
linkType: hard

"@fastify/multipart@npm:^8.1.0":
version: 8.1.0
resolution: "@fastify/multipart@npm:8.1.0"
"@fastify/multipart@npm:^8.2.0":
version: 8.2.0
resolution: "@fastify/multipart@npm:8.2.0"
dependencies:
"@fastify/busboy": ^1.0.0
"@fastify/busboy": ^2.1.0
"@fastify/deepmerge": ^1.0.0
"@fastify/error": ^3.0.0
fastify-plugin: ^4.0.0
secure-json-parse: ^2.4.0
stream-wormhole: ^1.1.0
checksum: 06c13b6669497d2eec55cbf4be9272f67c80947f521b9fb824a9947143fef38c1918badf2b51d67e2f8ba2193ba5a914bfeb7a6164bbb0a63acbaf1f644a6471
checksum: 0135a82aa4532fc4ae99b3ef1cdd29c39e9ef3ed06fb1c509dff932043b056cbfc12523e5fa0414424356f314fa48d040486c7dbff9ab16628f56e96b5efaf4d
languageName: node
linkType: hard

Expand Down Expand Up @@ -4708,7 +4706,7 @@ __metadata:
"@codex-team/config-loader": ^1.0.0
"@fastify/cookie": ^8.3.0
"@fastify/cors": ^8.3.0
"@fastify/multipart": ^8.1.0
"@fastify/multipart": ^8.2.0
"@fastify/oauth2": ^7.2.1
"@fastify/swagger": ^8.8.0
"@fastify/swagger-ui": ^1.9.3
Expand Down Expand Up @@ -6438,13 +6436,6 @@ __metadata:
languageName: node
linkType: hard

"text-decoding@npm:^1.0.0":
version: 1.0.0
resolution: "text-decoding@npm:1.0.0"
checksum: 4b2359d8efdabea72ac470304e991913e9b82a55b1c33ab5204f115d11305ac5900add80aee5f7d22b2bcf0faebaf35b193d28a10b74adf175d9ac9d63604445
languageName: node
linkType: hard

"text-table@npm:^0.2.0":
version: 0.2.0
resolution: "text-table@npm:0.2.0"
Expand Down

0 comments on commit ab61c3c

Please sign in to comment.