Prechádzať zdrojové kódy

Create / Authorize User feature

NGPixel 8 rokov pred
rodič
commit
85bd64ea8b

+ 2 - 0
CHANGELOG.md

@@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 ### Added
 - Change log
 - Added .editorconfig, .eslintrc.json and .pug-lintrc.json for code linting
+- Added Create / Authorize User feature
+- Added Login as... button to Forbidden page
 
 ### Fixed
 - Fixed issue with social accounts with empty name

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
assets/css/app.css


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
assets/js/app.js


+ 25 - 3
client/js/modals/admin-users-create.js

@@ -1,4 +1,4 @@
-/* global $, Vue */
+/* global $, Vue, alerts */
 
 // Vue Create User instance
 
@@ -8,7 +8,8 @@ let vueCreateUser = new Vue({
     email: '',
     provider: 'local',
     password: '',
-    name: ''
+    name: '',
+    loading: false
   },
   methods: {
     open: (ev) => {
@@ -21,7 +22,28 @@ let vueCreateUser = new Vue({
       vueCreateUser.provider = 'local'
     },
     create: (ev) => {
-      vueCreateUser.cancel()
+      vueCreateUser.loading = true
+      $.ajax('/admin/users/create', {
+        data: {
+          email: vueCreateUser.email,
+          provider: vueCreateUser.provider,
+          password: vueCreateUser.password,
+          name: vueCreateUser.name
+        },
+        dataType: 'json',
+        method: 'POST'
+      }).then((rData, rStatus, rXHR) => {
+        vueCreateUser.loading = false
+        if (rData.ok) {
+          vueCreateUser.cancel()
+          window.location.reload(true)
+        } else {
+          alerts.pushError('Something went wrong', rData.msg)
+        }
+      }, (rXHR, rStatus, err) => {
+        vueCreateUser.loading = false
+        alerts.pushError('Error', rXHR.responseJSON.msg)
+      })
     }
   }
 })

+ 59 - 0
controllers/admin.js

@@ -103,6 +103,65 @@ router.get('/users/:id', (req, res) => {
     })
 })
 
+/**
+ * Create / Authorize a new user
+ */
+router.post('/users/create', (req, res) => {
+  if (!res.locals.rights.manage) {
+    return res.status(401).json({ msg: 'Unauthorized' })
+  }
+
+  let nUsr = {
+    email: _.trim(req.body.email),
+    provider: _.trim(req.body.provider),
+    password: req.body.password,
+    name: _.trim(req.body.name)
+  }
+
+  if (!validator.isEmail(nUsr.email)) {
+    return res.status(400).json({ msg: 'Invalid email address' })
+  } else if (!validator.isIn(nUsr.provider, ['local', 'google', 'windowslive', 'facebook'])) {
+    return res.status(400).json({ msg: 'Invalid provider' })
+  } else if (nUsr.provider === 'local' && !validator.isLength(nUsr.password, { min: 6 })) {
+    return res.status(400).json({ msg: 'Password too short or missing' })
+  } else if (nUsr.provider === 'local' && !validator.isLength(nUsr.name, { min: 2 })) {
+    return res.status(400).json({ msg: 'Name is missing' })
+  }
+
+  db.User.findOne({ email: nUsr.email, provider: nUsr.provider }).then(exUsr => {
+    if (exUsr) {
+      return res.status(400).json({ msg: 'User already exists!' }) || true
+    }
+
+    let pwdGen = (nUsr.provider === 'local') ? db.User.hashPassword(nUsr.password) : Promise.resolve(true)
+    return pwdGen.then(nPwd => {
+      if (nUsr.provider !== 'local') {
+        nUsr.password = ''
+        nUsr.name = '-- pending --'
+      } else {
+        nUsr.password = nPwd
+      }
+
+      nUsr.rights = [{
+        role: 'read',
+        path: '/',
+        exact: false,
+        deny: false
+      }]
+
+      return db.User.create(nUsr).then(() => {
+        return res.json({ ok: true })
+      })
+    }).catch(err => {
+      winston.warn(err)
+      return res.status(500).json({ msg: err })
+    })
+  }).catch(err => {
+    winston.warn(err)
+    return res.status(500).json({ msg: err })
+  })
+})
+
 router.post('/users/:id', (req, res) => {
   if (!res.locals.rights.manage) {
     return res.status(401).json({ msg: 'Unauthorized' })

+ 1 - 0
views/error-forbidden.pug

@@ -27,3 +27,4 @@ html
       h1 Forbidden
       h2 Sorry, you don't have the necessary permissions to access this page.
       a.button.is-amber.is-inverted(href='/') Go Home
+      a.button.is-amber.is-inverted(href='/login') Login as...

+ 11 - 9
views/modals/admin-createuser.pug

@@ -3,31 +3,33 @@
   .modal-background
   .modal-container
     .modal-content
-      header.is-blue Create / Authorize User
+      header.is-blue
+        span Create / Authorize User
+        p.modal-notify(v-bind:class='{ "is-active": loading }'): i
       section
         label.label Email address:
         p.control.is-fullwidth
           input.input(type='text', placeholder='e.g. john.doe@company.com', v-model='email')
-          span.help.is-red.is-hidden This email is invalid!
       section
         label.label Provider:
         p.control.is-fullwidth
           select(v-model='provider')
             option(value='local') Local Database
-            option(value='windowslive') Microsoft Account
-            option(value='google') Google ID
-            option(value='facebook') Facebook
+            if appconfig.auth.microsoft.enabled
+              option(value='windowslive') Microsoft Account
+            if appconfig.auth.google.enabled
+              option(value='google') Google ID
+            if appconfig.auth.facebook.enabled
+              option(value='facebook') Facebook
       section(v-if='provider=="local"')
         label.label Password:
         p.control.is-fullwidth
           input.input(type='password', placeholder='', v-model='password')
-          span.help.is-red.is-hidden This password is invalid!
       section(v-if='provider=="local"')
         label.label Full Name:
         p.control.is-fullwidth
           input.input(type='text', placeholder='e.g. John Doe', v-model='name')
-          span.help.is-red.is-hidden This name is invalid!
       footer
         a.button.is-grey.is-outlined(v-on:click='cancel') Discard
-        a.button.is-blue(v-on:click='create', v-if='provider=="local"') Create User
-        a.button.is-blue(v-on:click='create', v-if='provider!="local"') Authorize User
+        a.button(v-on:click='create', v-if='provider=="local"', v-bind:disabled='loading', v-bind:class='{ "is-disabled": loading, "is-blue": !loading }') Create User
+        a.button(v-on:click='create', v-if='provider!="local"', v-bind:disabled='loading', v-bind:class='{ "is-disabled": loading, "is-blue": !loading }') Authorize User

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov