This commit is contained in:
Troplo 2020-10-12 22:03:09 +11:00
parent e3562ea570
commit 6c909c48c4
74 changed files with 992 additions and 633 deletions

View File

@ -0,0 +1,2 @@
VUE_APP_APIENDPOINT="/api/"
VUE_APP_APIVERSION="v1"

View File

@ -15,6 +15,7 @@
"@fortawesome/free-regular-svg-icons": "^5.13.0",
"@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/vue-fontawesome": "^0.1.9",
"@kevinfaguiar/vue-twemoji-picker": "^5.7.4",
"@saeris/vue-spinners": "^1.0.8",
"@sentry/browser": "^5.22.3",
"@sentry/integrations": "^5.22.3",
@ -30,10 +31,14 @@
"core-js": "^3.6.4",
"corejs": "^1.0.0",
"d3": "^4.9.1",
"dotenv-webpack": "^3.0.0",
"emoji-mart-vue": "^2.6.6",
"es6-promise": "^4.2.8",
"fs": "0.0.1-security",
"highlight.js": "^9.10.0",
"lodash.throttle": "^4.1.1",
"markdown-it": "^11.0.1",
"markdown-it-emoji": "^1.4.0",
"marked": "^0.8.2",
"moment": "^2.29.0",
"node-sass": "^4.13.1",

View File

