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 fs = require("fs")
const FileType = require("file-type") const FileType = require("file-type")
const { v4: uuidv4 } = require("uuid") const { v4: uuidv4 } = require("uuid")
const limiter = rateLimit({ const limiter = rateLimit({
windowMs: 10 * 1000, windowMs: 10 * 1000,
max: 8, max: 8,
@ -31,6 +30,13 @@ const limiter = rateLimit({
legacyHeaders: false, legacyHeaders: false,
keyGenerator: (req, res) => req.user.id || req.ip keyGenerator: (req, res) => req.user.id || req.ip
}) })
const whitelist = [
"image/png",
"image/jpeg",
"image/jpg",
"image/webp",
"image/gif"
]
const storage = multer.diskStorage({ const storage = multer.diskStorage({
destination: function (req, file, cb) { destination: function (req, file, cb) {
@ -177,6 +183,7 @@ router.get("/", auth, async (req, res, next) => {
as: "chat", as: "chat",
attributes: [ attributes: [
"id", "id",
"icon",
"name", "name",
"updatedAt", "updatedAt",
"createdAt", "createdAt",
@ -2110,5 +2117,48 @@ router.post("/create", auth, async (req, res, next) => {
next(err) 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 module.exports = router

View file

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

View file

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

View file

@ -180,6 +180,15 @@
" "
v-model="settings.item.chat.name" v-model="settings.item.chat.name"
></v-text-field> ></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 <v-card-title
>Members >Members
<v-btn <v-btn
@ -716,11 +725,8 @@
<v-list-item-avatar <v-list-item-avatar
:color="$vuetify.theme.themes.dark.primary" :color="$vuetify.theme.themes.dark.primary"
> >
<v-icon v-if="item.chat.type === 'group'">
mdi-account-group
</v-icon>
<v-img <v-img
v-else-if=" v-if="
item.chat.type === 'direct' && item.chat.type === 'direct' &&
getDirectRecipient(item).avatar getDirectRecipient(item).avatar
" "
@ -739,7 +745,13 @@
<v-list-item-avatar <v-list-item-avatar
:color="$vuetify.theme.themes.dark.primary" :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 mdi-account-group
</v-icon> </v-icon>
</v-list-item-avatar> </v-list-item-avatar>
@ -750,7 +762,9 @@
{{ getDirectRecipient(item).name }} {{ getDirectRecipient(item).name }}
</v-list-item-title> </v-list-item-title>
<v-list-item-title v-else> <v-list-item-title v-else>
<span> {{ item.chat.name }} </span> <span>
{{ item.chat.name }}
</span>
</v-list-item-title> </v-list-item-title>
<v-list-item-subtitle v-if="item.chat.type === 'group'"> <v-list-item-subtitle v-if="item.chat.type === 'group'">
@ -900,6 +914,7 @@ export default {
copyTooltip: false, copyTooltip: false,
settings: { settings: {
dialog: false, dialog: false,
avatar: null,
addMembers: { addMembers: {
dialog: false, dialog: false,
users: [], users: [],
@ -986,6 +1001,28 @@ export default {
this.route.modal = false this.route.modal = false
this.route.value = "" 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() { submitFeedback() {
this.axios this.axios
.post("/api/v1/feedback", { .post("/api/v1/feedback", {