mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
feat: Media attachment system
This commit is contained in:
@@ -147,11 +147,11 @@ export default {
|
||||
const hashedPassword = await hashPassword(form.password);
|
||||
const userInsert = {
|
||||
...pick(form, ['first_name', 'last_name', 'email', 'phone_number']),
|
||||
password: hashedPassword,
|
||||
active: true,
|
||||
};
|
||||
const registeredUser = await SystemUser.query().insert({
|
||||
...userInsert,
|
||||
password: hashedPassword,
|
||||
tenant_id: tenantOrganization.id,
|
||||
});
|
||||
await dbManager.createDb(`bigcapital_tenant_${organizationId}`);
|
||||
@@ -225,6 +225,7 @@ export default {
|
||||
mail.sendMail(mailOptions, (error) => {
|
||||
if (error) {
|
||||
Logger.log('error', 'Failed send reset password mail', { error, form });
|
||||
return;
|
||||
}
|
||||
Logger.log('info', 'User has been sent reset password email successfuly.', { form });
|
||||
});
|
||||
@@ -253,6 +254,7 @@ export default {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
Logger.log('info', 'User trying to reset password.');
|
||||
const { token } = req.params;
|
||||
const { password } = req.body;
|
||||
|
||||
@@ -284,6 +286,7 @@ export default {
|
||||
|
||||
// Delete the reset password token.
|
||||
await PasswordReset.query().where('token', token).delete();
|
||||
Logger.log('info', 'User password has been reset successfully.');
|
||||
|
||||
return res.status(200).send({});
|
||||
},
|
||||
|
||||
146
server/src/http/controllers/Media.js
Normal file
146
server/src/http/controllers/Media.js
Normal file
@@ -0,0 +1,146 @@
|
||||
|
||||
import express from 'express';
|
||||
import { check, param, query, validationResult } from 'express-validator';
|
||||
import fs from 'fs';
|
||||
import asyncMiddleware from '@/http/middleware/asyncMiddleware';
|
||||
import TenancyMiddleware from '@/http/middleware/TenancyMiddleware';
|
||||
import jwtAuth from '@/http/middleware/jwtAuth';
|
||||
import Logger from '@/services/Logger';
|
||||
|
||||
const fsPromises = fs.promises;
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Router constructor.
|
||||
*/
|
||||
router() {
|
||||
const router = express.Router();
|
||||
|
||||
router.use(jwtAuth);
|
||||
router.use(TenancyMiddleware);
|
||||
|
||||
router.post('/upload',
|
||||
this.upload.validation,
|
||||
asyncMiddleware(this.upload.handler));
|
||||
|
||||
router.delete('/delete/:id',
|
||||
this.delete.validation,
|
||||
asyncMiddleware(this.delete.handler));
|
||||
|
||||
router.get('/',
|
||||
this.get.validation,
|
||||
asyncMiddleware(this.get.handler));
|
||||
|
||||
return router;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve all or the given attachment ids.
|
||||
*/
|
||||
get: {
|
||||
validation: [
|
||||
query('ids'),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
const { Media } = req.models;
|
||||
const media = await Media.query().onBuild((builder) => {
|
||||
|
||||
if (req.query.ids) {
|
||||
const ids = Array.isArray(req.query.ids) ? req.query.ids : [req.query.ids];
|
||||
builder.whereIn('id', ids);
|
||||
}
|
||||
});
|
||||
|
||||
return res.status(200).send({ media });
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Uploads the given attachment file.
|
||||
*/
|
||||
upload: {
|
||||
validation: [
|
||||
// check('attachment').exists(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
if (!req.files.attachment) {
|
||||
return res.status(400).send({
|
||||
errors: [{ type: 'ATTACHMENT.NOT.FOUND', code: 200 }],
|
||||
});
|
||||
}
|
||||
const publicPath = 'storage/app/public/';
|
||||
const attachmentsMimes = ['image/png', 'image/jpeg'];
|
||||
const { attachment } = req.files;
|
||||
const { Media } = req.models;
|
||||
|
||||
const errorReasons = [];
|
||||
|
||||
// Validate the attachment.
|
||||
if (attachment && attachmentsMimes.indexOf(attachment.mimetype) === -1) {
|
||||
errorReasons.push({ type: 'ATTACHMENT.MINETYPE.NOT.SUPPORTED', code: 160 });
|
||||
}
|
||||
// Catch all error reasons to response 400.
|
||||
if (errorReasons.length > 0) {
|
||||
return res.status(400).send({ errors: errorReasons });
|
||||
}
|
||||
|
||||
try {
|
||||
await attachment.mv(`${publicPath}${req.organizationId}/${attachment.md5}.png`);
|
||||
Logger.log('info', 'Attachment uploaded successfully');
|
||||
} catch (error) {
|
||||
Logger.log('info', 'Attachment uploading failed.', { error });
|
||||
}
|
||||
|
||||
const media = await Media.query().insert({
|
||||
attachment_file: `${attachment.md5}.png`,
|
||||
});
|
||||
return res.status(200).send({ media });
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the given attachment ids from file system and database.
|
||||
*/
|
||||
delete: {
|
||||
validation: [
|
||||
param('id').exists().isNumeric().toInt(),
|
||||
],
|
||||
async handler(req, res) {
|
||||
const validationErrors = validationResult(req);
|
||||
|
||||
if (!validationErrors.isEmpty()) {
|
||||
return res.boom.badData(null, {
|
||||
code: 'validation_error', ...validationErrors,
|
||||
});
|
||||
}
|
||||
const { Media } = req.models;
|
||||
const { id } = req.params;
|
||||
const media = await Media.query().where('id', id).first();
|
||||
|
||||
if (!media) {
|
||||
return res.status(400).send({
|
||||
errors: [{ type: 'MEDIA.ID.NOT.FOUND', code: 200 }],
|
||||
});
|
||||
}
|
||||
const publicPath = 'storage/app/public/';
|
||||
const tenantPath = `${publicPath}${req.organizationId}`;
|
||||
|
||||
try {
|
||||
await fsPromises.unlink(`${tenantPath}/${media.attachmentFile}`);
|
||||
Logger.log('error', 'Attachment file has been deleted.');
|
||||
} catch (error) {
|
||||
Logger.log('error', 'Delete item attachment file delete failed.', { error });
|
||||
}
|
||||
await Media.query().where('id', media.id).delete();
|
||||
|
||||
return res.status(200).send();
|
||||
},
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user