Skip to content

Commit

Permalink
Switch to prisma
Browse files Browse the repository at this point in the history
  • Loading branch information
tomitheninja committed Aug 29, 2021
1 parent 3a75e6a commit 90f112d
Show file tree
Hide file tree
Showing 25 changed files with 259 additions and 410 deletions.
2 changes: 1 addition & 1 deletion public/js/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function updateRole(id) {
const roleEl = document.getElementById('role')
const role = roleEl.value
console.log(role)
if (role == '' || !(role == 'ADMIN' || role == 'TICKET_ADMIN' || role == 'USER')) {
if (role === '' || !(role === 'Admin' || role === 'TicketAdmin' || role === 'User')) {
displayMessage('A felhasználói jogkör nem megfelelő.')
} else {
fetch(`/users/${id}/role`, {
Expand Down
11 changes: 2 additions & 9 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,18 @@ import express from 'express'
import compression from 'compression'
import cookieParser from 'cookie-parser'
import session from 'express-session'
import Knex from 'knex'
import lusca from 'lusca'
import { Model } from 'objection'
import path from 'path'
import passport from 'passport'
import RateLimit from 'express-rate-limit'

import dbConfig = require('../knexfile')
import { SESSION_SECRET } from './util/secrets'

import userRouter from './components/users/user.routes'
import ticketRouter from './components/tickets/ticket.routes'
import roomRouter, { index } from './components/rooms/room.routes'
import groupRouter from './components/groups/group.routes'

const knex = Knex(dbConfig)

Model.knex(knex)

// Create Express server
const app = express()

Expand All @@ -45,7 +38,7 @@ app.use(lusca.xssProtection(true))

// set up rate limiter: maximum requests per minute
const limiter = new RateLimit({
windowMs: 1*60*1000, // 1 minute
windowMs: 1 * 60 * 1000, // 1 minute
max: 1000 // max number of requests
})
// apply rate limiter to all requests
Expand Down Expand Up @@ -107,6 +100,6 @@ app.get('/auth/oauth/callback',
/**
* Error routes
*/
app.use('*', (req, res) => res.render('error/not-found'))
app.use('*', (req, res) => res.status(404).render('error/not-found'))

export default app
116 changes: 60 additions & 56 deletions src/components/groups/group.middlewares.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,45 @@ import * as ics from 'ics'
import winston from 'winston'
import { differenceInMinutes } from 'date-fns'

import { RoleType, User } from '../users/user'
import { Group } from './group'
import { asyncWrapper } from '../../util/asyncWrapper'
import sendMessage from '../../util/sendMessage'
import { sendEmail } from '../../util/sendEmail'
import { prisma } from '../../prisma'
import { Group, RoleType } from '@prisma/client'

export const joinGroup = asyncWrapper(async (req: Request, res: Response, next: NextFunction) => {
const user = req.user
const group = req.group

// Join group if not already in it, and it's not closed or it's the owner who joins.
// We only join the group if it is not full already
if (group.doNotDisturb && (user.id !== group.ownerId)){
if (group.doNotDisturb && (user.id !== group.ownerId)) {
sendMessage(res, 'Ez egy privát csoport!')
} else if (group.users?.find(it => it.id === user.id)) {
} else if (group.users?.find(it => it.userId === user.id)) {
sendMessage(res, 'Már tagja vagy ennek a csoportnak!')
} else if ((group.users?.length || 0) >= group.maxAttendees) {
sendMessage(res, 'Ez a csoport már tele van!')
} else if (group.endDate < new Date()) {
sendMessage(res, 'Ez a csoport már véget ért!')
} else {
await Group.relatedQuery('users')
.for(group.id)
.relate(user.id)
await prisma.membership.create({
data: {
userId: user.id,
groupId: group.id
},
select: { id: true }
})
return next()
}
res.redirect(`/groups/${req.params.id}`)
})

export const sendEmailToOwner = asyncWrapper(
async (req: Request, res: Response, next: NextFunction) => {
async (req: Request, res: Response, next: NextFunction) => {
const user = req.user
const group = req.group

const emailRecepient = await User.query().findOne({ id: group.ownerId })
const emailRecepient = await prisma.user.findFirst({ where: { id: group.ownerId } })
sendEmail([emailRecepient], {
subject: 'Csatlakoztak egy csoportodba!',
body: `${user.name} csatlakozott a(z) ${group.name} csoportodba!`,
Expand All @@ -49,37 +53,39 @@ export const sendEmailToOwner = asyncWrapper(
next()
})
export const leaveGroup = asyncWrapper(async (req: Request, res: Response, next: NextFunction) => {
await Group.relatedQuery('users')
.for(req.group.id)
.unrelate()
.where('user_id', req.user.id)
await prisma.membership.deleteMany({
where: { userId: req.user.id, groupId: req.group.id },
})

next()
})

export const isMemberInGroup =
asyncWrapper(async (req: Request, res: Response, next: NextFunction) => {
const kickableUser = await Group.relatedQuery('users').for(req.group.id)
.findOne({ userId: parseInt(req.params.userid) })
if (kickableUser) {
next()
} else {
res.redirect('/not-found')
}
})
asyncWrapper(async (req: Request, res: Response, next: NextFunction) => {
const kickableUser = await prisma.membership.findFirst({
where: { groupId: req.group.id, userId: parseInt(req.params.userid) },
select: { id: true }
})
if (kickableUser) {
next()
} else {
res.status(404).redirect('/not-found')
}
})

export const kickMember = asyncWrapper(async (req: Request, res: Response, next: NextFunction) => {
await Group.relatedQuery('users')
.for(req.group.id)
.unrelate()
.where('user_id', req.params.userid)
await prisma.membership.deleteMany({
where: { userId: parseInt(req.params.userid), groupId: req.group.id },
})

next()
})

export const sendEmailToMember = asyncWrapper(
async (req: Request, res: Response, next: NextFunction) => {
const emailRecepient = await User.query().findOne({ id: req.params.userid })
async (req: Request, res: Response, next: NextFunction) => {
const emailRecepient = await prisma.user.findFirst({
where: { id: parseInt(req.params.userid) }
})
sendEmail([emailRecepient], {
subject: 'Kirúgtak egy csoportból!',
body: `A(z) ${req.group.name} csoport szervezője vagy egy admin kirúgott a csoportból.`,
Expand All @@ -103,7 +109,7 @@ export const isGroupOwner = asyncWrapper(
export const isGroupOwnerOrAdmin = asyncWrapper(
async (req: Request, res: Response, next: NextFunction) => {
if ((req.user?.id === req.group.ownerId)
|| (req.user?.role == RoleType.ADMIN)) {
|| (req.user?.role == RoleType.Admin)) {
next()
} else {
res.render('error/forbidden')
Expand Down Expand Up @@ -162,12 +168,12 @@ function isValidHttpsUrl(str) {
return false
} // not catching bad top lvl domain (1 character)

const pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$','i') // fragment locator
const pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$', 'i') // fragment locator
// not allowing '(' and ')'
// catching 1 character TLD

Expand Down Expand Up @@ -211,7 +217,7 @@ export const validateGroup = (): ValidationChain[] => {
.custom((value, { req }) => new Date(value).getTime() < new Date(req.body.endDate).getTime())
.withMessage('A kezdés nem lehet korábban, mint a befejezés')
.custom((value, { req }) =>
differenceInMinutes(new Date(req.body.endDate), new Date(value)) <= 5*60)
differenceInMinutes(new Date(req.body.endDate), new Date(value)) <= 5 * 60)
.withMessage('A foglalás időtartama nem lehet hosszabb 5 óránál'),
check('endDate', 'A befejezés időpontja kötelező')
.exists({ checkFalsy: true, checkNull: true }),
Expand All @@ -230,7 +236,7 @@ export const checkValidMaxAttendeeLimit = asyncWrapper(
if (req.group.users.length > (req.body.maxAttendees || 100)) {
res.status(400).json(
{
errors: [{msg: 'Nem lehet kisebb a maximum jelenlét, mint a jelenlegi'}]
errors: [{ msg: 'Nem lehet kisebb a maximum jelenlét, mint a jelenlegi' }]
}
)
} else {
Expand All @@ -241,28 +247,26 @@ export const checkValidMaxAttendeeLimit = asyncWrapper(

export const checkConflicts = asyncWrapper(
async (req: Request, res: Response, next: NextFunction) => {
const { type, ...group } = req.body as Group & { type: string }
const { type, ...group } = req.body as {
[x in keyof Group]: string
} & { type: string }
if (type !== 'floor') {
return next()
}
group.startDate = new Date(req.body.startDate)
group.endDate = new Date(req.body.endDate)
const conflictingGroups = await Group.query()
.where({ room: group.room })
.andWhere(builder => {
builder
.where(bld => {
bld
.where('startDate', '<', group.endDate)
.andWhere('endDate', '>=', group.endDate)
})
.orWhere(bld => {
bld
.where('endDate', '>', group.startDate)
.andWhere('endDate', '<=', group.endDate)
})
})
.andWhereNot({ id: req.params.id ?? null })
const id = parseInt(req.params.id)
const startDate = new Date(req.body.startDate)
const endDate = new Date(req.body.endDate)
const conflictingGroups = await prisma.group.findMany({
where: {
room: parseInt(group.room),
OR: [
{ startDate: { lt: endDate }, endDate: { gte: endDate } },
{ endDate: { gt: startDate, lte: endDate } }
],
NOT: Number.isFinite(id) ? { id } : {}
},
select: { name: true }
})

if (conflictingGroups.length) {
res.status(400).json(
Expand Down
6 changes: 3 additions & 3 deletions src/components/groups/group.routes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RoleType } from '@prisma/client'
import {
format,
formatDistanceToNowStrict,
Expand All @@ -10,7 +11,6 @@ import multer from 'multer'
import { isAuthenticated } from '../../config/passport'
import { DATE_FORMAT, ROOMS } from '../../util/constants'
import { handleValidationError, checkIdParam } from '../../util/validators'
import { RoleType } from '../users/user'
import {
joinGroup,
sendEmailToOwner,
Expand Down Expand Up @@ -68,9 +68,9 @@ router.get('/:id',
checkIdParam,
getGroup,
(req, res) => {
const joined = req.group.users.some(u => u.id === req.user.id)
const joined = req.group.users.some(u => u.userId === req.user.id)
const isOwner = req.group.ownerId === req.user.id
const isAdmin = req.user.role == RoleType.ADMIN
const isAdmin = req.user.role == RoleType.Admin
res.render('group/show', {
group: req.group, joined, isOwner, format, DATE_FORMAT, isAdmin
})
Expand Down
Loading

0 comments on commit 90f112d

Please sign in to comment.