mirror of
https://github.com/kyantech/Palmr.git
synced 2025-10-22 22:02:00 +00:00
- Changed references from 'temp-chunks' to 'temp-uploads' across .dockerignore, Dockerfile, and various configuration files for consistency. - Introduced a new directories configuration file to manage directory paths more effectively. - Updated file handling in the server code to utilize streaming for uploads and downloads, improving performance and memory management. - Enhanced cleanup processes for temporary directories to maintain a tidy file structure.
148 lines
4.8 KiB
TypeScript
148 lines
4.8 KiB
TypeScript
import { FastifyReply, FastifyRequest } from "fastify";
|
|
|
|
import { AvatarService } from "./avatar.service";
|
|
import { createRegisterUserSchema, UpdateUserSchema } from "./dto";
|
|
import { UserService } from "./service";
|
|
|
|
export class UserController {
|
|
private userService = new UserService();
|
|
private avatarService = new AvatarService();
|
|
|
|
async register(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const schema = await createRegisterUserSchema();
|
|
const input = schema.parse(request.body);
|
|
const user = await this.userService.register(input);
|
|
return reply.status(201).send({ user, message: "User created successfully" });
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async listUsers(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const users = await this.userService.listUsers();
|
|
return reply.send(users);
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getUserById(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const { id } = request.params as { id: string };
|
|
const user = await this.userService.getUserById(id);
|
|
return reply.send(user);
|
|
} catch (error: any) {
|
|
return reply.status(404).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async updateUser(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const input = UpdateUserSchema.parse(request.body);
|
|
const { id, ...updateData } = input;
|
|
const updatedUser = await this.userService.updateUser(id, updateData);
|
|
return reply.send(updatedUser);
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async activateUser(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const { id } = request.params as { id: string };
|
|
const user = await this.userService.activateUser(id);
|
|
return reply.send(user);
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async deactivateUser(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const { id } = request.params as { id: string };
|
|
const user = await this.userService.deactivateUser(id);
|
|
return reply.send(user);
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async deleteUser(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const { id } = request.params as { id: string };
|
|
const user = await this.userService.deleteUser(id);
|
|
return reply.send(user);
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async updateUserImage(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const input = UpdateUserSchema.parse(request.body);
|
|
const { id, ...updateData } = input;
|
|
const updatedUser = await this.userService.updateUser(id, updateData);
|
|
return reply.send(updatedUser);
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async uploadAvatar(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const userId = (request as any).user?.userId;
|
|
if (!userId) {
|
|
return reply.status(401).send({ error: "Unauthorized" });
|
|
}
|
|
|
|
const file = await request.file();
|
|
if (!file) {
|
|
return reply.status(400).send({ error: "No file uploaded" });
|
|
}
|
|
|
|
if (!file.mimetype.startsWith("image/")) {
|
|
return reply.status(400).send({ error: "Only images are allowed" });
|
|
}
|
|
|
|
// Avatar files should be small (max 5MB), so we can safely use streaming to buffer
|
|
const chunks: Buffer[] = [];
|
|
const maxAvatarSize = 5 * 1024 * 1024; // 5MB
|
|
let totalSize = 0;
|
|
|
|
for await (const chunk of file.file) {
|
|
totalSize += chunk.length;
|
|
if (totalSize > maxAvatarSize) {
|
|
throw new Error("Avatar file too large. Maximum size is 5MB.");
|
|
}
|
|
chunks.push(chunk);
|
|
}
|
|
|
|
const buffer = Buffer.concat(chunks);
|
|
const base64Image = await this.avatarService.uploadAvatar(buffer);
|
|
const updatedUser = await this.userService.updateUserImage(userId, base64Image);
|
|
|
|
return reply.send(updatedUser);
|
|
} catch (error: any) {
|
|
console.error("Upload error:", error);
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async removeAvatar(request: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const userId = (request as any).user?.userId;
|
|
if (!userId) {
|
|
return reply.status(401).send({ error: "Unauthorized" });
|
|
}
|
|
|
|
await this.avatarService.deleteAvatar(userId);
|
|
const updatedUser = await this.userService.getUserById(userId);
|
|
return reply.send(updatedUser);
|
|
} catch (error: any) {
|
|
return reply.status(400).send({ error: error.message });
|
|
}
|
|
}
|
|
}
|