Ver Fonte

fix: modules non-string config + live trail logging

Nicolas Giard há 6 anos atrás
pai
commit
904e2a6efb

+ 16 - 1
client/client-app.js

@@ -8,8 +8,11 @@ import VeeValidate from 'vee-validate'
 import { ApolloClient } from 'apollo-client'
 import { createPersistedQueryLink } from 'apollo-link-persisted-queries'
 // import { BatchHttpLink } from 'apollo-link-batch-http'
+import { split } from 'apollo-link'
 import { createHttpLink } from 'apollo-link-http'
+import { WebSocketLink } from 'apollo-link-ws'
 import { InMemoryCache } from 'apollo-cache-inmemory'
+import { getMainDefinition } from 'apollo-utilities'
 import VueApollo from 'vue-apollo'
 import Vuetify from 'vuetify'
 import Velocity from 'velocity-animate'
@@ -48,6 +51,7 @@ moment.locale(siteConfig.lang)
 // ====================================
 
 const graphQLEndpoint = window.location.protocol + '//' + window.location.host + '/graphql'
+const graphQLWSEndpoint = ((window.location.protocol === 'https:') ? 'wss:' : 'ws:') + '//' + window.location.host + '/graphql-subscriptions'
 
 const graphQLLink = createPersistedQueryLink().concat(
   createHttpLink({
@@ -77,8 +81,19 @@ const graphQLLink = createPersistedQueryLink().concat(
   })
 )
 
+const graphQLWSLink = new WebSocketLink({
+  uri: graphQLWSEndpoint,
+  options: {
+    reconnect: true,
+    lazy: true
+  }
+})
+
 window.graphQL = new ApolloClient({
-  link: graphQLLink,
+  link: split(({ query }) => {
+    const { kind, operation } = getMainDefinition(query)
+    return kind === 'OperationDefinition' && operation === 'subscription'
+  }, graphQLWSLink, graphQLLink),
   cache: new InMemoryCache(),
   connectToDevTools: (process.env.node_env === 'development')
 })

+ 1 - 1
client/components/admin/admin-auth.vue

@@ -164,7 +164,7 @@ export default {
             'selfRegistration',
             'domainWhitelist',
             'autoEnrollGroups'
-          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: cfg.value.value}))}))
+          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.stringify({ v: cfg.value.value })}))}))
         }
       })
       this.$store.commit('showNotification', {

+ 8 - 5
client/components/admin/admin-groups-edit.vue

@@ -1,9 +1,12 @@
 <template lang='pug'>
-  v-card
-    v-card(flat, :color='$vuetify.dark ? "grey darken-4" : "grey lighten-5"').pa-3.pt-4
-      .admin-header-icon: v-icon(size='80', color='grey lighten-2') people
-      .headline.blue--text.text--darken-2 Edit Group
-      .subheading.grey--text {{name}}
+  v-container(fluid, grid-list-lg)
+    v-layout(row wrap)
+      v-flex(xs12)
+        .admin-header
+          v-icon(size='80', color='grey lighten-2') people
+          .admin-header-title
+            .headline.blue--text.text--darken-2 Edit Group
+            .subheading.grey--text {{name}}
       v-btn(color='primary', fab, absolute, bottom, right, small, to='/groups'): v-icon arrow_upward
     v-tabs(v-model='tab', :color='$vuetify.dark ? "primary" : "grey lighten-4"', fixed-tabs, :slider-color='$vuetify.dark ? "white" : "primary"', show-arrows)
       v-tab(key='properties') Properties

+ 25 - 2
client/components/admin/admin-logging-console.vue

@@ -26,6 +26,8 @@ import _ from 'lodash'
 import { Terminal } from 'xterm'
 import * as fit from 'xterm/lib/addons/fit/fit'
 
+import livetrailSubscription from 'gql/admin/logging/logging-subscription-livetrail.gql'
+
 Terminal.applyAddon(fit)
 
 export default {
@@ -49,6 +51,8 @@ export default {
           this.term = new Terminal()
           this.term.open(this.$refs.consoleContainer)
           this.term.writeln('Connecting to \x1B[1;3;31mconsole output\x1B[0m...')
+
+          this.attach()
         }, 100)
       } else {
         this.term.dispose()
@@ -57,8 +61,7 @@ export default {
     }
   },
   mounted() {
-    this.term = new Terminal()
-    this.term.open(this.$refs.consoleContainer)
+
   },
   methods: {
     clear() {
@@ -66,6 +69,26 @@ export default {
     },
     close() {
       this.isShown = false
+    },
+    attach() {
+      const self = this
+      const observer = this.$apollo.subscribe({
+        query: livetrailSubscription
+      })
+      observer.subscribe({
+        next(data) {
+          const item = _.get(data, `data.loggingLiveTrail`, {})
+          console.info(item)
+          self.term.writeln(`${item.level}: ${item.output}`)
+        },
+        error(error) {
+          self.$store.commit('showNotification', {
+            style: 'red',
+            message: error.message,
+            icon: 'warning'
+          })
+        }
+      })
     }
   }
 }

+ 11 - 5
client/components/admin/admin-logging.vue

@@ -11,9 +11,9 @@
           v-btn(outline, color='grey', @click='refresh', large)
             v-icon refresh
           v-btn(color='black', dark, depressed, @click='toggleConsole', large)
-            v-icon(left) keyboard
-            span View Console
-          v-btn(color='primary', @click='save', depressed, large)
+            ConsoleLineIcon.mr-3
+            span Live Trail
+          v-btn.mr-0(color='primary', @click='save', depressed, large)
             v-icon(left) chevron_right
             span Apply Configuration
 
@@ -112,9 +112,12 @@ import LoggingConsole from './admin-logging-console.vue'
 import loggersQuery from 'gql/admin/logging/logging-query-loggers.gql'
 import loggersSaveMutation from 'gql/admin/logging/logging-mutation-save-loggers.gql'
 
+import ConsoleLineIcon from 'mdi/ConsoleLine'
+
 export default {
   components: {
-    LoggingConsole
+    LoggingConsole,
+    ConsoleLineIcon
   },
   data() {
     return {
@@ -147,7 +150,7 @@ export default {
             'key',
             'config',
             'level'
-          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: cfg.value.value}))}))
+          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.stringify({ v: cfg.value.value })}))}))
         }
       })
       this.$store.commit('showNotification', {
@@ -156,6 +159,9 @@ export default {
         icon: 'check'
       })
       this.$store.commit(`loadingStop`, 'admin-logging-saveloggers')
+    },
+    toggleConsole() {
+      this.showConsole = !this.showConsole
     }
   },
   apollo: {

+ 1 - 1
client/components/admin/admin-search.vue

@@ -133,7 +133,7 @@ export default {
             'isEnabled',
             'key',
             'config'
-          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: cfg.value.value}))}))
+          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.stringify({ v: cfg.value.value })}))}))
         }
       })
       this.$store.commit('showNotification', {

+ 1 - 1
client/components/admin/admin-storage.vue

@@ -148,7 +148,7 @@ export default {
             'key',
             'config',
             'mode'
-          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: cfg.value.value}))}))
+          ])).map(str => ({...str, config: str.config.map(cfg => ({...cfg, value: JSON.stringify({ v: cfg.value.value })}))}))
         }
       })
       this.$store.commit('showNotification', {

+ 7 - 0
client/graph/admin/logging/logging-subscription-livetrail.gql

@@ -0,0 +1,7 @@
+subscription {
+  loggingLiveTrail {
+    level
+    output
+    timestamp
+  }
+}

+ 4 - 0
package.json

@@ -74,6 +74,7 @@
     "getos": "3.1.0",
     "graphql": "14.0.2",
     "graphql-list-fields": "2.0.2",
+    "graphql-subscriptions": "1.0.0",
     "graphql-tools": "4.0.0",
     "highlight.js": "9.12.0",
     "i18next": "11.9.0",
@@ -147,6 +148,7 @@
     "semver": "5.5.1",
     "serve-favicon": "2.5.0",
     "sqlite3": "4.0.2",
+    "subscriptions-transport-ws": "0.9.15",
     "uslug": "1.0.4",
     "uuid": "3.3.2",
     "validator": "10.8.0",
@@ -179,6 +181,8 @@
     "apollo-link-error": "1.1.1",
     "apollo-link-http": "1.5.5",
     "apollo-link-persisted-queries": "0.2.1",
+    "apollo-link-ws": "1.0.9",
+    "apollo-utilities": "1.0.21",
     "autoprefixer": "9.1.5",
     "babel-eslint": "10.0.1",
     "babel-jest": "23.6.0",

+ 26 - 4
server/graph/index.js

@@ -3,11 +3,18 @@ const fs = require('fs')
 // const gqlTools = require('graphql-tools')
 const path = require('path')
 const autoload = require('auto-load')
+const PubSub = require('graphql-subscriptions').PubSub
+const util = require('util')
+const winston = require('winston')
 
 /* global WIKI */
 
 WIKI.logger.info(`Loading GraphQL Schema...`)
 
+// Init Subscription PubSub
+
+WIKI.GQLEmitter = new PubSub()
+
 // Schemas
 
 let typeDefs = []
@@ -24,10 +31,25 @@ resolversObj.forEach(resolver => {
   _.merge(resolvers, resolver)
 })
 
-// const Schema = gqlTools.makeExecutableSchema({
-//   typeDefs,
-//   resolvers
-// })
+// Live Trail Logger (admin)
+
+let LiveTrailLogger = winston.transports.LiveTrailLogger = function (options) {
+  this.name = 'livetrailLogger'
+  this.level = 'debug'
+}
+util.inherits(LiveTrailLogger, winston.Transport)
+LiveTrailLogger.prototype.log = function (level, msg, meta, callback) {
+  WIKI.GQLEmitter.publish('livetrail', {
+    loggingLiveTrail: {
+      timestamp: new Date(),
+      level,
+      output: msg
+    }
+  })
+  callback(null, true)
+}
+
+WIKI.logger.add(new LiveTrailLogger({}))
 
 WIKI.logger.info(`GraphQL Schema: [ OK ]`)
 

+ 1 - 1
server/graph/resolvers/authentication.js

@@ -68,7 +68,7 @@ module.exports = {
           await WIKI.models.authentication.query().patch({
             isEnabled: str.isEnabled,
             config: _.reduce(str.config, (result, value, key) => {
-              _.set(result, `${value.key}.value`, value.value)
+              _.set(result, `${value.key}`, _.get(JSON.parse(value.value), 'v', null))
               return result
             }, {}),
             selfRegistration: str.selfRegistration,

+ 5 - 0
server/graph/resolvers/logging.js

@@ -10,6 +10,11 @@ module.exports = {
   Mutation: {
     async logging() { return {} }
   },
+  Subscription: {
+    loggingLiveTrail: {
+      subscribe: () => WIKI.GQLEmitter.asyncIterator('livetrail')
+    }
+  },
   LoggingQuery: {
     async loggers(obj, args, context, info) {
       let loggers = await WIKI.models.loggers.getLoggers()

+ 1 - 1
server/graph/resolvers/search.js

@@ -42,7 +42,7 @@ module.exports = {
           await WIKI.models.searchEngines.query().patch({
             isEnabled: searchEngine.isEnabled,
             config: _.reduce(searchEngine.config, (result, value, key) => {
-              _.set(result, `${value.key}`, value.value)
+              _.set(result, `${value.key}`, _.get(JSON.parse(value.value), 'v', null))
               return result
             }, {})
           }).where('key', searchEngine.key)

+ 1 - 1
server/graph/resolvers/storage.js

@@ -43,7 +43,7 @@ module.exports = {
             isEnabled: tgt.isEnabled,
             mode: tgt.mode,
             config: _.reduce(tgt.config, (result, value, key) => {
-              _.set(result, `${value.key}`, value.value)
+              _.set(result, `${value.key}`, _.get(JSON.parse(value.value), 'v', null))
               return result
             }, {})
           }).where('key', tgt.key)

+ 2 - 0
server/graph/schemas/common.graphql

@@ -250,3 +250,5 @@ type Mutation {
     filename: String!
   ): File
 }
+
+type Subscription

+ 10 - 0
server/graph/schemas/logging.graphql

@@ -10,6 +10,10 @@ extend type Mutation {
   logging: LoggingMutation
 }
 
+extend type Subscription {
+  loggingLiveTrail: LoggerTrailLine
+}
+
 # -----------------------------------------------
 # QUERIES
 # -----------------------------------------------
@@ -52,3 +56,9 @@ input LoggerInput {
   level: String!
   config: [KeyValuePairInput]
 }
+
+type LoggerTrailLine {
+  level: String!
+  output: String!
+  timestamp: Date!
+}

+ 8 - 1
server/master.js

@@ -129,7 +129,13 @@ module.exports = async () => {
   const graphqlSchema = require('./graph')
   const apolloServer = new ApolloServer({
     ...graphqlSchema,
-    context: ({ req, res }) => ({ req, res })
+    context: ({ req, res }) => ({ req, res }),
+    subscriptions: {
+      onConnect: (connectionParams, webSocket) => {
+
+      },
+      path: '/graphql-subscriptions'
+    }
   })
   apolloServer.applyMiddleware({ app })
 
@@ -169,6 +175,7 @@ module.exports = async () => {
 
   app.set('port', WIKI.config.port)
   WIKI.server = http.createServer(app)
+  apolloServer.installSubscriptionHandlers(WIKI.server)
 
   WIKI.server.listen(WIKI.config.port, WIKI.config.bindIP)
   WIKI.server.on('error', (error) => {

+ 13 - 13
yarn.lock

@@ -1755,7 +1755,7 @@ apollo-link-state@^0.4.2:
     apollo-utilities "^1.0.8"
     graphql-anywhere "^4.1.0-alpha.0"
 
-apollo-link-ws@^1.0.9:
+apollo-link-ws@1.0.9, apollo-link-ws@^1.0.9:
   version "1.0.9"
   resolved "https://registry.yarnpkg.com/apollo-link-ws/-/apollo-link-ws-1.0.9.tgz#e2198abd6d3900e83fd842fdee335a28b347ea2d"
   dependencies:
@@ -5719,15 +5719,15 @@ graphql-request@^1.5.0:
   dependencies:
     cross-fetch "2.2.2"
 
-graphql-subscriptions@^0.5.8:
-  version "0.5.8"
-  resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7"
+graphql-subscriptions@1.0.0, graphql-subscriptions@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8"
   dependencies:
     iterall "^1.2.1"
 
-graphql-subscriptions@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8"
+graphql-subscriptions@^0.5.8:
+  version "0.5.8"
+  resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz#13a6143c546bce390404657dc73ca501def30aa7"
   dependencies:
     iterall "^1.2.1"
 
@@ -12040,9 +12040,9 @@ stylus@0.54.5:
     sax "0.5.x"
     source-map "0.1.x"
 
-subscriptions-transport-ws@^0.9.11:
-  version "0.9.12"
-  resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.12.tgz#0deb945134890d8694a93a090bacc6459c4478cc"
+subscriptions-transport-ws@0.9.15, subscriptions-transport-ws@^0.9.15:
+  version "0.9.15"
+  resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d"
   dependencies:
     backo2 "^1.0.2"
     eventemitter3 "^3.1.0"
@@ -12050,9 +12050,9 @@ subscriptions-transport-ws@^0.9.11:
     symbol-observable "^1.0.4"
     ws "^5.2.0"
 
-subscriptions-transport-ws@^0.9.15:
-  version "0.9.15"
-  resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d"
+subscriptions-transport-ws@^0.9.11:
+  version "0.9.12"
+  resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.12.tgz#0deb945134890d8694a93a090bacc6459c4478cc"
   dependencies:
     backo2 "^1.0.2"
     eventemitter3 "^3.1.0"