This commit is contained in:
Troplo 2022-11-03 21:55:19 +11:00
parent 9e1c1f993f
commit c8ef2f58c1
4 changed files with 98 additions and 11 deletions

View file

@ -22,7 +22,6 @@ const path = require("path")
const fs = require("fs")
const FileType = require("file-type")
const { v4: uuidv4 } = require("uuid")
const limiter = rateLimit({
windowMs: 10 * 1000,
max: 8,
@ -31,6 +30,13 @@ const limiter = rateLimit({
legacyHeaders: false,
keyGenerator: (req, res) => req.user.id || req.ip
})
const whitelist = [
"image/png",
"image/jpeg",
"image/jpg",
"image/webp",
"image/gif"
]
const storage = multer.diskStorage({
destination: function (req, file, cb) {
@ -177,6 +183,7 @@ router.get("/", auth, async (req, res, next) => {
as: "chat",
attributes: [
"id",
"icon",
"name",
"updatedAt",
"createdAt",
@ -2110,5 +2117,48 @@ router.post("/create", auth, async (req, res, next) => {
next(err)
}
})
router.post(
"/avatar/:id",
auth,
upload.single("avatar"),
async (req, res, next) => {
try {
const chat = await ChatAssociation.findOne({
where: {
userId: req.user.id,
id: req.params.id,
rank: "admin"
}
})
if (!chat) throw Errors.chatNotFoundOrNotAdmin
if (req.file) {
const meta = await FileType.fromFile(req.file.path)
if (!whitelist.includes(meta.mime)) {
throw Errors.invalidFileType
}
const attachment = await Attachment.create({
userId: req.user.id,
type: "avatar",
attachment: req.file.filename,
name: req.file.originalname,
extension: meta.ext,
size: req.file.size
})
await Chat.update(
{
icon: attachment.attachment
},
{
where: {
id: chat.chatId
}
}
)
res.sendStatus(204)
}
} catch (err) {
next(err)
}
}
)
module.exports = router

View file

@ -1,6 +1,6 @@
{
"name": "colubrina",
"version": "1.0.34",
"version": "1.0.35",
"description": "Simple instant communication.",
"private": true,
"author": "Troplo <troplo@troplo.com>",

View file

@ -187,7 +187,7 @@ div .theme--dark.v-calendar-daily .v-calendar-daily__day {
}
::-webkit-scrollbar-thumb {
background: var(--v-text-lighten3) !important;
background: var(--v-text-base) !important;
border: solid 3px var(--v-bg-base) !important;
border-radius: 7px !important;
}
@ -202,4 +202,4 @@ div .theme--dark.v-calendar-daily .v-calendar-daily__day {
:root {
overflow-y: auto !important;
}
}

View file

@ -180,6 +180,15 @@
"
v-model="settings.item.chat.name"
></v-text-field>
<v-file-input
ref="avatarUpload"
accept="image/png, image/jpeg, image/jpg, image/gif, image/webp"
placeholder="Avatar"
prepend-icon=""
label="Profile Picture"
v-model="settings.avatar"
@change="doUpload"
></v-file-input>
<v-card-title
>Members
<v-btn
@ -716,11 +725,8 @@
<v-list-item-avatar
:color="$vuetify.theme.themes.dark.primary"
>
<v-icon v-if="item.chat.type === 'group'">
mdi-account-group
</v-icon>
<v-img
v-else-if="
v-if="
item.chat.type === 'direct' &&
getDirectRecipient(item).avatar
"
@ -739,7 +745,13 @@
<v-list-item-avatar
:color="$vuetify.theme.themes.dark.primary"
>
<v-icon v-if="item.chat.type === 'group'">
<v-img
v-if="item.chat.type === 'group' && item.chat.icon"
:src="
$store.state.baseURL + '/usercontent/' + item.chat.icon
"
/>
<v-icon v-else-if="item.chat.type === 'group'">
mdi-account-group
</v-icon>
</v-list-item-avatar>
@ -750,7 +762,9 @@
{{ getDirectRecipient(item).name }}
</v-list-item-title>
<v-list-item-title v-else>
<span> {{ item.chat.name }} </span>
<span>
{{ item.chat.name }}
</span>
</v-list-item-title>
<v-list-item-subtitle v-if="item.chat.type === 'group'">
@ -900,6 +914,7 @@ export default {
copyTooltip: false,
settings: {
dialog: false,
avatar: null,
addMembers: {
dialog: false,
users: [],
@ -986,6 +1001,28 @@ export default {
this.route.modal = false
this.route.value = ""
},
doUpload() {
if (this.settings.avatar) {
let formData = new FormData()
formData.append("avatar", this.settings.avatar)
this.axios
.post(
"/api/v1/communications/avatar/" + this.settings.item.id,
formData,
{
headers: {
"Content-Type": "multipart/form-data"
}
}
)
.then(() => {
this.$toast.success("Avatar updated")
})
.catch((e) => {
AjaxErrorHandler(this.$store)(e)
})
}
},
submitFeedback() {
this.axios
.post("/api/v1/feedback", {