2
0
Эх сурвалжийг харах

Setup wizard - considerations + syschecks UI fixes

NGPixel 8 жил өмнө
parent
commit
40685410f0

+ 7 - 0
.travis.yml

@@ -39,3 +39,10 @@ deploy:
     repo: Requarks/wiki
     repo: Requarks/wiki
     tags: true
     tags: true
     node: '7'
     node: '7'
+notifications:
+  webhooks:
+    urls:
+      - https://webhooks.gitter.im/e/56b27cb2ec4692419db9
+    on_success: change
+    on_failure: always
+    on_start: never

+ 2 - 1
CHANGELOG.md

@@ -6,7 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 ### Added
 ### Added
 - Interactive setup
 - Interactive setup
 - GitHub and Slack authentication providers are now available
 - GitHub and Slack authentication providers are now available
-- Experimental: LDAP authentication provider
+- LDAP authentication provider
 
 
 ### Changed
 ### Changed
 - Content headers are now showing an anchor icon instead of a #
 - Content headers are now showing an anchor icon instead of a #
@@ -21,6 +21,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 - Missing icons on login page
 - Missing icons on login page
 - Image alignement center and right should now behave correctly
 - Image alignement center and right should now behave correctly
 - Error notification when upload is too large for server
 - Error notification when upload is too large for server
+- Authentication would fail if email has uppercase chars and provider callback is in lowercase
 
 
 ## [v1.0.0-beta.8] - 2017-02-19
 ## [v1.0.0-beta.8] - 2017-02-19
 ### Added
 ### Added

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
assets/css/app.css


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
assets/css/configure.css


+ 1 - 1
assets/js/configure.js

@@ -1 +1 @@
-"use strict";jQuery(document).ready(function(e){new Vue({el:"main",data:{loading:!1,state:"welcome",syscheck:{ok:!1,error:""},conf:{title:"Wiki",host:"",port:80,lang:"en",db:"mongodb://localhost:27017/wiki"}},methods:{proceedToWelcome:function(e){this.state="welcome",this.loading=!1},proceedToSyscheck:function(e){var o=this;this.state="syscheck",this.loading=!0,_.delay(function(){axios.post("/syscheck").then(function(e){e.data.ok===!0?o.syscheck.ok=!0:(o.syscheck.ok=!1,o.syscheck.error=e.data.error),o.loading=!1}).catch(function(e){window.alert(e.message)})},1e3)},proceedToGeneral:function(e){this.state="general",this.loading=!1},proceedToDb:function(e){this.state="db",this.loading=!1}}})});
+"use strict";jQuery(document).ready(function(t){new Vue({el:"main",data:{loading:!1,state:"considerations",syscheck:{ok:!1,error:"",results:[]},conf:{title:"Wiki",host:"",port:80,lang:"en",db:"mongodb://localhost:27017/wiki"},considerations:{https:!1,port:!1,localhost:!1}},methods:{proceedToWelcome:function(t){this.state="welcome",this.loading=!1},proceedToSyscheck:function(t){var s=this;this.state="syscheck",this.loading=!0,s.syscheck={ok:!1,error:"",results:[]},_.delay(function(){axios.post("/syscheck").then(function(t){t.data.ok===!0?(s.syscheck.ok=!0,s.syscheck.results=t.data.results):(s.syscheck.ok=!1,s.syscheck.error=t.data.error),s.loading=!1,s.$nextTick()}).catch(function(t){window.alert(t.message)})},1e3)},proceedToGeneral:function(t){this.state="general",this.loading=!1},proceedToConsiderations:function(t){this.considerations={https:!_.startsWith(this.conf.host,"https"),port:!1,localhost:_.includes(this.conf.host,"localhost")},this.state="considerations",this.loading=!1},proceedToDb:function(t){this.state="db",this.loading=!1}}})});

+ 24 - 2
client/js/configure.js

