aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/routes/auth/registerPOST.js10
-rw-r--r--src/site/pages/dashboard/admin/users.vue92
2 files changed, 99 insertions, 3 deletions
diff --git a/src/api/routes/auth/registerPOST.js b/src/api/routes/auth/registerPOST.js
index 1cf3630..54e683e 100644
--- a/src/api/routes/auth/registerPOST.js
+++ b/src/api/routes/auth/registerPOST.js
@@ -2,6 +2,7 @@ const bcrypt = require('bcrypt');
const moment = require('moment');
const Route = require('../../structures/Route');
const log = require('../../utils/Log');
+const Util = require('../../utils/Util');
class registerPOST extends Route {
constructor() {
@@ -9,7 +10,10 @@ class registerPOST extends Route {
}
async run(req, res, db) {
- if (process.env.USER_ACCOUNTS === 'false') return res.status(401).json({ message: 'Creation of new accounts is currently disabled' });
+ // Only allow admins to create new accounts if the sign up is deactivated
+ const user = await Util.isAuthorized(req);
+ if ((!user || !user.isAdmin) && process.env.USER_ACCOUNTS === 'false') return res.status(401).json({ message: 'Creation of new accounts is currently disabled' });
+
if (!req.body) return res.status(400).json({ message: 'No body provided' });
const { username, password } = req.body;
if (!username || !password) return res.status(401).json({ message: 'Invalid body provided' });
@@ -24,8 +28,8 @@ class registerPOST extends Route {
/*
Make sure the username doesn't exist yet
*/
- const user = await db.table('users').where('username', username).first();
- if (user) return res.status(401).json({ message: 'Username already exists' });
+ const exists = await db.table('users').where('username', username).first();
+ if (exists) return res.status(401).json({ message: 'Username already exists' });
/*
Hash the supplied password
diff --git a/src/site/pages/dashboard/admin/users.vue b/src/site/pages/dashboard/admin/users.vue
index 5345086..5195e5d 100644
--- a/src/site/pages/dashboard/admin/users.vue
+++ b/src/site/pages/dashboard/admin/users.vue
@@ -12,6 +12,56 @@
<hr>
<div class="view-container">
+ <button v-if="!isCreateUserOpen"
+ class="button is-chibisafe"
+ @click="isCreateUserOpen = true">
+ New user
+ </button>
+ <div v-if="isCreateUserOpen"
+ class="userCreate">
+ <div class="columns">
+ <div class="column is-4 is-offset-4">
+ <b-field>
+ <b-input
+ v-model="username"
+ class="chibisafe-input"
+ type="text"
+ placeholder="Username" />
+ </b-field>
+ <b-field>
+ <b-input
+ v-model="password"
+ class="chibisafe-input"
+ type="password"
+ placeholder="Password"
+ password-reveal
+ @keyup.enter.native="register" />
+ </b-field>
+ <div class="level">
+ <!-- Left side -->
+ <div class="level-left">
+ <div class="level-item">
+ <button class="button is-chibisafe"
+ @click="cleanUpRegister">
+ Cancel
+ </button>
+ </div>
+ </div>
+ <!-- Right side -->
+ <div class="level-right">
+ <p class="level-item">
+ <b-button
+ type="is-chibisafe"
+ :disabled="isLoading"
+ @click="register">
+ Register
+ </b-button>
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
<b-table
:data="users"
:mobile-cards="true">
@@ -101,6 +151,14 @@ export default {
console.error(e);
}
}],
+ data() {
+ return {
+ isCreateUserOpen: false,
+ username: null,
+ password: null,
+ isLoading: null
+ };
+ },
computed: mapState({
users: state => state.admin.users,
config: state => state.config
@@ -128,6 +186,34 @@ export default {
},
async purgeFiles(row) {
this.$handler.executeAction('admin/purgeUserFiles', row.id);
+ },
+ async register() {
+ if (this.isLoading) return;
+
+ if (!this.username || !this.password) {
+ this.$notifier.error('Please fill all fields before attempting to register.');
+ return;
+ }
+ this.isLoading = true;
+
+ try {
+ const response = await this.$store.dispatch('auth/register', {
+ username: this.username,
+ password: this.password
+ });
+ this.$store.dispatch('admin/fetchUsers');
+ this.$notifier.success(response.message);
+ return this.cleanUpRegister();
+ } catch (error) {
+ this.$notifier.error(error.message);
+ } finally {
+ this.isLoading = false;
+ }
+ },
+ cleanUpRegister() {
+ this.isCreateUserOpen = false;
+ this.username = null;
+ this.password = null;
}
},
head() {
@@ -142,6 +228,12 @@ export default {
@import '~/assets/styles/_colors.scss';
div.view-container {
padding: 2rem;
+ > .button {
+ margin-bottom: 1rem;
+ }
+ .userCreate {
+ margin-bottom: 2rem;
+ }
}
div.album {
display: flex;