Proper Teams Role API, Join & Leave

This commit is contained in:
Troplo 2020-11-19 22:43:03 +11:00
parent 74e6f420f4
commit 44fe52be54
12 changed files with 347 additions and 78 deletions

View File

@ -3,17 +3,43 @@
<div class="section">
<div class="column">
<div class="box">
<div class="field">
<b-radio v-model="createType"
size="is-large"
native-value="Shirt">
Shirt
</b-radio>
<b-radio v-model="createType"
size="is-large"
native-value="Pants">
Pants
</b-radio>
<div v-if="stage === 1">
<center><h1>Hi, what asset would you like to create?</h1>
<b-button @click="createType = 'hat'; stage = 2" v-if="$store.state.admin" class="is-large">
Hat
</b-button>
&nbsp;
<b-button @click="createType = 'face'; stage = 2" v-if="$store.state.admin" class="is-large">
Face
</b-button>
&nbsp;
<b-button @click="createType = 'shirt'; stage = 2" class="is-large">
Shirt
</b-button>
&nbsp;
<b-button @click="createType = 'pants'; stage = 2" class="is-large">
Pants
</b-button>
</center>
</div>
<div v-if="stage === 2">
<b-button @click="goBack()">Go back</b-button>
<center>
<h1>
Upload {{createType}}
</h1>
<b-input :value="$store.state.username + '\'s ' + createType"
maxlength="30">
</b-input>
<b-field class="file">
<b-upload v-model="file" expanded>
<a class="button is-primary is-fullwidth">
<b-icon icon="upload"></b-icon>
<span>{{ file.name || "Click to upload"}}</span>
</a>
</b-upload>
</b-field>
</center>
</div>
</div>
</div>
@ -25,7 +51,18 @@ export default {
name: 'MarketplaceCreate',
data() {
return {
createType: 'shirt'
createType: null,
stage: 1,
file: '',
dropFiles: null
}
},
methods: {
goBack() {
this.createType = null
this.stage = 1
this.file = null
this.dropFiles = null
}
}
}

View File

@ -75,6 +75,12 @@
<b-button v-if="$store.state.username && $store.state.UserId === user.OwnerId" class="button is-primary" style="float: right" @click='$router.push(`/team/${user.username}`)'>
Edit Team
</b-button>
<b-button v-if="$store.state.username && $store.state.UserId !== user.OwnerId && !joined" class="button is-primary" style="float: right" @click='joinTeam()'>
Join Team
</b-button>
<b-button v-if="$store.state.username && $store.state.UserId !== user.OwnerId && joined" class="button is-danger" style="float: right" @click='leaveTeam()'>
Leave Team
</b-button>
</div>
</div>
</div>
@ -104,11 +110,10 @@
</template>
<script>
import AjaxErrorHandler from '../../assets/js/errorHandler'
import MenuButton from '../MenuButton'
export default {
name: 'user',
name: 'Team',
// eslint-disable-next-line vue/no-unused-components
components: {MenuButton},
data () {
@ -124,6 +129,7 @@ export default {
username: this.$route.params.username,
user: null,
relationship: false,
joined: false,
relationships: {
type: ''
}
@ -159,54 +165,47 @@ export default {
},
fetchData () {
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `user/${this.$route.params.username}`)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/view/${this.$route.params.username}`)
.then(res => this.user = res.data)
},
scrubDesc () {
leaveTeam () {
this.axios
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/user/scrub', {
description: "descscram",
user: this.username
})
.then(() => {
this.resetFetchData()
})
.catch(AjaxErrorHandler(this.$store))
},
scrubUsername () {
this.axios
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/user/scrub', {
username: "usernamescram",
user: this.username
})
.then(() => {
this.description.loading = false
})
.catch(AjaxErrorHandler(this.$store))
},
doRelationship () {
this.axios
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'relationships/' + this.user.username, {
type: this.relationships.type
})
.then(() => {
this.description.loading = false
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/leave/' + this.user.username)
.then(res => {
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/check/' + this.$route.params.username)
.then(res => {
this.joined = res.data.success
})
res(1)
})
.catch(e => {
this.description.loading = false
AjaxErrorHandler(this.$store)(e, error => {
this.description.error = error.message
})
e()
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/check/' + this.$route.params.username)
.then(res => {
this.joined = res.data.success
})
})
},
joinTeam () {
this.axios
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/join/' + this.user.username)
.then(res => {
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/check/' + this.$route.params.username)
.then(res => {
this.joined = res.data.success
})
res(1)
})
.catch(e => {
AjaxErrorHandler(this.$store)(e, error => {
this.description.error = error.message
})
e()
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/check/' + this.$route.params.username)
.then(res => {
this.joined = res.data.success
})
})
},
getIndexFromRoute (path) {
@ -229,6 +228,11 @@ export default {
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/view/${this.$route.params.username}`)
.then(res => this.user = res.data)
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/check/' + this.$route.params.username)
.then(res => {
this.joined = res.data.success
})
}
}
</script>

View File

@ -214,9 +214,8 @@
this.tcreateProd.loading = true
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/create`, postParams).then(res => {
this.signup.loading = false
this.$store.commit('setUsername', res.data.username)
this.closeAccountModal()
this.tcreateProd.loading = false
this.closeAccountModal(res)
}).catch(e => {
this.tcreateProd.loading = false
AjaxErrorHandler(this.$store)(e);

View File

@ -16,13 +16,25 @@ let Errors = {
400
],
teamBanned: [
'This team is banned and cannot be interacted or viewed.',
'This team is banned and cannot be interacted with or viewed.',
400
],
notInTeam: [
'You need to be in this Team to do that action.',
400
],
teamDoesNotExist: [
'This team does not exist.',
400
],
itemUnavailable: [
'This item is currently unavailable at this time.',
400
],
joinedTeam: [
'You are already in this Team',
400
],
LoginRequired: [
'Due to the nature of this action, a login is required.',
401

View File

@ -0,0 +1,27 @@
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('TeamMemberRoles', {
id: {
type: Sequelize.BIGINT,
primaryKey: true,
autoIncrement: true
},
TeamId: {
type: Sequelize.BIGINT,
allowNull: false
},
RoleId: {
type: Sequelize.BIGINT,
allowNull: false
},
UserId: {
type: Sequelize.BIGINT,
allowNull: false
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('TeamMemberRoles');
}
};

View File

@ -0,0 +1,20 @@
module.exports = {
up(queryInterface, Sequelize) {
return Promise.all([
queryInterface.addColumn(
'TeamMemberRoles',
'UpdatedAt',
{
type: Sequelize.DATE
},
),
queryInterface.addColumn(
'TeamMemberRoles',
'CreatedAt',
{
type: Sequelize.DATE
},
),
]);
},
}

View File

@ -0,0 +1,56 @@
let createDOMPurify = require('dompurify');
let { JSDOM } = require('jsdom');
let window = new JSDOM('').window;
let DOMPurify = createDOMPurify(window);
var escaped_str = require('querystring')
const Errors = require('../lib/errors')
let pagination = require('../lib/pagination.js')
module.exports = (sequelize, DataTypes) => {
let TeamMemberRole = sequelize.define('TeamMemberRole', {
TeamId: {
type: DataTypes.BIGINT,
allowNull: false
},
RoleId: {
type: DataTypes.BIGINT
},
UserId: {
type: DataTypes.BIGINT,
allowNull: false
},
createdAt: {
type: DataTypes.DATE,
allowNull: false
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false
}
}, {
classMethods: {
associate(models) {
TeamMemberRole.belongsTo(models.User)
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role'})
TeamMemberRole.belongsTo(models.Team)
},
includeOptions() {
let models = sequelize.models
return [
{model: models.User, as: 'User', attributes: ['username', 'createdAt', 'id', 'color', 'picture']},
{model: models.TeamRoles, as: 'Role'},
]
}
},
instanceMethods: {
async leaveTeam() {
await this.destroy()
}
}
})
return TeamMemberRole
}

View File

@ -16,13 +16,12 @@ module.exports = (sequelize, DataTypes) => {
},
userId: DataTypes.BIGINT,
roles: {
type: DataTypes.TEXT,
type: DataTypes.JSON,
defaultValue: "1"
},
}, {
classMethods: {
associate (models) {
TeamMembers.belongsTo(models.TeamRoles)
TeamMembers.belongsTo(models.User)
},
includeOptions () {
@ -32,7 +31,11 @@ module.exports = (sequelize, DataTypes) => {
{ model: models.User, as: 'user', attributes: ['username', 'createdAt', 'id', 'color', 'picture']},
]
}
},
}, instanceMethods: {
async leaveTeam() {
await this.destroy()
}
}
})
return TeamMembers

View File

@ -56,6 +56,9 @@ module.exports = (sequelize, DataTypes) => {
priority: {
type: DataTypes.BIGINT,
default: 1
},
teamId: {
type: DataTypes.BIGINT
}
}, {
instanceMethods: {

View File

@ -66,7 +66,7 @@ router.delete('/:ban_id', auth, async(req, res, next) => {
error: 'ban does not exist',
value: req.body.userId
})
AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' unbanned UID:' + ban.UserId + ' and succeeded (unbanned).'})
AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' unbanned UID: ' + ban.UserId + ' and succeeded (unbanned).'})
await ban.destroy()
res.json({ success: true })

View File

@ -41,7 +41,7 @@ var reCAPTCHASecret = "6LdlbrwZAAAAAKvtcVQhVl_QaNOqmQ4PgyW3SKHy";
const Errors = require('../lib/errors.js')
var format = require('date-format');
let {
User, Post, teamWall, Transaction, teamPicture, userWall, StaffApplications, AdminToken, PassKey, Thread, Category, Sequelize, Ip, Ban, sequelize, Team, TeamMembers, TeamRoles
User, Post, teamWall, 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');
@ -72,7 +72,6 @@ router.post('/create', emailLimiter, auth, async(req, res, next) => {
username: req.userData.username
}})
if(user.koins >= 300) {
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)})
let userParams = {
username: req.body.username,
name: req.body.name,
@ -84,10 +83,11 @@ router.post('/create', emailLimiter, auth, async(req, res, next) => {
teamWallOptOut: false,
approved: false,
picture: "default",
OwnerId: req.userData.id
OwnerId: req.userData.UserId
}
let team = await Team.create(userParams)
let teamInfo = team.toJSON()
console.log(teamInfo)
let teamRoleMembers = {
name: "Members",
teamId: teamInfo.id,
@ -103,12 +103,25 @@ router.post('/create', emailLimiter, auth, async(req, res, next) => {
let memberRoleInfo = memberRole.toJSON()
let adminRole = await TeamRoles.create(teamRoleAdmins)
let adminRoleInfo = adminRole.toJSON()
let teamMemberOwner = {
userId: req.userData.id,
let teamAddOwner = {
userId: req.userData.UserId,
teamId: teamInfo.id,
roles: memberRoleInfo.id + ", " + adminRoleInfo.id
roles: {"deprecated": "deprecated"}
}
await TeamMembers.create(teamMemberOwner)
let teamRoleOwner = {
UserId: req.userData.UserId,
TeamId: teamInfo.id,
RoleId: adminRoleInfo.id
}
let teamRoleOwnerUser = {
UserId: req.userData.UserId,
TeamId: teamInfo.id,
RoleId: memberRoleInfo.id
}
await TeamMembers.create(teamAddOwner)
await TeamMemberRole.create(teamRoleOwner)
await TeamMemberRole.create(teamRoleOwnerUser)
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
@ -203,10 +216,11 @@ router.get('/view/:username/members', async(req, res, next) => {
username: req.params.username
}
})
if(user.banned) {
throw Errors.teamBanned
}
if(user) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamMembers.findAll({
order: [['id', 'DESC']],
where: {
@ -214,10 +228,6 @@ router.get('/view/:username/members', async(req, res, next) => {
},
include: [
{ model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture', 'locked'] },
{
model: TeamRoles, order: [['id']], where: { teamRoles }, include:
[{ model: User, attributes: ['username', 'id'] }]
}
]
})
res.json(team)
@ -272,25 +282,96 @@ router.put('/join/:username', auth, async(req, res, next) => {
let team = await Team.findOne({
where: { username: req.params.username }
})
console.log(team.id)
if(team) {
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
}
let role = await TeamRoles.findOne({
where: {teamId: team.id, name: "Members"}
})
console.log(role)
let join = {
userId: req.userData.id,
userId: req.userData.UserId,
teamId: team.id,
roles: role.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.unknown
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.username)
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) }
})

View File

@ -127,4 +127,31 @@ router.put('/modify/:username', auth, async(req, res, next) => {
} catch (e) { next(e) }
})
router.post('/roles/create/: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) }
})
module.exports = router;