@@ -7,10 +7,11 @@ jQuery(document).ready(function ($) {
     el: 'main',
     el: 'main',
     data: {
     data: {
       loading: false,
       loading: false,
-      state: 'welcome',
+      state: 'considerations',
       syscheck: {
       syscheck: {
         ok: false,
         ok: false,
-        error: ''
+        error: '',
+        results: []
       },
       },
       conf: {
       conf: {
         title: 'Wiki',
         title: 'Wiki',
@@ -18,6 +19,11 @@ jQuery(document).ready(function ($) {
         port: 80,
         port: 80,
         lang: 'en',
         lang: 'en',
         db: 'mongodb://localhost:27017/wiki'
         db: 'mongodb://localhost:27017/wiki'
+      },
+      considerations: {
+        https: false,
+        port: false,
+        localhost: false
       }
       }
     },
     },
     methods: {
     methods: {
@@ -29,16 +35,23 @@ jQuery(document).ready(function ($) {
         let self = this
         let self = this
         this.state = 'syscheck'
         this.state = 'syscheck'
         this.loading = true
         this.loading = true
+        self.syscheck = {
+          ok: false,
+          error: '',
+          results: []
+        }
 
 
         _.delay(() => {
         _.delay(() => {
           axios.post('/syscheck').then(resp => {
           axios.post('/syscheck').then(resp => {
             if (resp.data.ok === true) {
             if (resp.data.ok === true) {
               self.syscheck.ok = true
               self.syscheck.ok = true
+              self.syscheck.results = resp.data.results
             } else {
             } else {
               self.syscheck.ok = false
               self.syscheck.ok = false
               self.syscheck.error = resp.data.error
               self.syscheck.error = resp.data.error
             }
             }
             self.loading = false
             self.loading = false
+            self.$nextTick()
           }).catch(err => {
           }).catch(err => {
             window.alert(err.message)
             window.alert(err.message)
           })
           })
@@ -48,6 +61,15 @@ jQuery(document).ready(function ($) {
         this.state = 'general'
         this.state = 'general'
         this.loading = false
         this.loading = false
       },
       },
+      proceedToConsiderations: function (ev) {
+        this.considerations = {
+          https: !_.startsWith(this.conf.host, 'https'),
+          port: false, // TODO
+          localhost: _.includes(this.conf.host, 'localhost')
+        }
+        this.state = 'considerations'
+        this.loading = false
+      },
       proceedToDb: function (ev) {
       proceedToDb: function (ev) {
         this.state = 'db'
         this.state = 'db'
         this.loading = false
         this.loading = false

+ 3 - 0
client/scss/configure.scss

@@ -36,6 +36,9 @@ i.icon-check {
 i.icon-square-cross {
 i.icon-square-cross {
   color: mc('red', '500')
   color: mc('red', '500')
 }
 }
+i.icon-warning-outline {
+  color: mc('orange', '500')
+}
 
 
 .tst-welcome-leave-active, .tst-welcome-enter-active {
 .tst-welcome-leave-active, .tst-welcome-enter-active {
   transition: all .5s;
   transition: all .5s;

+ 14 - 14
configure.js

@@ -56,23 +56,16 @@ module.exports = (port, spinner) => {
       () => {
       () => {
         const semver = require('semver')
         const semver = require('semver')
         if (!semver.satisfies(semver.clean(process.version), '>=4.6.0')) {
         if (!semver.satisfies(semver.clean(process.version), '>=4.6.0')) {
-          throw new Error('Node.js version is too old. Minimum is 4.6.0.')
+          throw new Error('Node.js version is too old. Minimum is v4.6.0.')
         }
         }
-        return true
-      },
-      () => {
-        const os = require('os')
-        if (os.totalmem() < 1024 * 1024 * 512) {
-          throw new Error('Not enough memory. Minimum is 512 MB.')
-        }
-        return true
+        return 'Node.js ' + process.version + ' detected. Minimum is v4.6.0.'
       },
       },
       () => {
       () => {
         return Promise.try(() => {
         return Promise.try(() => {
           require('crypto')
           require('crypto')
         }).catch(err => { // eslint-disable-line handle-callback-err
         }).catch(err => { // eslint-disable-line handle-callback-err
           throw new Error('Crypto Node.js module is not available.')
           throw new Error('Crypto Node.js module is not available.')
-        }).return(true)
+        }).return('Node.js Crypto module is available.')
       },
       },
       () => {
       () => {
         const exec = require('child_process').exec
         const exec = require('child_process').exec
@@ -84,22 +77,29 @@ module.exports = (port, spinner) => {
             }
             }
             let gitver = _.chain(stdout.replace(/[^\d.]/g, '')).split('.').take(3).join('.').value()
             let gitver = _.chain(stdout.replace(/[^\d.]/g, '')).split('.').take(3).join('.').value()
             if (!semver.satisfies(semver.clean(gitver), '>=2.11.0')) {
             if (!semver.satisfies(semver.clean(gitver), '>=2.11.0')) {
-              reject(new Error('Git version is too old. Minimum is 2.11.0.'))
+              reject(new Error('Git version is too old. Minimum is v2.11.0.'))
             }
             }
-            resolve(true)
+            resolve('Git v' + gitver + ' detected. Minimum is v2.11.0.')
           })
           })
         })
         })
       },
       },
+      () => {
+        const os = require('os')
+        if (os.totalmem() < 1024 * 1024 * 768) {
+          throw new Error('Not enough memory. Minimum is 768 MB.')
+        }
+        return _.round(os.totalmem() / (1024 * 1024)) + ' MB of system memory available. Minimum is 768 MB.'
+      },
       () => {
       () => {
         let fs = require('fs')
         let fs = require('fs')
         return Promise.try(() => {
         return Promise.try(() => {
           fs.accessSync(path.join(ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK)
           fs.accessSync(path.join(ROOTPATH, 'config.yml'), (fs.constants || fs).W_OK)
         }).catch(err => { // eslint-disable-line handle-callback-err
         }).catch(err => { // eslint-disable-line handle-callback-err
           throw new Error('config.yml file is not writable by Node.js process or was not created properly.')
           throw new Error('config.yml file is not writable by Node.js process or was not created properly.')
-        }).return(true)
+        }).return('config.yml is writable by the setup process.')
       }
       }
     ], test => { return test() }).then(results => {
     ], test => { return test() }).then(results => {
-      res.json({ ok: true })
+      res.json({ ok: true, results })
     }).catch(err => {
     }).catch(err => {
       res.json({ ok: false, error: err.message })
       res.json({ ok: false, error: err.message })
     })
     })

+ 33 - 2
views/configure/index.pug

@@ -54,7 +54,12 @@ html
                   i(v-if='loading')
                   i(v-if='loading')
                 .panel-content.is-text
                 .panel-content.is-text
                   p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Checking your system for compatibility...
                   p(v-if='loading') #[i.icon-loader.animated.rotateIn.infinite] Checking your system for compatibility...
-                  p(v-if='!loading && syscheck.ok') #[i.icon-check] Looks great! No issues so far.
+                  p(v-if='!loading && syscheck.ok')
+                    ul
+                      li(v-for='rs in syscheck.results') #[i.icon-check] {{rs}}
+                  p(v-if='!loading && syscheck.ok')
+                    i.icon-check
+                    strong  Looks good! No issues so far.
                   p(v-if='!loading && !syscheck.ok') #[i.icon-square-cross] Error: {{ syscheck.error }}
                   p(v-if='!loading && !syscheck.ok') #[i.icon-square-cross] Error: {{ syscheck.error }}
                 .panel-footer
                 .panel-footer
                   button.button.is-indigo.is-outlined(v-on:click='proceedToWelcome', v-bind:disabled='loading') Back
                   button.button.is-indigo.is-outlined(v-on:click='proceedToWelcome', v-bind:disabled='loading') Back
@@ -90,6 +95,32 @@ html
                       p.desc The language in which navigation, help and other UI elements will be displayed.
                       p.desc The language in which navigation, help and other UI elements will be displayed.
                 .panel-footer
                 .panel-footer
                   button.button.is-indigo.is-outlined(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Back
                   button.button.is-indigo.is-outlined(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Back
+                  button.button.is-indigo(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Continue
+
+            template(v-else-if='state === "considerations"')
+              .panel
+                h2.panel-title.is-featured
+                  span Important Considerations
+                  i(v-if='loading')
+                .panel-content.is-text
+                  h3 Is Wiki.js going to be behind a web server (e.g. nginx / apache / IIS) or proxy?
+                  p
+                    ul
+                      li - Make sure the upload limit is sufficient. Most web servers have a low limit (e.g. 2 MB) by default.
+                      li - Make sure your web server is configured to allow web sockets. Wiki.js will fallback to standard XHR queries if not available.
+                      li - Do not rewrite URLs after the domain. This can cause unexpected issues in Wiki.js navigation.
+                      li - Do not remove or alter the client IP when proxying the requests. This can cause the authentication brute force protection to engage unexpectedly.
+                  template(v-if='considerations.https')
+                    h3 The site will not be using HTTPS? #[i.icon-warning-outline.animated.fadeOut.infinite]
+                    p The host URL you specified is not HTTPS. It is highly recommended to use HTTPS. You must use a web server / proxy (e.g. nginx / apache / IIS) in front of Wiki.js to use HTTPS. Wiki.js does not provide HTTPS handling by itself.
+                  template(v-if='considerations.port')
+                    h3 You are using a non-standard port.
+                    p If you are not planning on using a web server / proxy in front of Wiki.js, be aware that users will need to specify the port when accessing the wiki. Make sure this is the intended behavior. Otherwise set a standard HTTP port such as 80.
+                  template(v-if='considerations.localhost')
+                    h3 Are you sure you want to use localhost as the host base URL? #[i.icon-warning-outline.animated.fadeOut.infinite]
+                    p The host URL you specified is localhost. Unless you are a developer running Wiki.js locally on your machine, this is not recommended!
+                .panel-footer
+                  button.button.is-indigo.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back
                   button.button.is-indigo(v-on:click='proceedToDb', v-bind:disabled='loading') Continue
                   button.button.is-indigo(v-on:click='proceedToDb', v-bind:disabled='loading') Continue
 
 
             template(v-else-if='state === "db"')
             template(v-else-if='state === "db"')
@@ -104,7 +135,7 @@ html
                       input(type='text', placeholder='e.g. mongodb://localhost:27017/wiki', v-model='conf.db')
                       input(type='text', placeholder='e.g. mongodb://localhost:27017/wiki', v-model='conf.db')
                       p.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.
                       p.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.
                 .panel-footer
                 .panel-footer
-                  button.button.is-indigo.is-outlined(v-on:click='proceedToGeneral', v-bind:disabled='loading') Back
+                  button.button.is-indigo.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back
                   button.button.is-indigo(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Connect
                   button.button.is-indigo(v-on:click='proceedToSyscheck', v-bind:disabled='loading') Connect
 
 
       footer.footer
       footer.footer

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно