const express = require('express'); const passport = require('passport'); const crypto = require('crypto'); const db = require('../db'); const router = express.Router(); async function create_message(channel_id, msg, author) { console.log("create_message: " + channel_id + " - " + msg + " - " + author); let r = await db.query('SELECT * FROM channels WHERE id=$1', [channel_id]); if (r.rowCount < 1) { console.error('Channel not found'); return false; } const channel = r.rows[0]; if (channel.private) { // check permissions r = await db.query('SELECT * FROM allowed_users WHERE channel_id = $1 AND user_email = $2', [channel_id, author]); if (r.rowCount < 1) { console.error('You are not allowed to write in this channel'); return false; } } await db.query('INSERT INTO messages (id, channel_id, data, author) VALUES ($1,$2,$3,$4)', [crypto.randomUUID(), channel_id, msg, author]); return true; } async function list_channels(user) { console.log("list_channel: " + JSON.stringify(user)); const r = await db.query('SELECT id, detail, private FROM channels WHERE private=FALSE UNION SELECT id, detail, private FROM channels, allowed_users WHERE id = channel_id AND user_email = $1', [user]); return r.rows; } router.get('/channel', async (req, res, next) => { const channels = await list_channels(req.user.email); res.render('channels', { channels, favorites: req.cookies }); }); router.get('/channel/:id', async (req, res, next) => { const chanid = req.params.id; let r = await db.query('SELECT * FROM channels WHERE id=$1', [chanid]); const channel = r.rows[0]; r = await db.query('SELECT * FROM messages WHERE channel_id=$1', [chanid]); const messages = r.rows; if (!channel) { return res.status(404).send('not found'); } if (channel.private) { let r = await db.query('SELECT user_email FROM allowed_users WHERE user_email=$1 AND channel_id=$2', [req.user.email, chanid]); if (r.rowCount < 1) { res.locals.errormsg = 'You are not allowed to do this'; return res.status(403).render('error'); } } res.render('channel', { channel, messages }); }); router.post('/new_channel', async (req, res, next) => { console.log("/new_chanell: " + JSON.stringify(req.body)); const { channelid, detail } = req.body; const user = req.user.email; if (!/[a-zA-Z0-9]{4,40}/.test(channelid)) { return res.status(400).json({ error: 'Invalid channel name' }); } await db.query('INSERT INTO channels (id, detail, private) VALUES ($1,$2,$3)', [channelid, detail, true]); await db.query('INSERT INTO allowed_users (user_email, channel_id) VALUES ($1,$2)', [user, channelid]); res.cookie(channelid, 'true'); return res.json({ msg: 'Channel created' }); }); router.post('/new_message', async (req, res, next) => { const { msg, channelid } = req.body; console.log("/new_message: ", + JSON.stringify(req.body)); const author = req.user.email; try { await create_message(channelid, msg, author); res.json({ msg: 'Message created' }); } catch (error) { // console.error(error); res.status(500).send(error.toString()); } }); router.post('/invite', async (req, res, next) => { const { channelid, user } = req.body; const logged_user = req.user.email; console.log("/invite: ", +JSON.stringify(req.body)); let r = await db.query('SELECT user_email FROM allowed_users WHERE user_email=$1 AND channel_id=$2', [logged_user, channelid]); if (r.rowCount < 1) { return res.status(403).json({ error: 'You are not allowed to do this' }); } r = await db.query('SELECT email FROM users WHERE nickname=$1 OR email=$1', [user]); if (r.rowCount < 1) { return res.status(403).json({ error: 'User not found' }); } const invited_email = r.rows[0].email; try { await db.query('INSERT INTO allowed_users (user_email, channel_id) VALUES ($1,$2)', [invited_email, channelid]); } catch (error) { console.log(error); } return res.json({ msg: 'User invited' }); }); router.get('/broadcast', async (req, res, next) => { const channels = await list_channels(req.user.email); res.render('broadcast', { channels, favorites: req.cookies }); }); router.post('/broadcast', async (req, res, next) => { console.log("/broadcast: ", JSON.stringify(req.body)); let { msg } = req.body; const author = req.user.email; const channels = Object.keys(req.cookies); console.log('BROADCAST'); console.error(channels); let promises = []; for (const c of channels) { if (c !== 'session') promises.push(create_message(c, msg, author)); } await Promise.all(promises); res.redirect('/channel'); }); module.exports = router;