forked from kaverti/website
More Team Roles, and Admin stuff
This commit is contained in:
parent
8d9ce2ed14
commit
70fa581cff
|
@ -1,5 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
port: process.env.PORT || 23981,
|
port: process.env.PORT || 23981,
|
||||||
sessionSecret: process.env.SESSION_SECRET || 'iouydhtrfguyrthgftryhgidrhytgidhytiglriltnhgrhtiuygrthiugritghiyutrcginhrtijghurfcuhjgnioergjfuiehtiehtiehyritheithreifbhgehfbdxhbkvfdbhjkvgdkhnjUIYIRUiuiuYIYI3i42yiuyIUYIU4yiu$YUI#YUI$3mvsazr57;',
|
sessionSecret: process.env.SESSION_SECRET || 'iouydhtrfguyrthgftryhgidrhytgidhytiglriltnhgrhtiuygrthiugritghiyutrcginhrtijghurfcuhjgnioergjfuiehtiehtiehyritheithreifbhgehfbdxhbkvfdbhjkvgdkhnjUIYIRUiuiuYIYI3i42yiuyIUYIU4yiu$YUI#YUI$3mvsazr57;',
|
||||||
imageUploadTeams: process.env.TEAMUPLOADS || "C:\\Users\\matth\\Documents\\GitHub\\Kaverti-Team-Images"
|
imageUploadTeams: process.env.TEAMUPLOADS || "C:\\Users\\matth\\Documents\\GitHub\\Kaverti-Team-Images",
|
||||||
|
maintenance: process.env.MAINTENANCE || false
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
"vue-matomo": "^3.14.0-0",
|
"vue-matomo": "^3.14.0-0",
|
||||||
"vue-router": "^2.7.0",
|
"vue-router": "^2.7.0",
|
||||||
"vue-router-sitemap": "^0.0.4",
|
"vue-router-sitemap": "^0.0.4",
|
||||||
|
"vuedraggable": "^2.24.3",
|
||||||
"vuejs-paginator": "^2.0.2",
|
"vuejs-paginator": "^2.0.2",
|
||||||
"vuetify": "^2.3.8",
|
"vuetify": "^2.3.8",
|
||||||
"vuex": "^2.1.1"
|
"vuex": "^2.1.1"
|
||||||
|
|
|
@ -3,7 +3,7 @@ module.exports = function(vuex) {
|
||||||
let errors = []
|
let errors = []
|
||||||
|
|
||||||
if(res.response === undefined || res.response.data.errors === undefined) {
|
if(res.response === undefined || res.response.data.errors === undefined) {
|
||||||
errors.push('Something went wrong connecting to the Kaverti service, maybe try again later.')
|
errors.push('Something went wrong connecting to the Kaverti service, please try again later.')
|
||||||
} else {
|
} else {
|
||||||
res.response.data.errors.forEach(error => {
|
res.response.data.errors.forEach(error => {
|
||||||
let path = error.path
|
let path = error.path
|
||||||
|
@ -15,7 +15,6 @@ module.exports = function(vuex) {
|
||||||
errors.push(error.message[0].toUpperCase() + error.message.slice(1))
|
errors.push(error.message[0].toUpperCase() + error.message.slice(1))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if(errors.length) {
|
if(errors.length) {
|
||||||
vuex.commit('setAjaxErrors', errors)
|
vuex.commit('setAjaxErrors', errors)
|
||||||
vuex.commit('setAjaxErrorsModalState', true)
|
vuex.commit('setAjaxErrorsModalState', true)
|
||||||
|
|
|
@ -100,6 +100,37 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template v-if='teams.length'>
|
||||||
|
<div class='search_box__results__header search_box__results__header--divider'>Teams</div>
|
||||||
|
<div
|
||||||
|
class='search_box__results__search_all'
|
||||||
|
:class='{
|
||||||
|
"search_box__results--highlight": highlightIndex === getHighlightIndex("teams header")
|
||||||
|
}'
|
||||||
|
ref='teams header'
|
||||||
|
@mouseover='highlightIndex = getHighlightIndex("teams header")'
|
||||||
|
@click='goToSearch'
|
||||||
|
>
|
||||||
|
<div class='search_box__results__icon'><font-awesome-icon :icon='["fa", "search"]' /></div>
|
||||||
|
<div>
|
||||||
|
Search all teams containing '<strong>{{searchField}}</strong>'
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class='search_box__results__team'
|
||||||
|
:class='{
|
||||||
|
"search_box__results--highlight": highlightIndex === getHighlightIndex("teams", index)
|
||||||
|
}'
|
||||||
|
v-for='(team, index) in teams'
|
||||||
|
:key='"team-result-" + index'
|
||||||
|
ref='teams'
|
||||||
|
@mouseover='highlightIndex = getHighlightIndex("teams", index)'
|
||||||
|
@click='goToSearch'
|
||||||
|
>
|
||||||
|
<div class='search_box__results__title'>{{team.name}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class='search_box__results__message' v-if='!threads.length && !users.length && !loading'>
|
<div class='search_box__results__message' v-if='!threads.length && !users.length && !loading'>
|
||||||
Uh oh! There were no results for the query: '<strong>{{searchField}}</strong>'
|
Uh oh! There were no results for the query: '<strong>{{searchField}}</strong>'
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,7 +163,8 @@
|
||||||
MinQueryLength: 2,
|
MinQueryLength: 2,
|
||||||
|
|
||||||
threads: [],
|
threads: [],
|
||||||
users: []
|
users: [],
|
||||||
|
teams: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -193,7 +225,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
} else if(group === 'teams' || group === 'teams header') {
|
||||||
|
let ret = 0;
|
||||||
|
if(this.threads.length) {
|
||||||
|
ret += 1 + this.threads.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(group === 'teams') {
|
||||||
|
ret += 1 + index;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
//Produces relative group and index
|
//Produces relative group and index
|
||||||
//from overall highlight index
|
//from overall highlight index
|
||||||
|
@ -216,6 +258,12 @@
|
||||||
} else {
|
} else {
|
||||||
return { group: 'users', index: index-1 };
|
return { group: 'users', index: index-1 };
|
||||||
}
|
}
|
||||||
|
} else if(this.teams.length) {
|
||||||
|
if(index === 0) {
|
||||||
|
return { group: 'teams header', index: null };
|
||||||
|
} else {
|
||||||
|
return { group: 'teams', index: index-1 };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setKeyHighlight (e) {
|
setKeyHighlight (e) {
|
||||||
|
@ -279,7 +327,11 @@
|
||||||
this.$router.push('/thread/' + thread.slug + '/' + thread.id);
|
this.$router.push('/thread/' + thread.slug + '/' + thread.id);
|
||||||
} else if (group === 'users header') {
|
} else if (group === 'users header') {
|
||||||
this.$router.push('/search/users/' + searchEncoded);
|
this.$router.push('/search/users/' + searchEncoded);
|
||||||
} else {
|
} else if(group === 'teams') {
|
||||||
|
this.$router.push('/t/' + this.teams[index].username);
|
||||||
|
} else if(group === 'teams header') {
|
||||||
|
this.$router.push('/search/teams/' + searchEncoded);
|
||||||
|
} else {
|
||||||
this.$router.push('/search/threads/' + searchEncoded);
|
this.$router.push('/search/threads/' + searchEncoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +347,7 @@
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.threads = [];
|
this.threads = [];
|
||||||
this.users = [];
|
this.users = [];
|
||||||
|
this.teams = [];
|
||||||
|
|
||||||
this.axios
|
this.axios
|
||||||
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/thread?q=' + q)
|
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/thread?q=' + q)
|
||||||
|
@ -311,6 +364,14 @@
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
})
|
})
|
||||||
.catch(AjaxErrorHandler(this.$store));
|
.catch(AjaxErrorHandler(this.$store));
|
||||||
|
|
||||||
|
this.axios
|
||||||
|
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/team?q=' + q)
|
||||||
|
.then(res => {
|
||||||
|
this.teams = res.data.teams.slice(0, 5);
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(AjaxErrorHandler(this.$store));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class='user_display'
|
||||||
|
@click='$router.push("/user/" + user.username)'
|
||||||
|
>
|
||||||
|
<team-icon :user='user' size='small'></team-icon>
|
||||||
|
<div class='user_display__username'>
|
||||||
|
{{user.username}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TeamIcon from './TeamIcon'
|
||||||
|
export default {
|
||||||
|
name: 'UserDisplay',
|
||||||
|
props: ['user'],
|
||||||
|
components: {TeamIcon
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
@import '../assets/scss/variables.scss';
|
||||||
|
|
||||||
|
.user_display {
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
border: thin solid $color__gray--darker;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
transition: box-shadow 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@extend .shadow_border--hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
@at-root #{&}__username {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,168 @@
|
||||||
|
<template>
|
||||||
|
<info-tooltip class='avatar_icon' :noEvents='user === null'>
|
||||||
|
|
||||||
|
<template slot='content'>
|
||||||
|
|
||||||
|
<template v-if='userData'>
|
||||||
|
<div class='avatar_icon__header'>
|
||||||
|
<figure class="avatar_icon__icon--small picture_circle">
|
||||||
|
<img
|
||||||
|
:src = userPicture
|
||||||
|
>
|
||||||
|
</figure>
|
||||||
|
<div class='avatar_icon__header_info'>
|
||||||
|
<span class='avatar_icon__username' @click.stop='goToUser'>
|
||||||
|
{{proxyUser.username}}
|
||||||
|
</span>
|
||||||
|
<span class='avatar_icon__date'>Created: {{proxyUser.createdAt | formatDate('date') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='avatar_icon__description' v-if='proxyUser.description'>
|
||||||
|
{{proxyUser.description | stripTags | truncate(30)}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>Loading...</template>
|
||||||
|
</template>
|
||||||
|
<figure
|
||||||
|
slot="display"
|
||||||
|
class='avatar_icon__icon picture_circle'
|
||||||
|
:class='{
|
||||||
|
"avatar_icon__icon--small": size === "small",
|
||||||
|
"avatar_icon__icon--tiny": size === "tiny"
|
||||||
|
}'
|
||||||
|
@click.stop="goToUser">
|
||||||
|
<img
|
||||||
|
:src = userPicture
|
||||||
|
>
|
||||||
|
</figure>
|
||||||
|
</info-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import InfoTooltip from './InfoTooltip'
|
||||||
|
import AjaxErrorHandler from '../assets/js/errorHandler'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AvatarIcon',
|
||||||
|
props: ['user', 'size'],
|
||||||
|
components: { InfoTooltip },
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
userData: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
//So that you never access a null variable
|
||||||
|
proxyUser () {
|
||||||
|
if(this.userData) {
|
||||||
|
//Data loaded via api
|
||||||
|
return this.userData;
|
||||||
|
} else if (this.user) {
|
||||||
|
//Data provided as a prop
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
letter () {
|
||||||
|
if(this.proxyUser.username && !this.proxyUser.picture) {
|
||||||
|
return this.proxyUser.username[0].toUpperCase();
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
userPicture () {
|
||||||
|
if(this.user && this.user.approved && !this.user.banned && this.user.picture !== 'default') {
|
||||||
|
return this.user.picture
|
||||||
|
} else if(this.user && this.user.banned) {
|
||||||
|
return "https://cdn.kaverti.com/teams/unknown-light.png"
|
||||||
|
} else if(this.user && !this.user.banned && !this.user.approved && this.$store.state.theme === 'light') {
|
||||||
|
return "https://cdn.kaverti.com/teams/pending-light.png"
|
||||||
|
} else if(this.user && !this.user.banned && !this.user.approved && this.$store.state.theme === 'dark') {
|
||||||
|
return "https://cdn.kaverti.com/teams/pending-dark.png"
|
||||||
|
} else if(this.user && !this.user.banned && !this.user.approved) {
|
||||||
|
return "https://cdn.kaverti.com/teams/pending-light.png"
|
||||||
|
} else {
|
||||||
|
return "https://cdn.kaverti.com/teams/unknown-light.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadUser () {
|
||||||
|
//If user is already loaded or no user provided as a prop
|
||||||
|
if(this.userData || this.user === null) return;
|
||||||
|
|
||||||
|
this.axios
|
||||||
|
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/view/' + this.proxyUser.username)
|
||||||
|
.then((res) => {
|
||||||
|
this.userData = res.data;
|
||||||
|
})
|
||||||
|
.catch(AjaxErrorHandler(this.$store));
|
||||||
|
},
|
||||||
|
goToUser () {
|
||||||
|
if(this.user === null) return;
|
||||||
|
|
||||||
|
this.$router.push('/user/' + this.user.username)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() { this.loadUser(); }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss'>
|
||||||
|
@import '../assets/scss/variables.scss';
|
||||||
|
|
||||||
|
.avatar_icon {
|
||||||
|
@at-root #{&}__icon {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
margin-right: 0.25rem;
|
||||||
|
color: rgba(0, 0, 0, 0.87);
|
||||||
|
}
|
||||||
|
|
||||||
|
@at-root #{&}__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@at-root #{&}__icon {
|
||||||
|
height: 3rem;
|
||||||
|
width: 3rem;
|
||||||
|
line-height: 3rem;
|
||||||
|
cursor: pointer;
|
||||||
|
@include text($font--role-emphasis, 2rem);
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 100%;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
@at-root #{&}--small {
|
||||||
|
height: 3rem;
|
||||||
|
width: 3rem;
|
||||||
|
font-size: 1.75rem;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
}
|
||||||
|
@at-root #{&}--tiny {
|
||||||
|
height: 1.5rem;
|
||||||
|
width: 1.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@at-root #{&}__header_info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 2.5rem;
|
||||||
|
}
|
||||||
|
@at-root #{&}__username {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@at-root #{&}__date {
|
||||||
|
color: $color__darkgray--primary;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
@at-root #{&}__description {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<main>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
</template>
|
|
@ -57,6 +57,40 @@
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
<transition name='fade' mode='out-in'>
|
||||||
|
<div class='search__results' key='results' v-if='teams && teams.length && !loadingTeams'>
|
||||||
|
<h2>Teams</h2>
|
||||||
|
<team-display v-for='user in teams.slice(0, 5)' :key='"search-user-" + user.id' :user='user'></team-display>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class='search__item search__more' v-if='users.length > 5'
|
||||||
|
@click='$router.push("/search/users/" + $route.params.q)'
|
||||||
|
>
|
||||||
|
<font-awesome-icon :icon='["fa", "user"]' fixed-width />
|
||||||
|
View all matching teams
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
key='loading'
|
||||||
|
v-if='loadingTeams'
|
||||||
|
>
|
||||||
|
<h2>Teams</h2>
|
||||||
|
<user-placeholder></user-placeholder>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class='overlay_message search__overlay_message'
|
||||||
|
v-if='showNoResults || queryTooShort'
|
||||||
|
key='no results'
|
||||||
|
>
|
||||||
|
<i class="far fa-exclamation-circle" />
|
||||||
|
{{queryTooShort ?
|
||||||
|
"Search term is too short." :
|
||||||
|
"Uh oh! There were no results."
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -66,8 +100,9 @@
|
||||||
import UserPlaceholder from '../UserPlaceholder'
|
import UserPlaceholder from '../UserPlaceholder'
|
||||||
import ThreadDisplay from '../ThreadDisplay'
|
import ThreadDisplay from '../ThreadDisplay'
|
||||||
import ThreadDisplayPlaceholder from '../ThreadDisplayPlaceholder'
|
import ThreadDisplayPlaceholder from '../ThreadDisplayPlaceholder'
|
||||||
|
import TeamDisplay from '../TeamDisplay'
|
||||||
|
|
||||||
import AjaxErrorHandler from '../../assets/js/errorHandler'
|
import AjaxErrorHandler from '../../assets/js/errorHandler'
|
||||||
import logger from '../../assets/js/logger'
|
import logger from '../../assets/js/logger'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -76,7 +111,8 @@
|
||||||
UserDisplay,
|
UserDisplay,
|
||||||
UserPlaceholder,
|
UserPlaceholder,
|
||||||
ThreadDisplay,
|
ThreadDisplay,
|
||||||
ThreadDisplayPlaceholder
|
ThreadDisplayPlaceholder,
|
||||||
|
TeamDisplay
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -84,7 +120,10 @@
|
||||||
loadingThreads: false,
|
loadingThreads: false,
|
||||||
|
|
||||||
users: [],
|
users: [],
|
||||||
loadingUsers: false
|
loadingUsers: false,
|
||||||
|
|
||||||
|
teams: [],
|
||||||
|
loadingTeams: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -121,6 +160,17 @@
|
||||||
})
|
})
|
||||||
.catch(AjaxErrorHandler(this.$store))
|
.catch(AjaxErrorHandler(this.$store))
|
||||||
},
|
},
|
||||||
|
getTeams () {
|
||||||
|
this.loadingTeams = true;
|
||||||
|
|
||||||
|
this.axios
|
||||||
|
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/team?q=' + this.$route.params.q)
|
||||||
|
.then(res => {
|
||||||
|
this.loadingTeams = false;
|
||||||
|
this.teams = res.data.teams;
|
||||||
|
})
|
||||||
|
.catch(AjaxErrorHandler(this.$store))
|
||||||
|
},
|
||||||
getResults () {
|
getResults () {
|
||||||
if(this.queryTooShort) return;
|
if(this.queryTooShort) return;
|
||||||
|
|
||||||
|
@ -128,7 +178,8 @@
|
||||||
|
|
||||||
this.getThreads();
|
this.getThreads();
|
||||||
this.getUsers();
|
this.getUsers();
|
||||||
}
|
this.getTeams();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.params': 'getResults'
|
'$route.params': 'getResults'
|
||||||
|
|
|
@ -56,18 +56,31 @@
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="">
|
<div class="">
|
||||||
<h1>Roles:</h1>
|
<h1>Roles:</h1>
|
||||||
<scroll-load
|
<ul class="list-group mb-2">
|
||||||
key='user-row'
|
<draggable
|
||||||
v-if='roles.length'
|
class="list-group"
|
||||||
:loading='loading'
|
tag="ul"
|
||||||
@loadNext='fetchData'
|
v-model="roles"
|
||||||
>
|
v-bind="dragOptions"
|
||||||
<div class="column is-10" v-for='role in roles' :key='"user-row" + role.name' v-show="role">
|
>
|
||||||
<b-tag class="is-large">{{role.name}}</b-tag>
|
<transition-group type="transition">
|
||||||
</div>
|
<li
|
||||||
<br>
|
class="list-group-item"
|
||||||
<b-button @click="toggleRoleCreate"><i class="fas fa-plus"></i> Add Role</b-button>
|
v-for="role in roles"
|
||||||
</scroll-load>
|
:key="role.priority"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<b-tag class="is-large">{{ role.name }} <b-tag @click="toggleRoleCreate"><i @click="toggleRoleCreate" class="fas fa-pencil"></i></b-tag></b-tag>
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
|
</draggable>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<b-button @click="saveRoles()">Save Role Order</b-button>
|
||||||
|
|
||||||
|
<b-button class="is-info" @click="toggleRoleCreate()"><i class="fas fa-plus"></i> Add Role</b-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p name='fade' mode='out-in'>
|
<p name='fade' mode='out-in'>
|
||||||
|
@ -81,15 +94,18 @@
|
||||||
import LoadingMessage from '../LoadingMessage';
|
import LoadingMessage from '../LoadingMessage';
|
||||||
import ScrollLoad from '../ScrollLoad';
|
import ScrollLoad from '../ScrollLoad';
|
||||||
import ModalWindow from "@/components/ModalWindow";
|
import ModalWindow from "@/components/ModalWindow";
|
||||||
|
import draggable from 'vuedraggable'
|
||||||
import throttle from 'lodash.throttle';
|
import throttle from 'lodash.throttle';
|
||||||
import AjaxErrorHandler from '../../assets/js/errorHandler';
|
import AjaxErrorHandler from '../../assets/js/errorHandler';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TeamMembers',
|
name: 'TeamRoles',
|
||||||
components: {
|
components: {
|
||||||
LoadingMessage,
|
LoadingMessage,
|
||||||
|
// eslint-disable-next-line vue/no-unused-components
|
||||||
ScrollLoad,
|
ScrollLoad,
|
||||||
ModalWindow
|
ModalWindow,
|
||||||
|
draggable
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -99,12 +115,13 @@ export default {
|
||||||
roles: [],
|
roles: [],
|
||||||
team: [],
|
team: [],
|
||||||
|
|
||||||
loading: true,
|
loading: false,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 15,
|
limit: 15,
|
||||||
showTeamTab: 0,
|
showTeamTab: 0,
|
||||||
showRoleModal: false,
|
showRoleModal: false,
|
||||||
createTeamModal: false,
|
createTeamModal: false,
|
||||||
|
drag: false,
|
||||||
tRole: {
|
tRole: {
|
||||||
name: '',
|
name: '',
|
||||||
|
|
||||||
|
@ -132,6 +149,28 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
updateListSortOrder() {
|
||||||
|
const newList = [...this.roles].map((item, index) => {
|
||||||
|
const newSort = index + 1;
|
||||||
|
item.priority = newSort;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
this.roles = newList;
|
||||||
|
},
|
||||||
|
saveRoles() {
|
||||||
|
this.updateListSortOrder()
|
||||||
|
this.axios.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/admin/roles/modify/` + this.$route.params.username, {
|
||||||
|
roles: this.roles
|
||||||
|
}).then(() => {
|
||||||
|
this.tRole.loading = false
|
||||||
|
this.closeAccountModal()
|
||||||
|
}).catch(e => {
|
||||||
|
this.tRole.loading = false
|
||||||
|
AjaxErrorHandler(this.$store)(e)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
clearTeamErrors() {
|
clearTeamErrors() {
|
||||||
this.tcreateProd.errors.username = ''
|
this.tcreateProd.errors.username = ''
|
||||||
this.tcreateProd.errors.name = ''
|
this.tcreateProd.errors.name = ''
|
||||||
|
@ -140,7 +179,9 @@ export default {
|
||||||
this.showRoleModal = false
|
this.showRoleModal = false
|
||||||
},
|
},
|
||||||
addRole() {
|
addRole() {
|
||||||
let postParams = {
|
this.tRole.loading = true
|
||||||
|
|
||||||
|
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/admin/roles/create/` + this.$route.params.username, {
|
||||||
name: this.tRole.name,
|
name: this.tRole.name,
|
||||||
|
|
||||||
administrator: this.tRole.administrator,
|
administrator: this.tRole.administrator,
|
||||||
|
@ -151,16 +192,14 @@ export default {
|
||||||
changeTeamPrivacy: this.tRole.changeTeamPrivacy,
|
changeTeamPrivacy: this.tRole.changeTeamPrivacy,
|
||||||
submitTeamItems: this.tRole.submitTeamItems,
|
submitTeamItems: this.tRole.submitTeamItems,
|
||||||
priority: this.tRole.priority
|
priority: this.tRole.priority
|
||||||
}
|
}).then(() => {
|
||||||
this.tRole.loading = true
|
|
||||||
|
|
||||||
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/admin/roles/create/` + this.$route.params.username, postParams).then(res => {
|
|
||||||
res()
|
|
||||||
this.tRole.loading = false
|
this.tRole.loading = false
|
||||||
this.closeAccountModal()
|
this.closeAccountModal()
|
||||||
|
this.fetchData()
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
this.tRole.loading = false
|
this.tRole.loading = false
|
||||||
AjaxErrorHandler(this.$store)(e);
|
AjaxErrorHandler(this.$store)(e)
|
||||||
|
this.fetchData()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
toggleRoleCreate() {
|
toggleRoleCreate() {
|
||||||
|
@ -174,9 +213,12 @@ export default {
|
||||||
this.axios
|
this.axios
|
||||||
.get( process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/view/' + this.$route.params.username + "/roles")
|
.get( process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/view/' + this.$route.params.username + "/roles")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.roles.push(...res.data);
|
this.roles = res.data.filter(role => role.priority);
|
||||||
|
//this.roles.push(...res.data);
|
||||||
this.loading = /*loading =*/ false;
|
this.loading = /*loading =*/ false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//If returned data is less than the limit
|
//If returned data is less than the limit
|
||||||
//then there must be no more pages to paginate
|
//then there must be no more pages to paginate
|
||||||
if(res.data.length < this.limit) {
|
if(res.data.length < this.limit) {
|
||||||
|
@ -230,6 +272,16 @@ export default {
|
||||||
mounted () {
|
mounted () {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
dragOptions() {
|
||||||
|
return {
|
||||||
|
animation: 200,
|
||||||
|
group: "description",
|
||||||
|
disabled: false,
|
||||||
|
ghostClass: "ghost"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
tableSort: 'resetFetchData',
|
tableSort: 'resetFetchData',
|
||||||
roleSelected: 'resetFetchData',
|
roleSelected: 'resetFetchData',
|
||||||
|
@ -239,3 +291,24 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
.flip-list-move {
|
||||||
|
transition: transform 0.5s;
|
||||||
|
}
|
||||||
|
.no-move {
|
||||||
|
transition: transform 0s;
|
||||||
|
}
|
||||||
|
.ghost {
|
||||||
|
opacity: 0.5;
|
||||||
|
background: #c8ebfb;
|
||||||
|
}
|
||||||
|
.list-group {
|
||||||
|
min-height: 20px;
|
||||||
|
}
|
||||||
|
.list-group-item {
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
.list-group-item i {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -134,6 +134,7 @@ const AdminMarketplace = () => import('./components/routes/AdminMarketplace')
|
||||||
|
|
||||||
const Licenses = () => import('./components/routes/LICENSES')
|
const Licenses = () => import('./components/routes/LICENSES')
|
||||||
const ConnectionProblems = () => import('./components/routes/ConnectionProblems')
|
const ConnectionProblems = () => import('./components/routes/ConnectionProblems')
|
||||||
|
const Maintenance = () => import('./components/routes/Maintenance')
|
||||||
const Contributors = () => import('./components/routes/Contributors')
|
const Contributors = () => import('./components/routes/Contributors')
|
||||||
|
|
||||||
const Inventory = () => import('./components/routes/Inventory')
|
const Inventory = () => import('./components/routes/Inventory')
|
||||||
|
@ -238,6 +239,7 @@ const router = new VueRouter({
|
||||||
] },
|
] },
|
||||||
{ path: '/forum', redirect: '/category/all', component: Index },
|
{ path: '/forum', redirect: '/category/all', component: Index },
|
||||||
{ path: '/connection', component: ConnectionProblems },
|
{ path: '/connection', component: ConnectionProblems },
|
||||||
|
{ path: '/maintenance', component: Maintenance },
|
||||||
{ path: '/contributors', component: Contributors },
|
{ path: '/contributors', component: Contributors },
|
||||||
{ path: '/forums', redirect: '/category/all', component: Index },
|
{ path: '/forums', redirect: '/category/all', component: Index },
|
||||||
{ path: '/search/:q', component: Search },
|
{ path: '/search/:q', component: Search },
|
||||||
|
|
|
@ -9107,6 +9107,11 @@ sort-keys@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-plain-obj "^1.0.0"
|
is-plain-obj "^1.0.0"
|
||||||
|
|
||||||
|
sortablejs@1.10.2:
|
||||||
|
version "1.10.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.10.2.tgz#6e40364d913f98b85a14f6678f92b5c1221f5290"
|
||||||
|
integrity sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==
|
||||||
|
|
||||||
source-list-map@^2.0.0:
|
source-list-map@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://npm.open-registry.dev/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
resolved "https://npm.open-registry.dev/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||||
|
@ -10210,6 +10215,13 @@ vue@^2.6.11:
|
||||||
resolved "https://npm.open-registry.dev/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
|
resolved "https://npm.open-registry.dev/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
|
||||||
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
|
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
|
||||||
|
|
||||||
|
vuedraggable@^2.24.3:
|
||||||
|
version "2.24.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/vuedraggable/-/vuedraggable-2.24.3.tgz#43c93849b746a24ce503e123d5b259c701ba0d19"
|
||||||
|
integrity sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==
|
||||||
|
dependencies:
|
||||||
|
sortablejs "1.10.2"
|
||||||
|
|
||||||
vuejs-paginator@^2.0.2:
|
vuejs-paginator@^2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/vuejs-paginator/-/vuejs-paginator-2.0.2.tgz#89792bb33cf73f4ddbd329485f174e23acf0f12c"
|
resolved "https://registry.yarnpkg.com/vuejs-paginator/-/vuejs-paginator-2.0.2.tgz#89792bb33cf73f4ddbd329485f174e23acf0f12c"
|
||||||
|
|
|
@ -59,6 +59,10 @@ let Errors = {
|
||||||
'This category has already been created',
|
'This category has already been created',
|
||||||
400
|
400
|
||||||
],
|
],
|
||||||
|
maintenance: [
|
||||||
|
'Kaverti is currently under routine maintenance, website access has been restricted, please try again later.',
|
||||||
|
400
|
||||||
|
],
|
||||||
accountDoesNotExist: [
|
accountDoesNotExist: [
|
||||||
'This account does not exist',
|
'This account does not exist',
|
||||||
400
|
400
|
||||||
|
|
|
@ -9,6 +9,7 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
let TeamRoles = sequelize.define('TeamRoles', {
|
let TeamRoles = sequelize.define('TeamRoles', {
|
||||||
name: {
|
name: {
|
||||||
type: DataTypes.STRING,
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
validate: {
|
validate: {
|
||||||
isString(val) {
|
isString(val) {
|
||||||
if (typeof val !== 'string') {
|
if (typeof val !== 'string') {
|
||||||
|
@ -55,7 +56,8 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
},
|
},
|
||||||
priority: {
|
priority: {
|
||||||
type: DataTypes.BIGINT,
|
type: DataTypes.BIGINT,
|
||||||
default: 1
|
default: 1,
|
||||||
|
allowNull: false,
|
||||||
},
|
},
|
||||||
teamId: {
|
teamId: {
|
||||||
type: DataTypes.BIGINT
|
type: DataTypes.BIGINT
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"@sendgrid/mail": "^7.2.5",
|
"@sendgrid/mail": "^7.2.5",
|
||||||
"axios": "^0.19.0",
|
"axios": "^0.19.0",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
|
"bluebird": "^3.7.2",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"compression": "^1.7.3",
|
"compression": "^1.7.3",
|
||||||
"connect-multiparty": "^2.2.0",
|
"connect-multiparty": "^2.2.0",
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
let express = require('express')
|
||||||
|
let router = express.Router()
|
||||||
|
const auth = require('../lib/authUserInfo')
|
||||||
|
const Errors = require('../lib/errors')
|
||||||
|
let { Settings, Sequelize } = require('../models')
|
||||||
|
|
||||||
|
router.get('*', async(req, res, next) => {
|
||||||
|
try {
|
||||||
|
throw Errors.maintenance
|
||||||
|
} catch (err) { next(err) }
|
||||||
|
})
|
||||||
|
|
||||||
|
router.post('*', async(req, res, next) => {
|
||||||
|
try {
|
||||||
|
throw Errors.maintenance
|
||||||
|
} catch (err) { next(err) }
|
||||||
|
})
|
||||||
|
|
||||||
|
router.put('*', async(req, res, next) => {
|
||||||
|
try {
|
||||||
|
throw Errors.maintenance
|
||||||
|
} catch (err) { next(err) }
|
||||||
|
})
|
||||||
|
|
||||||
|
router.options('*', async(req, res, next) => {
|
||||||
|
try {
|
||||||
|
res.status(200)
|
||||||
|
res.json({success: true})
|
||||||
|
} catch (err) { next(err) }
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router
|
|
@ -2,7 +2,7 @@ let express = require('express')
|
||||||
let router = express.Router()
|
let router = express.Router()
|
||||||
const auth = require('../lib/auth')
|
const auth = require('../lib/auth')
|
||||||
|
|
||||||
let { Post, Ban, Thread, User, Category, Sequelize } = require('../models')
|
let { Post, Ban, Team, Thread, User, Category, Sequelize } = require('../models')
|
||||||
const Errors = require('../lib/errors')
|
const Errors = require('../lib/errors')
|
||||||
const { setRandomFallback } = require('bcryptjs')
|
const { setRandomFallback } = require('bcryptjs')
|
||||||
|
|
||||||
|
@ -159,4 +159,28 @@ router.get('/user', async(req, res, next) => {
|
||||||
} catch (e) { next(e) }
|
} catch (e) { next(e) }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.get('/team', async(req, res, next) => {
|
||||||
|
try {
|
||||||
|
let searchString = req.query.q
|
||||||
|
let offset = +req.query.offset || 0
|
||||||
|
let limit = 10
|
||||||
|
let teams = await Team.findAll({
|
||||||
|
where: {
|
||||||
|
username: { $like: '%' + searchString + '%' }
|
||||||
|
},
|
||||||
|
order: [ ['username', 'DESC'] ],
|
||||||
|
attributes: {exclude: ['banReason']},
|
||||||
|
limit,
|
||||||
|
offset
|
||||||
|
})
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
teams,
|
||||||
|
offset: teams.length < limit ? null : offset + limit,
|
||||||
|
next: teams.length < limit ? null : limit
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (e) { next(e) }
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
let express = require('express')
|
|
||||||
let router = express.Router()
|
|
||||||
const auth = require('../lib/auth')
|
|
||||||
|
|
||||||
const Errors = require('../lib/errors')
|
|
||||||
let { Settings, Ban, Sequelize } = require('../models')
|
|
||||||
|
|
||||||
router.get('/', async(req, res, next) => {
|
|
||||||
try {
|
|
||||||
let settings = await Settings.get()
|
|
||||||
|
|
||||||
if(!settings) throw Errors.noSettings
|
|
||||||
|
|
||||||
res.json(settings.toJSON())
|
|
||||||
} catch (e) { next(e) }
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
router.all('*', auth, (req, res, next) => {
|
|
||||||
if(req.userData.admin) {
|
|
||||||
next()
|
|
||||||
} else {
|
|
||||||
res.status(401)
|
|
||||||
res.json({
|
|
||||||
errors: [Errors.requestNotAuthorized]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
router.put('/', auth, async(req, res, next) => {
|
|
||||||
try {
|
|
||||||
throw Errors.featureDisabledState
|
|
||||||
await Ban.ReadOnlyMode(req.userData.username)
|
|
||||||
let params = {}
|
|
||||||
|
|
||||||
if(req.body.siteName) {
|
|
||||||
params.siteName = req.body.siteName
|
|
||||||
}
|
|
||||||
if(req.body.siteDesc !== undefined) {
|
|
||||||
params.siteDesc = req.body.siteDesc
|
|
||||||
}
|
|
||||||
if(req.body.showDescription !== undefined) {
|
|
||||||
params.showDescription = req.body.showDescription
|
|
||||||
}
|
|
||||||
if(req.body.bannerEnabled !== undefined) {
|
|
||||||
params.bannerEnabled = req.body.bannerEnabled
|
|
||||||
}
|
|
||||||
if(req.body.bannerText !== undefined) {
|
|
||||||
params.bannerText = req.body.bannerText
|
|
||||||
}
|
|
||||||
|
|
||||||
let updatedSettings = await Settings.set(params)
|
|
||||||
|
|
||||||
res.json(params)
|
|
||||||
|
|
||||||
} catch (e) { next(e) }
|
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = router
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
let express = require('express')
|
||||||
|
let router = express.Router()
|
||||||
|
const auth = require('../lib/auth')
|
||||||
|
|
||||||
|
const Errors = require('../lib/errors')
|
||||||
|
let { Settings, Ban, Sequelize } = require('../models')
|
||||||
|
|
||||||
|
router.get('/', async(req, res, next) => {
|
||||||
|
try {
|
||||||
|
let settings = await Settings.findOne({
|
||||||
|
where: {
|
||||||
|
id: 1
|
||||||
|
},
|
||||||
|
attributes: { exclude: ['id', 'createdAt', 'updatedAt'] }
|
||||||
|
})
|
||||||
|
|
||||||
|
if(!settings) throw Errors.noSettings
|
||||||
|
|
||||||
|
res.json(settings.toJSON())
|
||||||
|
} catch (e) { next(e) }
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
router.all('*', auth, (req, res, next) => {
|
||||||
|
if(req.userData.admin) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
res.status(401)
|
||||||
|
res.json({
|
||||||
|
errors: [Errors.requestNotAuthorized]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router
|
|
@ -48,6 +48,7 @@ const sgMail = require('@sendgrid/mail');
|
||||||
const MailGen = require('mailgen')
|
const MailGen = require('mailgen')
|
||||||
const crypto = require("crypto")
|
const crypto = require("crypto")
|
||||||
const cryptoRandomString = require("crypto-random-string")
|
const cryptoRandomString = require("crypto-random-string")
|
||||||
|
let Promise = require('bluebird');
|
||||||
const rateLimit = require("express-rate-limit");
|
const rateLimit = require("express-rate-limit");
|
||||||
let upload = multer({
|
let upload = multer({
|
||||||
storage: multer.memoryStorage(),
|
storage: multer.memoryStorage(),
|
||||||
|
@ -154,13 +155,92 @@ router.post('/roles/create/:username', auth, async(req, res, next) => {
|
||||||
priority: req.body.priority,
|
priority: req.body.priority,
|
||||||
teamId: team.id
|
teamId: team.id
|
||||||
}
|
}
|
||||||
await TeamRoles.create(makeRole)
|
let teamCreate = await TeamRoles.create(makeRole)
|
||||||
res.status(200)
|
res.status(200)
|
||||||
res.json({success: true})
|
res.json(teamCreate.toJSON())
|
||||||
} else if (!teamJoinTest) {
|
} else if (!teamJoinTest) {
|
||||||
|
res.status(400)
|
||||||
|
res.json({success: false})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw Errors.teamDoesNotExist
|
||||||
|
}
|
||||||
|
} catch (e) { next(e) }
|
||||||
|
})
|
||||||
|
|
||||||
|
router.put('/roles/modify/:username/:id', 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.status(200)
|
||||||
res.json({success: false})
|
res.json({success: false})
|
||||||
}
|
}
|
||||||
|
let teamJoinTest = await TeamMembers.findOne(queryObj3)
|
||||||
|
if (teamJoinTest) {
|
||||||
|
if(req.body.name) {
|
||||||
|
let find = await TeamRoles.findOne({
|
||||||
|
where: {
|
||||||
|
id: req.params.id,
|
||||||
|
teamId: team.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(find) {
|
||||||
|
let update = await TeamRoles.update({
|
||||||
|
priority: req.body.priority,
|
||||||
|
name: req.body.name,
|
||||||
|
administrator: req.body.administrator,
|
||||||
|
inviteUsers: req.body.inviteUsers,
|
||||||
|
changeTeamMeta: req.body.changeTeamMeta,
|
||||||
|
forumAdministrator: req.body.forumAdministrator,
|
||||||
|
moderateForumThreads: req.body.moderateForumThreads,
|
||||||
|
changeTeamPrivacy: req.body.changeTeamPrivacy,
|
||||||
|
submitTeamItems: req.body.submitTeamItems,
|
||||||
|
}, {
|
||||||
|
where: {
|
||||||
|
id: req.params.id,
|
||||||
|
teamId: team.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res.status(200)
|
||||||
|
res.json({success: true})
|
||||||
|
} else {
|
||||||
|
res.status(400)
|
||||||
|
res.json({success: false})
|
||||||
|
}
|
||||||
|
} else if(req.body.priority && !req.body.name) {
|
||||||
|
let find = await TeamRoles.findOne({
|
||||||
|
where: {
|
||||||
|
id: req.params.id,
|
||||||
|
teamId: team.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(find) {
|
||||||
|
await TeamRoles.update({priority: req.body.priority}, {
|
||||||
|
where: {
|
||||||
|
id: req.params.id,
|
||||||
|
teamId: team.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res.status(200)
|
||||||
|
res.json({success:true})
|
||||||
|
} else {
|
||||||
|
res.status(400)
|
||||||
|
res.json({success: false})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.status(400)
|
||||||
|
res.json({success: false})
|
||||||
|
}
|
||||||
|
} else if (!teamJoinTest) {
|
||||||
|
res.status(400)
|
||||||
|
res.json({success: false})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw Errors.teamDoesNotExist
|
throw Errors.teamDoesNotExist
|
||||||
}
|
}
|
||||||
|
@ -168,46 +248,5 @@ router.post('/roles/create/:username', auth, async(req, res, next) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
router.post('/admin/', 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 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) }
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
86
server.js
86
server.js
|
@ -66,7 +66,6 @@ const passport = require('passport');
|
||||||
const specs = swaggerJsdoc(options);
|
const specs = swaggerJsdoc(options);
|
||||||
const csrf = require('csurf')
|
const csrf = require('csurf')
|
||||||
const csrfProtection = csrf({ cookie: true })
|
const csrfProtection = csrf({ cookie: true })
|
||||||
|
|
||||||
if(process.env.NODE_ENV === 'production') {
|
if(process.env.NODE_ENV === 'production') {
|
||||||
app.set('trust proxy', 1);
|
app.set('trust proxy', 1);
|
||||||
}
|
}
|
||||||
|
@ -80,45 +79,52 @@ app.use(expAutoSan.all);
|
||||||
if(process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'production') {
|
if(process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'production') {
|
||||||
app.use(require('morgan')('dev'))
|
app.use(require('morgan')('dev'))
|
||||||
}
|
}
|
||||||
app.use('/api/v1/user/', require('./routes/user'))
|
if(!config.maintenance) {
|
||||||
app.use('/api/v1/passkey', require('./routes/user_passkey'))
|
app.use('/api/v1/user/', require('./routes/user'))
|
||||||
app.use('/api/v1/admin/admin_token', require('./routes/admin_token'))
|
app.use('/api/v1/passkey', require('./routes/user_passkey'))
|
||||||
app.use('/api/v1/admin/passkey', require('./routes/user_passkey'))
|
app.use('/api/v1/admin/admin_token', require('./routes/admin_token'))
|
||||||
app.use('/api/v1/forums/category', require('./routes/category'))
|
app.use('/api/v1/admin/passkey', require('./routes/user_passkey'))
|
||||||
app.use('/api/v1/forums/thread', require('./routes/thread'))
|
app.use('/api/v1/forums/category', require('./routes/category'))
|
||||||
app.use('/api/v1/users/notification', require('./routes/notification'))
|
app.use('/api/v1/forums/thread', require('./routes/thread'))
|
||||||
app.use('/api/v1/forums/post', require('./routes/post'))
|
app.use('/api/v1/users/notification', require('./routes/notification'))
|
||||||
app.use('/api/v1/kaverti/state', require('./routes/settings'))
|
app.use('/api/v1/forums/post', require('./routes/post'))
|
||||||
app.use('/api/v1/users/report', require('./routes/report'))
|
app.use('/api/v1/kaverti/state', require('./routes/state'))
|
||||||
app.use('/api/v1/users/unban-request', require('./routes/UnbanRequest'))
|
app.use('/api/v1/users/report', require('./routes/report'))
|
||||||
app.use('/api/v1/admin/ban', require('./routes/ban'))
|
app.use('/api/v1/users/unban-request', require('./routes/UnbanRequest'))
|
||||||
app.use('/api/v1/kaverti/search', require('./routes/search'))
|
app.use('/api/v1/admin/ban', require('./routes/ban'))
|
||||||
app.use('/api/v1/log', require('./routes/log'))
|
app.use('/api/v1/kaverti/search', require('./routes/search'))
|
||||||
app.use('/api/v1/forums/poll', require('./routes/poll'))
|
app.use('/api/v1/log', require('./routes/log'))
|
||||||
app.use('/api/v1/forums/link_preview', require('./routes/link_preview'))
|
app.use('/api/v1/forums/poll', require('./routes/poll'))
|
||||||
app.use('/api/v1/kaverti/stats', require('./routes/stats'))
|
app.use('/api/v1/forums/link_preview', require('./routes/link_preview'))
|
||||||
app.use('/api/v1/users/login_status', require('./routes/login_status'))
|
app.use('/api/v1/kaverti/stats', require('./routes/stats'))
|
||||||
app.use('/api/v1/users/', require('./routes/userutils'))
|
app.use('/api/v1/users/login_status', require('./routes/login_status'))
|
||||||
app.use('/api/v1/admin/killsession', require('./routes/admin_kill_session'))
|
app.use('/api/v1/users/', require('./routes/userutils'))
|
||||||
app.use('/api/v1/admin/ban', require('./routes/ban'))
|
app.use('/api/v1/admin/killsession', require('./routes/admin_kill_session'))
|
||||||
app.use('/api/v1/kaverti/job-apply', require('./routes/StaffApplications'))
|
app.use('/api/v1/admin/ban', require('./routes/ban'))
|
||||||
app.use('/api/v1/admin/', require('./routes/admin'))
|
app.use('/api/v1/kaverti/job-apply', require('./routes/StaffApplications'))
|
||||||
app.use('/api/v1/users/render', require('./routes/avatar'))
|
app.use('/api/v1/admin/', require('./routes/admin'))
|
||||||
app.use('/api/v1/users/render/', require('./routes/avatar'))
|
app.use('/api/v1/users/render', require('./routes/avatar'))
|
||||||
app.use('/api/v1/userinfo', require('./routes/userinfo'))
|
app.use('/api/v1/users/render/', require('./routes/avatar'))
|
||||||
app.use('/api/v1/wall', require('./routes/user_wall'))
|
app.use('/api/v1/userinfo', require('./routes/userinfo'))
|
||||||
app.use('/api/v1/chat/conversation', require('./routes/conversation'));
|
app.use('/api/v1/wall', require('./routes/user_wall'))
|
||||||
app.use('/api/v1/chat/message', require('./routes/message'));
|
app.use('/api/v1/chat/conversation', require('./routes/conversation'));
|
||||||
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs, { explorer: true }));
|
app.use('/api/v1/chat/message', require('./routes/message'));
|
||||||
app.use('/api/v1/teams/', require('./routes/team'))
|
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs, {explorer: true}));
|
||||||
app.use('/api/v1/teams/admin/', require('./routes/team_admin'))
|
app.use('/api/v1/teams/', require('./routes/team'))
|
||||||
app.use('/api/v1/teams/wall/', require('./routes/team_wall'))
|
app.use('/api/v1/teams/admin/', require('./routes/team_admin'))
|
||||||
app.use('/api/v1/marketplace', require('./routes/marketplace'))
|
app.use('/api/v1/teams/wall/', require('./routes/team_wall'))
|
||||||
app.use('/api/v1/inventory', require('./routes/inventory'))
|
app.use('/api/v1/marketplace', require('./routes/marketplace'))
|
||||||
app.use('/api/v1/transactions', require('./routes/transactions'))
|
app.use('/api/v1/inventory', require('./routes/inventory'))
|
||||||
app.use(require('./lib/errorHandler'))
|
app.use('/api/v1/transactions', require('./routes/transactions'))
|
||||||
app.use(profanity.init);
|
app.use(require('./lib/errorHandler'))
|
||||||
app.set('trust proxy', true)
|
app.set('trust proxy', true)
|
||||||
|
} else {
|
||||||
|
app.use('/api/v1/userinfo', require('./routes/userinfo'))
|
||||||
|
app.use('/api/v1/kaverti/state', require('./routes/state'))
|
||||||
|
app.use('/api/v1/', require('./routes/maintenance'))
|
||||||
|
app.use(require('./lib/errorHandler'))
|
||||||
|
app.set('trust proxy', true)
|
||||||
|
}
|
||||||
function main () {
|
function main () {
|
||||||
let server = app.listen(config.port, () => {
|
let server = app.listen(config.port, () => {
|
||||||
console.log('Initialized')
|
console.log('Initialized')
|
||||||
|
|
Loading…
Reference in New Issue