forked from kaverti/website
Fix things
This commit is contained in:
parent
6991709666
commit
0cf9f72d3f
|
@ -1,5 +1,10 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"useBuiltIns": "entry"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v5.14.0/js/fontawesome.js">
|
||||
<title>Kaverti</title>
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es2015%2Ces2016%2Ces2018%2Ces2019%2Ces2017%2Ces6%2Ces5%2Ces7%2Cdefault%2CIntl%2Cblissfuljs"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
"buefy": "^0.8.20",
|
||||
"child_process": "^1.0.2",
|
||||
"core-js": "^3.6.4",
|
||||
"corejs": "^1.0.0",
|
||||
"d3": "^4.9.1",
|
||||
"es6-promise": "^4.2.8",
|
||||
"fs": "0.0.1-security",
|
||||
"highlight.js": "^9.10.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
|
@ -38,7 +40,6 @@
|
|||
"sass-loader": "^8.0.2",
|
||||
"socket.io-client": "^2.1.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-analytics": "^5.22.1",
|
||||
"vue-axios": "^2.0.2",
|
||||
"vue-matomo": "^3.14.0-0",
|
||||
"vue-router": "^2.7.0",
|
||||
|
@ -48,10 +49,18 @@
|
|||
"vuex": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
||||
"@babel/plugin-proposal-decorators": "^7.6.0",
|
||||
"@babel/plugin-transform-runtime": "^7.6.2",
|
||||
"@babel/preset-env": "^7.11.5",
|
||||
"@babel/preset-typescript": "^7.6.0",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@vue/cli-plugin-babel": "^4.5.2",
|
||||
"@vue/cli-plugin-eslint": "~4.3.0",
|
||||
"@vue/cli-service": "~4.3.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"vue-cli-plugin-sitemap": "^2.2.0",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<title>Kaverti</title>
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es2015%2Ces2016%2Ces2018%2Ces2019%2Ces2017%2Ces6%2Ces5%2Ces7%2Cdefault%2CIntl%2Cblissfuljs"></script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
|
|
@ -38,18 +38,21 @@
|
|||
<template>
|
||||
<div id='app'>
|
||||
<main>
|
||||
<modal-window v-model='showAjaxErrorsModal' style='z-index: 100' width='25rem' :no-padding='true'>
|
||||
<modal-window v-model='showAjaxErrorsModal' style='z-index: 100' width='25rem' :no-padding='true' :is-error="true">
|
||||
<div slot="header">
|
||||
Oh uh!
|
||||
</div>
|
||||
<div slot='main'>
|
||||
<p :key='error' v-for='error in this.$store.state.ajaxErrors' style='margin: 1rem;'>{{error}}</p>
|
||||
</div>
|
||||
<button
|
||||
slot='footer'
|
||||
class='button button--modal'
|
||||
style='z-index: 100' width='25rem'
|
||||
class='button is-info'
|
||||
style='z-index: 100; width: 100%;'
|
||||
@click='showAjaxErrorsModal = false'
|
||||
ref='ajaxErrorsModalButton'
|
||||
>
|
||||
OK
|
||||
Okay
|
||||
</button>
|
||||
</modal-window>
|
||||
<b-modal :can-cancel="false" :active="connModal" @update:active="value => connModal = value" v-model="connModal" full-screen>
|
||||
|
@ -68,9 +71,10 @@
|
|||
@input='closeAccountModal'
|
||||
:no-padding='true'
|
||||
:hide-footer='true'
|
||||
:hide-header="true"
|
||||
>
|
||||
<tab-view
|
||||
:tabs='["Register", "Login"]'
|
||||
:tabs='["Register", "Login", "Recovery"]'
|
||||
v-model="showAccountTab"
|
||||
padding='true'
|
||||
slot='main'
|
||||
|
@ -190,6 +194,35 @@
|
|||
</div>
|
||||
</form>
|
||||
</template>
|
||||
<template slot='Recovery'>
|
||||
<p style='margin-top: 0;'>
|
||||
{{name}} Account Recovery
|
||||
</p>
|
||||
<form @submit.prevent='doRecovery'>
|
||||
<fancy-input
|
||||
v-model='recovery.email'
|
||||
:error='recovery.errors.email'
|
||||
placeholder='Email'
|
||||
width='100%'
|
||||
>
|
||||
</fancy-input>
|
||||
|
||||
<div style='margin-top: 0.5rem;'>
|
||||
<b-button
|
||||
class='is-info'
|
||||
style="width: 55%"
|
||||
:loading='recovery.loading'
|
||||
@click='doRecovery'
|
||||
>
|
||||
Send email
|
||||
</b-button>
|
||||
|
||||
<b-button style="float: right" class="is-danger-passive" @click='closeAccountModal'>
|
||||
Cancel
|
||||
</b-button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
</tab-view>
|
||||
</modal-window>
|
||||
<template>
|
||||
|
@ -371,6 +404,15 @@
|
|||
hash: ''
|
||||
}
|
||||
},
|
||||
recovery: {
|
||||
email: '',
|
||||
|
||||
loading: false,
|
||||
|
||||
errors: {
|
||||
email: ''
|
||||
}
|
||||
},
|
||||
loadingLogout: false,
|
||||
showMenu: false,
|
||||
connModal: true,
|
||||
|
@ -454,8 +496,6 @@
|
|||
this.$store.commit('setAdmin', res.data.admin)
|
||||
|
||||
this.$socket.emit('accountEvent')
|
||||
|
||||
this.$router.push('/')
|
||||
}).catch(err => {
|
||||
this.loadingLogout = false
|
||||
this.ajaxErrorHandler(err)
|
||||
|
@ -487,6 +527,15 @@
|
|||
this.signup.errors.email = ''
|
||||
this.signup.errors.passkey = ''
|
||||
},
|
||||
clearRecovery () {
|
||||
this.recovery.email = ''
|
||||
|
||||
this.$store.commit('setToken', null)
|
||||
this.$store.commit('setPassKey', null)
|
||||
},
|
||||
clearRecoveryErrors () {
|
||||
this.recovery.errors.email = ''
|
||||
},
|
||||
pollConn() {
|
||||
this.polling = setInterval(() => {
|
||||
this.retryConnection()
|
||||
|
@ -663,6 +712,54 @@
|
|||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
doRecovery () {
|
||||
this.clearRecoveryErrors()
|
||||
|
||||
if(!this.recovery.email.trim().length) {
|
||||
this.recovery.errors.email = 'Email must not be blank'
|
||||
return
|
||||
}
|
||||
|
||||
this.recovery.loading = true
|
||||
|
||||
this.axios.post(`/api/v1/users/recovery`, {
|
||||
email: this.recovery.email
|
||||
}).then(res => {
|
||||
this.recovery.loading = false
|
||||
this.$store.commit('setUsername', res.data.username)
|
||||
this.$store.commit('setAdmin', res.data.admin)
|
||||
this.closeAccountModal()
|
||||
|
||||
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.$store.commit('setKoins', res.data.koins)
|
||||
this.closeConn()
|
||||
}).catch(err => {
|
||||
this.showConn()
|
||||
this.pollConn()
|
||||
if(err.response.data.errors[0].name === 'noSettings') {
|
||||
this.showConn()
|
||||
this.pollConn()
|
||||
} else {
|
||||
this.showConn()
|
||||
this.pollConn()
|
||||
}
|
||||
})
|
||||
}).catch(e => {
|
||||
this.recovery.loading = false
|
||||
this.ajaxErrorHandler(e, (error) => {
|
||||
let path = error.path
|
||||
|
||||
if(this.recovery.errors[path] !== undefined && this.recovery.errors[path] !== undefined) {
|
||||
this.recovery.errors[path] = error.message
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
|
|
@ -3,7 +3,7 @@ module.exports = function(vuex) {
|
|||
let errors = []
|
||||
|
||||
if(res.response === undefined || res.response.data.errors === undefined) {
|
||||
errors.push('Oh uh! An unknown network connection problem occurred, Please contact a Kaverti staff member for assistance. (SERV_FAIL)')
|
||||
errors.push('Something went wrong connecting to the Kaverti service, maybe try again later.')
|
||||
} else {
|
||||
res.response.data.errors.forEach(error => {
|
||||
let path = error.path
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<modal-window class='b-dialog' :class='{"modal_window--show": value}' @click.self='closeModal'>
|
||||
<div class='modal_window dialog' :class='{"modal_window--show": value}' :style='{"width": width || "20rem"}'>
|
||||
<div
|
||||
class='modal_window__loading_overlay'
|
||||
:class='{
|
||||
"modal_window__loading_overlay--show": loading
|
||||
}'
|
||||
>
|
||||
<loading-icon></loading-icon>
|
||||
</div>
|
||||
|
||||
<span
|
||||
class='modal_window__close'
|
||||
@click='closeModal'
|
||||
v-if='closeButton'
|
||||
>
|
||||
<font-awesome-icon :icon='["fa", "times"]' />
|
||||
</span>
|
||||
<div class='modal_window__main' :class='{ "modal_window__main--no_padding": noPadding }'>
|
||||
<slot name='main'></slot>
|
||||
</div>
|
||||
<div class='modal_window__footer' v-if='!hideFooter'>
|
||||
<slot name='footer'></slot>
|
||||
</div>
|
||||
</div>
|
||||
</modal-window>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LoadingIcon from './LoadingIcon'
|
||||
|
||||
export default {
|
||||
name: 'ModalWindow',
|
||||
props: ['value', 'width', 'close-button', 'hide-footer', 'no-padding', 'loading', 'is-error'],
|
||||
components: { LoadingIcon },
|
||||
methods: {
|
||||
closeModal () {
|
||||
this.$emit('input', false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
@import '../assets/scss/variables.scss';
|
||||
|
||||
.modal_window__overlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
z-index: 3;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s;
|
||||
|
||||
@at-root #{&}--show {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
}
|
||||
.modal_window {
|
||||
box-shadow: 0 14px 28px rgba(0,0,0,0.15), 0 10px 10px rgba(0,0,0,0.10);
|
||||
background-color: #fff;
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
border-radius: 0.25rem;
|
||||
pointer-events: none;
|
||||
transform: scale(1.1);
|
||||
|
||||
transition: margin-top 0.3s, opacity 0.3s, transform 0.3s;
|
||||
|
||||
@at-root #{&}__loading_overlay {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 5;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
|
||||
transition: all 0.2s;
|
||||
|
||||
@at-root #{&}--show {
|
||||
pointer-events: all;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@at-root #{&}__main {
|
||||
padding: 0 1rem 1rem 1rem;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
@at-root #{&}--no_padding {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@at-root #{&}__footer {
|
||||
background-color: $color__lightgray--darkest;
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 0.35rem 1rem;
|
||||
}
|
||||
|
||||
@at-root #{&}__close {
|
||||
position: absolute;
|
||||
right: 0.7rem;
|
||||
top: 0.5rem;
|
||||
transition: color 0.2s;
|
||||
cursor: pointer;
|
||||
color: $color__gray--darkest;
|
||||
|
||||
&:hover {
|
||||
color: $color__darkgray--primary;
|
||||
}
|
||||
}
|
||||
|
||||
@at-root #{&}--show {
|
||||
margin-top: 0;
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
|
||||
transition: all 0.3s;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class='modal_window__overlay' :class='{"modal_window--show": value}' @click.self='closeModal'>
|
||||
<div class='modal_window' :class='{"modal_window--show": value}' :style='{"width": width || "20rem"}'>
|
||||
<div class='modal_window dialog' :class='{"modal_window--show": value}' :style='{"width": width || "20rem"}'>
|
||||
<div
|
||||
class='modal_window__loading_overlay'
|
||||
:class='{
|
||||
|
@ -17,12 +17,21 @@
|
|||
>
|
||||
<font-awesome-icon :icon='["fa", "times"]' />
|
||||
</span>
|
||||
<div class='modal_window__main' :class='{ "modal_window__main--no_padding": noPadding }'>
|
||||
<slot name='main'></slot>
|
||||
</div>
|
||||
<div class='modal_window__footer' v-if='!hideFooter'>
|
||||
<slot name='footer'></slot>
|
||||
</div>
|
||||
<header class="modal-card-head" v-if='!hideHeader'>
|
||||
<p class="modal-card-title">
|
||||
<slot name='header'></slot>
|
||||
</p>
|
||||
</header>
|
||||
<section>
|
||||
<div class="media">
|
||||
<div class="media-content">
|
||||
<slot name="main"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="modal-card-foot" v-if='!hideFooter'>
|
||||
<slot name='footer'></slot>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,7 +41,7 @@
|
|||
|
||||
export default {
|
||||
name: 'ModalWindow',
|
||||
props: ['value', 'width', 'close-button', 'hide-footer', 'no-padding', 'loading'],
|
||||
props: ['value', 'width', 'close-button', 'hide-footer', 'no-padding', 'loading', 'hide-header', 'is-error'],
|
||||
components: { LoadingIcon },
|
||||
methods: {
|
||||
closeModal () {
|
||||
|
@ -138,4 +147,4 @@
|
|||
transition: all 0.3s;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
if(text.length) {
|
||||
this.quoteY = coords.top - rootCoords.top - 30;
|
||||
this.quoteX = coords.left - rootCoords.left;
|
||||
this.quoteSelection = '~ ' + text.replace(/\n/g, '\n~ ') + '\n\n';
|
||||
this.quoteSelection = '> ' + text.replace(/\n/g, '\n> ') + '\n\n';
|
||||
this.showQuote = true;
|
||||
} else {
|
||||
this.showQuote = false;
|
||||
|
|
|
@ -149,7 +149,7 @@ export default {
|
|||
if(text.length) {
|
||||
this.quoteY = coords.top - rootCoords.top - 30;
|
||||
this.quoteX = coords.left - rootCoords.left;
|
||||
this.quoteSelection = '~ ' + text.replace(/\n/g, '\n~ ') + '\n\n';
|
||||
this.quoteSelection = '> ' + text.replace(/\n/g, '\n> ') + '\n\n';
|
||||
this.showQuote = true;
|
||||
} else {
|
||||
this.showQuote = false;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
:class='{ "admin__menu__item--selected" : route.route.includes(selected) }'
|
||||
@click='$router.push("/admin/" + route.route)'
|
||||
>
|
||||
<b-dialog>Not mobile optimized</b-dialog>
|
||||
<div>
|
||||
<i :class='["fas", "fa-",route.icon]' class='admin__menu__item__icon' />
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<section class="hero is-info is-fullheight-with-navbar">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<div class="box" v-if="!$store.state.emailVerified">
|
||||
<div class="box" v-if="!$store.state.emailVerified && $store.state.username">
|
||||
<article class="media">
|
||||
<div class="media-content">
|
||||
<center>
|
||||
|
@ -16,7 +16,20 @@
|
|||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<div class="box" v-if="$store.state.emailVerified">
|
||||
<div class="box" v-if="!$store.state.username">
|
||||
<article class="media">
|
||||
<div class="media-content">
|
||||
<center>
|
||||
<i class="fas fa-envelope-open" style="color:#0a8bff; font-size: 30px;"></i>
|
||||
<div class="content">
|
||||
<h1>You need to be logged in to perform this action.</h1>
|
||||
<p>Please login, and try again.</p>
|
||||
</div>
|
||||
</center>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<div class="box" v-if="$store.state.emailVerified && $store.state.username">
|
||||
<article class="media">
|
||||
<div class="media-content">
|
||||
<center>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<center>
|
||||
<div class="column is-9">
|
||||
<h1>Privacy Policy</h1>
|
||||
<h2>Last updated on the 16th of August 2020</h2>
|
||||
<h2>Last updated on the 1st of October 2020</h2>
|
||||
<p>Welcome to Kaverti, Kaverti is a platform that allows users to socialize and customize their avatars.</p>
|
||||
<h2>Stored user information:</h2>
|
||||
<p>Kaverti needs to store some user information for our platform to work, and for the best experience imaginable. So what does it store?</p>
|
||||
|
@ -20,7 +20,7 @@
|
|||
<b>
|
||||
<table>
|
||||
<ol>
|
||||
<li><b>Koins</b> - Koins are our virtual currency, this allows users to purchase items from the marketplace, Koins can be purchased individually as one time purchases, or obtained daily, your daily Koins will increase if you buy the Premium monthly subscription which can be cancelled at any time. Your Koin count is available for everyone to see on your profile, this may be removed in the future.</li>
|
||||
<li><b>Koins</b> - Koins are our virtual currency, this allows users to purchase items from the marketplace, Koins can be purchased individually as one time purchases, or obtained daily, your daily Koins will increase if you buy the Premium monthly subscription which can be cancelled at any time.</li>
|
||||
<li><b>Post and thread count</b> - Kaverti keeps track of how many posts and threads you've made, and can be publicly viewable.</li>
|
||||
<li><b>Join date</b> - Kaverti keeps a record on when you've created your account, and can be viewed on your profile or user list.</li>
|
||||
<li><b>Updated date</b> - Kaverti keeps a record on when you've updated your post, account or Marketplace item.</li>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<b>
|
||||
<table>
|
||||
<ol>
|
||||
<li>However, we do use the Google Analytics service for keeping track on visit and website analytics, to see if we're growing or not, if you have an AdBlocker on your router, or browser, usually it blocks Google Analytics, which is perfectly fine, we do not force anyone to disable such programs to get the same experience as other people without an ad blocking program.</li>
|
||||
<li>However, we do use Analytics software ("Matomo self-hosted") for keeping track on visit and website analytics, to see if we're growing or not, if you have an AdBlocker on your router, or browser, it will generally block this software, which we allow, we do not force anyone to disable such programs to get the same experience as other people without an ad blocking program, this data does not get accessed by anyone other then Kaverti, as the data is hosted on the Australian Kaverti servers for privacy reasons.</li>
|
||||
</ol>
|
||||
</table>
|
||||
</b>
|
||||
|
|
|
@ -25,11 +25,8 @@
|
|||
<span v-else-if='notification.type === "reply"'>Post reply</span>
|
||||
<span>
|
||||
<span class='notification_button__menu__item__header__date'>{{notification.createdAt | formatDate }}</span>
|
||||
</span> <span
|
||||
@click.stop='deleteNotification(notification.id)'
|
||||
>×</span>
|
||||
</span>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<span v-if='isYouOrDeleted(notification.PostNotification.User)'>
|
||||
{{ notification.PostNotification.User ? 'You' : '[deleted]' }}
|
||||
|
@ -41,6 +38,9 @@
|
|||
wrote
|
||||
"{{notification.PostNotification.Post.content | stripTags | truncate(50)}}"
|
||||
</div>
|
||||
<b-button
|
||||
@click.stop='deleteNotification(notification.id)'
|
||||
>Close</b-button>
|
||||
|
||||
</div>
|
||||
<div v-if='!notifications.length'>
|
||||
|
@ -302,16 +302,6 @@
|
|||
background-color: $color__lightgray--primary;
|
||||
}
|
||||
|
||||
|
||||
@at-root #{&}--uninteracted {
|
||||
background-color: rgba(13, 71, 161, 0.1);
|
||||
border-bottom-color: $color__gray--darkest;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(13, 71, 161, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@at-root #{&}__link {
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'babel-polyfill'
|
||||
import NProgress from 'nprogress'
|
||||
import io from 'socket.io-client'
|
||||
import "core-js/stable";
|
||||
|
||||
window.onload = () => {
|
||||
let div = document.createElement('div');
|
||||
|
|
|
@ -25,7 +25,7 @@ export default new Vuex.Store({
|
|||
koins: '',
|
||||
email: '',
|
||||
emailVerified: '',
|
||||
clientVersion: '0.159-stable',
|
||||
clientVersion: '0.162-stable',
|
||||
latestClientVersion: '',
|
||||
|
||||
token: null,
|
||||
|
|
|
@ -75,6 +75,28 @@
|
|||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/core@^7.11.6":
|
||||
version "7.11.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651"
|
||||
integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.11.6"
|
||||
"@babel/helper-module-transforms" "^7.11.0"
|
||||
"@babel/helpers" "^7.10.4"
|
||||
"@babel/parser" "^7.11.5"
|
||||
"@babel/template" "^7.10.4"
|
||||
"@babel/traverse" "^7.11.5"
|
||||
"@babel/types" "^7.11.5"
|
||||
convert-source-map "^1.7.0"
|
||||
debug "^4.1.0"
|
||||
gensync "^1.0.0-beta.1"
|
||||
json5 "^2.1.2"
|
||||
lodash "^4.17.19"
|
||||
resolve "^1.3.2"
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.11.0":
|
||||
version "7.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c"
|
||||
|
@ -84,6 +106,15 @@
|
|||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.11.5", "@babel/generator@^7.11.6":
|
||||
version "7.11.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620"
|
||||
integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.11.5"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.9.6":
|
||||
version "7.9.6"
|
||||
resolved "https://npm.open-registry.dev/@babel/generator/-/generator-7.9.6.tgz#5408c82ac5de98cda0d77d8124e99fa1f2170a43"
|
||||
|
@ -427,6 +458,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9"
|
||||
integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==
|
||||
|
||||
"@babel/parser@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037"
|
||||
integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==
|
||||
|
||||
"@babel/parser@^7.7.0", "@babel/parser@^7.8.6", "@babel/parser@^7.9.6":
|
||||
version "7.9.6"
|
||||
resolved "https://npm.open-registry.dev/@babel/parser/-/parser-7.9.6.tgz#3b1bbb30dabe600cd72db58720998376ff653bc7"
|
||||
|
@ -441,7 +477,7 @@
|
|||
"@babel/helper-remap-async-to-generator" "^7.10.4"
|
||||
"@babel/plugin-syntax-async-generators" "^7.8.0"
|
||||
|
||||
"@babel/plugin-proposal-class-properties@^7.10.4":
|
||||
"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.5.5":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807"
|
||||
integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==
|
||||
|
@ -457,6 +493,15 @@
|
|||
"@babel/helper-create-class-features-plugin" "^7.8.3"
|
||||
"@babel/helper-plugin-utils" "^7.8.3"
|
||||
|
||||
"@babel/plugin-proposal-decorators@^7.6.0":
|
||||
version "7.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz#42898bba478bc4b1ae242a703a953a7ad350ffb4"
|
||||
integrity sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ==
|
||||
dependencies:
|
||||
"@babel/helper-create-class-features-plugin" "^7.10.5"
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
"@babel/plugin-syntax-decorators" "^7.10.4"
|
||||
|
||||
"@babel/plugin-proposal-decorators@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://npm.open-registry.dev/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz#2156860ab65c5abf068c3f67042184041066543e"
|
||||
|
@ -578,6 +623,13 @@
|
|||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
|
||||
"@babel/plugin-syntax-decorators@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz#6853085b2c429f9d322d02f5a635018cdeb2360c"
|
||||
integrity sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
|
||||
"@babel/plugin-syntax-decorators@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://npm.open-registry.dev/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz#8d2c15a9f1af624b0025f961682a9d53d3001bda"
|
||||
|
@ -892,6 +944,16 @@
|
|||
resolve "^1.8.1"
|
||||
semver "^5.5.1"
|
||||
|
||||
"@babel/plugin-transform-runtime@^7.6.2":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.5.tgz#f108bc8e0cf33c37da031c097d1df470b3a293fc"
|
||||
integrity sha512-9aIoee+EhjySZ6vY5hnLjigHzunBlscx9ANKutkeWTJTx6m5Rbq6Ic01tLvO54lSusR+BxV7u4UDdCmXv5aagg==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.10.4"
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
resolve "^1.8.1"
|
||||
semver "^5.5.1"
|
||||
|
||||
"@babel/plugin-transform-shorthand-properties@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6"
|
||||
|
@ -1028,6 +1090,80 @@
|
|||
levenary "^1.1.1"
|
||||
semver "^5.5.0"
|
||||
|
||||
"@babel/preset-env@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272"
|
||||
integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==
|
||||
dependencies:
|
||||
"@babel/compat-data" "^7.11.0"
|
||||
"@babel/helper-compilation-targets" "^7.10.4"
|
||||
"@babel/helper-module-imports" "^7.10.4"
|
||||
"@babel/helper-plugin-utils" "^7.10.4"
|
||||
"@babel/plugin-proposal-async-generator-functions" "^7.10.4"
|
||||
"@babel/plugin-proposal-class-properties" "^7.10.4"
|
||||
"@babel/plugin-proposal-dynamic-import" "^7.10.4"
|
||||
"@babel/plugin-proposal-export-namespace-from" "^7.10.4"
|
||||
"@babel/plugin-proposal-json-strings" "^7.10.4"
|
||||
"@babel/plugin-proposal-logical-assignment-operators" "^7.11.0"
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4"
|
||||
"@babel/plugin-proposal-numeric-separator" "^7.10.4"
|
||||
"@babel/plugin-proposal-object-rest-spread" "^7.11.0"
|
||||
"@babel/plugin-proposal-optional-catch-binding" "^7.10.4"
|
||||
"@babel/plugin-proposal-optional-chaining" "^7.11.0"
|
||||
"@babel/plugin-proposal-private-methods" "^7.10.4"
|
||||
"@babel/plugin-proposal-unicode-property-regex" "^7.10.4"
|
||||
"@babel/plugin-syntax-async-generators" "^7.8.0"
|
||||
"@babel/plugin-syntax-class-properties" "^7.10.4"
|
||||
"@babel/plugin-syntax-dynamic-import" "^7.8.0"
|
||||
"@babel/plugin-syntax-export-namespace-from" "^7.8.3"
|
||||
"@babel/plugin-syntax-json-strings" "^7.8.0"
|
||||
"@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
|
||||
"@babel/plugin-syntax-numeric-separator" "^7.10.4"
|
||||
"@babel/plugin-syntax-object-rest-spread" "^7.8.0"
|
||||
"@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
|
||||
"@babel/plugin-syntax-optional-chaining" "^7.8.0"
|
||||
"@babel/plugin-syntax-top-level-await" "^7.10.4"
|
||||
"@babel/plugin-transform-arrow-functions" "^7.10.4"
|
||||
"@babel/plugin-transform-async-to-generator" "^7.10.4"
|
||||
"@babel/plugin-transform-block-scoped-functions" "^7.10.4"
|
||||
"@babel/plugin-transform-block-scoping" "^7.10.4"
|
||||
"@babel/plugin-transform-classes" "^7.10.4"
|
||||
"@babel/plugin-transform-computed-properties" "^7.10.4"
|
||||
"@babel/plugin-transform-destructuring" "^7.10.4"
|
||||
"@babel/plugin-transform-dotall-regex" "^7.10.4"
|
||||
"@babel/plugin-transform-duplicate-keys" "^7.10.4"
|
||||
"@babel/plugin-transform-exponentiation-operator" "^7.10.4"
|
||||
"@babel/plugin-transform-for-of" "^7.10.4"
|
||||
"@babel/plugin-transform-function-name" "^7.10.4"
|
||||
"@babel/plugin-transform-literals" "^7.10.4"
|
||||
"@babel/plugin-transform-member-expression-literals" "^7.10.4"
|
||||
"@babel/plugin-transform-modules-amd" "^7.10.4"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.10.4"
|
||||
"@babel/plugin-transform-modules-systemjs" "^7.10.4"
|
||||
"@babel/plugin-transform-modules-umd" "^7.10.4"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4"
|
||||
"@babel/plugin-transform-new-target" "^7.10.4"
|
||||
"@babel/plugin-transform-object-super" "^7.10.4"
|
||||
"@babel/plugin-transform-parameters" "^7.10.4"
|
||||
"@babel/plugin-transform-property-literals" "^7.10.4"
|
||||
"@babel/plugin-transform-regenerator" "^7.10.4"
|
||||
"@babel/plugin-transform-reserved-words" "^7.10.4"
|
||||
"@babel/plugin-transform-shorthand-properties" "^7.10.4"
|
||||
"@babel/plugin-transform-spread" "^7.11.0"
|
||||
"@babel/plugin-transform-sticky-regex" "^7.10.4"
|
||||
"@babel/plugin-transform-template-literals" "^7.10.4"
|
||||
"@babel/plugin-transform-typeof-symbol" "^7.10.4"
|
||||
"@babel/plugin-transform-unicode-escapes" "^7.10.4"
|
||||
"@babel/plugin-transform-unicode-regex" "^7.10.4"
|
||||
"@babel/preset-modules" "^0.1.3"
|
||||
"@babel/types" "^7.11.5"
|
||||
browserslist "^4.12.0"
|
||||
core-js-compat "^3.6.2"
|
||||
invariant "^2.2.2"
|
||||
levenary "^1.1.1"
|
||||
semver "^5.5.0"
|
||||
|
||||
"@babel/preset-modules@^0.1.3":
|
||||
version "0.1.3"
|
||||
resolved "https://npm.open-registry.dev/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72"
|
||||
|
@ -1047,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.0.0", "@babel/runtime@^7.11.0", "@babel/runtime@^7.11.2":
|
||||
version "7.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
|
||||
integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
|
||||
|
@ -1094,6 +1230,21 @@
|
|||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/traverse@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3"
|
||||
integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.11.5"
|
||||
"@babel/helper-function-name" "^7.10.4"
|
||||
"@babel/helper-split-export-declaration" "^7.11.0"
|
||||
"@babel/parser" "^7.11.5"
|
||||
"@babel/types" "^7.11.5"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/traverse@^7.7.0", "@babel/traverse@^7.9.6":
|
||||
version "7.9.6"
|
||||
resolved "https://npm.open-registry.dev/@babel/traverse/-/traverse-7.9.6.tgz#5540d7577697bf619cc57b92aa0f1c231a94f442"
|
||||
|
@ -1118,6 +1269,15 @@
|
|||
lodash "^4.17.19"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
|
||||
integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.10.4"
|
||||
lodash "^4.17.19"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.5", "@babel/types@^7.9.6":
|
||||
version "7.9.6"
|
||||
resolved "https://npm.open-registry.dev/@babel/types/-/types-7.9.6.tgz#2c5502b427251e9de1bd2dff95add646d95cc9f7"
|
||||
|
@ -2113,7 +2273,7 @@ babel-eslint@^10.1.0:
|
|||
eslint-visitor-keys "^1.0.0"
|
||||
resolve "^1.12.0"
|
||||
|
||||
babel-loader@^8.1.0:
|
||||
babel-loader@^8.0.6, babel-loader@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://npm.open-registry.dev/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3"
|
||||
integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==
|
||||
|
@ -3122,6 +3282,11 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
|
|||
resolved "https://npm.open-registry.dev/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
corejs@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/corejs/-/corejs-1.0.0.tgz#6d19351be6bb85ec96c60fd69c9ce087ad3f0d66"
|
||||
integrity sha1-bRk1G+a7heyWxg/WnJzgh60/DWY=
|
||||
|
||||
cosmiconfig@^5.0.0:
|
||||
version "5.2.1"
|
||||
resolved "https://npm.open-registry.dev/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
|
||||
|
@ -4212,6 +4377,11 @@ es-to-primitive@^1.2.1:
|
|||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
es6-promise@^4.2.8:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
escalade@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
|
||||
|
@ -9710,11 +9880,6 @@ vm-browserify@^1.0.1:
|
|||
resolved "https://npm.open-registry.dev/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
vue-analytics@^5.22.1:
|
||||
version "5.22.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-analytics/-/vue-analytics-5.22.1.tgz#9d6b32da56daee1b9dfb23a267b50349a03f710f"
|
||||
integrity sha512-HPKQMN7gfcUqS5SxoO0VxqLRRSPkG1H1FqglsHccz6BatBatNtm/Vyy8brApktZxNCfnAkrSVDpxg3/FNDeOgQ==
|
||||
|
||||
vue-axios@^2.0.2:
|
||||
version "2.1.5"
|
||||
resolved "https://npm.open-registry.dev/vue-axios/-/vue-axios-2.1.5.tgz#1af4bf1218ed71309c76afb38d0f683e312c24a7"
|
||||
|
|
|
@ -47,7 +47,7 @@ let Errors = {
|
|||
401
|
||||
],
|
||||
requestNotAuthorized: [
|
||||
'You do not have sufficient permissions to do that action.',
|
||||
'You aren\'t logged in, or you don\'t have permissions to perform this action.',
|
||||
401
|
||||
],
|
||||
verifyEmail: [
|
||||
|
|
191
routes/user.js
191
routes/user.js
|
@ -31,89 +31,7 @@ function setUserSession(req, res, username, UserId, admin) {
|
|||
|
||||
if(admin) { req.session.admin = true }
|
||||
}
|
||||
router.post('/email-send', emailLimiter, async (req, res, next) => {
|
||||
const mailGenerator = new MailGen({
|
||||
theme: 'salted',
|
||||
product: {
|
||||
name: 'Kaverti',
|
||||
link: 'https://kaverti.com'
|
||||
},
|
||||
})
|
||||
let queryObj = {
|
||||
attributes: {include: ['email', 'emailVerified', 'emailToken', 'username']},
|
||||
where: {username: req.session.username}
|
||||
}
|
||||
let user = await User.findOne(queryObj)
|
||||
await user.rand()
|
||||
const verifyEmail = {
|
||||
body: {
|
||||
name: user.username,
|
||||
intro: 'Welcome to Kaverti',
|
||||
action: {
|
||||
instructions: 'Please verify your account via the button below',
|
||||
button: {
|
||||
color: '#33b5e5',
|
||||
text: 'Verify account',
|
||||
link: 'https://kaverti.com/verify/?token=' + user.emailToken,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const emailTemplate = mailGenerator.generate(verifyEmail)
|
||||
const message = {
|
||||
to: user.email,
|
||||
from: 'automailer@kaverti.com',
|
||||
subject: 'Kaverti account verification',
|
||||
html: emailTemplate
|
||||
}
|
||||
|
||||
const sendMail = async () => {
|
||||
try {
|
||||
sgMail.setApiKey("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")
|
||||
return sgMail.send(message)
|
||||
} catch (error) {
|
||||
throw new Error(error.message)
|
||||
}
|
||||
}
|
||||
try {
|
||||
if(user.emailVerified) {
|
||||
throw Errors.alreadyVerified
|
||||
} else {
|
||||
const sent = await sendMail()
|
||||
if (sent) {
|
||||
res.send({ message: 'Email has been sent, check your spam if you can\'t find it!' })
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error.message)
|
||||
}
|
||||
});
|
||||
router.get('/email-verify/:token', async (req, res) => {
|
||||
try {
|
||||
let queryObj = {
|
||||
attributes: {include: ['emailToken', 'emailVerified']},
|
||||
where: { username: req.session.username }
|
||||
}
|
||||
let user = await User.findOne(queryObj)
|
||||
if (user.emailToken == req.params.token) {
|
||||
user.emailVerify()
|
||||
res.status(200)
|
||||
res.json({
|
||||
success: "true"
|
||||
})
|
||||
} else {
|
||||
res.status(400)
|
||||
res.json({
|
||||
errors: [Errors.invalidParameter('token', 'Invalid token')]
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(400)
|
||||
res.json({
|
||||
errors: [Errors.invalidParameter('token', 'Invalid token')]
|
||||
})
|
||||
}
|
||||
});
|
||||
router.post('/oidfhuisadhi8243', emailLimiter, async (req, res) => {
|
||||
try {
|
||||
await Ban.isIpBanned(req.ip)
|
||||
|
@ -326,61 +244,6 @@ router.get('/:username/picture', async (req, res, next) => {
|
|||
}
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
router.all('*', (req, res, next) => {
|
||||
if(req.session.username) {
|
||||
next()
|
||||
} else {
|
||||
res.status(401)
|
||||
res.json({
|
||||
errors: [Errors.requestNotAuthorized]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
router.put('/:username', async (req, res, next) => {
|
||||
try {
|
||||
if(req.session.username !== req.params.username) {
|
||||
throw Errors.requestNotAuthorized
|
||||
}
|
||||
await Ban.ReadOnlyMode(req.session.username)
|
||||
|
||||
if(req.autosan.body.description !== undefined) {
|
||||
let user = await User.update({ description: req.autosan.body.description }, { where: {
|
||||
username: req.session.username
|
||||
}})
|
||||
|
||||
res.json({ success: true })
|
||||
|
||||
} else if(
|
||||
req.body.currentPassword !== undefined &&
|
||||
req.body.newPassword !== undefined
|
||||
) {
|
||||
let user = await User.findOne({
|
||||
where: {
|
||||
username: req.session.username
|
||||
}
|
||||
})
|
||||
|
||||
await user.updatePassword(req.body.currentPassword, req.body.newPassword)
|
||||
res.json({success: true})
|
||||
} else if(
|
||||
req.body.emailCurrentPassword !== undefined &&
|
||||
req.body.newEmail !== undefined
|
||||
) {
|
||||
let user = await User.findOne({where: {
|
||||
username: req.session.username
|
||||
}})
|
||||
|
||||
await user.updateEmail(req.body.emailCurrentPassword, req.body.newEmail)
|
||||
res.json({ success: true })
|
||||
|
||||
} else {
|
||||
res.json({ success: false })
|
||||
}
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
router.get('/', async function(req, res) {
|
||||
try {
|
||||
let sortFields = {
|
||||
|
@ -441,4 +304,58 @@ router.get('/', async function(req, res) {
|
|||
}
|
||||
})
|
||||
|
||||
router.all('*', (req, res, next) => {
|
||||
if(req.session.username) {
|
||||
next()
|
||||
} else {
|
||||
res.status(401)
|
||||
res.json({
|
||||
errors: [Errors.requestNotAuthorized]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
router.put('/:username', async (req, res, next) => {
|
||||
try {
|
||||
if(req.session.username !== req.params.username) {
|
||||
throw Errors.requestNotAuthorized
|
||||
}
|
||||
await Ban.ReadOnlyMode(req.session.username)
|
||||
|
||||
if(req.autosan.body.description !== undefined) {
|
||||
let user = await User.update({ description: req.autosan.body.description }, { where: {
|
||||
username: req.session.username
|
||||
}})
|
||||
|
||||
res.json({ success: true })
|
||||
|
||||
} else if(
|
||||
req.body.currentPassword !== undefined &&
|
||||
req.body.newPassword !== undefined
|
||||
) {
|
||||
let user = await User.findOne({
|
||||
where: {
|
||||
username: req.session.username
|
||||
}
|
||||
})
|
||||
|
||||
await user.updatePassword(req.body.currentPassword, req.body.newPassword)
|
||||
res.json({success: true})
|
||||
} else if(
|
||||
req.body.emailCurrentPassword !== undefined &&
|
||||
req.body.newEmail !== undefined
|
||||
) {
|
||||
let user = await User.findOne({where: {
|
||||
username: req.session.username
|
||||
}})
|
||||
|
||||
await user.updateEmail(req.body.emailCurrentPassword, req.body.newEmail)
|
||||
res.json({ success: true })
|
||||
|
||||
} else {
|
||||
res.json({ success: false })
|
||||
}
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -31,89 +31,7 @@ function setUserSession(req, res, username, UserId, admin) {
|
|||
|
||||
if(admin) { req.session.admin = true }
|
||||
}
|
||||
router.post('/email-send', emailLimiter, async (req, res, next) => {
|
||||
const mailGenerator = new MailGen({
|
||||
theme: 'salted',
|
||||
product: {
|
||||
name: 'Kaverti',
|
||||
link: 'https://kaverti.com'
|
||||
},
|
||||
})
|
||||
let queryObj = {
|
||||
attributes: {include: ['email', 'emailVerified', 'emailToken', 'username']},
|
||||
where: {username: req.session.username}
|
||||
}
|
||||
let user = await User.findOne(queryObj)
|
||||
await user.rand()
|
||||
const verifyEmail = {
|
||||
body: {
|
||||
name: user.username,
|
||||
intro: 'Welcome to Kaverti',
|
||||
action: {
|
||||
instructions: 'Please verify your account via the button below',
|
||||
button: {
|
||||
color: '#33b5e5',
|
||||
text: 'Verify account',
|
||||
link: 'https://kaverti.com/verify/?token=' + user.emailToken,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const emailTemplate = mailGenerator.generate(verifyEmail)
|
||||
const message = {
|
||||
to: user.email,
|
||||
from: 'automailer@kaverti.com',
|
||||
subject: 'Kaverti account verification',
|
||||
html: emailTemplate
|
||||
}
|
||||
|
||||
const sendMail = async () => {
|
||||
try {
|
||||
sgMail.setApiKey("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")
|
||||
return sgMail.send(message)
|
||||
} catch (error) {
|
||||
throw new Error(error.message)
|
||||
}
|
||||
}
|
||||
try {
|
||||
if(user.emailVerified) {
|
||||
throw Errors.alreadyVerified
|
||||
} else {
|
||||
const sent = await sendMail()
|
||||
if (sent) {
|
||||
res.send({ message: 'Email has been sent, check your spam if you can\'t find it!' })
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error.message)
|
||||
}
|
||||
});
|
||||
router.get('/email-verify/:token', async (req, res) => {
|
||||
try {
|
||||
let queryObj = {
|
||||
attributes: {include: ['emailToken', 'emailVerified']},
|
||||
where: { username: req.session.username }
|
||||
}
|
||||
let user = await User.findOne(queryObj)
|
||||
if (user.emailToken == req.params.token) {
|
||||
user.emailVerify()
|
||||
res.status(200)
|
||||
res.json({
|
||||
success: "true"
|
||||
})
|
||||
} else {
|
||||
res.status(400)
|
||||
res.json({
|
||||
errors: [Errors.invalidParameter('token', 'Invalid token')]
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(400)
|
||||
res.json({
|
||||
errors: [Errors.invalidParameter('token', 'Invalid token')]
|
||||
})
|
||||
}
|
||||
});
|
||||
router.post('/oidfhuisadhi8243', async (req, res) => {
|
||||
try {
|
||||
await Ban.isIpBanned(req.ip)
|
||||
|
@ -343,4 +261,88 @@ router.get('/', async function(req, res) {
|
|||
}
|
||||
})
|
||||
|
||||
router.post('/email-send', emailLimiter, async (req, res, next) => {
|
||||
const mailGenerator = new MailGen({
|
||||
theme: 'salted',
|
||||
product: {
|
||||
name: 'Kaverti',
|
||||
link: 'https://kaverti.com'
|
||||
},
|
||||
})
|
||||
let queryObj = {
|
||||
attributes: {include: ['email', 'emailVerified', 'emailToken', 'username']},
|
||||
where: {username: req.session.username}
|
||||
}
|
||||
let user = await User.findOne(queryObj)
|
||||
await user.rand()
|
||||
const verifyEmail = {
|
||||
body: {
|
||||
name: user.username,
|
||||
intro: 'Welcome to Kaverti',
|
||||
action: {
|
||||
instructions: 'Please verify your account via the button below',
|
||||
button: {
|
||||
color: '#33b5e5',
|
||||
text: 'Verify account',
|
||||
link: 'https://kaverti.com/verify/?token=' + user.emailToken,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
const emailTemplate = mailGenerator.generate(verifyEmail)
|
||||
const message = {
|
||||
to: user.email,
|
||||
from: 'automailer@kaverti.com',
|
||||
subject: 'Kaverti account verification',
|
||||
html: emailTemplate
|
||||
}
|
||||
|
||||
const sendMail = async () => {
|
||||
try {
|
||||
sgMail.setApiKey("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")
|
||||
return sgMail.send(message)
|
||||
} catch (error) {
|
||||
throw new Error(error.message)
|
||||
}
|
||||
}
|
||||
try {
|
||||
if(user.emailVerified) {
|
||||
throw Errors.alreadyVerified
|
||||
} else {
|
||||
const sent = await sendMail()
|
||||
if (sent) {
|
||||
res.send({ message: 'Email has been sent, check your spam if you can\'t find it!' })
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(error.message)
|
||||
}
|
||||
});
|
||||
router.get('/email-verify/:token', async (req, res) => {
|
||||
try {
|
||||
let queryObj = {
|
||||
attributes: {include: ['emailToken', 'emailVerified']},
|
||||
where: { username: req.session.username }
|
||||
}
|
||||
let user = await User.findOne(queryObj)
|
||||
if (user.emailToken == req.params.token) {
|
||||
user.emailVerify()
|
||||
res.status(200)
|
||||
res.json({
|
||||
success: "true"
|
||||
})
|
||||
} else {
|
||||
res.status(400)
|
||||
res.json({
|
||||
errors: [Errors.invalidParameter('token', 'Invalid token')]
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(400)
|
||||
res.json({
|
||||
errors: [Errors.invalidParameter('token', 'Invalid token')]
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
|
Loading…
Reference in New Issue