瀏覽代碼

feat: gitlab auth module + storage locale namespacing fix

NGPixel 6 年之前
父節點
當前提交
4e990d50eb

+ 1 - 1
client/components/editor.vue

@@ -267,7 +267,7 @@ export default {
         if (this.$store.get('editor/mode') === 'create') {
           window.location.assign(`/`)
         } else {
-          window.location.assign(`/${this.$store.get('page/path')}`)
+          window.location.assign(`/${this.$store.get('page/locale')}/${this.$store.get('page/path')}`)
         }
       }, 500)
     }

+ 1 - 0
client/static/svg/auth-icon-gitlab.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 2500 2305" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><path d="M1250.72,2305.57l-1209.86,-879.014c-33.288,-24.189 -47.306,-67.341 -34.589,-106.475l139.78,-430.219l-0.005,-0.005l0.01,-0.01l-0.005,0.015l1104.67,1415.7l-0.006,-0.017l-1104.65,-1415.68l-0.007,0l0.002,-0.007l-0.002,-0.003l0.003,0l277.047,-852.676c14.249,-43.867 76.319,-43.877 90.577,0l277.037,852.676l0.004,0l0.003,0.01l920.003,0l0.003,-0.01l0.004,0l277.047,-852.676c14.258,-43.877 76.328,-43.867 90.576,0l277.048,852.676l0.003,0l-0.002,0.003l0.002,0.007l-0.007,0l-1104.66,1415.68l-0.013,0.038l1104.68,-1415.72l0,-0.01l139.785,430.234c12.715,39.136 -1.308,82.289 -34.599,106.475l-1209.86,879.023l-0.009,0l-0.003,-0.009Z" style="fill:#fff;fill-rule:nonzero;"/></svg>

+ 1 - 0
package.json

@@ -123,6 +123,7 @@
     "passport-dropbox-oauth2": "1.1.0",
     "passport-facebook": "3.0.0",
     "passport-github2": "0.1.11",
+    "passport-gitlab2": "5.0.0",
     "passport-google-oauth20": "2.0.0",
     "passport-jwt": "4.0.0",
     "passport-ldapauth": "2.1.3",

+ 9 - 7
server/graph/resolvers/authentication.js

@@ -21,14 +21,16 @@ module.exports = {
           ...strategyInfo,
           ...stg,
           config: _.sortBy(_.transform(stg.config, (res, value, key) => {
-            const configData = _.get(strategyInfo.props, key, {})
-            res.push({
-              key,
-              value: JSON.stringify({
-                ...configData,
-                value
+            const configData = _.get(strategyInfo.props, key, false)
+            if (configData) {
+              res.push({
+                key,
+                value: JSON.stringify({
+                  ...configData,
+                  value
+                })
               })
-            })
+            }
           }, []), 'key')
         }
       })

+ 9 - 7
server/graph/resolvers/storage.js

@@ -22,14 +22,16 @@ module.exports = {
           syncInterval: targetInfo.syncInterval || targetInfo.schedule || 'P0D',
           syncIntervalDefault: targetInfo.schedule,
           config: _.sortBy(_.transform(tgt.config, (res, value, key) => {
-            const configData = _.get(targetInfo.props, key, {})
-            res.push({
-              key,
-              value: JSON.stringify({
-                ...configData,
-                value
+            const configData = _.get(targetInfo.props, key, false)
+            if (configData) {
+              res.push({
+                key,
+                value: JSON.stringify({
+                  ...configData,
+                  value
+                })
               })
-            })
+            }
           }, []), 'key')
         }
       })

+ 34 - 0
server/modules/authentication/gitlab/authentication.js

@@ -0,0 +1,34 @@
+/* global WIKI */
+
+// ------------------------------------
+// GitLab Account
+// ------------------------------------
+
+const GitLabStrategy = require('passport-gitlab2').Strategy
+const _ = require('lodash')
+
+module.exports = {
+  init (passport, conf) {
+    passport.use('gitlab',
+      new GitLabStrategy({
+        clientID: conf.clientId,
+        clientSecret: conf.clientSecret,
+        callbackURL: conf.callbackURL,
+        scope: ['read_user']
+      }, async (accessToken, refreshToken, profile, cb) => {
+        try {
+          const user = await WIKI.models.users.processProfile({
+            profile: {
+              ...profile,
+              picture: _.get(profile, 'avatarUrl', '')
+            },
+            providerKey: 'gitlab'
+          })
+          cb(null, user)
+        } catch (err) {
+          cb(err, null)
+        }
+      }
+      ))
+  }
+}

