/*! * Copyright (c) 2024 PLANKA Software GmbH * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ /** * @swagger * /api/users/{id}/avatar: * patch: * summary: Update user avatar * description: Updates a user's avatar image. Users can update their own avatar, admins can update any user's avatar. * tags: * - Users * parameters: * - name: id * in: path * required: true * description: ID of the user whose avatar to update * schema: * type: string * example: 1357158568008091264 * requestBody: * required: true * content: * multipart/form-data: * schema: * type: object * required: * - file * properties: * file: * type: string * format: binary * description: Avatar image file (must be an image format) * responses: * 200: * description: Avatar updated successfully * content: * application/json: * schema: * type: object * required: * - item * properties: * item: * $ref: '#/components/schemas/User' * 400: * $ref: '#/components/responses/ValidationError' * 401: * $ref: '#/components/responses/Unauthorized' * 404: * $ref: '#/components/responses/NotFound' * 422: * $ref: '#/components/responses/UnprocessableEntity' */ const { idInput } = require('../../../utils/inputs'); const Errors = { USER_NOT_FOUND: { userNotFound: 'User not found', }, NO_FILE_WAS_UPLOADED: { noFileWasUploaded: 'No file was uploaded', }, FILE_IS_NOT_IMAGE: { fileIsNotImage: 'File is not image', }, }; module.exports = { inputs: { id: { ...idInput, required: true, }, }, exits: { userNotFound: { responseType: 'notFound', }, noFileWasUploaded: { responseType: 'unprocessableEntity', }, fileIsNotImage: { responseType: 'unprocessableEntity', }, uploadError: { responseType: 'unprocessableEntity', }, }, async fn(inputs, exits) { const { currentUser } = this.req; let user; if (currentUser.role === User.Roles.ADMIN) { user = await User.qm.getOneById(inputs.id); if (!user) { throw Errors.USER_NOT_FOUND; } } else if (inputs.id !== currentUser.id) { throw Errors.USER_NOT_FOUND; // Forbidden } else { user = currentUser; } let files; try { files = await sails.helpers.utils.receiveFile(this.req.file('file')); } catch (error) { return exits.uploadError(error.message); // TODO: add error } if (files.length === 0) { throw Errors.NO_FILE_WAS_UPLOADED; } const file = _.last(files); const avatar = await sails.helpers.users .processUploadedAvatarFile(file) .intercept('fileIsNotImage', () => Errors.FILE_IS_NOT_IMAGE); user = await sails.helpers.users.updateOne.with({ record: user, values: { avatar, }, actorUser: currentUser, request: this.req, }); if (!user) { throw Errors.USER_NOT_FOUND; } return exits.success({ item: sails.helpers.users.presentOne(user, currentUser), }); }, };