You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
7.8 KiB
278 lines
7.8 KiB
// auth.js
|
|
// Copyright (C) 2024 DTP Technologies, LLC
|
|
// All Rights Reserved
|
|
|
|
'use strict';
|
|
|
|
import express from 'express';
|
|
|
|
import { SiteController, SiteError } from '../../lib/site-lib.js';
|
|
|
|
export default class ChatController extends SiteController {
|
|
|
|
static get name ( ) { return 'ChatController'; }
|
|
static get slug ( ) { return 'chat'; }
|
|
|
|
static get MESSAGES_PER_PAGE ( ) { return 20; }
|
|
|
|
constructor (dtp) {
|
|
super(dtp, ChatController);
|
|
}
|
|
|
|
async start ( ) {
|
|
const {
|
|
// csrfToken: csrfTokenService,
|
|
// limiter: limiterService,
|
|
session: sessionService,
|
|
} = this.dtp.services;
|
|
|
|
const authRequired = sessionService.authCheckMiddleware({ requireLogin: true });
|
|
const multer = this.createMulter(ChatController.slug);
|
|
|
|
async function requireRoomOwner (req, res, next) {
|
|
if (!req.user) {
|
|
return next(new SiteError(403, 'Must be logged in to proceed'));
|
|
}
|
|
if (!res.locals.room) {
|
|
return next(new SiteError(403, 'Room not found'));
|
|
}
|
|
if (!res.locals.room.owner._id.equals(req.user._id)) {
|
|
return next(new SiteError(403, 'This is not your room'));
|
|
}
|
|
|
|
return next();
|
|
}
|
|
|
|
const router = express.Router();
|
|
this.dtp.app.use('/chat', router);
|
|
|
|
router.use(
|
|
async (req, res, next) => {
|
|
res.locals.currentView = 'auth';
|
|
return next();
|
|
},
|
|
authRequired,
|
|
);
|
|
|
|
router.param('roomId', this.populateRoomId.bind(this));
|
|
router.param('messageId', this.populateMessageId.bind(this));
|
|
|
|
router.post(
|
|
'/room/:roomId/message',
|
|
// limiterService.create(limiterService.config.chat.postRoomMessage),
|
|
multer.fields([{ name: 'imageFiles', maxCount: 6 }, { name: 'videoFiles', maxCount: 1 }]),
|
|
this.postRoomMessage.bind(this),
|
|
);
|
|
|
|
router.post(
|
|
'/room/:roomId/settings',
|
|
requireRoomOwner,
|
|
// limiterService.create(limiterService.config.chat.postRoomSettings),
|
|
this.postRoomSettings.bind(this),
|
|
);
|
|
|
|
router.post(
|
|
'/room',
|
|
// limiterService.create(limiterService.config.chat.postCreateRoom),
|
|
this.postCreateRoom.bind(this),
|
|
);
|
|
|
|
router.post(
|
|
'/message/:messageId/reaction',
|
|
// limiterService.create(limiterService.config.chat.postMessageReaction),
|
|
multer.none(),
|
|
this.postMessageReaction.bind(this),
|
|
);
|
|
|
|
router.get(
|
|
'/room/create',
|
|
// limiterService.create(limiterService.config.chat.getRoomCreateView),
|
|
this.getRoomCreateView.bind(this),
|
|
);
|
|
|
|
router.get(
|
|
'/room/:roomId/join',
|
|
// limiterService.create(limiterService.config.chat.getRoomView),
|
|
this.getRoomJoin.bind(this),
|
|
);
|
|
|
|
router.get(
|
|
'/room/:roomId/messages',
|
|
// limiterService.create(limiterService.config.chat.getRoomMessages),
|
|
this.getRoomMessages.bind(this),
|
|
);
|
|
|
|
router.get(
|
|
'/room/:roomId/settings',
|
|
// limiterService.create(limiterService.config.chat.getRoomMessages),
|
|
requireRoomOwner,
|
|
this.getRoomSettingsView.bind(this),
|
|
);
|
|
|
|
router.get(
|
|
'/room/:roomId',
|
|
// limiterService.create(limiterService.config.chat.getRoomView),
|
|
this.getRoomView.bind(this),
|
|
);
|
|
|
|
router.delete(
|
|
'/room/:roomId',
|
|
// limiterService.create(limiterService.config.chat.deleteRoom),
|
|
this.deleteRoom.bind(this),
|
|
);
|
|
|
|
return router;
|
|
}
|
|
|
|
async populateRoomId (req, res, next, roomId) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
res.locals.room = await chatService.getRoomById(roomId);
|
|
if (!res.locals.room) {
|
|
throw new SiteError(404, "The chat room doesn't exist.");
|
|
}
|
|
return next();
|
|
} catch (error) {
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async populateMessageId (req, res, next, messageId) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
res.locals.message = await chatService.getMessageById(messageId);
|
|
if (!res.locals.message) {
|
|
throw new SiteError(404, "The chat message doesn't exist.");
|
|
}
|
|
return next();
|
|
} catch (error) {
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async postMessageReaction (req, res) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
await chatService.toggleMessageReaction(req.user, res.locals.message, req.body);
|
|
return res.status(200).json({ success: true });
|
|
} catch (error) {
|
|
this.log.error('failed to send chat room message', { error });
|
|
return res.status(error.statusCode || 500).json({
|
|
success: false,
|
|
message: error.message,
|
|
});
|
|
}
|
|
}
|
|
|
|
async postRoomMessage (req, res) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
this.log.debug('post attachments', {
|
|
imageFiles: req.files.imageFiles,
|
|
videoFiles: req.files.videoFiles,
|
|
});
|
|
|
|
await chatService.sendRoomMessage(
|
|
res.locals.room,
|
|
req.user,
|
|
req.body,
|
|
req.files.imageFiles,
|
|
req.files.videoFiles,
|
|
);
|
|
|
|
return res.status(200).json({ success: true });
|
|
} catch (error) {
|
|
this.log.error('failed to send chat room message', { error });
|
|
return res.status(error.statusCode || 500).json({
|
|
success: false,
|
|
message: error.message,
|
|
});
|
|
}
|
|
}
|
|
|
|
async postRoomSettings (req, res, next) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
await chatService.updateRoomSettings(res.locals.room, req.body);
|
|
res.redirect(`/chat/room/${res.locals.room._id}`);
|
|
} catch (error) {
|
|
this.log.error('failed to present the room settings view', { error });
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async postCreateRoom (req, res, next) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
res.locals.room = await chatService.createRoom(req.user, req.body);
|
|
res.redirect(`/chat/room/${res.locals.room._id}`);
|
|
} catch (error) {
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async getRoomCreateView (req, res) {
|
|
res.render('chat/room/create');
|
|
}
|
|
|
|
async getRoomJoin (req, res, next) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
await chatService.joinRoom(res.locals.room, req.user);
|
|
res.status(200).json({ success: true, room: res.locals.room });
|
|
} catch (error) {
|
|
this.log.error('failed to join chat room', { error });
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async getRoomMessages (req, res, next) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
res.locals.pagination = this.getPaginationParameters(req, ChatController.MESSAGES_PER_PAGE);
|
|
res.locals.messages = await chatService.getRoomMessages(res.locals.room, res.locals.pagination);
|
|
|
|
res.render('chat/room/view');
|
|
} catch (error) {
|
|
this.log.error('failed to present the chat room view', { error });
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async getRoomSettingsView (req, res) {
|
|
res.render('chat/room/settings');
|
|
}
|
|
|
|
async getRoomView (req, res, next) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
res.locals.currentView = 'chat-room';
|
|
|
|
res.locals.pagination = this.getPaginationParameters(req, ChatController.MESSAGES_PER_PAGE);
|
|
res.locals.messages = await chatService.getRoomMessages(res.locals.room, res.locals.pagination);
|
|
|
|
res.render('chat/room/view');
|
|
} catch (error) {
|
|
this.log.error('failed to present the chat room view', { error });
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async deleteRoom (req, res) {
|
|
const { chat: chatService } = this.dtp.services;
|
|
try {
|
|
await chatService.destroyRoom(req.user, res.locals.room);
|
|
|
|
const displayList = this.createDisplayList('chat-room-delete');
|
|
displayList.navigateto('/');
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
} catch (error) {
|
|
this.log.error('failed to destroy chat room', { error });
|
|
res.status(error.statusCode || 500).json({
|
|
success: false,
|
|
message: error.message,
|
|
});
|
|
}
|
|
}
|
|
}
|