+ 26 - 0
server/modules/authentication/gitlab/definition.yml

@@ -0,0 +1,26 @@
+key: gitlab
+title: GitLab
+description: GitLab is a web-based DevOps lifecycle tool that provides a Git-repository manager providing wiki, issue-tracking and CI/CD pipeline features.
+author: requarks.io
+logo: https://static.requarks.io/logo/gitlab.svg
+color: deep-orange
+website: https://gitlab.com
+isAvailable: true
+useForm: false
+props:
+  clientId:
+    type: String
+    title: Client ID
+    hint: Application Client ID
+    order: 1
+  clientSecret:
+    type: String
+    title: Client Secret
+    hint: Application Client Secret
+    order: 2
+  baseUrl:
+    type: String
+    title: Base URL
+    hint: For self-managed GitLab instances, define the base URL (e.g. https://gitlab.example.com). Leave default for GitLab.com SaaS (https://gitlab.com).
+    default: https://gitlab.com
+    order: 3

+ 29 - 3
server/modules/storage/digitalocean/definition.yml

@@ -4,10 +4,36 @@ description: DigitalOcean provides developers and businesses a reliable, easy-to
 author: requarks.io
 logo: https://static.requarks.io/logo/digitalocean.svg
 website: https://www.digitalocean.com/products/spaces/
+isAvailable: false
+supportedModes:
+  - push
+defaultMode: push
+schedule: false
 props:
-  accessKeyId: String
-  accessSecret: String
   region:
     type: String
+    title: Region
+    hint: The DigitalOcean datacenter region where the Space will be created.
     default: nyc3
-  bucket: String
+    enum:
+      - ams3
+      - fra1
+      - nyc3
+      - sfo2
+      - sgp1
+    order: 1
+  spaceId:
+    type: String
+    title: Space Unique Name
+    hint: The unique space name to create (e.g. wiki-johndoe)
+    order: 2
+  accessKeyId:
+    type: String
+    title: Access Key ID
+    hint: The Access Key (Generated in API > Tokens/Keys > Spaces access keys).
+    order: 3
+  secretAccessKey :
+    type: String
+    title: Access Key Secret
+    hint: The Access Key Secret for the Access Key ID you created above.
+    order: 4

+ 27 - 7
server/modules/storage/disk/storage.js

@@ -59,24 +59,41 @@ module.exports = {
   },
   async created(page) {
     WIKI.logger.info(`(STORAGE/DISK) Creating file ${page.path}...`)
-    const filePath = path.join(this.config.path, `${page.path}.${getFileExtension(page.contentType)}`)
+    let fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      fileName = `${page.localeCode}/${fileName}`
+    }
+    const filePath = path.join(this.config.path, fileName)
     await fs.outputFile(filePath, page.injectMetadata(), 'utf8')
   },
   async updated(page) {
     WIKI.logger.info(`(STORAGE/DISK) Updating file ${page.path}...`)
-    const filePath = path.join(this.config.path, `${page.path}.${getFileExtension(page.contentType)}`)
+    let fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      fileName = `${page.localeCode}/${fileName}`
+    }
+    const filePath = path.join(this.config.path, fileName)
     await fs.outputFile(filePath, page.injectMetadata(), 'utf8')
   },
   async deleted(page) {
     WIKI.logger.info(`(STORAGE/DISK) Deleting file ${page.path}...`)
-    const filePath = path.join(this.config.path, `${page.path}.${getFileExtension(page.contentType)}`)
+    let fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      fileName = `${page.localeCode}/${fileName}`
+    }
+    const filePath = path.join(this.config.path, fileName)
     await fs.unlink(filePath)
   },
   async renamed(page) {
     WIKI.logger.info(`(STORAGE/DISK) Renaming file ${page.sourcePath} to ${page.destinationPath}...`)
-    const sourceFilePath = path.join(this.config.path, `${page.sourcePath}.${getFileExtension(page.contentType)}`)
-    const destinationFilePath = path.join(this.config.path, `${page.destinationPath}.${getFileExtension(page.contentType)}`)
-    await fs.move(sourceFilePath, destinationFilePath, { overwrite: true })
+    let sourceFilePath = `${page.sourcePath}.${getFileExtension(page.contentType)}`
+    let destinationFilePath = `${page.destinationPath}.${getFileExtension(page.contentType)}`
+
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      sourceFilePath = `${page.localeCode}/${sourceFilePath}`
+      destinationFilePath = `${page.localeCode}/${destinationFilePath}`
+    }
+    await fs.move(path.join(this.config.path, sourceFilePath), path.join(this.config.path, destinationFilePath), { overwrite: true })
   },
 
   /**
@@ -91,7 +108,10 @@ module.exports = {
       new stream.Transform({
         objectMode: true,
         transform: async (page, enc, cb) => {
-          const fileName = `${page.path}.${getFileExtension(page.contentType)}`
+          let fileName = `${page.path}.${getFileExtension(page.contentType)}`
+          if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+            fileName = `${page.localeCode}/${fileName}`
+          }
           WIKI.logger.info(`(STORAGE/DISK) Dumping ${fileName}...`)
           const filePath = path.join(this.config.path, fileName)
           await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8')

+ 22 - 5
server/modules/storage/git/storage.js

@@ -244,7 +244,10 @@ module.exports = {
    */
   async created(page) {
     WIKI.logger.info(`(STORAGE/GIT) Committing new file ${page.path}...`)
-    const fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    let fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      fileName = `${page.localeCode}/${fileName}`
+    }
     const filePath = path.join(this.repoPath, fileName)
     await fs.outputFile(filePath, page.injectMetadata(), 'utf8')
 