@ -34,6 +34,12 @@
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.emoji {
height: 1em;
width: 1em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
</style>
<template>
<div id='app'>
@ -519,7 +525,7 @@
dailyReward () {
this.loadingLogout = true
this.axios.get(
'/api/v1/users/reward'
process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/reward'
).then(res => {
this.$store.commit('setKoins', res.data.koins)
@ -532,7 +538,7 @@
this.toggleMenu()
this.loadingLogout = true
this.axios.post(
'/api/v1/user/' +
process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' +
this.$store.state.username +
'/logout'
@ -601,7 +607,7 @@
this.login.errors.hash = ''
},
retryConnection () {
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -611,7 +617,7 @@
this.$store.commit('setDevMode', res.data.developerMode)
this.$store.commit('setTheme', res.data.theme)
this.$store.commit('setExecutive', res.data.executive)
this.axios.get('/api/v1/kaverti/state')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/state')
.then(res => {
this.$store.commit('setSettings', res.data)
this.$store.dispatch('setTitle', this.$store.state.meta.title)
@ -626,13 +632,13 @@
}
})
})
this.axios.get('/api/v1/kaverti/state')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/state')
.then(res => {
this.$store.commit('setSettings', res.data)
this.$store.dispatch('setTitle', this.$store.state.meta.title)
this.$store.commit('setAPIVersion', res.data.latestAPIVersion)
this.$store.commit('setLatestVersion', res.data.latestStableVersion)
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -694,7 +700,7 @@
this.closeAccountModal()
this.$socket.emit('accountEvent')
this.axios
.post('/api/v1/users/email-send')
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/email-send')
.then(() => {
this.email.loading = false
})
@ -735,7 +741,7 @@
this.closeAccountModal()
this.$socket.emit('accountEvent')
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -786,7 +792,7 @@
this.$store.commit('setAdmin', res.data.admin)
this.closeAccountModal()
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -815,7 +821,7 @@
}
},
mounted () {
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -837,14 +843,14 @@
this.pollConn()
}
})
this.axios.get('/api/v1/kaverti/state')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/state')
.then(res => {
this.$store.commit('setSettings', res.data)
this.$store.dispatch('setTitle', this.$store.state.meta.title)
this.$store.commit('setAPIVersion', res.data.latestAPIVersion)
this.$store.commit('setLatestVersion', res.data.latestStableVersion)
this.closeConn()
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -869,7 +875,7 @@
}
})
this.axios.get(
'/api/v1/users/reward'
process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/reward'
).then(res => {
this.$store.commit('setKoins', res.data.koins)
@ -886,7 +892,7 @@
}
})
this.axios.get('/api/v1/forums/category')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category')
.then(res => {
this.$store.commit('addCategories', res.data)
if(!this.$store.state.meta.title.length && this.$route.params.category) {

View File

@ -1113,17 +1113,17 @@ a.box:active {
}
.button.is-primary.is-light {
background-color: #f2effb;
color: #552fbc;
color: #1181fa;
}
.button.is-primary.is-light:hover, .button.is-primary.is-light.is-hovered {
background-color: #eae4f8;
border-color: transparent;
color: #552fbc;
color: #1181fa;
}
.button.is-primary.is-light:active, .button.is-primary.is-light.is-active {
background-color: #e2daf6;
border-color: transparent;
color: #552fbc;
color: #1181fa;
}
.button.is-link {
background-color: #1181fa;
@ -1210,17 +1210,17 @@ a.box:active {
}
.button.is-link.is-light {
background-color: #f2effb;
color: #552fbc;
color: #1181fa;
}
.button.is-link.is-light:hover, .button.is-link.is-light.is-hovered {
background-color: #eae4f8;
border-color: transparent;
color: #552fbc;
color: #1181fa;
}
.button.is-link.is-light:active, .button.is-link.is-light.is-active {
background-color: #e2daf6;
border-color: transparent;
color: #552fbc;
color: #1181fa;
}
.button.is-info {
background-color: #167df0;
@ -2109,7 +2109,7 @@ a.box:active {
}
.notification.is-primary.is-light {
background-color: #f2effb;
color: #552fbc;
color: #1181fa;
}
.notification.is-link {
background-color: #1181fa;
@ -2117,7 +2117,7 @@ a.box:active {
}
.notification.is-link.is-light {
background-color: #f2effb;
color: #552fbc;
color: #1181fa;
}
.notification.is-info {
background-color: #167df0;
@ -2592,7 +2592,7 @@ a.box:active {
}
.tag:not(body).is-primary.is-light {
background-color: #f2effb;
color: #552fbc;
color: #1181fa;
}
.tag:not(body).is-link {
background-color: #1181fa;
@ -2600,7 +2600,7 @@ a.box:active {
}
.tag:not(body).is-link.is-light {
background-color: #f2effb;
color: #552fbc;
color: #1181fa;
}
.tag:not(body).is-info {
background-color: #167df0;
@ -4345,7 +4345,7 @@ button.dropdown-item.is-active {
}
.message.is-primary .message-body {
border-color: #1181fa;
color: #552fbc;
color: #1181fa;
}
.message.is-link {
background-color: #f2effb;
@ -4356,7 +4356,7 @@ button.dropdown-item.is-active {
}
.message.is-link .message-body {
border-color: #1181fa;
color: #552fbc;
color: #1181fa;
}
.message.is-info {
background-color: #ecf4fe;
@ -7814,7 +7814,7 @@ a.has-text-dark:hover, a.has-text-dark:focus {
}
a.has-text-primary:hover, a.has-text-primary:focus {
color: #5a32c7 !important;
color: #1181fa !important;
}
.has-background-primary {
@ -7834,15 +7834,15 @@ a.has-text-primary-light:hover, a.has-text-primary-light:focus {
}
.has-text-primary-dark {
color: #552fbc !important;
color: #1181fa !important;
}
a.has-text-primary-dark:hover, a.has-text-primary-dark:focus {
color: #704bd2 !important;
color: #1181fa !important;
}
.has-background-primary-dark {
background-color: #552fbc !important;
background-color: #1181fa !important;
}
.has-text-link {
@ -7850,7 +7850,7 @@ a.has-text-primary-dark:hover, a.has-text-primary-dark:focus {
}
a.has-text-link:hover, a.has-text-link:focus {
color: #5a32c7 !important;
color: #1181fa !important;
}
.has-background-link {
@ -7870,15 +7870,15 @@ a.has-text-link-light:hover, a.has-text-link-light:focus {
}
.has-text-link-dark {
color: #552fbc !important;
color: #1181fa !important;
}
a.has-text-link-dark:hover, a.has-text-link-dark:focus {
color: #704bd2 !important;
color: #1181fa !important;
}
.has-background-link-dark {
background-color: #552fbc !important;
background-color: #1181fa !important;
}
.has-text-info {
@ -9622,11 +9622,11 @@ a.has-text-danger-dark:hover, a.has-text-danger-dark:focus {
color: #1181fa;
}
.hero.is-primary.is-bold {
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #9b67df 100%);
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #1181fa 100%);
}
@media screen and (max-width: 768px) {
.hero.is-primary.is-bold .navbar-menu {
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #9b67df 100%);
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #1181fa 100%);
}
}
.hero.is-link {
@ -9684,11 +9684,11 @@ a.has-text-danger-dark:hover, a.has-text-danger-dark:focus {
color: #1181fa;
}
.hero.is-link.is-bold {
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #9b67df 100%);
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #1181fa 100%);
}
@media screen and (max-width: 768px) {
.hero.is-link.is-bold .navbar-menu {
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #9b67df 100%);
background-image: linear-gradient(141deg, #3725d4 0%, #1181fa 71%, #1181fa 100%);
}
}
.hero.is-info {
@ -13549,7 +13549,7 @@ MIT (https://github.com/Wikiki/bulma-steps/blob/master/LICENSE)
background: rgba(241, 70, 104, 0.9);
}
.switch:hover input[type=checkbox]:checked + .check {
background: rgba(121, 87, 213, 0.9);
background: #1181fa;
}
.switch:hover input[type=checkbox]:checked + .check.is-white {
background: rgba(255, 255, 255, 0.9);
@ -14232,14 +14232,14 @@ MIT (https://github.com/Wikiki/bulma-steps/blob/master/LICENSE)
background: #1181fa;
}
.tag .delete.is-primary:hover, .tag.is-delete.is-primary:hover, .tag.has-delete-icon.is-primary:hover {
background-color: #5a32c7;
background-color: #1181fa;
text-decoration: none;
}
.tag .delete.is-link, .tag.is-delete.is-link, .tag.has-delete-icon.is-link {
background: #1181fa;
}
.tag .delete.is-link:hover, .tag.is-delete.is-link:hover, .tag.has-delete-icon.is-link:hover {
background-color: #5a32c7;
background-color: #1181fa;
text-decoration: none;
}
.tag .delete.is-info, .tag.is-delete.is-info, .tag.has-delete-icon.is-info {

View File

@ -49,7 +49,7 @@ export default {
replaceLink(cached, link);
} else {
Vue.axios
.get('/api/v1/forums/link_preview?url=' + link.href)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/link_preview?url=' + link.href)
.then(res => {
cache[link.href] = res.data;
replaceLink(res.data, link);

View File

@ -4,10 +4,10 @@ export default function (route, resourceId) {
//In which case resourceId is really the username
if(route === 'userPosts' || route === 'userThreads') {
axios
.get('/api/v1/user/' + resourceId)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + resourceId)
.then(res => {
return axios
.post('/api/v1/log', {
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'log', {
route,
resourceId: res.data.id
})
@ -15,7 +15,7 @@ export default function (route, resourceId) {
.catch(console.log)
} else {
axios
.post('/api/v1/log', {
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'log', {
route,
resourceId
})

View File

@ -144,7 +144,7 @@
this.loading = true
this.axios
.post('/api/v1/forums/category', { name: this.add.name, color: this.add.color, locked: this.add.locked })
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category', { name: this.add.name, color: this.add.color, locked: this.add.locked })
.then(res => {
this.toggleAddModal()
this.loading = false
@ -155,7 +155,7 @@
},
removeCategory (id, index) {
this.axios
.delete('/api/v1/forums/category/' + id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category/' + id)
.then(res => {
this.categories.splice(index, 1)
this.$store.commit('removeCategory', id)
@ -170,7 +170,7 @@
this.loading = true
this.axios
.put('/api/v1/forums/category/' + this.edit.id ,{
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category/' + this.edit.id ,{
name: this.edit.name,
color: this.edit.color,
locked: this.edit.locked
@ -187,7 +187,7 @@
},
mounted () {
this.axios
.get('/api/v1/forums/category')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category')
.then(res => {
this.categories = res.data.filter(c => c.name !== 'Other')
})

View File

@ -37,7 +37,7 @@
this.loading = true
let settingsReq = this.axios.put('/api/v1/kaverti/state', {
let settingsReq = this.axios.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/state', {
siteName: this.name,
siteDesc: this.description || '',
showDescription: this.showDescription
@ -62,7 +62,7 @@
},
mounted () {
this.axios
.get('/api/v1/kaverti/state')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/state')
.then(res => {
this.name = res.data.siteName || ''
this.description = res.data.siteDesc || ''

View File

@ -58,7 +58,7 @@
},
getLink () {
this.axios
.post('/api/v1/admin/admin_token')
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/admin_token')
.then(res => {
this.link = window.location.origin + '/?token=' + res.data.token
this.toggleModal()
@ -87,7 +87,7 @@
},
created () {
this.axios
.get('/api/v1/user?role=admin')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user?role=admin')
.then(res => {
this.admins = res.data
})

View File

@ -30,7 +30,7 @@
this.loading = true
this.axios
.post('/api/v1/admin/killsession/' + this.username)
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/killsession/' + this.username)
.then(res => {
this.loading = false
this.KillSession.push(res.data)

View File

@ -85,7 +85,7 @@
if(this.userData || this.user === null) return;
this.axios
.get('/api/v1/user/' + this.proxyUser.username)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + this.proxyUser.username)
.then((res) => {
this.userData = res.data;
})

View File

@ -67,7 +67,7 @@
.emoji_selector {
display: inline-block;
position: absolute;
@at-root #{&}__context {
transform: translateZ(0);
position: relative;
@ -100,7 +100,7 @@
border-radius: 0.25rem;
border: 0.125rem solid $color__gray--primary;
background-color: #fff;
left: 0.25rem;
box-shadow: 0 10px 10px rgba(0, 0, 0, 0.22);
cursor: default;
@ -149,4 +149,4 @@
display: none;
}
}
</style>
</style>

View File

@ -99,10 +99,10 @@
if(!this.liked) {
this.axios
.put('/api/v1/forums/post/' + id + '/like')
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + id + '/like')
.then(() => {
return this.axios
.get('/api/v1/user/' + this.$store.state.username)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + this.$store.state.username)
})
.then(res => {
this.likes.push(res.data)
@ -110,7 +110,7 @@
.catch(AjaxErrorHandler(this.$store))
} else {
this.axios
.delete('/api/v1/forums/post/' + id + '/like')
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + id + '/like')
.then(() => {
this.likes.splice(this.getIndexOfUser(), 1)
})

View File

@ -13,7 +13,7 @@
<div class='input_editor__reply_username' v-if='replyUsername'>Replying to <strong>{{replyUsername}}</strong></div>
<div class='input_editor__close input_editor__format_button' @click='closeEditor'>&times;</div>
<tab-view :tabs='["Editor"]' v-model='showTab' :small-tabs='true'>
<tab-view :tabs='["Editor", "Preview"]' v-model='showTab' :small-tabs='true'>
<template slot='Editor'>
<input-editor-core
:value='value'
@ -26,6 +26,9 @@
@blur='setFocusInput(false)'
></input-editor-core>
</template>
<template slot='Preview'>
<input-editor-preview :value='value' :mentions='mentions'></input-editor-preview>
</template>
</tab-view>
@ -37,7 +40,8 @@
<script>
import InputEditorCore from './InputEditorCore'
import LoadingIcon from './LoadingIcon'
import InputEditorPreview from './InputEditorPreview'
import LoadingIcon from './LoadingIcon'
import TabView from './TabView'
@ -47,7 +51,8 @@
components: {
InputEditorCore,
LoadingIcon,
TabView
TabView,
InputEditorPreview
},
data () {
return {

View File

@ -1,402 +1,391 @@
<template>
<div
class='input_editor_core'
>
<div>
<emoji-selector
v-model='emojiSelectorVisible'
<div
class='input_editor_core'
>
<div>
<emoji-selector
v-model='emojiSelectorVisible'
style='margin-left: 0.25rem;'
@emoji='addEmoji'
:right-align='rightAlignEmoji'
></emoji-selector>
:right-align='rightAlignEmoji'
></emoji-selector>
<div class='panel-block'>
<div
class='input_editor_core__format_button input_editor_core__format_button--emoji'
<div class='panel-block'>
<div
class='input_editor_core__format_button input_editor_core__format_button--emoji'
style='margin-left: 0.25rem;'
title='Emoji'
@click='emojiSelectorVisible = true'
>
<font-awesome-icon :icon='["fa", "grin"]' />
</div>
<div
class='input_editor_core__format_button'
style='margin-left: 0.25rem;'
title='Bold (CTRL + B)'
@click='replaceSelectedText("__", "__")'
>
B
</div>
<div
class='input_editor_core__format_button'
style='margin-left: 0.25rem;'
title='Italic (CTRL + I)'
@click='replaceSelectedText("*", "*")'
>
I
</div>
@click='emojiSelectorVisible = true'
>
<font-awesome-icon :icon='["fa", "grin"]' />
</div>
<div
class='input_editor_core__format_button'
style='margin-left: 0.25rem;'
title='New line (CTRL + Q)'
@click='replaceSelectedText("", `\\
`)'
title='Bold (CTRL + B)'
@click='replaceSelectedText("__", "__")'
>
B
</div>
<div
class='input_editor_core__format_button'
<div
class='input_editor_core__format_button'
style='margin-left: 0.25rem;'
title='Italic (CTRL + I)'
@click='replaceSelectedText("*", "*")'
>
I
</div>
<div
class='input_editor_core__format_button'
style='margin-left: 0.25rem;'
title='Link (CTRL + L)'
@click='setModalState("link", true)'
>
<font-awesome-icon :icon='["fa", "link"]' />
</div>
<div
class='input_editor_core__format_button'
style='margin-left: 0.25rem;'
title='Code (CTRL + K)'
@click='formatCode'
>
<font-awesome-icon :icon='["fa", "code"]' />
</div>
</div>
<textarea
class='input_editor_core__input'
placeholder='Type here - you can format using Markdown'
@click='setModalState("link", true)'
>
<font-awesome-icon :icon='["fa", "link"]' />
</div>
<div
class='input_editor_core__format_button'
style='margin-left: 0.25rem;'
title='Code (CTRL + K)'
@click='formatCode'
>
<font-awesome-icon :icon='["fa", "code"]' />
</div>
</div>
<textarea
class='input_editor_core__input'
placeholder='Type here - you can format using Markdown'
ref='textarea'
:value='value'
ref='textarea'
:value='value'
@input='setEditor($event.target.value)'
@focus='$emit("focus")'
@blur='$emit("blur")'
@input='setEditor($event.target.value)'
@focus='$emit("focus")'
@blur='$emit("blur")'
@keydown.ctrl.66.prevent='replaceSelectedText("__", "__")'
@keydown.ctrl.73.prevent='replaceSelectedText("*", "*")'
@keydown.ctrl.76.prevent='setModalState("link", true)'
@keydown.ctrl.81.prevent='replaceSelectedText("", `\\
`)'
@keydown.ctrl.75.prevent='formatCode'
>
@keydown.ctrl.66.prevent='replaceSelectedText("__", "__")'
@keydown.ctrl.73.prevent='replaceSelectedText("*", "*")'
@keydown.ctrl.76.prevent='setModalState("link", true)'
@keydown.ctrl.75.prevent='formatCode'
>
</textarea>
</div>
</div>
<modal-window v-model='linkModalVisible'>
<modal-window v-model='linkModalVisible'>
<div slot="header">
<h2>
Attach link to post
</h2>
</div>
<div slot='main' class="card-content">
<fancy-input placeholder='Text for link' width='100%' v-model='linkText'></fancy-input>
<fancy-input placeholder='Web address for link' width='100%' v-model='linkURL'></fancy-input>
</div>
<div slot='main' class="card-content">
<fancy-input placeholder='Text for link' width='100%' v-model='linkText'></fancy-input>
<fancy-input placeholder='Web address for link' width='100%' v-model='linkURL'></fancy-input>
</div>
<div slot='footer'>
<button class='button button--green button--modal' @click='addLink'>
Add link
</button>
<button class='button button--modal' @click='setModalState("link", false)'>
Cancel
</button>
</div>
</modal-window>
<div slot='footer'>
<button class='button button--green button--modal' @click='addLink'>
Add link
</button>
<button class='button button--modal' @click='setModalState("link", false)'>
Cancel
</button>
</div>
</modal-window>
</div>
</div>
</template>
<script>
import ModalWindow from './ModalWindow'
import FancyInput from './FancyInput'
import EmojiSelector from './EmojiSelector'
import ModalWindow from './ModalWindow'
import FancyInput from './FancyInput'
import EmojiSelector from './EmojiSelector'
let usernames = {}
let usernames = {}
export default {
name: 'InputEditorCore',
props: ['value', 'error', 'right-align-emoji'],
components: {
ModalWindow,
FancyInput,
EmojiSelector
},
data () {
return {
linkText: '',
linkURL: '',
linkModalVisible: false,
imageModalVisible: false,
emojiSelectorVisible: false
}
},
methods: {
setModalState (modal, state) {
if(modal === 'link') {
this.linkModalVisible = state
export default {
name: 'InputEditorCore',
props: ['value', 'error', 'right-align-emoji'],
components: {
ModalWindow,
FancyInput,
EmojiSelector
},
data () {
return {
linkText: '',
linkURL: '',
linkModalVisible: false,
imageModalVisible: false,
emojiSelectorVisible: false
}
},
methods: {
setModalState (modal, state) {
if(modal === 'link') {
this.linkModalVisible = state
if(state) {
this.linkText = this.getSelectionData().val;
} else {
this.linkText = '';
this.linkURL = '';
}
} else if(modal === 'image') {
this.imageModalVisible = state
}
},
checkUsernames (matches) {
let doneCount = 0
let mentions = []
if(state) {
this.linkText = this.getSelectionData().val;
} else {
this.linkText = '';
this.linkURL = '';
}
} else if(modal === 'image') {
this.imageModalVisible = state
}
},
checkUsernames (matches) {
let doneCount = 0
let mentions = []
let done = res => {
doneCount++
let done = res => {
doneCount++
if(res) mentions.push(res)
if(res) mentions.push(res)
if(doneCount === matches.length) {
this.$emit('mentions', mentions)
}
}
if(doneCount === matches.length) {
this.$emit('mentions', mentions)
}
}
matches.forEach(match => {
this.checkUsername(match, done)
})
matches.forEach(match => {
this.checkUsername(match, done)
})
},
checkUsername (match, cb) {
let username = match.trim().slice(1)
let checkedUsername = usernames[username]
},
checkUsername (match, cb) {
let username = match.trim().slice(1)
let checkedUsername = usernames[username]
if(checkedUsername !== undefined) {
cb(checkedUsername)
} else if(checkedUsername === undefined) {
this.axios
.get('/api/v1/user/' + username)
.then(() => {
usernames[username] = username
cb(username)
})
.catch(() => {
usernames[username] = null
cb(null)
})
}
},
setEditor (value) {
let matches = value.match(/(^|\s)@[^\s]+/g) || []
this.checkUsernames(matches)
if(checkedUsername !== undefined) {
cb(checkedUsername)
} else if(checkedUsername === undefined) {
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + username)
.then(() => {
usernames[username] = username
cb(username)
})
.catch(() => {
usernames[username] = null
cb(null)
})
}
},
setEditor (value) {
let matches = value.match(/(^|\s)@[^\s]+/g) || []
this.checkUsernames(matches)
this.$emit('input', value)
},
getSelectionData () {
var el = this.$refs.textarea,
start = el.selectionStart,
end = el.selectionEnd;
this.$emit('input', value)
},
getSelectionData () {
var el = this.$refs.textarea,
start = el.selectionStart,
end = el.selectionEnd;
return {
val: el.value.slice(start, end),
start,
end
};
return {
val: el.value.slice(start, end),
start,
end
};
},
replaceSelectedText (before, after) {
var selectionData = this.getSelectionData();
var el = this.$refs.textarea;
},
replaceSelectedText (before, after) {
var selectionData = this.getSelectionData();
var el = this.$refs.textarea;
if(
this.value.substr(selectionData.start - before.length, before.length) === before &&
this.value.substr(selectionData.end, after.length) === after
) {
this.setEditor(
this.value.slice(0, selectionData.start - before.length) +
selectionData.val +
this.value.slice(selectionData.end + after.length)
);
setTimeout(function() {
el.selectionStart = selectionData.start - before.length;
el.selectionEnd = selectionData.end - after.length;
}, 0);
} else {
this.setEditor(
this.value.slice(0, selectionData.start) +
before + selectionData.val + after +
this.value.slice(selectionData.end)
);
setTimeout(function() {
el.selectionStart = selectionData.start + before.length;
el.selectionEnd = selectionData.end + after.length;
}, 0);
}
if(
this.value.substr(selectionData.start - before.length, before.length) === before &&
this.value.substr(selectionData.end, after.length) === after
) {
this.setEditor(
this.value.slice(0, selectionData.start - before.length) +
selectionData.val +
this.value.slice(selectionData.end + after.length)
);
setTimeout(function() {
el.selectionStart = selectionData.start - before.length;
el.selectionEnd = selectionData.end - after.length;
}, 0);
} else {
this.setEditor(
this.value.slice(0, selectionData.start) +
before + selectionData.val + after +
this.value.slice(selectionData.end)
);
setTimeout(function() {
el.selectionStart = selectionData.start + before.length;
el.selectionEnd = selectionData.end + after.length;
}, 0);
}
el.focus(selectionData.end);
},
addLink () {
var linkTextLength = this.linkText.length;
var selectionData = this.getSelectionData();
var el = this.$refs.textarea;
el.focus(selectionData.end);
},
addLink () {
var linkTextLength = this.linkText.length;
var selectionData = this.getSelectionData();
var el = this.$refs.textarea;
this.setEditor(
this.value.slice(0, selectionData.start) +
'[' + this.linkText + '](' + this.linkURL + ')' +
this.value.slice(selectionData.end)
);
el.focus();
this.setEditor(
this.value.slice(0, selectionData.start) +
'[' + this.linkText + '](' + this.linkURL + ')' +
this.value.slice(selectionData.end)
);
el.focus();
setTimeout(function() {
el.selectionStart = selectionData.start + 1;
el.selectionEnd = selectionData.start + 1 + linkTextLength;
}, 0);
setTimeout(function() {
el.selectionStart = selectionData.start + 1;
el.selectionEnd = selectionData.start + 1 + linkTextLength;
}, 0);
this.setModalState('link', false);
},
addEmoji (emoji) {
var selectionData = this.getSelectionData();
var el = this.$refs.textarea;
this.setModalState('link', false);
},
addEmoji (emoji) {
var selectionData = this.getSelectionData();
var el = this.$refs.textarea;
this.setEditor(
this.value.slice(0, selectionData.start) +
emoji +
this.value.slice(selectionData.end)
);
el.focus();
this.setEditor(
this.value.slice(0, selectionData.start) +
emoji +
this.value.slice(selectionData.end)
);
el.focus();
setTimeout(function() {
el.selectionStart = selectionData.start + emoji.length;
el.selectionEnd = selectionData.start + emoji.length;
}, 0);
},
formatCode (e) {
e.preventDefault()
setTimeout(function() {
el.selectionStart = selectionData.start + emoji.length;
el.selectionEnd = selectionData.start + emoji.length;
}, 0);
},
formatCode (e) {
e.preventDefault()
var selectionData = this.getSelectionData();
var selectionData = this.getSelectionData();
if(this.value[selectionData.start-1] === '\n' || selectionData.start === 0) {
var el = this.$refs.textarea;
var matches = ( selectionData.val.match(/\n/g) || [] ).length
var replacedText = ' ' + selectionData.val.replace(/\n/g, '\n ')
if(this.value[selectionData.start-1] === '\n' || selectionData.start === 0) {
var el = this.$refs.textarea;
var matches = ( selectionData.val.match(/\n/g) || [] ).length
var replacedText = ' ' + selectionData.val.replace(/\n/g, '\n ')
this.setEditor(
this.value.slice(0, selectionData.start) +
replacedText +
this.value.slice(selectionData.end)
);
el.focus();
this.setEditor(
this.value.slice(0, selectionData.start) +
replacedText +
this.value.slice(selectionData.end)
);
el.focus();
setTimeout(function() {
el.selectionStart = selectionData.start + 4;
el.selectionEnd = selectionData.end + (matches + 1)*4;
}, 0);
} else {
this.replaceSelectedText('`', '`');
}
}
}
}
setTimeout(function() {
el.selectionStart = selectionData.start + 4;
el.selectionEnd = selectionData.end + (matches + 1)*4;
}, 0);
} else {
this.replaceSelectedText('`', '`');
}
}
}
}
</script>
<style lang='scss' scoped>
@import '../assets/scss/variables.scss';
@import '../assets/scss/variables.scss';
.input_editor_core {
@at-root #{&}__format_bar {
width: auto;
position: absolute;
height: 2rem;
top: 0.25rem;
right: 0;
background-color: transparent;
display: flex;
align-items: center;
padding: 0 0.125rem;
margin-right: 2.4rem;
}
@at-root #{&}__format_button {
height: 1.5rem;
width: 1.5rem;
border-radius: 0.25rem;
text-align: center;
line-height: 1.4rem;
cursor: pointer;
@include user-select(none);
@include text($font--role-default, 1rem, 600);
color: $color__darkgray--primary;
transition: background-color 0.2s;
.input_editor_core {
@at-root #{&}__format_bar {
width: auto;
position: absolute;
height: 2rem;
top: 0.25rem;
right: 0;
background-color: transparent;
display: flex;
align-items: center;
padding: 0 0.125rem;
margin-right: 2.4rem;
}
@at-root #{&}__format_button {
height: 1.5rem;
width: 1.5rem;
border-radius: 0.25rem;
text-align: center;
line-height: 1.4rem;
cursor: pointer;
@include user-select(none);
@include text($font--role-default, 1rem, 600);
color: $color__darkgray--primary;
transition: background-color 0.2s;
&:hover {
background-color: $color__gray--darker;
}
&:active {
background-color: $color__gray--darkest;
}
}
&:hover {
background-color: $color__gray--darker;
}
&:active {
background-color: $color__gray--darkest;
}
}
@at-root #{&}__spacer {
width: 0.6rem;
}
@at-root #{&}__spacer {
width: 0.6rem;
}
@at-root #{&}__input {
width: 100%;
height: 8rem;
border: 0;
padding: 0.5rem;
@include text;
outline: none;
resize: none;
@at-root #{&}__input {
width: 100%;
height: 8rem;
border: 0;
padding: 0.5rem;
@include text;
outline: none;
resize: none;
@include placeholder {
@include text($font--role-emphasis, 1rem);
display: flex;
align-content: center;
@include user-select(none);
cursor: default;
}
}
@include placeholder {
@include text($font--role-emphasis, 1rem);
display: flex;
align-content: center;
@include user-select(none);
cursor: default;
}
}
@at-root #{&}__error {
position: absolute;
background-color: #ffeff1;
border: 0.125rem solid #D32F2F;
font-size: 0.9rem;
padding: 0.1rem 0.25rem;
top: 0.2125rem;
left: calc(100% + 0.25rem);
white-space: nowrap;
@at-root #{&}__error {
position: absolute;
background-color: #ffeff1;
border: 0.125rem solid #D32F2F;
font-size: 0.9rem;
padding: 0.1rem 0.25rem;
top: 0.2125rem;
left: calc(100% + 0.25rem);
white-space: nowrap;
&:first-letter{ text-transform: capitalize; }
&:first-letter{ text-transform: capitalize; }
opacity: 0;
pointer-events: none;
margin-top: -1rem;
transition: opacity 0.2s, margin-top 0.2s;
opacity: 0;
pointer-events: none;
margin-top: -1rem;
transition: opacity 0.2s, margin-top 0.2s;
@at-root #{&}--show {
opacity: 1;
pointer-events: all;
margin-top: 0;
transition: opacity 0.2s, margin-top 0.2s;
}
@at-root #{&}--show {
opacity: 1;
pointer-events: all;
margin-top: 0;
transition: opacity 0.2s, margin-top 0.2s;
}
&::after {
content: '';
position: relative;
width: 0;
height: 0;
display: inline-block;
right: calc(100% + 0.3rem);
border-top: 0.3rem solid transparent;
border-bottom: 0.3rem solid transparent;
border-right: 0.3rem solid #D32F2F;
}
}
}
&::after {
content: '';
position: relative;
width: 0;
height: 0;
display: inline-block;
right: calc(100% + 0.3rem);
border-top: 0.3rem solid transparent;
border-bottom: 0.3rem solid transparent;
border-right: 0.3rem solid #D32F2F;
}
}
}
@media (max-width: 420px) {
.input_editor_core__format_button--emoji {
display: none;
}
}
@media (max-width: 420px) {
.input_editor_core__format_button--emoji {
display: none;
}
}
</style>

View File

@ -1,75 +1,97 @@
<template>
<div class='input_editor_preview__markdownHTML'>
<!--
A hack to call the getHTML() function, not sure why
the value watcher function is not working, as it does
in the ThreadNew page
!-->
<div style='display: none;'>{{valueWatch}}</div>
<div v-html='HTML' style='margin-top: -0.5rem;'></div>
<div v-if='!value.trim().length' class='input_editor_preview__markdownHTML--empty'>
Type to get a preview of your MarkDown
</div>
</div>
</template>
<script>
import Marked from 'marked'
var md = require('markdown-it')({
html: false, // Enable HTML tags in source
xhtmlOut: false, // Use '/' to close single tags (<br />).
// This is only for full CommonMark compatibility.
breaks: true, // Convert '\n' in paragraphs into <br>
langPrefix: 'language-', // CSS language prefix for fenced blocks. Can be
// useful for external highlighters.
linkify: true, // Autoconvert URL-like text to links
image: false,
Marked.setOptions({
highlight: function (code) {
return require('highlight.js').highlightAuto(code).value;
}
});
// Enable some language-neutral replacement + quotes beautification
typographer: true,
const renderer = new Marked.Renderer();
renderer.link = function (href, title, text) {
if(!href.match(/[a-z]+:\/\/.+/i)) {
href = 'http://' + href;
}
// Double + single quotes replacement pairs, when typographer enabled,
// and smartquotes on. Could be either a String or an Array.
//
// For example, you can use '«»' for Russian, '' for German,
// and ['«\xA0', '\xA0»', '\xA0', '\xA0'] for French (including nbsp).
quotes: '“”‘’',
return `
<a @click='showAjaxErrorsModal = true'>
${text}
</a>
`;
};
export default {
name: 'InputEditorPreview',
props: ['value', 'mentions'],
data () {
return {
HTML: ''
}
},
computed: {
valueWatch () {
this.getHTML();
return '';
}
},
methods: {
getHTML () {
let replacedMd = this.value;
(this.mentions || []).forEach(mention => {
let regexp = new RegExp('(^|\\s)@' + mention + '($|\\s)')
replacedMd = replacedMd.replace(regexp, `$1[@${mention}](/user/${mention})$2`)
})
let HTML = Marked(replacedMd, { renderer });
this.HTML = HTML;
this.$linkExpander(HTML, v => this.HTML = v);
}
}
}
// Highlighter function. Should return escaped HTML,
// or '' if the source string is not changed and should be escaped externally.
// If result starts with <pre... internal wrapper is skipped.
highlight: function (/*str, lang*/) { return ''; }
});
md.disable('image')
var emoji = require('markdown-it-emoji');
var twemoji = require('twemoji')
md.use(emoji);
md.renderer.rules.emoji = function(token, idx) {
return twemoji.parse(token[idx].content);
};
export default {
name: 'InputEditorPreview',
props: ['value', 'mentions'],
data () {
return {
HTML: ''
}
},
computed: {
valueWatch () {
this.getHTML();
return '';
}
},
methods: {
getHTML () {
let replacedMd = this.value;
(this.mentions || []).forEach(mention => {
let regexp = new RegExp('(^|\\s)@' + mention + '($|\\s)')
replacedMd = replacedMd.replace(regexp, `$1[@${mention}](/user/${mention})$2`)
})
let HTML =md.render(replacedMd);
this.HTML = HTML;
this.$linkExpander(HTML, v => this.HTML = v);
}
}
}
</script>
<style lang='scss' scoped>
@import '../assets/scss/variables.scss';
.input_editor_preview {
@at-root #{&}__markdownHTML {
height: 8.125rem;
overflow: auto;
padding: 0.5rem;
@at-root #{&}--empty {
@include text($font--role-emphasis, 1rem);
display: flex;
margin-top: 0.5rem;
align-content: center;
@include user-select(none);
cursor: default;
color: $color__darkgray--primary;
}
}
}
@import '../assets/scss/variables.scss';
.input_editor_preview {
@at-root #{&}__markdownHTML {
height: 8.125rem;
overflow: auto;
padding: 0.5rem;
@at-root #{&}--empty {
@include text($font--role-emphasis, 1rem);
display: flex;
margin-top: 0.5rem;
align-content: center;
@include user-select(none);
cursor: default;
color: $color__darkgray--primary;
}
}
}
</style>

View File

@ -37,7 +37,7 @@
},
mounted () {
this.axios
.get('/api/v1/forums/category/' + this.category.value)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category/' + this.category.value)
.then(res => {
let filtered = res.data.Threads.filter(thread => {
return thread.id !== this.threadId

View File

@ -125,7 +125,7 @@
},
getNotifications () {
this.axios
.get('/api/v1/users/notification')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification')
.then(res => {
this.notifications = res.data.Notifications
this.unreadCount = res.data.unreadCount
@ -136,7 +136,7 @@
},
resetUnreadCount () {
this.axios
.put('/api/v1/users/notification')
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification')
.then(() => {
this.unreadCount = 0
})
@ -146,7 +146,7 @@
let index = this.getIndexById(id)
this.axios
.delete('/api/v1/users/notification/' + id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification/' + id)
.then(() => {
this.notifications.splice(index, 1)
})
@ -157,7 +157,7 @@
let item = this.notifications[index]
this.axios
.put('/api/v1/users/notification/' + id)
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification/' + id)
.then(() => {
this.$set(
this.notifications,

View File

@ -45,7 +45,7 @@
if(this.post) return
this.axios
.get('/api/v1/forums/post/' + this.replyId)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + this.replyId)
.then((res) => {
this.post = res.data
})

View File

@ -52,7 +52,7 @@
this.loading = true
this.axios
.post('/api/v1/users/report/post', {
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/report/post', {
postId: this.postId,
reason: this.selectedOption
})

View File

@ -297,7 +297,7 @@
this.users = [];
this.axios
.get('/api/v1/kaverti/search/thread?q=' + q)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/thread?q=' + q)
.then(res => {
this.threads = res.data.threads.slice(0, 3);
this.loading = false;
@ -305,7 +305,7 @@
.catch(AjaxErrorHandler(this.$store));
this.axios
.get('/api/v1/kaverti/search/user?q=' + q)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/user?q=' + q)
.then(res => {
this.users = res.data.users.slice(0, 5);
this.loading = false;

View File

@ -49,8 +49,9 @@
({{result.percent || 0}}%)
</span>
</div>
<div class='poll__result__bar_outer'></div>
<div class='poll__result__bar' :style='{ "width": (result.percent || 0) + "%" }'></div>
<b-progress size="is-large" :value="result.percent" show-value format="percent">
{{result.answer}} - {{result.percent}}%
</b-progress>
</div>
</div>
@ -94,7 +95,7 @@
this.loading = true
this.axios
.post('/api/v1/forums/poll/' + this.id, { answer: this.selected.answer })
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/poll/' + this.id, { answer: this.selected.answer })
.then(res => {
this.poll = res.data
this.loading = false
@ -109,7 +110,7 @@
},
mounted () {
this.axios
.get('/api/v1/forums/poll/' + this.id)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/poll/' + this.id)
.then(res => this.poll = res.data)
.catch(AjaxErrorHandler(this.$store))
}

View File

@ -132,7 +132,7 @@ export default {
methods: {
deleteReport (id, index) {
return this.axios
.delete('/api/v1/users/report/' + id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/report/' + id)
.then(() => {
this.reports.splice(index, 1)
})
@ -148,7 +148,7 @@ export default {
let threadId = this.removePostObj.report.Post.Thread.id
this.axios
.delete('/api/v1/forums/thread/' + threadId)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + threadId)
.then(() => {
//Get reports with id of deleted thread
//and remove them locally
@ -168,9 +168,9 @@ export default {
this.removePostObj.showConfirmModal = true
} else {
this.axios
.delete('/api/v1/forums/post/' + this.removePostObj.report.Post.id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + this.removePostObj.report.Post.id)
.then(() => {
return this.axios.delete('/api/v1/users/report/post/' + this.removePostObj.report.id)
return this.axios.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/report/post/' + this.removePostObj.report.id)
})
.then(() => {
this.reports.splice(this.removePostObj.index, 1)
@ -192,7 +192,7 @@ export default {
this.$store.dispatch('setTitle', 'Moderation - Admin')
this.axios
.get('/api/v1/users/report')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/report')
.then(res => {
this.reports = res.data
})

View File

@ -115,7 +115,7 @@
},
modifyUser (user) {
this.axios
.put('/api/v1/admin/user/modify', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/user/modify', {
username: user.username,
bot: user.bot,
system: user.system,

View File

@ -179,7 +179,7 @@
this.loading = true
this.axios
.post('/api/v1/admin/ban', obj)
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/ban', obj)
.then(res => {
this.loading = false
this.bans_.push(res.data)
@ -193,7 +193,7 @@
},
deleteBan (ban, index) {
this.axios
.delete('/api/v1/admin/ban/' + ban.id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/ban/' + ban.id)
.then(() => {
this.bans_.splice(index, 1)
})
@ -203,7 +203,7 @@
mounted () {
this.$store.dispatch('setTitle', '')
this.axios
.get('/api/v1/admin/ban')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/ban')
.then(res => {
this.bans_ = res.data
})

View File

@ -139,7 +139,7 @@
methods: {
deleteReport (id, index) {
return this.axios
.delete('/api/v1/users/report/' + id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/report/' + id)
.then(() => {
this.reports.splice(index, 1)
})
@ -155,7 +155,7 @@
let threadId = this.removePostObj.report.Post.Thread.id
this.axios
.delete('/api/v1/forums/thread/' + threadId)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + threadId)
.then(() => {
//Get reports with id of deleted thread
//and remove them locally
@ -175,9 +175,9 @@
this.removePostObj.showConfirmModal = true
} else {
this.axios
.delete('/api/v1/forums/post/' + this.removePostObj.report.Post.id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + this.removePostObj.report.Post.id)
.then(() => {
return this.axios.delete('/api/v1/users/report/post/' + this.removePostObj.report.id)
return this.axios.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/report/post/' + this.removePostObj.report.id)
})
.then(() => {
this.reports.splice(this.removePostObj.index, 1)
@ -199,7 +199,7 @@
this.$store.dispatch('setTitle', 'Moderation - Admin')
this.axios
.get('/api/v1/users/report')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/report')
.then(res => {
this.reports = res.data
})

View File

@ -14,7 +14,7 @@
stopService() {
this.loading = true
this.axios.post('/api/v1/admin/service/stop', {
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/service/stop', {
action: "stop"
}).then(() => {
this.loading = false

View File

@ -19,6 +19,9 @@
<b-switch v-model="user.bot">
Bot
</b-switch><br>
<b-switch type="is-dark" v-model="user.hidden">
Hidden
</b-switch><br>
<b-switch type="is-danger" v-model="user.admin" v-if="$store.state.executive">
Admin
</b-switch>
@ -70,7 +73,7 @@
<sort-menu v-model='tableSort' column='threadCount' display='Threads count'></sort-menu>
</th>
</tr>
<tr v-for='user in users' :key='"user-row" + user.username' v-show="user && !user.hidden">
<tr v-for='user in users' :key='"user-row" + user.username' v-show="user">
<td class='admin_users__user_column'>
<avatar-icon :user='user' size='small'></avatar-icon>
<router-link :to='"/user/" + user.username'>{{user.username}}</router-link>
@ -175,7 +178,8 @@
booster: '',
bot: '',
system: '',
admin: ''
admin: '',
hidden: ''
},
}
},
@ -194,12 +198,13 @@
},
modifyUser (user) {
this.axios
.put('/api/v1/admin/user/modify', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/user/modify', {
username: user.username,
bot: user.bot,
system: user.system,
booster: user.booster,
admin: user.admin
admin: user.admin,
hidden: user.hidden
})
.then(() => {
this.showBadgeModal = false

View File

@ -55,7 +55,7 @@
this.loading = true
this.axios
.post('/api/v1/users/unban-request', {
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/unban-request', {
reason: this.selectedOption
})
.then(() => {

View File

@ -116,7 +116,7 @@ export default {
getThreads (initial) {
if(this.nextURL === null && !initial) return
let URL = '/api/v1/forums/category/' + this.selectedCategory
let URL = process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category/' + this.selectedCategory
if(!initial) {
URL = this.nextURL || URL
}
@ -147,7 +147,7 @@ export default {
this.loadingNewer = true
this.axios
.get('/api/v1/forums/category/' + this.selectedCategory + '?limit=' + this.newThreads)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category/' + this.selectedCategory + '?limit=' + this.newThreads)
.then(res => {
this.loadingNewer = false
this.newThreads = 0

View File

@ -1,6 +1,6 @@
<template>
<!--
* Character customisation page almost complete, please wait. ~Bytetrex
* Character customisation page almost complete, please wait. ~Bytetrex
* What's Coming?
* Avatar mask (colors [modal]), inventory, equipped items, current avatar render display.
-->
@ -77,7 +77,7 @@ export default {
methods: {
RefreshAvatar () {
this.axios
.post('/api/v1/users/avatar/refresh', {
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/avatar/refresh', {
})
.then(() => {
this.refreshavatar.loading = false

View File

@ -32,7 +32,7 @@ export default {
retryConnection() {
this.connection.loading = true
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)

View File

@ -126,7 +126,7 @@ export default {
this.loadingNewer = true
this.axios
.get('/api/v1/users' + '?limit=' + this.newUsers)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users' + '?limit=' + this.newUsers)
.then(res => {
this.loadingNewer = false
this.newUsers = 0

View File

@ -72,7 +72,7 @@ export default {
},
mounted () {
this.$store.dispatch('setTitle', 'Email Verification')
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)

View File

@ -64,7 +64,7 @@
this.email.loading = true
this.axios
.post('/api/v1/users/email-send')
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/email-send')
.then(() => {
this.email.loading = false
})
@ -76,7 +76,7 @@
},
mounted () {
this.$store.dispatch('setTitle', 'Email Verification Failure')
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)

View File

@ -41,7 +41,7 @@
},
mounted () {
this.$store.dispatch('setTitle', 'Email Verification')
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)

View File

@ -175,7 +175,7 @@ export default {
this.loading = true
this.axios
.post('/api/v1/kaverti/job-apply', {
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/job-apply', {
username: this.apply.username,
dob: this.apply.dob,
email: this.apply.email,

View File

@ -190,7 +190,7 @@
},
getUserInfo () {
this.axios
.get('/api/v1/userinfo')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
},
clearErrors () {
this.errors.content = ''

View File

@ -249,7 +249,7 @@
getThreads (initial) {
if(this.nextURL === null && !initial) return
let URL = '/api/v1/forums/category/' + this.selectedCategory
let URL = process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category/' + this.selectedCategory
if(!initial) {
URL = this.nextURL || URL
}
@ -280,7 +280,7 @@
this.loadingNewer = true
this.axios
.get('/api/v1/forums/category/' + this.selectedCategory + '?limit=' + this.newThreads)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/category/' + this.selectedCategory + '?limit=' + this.newThreads)
.then(res => {
this.loadingNewer = false
this.newThreads = 0

View File

@ -110,7 +110,7 @@
},
getNotifications () {
this.axios
.get('/api/v1/users/notification')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification')
.then(res => {
this.notifications = res.data.Notifications
this.unreadCount = res.data.unreadCount
@ -121,7 +121,7 @@
},
resetUnreadCount () {
this.axios
.put('/api/v1/users/notification')
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification')
.then(() => {
this.unreadCount = 0
})
@ -131,7 +131,7 @@
let index = this.getIndexById(id)
this.axios
.delete('/api/v1/users/notification/' + id)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification/' + id)
.then(() => {
this.notifications.splice(index, 1)
})
@ -142,7 +142,7 @@
let item = this.notifications[index]
this.axios
.put('/api/v1/users/notification/' + id)
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/notification/' + id)
.then(() => {
this.$set(
this.notifications,

View File

@ -13,7 +13,7 @@
let id = this.$route.params.id
this.axios
.get('/api/v1/forums/post/' + id)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + id)
.then((res) => {
this.$router.push(
`/thread/${res.data.Thread.slug}/${res.data.Thread.id}/${res.data.postNumber}`

View File

@ -85,7 +85,7 @@
},
mounted () {
this.$store.dispatch('setTitle', 'Account Recovery')
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)

View File

@ -103,7 +103,7 @@
this.loadingUsers = true;
this.axios
.get('/api/v1/kaverti/search/user?q=' + this.$route.params.q)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/user?q=' + this.$route.params.q)
.then(res => {
this.loadingUsers = false;
this.users = res.data.users;
@ -114,7 +114,7 @@
this.loadingThreads = true;
this.axios
.get('/api/v1/kaverti/search/thread?q=' + this.$route.params.q)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'kaverti/search/thread?q=' + this.$route.params.q)
.then(res => {
this.loadingThreads = false;
this.threads = res.data.threads;

View File

@ -47,7 +47,7 @@
},
mounted () {
this.selected = this.getIndexFromRoute(this.$route.path)
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)

View File

@ -55,6 +55,32 @@
:loading='password.loading'
>Change password</b-button>
</div>
<div>
<h2>Change your username</h2>
<b>
Changing your username will cost 200 Koins!
</b>
<div>
<fancy-input
placeholder='Current password'
v-model='username.password'
:error='username.errors["password"]'
type='password'
></fancy-input>
</div>
<div>
<fancy-input
placeholder='New username'
v-model='username.username'
:error='username.errors["username"]'
></fancy-input>
</div>
<b-button
class='button is-success'
@click='saveUsername'
:loading='username.loading'
>Change username</b-button>
</div>
<div>
<br>
<h2>Change your email address</h2>
@ -152,8 +178,10 @@
}
},
username: {username: '',
password: '',
errors: {
'username': ''
'username': '',
'password': '',
},
loading: false,
},
@ -189,7 +217,7 @@
this.password.loading = true
this.axios
.put('/api/v1/user/' + this.$store.state.username, {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + this.$store.state.username, {
currentPassword: this.password.current,
newPassword: this.password.new
})
@ -229,7 +257,7 @@
this.email.loadingChange = true
this.axios
.put('/api/v1/user/' + this.$store.state.username, {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + this.$store.state.username, {
emailCurrentPassword: this.email.currentPassword,
newEmail: this.email.new
})
@ -237,7 +265,7 @@
this.email.currentPassword = ''
this.email.newEmail = ''
this.axios
.post('/api/v1/users/email-send')
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/email-send')
.then(() => {
this.email.loadingChange = false
AjaxErrorHandler("Success, your email has been changed, and a verification email has been sent to your new email: " + this.$store.state.email)
@ -246,7 +274,7 @@
this.email.loadingChange = false
AjaxErrorHandler(this.$store)(e)
})
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -276,21 +304,30 @@
this.username.loading = true
this.axios
.put('/api/v1/user/preferences', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/preferences', {
username: this.username.username,
password: this.username.password,
changeUsername: true
})
.then(() => {
this.username.username = ''
this.axios
this.username.loading = false
this.axios.get('/api/v1/userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
this.$store.commit('setEmailVerified', res.data.emailVerified)
this.$store.commit('setAdmin', res.data.admin)
})
this.axios.post(
process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' +
this.$store.state.username +
'/logout'
).then(res => {
this.loadingLogout = false
this.$store.commit('setUsername', '')
this.$store.commit('setAdmin', res.data.admin)
this.$socket.emit('accountEvent')
}).catch(err => {
this.loadingLogout = false
this.ajaxErrorHandler(err)
})
})
.catch(e => {
this.username.loading = false
@ -305,7 +342,7 @@
deleteAccount() {
this.deleteAccountLoading = true
this.axios
.put('/api/v1/users/delete', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/delete', {
password: this.deleteAcc.password
})
.then(() => {
@ -324,7 +361,7 @@
this.email.loading = true
this.axios
.post('/api/v1/users/email-send')
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/email-send')
.then(() => {
this.email.loading = false
})
@ -336,7 +373,7 @@
},
mounted () {
this.$store.dispatch('setTitle', 'Account Settings')
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)

View File

@ -74,12 +74,12 @@
this.experiments.loading = true
this.axios
.put('/api/v1/users/experiments', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/experiments', {
theme: this.experiments.theme
})
.then(() => {
this.experiments.loading = false
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -96,7 +96,7 @@
}
},
created () {
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -108,7 +108,7 @@
this.$nextTick(() => {
this.axios
.get('/api/v1/userinfo')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.experiments.theme = res.data.theme || ''
})

View File

@ -76,7 +76,7 @@
this.description.loading = true
this.axios
.put('/api/v1/users/preferences', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/preferences', {
description: this.description.value
})
.then(() => {
@ -92,12 +92,12 @@
this.preferences.loading = true
this.axios
.put('/api/v1/users/preferences', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/preferences', {
developerMode: this.preferences.developerMode
})
.then(() => {
this.preferences.loading = false
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -113,7 +113,7 @@
}
},
created () {
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -125,7 +125,7 @@
this.$nextTick(() => {
this.axios
.get('/api/v1/userinfo')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.description.value = res.data.description || ''
this.preferences.developerMode = res.data.developerMode

View File

@ -55,12 +55,12 @@ export default {
this.privacy.loading = true
this.axios
.put('/api/v1/users/preferences', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users/preferences', {
userWallOptOut: this.privacy.wall
})
.then(() => {
this.privacy.loading = false
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -77,7 +77,7 @@ export default {
}
},
created () {
this.axios.get('/api/v1/userinfo')
this.axios.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.$store.commit('setUsername', res.data.username)
this.$store.commit('setEmail', res.data.email)
@ -89,7 +89,7 @@ export default {
this.$nextTick(() => {
this.axios
.get('/api/v1/userinfo')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'userinfo')
.then(res => {
this.privacy.wall = res.data.userWallOptOut || ''
})

View File

@ -282,7 +282,7 @@
//Get the postNumber via api request
if(getPostNumber) {
this.axios
.get('/api/v1/forums/post/' + number)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + number)
.then( res => pushRoute(res.data.postNumber) )
} else {
pushRoute(number)

View File

@ -86,6 +86,13 @@
></input-editor-core>
</div>
</div>
<br>
<div class='editor__preview'>
<div class='editor__format_bar editor__format_bar--preview'>
<i class="fab fa-markdown"></i>
</div>
<input-editor-preview :value='editor' :mentions='mentions'></input-editor-preview>
</div>
<error-tooltip :error='errors.content' class='editor_error'></error-tooltip>
<b-button class='button--green submit' :loading='loading' @click='postThread'>Post thread</b-button>
@ -94,7 +101,8 @@
<script>
import InputEditorCore from '../InputEditorCore'
import FancyInput from '../FancyInput'
import InputEditorPreview from '../InputEditorPreview'
import FancyInput from '../FancyInput'
import SelectButton from '../SelectButton'
import ErrorTooltip from '../ErrorTooltip'
@ -105,6 +113,7 @@
name: 'ThreadNew',
components: {
InputEditorCore,
InputEditorPreview,
SelectButton,
FancyInput,
ErrorTooltip
@ -204,7 +213,7 @@
this.loading = true
this.axios.post('/api/v1/forums/thread', {
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread', {
name: this.name,
category: this.selectedCategory
}).then(res => {
@ -212,7 +221,7 @@
let ajax = []
ajax.push(
this.axios.post('/api/v1/forums/post', {
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post', {
threadId: res.data.id,
content: this.editor,
mentions: this.mentions
@ -221,7 +230,7 @@
if(this.showPoll) {
ajax.push(
this.axios.post('/api/v1/forums/poll', {
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/poll', {
question: this.pollQuestion,
answers: this.pollAnswers.map(a => a.answer),
threadId: res.data.id
@ -236,15 +245,7 @@
}).catch(e => {
this.loading = false
AjaxErrorHandler(this.$store)(e, (error, errors) => {
let path = error.path
if(this.errors[path] !== undefined) {
this.errors[path] = error.message
} else {
errors.push(error.message)
}
})
AjaxErrorHandler(this.$store)(e)
})
},
setFocusInput (val) {
@ -363,11 +364,9 @@
height: 2.5rem;
background-color: $color__gray--primary;
display: flex;
padding-right: 1rem;
padding-left: 1rem;
padding-bottom: 0.25rem;
justify-content: flex-end;
align-items: center;
font-variant: small-caps;
@at-root #{&}--preview {
border-radius: 0 0.25rem 0 0;

View File

@ -155,7 +155,7 @@
},
scrubDesc () {
this.axios
.put('/api/v1/admin/user/scrub', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/user/scrub', {
description: "descscram",
user: this.username
})
@ -166,7 +166,7 @@
},
scrubUsername () {
this.axios
.put('/api/v1/admin/user/scrub', {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'admin/user/scrub', {
username: "usernamescram",
user: this.username
})
@ -177,7 +177,7 @@
},
doRelationship () {
this.axios
.put('/api/v1/relationships/' + this.user.username, {
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'relationships/' + this.user.username, {
type: this.relationships.type
})
.then(() => {

View File

@ -139,7 +139,7 @@ export default {
},
getUserInfo () {
this.axios
.get('/api/v1/user/' + this.$route.params.username)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'user/' + this.$route.params.username)
.catch((e) => {
AjaxErrorHandler(this.$store)(e)
})

View File

@ -146,7 +146,7 @@ export default {
this.loadingNewer = true
this.axios
.get('/api/v1/users' + '?limit=' + this.newUsers)
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'users' + '?limit=' + this.newUsers)
.then(res => {
this.loadingNewer = false
this.newUsers = 0

View File

@ -125,7 +125,7 @@
window.addEventListener('resize', this.updateFuncs)
this.axios
.get('/api/v1/log/categories')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'log/categories')
.then(res => {
this.data = res.data
this.updateFuncs()

View File

@ -45,7 +45,7 @@
},
created () {
this.axios
.get('/api/v1/log/new-thread')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'log/new-thread')
.then(res => {
this.count = res.data.count
this.change = res.data.change

View File

@ -22,7 +22,7 @@
},
mounted () {
this.axios
.get('/api/v1/log/new-users')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'log/new-users')
.then(res => {
this.points = res.data.map(d => {
d.date = new Date(d.date)

View File

@ -22,7 +22,7 @@
},
mounted () {
this.axios
.get('/api/v1/log/page-views')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'log/page-views')
.then(res => {
this.points = res.data.map(d => {
d.date = new Date(d.date)

View File

@ -75,7 +75,7 @@
},
created () {
this.axios
.get('/api/v1/log/top-threads')
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'log/top-threads')
.then(res => {
this.data_ = res.data
this.loading = false

View File

@ -25,7 +25,7 @@ export default new Vuex.Store({
koins: '',
email: '',
emailVerified: true,
clientVersion: '0.174-stable',
clientVersion: '0.175-stable',
latestClientVersion: '',
developerMode: false,
theme: '',

View File

@ -40,7 +40,7 @@ const getters = {
const actions = {
deleteThread ({ state }, vue) {
vue.axios
.delete('/api/v1/forums/thread/' + state.threadId)
.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + state.threadId)
.then(() => {
vue.$router.push('/')
})
@ -49,7 +49,7 @@ const actions = {
removePostsAsync ({ state, commit }, vue) {
commit('setRemovePostsButtonLoading', true)
let promises = state.selectedPosts.map(id => vue.axios.delete('/api/v1/forums/post/' + id))
let promises = state.selectedPosts.map(id => vue.axios.delete(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post/' + id))
Promise.all(promises)
.then(() => {
@ -91,7 +91,7 @@ const actions = {
commit('setThreadEditorLoading', true)
vue.axios
.post('/api/v1/forums/post', post)
.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/post', post)
.then(res => {
commit('setThreadEditorLoading', false)
commit('addPost', res.data);
@ -116,7 +116,7 @@ const actions = {
dispatch('setTitle', 'Loading...')
let postNumber = vue.$route.params.post_number
let apiURL = '/api/v1/forums/thread/' + vue.$route.params.id
let apiURL = process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + vue.$route.params.id
if(postNumber !== undefined) {
apiURL += '?postNumber=' + postNumber
@ -201,7 +201,7 @@ const actions = {
loadNewPostsSinceLoad ({ state, commit }, post) {
if(state.nextPostsCount < 10) {
let nextURL = state.nextURL
let baseURL = '/api/v1/forums/thread/' + state.threadId + '?limit=10&from='
let baseURL = process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + state.threadId + '?limit=10&from='
commit('incrementNextPostsCount')
@ -212,7 +212,7 @@ const actions = {
},
setThreadLockedState ({ state, commit }, vue) {
vue.axios
.put('/api/v1/forums/thread/' + state.threadId, { locked: !state.locked })
.put(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'forums/thread/' + state.threadId, { locked: !state.locked })
.then(() => {
commit('setLocked', !state.locked)
})

View File

@ -1,7 +1,13 @@
const Dotenv = require('dotenv-webpack');
module.exports = {
devServer: {
proxy: 'http://localhost:23981'
},
publicPath: '/',
productionSourceMap: false
productionSourceMap: false,
configureWebpack: {
plugins: [
new Dotenv()
]
}
}

View File

@ -1183,7 +1183,7 @@
"@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-transform-typescript" "^7.10.4"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.0", "@babel/runtime@^7.11.2":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.3.1":
version "7.11.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
@ -1364,6 +1364,17 @@
cssnano-preset-default "^4.0.0"
postcss "^7.0.0"
"@kevinfaguiar/vue-twemoji-picker@^5.7.4":
version "5.7.4"
resolved "https://registry.yarnpkg.com/@kevinfaguiar/vue-twemoji-picker/-/vue-twemoji-picker-5.7.4.tgz#76dd0a2dc9cc350af0886eae985492c868b02e49"
integrity sha512-5E3hdAP7wFnY9DOEtQNEpW8uXKcw3ed3AjXQaJqpF/qwNgxwTRiJeqGhFZW1nKhEC5fRscpSm2JphKQENFMyEQ==
dependencies:
"@popperjs/core" "^2.4.0"
lodash.pick "^4.4.0"
twemoji "^13.0.0"
twitter-text "^3.1.0"
vue-clickaway "^2.2.2"
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://npm.open-registry.dev/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@ -1377,6 +1388,11 @@
resolved "https://npm.open-registry.dev/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@popperjs/core@^2.4.0":
version "2.5.3"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.5.3.tgz#4982b0b66b7a4cf949b86f5d25a8cf757d3cfd9d"
integrity sha512-RFwCobxsvZ6j7twS7dHIZQZituMIDJJNHS/qY6iuthVebxS3zhRY+jaC2roEKiAYaVuTcGmX6Luc6YBcf6zJVg==
"@saeris/vue-spinners@^1.0.8":
version "1.0.8"
resolved "https://registry.yarnpkg.com/@saeris/vue-spinners/-/vue-spinners-1.0.8.tgz#bc66975143ccfeeb60d38eb207729384804ee755"
@ -4210,11 +4226,25 @@ dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"
dotenv-defaults@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/dotenv-defaults/-/dotenv-defaults-2.0.1.tgz#ea6f9632b3b5cc55e48b736760def5561f1cb7c0"
integrity sha512-ugFCyBF7ILuwpmznduHPQZBMucHHJ8T4OBManTEVjemxCm2+nqifSuW2lD2SNKdiKSH1E324kZSdJ8M04b4I/A==
dependencies:
dotenv "^8.2.0"
dotenv-expand@^5.1.0:
version "5.1.0"
resolved "https://npm.open-registry.dev/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
dotenv-webpack@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-3.0.0.tgz#ff4af756f0f85c858d4d381a767b33e717b568ed"
integrity sha512-HsBTgVbh9E71IdC6QcQTnAuVt11niA5QMKblcBqhVBxP975XPGMqxf21pqgVBPyRKn2GqPh5kSHMgjxeR/HEAA==
dependencies:
dotenv-defaults "^2.0.1"
dotenv@^8.2.0:
version "8.2.0"
resolved "https://npm.open-registry.dev/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
@ -4286,6 +4316,13 @@ elliptic@^6.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.0"
emoji-mart-vue@^2.6.6:
version "2.6.6"
resolved "https://registry.yarnpkg.com/emoji-mart-vue/-/emoji-mart-vue-2.6.6.tgz#afd60da47ff0b59938b3d3cd90dacab6ab0f531e"
integrity sha512-844CI/Sa99G6goiZN6u+zT5XxB4wUhpYYTK8s3FrU2fl9y0ckbqe0uw7EuY0R53hb4bo9uJHVOPywE+C4vu4fg==
dependencies:
postcss-loader "^3.0.0"
emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://npm.open-registry.dev/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@ -4365,6 +4402,11 @@ entities@^2.0.0:
resolved "https://npm.open-registry.dev/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
entities@~2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
errno@^0.1.3, errno@~0.1.7:
version "0.1.7"
resolved "https://npm.open-registry.dev/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@ -4990,6 +5032,15 @@ fs-extra@^7.0.1:
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@^8.0.1:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://npm.open-registry.dev/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
@ -5230,7 +5281,7 @@ got@^8.0.3:
url-parse-lax "^3.0.0"
url-to-options "^1.0.1"
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2:
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2:
version "4.2.4"
resolved "https://npm.open-registry.dev/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
@ -6236,6 +6287,15 @@ jsonfile@^4.0.0:
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-5.0.0.tgz#e6b718f73da420d612823996fdf14a03f6ff6922"
integrity sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==
dependencies:
universalify "^0.1.2"
optionalDependencies:
graceful-fs "^4.1.6"
jsonpointer@^4.0.1:
version "4.1.0"
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.1.0.tgz#501fb89986a2389765ba09e6053299ceb4f2c2cc"
@ -6341,6 +6401,13 @@ lines-and-columns@^1.1.6:
resolved "https://npm.open-registry.dev/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
linkify-it@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8"
integrity sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ==
dependencies:
uc.micro "^1.0.1"
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://npm.open-registry.dev/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
@ -6434,6 +6501,11 @@ lodash.memoize@^4.1.2:
resolved "https://npm.open-registry.dev/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
lodash.pick@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
lodash.throttle@^4.1.1:
version "4.1.1"
resolved "https://npm.open-registry.dev/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
@ -6471,7 +6543,7 @@ loglevel@^1.6.6:
resolved "https://npm.open-registry.dev/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171"
integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==
loose-envify@^1.0.0:
loose-envify@^1.0.0, loose-envify@^1.2.0:
version "1.4.0"
resolved "https://npm.open-registry.dev/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@ -6555,6 +6627,22 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
markdown-it-emoji@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc"
integrity sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=
markdown-it@^11.0.1:
version "11.0.1"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-11.0.1.tgz#b54f15ec2a2193efa66dda1eb4173baea08993d6"
integrity sha512-aU1TzmBKcWNNYvH9pjq6u92BML+Hz3h5S/QpfTFwiQF852pLT+9qHsrhM9JYipkOXZxGn+sGH8oyJE9FD9WezQ==
dependencies:
argparse "^1.0.7"
entities "~2.0.0"
linkify-it "^3.0.1"
mdurl "^1.0.1"
uc.micro "^1.0.5"
marked@^0.8.2:
version "0.8.2"
resolved "https://npm.open-registry.dev/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355"
@ -6579,6 +6667,11 @@ mdn-data@2.0.6:
resolved "https://npm.open-registry.dev/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978"
integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==
mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
media-typer@0.3.0:
version "0.3.0"
resolved "https://npm.open-registry.dev/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@ -8155,7 +8248,7 @@ punycode@1.3.2:
resolved "https://npm.open-registry.dev/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
punycode@^1.2.4:
punycode@1.4.1, punycode@^1.2.4:
version "1.4.1"
resolved "https://npm.open-registry.dev/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
@ -9622,6 +9715,36 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
resolved "https://npm.open-registry.dev/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
twemoji-parser@13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.0.0.tgz#bd9d1b98474f1651dc174696b45cabefdfa405af"
integrity sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ==
twemoji-parser@^11.0.2:
version "11.0.2"
resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-11.0.2.tgz#24e87c2008abe8544c962f193b88b331de32b446"
integrity sha512-5kO2XCcpAql6zjdLwRwJjYvAZyDy3+Uj7v1ipBzLthQmDL7Ce19bEqHr3ImSNeoSW2OA8u02XmARbXHaNO8GhA==
twemoji@^13.0.0:
version "13.0.1"
resolved "https://registry.yarnpkg.com/twemoji/-/twemoji-13.0.1.tgz#57ddc8bd86c8175c11376f5f9ab322a02e739c2d"
integrity sha512-mrTBq+XpCLM4zm76NJOjLHoQNV9mHdBt3Cba/T5lS1rxn8ArwpqE47mqTocupNlkvcLxoeZJjYSUW0DU5ZwqZg==
dependencies:
fs-extra "^8.0.1"
jsonfile "^5.0.0"
twemoji-parser "13.0.0"
universalify "^0.1.2"
twitter-text@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/twitter-text/-/twitter-text-3.1.0.tgz#798e932b289f506efe2a1f03fe917ba30627f125"
integrity sha512-nulfUi3FN6z0LUjYipJid+eiwXvOLb8Ass7Jy/6zsXmZK3URte043m8fL3FyDzrK+WLpyqhHuR/TcARTN/iuGQ==
dependencies:
"@babel/runtime" "^7.3.1"
core-js "^2.5.0"
punycode "1.4.1"
twemoji-parser "^11.0.2"
type-check@~0.3.2:
version "0.3.2"
resolved "https://npm.open-registry.dev/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
@ -9657,6 +9780,11 @@ typedarray@^0.0.6:
resolved "https://npm.open-registry.dev/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
uglify-js@3.4.x:
version "3.4.10"
resolved "https://npm.open-registry.dev/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
@ -9727,7 +9855,7 @@ unique-slug@^2.0.0:
dependencies:
imurmurhash "^0.1.4"
universalify@^0.1.0:
universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://npm.open-registry.dev/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
@ -9937,6 +10065,13 @@ vue-cli-plugin-sitemap@^2.2.0:
better-ajv-errors "^0.6.7"
chalk "^4.1.0"
vue-clickaway@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/vue-clickaway/-/vue-clickaway-2.2.2.tgz#cecf6839575e8b2afc5d3edb3efb616d293dbb44"
integrity sha512-25SpjXKetL06GLYoLoC8pqAV6Cur9cQ//2g35GRFBV4FgoljbZZjTINR8g2NuVXXDMLSUXaKx5dutgO4PaDE7A==
dependencies:
loose-envify "^1.2.0"
vue-eslint-parser@^7.0.0:
version "7.0.0"
resolved "https://npm.open-registry.dev/vue-eslint-parser/-/vue-eslint-parser-7.0.0.tgz#a4ed2669f87179dedd06afdd8736acbb3a3864d6"

View File

@ -24,6 +24,12 @@ var md = require('../kaverti_modules/markdown-it')({
highlight: function (/*str, lang*/) { return ''; }
});
md.disable('image')
var emoji = require('markdown-it-emoji');
var twemoji = require('twemoji')
md.use(emoji);
md.renderer.rules.emoji = function(token, idx) {
return twemoji.parse(token[idx].content);
};
let createDOMPurify = require('dompurify');
let { JSDOM } = require('jsdom');
var marked = require('marked')

View File

@ -19,11 +19,11 @@ module.exports = (sequelize, DataTypes) => {
allowNull: false,
validate: {
notEmpty: {
msg: 'Did you forget something? (Fill this in!)'
msg: 'Did you forget something?'
},
len: {
args: [4, 256],
msg: 'The title must be between 4 and 256 characters'
args: [4, 50],
msg: 'The title must be between 4 and 50 characters'
},
isString (val) {
if(typeof val !== 'string') {

View File

@ -10,7 +10,7 @@ module.exports = (sequelize, DataTypes) => {
username: {
type: DataTypes.STRING(191),
unique: {
msg: 'Username has already been taken, try another',
msg: 'Username is already taken, try another!',
fields: ['username']
},
validate: {
@ -316,11 +316,20 @@ module.exports = (sequelize, DataTypes) => {
throw Errors.invalidLoginCredentials
}
},
async updateUsername (username) {
async updateUsername (username, password) {
if(typeof username !== 'string') {
throw new sequelize.ValidationError('input must be a string')
throw new sequelize.ValidationError('Please enter your new username')
}
if(typeof password !== 'string') {
throw new sequelize.ValidationError('Please enter your password')
}
let correctPassword = await bcrypt.compare(password, this.hash)
if(correctPassword) {
await this.update({username: username, koins: this.koins - 200})
} else {
throw Errors.invalidLoginCredentials
}
await this.update({ username: username, koins: this.koins - 200})
},
async comparePassword (password) {
return await bcrypt.compare(password, this.hash)

View File

@ -1,4 +1,35 @@
let marked = require('marked');
var md = require('../kaverti_modules/markdown-it')({
html: false, // Enable HTML tags in source
xhtmlOut: false, // Use '/' to close single tags (<br />).
// This is only for full CommonMark compatibility.
breaks: true, // Convert '\n' in paragraphs into <br>
langPrefix: 'language-', // CSS language prefix for fenced blocks. Can be
// useful for external highlighters.
linkify: true, // Autoconvert URL-like text to links
image: false,
// Enable some language-neutral replacement + quotes beautification
typographer: true,
// Double + single quotes replacement pairs, when typographer enabled,
// and smartquotes on. Could be either a String or an Array.
//
// For example, you can use '«»„“' for Russian, '„“‚‘' for German,
// and ['«\xA0', '\xA0»', '\xA0', '\xA0'] for French (including nbsp).
quotes: '“”‘’',
// Highlighter function. Should return escaped HTML,
// or '' if the source string is not changed and should be escaped externally.
// If result starts with <pre... internal wrapper is skipped.
highlight: function (/*str, lang*/) { return ''; }
});
md.disable('image')
var emoji = require('markdown-it-emoji');
var twemoji = require('twemoji')
md.use(emoji);
md.renderer.rules.emoji = function(token, idx) {
return twemoji.parse(token[idx].content);
};
let createDOMPurify = require('dompurify');
let { JSDOM } = require('jsdom');
@ -8,25 +39,6 @@ var escaped_str = require('querystring')
const Errors = require('../lib/errors')
let pagination = require('../lib/pagination.js')
marked.setOptions({
highlight: function (code) {
return require('highlight.js').highlightAuto(code).value;
}
});
const renderer = new marked.Renderer();
renderer.link = function (href, title, text) {
if (!href.match(/[a-z]+:\/\/.+/i)) {
href = 'http://' + href;
}
return `
<a href='/out/?uri=${href}' ${title ? "title='" + title + "'" : ""} target='_blank' rel='noopener'>
${text}
</a>
`;
}
module.exports = (sequelize, DataTypes) => {
let userWall = sequelize.define('userWall', {
@ -40,7 +52,7 @@ module.exports = (sequelize, DataTypes) => {
})
}
let rawHTML = marked(val, { renderer });
let rawHTML = md.render(val);
let cleanHTML = DOMPurify.sanitize(rawHTML);
let plainText = (new JSDOM(cleanHTML)).window.document.body.textContent;

View File

@ -18,7 +18,7 @@
"@sendgrid/mail": "^7.2.5",
"axios": "^0.19.0",
"bcryptjs": "^2.4.3",
"body-parser": "^1.16.0",
"body-parser": "^1.19.0",
"compression": "^1.7.3",
"connect-multiparty": "^2.2.0",
"connect-session-sequelize": "^5.1.0",
@ -37,10 +37,12 @@
"helmet": "^3.23.3",
"highlight.js": "^9.18.3",
"jsdom": "^16.3.0",
"jsonwebtoken": "^8.5.1",
"lodash.debounce": "^4.0.8",
"mailgen": "^2.0.13",
"mailgun-js": "^0.22.0",
"markdown-it": "^11.0.1",
"markdown-it-emoji": "^1.4.0",
"markdown-it-link-attributes": "^3.0.0",
"marked": "^0.8.2",
"moment": "^2.28.0",
@ -49,6 +51,7 @@
"mysql2": "^1.7.0",
"node-email-verification": "^0.0.0",
"passport": "^0.4.1",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"passport-local-sequelize": "^0.9.0",
"postgres": "^1.0.2",
@ -65,6 +68,7 @@
"socket.io": "^2.1.1",
"swagger-jsdoc": "^4.0.0",
"swagger-ui-express": "^4.1.4",
"twemoji": "^13.0.1",
"url-slug": "^2.0.0"
},
"devDependencies": {

View File

@ -93,7 +93,8 @@ router.put('/user/modify', async (req, res, next) => {
booster: req.body.booster,
bot: req.body.bot,
system: req.body.system,
admin: req.body.admin
admin: req.body.admin,
hidden: req.body.hidden
}, {
where: {
username: req.body.username
@ -105,7 +106,8 @@ router.put('/user/modify', async (req, res, next) => {
let userUpdate = await User.update({
booster: req.body.booster,
bot: req.body.bot,
system: req.body.system
system: req.body.system,
hidden: req.body.hidden
}, {
where: {
username: req.body.username

View File

@ -102,7 +102,7 @@ router.post('/', postLimiter, async (req, res, next) => {
req.body.replyingToId, thread
)
post = await Post.create({ content: req.autosan.body.content, postNumber: thread.postsCount })
post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
await post.setReplyingTo(replyingToPost)
await replyingToPost.addReplies(post)
@ -118,7 +118,7 @@ router.post('/', postLimiter, async (req, res, next) => {
req.app.get('io')
)
} else {
post = await Post.create({ content: req.autosan.body.content, postNumber: thread.postsCount })
post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
}
await post.setUser(user)

View File

@ -61,7 +61,7 @@ router.post('/', postLimiter, async (req, res, next) => {
let thread = await Thread.create({
name: req.autosan.body.name
name: req.body.name
})
await thread.setCategory(category)

View File

@ -377,7 +377,12 @@ router.put('/:username', async (req, res, next) => {
await user.updateEmail(req.body.emailCurrentPassword, req.body.newEmail)
res.json({ success: true })
} else if(
req.body.username !== undefined &&
req.body.changeUsername === true
) {
console.log("yes")
res.json({ success: true })
} else {
res.json({ success: false })
}

View File

@ -81,7 +81,7 @@ router.post('/post', postLimiter, async (req, res, next) => {
fromUserId: sessionId.id
}})
post = await userWall.create({content: req.autosan.body.content, postNumber: "0", userId: getWallUser.id, fromUserId: req.session.UserId})
post = await userWall.create({content: req.body.content, postNumber: "0", userId: getWallUser.id, fromUserId: req.session.UserId})
if (uniqueMentions.length) {
let ioUsers = req.app.get('io-users')

View File

@ -499,14 +499,15 @@ router.put('/preferences', async (req, res, next) => {
res.json({ success: true })
} else if(
req.body.username !== undefined &&
req.body.changeUsername !== undefined
req.body.changeUsername !== undefined &&
req.body.password !== undefined
) {
let user = await User.findOne({where: {
username: req.session.username
}})
if(user.koins >= 200) {
await user.updateUsername(req.body.username)
await user.updateUsername(req.body.username, req.body.password)
} else {
throw Errors.insufficientKoins
}

118
yarn.lock
View File

@ -455,7 +455,7 @@ bluebird@^3.3.4, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
body-parser@1.19.0, body-parser@^1.16.0:
body-parser@1.19.0:
version "1.19.0"
resolved "https://npm.open-registry.dev/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
@ -471,6 +471,22 @@ body-parser@1.19.0, body-parser@^1.16.0:
raw-body "2.4.0"
type-is "~1.6.17"
body-parser@^1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
dependencies:
bytes "3.1.0"
content-type "~1.0.4"
debug "2.6.9"
depd "~1.1.2"
http-errors "1.7.2"
iconv-lite "0.4.24"
on-finished "~2.3.0"
qs "6.7.0"
raw-body "2.4.0"
type-is "~1.6.17"
boolbase@~1.0.0:
version "1.0.0"
resolved "https://npm.open-registry.dev/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
@ -1828,6 +1844,15 @@ fs-extra@^5.0.0:
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@^8.0.1:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
@ -1937,7 +1962,7 @@ glob@7.1.6, glob@^7.0.3, glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.4"
resolved "https://npm.open-registry.dev/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
@ -2496,6 +2521,15 @@ jsonfile@^4.0.0:
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-5.0.0.tgz#e6b718f73da420d612823996fdf14a03f6ff6922"
integrity sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==
dependencies:
universalify "^0.1.2"
optionalDependencies:
graceful-fs "^4.1.6"
jsonschema-draft4@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsonschema-draft4/-/jsonschema-draft4-1.0.0.tgz#f0af2005054f0f0ade7ea2118614b69dc512d865"
@ -2517,6 +2551,22 @@ jsonwebtoken@^7.2.1:
ms "^2.0.0"
xtend "^4.0.1"
jsonwebtoken@^8.2.0, jsonwebtoken@^8.5.1:
version "8.5.1"
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
dependencies:
jws "^3.2.2"
lodash.includes "^4.3.0"
lodash.isboolean "^3.0.3"
lodash.isinteger "^4.0.4"
lodash.isnumber "^3.0.3"
lodash.isplainobject "^4.0.6"
lodash.isstring "^4.0.1"
lodash.once "^4.0.0"
ms "^2.1.1"
semver "^5.6.0"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://npm.open-registry.dev/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -2549,7 +2599,7 @@ jwa@^1.4.1:
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
jws@^3.1.4:
jws@^3.1.4, jws@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
@ -2671,11 +2721,41 @@ lodash.get@4.4.2, lodash.get@^4.0.0, lodash.get@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
lodash.isboolean@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
lodash.isequal@^4.0.0, lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
lodash.isinteger@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
lodash.isnumber@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
lodash.isstring@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.map@^4.4.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
@ -2794,6 +2874,11 @@ mailparser@^0.6.1:
mimelib "^0.3.0"
uue "^3.1.0"
markdown-it-emoji@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc"
integrity sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=
markdown-it-link-attributes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/markdown-it-link-attributes/-/markdown-it-link-attributes-3.0.0.tgz#12d6f403102ac22695ee2617bec109ee79426e45"
@ -3516,6 +3601,14 @@ parseurl@~1.3.3:
resolved "https://npm.open-registry.dev/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
passport-jwt@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065"
integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==
dependencies:
jsonwebtoken "^8.2.0"
passport-strategy "^1.0.0"
passport-local-sequelize@^0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/passport-local-sequelize/-/passport-local-sequelize-0.9.0.tgz#36b6c24b643b26074e7bb72e2e2b12cbc3eebc24"
@ -3532,7 +3625,7 @@ passport-local@^1.0.0, passport-local@~1.0.0:
dependencies:
passport-strategy "1.x.x"
passport-strategy@1.x.x:
passport-strategy@1.x.x, passport-strategy@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"
integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=
@ -4744,6 +4837,21 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
resolved "https://npm.open-registry.dev/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
twemoji-parser@13.0.0:
version "13.0.0"
resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.0.0.tgz#bd9d1b98474f1651dc174696b45cabefdfa405af"
integrity sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ==
twemoji@^13.0.1:
version "13.0.1"
resolved "https://registry.yarnpkg.com/twemoji/-/twemoji-13.0.1.tgz#57ddc8bd86c8175c11376f5f9ab322a02e739c2d"
integrity sha512-mrTBq+XpCLM4zm76NJOjLHoQNV9mHdBt3Cba/T5lS1rxn8ArwpqE47mqTocupNlkvcLxoeZJjYSUW0DU5ZwqZg==
dependencies:
fs-extra "^8.0.1"
jsonfile "^5.0.0"
twemoji-parser "13.0.0"
universalify "^0.1.2"
type-check@~0.3.2:
version "0.3.2"
resolved "https://npm.open-registry.dev/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
@ -4823,7 +4931,7 @@ unidecode@^0.1.8:
resolved "https://npm.open-registry.dev/unidecode/-/unidecode-0.1.8.tgz#efbb301538bc45246a9ac8c559d72f015305053e"
integrity sha1-77swFTi8RSRqmsjFWdcvAVMFBT4=
universalify@^0.1.0:
universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://npm.open-registry.dev/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==