* Added some basic table styles for inserting some shitty tables * Made popup notification styles look better and work better on mobile * Quick note now opens a note and not some weird page * Menu collapses when page is small, behaves like mobile menu * Added terms and conditions to help and login forms * Added password change functionality * Better styles for shared page * Added some tests for changing password
257 lines
6.8 KiB
Vue
257 lines
6.8 KiB
Vue
<template>
|
|
<div class="ui grid">
|
|
<div class="row"></div>
|
|
<!-- spacer column -->
|
|
<div class="sixteen wide column">
|
|
<h2 class="ui dividing header">
|
|
<i class="cog icon"></i>
|
|
Settings
|
|
</h2>
|
|
|
|
<div class="ui segment">
|
|
<h3>Change Password</h3>
|
|
<p>Create a new scratch pad. Old scratch pad will turn into a normal note.</p>
|
|
<div class="ui compact basic button shrinking" v-if="!showNewNoteConfirm" v-on:click="showNewNoteConfirm = true">
|
|
<i class="sync alternate reload icon"></i>
|
|
New Scratch Pad
|
|
</div>
|
|
<div v-if="showNewNoteConfirm" class="ui compact basic button shrinking" v-on:click="showNewNoteConfirm = false">
|
|
<i class="close icon"></i>
|
|
Cancel
|
|
</div>
|
|
<div v-if="showNewNoteConfirm" class="ui compact basic button shrinking" v-on:click="newQuickNote()">
|
|
<i class="green thumbs up icon"></i>
|
|
Confirm
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Accent Color -->
|
|
<div class="ui segment">
|
|
<div class="ui grid">
|
|
<div class="sixteen wide column">
|
|
<h3 class="ui header">
|
|
Accent Color
|
|
</h3>
|
|
<div
|
|
v-for="color in themeColors"
|
|
class="ui compact basic button"
|
|
:style="`background: linear-gradient(0deg, ${color} 4%, rgba(0,0,0,0) 5%);`"
|
|
v-on:click="setAccentColor(color)">
|
|
<logo style="width: 33px; height: auto;" :color="color" />
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Enable Two Factor -->
|
|
<div class="ui segment">
|
|
<h3>Two Factor Authentication</h3>
|
|
<div class="ui stackable grid">
|
|
<div class="four wide column">
|
|
<p>1. Enter Password and get QR</p>
|
|
<div class="ui fluid action input">
|
|
<input type="password" placeholder="Current Password" v-model="password">
|
|
|
|
<div v-if="password.length == 0" class="ui disabled button">
|
|
Get QR code
|
|
</div>
|
|
<div v-if="password.length > 0" class="ui green button" v-on:click="getQrCode()">
|
|
Get QR code
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="five wide column">
|
|
<p>2. Scan QR Code</p>
|
|
<p v-if="qrCode == ''">QR Code Will appear here.</p>
|
|
<img v-if="qrCode != ''" :src="qrCode" alt="QR Code">
|
|
</div>
|
|
<div class="four wide column">
|
|
<p>3. Verify with code</p>
|
|
<div class="ui input" v-if="qrCode != ''">
|
|
<input type="text" placeholder="Verification Code" v-model="verificationToken" v-on:keyup.enter="verifyQrCode()">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- change password -->
|
|
<div class="ui segment">
|
|
<h3>Change Password</h3>
|
|
<div class="ui grid">
|
|
<div class="five wide column">
|
|
<label>Current Password</label>
|
|
<div class="ui fluid input">
|
|
<input v-model="change1" type="password" placeholder="Current Password">
|
|
</div>
|
|
</div>
|
|
<div class="five wide column">
|
|
<label>New Password</label>
|
|
<div class="ui fluid input">
|
|
<input v-model="change2" type="password" placeholder="New Password">
|
|
</div>
|
|
</div>
|
|
<div class="six wide column">
|
|
<label>Rereat New Password</label>
|
|
<div class="ui fluid action input">
|
|
<input v-model="change3" type="password" placeholder="Repeat Password">
|
|
<div v-on:click="passwordChange()" class="ui button" :class="{'green':(change1.length > 0 && change2 == change3)}">
|
|
Change it!
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- log out -->
|
|
<div class="ui segment">
|
|
<div class="ui grid">
|
|
<div class="sixteen wide column">
|
|
<h3>Log Out</h3>
|
|
</div>
|
|
<div class="eight wide column">
|
|
<div class="ui button" v-on:click="logout()">
|
|
Log Out this browser
|
|
</div>
|
|
</div>
|
|
<div class="eight wide column">
|
|
<div class="ui button" v-on:click="revokeAllSessions()">
|
|
Log Out all other browsers
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
import axios from 'axios'
|
|
|
|
export default {
|
|
name: 'SettingsPage',
|
|
components: {
|
|
'logo':require('@/components/LogoComponent.vue').default,
|
|
},
|
|
data () {
|
|
return {
|
|
password: '',
|
|
qrCode: '',
|
|
verificationToken: '',
|
|
showNewNoteConfirm: false,
|
|
|
|
themeColors: [
|
|
'#21BA45', //Green
|
|
'#b5cc18', //Lime
|
|
'#00b5ad', //Teal
|
|
'#2185d0', //Blue
|
|
'#7128b9', //Violet
|
|
'#a333c8', // "Purple"
|
|
'#e03997', //Pink
|
|
'#db2828', //Red
|
|
'#f2711c', //Orange
|
|
'#fbbd08', //Yellow
|
|
'#767676', //Grey
|
|
'#303030', //Black-almost
|
|
],
|
|
|
|
change1: '',
|
|
change2: '',
|
|
change3: '',
|
|
}
|
|
},
|
|
methods: {
|
|
newQuickNote(){
|
|
|
|
this.showNewNoteConfirm = true
|
|
|
|
axios.post('/api/quick-note/new')
|
|
.then( ({data}) => {
|
|
this.showNewNoteConfirm = false
|
|
this.$store.dispatch('fetchAndUpdateUserTotals')
|
|
this.$bus.$emit('notification', 'New Scratch Pad Created')
|
|
})
|
|
|
|
},
|
|
logout() {
|
|
this.$store.commit('destroyLoginToken')
|
|
this.$router.push('/')
|
|
axios.post('/api/user/logout')
|
|
setTimeout(() => {
|
|
this.$bus.$emit('notification', 'Logged Out')
|
|
}, 200)
|
|
},
|
|
setAccentColor(color){
|
|
|
|
let root = document.documentElement
|
|
root.style.setProperty('--main-accent', color)
|
|
localStorage.setItem('main-accent', color)
|
|
|
|
if(!color || color == '#21BA45'){
|
|
localStorage.removeItem('main-accent')
|
|
}
|
|
},
|
|
getQrCode(){
|
|
|
|
axios.post('/api/user/twofactorsetup', { password:this.password })
|
|
.then(({data}) => {
|
|
this.qrCode = data
|
|
})
|
|
},
|
|
verifyQrCode(){
|
|
|
|
axios.post('/api/user/verifytwofactorsetuptoken', { password:this.password, token: this.verificationToken })
|
|
.then(({data}) => {
|
|
if(data == true){
|
|
//Two FA is set up
|
|
} else {
|
|
//It failed
|
|
}
|
|
})
|
|
},
|
|
passwordChange(){
|
|
|
|
if(this.change1 == '' || this.change2 == '' || this.change3 == ''){
|
|
this.$bus.$emit('notification', 'All Password Fields Required')
|
|
return
|
|
}
|
|
|
|
if(this.change1 == this.change2){
|
|
this.$bus.$emit('notification', 'Old password matches new password')
|
|
return
|
|
}
|
|
|
|
if(this.change2 != this.change3){
|
|
this.$bus.$emit('notification', 'New Passwords do not match')
|
|
return
|
|
}
|
|
|
|
const postData = {
|
|
'currentPass':this.change1,
|
|
'newPass':this.change3
|
|
}
|
|
|
|
axios.post('/api/user/changepassword', postData)
|
|
.then(({data}) => {
|
|
if(data){
|
|
this.$bus.$emit('notification', 'Success: Password Changed')
|
|
this.change1 = ''
|
|
this.change2 = ''
|
|
this.change3 = ''
|
|
} else {
|
|
this.$bus.$emit('notification', 'Failed to change password')
|
|
this.change1 = ''
|
|
}
|
|
})
|
|
},
|
|
revokeAllSessions(){
|
|
axios.post('/api/user/revokesessions')
|
|
.then(({data}) => {
|
|
this.$bus.$emit('notification', 'All other active sessions revoked.')
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script> |