cubash-archive/routes/team.js

866 lines
30 KiB
JavaScript

/*
@swagger
components:
schemas:
Book:
type: object
required:
- title
- author
- finished
properties:
id:
type: integer
description: The auto-generated id of the book.
title:
type: string
description: The title of your book.
author:
type: string
description: Who wrote the book?
finished:
type: boolean
description: Have you finished reading it?
createdAt:
type: string
format: date
description: The date of the record creation.
example:
title: The Pragmatic Programmer
author: Andy Hunt / Dave Thomas
finished: true
*/
let bcrypt = require('bcryptjs')
let multer = require('multer')
let express = require('express')
let router = express.Router()
const auth = require('../lib/auth')
var Recaptcha = require('express-recaptcha').RecaptchaV3;
var recaptcha = new Recaptcha('6LdlbrwZAAAAAKvtcVQhVl_QaNOqmQ4PgyW3SKHy', '6LdlbrwZAAAAAMAWPVDrL8eNPxrws6AMDtLf1bgd');
var reCAPTCHASecret = "6LdlbrwZAAAAAKvtcVQhVl_QaNOqmQ4PgyW3SKHy";
const Errors = require('../lib/errors.js')
var format = require('date-format');
let {
User, Post, teamWall, TeamInvite, TeamMemberRole, Transaction, teamPicture, userWall, StaffApplications, AdminToken, PassKey, Thread, Category, Sequelize, Ip, Ban, sequelize, Team, TeamMembers, TeamRoles
} = require('../models')
let pagination = require('../lib/pagination.js')
const sgMail = require('@sendgrid/mail');
const MailGen = require('mailgen')
const crypto = require("crypto")
const cryptoRandomString = require("crypto-random-string")
const rateLimit = require("express-rate-limit");
const emailLimiter = rateLimit({
windowMs: 60000,
max: 1, // limit each IP to 100 requests per windowMs
message: "{\"errors\":[{\"name\":\"rateLimit\",\"message\":\"You may only make 1 request to this endpoint per minute.\",\"status\":429}]}"
});
function setUserSession(req, res, username, UserId, admin) {
req.userData.loggedIn = true
req.userData.username = username
req.userData.UserId = UserId
res.cookie('username', username)
if(admin) { req.userData.admin = true }
}
router.post('/create', emailLimiter, auth, async(req, res, next) => {
try {
await Ban.isIpBanned(req.ip)
let user = await User.findOne({where: {
username: req.userData.username
}})
if(user.koins >= 300) {
let userParams = {
username: req.body.username,
name: req.body.name,
description: "This is the " + req.body.username + " team!",
banned: false,
banReason: "No reason provided",
itemsOptOut: false,
forumEnabled: false,
teamWallOptOut: false,
approved: false,
picture: "default",
OwnerId: req.userData.UserId
}
let team = await Team.create(userParams)
let teamInfo = team.toJSON()
console.log(teamInfo)
let teamRoleMembers = {
name: "Members",
teamId: teamInfo.id,
priority: 2
}
let teamRoleAdmins = {
name: "Administrators",
teamId: teamInfo.id,
administrator: true,
priority: 1
}
let memberRole = await TeamRoles.create(teamRoleMembers)
let memberRoleInfo = memberRole.toJSON()
let adminRole = await TeamRoles.create(teamRoleAdmins)
let adminRoleInfo = adminRole.toJSON()
let teamAddOwner = {
userId: req.userData.UserId,
teamId: teamInfo.id,
roles: {"deprecated": "deprecated"}
}
let teamRoleOwner = {
UserId: req.userData.UserId,
TeamId: teamInfo.id,
RoleId: adminRoleInfo.id,
Role2Id: memberRoleInfo.id
}
await TeamMembers.create(teamAddOwner)
await TeamMemberRole.create(teamRoleOwner)
await Transaction.create({UserId: user.id, priceOfPurchase: 300, text: user.username + ' purchased a Kaverti Team for 300 koins', limited: false, ipId: Ip.createIfNotExists(req.ip, user)})
res.json(team.toJSON())
} else {
throw Errors.insufficientKoins
}
} catch (e) { next(e) }
})
router.get('/view/:username', async(req, res, next) => {
try {
let queryObj = {
attributes: {exclude: ['banReason', 'TeamRoleId']},
where: {username: req.params.username}
}
let queryObjBanned = {
attributes: {exclude: ['banReason', 'description', 'picture', 'forumEnabled', 'TeamRoleId', 'OwnerId']},
where: {username: req.params.username}
}
if(req.query.wall) {
let {from, limit} = pagination.getPaginationProps(req.query, true)
let postInclude = {
model: teamWall,
include: teamWall.includeOptions(),
limit,
order: [['id', 'DESC']],
}
if (from !== null) {
postInclude.where = {id: {$lte: from}}
}
queryObj.include = [postInclude]
let user = await Team.findOne(queryObj)
if (!user) throw Errors.accountDoesNotExist
if(user.banned) {
throw Errors.teamBanned
}
if (user.teamWallOptOut) {
res.json({teamWalls: []})
}
res.json(Object.assign(user.toJSON(limit)))
} else {
let team = await Team.findOne(queryObj)
if (!team) throw Errors.accountDoesNotExist
if(!team.banned) {
res.json(team.toJSON())
} else {
let team = await Team.findOne(queryObjBanned)
res.json(team.toJSON())
}
}
} catch (err) { next(err) }
})
router.get('/view/:username/picture', async (req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
if(!user) throw Errors.accountDoesNotExist
let picture = await teamPicture.findOne({
where: {
TeamId: user.id
}
})
if(!picture) {
res.status(404)
res.json({picture: "http://localhost/teams/unknown-light.png"})
} else if(!user.banned) {
res.writeHead(200, {
'Content-Type': picture.mimetype,
'Content-disposition': 'attachment;filename=kaverti-team-profile-picture',
'Content-Length': picture.file.length
})
res.end(new Buffer.from(picture.file, 'binary'))
} else {
res.status(404)
res.json({picture: "http://localhost/teams/unknown-light.png"})
}
} catch (e) { next(e) }
})
router.get('/view/:username/members', async(req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
if(user) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamMembers.findAll({
order: [['id', 'DESC']],
where: {
TeamId: user.id
},
include: [
{ model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture', 'description'] }
]
})
res.json(team)
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/view/:username/userRoles', async(req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
if(user) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamMemberRole.findAll({
order: [['id', 'DESC']],
where: {
TeamId: user.id
},
include: [
{ model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] },
{ model: TeamRoles, as: 'Role' },
{ model: TeamRoles, as: 'Role2' },
{ model: TeamRoles, as: 'Role3' },
{ model: TeamRoles, as: 'Role4' },
{ model: TeamRoles, as: 'Role5' },
{ model: TeamRoles, as: 'Role6' },
{ model: TeamRoles, as: 'Role7' },
{ model: TeamRoles, as: 'Role8' },
{ model: TeamRoles, as: 'Role9' },
{ model: TeamRoles, as: 'Role10' },
]
})
res.json(team)
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/view/:username/roles', async(req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
if(user) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamRoles.findAll({
order: [['priority', 'ASC']],
where: {
TeamId: user.id
},
})
res.json(team)
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/view/:username/roles/id/:id', async(req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
if(user) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamMemberRole.findAll({
order: [['id', 'DESC']],
where: {
TeamId: user.id,
RoleId: req.params.id
},
include: { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] },
})
res.json(team)
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/view/:username/roles/name/:id', async(req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
let userParam = await User.findOne({
where: {
username: req.params.id
}
})
if(user && userParam) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamMemberRole.findAll({
order: [['id', 'DESC']],
where: {
TeamId: user.id,
UserID: userParam.id
},
include: [ { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] }, { model: TeamRoles, as: 'Role' } ]
})
res.json(team)
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/view/:username/roles/permissions/:id', async(req, res, next) => {
try {
let team = await Team.findOne({
where: {username: req.params.username}
});
let user = await User.findOne({
where: {username: req.params.id}
});
if(user && team) {
let isAuthMem = await TeamMembers.findOne({
where: {UserId: user.id, TeamId: team.id}
});
if (!isAuthMem) {
throw Errors.notInTeam
}
let isAuthRole = await TeamMemberRole.findOne({
where: {UserId: user.id, TeamId: team.id}
})
let isAuthOwner = await Team.findOne({
where: {OwnerId: user.id, id: team.id}
})
let isAuth1 = await TeamRoles.findOne({
where: {id: isAuthRole.RoleId, inviteUsers: true}
})
let isAuth2 = await TeamRoles.findOne({
where: {id: isAuthRole.Role2Id, inviteUsers: true}
})
let isAuth3 = await TeamRoles.findOne({
where: {id: isAuthRole.Role3Id, inviteUsers: true}
})
let isAuth4 = await TeamRoles.findOne({
where: {id: isAuthRole.Role4Id, inviteUsers: true}
})
let isAuth5 = await TeamRoles.findOne({
where: {id: isAuthRole.Role5Id, inviteUsers: true}
})
let isAuth6 = await TeamRoles.findOne({
where: {id: isAuthRole.Role6Id, inviteUsers: true}
})
let isAuth7 = await TeamRoles.findOne({
where: {id: isAuthRole.Role7Id, inviteUsers: true}
})
let isAuth8 = await TeamRoles.findOne({
where: {id: isAuthRole.Role8Id, inviteUsers: true}
})
let isAuth9 = await TeamRoles.findOne({
where: {id: isAuthRole.Role9Id, inviteUsers: true}
})
let isAuth10 = await TeamRoles.findOne({
where: {id: isAuthRole.Role10Id, inviteUsers: true}
})
const allowArray = [
isAuth1,
isAuth2,
isAuth3,
isAuth4,
isAuth5,
isAuth6,
isAuth7,
isAuth8,
isAuth9,
isAuth10,
isAuthOwner
]
let invite = allowArray.some(function (el) {
return el !== null;
});
let isAuth11 = await TeamRoles.findOne({
where: {id: isAuthRole.RoleId, administrator: true}
})
let isAuth12 = await TeamRoles.findOne({
where: {id: isAuthRole.Role2Id, administrator: true}
})
let isAuth13 = await TeamRoles.findOne({
where: {id: isAuthRole.Role3Id, administrator: true}
})
let isAuth14 = await TeamRoles.findOne({
where: {id: isAuthRole.Role4Id, administrator: true}
})
let isAuth15 = await TeamRoles.findOne({
where: {id: isAuthRole.Role5Id, administrator: true}
})
let isAuth16 = await TeamRoles.findOne({
where: {id: isAuthRole.Role6Id, administrator: true}
})
let isAuth17 = await TeamRoles.findOne({
where: {id: isAuthRole.Role7Id, administrator: true}
})
let isAuth18 = await TeamRoles.findOne({
where: {id: isAuthRole.Role8Id, administrator: true}
})
let isAuth19 = await TeamRoles.findOne({
where: {id: isAuthRole.Role9Id, administrator: true}
})
let isAuth20 = await TeamRoles.findOne({
where: {id: isAuthRole.Role10Id, administrator: true}
})
const adminArray = [
isAuth10,
isAuth12,
isAuth13,
isAuth14,
isAuth15,
isAuth16,
isAuth17,
isAuth18,
isAuth19,
isAuth20,
isAuthOwner
]
let administrator = adminArray.some(function (el) {
return el !== null;
});
let isAuth21 = await TeamRoles.findOne({
where: {id: isAuthRole.RoleId, changeTeamMeta: true}
})
let isAuth22 = await TeamRoles.findOne({
where: {id: isAuthRole.Role2Id, changeTeamMeta: true}
})
let isAuth23 = await TeamRoles.findOne({
where: {id: isAuthRole.Role3Id, changeTeamMeta: true}
})
let isAuth24 = await TeamRoles.findOne({
where: {id: isAuthRole.Role4Id, changeTeamMeta: true}
})
let isAuth25 = await TeamRoles.findOne({
where: {id: isAuthRole.Role5Id, changeTeamMeta: true}
})
let isAuth26 = await TeamRoles.findOne({
where: {id: isAuthRole.Role6Id, changeTeamMeta: true}
})
let isAuth27 = await TeamRoles.findOne({
where: {id: isAuthRole.Role7Id, changeTeamMeta: true}
})
let isAuth28 = await TeamRoles.findOne({
where: {id: isAuthRole.Role8Id, changeTeamMeta: true}
})
let isAuth29 = await TeamRoles.findOne({
where: {id: isAuthRole.Role9Id, changeTeamMeta: true}
})
let isAuth30 = await TeamRoles.findOne({
where: {id: isAuthRole.Role10Id, changeTeamMeta: true}
})
const metaArray = [
isAuth21,
isAuth22,
isAuth23,
isAuth24,
isAuth25,
isAuth26,
isAuth27,
isAuth28,
isAuth29,
isAuth30,
isAuthOwner
]
let meta = metaArray.some(function (el) {
return el !== null;
});
let isAuth31 = await TeamRoles.findOne({
where: {id: isAuthRole.RoleId, changeTeamRoles: true}
})
let isAuth32 = await TeamRoles.findOne({
where: {id: isAuthRole.Role2Id, changeTeamRoles: true}
})
let isAuth33 = await TeamRoles.findOne({
where: {id: isAuthRole.Role3Id, changeTeamRoles: true}
})
let isAuth34 = await TeamRoles.findOne({
where: {id: isAuthRole.Role4Id, changeTeamRoles: true}
})
let isAuth35 = await TeamRoles.findOne({
where: {id: isAuthRole.Role5Id, changeTeamRoles: true}
})
let isAuth36 = await TeamRoles.findOne({
where: {id: isAuthRole.Role6Id, changeTeamRoles: true}
})
let isAuth37 = await TeamRoles.findOne({
where: {id: isAuthRole.Role7Id, changeTeamRoles: true}
})
let isAuth38 = await TeamRoles.findOne({
where: {id: isAuthRole.Role8Id, changeTeamRoles: true}
})
let isAuth39 = await TeamRoles.findOne({
where: {id: isAuthRole.Role9Id, changeTeamRoles: true}
})
let isAuth40 = await TeamRoles.findOne({
where: {id: isAuthRole.Role10Id, changeTeamRoles: true}
})
const roleArray = [
isAuth31,
isAuth32,
isAuth33,
isAuth34,
isAuth35,
isAuth36,
isAuth37,
isAuth38,
isAuth39,
isAuth40,
isAuthOwner
]
let role = roleArray.some(function (el) {
return el !== null;
});
if (team) {
if (team.banned) {
res.status(200)
res.json({administrator: false, inviteUsers: false})
}
res.json({inviteUsers: invite, administrator: administrator, changeTeamMeta: meta, changeTeamRoles: role})
} else {
throw Errors.accountDoesNotExist
}
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/', async(req, res, next) => {
try {
let sortFields = {
createdAt: 'X.id',
username: 'X.username',
};
let offset = Number.isInteger(+req.query.offset) ? +req.query.offset : 0;
let havingClause = 'Having Teams.banned = false';
if(req.query.search) {
//I.e. if there is not already a HAVING clause
if(!havingClause.length) {
havingClause = 'HAVING ';
} else {
havingClause += ' AND ';
}
havingClause += 'Team.username LIKE $search';
}
let sql = `
SELECT X.username, X.approved, X.name, X.picture, X.id, X.forumEnabled, X.description, X.banned, X.createdAt, X.updatedAt
FROM (
SELECT Teams.*
FROM Teams
GROUP BY Teams.id
${havingClause}
) as X
GROUP BY X.id
ORDER BY ${sortFields[req.query.sort] || 'X.id'} ${req.query.order === 'asc' ? 'DESC' : 'ASC'}
LIMIT 30
OFFSET ${offset}
`;
let users = await sequelize.query(sql, {
model: Team,
bind: { search: req.query.search + '%' }
});
res.json(users)
} catch (e) { next(e) }
})
router.put('/join/:username', auth, async(req, res, next) => {
try {
await Ban.ReadOnlyMode(req.userData.UserId)
let team = await Team.findOne({
where: { username: req.params.username }
})
if(team) {
if(team.banned) {
throw Errors.teamBanned
}
if(team.inviteOnly) {
throw Errors.inviteOnly
}
let queryObj3 = {
where: {userId: req.userData.UserId, teamId: team.id},
}
let teamJoinTest = await TeamMembers.findOne(queryObj3)
if(teamJoinTest) {
throw Errors.joinedTeam
}
let role = await TeamRoles.findOne({
where: {teamId: team.id, name: "Members"}
})
let join = {
userId: req.userData.UserId,
teamId: team.id,
roles: {"deprecated": "deprecated"}
}
console.log(role)
let roleUser = {
UserId: req.userData.UserId,
TeamId: team.id,
RoleId: role.id
}
await TeamMembers.create(join)
await TeamMemberRole.create(roleUser)
res.status(200)
res.json({success: true})
} else {
throw Errors.teamDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/check/:username', auth, async(req, res, next) => {
try {
let team = await Team.findOne({
where: {username: req.params.username}
});
if(team) {
let queryObj3 = {
where: {userId: req.userData.UserId, teamId: team.id},
}
if(team.banned) {
res.status(200)
res.json({success: false})
}
let teamJoinTest = await TeamMembers.findOne(queryObj3)
if (teamJoinTest) {
res.status(200)
res.json({success: true})
} else if (!teamJoinTest) {
res.status(200)
res.json({success: false})
}
} else {
throw Errors.teamDoesNotExist
}
} catch (e) { next(e) }
})
router.put('/leave/:username', auth, async(req, res, next) => {
try {
await Ban.ReadOnlyMode(req.userData.UserId)
let team = await Team.findOne({
where: { username: req.params.username }
})
if(team) {
if(team.banned) {
throw Errors.teamBanned
}
let queryObj3 = {
where: {userId: req.userData.UserId, teamId: team.id},
}
let teamLeaveTeam = await TeamMembers.findOne(queryObj3)
if(teamLeaveTeam) {
let queryObj4 = {
where: {UserId: req.userData.UserId, TeamId: team.id},
}
let teamLeaveRoles = await TeamMemberRole.findAll(queryObj4)
await teamLeaveTeam.leaveTeam()
teamLeaveRoles.forEach((TeamMemberRole) => TeamMemberRole.leaveTeam());
res.status(200)
res.json({success: true})
} else {
throw Errors.notInTeam
}
} else {
throw Errors.teamDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/invite/:username', async(req, res, next) => {
try {
let code = await TeamInvite.findOne({
where: {code: req.params.username},
include: [{model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture']}, {model: Team, attributes: { exclude: [ 'banReason' ]}}, {model: TeamRoles, as: 'Role'}]
})
if (code) {
if(code.maxUses === 0) {
res.status(200)
res.json(code.toJSON())
} else if(code.uses >= code.maxUses) {
throw Errors.invalidInvite
} else if(code.uses < code.maxUses) {
res.status(200)
res.json(code.toJSON())
} else {
throw Errors.invalidInvite
}
} else {
throw Errors.invalidInvite
}
} catch (e) { next(e) }
})
router.post('/invite/:code', auth, async(req, res, next) => {
try {
await Ban.ReadOnlyMode(req.userData.UserId)
let code = await TeamInvite.findOne({
where: {code: req.params.code}
})
if (code) {
let team = await Team.findOne({
where: {id: code.TeamId}
})
if (team.banned) {
throw Errors.teamBanned
}
let queryObj3 = {
where: {userId: req.userData.UserId, teamId: team.id},
}
let teamJoinTest = await TeamMembers.findOne(queryObj3)
if (teamJoinTest) {
throw Errors.joinedTeam
}
if(code.maxUses > 0 && code.maxUses === code.uses) {
console.log('failed at maxUses over code.uses')
throw Errors.invalidInvite
} else if(code.maxUses === 0) {
let role = await TeamRoles.findOne({
where: {teamId: team.id, name: "Members"}
})
if(code.RoleId > 0) {
let roleLookup = await TeamRoles.findOne({
where: {id: code.RoleId, TeamId: team.id}
})
if(roleLookup) {
let join = {
userId: req.userData.UserId,
teamId: team.id,
roles: {"deprecated": "deprecated"}
}
let roleUser = {
UserId: req.userData.UserId,
TeamId: team.id,
RoleId: role.id,
Role2Id: roleLookup.id
}
await TeamInvite.update({ uses: + 1}, {
where: {id: code.id, TeamId: team.id}
})
await TeamMembers.create(join)
await TeamMemberRole.create(roleUser)
res.status(200)
res.json({success: true})
} else {
let join = {
userId: req.userData.UserId,
teamId: team.id,
roles: {"deprecated": "deprecated"}
}
console.log(role)
let roleUser = {
UserId: req.userData.UserId,
TeamId: team.id,
RoleId: role.id
}
await TeamInvite.update({ uses: + 1}, {
where: {id: code.id, TeamId: team.id}
})
await TeamMembers.create(join)
await TeamMemberRole.create(roleUser)
res.status(200)
res.json({success: true})
}
} else {
let join = {
userId: req.userData.UserId,
teamId: team.id,
roles: {"deprecated": "deprecated"}
}
let roleUser = {
UserId: req.userData.UserId,
TeamId: team.id,
RoleId: role.id
}
await TeamInvite.update({ uses: + 1}, {
where: {id: code.id, TeamId: team.id}
})
await TeamMembers.create(join)
await TeamMemberRole.create(roleUser)
res.status(200)
res.json({success: true})
}
} else if(code.uses < code.maxUses) {
let role = await TeamRoles.findOne({
where: {teamId: team.id, name: "Members"}
})
let join = {
userId: req.userData.UserId,
teamId: team.id,
roles: {"deprecated": "deprecated"}
}
let roleUser = {
UserId: req.userData.UserId,
TeamId: team.id,
RoleId: role.id,
}
await TeamInvite.update({ uses: + 1}, {
where: {id: code.id, TeamId: team.id}
})
await TeamMembers.create(join)
await TeamMemberRole.create(roleUser)
res.status(200)
res.json({success: true})
} else {
console.log('failed at second last else')
throw Errors.invalidInvite
}
} else {
console.log('failed at last else')
throw Errors.invalidInvite
}
} catch (e) { next(e) }
})
module.exports = router;