@@ -260,7 +263,10 @@ module.exports = {
    */
   async updated(page) {
     WIKI.logger.info(`(STORAGE/GIT) Committing updated file ${page.path}...`)
-    const fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    let fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      fileName = `${page.localeCode}/${fileName}`
+    }
     const filePath = path.join(this.repoPath, fileName)
     await fs.outputFile(filePath, page.injectMetadata(), 'utf8')
 
@@ -276,7 +282,10 @@ module.exports = {
    */
   async deleted(page) {
     WIKI.logger.info(`(STORAGE/GIT) Committing removed file ${page.path}...`)
-    const fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    let fileName = `${page.path}.${getFileExtension(page.contentType)}`
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      fileName = `${page.localeCode}/${fileName}`
+    }
 
     await this.git.rm(`./${fileName}`)
     await this.git.commit(`docs: delete ${page.path}`, fileName, {
@@ -290,8 +299,13 @@ module.exports = {
    */
   async renamed(page) {
     WIKI.logger.info(`(STORAGE/GIT) Committing file move from ${page.sourcePath} to ${page.destinationPath}...`)
-    const sourceFilePath = `${page.sourcePath}.${getFileExtension(page.contentType)}`
-    const destinationFilePath = `${page.destinationPath}.${getFileExtension(page.contentType)}`
+    let sourceFilePath = `${page.sourcePath}.${getFileExtension(page.contentType)}`
+    let destinationFilePath = `${page.destinationPath}.${getFileExtension(page.contentType)}`
+
+    if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+      sourceFilePath = `${page.localeCode}/${sourceFilePath}`
+      destinationFilePath = `${page.localeCode}/${destinationFilePath}`
+    }
 
     await this.git.mv(`./${sourceFilePath}`, `./${destinationFilePath}`)
     await this.git.commit(`docs: rename ${page.sourcePath} to ${destinationFilePath}`, destinationFilePath, {
@@ -338,6 +352,9 @@ module.exports = {
         objectMode: true,
         transform: async (page, enc, cb) => {
           const fileName = `${page.path}.${getFileExtension(page.contentType)}`
+          if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
+            fileName = `${page.localeCode}/${fileName}`
+          }
           WIKI.logger.info(`(STORAGE/GIT) Adding ${fileName}...`)
           const filePath = path.join(this.repoPath, fileName)
           await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8')

+ 36 - 9
yarn.lock

@@ -3888,7 +3888,7 @@ consolidate@^0.15.1:
   dependencies:
     bluebird "^3.1.1"
 
-constantinople@^3.0.1, constantinople@^3.1.2:
+constantinople@^3.0.1, constantinople@^3.0.2, constantinople@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.2.tgz#d45ed724f57d3d10500017a7d3a889c1381ae647"
   integrity sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==
@@ -6690,10 +6690,15 @@ html-webpack-plugin@3.2.0:
     toposort "^1.0.0"
     util.promisify "1.0.0"
 
-html-webpack-pug-plugin@0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/html-webpack-pug-plugin/-/html-webpack-pug-plugin-0.3.0.tgz#83e96e05c2b48b498d411a6a26f482508b52c885"
-  integrity sha512-84A4BCrgMdIaOwkhXbBqZOMwRnU937xI+cVE2GykQXi4CNg6AUp6AMet5ruhTfXJs7+xJ/b7jOSpc1/kF4ukMA==
+html-webpack-pug-plugin@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/html-webpack-pug-plugin/-/html-webpack-pug-plugin-2.0.0.tgz#875773ded14f7857b60e81f6a393588ce3deb367"
+  integrity sha512-4RZIZGIuIJBb44jFpeNuXyQQ7degfyl70rIzgOyOhYAh6hWfvYHQCLXUL/u5V9HUtp8Ai4P4CGQp8VZdYQBXmg==
+  dependencies:
+    pug-lexer "^4.0.0"
+    pug-parser "^5.0.0"
+    pug-source-gen "0.0.2"
+    pug-walk "^1.1.7"
 
 htmlparser2@^3.9.1:
   version "3.10.0"
@@ -9721,6 +9726,13 @@ passport-github2@0.1.11:
   dependencies:
     passport-oauth2 "1.x.x"
 
+passport-gitlab2@5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/passport-gitlab2/-/passport-gitlab2-5.0.0.tgz#ea37e5285321c026a02671e87469cac28cce9b69"
+  integrity sha512-cXQMgM6JQx9wHVh7JLH30D8fplfwjsDwRz+zS0pqC8JS+4bNmc1J04NGp5g2M4yfwylH9kQRrMN98GxMw7q7cg==
+  dependencies:
+    passport-oauth2 "^1.4.0"
+
 passport-google-oauth20@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef"
@@ -9779,7 +9791,7 @@ passport-oauth2@1.2.0:
     passport-strategy "1.x.x"
     uid2 "0.0.x"
 
-passport-oauth2@1.5.0, passport-oauth2@^1.3.0:
+passport-oauth2@1.5.0, passport-oauth2@^1.3.0, passport-oauth2@^1.4.0:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.5.0.tgz#64babbb54ac46a4dcab35e7f266ed5294e3c4108"
   integrity sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==
@@ -11496,7 +11508,7 @@ pug-lexer@^2.0.1:
     is-expression "^3.0.0"
     pug-error "^1.3.2"
 
-pug-lexer@^4.1.0:
+pug-lexer@^4.0.0, pug-lexer@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-4.1.0.tgz#531cde48c7c0b1fcbbc2b85485c8665e31489cfd"
   integrity sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==
@@ -11549,7 +11561,7 @@ pug-loader@2.4.0:
     pug-walk "^1.0.0"
     resolve "^1.1.7"
 
-pug-parser@^5.0.1:
+pug-parser@^5.0.0, pug-parser@^5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-5.0.1.tgz#03e7ada48b6840bd3822f867d7d90f842d0ffdc9"
   integrity sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==
@@ -11574,6 +11586,16 @@ pug-runtime@^2.0.5:
   resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.5.tgz#6da7976c36bf22f68e733c359240d8ae7a32953a"
   integrity sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==
 
+pug-source-gen@0.0.2:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/pug-source-gen/-/pug-source-gen-0.0.2.tgz#76d7753d89693c6846578c80da1628b8c6fc6fdb"
+  integrity sha1-dtd1PYlpPGhGV4yA2hYouMb8b9s=
+  dependencies:
+    constantinople "^3.0.2"
+    object-assign "^4.0.1"
+    pug-walk "0.0.3"
+    repeat-string "^1.5.2"
+
 pug-strip-comments@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz#cc1b6de1f6e8f5931cf02ec66cdffd3f50eaf8a8"
@@ -11581,12 +11603,17 @@ pug-strip-comments@^1.0.4:
   dependencies:
     pug-error "^1.3.3"
 
+pug-walk@0.0.3:
+  version "0.0.3"
+  resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-0.0.3.tgz#c28be7bcc540f24b83d274472410827c84e31ac6"
+  integrity sha1-wovnvMVA8kuD0nRHJBCCfITjGsY=
+
 pug-walk@^1.0.0:
   version "1.1.7"
   resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.7.tgz#c00d5c5128bac5806bec15d2b7e7cdabe42531f3"
   integrity sha1-wA1cUSi6xYBr7BXSt+fNq+QlMfM=
 
-pug-walk@^1.1.8:
+pug-walk@^1.1.7, pug-walk@^1.1.8:
   version "1.1.8"
   resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.8.tgz#b408f67f27912f8c21da2f45b7230c4bd2a5ea7a"
   integrity sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==