feat: add DELETE services to delete files uploaded

This commit is contained in:
Divlo 2022-06-29 05:19:03 +02:00
parent 262c1d76c2
commit 7ff8d8e347
No known key found for this signature in database
GPG Key ID: 8F9478F220CE65E9
7 changed files with 215 additions and 1 deletions

View File

@ -1,5 +1,8 @@
import { application } from './application.js'
import { HOST, PORT } from './tools/configurations/index.js'
const address = await application.listen(PORT, HOST)
const address = await application.listen({
port: PORT,
host: HOST
})
console.log('\u001B[36m%s\u001B[0m', `🚀 Server listening at ${address}`)

View File

@ -0,0 +1,48 @@
import { FastifyPluginAsync, FastifySchema } from 'fastify'
import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js'
import {
DeleteParameters,
deleteParameters,
deleteUploadedFile
} from '../../../tools/utils/deleteUploadedFile.js'
export const deleteServiceSchema: FastifySchema = {
tags: ['guilds'] as string[],
security: [
{
apiKeyAuth: []
}
] as Array<{ [key: string]: [] }>,
params: deleteParameters,
response: {
200: Type.String(),
400: fastifyErrors[400],
404: fastifyErrors[404],
500: fastifyErrors[500]
}
} as const
export const deleteGuildsUploadsService: FastifyPluginAsync = async (
fastify
) => {
await fastify.register(verifyAPIKey)
await fastify.route<{
Params: DeleteParameters
}>({
method: 'DELETE',
url: '/uploads/guilds/:file',
schema: deleteServiceSchema,
handler: async (request, reply) => {
return await deleteUploadedFile({
fastify,
request,
reply,
folder: 'guilds'
})
}
})
}

View File

@ -1,19 +1,25 @@
import { FastifyPluginAsync } from 'fastify'
import { deleteGuildsUploadsService } from './guilds/delete.js'
import { getGuildsUploadsService } from './guilds/get.js'
import { postGuildsUploadsIconService } from './guilds/post.js'
import { deleteMessagesUploadsService } from './messages/delete.js'
import { getMessagesUploadsService } from './messages/get.js'
import { postMessagesUploadsService } from './messages/post.js'
import { deleteUsersUploadsService } from './users/delete.js'
import { getUsersUploadsService } from './users/get.js'
import { postUsersUploadsLogoService } from './users/post.js'
export const uploadsService: FastifyPluginAsync = async (fastify) => {
await fastify.register(deleteGuildsUploadsService)
await fastify.register(getGuildsUploadsService)
await fastify.register(postGuildsUploadsIconService)
await fastify.register(deleteMessagesUploadsService)
await fastify.register(getMessagesUploadsService)
await fastify.register(postMessagesUploadsService)
await fastify.register(deleteUsersUploadsService)
await fastify.register(getUsersUploadsService)
await fastify.register(postUsersUploadsLogoService)
}

View File

@ -0,0 +1,48 @@
import { FastifyPluginAsync, FastifySchema } from 'fastify'
import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js'
import {
DeleteParameters,
deleteParameters,
deleteUploadedFile
} from '../../../tools/utils/deleteUploadedFile.js'
export const deleteServiceSchema: FastifySchema = {
tags: ['messages'] as string[],
security: [
{
apiKeyAuth: []
}
] as Array<{ [key: string]: [] }>,
params: deleteParameters,
response: {
200: Type.String(),
400: fastifyErrors[400],
404: fastifyErrors[404],
500: fastifyErrors[500]
}
} as const
export const deleteMessagesUploadsService: FastifyPluginAsync = async (
fastify
) => {
await fastify.register(verifyAPIKey)
await fastify.route<{
Params: DeleteParameters
}>({
method: 'DELETE',
url: '/uploads/messages/:file',
schema: deleteServiceSchema,
handler: async (request, reply) => {
return await deleteUploadedFile({
fastify,
request,
reply,
folder: 'messages'
})
}
})
}

View File

@ -0,0 +1,48 @@
import { FastifyPluginAsync, FastifySchema } from 'fastify'
import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js'
import {
DeleteParameters,
deleteParameters,
deleteUploadedFile
} from '../../../tools/utils/deleteUploadedFile.js'
export const deleteServiceSchema: FastifySchema = {
tags: ['users'] as string[],
security: [
{
apiKeyAuth: []
}
] as Array<{ [key: string]: [] }>,
params: deleteParameters,
response: {
200: Type.String(),
400: fastifyErrors[400],
404: fastifyErrors[404],
500: fastifyErrors[500]
}
} as const
export const deleteUsersUploadsService: FastifyPluginAsync = async (
fastify
) => {
await fastify.register(verifyAPIKey)
await fastify.route<{
Params: DeleteParameters
}>({
method: 'DELETE',
url: '/uploads/users/:file',
schema: deleteServiceSchema,
handler: async (request, reply) => {
return await deleteUploadedFile({
fastify,
request,
reply,
folder: 'users'
})
}
})
}

View File

@ -0,0 +1,51 @@
import { IncomingMessage, Server, ServerResponse } from 'node:http'
import { fileURLToPath } from 'node:url'
import fs from 'node:fs'
import { Static, Type } from '@sinclair/typebox'
import {
FastifyInstance,
FastifyLoggerInstance,
FastifyReply,
FastifyRequest,
FastifyTypeProviderDefault
} from 'fastify'
import { isExistingFile } from './isExistingFile.js'
export const deleteParameters = Type.Object({
file: Type.String()
})
export type DeleteParameters = Static<typeof deleteParameters>
export interface DeleteUploadedFileOptions {
folder: 'guilds' | 'messages' | 'users'
fastify: FastifyInstance<
Server,
IncomingMessage,
ServerResponse,
FastifyLoggerInstance,
FastifyTypeProviderDefault
>
request: FastifyRequest<{ Params: DeleteParameters }>
reply: FastifyReply
}
export const deleteUploadedFile = async (
options: DeleteUploadedFileOptions
): Promise<string> => {
const { request, fastify, reply, folder } = options
if (request.apiKey == null) {
throw fastify.httpErrors.forbidden()
}
const { file } = request.params
const fileURL = new URL(`../../../uploads/${folder}/${file}`, import.meta.url)
const filePath = fileURLToPath(fileURL)
if (!(await isExistingFile(filePath))) {
throw fastify.httpErrors.notFound('File does not exist')
}
await fs.promises.rm(filePath, { force: true })
reply.statusCode = 200
return file
}

View File

@ -0,0 +1,10 @@
import fs from 'node:fs'
export const isExistingFile = async (path: string): Promise<boolean> => {
try {
await fs.promises.access(path, fs.constants.F_OK)
return true
} catch {
return false
}
}