forked from external-repos/noisedash
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) => {
|
||||
if (!req.user) {
|
||||
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-bind="attrs"
|
||||
v-on="on"
|
||||
@click="$refs.registerUserForm.reset()"
|
||||
@click="resetRegisterUserForm"
|
||||
>
|
||||
Register User
|
||||
</v-btn>
|
||||
@@ -137,7 +137,7 @@
|
||||
v-model="snackbar"
|
||||
timeout="3000"
|
||||
>
|
||||
{{ updateText }}
|
||||
{{ snackbarText }}
|
||||
|
||||
<template v-slot:action="{ attrs }">
|
||||
<v-btn
|
||||
|
||||
@@ -29,6 +29,16 @@
|
||||
Home
|
||||
</v-list-item-title>
|
||||
</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-if="isAdmin"
|
||||
@click="admin"
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
class="mx-3 my-3"
|
||||
:disabled="playDisabled"
|
||||
v-on="on"
|
||||
@click="$refs.profileForm.reset()"
|
||||
@click="resetProfileForm"
|
||||
>
|
||||
Save Profile As...
|
||||
</v-btn>
|
||||
@@ -481,7 +481,7 @@
|
||||
v-bind="attrs"
|
||||
class="mx-3 my-3 mb-5"
|
||||
v-on="on"
|
||||
@click="$refs.uploadSampleForm.reset()"
|
||||
@click="resetUploadSampleForm"
|
||||
>
|
||||
Upload Sample
|
||||
</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: {},
|
||||
users: [],
|
||||
snackbar: false,
|
||||
updateText: '',
|
||||
snackbarText: '',
|
||||
registerUserDialog: false,
|
||||
isUserValid: false,
|
||||
name: '',
|
||||
@@ -44,11 +44,11 @@ export default {
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status === 200) {
|
||||
this.updateText = 'User updated'
|
||||
this.snackbarText = 'User updated'
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.updateText = 'Error updating user'
|
||||
this.snackbarText = 'Error updating user'
|
||||
})
|
||||
},
|
||||
updateUserUpload (id, canUpload) {
|
||||
@@ -57,11 +57,11 @@ export default {
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status === 200) {
|
||||
this.updateText = 'User updated'
|
||||
this.snackbarText = 'User updated'
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.updateText = 'Error updating user'
|
||||
this.snackbarText = 'Error updating user'
|
||||
})
|
||||
},
|
||||
deleteUser (id) {
|
||||
@@ -84,11 +84,16 @@ export default {
|
||||
.then(response => {
|
||||
if (response.status === 200) {
|
||||
this.registerUserDialog = false
|
||||
this.updateText = 'User Registered'
|
||||
this.snackbarText = 'User Registered'
|
||||
this.snackbar = true
|
||||
this.getUsers()
|
||||
}
|
||||
})
|
||||
},
|
||||
resetRegisterUserForm () {
|
||||
if (this.$refs.registerUserForm) {
|
||||
this.$refs.registerUserForm.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@ export default {
|
||||
home () {
|
||||
this.$router.push('/')
|
||||
},
|
||||
account () {
|
||||
this.$router.push('/account')
|
||||
},
|
||||
admin () {
|
||||
this.$router.push('/admin')
|
||||
},
|
||||
|
||||
@@ -393,6 +393,16 @@ export default {
|
||||
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',
|
||||
name: 'Login',
|
||||
// route level code-splitting
|
||||
// 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')
|
||||
component: () => import('../views/LoginView.vue')
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
name: 'Register',
|
||||
// route level code-splitting
|
||||
// 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')
|
||||
component: () => import('../views/RegisterView.vue')
|
||||
},
|
||||
{
|
||||
path: '/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')
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error.response)
|
||||
.catch(() => {
|
||||
next('/register')
|
||||
})
|
||||
} else if (to.name === 'Admin') {
|
||||
@@ -63,8 +61,7 @@ router.beforeEach((to, from, next) => {
|
||||
next('/')
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error.response)
|
||||
.catch(() => {
|
||||
next('/')
|
||||
})
|
||||
} else if (to.name === 'Register') {
|
||||
@@ -76,10 +73,21 @@ router.beforeEach((to, from, next) => {
|
||||
next()
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error.response)
|
||||
.catch(() => {
|
||||
next('/login')
|
||||
})
|
||||
} else if (to.name === 'Account') {
|
||||
instance.get('/auth')
|
||||
.then(response => {
|
||||
if (response.status === 200) {
|
||||
next()
|
||||
} else {
|
||||
next('/register')
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
next('/register')
|
||||
})
|
||||
} else {
|
||||
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