* Force logout of user with authorization error * Wrong site blocker doesn't trigger on the solid scribe domain * Added log out button to main side bar making it easier to find * Improved icon set for notes * Colored notes display better on mobile, fixed text color based on color brightness * Moved terms of use link to the bottom of a few pages * Updated feature sections on home page, make them clearer and easier to process * Tweaked color themes * Deleted links no longer show up in search * Updated search to use multiple key words * Updated tests to do a multi word search * Tweaked a bunch of styles to look better on chrome and browsers
283 lines
7.5 KiB
Vue
283 lines
7.5 KiB
Vue
<template>
|
|
<div class="squire-box">
|
|
<div>
|
|
|
|
<h3 class="ui dividing header">
|
|
<i class="inline green cog icon"></i>
|
|
Settings for {{ $store.getters.getUsername }}
|
|
</h3>
|
|
|
|
<h4>New Scratch Pad</h4>
|
|
<div class="ui segment">
|
|
<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 -->
|
|
<h4 class="ui header">
|
|
Accent Color
|
|
</h4>
|
|
<div class="ui segment">
|
|
<div class="ui doubling grid">
|
|
<div class="sixteen wide column">
|
|
<p>Theme changes are only saved to this browser.</p>
|
|
<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 -->
|
|
<h4>Two Factor Authentication</h4>
|
|
<div class="ui segment">
|
|
<div class="ui stackable grid">
|
|
<div class="six 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="four 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="six wide column">
|
|
<p>3. Verify with code</p>
|
|
<div class="ui fluid action input" v-if="qrCode != ''">
|
|
<input type="text" placeholder="Verification Code" v-model="verificationToken" v-on:keyup.enter="verifyQrCode()">
|
|
<div class="ui green button">
|
|
Verify!
|
|
</div>
|
|
</div>
|
|
<div class="ui fluid action input" v-if="qrCode == ''">
|
|
<input type="text" placeholder="Verification Code" >
|
|
<div class="ui disabled button">
|
|
Verify!
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- change password -->
|
|
<h4>Change Password</h4>
|
|
<div class="ui segment">
|
|
<div class="ui stackable grid">
|
|
<div class="five wide column">
|
|
<p>Current Password</p>
|
|
<div class="ui fluid input">
|
|
<input v-model="change1" type="password" placeholder="Current Password">
|
|
</div>
|
|
</div>
|
|
<div class="five wide column">
|
|
<p>New Password</p>
|
|
<div class="ui fluid input">
|
|
<input v-model="change2" type="password" placeholder="New Password">
|
|
</div>
|
|
</div>
|
|
<div class="six wide column">
|
|
<p>Rereat New Password</p>
|
|
<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 -->
|
|
<h4>Revoke Other Active Sessions</h4>
|
|
<div class="ui segment">
|
|
<div class="ui stackable grid">
|
|
<div class="sixteen wide column">
|
|
<p>Revoke access on any logged in device, except for the one you are currently using.<br><br></p>
|
|
<div class="ui button" v-on:click="revokeAllSessions()">
|
|
<i class="sign out icon"></i>
|
|
Log Out all other devices
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h4>Export All Data (In Development)</h4>
|
|
<div class="ui segment">
|
|
<p>Download all files and notes in raw text or html</p>
|
|
<div class="ui button">Export all Data</div>
|
|
</div>
|
|
|
|
<h4>Delete Account (In Development)</h4>
|
|
<div class="ui segment">
|
|
<div class="ui stackable grid">
|
|
<div class="eight wide column">
|
|
<p>Delete all data. This can not be undone.</p>
|
|
<div class="ui fluid input">
|
|
<input type="password" placeholder="Current Password" v-model="password">
|
|
</div>
|
|
</div>
|
|
<div class="four wide bottom aligned column">
|
|
<div class="ui fluid button">Verify</div>
|
|
</div>
|
|
<div class="four wide bottom aligned column">
|
|
<div class="ui disabled fluid button">Delete Account</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ui grid">
|
|
<div class="center aligned sixteen wide column">
|
|
<router-link to="/terms"></i>Solid Scribe Terms of Use</router-link>
|
|
</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')
|
|
})
|
|
|
|
},
|
|
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> |