mirror of
https://github.com/kaythomas0/noisedash.git
synced 2025-11-14 04:14:02 +00:00
Add account page
This commit is contained in:
@@ -232,6 +232,33 @@ router.patch('/users/dark-mode', (req, res) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.patch('/users/password', (req, res) => {
|
||||||
|
if (!req.user) {
|
||||||
|
return res.sendStatus(401)
|
||||||
|
}
|
||||||
|
|
||||||
|
const salt = crypto.randomBytes(16)
|
||||||
|
crypto.pbkdf2(req.body.password, salt, 10000, 32, 'sha256', (err, hashedPassword) => {
|
||||||
|
if (err) {
|
||||||
|
logger.error(err)
|
||||||
|
return res.sendStatus(500)
|
||||||
|
}
|
||||||
|
|
||||||
|
db.run('UPDATE users SET hashed_password = ?, salt = ? WHERE id = ?', [
|
||||||
|
hashedPassword,
|
||||||
|
salt,
|
||||||
|
req.user.id
|
||||||
|
], (err) => {
|
||||||
|
if (err) {
|
||||||
|
logger.error(err)
|
||||||
|
return res.sendStatus(500)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.sendStatus(200)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
router.delete('/users/:userId', (req, res) => {
|
router.delete('/users/:userId', (req, res) => {
|
||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
return res.sendStatus(401)
|
return res.sendStatus(401)
|
||||||
|
|||||||
99
src/components/Account.vue
Normal file
99
src/components/Account.vue
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-col class="mb-5">
|
||||||
|
<h1 class="display-2 font-weight-bold mb-3">
|
||||||
|
Account
|
||||||
|
</h1>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-row>
|
||||||
|
ID: {{ currentUser.id }}
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
Username: {{ currentUser.username }}
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
Name: {{ currentUser.name }}
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-dialog
|
||||||
|
v-model="changePasswordDialog"
|
||||||
|
max-width="600px"
|
||||||
|
>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-btn
|
||||||
|
class="my-3"
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
@click="resetChangePasswordForm"
|
||||||
|
>
|
||||||
|
Change Password
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<v-form
|
||||||
|
ref="changePasswordForm"
|
||||||
|
v-model="isPasswordValid"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
<span class="text-h5">Change Password</span>
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-text-field
|
||||||
|
v-model="password"
|
||||||
|
type="password"
|
||||||
|
:rules="[rules.required]"
|
||||||
|
label="Password"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
@click="changePasswordDialog = false"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
:disabled="!isPasswordValid"
|
||||||
|
@click="updatePassword"
|
||||||
|
>
|
||||||
|
Change Password
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-form>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
<v-snackbar
|
||||||
|
v-model="snackbar"
|
||||||
|
timeout="3000"
|
||||||
|
>
|
||||||
|
{{ snackbarText }}
|
||||||
|
|
||||||
|
<template v-slot:action="{ attrs }">
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
v-bind="attrs"
|
||||||
|
@click="snackbar = false"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-snackbar>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./account.js"></script>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<v-btn
|
<v-btn
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
v-on="on"
|
v-on="on"
|
||||||
@click="$refs.registerUserForm.reset()"
|
@click="resetRegisterUserForm"
|
||||||
>
|
>
|
||||||
Register User
|
Register User
|
||||||
</v-btn>
|
</v-btn>
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
v-model="snackbar"
|
v-model="snackbar"
|
||||||
timeout="3000"
|
timeout="3000"
|
||||||
>
|
>
|
||||||
{{ updateText }}
|
{{ snackbarText }}
|
||||||
|
|
||||||
<template v-slot:action="{ attrs }">
|
<template v-slot:action="{ attrs }">
|
||||||
<v-btn
|
<v-btn
|
||||||
|
|||||||
@@ -29,6 +29,16 @@
|
|||||||
Home
|
Home
|
||||||
</v-list-item-title>
|
</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
@click="account"
|
||||||
|
>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>mdi-account</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>
|
||||||
|
Account
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-if="isAdmin"
|
v-if="isAdmin"
|
||||||
@click="admin"
|
@click="admin"
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
class="mx-3 my-3"
|
class="mx-3 my-3"
|
||||||
:disabled="playDisabled"
|
:disabled="playDisabled"
|
||||||
v-on="on"
|
v-on="on"
|
||||||
@click="$refs.profileForm.reset()"
|
@click="resetProfileForm"
|
||||||
>
|
>
|
||||||
Save Profile As...
|
Save Profile As...
|
||||||
</v-btn>
|
</v-btn>
|
||||||
@@ -481,7 +481,7 @@
|
|||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
class="mx-3 my-3 mb-5"
|
class="mx-3 my-3 mb-5"
|
||||||
v-on="on"
|
v-on="on"
|
||||||
@click="$refs.uploadSampleForm.reset()"
|
@click="resetUploadSampleForm"
|
||||||
>
|
>
|
||||||
Upload Sample
|
Upload Sample
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|||||||
45
src/components/account.js
Normal file
45
src/components/account.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
export default {
|
||||||
|
name: 'Admin',
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
currentUser: {},
|
||||||
|
changePasswordDialog: false,
|
||||||
|
isPasswordValid: false,
|
||||||
|
password: '',
|
||||||
|
snackbar: false,
|
||||||
|
snackbarText: '',
|
||||||
|
rules: {
|
||||||
|
required: v => !!v || 'Required'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
created () {
|
||||||
|
this.getCurrentUser()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getCurrentUser () {
|
||||||
|
this.$http.get('/users/current')
|
||||||
|
.then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.currentUser = response.data.user
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updatePassword () {
|
||||||
|
this.$http.patch('/users/password', {
|
||||||
|
password: this.password
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.changePasswordDialog = false
|
||||||
|
this.snackbarText = 'Password Changed'
|
||||||
|
this.snackbar = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
resetChangePasswordForm () {
|
||||||
|
if (this.$refs.changePasswordForm) {
|
||||||
|
this.$refs.changePasswordForm.reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ export default {
|
|||||||
currentUser: {},
|
currentUser: {},
|
||||||
users: [],
|
users: [],
|
||||||
snackbar: false,
|
snackbar: false,
|
||||||
updateText: '',
|
snackbarText: '',
|
||||||
registerUserDialog: false,
|
registerUserDialog: false,
|
||||||
isUserValid: false,
|
isUserValid: false,
|
||||||
name: '',
|
name: '',
|
||||||
@@ -44,11 +44,11 @@ export default {
|
|||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.updateText = 'User updated'
|
this.snackbarText = 'User updated'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.updateText = 'Error updating user'
|
this.snackbarText = 'Error updating user'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
updateUserUpload (id, canUpload) {
|
updateUserUpload (id, canUpload) {
|
||||||
@@ -57,11 +57,11 @@ export default {
|
|||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.updateText = 'User updated'
|
this.snackbarText = 'User updated'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.updateText = 'Error updating user'
|
this.snackbarText = 'Error updating user'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
deleteUser (id) {
|
deleteUser (id) {
|
||||||
@@ -84,11 +84,16 @@ export default {
|
|||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.registerUserDialog = false
|
this.registerUserDialog = false
|
||||||
this.updateText = 'User Registered'
|
this.snackbarText = 'User Registered'
|
||||||
this.snackbar = true
|
this.snackbar = true
|
||||||
this.getUsers()
|
this.getUsers()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
resetRegisterUserForm () {
|
||||||
|
if (this.$refs.registerUserForm) {
|
||||||
|
this.$refs.registerUserForm.reset()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ export default {
|
|||||||
home () {
|
home () {
|
||||||
this.$router.push('/')
|
this.$router.push('/')
|
||||||
},
|
},
|
||||||
|
account () {
|
||||||
|
this.$router.push('/account')
|
||||||
|
},
|
||||||
admin () {
|
admin () {
|
||||||
this.$router.push('/admin')
|
this.$router.push('/admin')
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -393,6 +393,16 @@ export default {
|
|||||||
this.$vuetify.theme.dark = response.data.user.darkMode
|
this.$vuetify.theme.dark = response.data.user.darkMode
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
resetProfileForm () {
|
||||||
|
if (this.$refs.profileForm) {
|
||||||
|
this.$refs.profileForm.reset()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetUploadSampleForm () {
|
||||||
|
if (this.$refs.uploadSampleForm) {
|
||||||
|
this.$refs.uploadSampleForm.reset()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,23 +14,22 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
// route level code-splitting
|
component: () => import('../views/LoginView.vue')
|
||||||
// this generates a separate chunk (about.[hash].js) for this route
|
|
||||||
// which is lazy-loaded when the route is visited.
|
|
||||||
component: () => import(/* webpackChunkName: "about" */ '../views/LoginView.vue')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/register',
|
path: '/register',
|
||||||
name: 'Register',
|
name: 'Register',
|
||||||
// route level code-splitting
|
component: () => import('../views/RegisterView.vue')
|
||||||
// this generates a separate chunk (about.[hash].js) for this route
|
|
||||||
// which is lazy-loaded when the route is visited.
|
|
||||||
component: () => import(/* webpackChunkName: "about" */ '../views/RegisterView.vue')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/admin',
|
path: '/admin',
|
||||||
name: 'Admin',
|
name: 'Admin',
|
||||||
component: () => import(/* webpackChunkName: "about" */ '../views/AdminView.vue')
|
component: () => import('../views/AdminView.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/account',
|
||||||
|
name: 'Account',
|
||||||
|
component: () => import('../views/AccountView.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -50,8 +49,7 @@ router.beforeEach((to, from, next) => {
|
|||||||
next('/register')
|
next('/register')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(() => {
|
||||||
console.error(error.response)
|
|
||||||
next('/register')
|
next('/register')
|
||||||
})
|
})
|
||||||
} else if (to.name === 'Admin') {
|
} else if (to.name === 'Admin') {
|
||||||
@@ -63,8 +61,7 @@ router.beforeEach((to, from, next) => {
|
|||||||
next('/')
|
next('/')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(() => {
|
||||||
console.error(error.response)
|
|
||||||
next('/')
|
next('/')
|
||||||
})
|
})
|
||||||
} else if (to.name === 'Register') {
|
} else if (to.name === 'Register') {
|
||||||
@@ -76,10 +73,21 @@ router.beforeEach((to, from, next) => {
|
|||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(() => {
|
||||||
console.error(error.response)
|
|
||||||
next('/login')
|
next('/login')
|
||||||
})
|
})
|
||||||
|
} else if (to.name === 'Account') {
|
||||||
|
instance.get('/auth')
|
||||||
|
.then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
next('/register')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
next('/register')
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/views/AccountView.vue
Normal file
15
src/views/AccountView.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<Account />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Account from '../components/Account'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AccountView',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Account
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user