From b78026e49ff05f9462016657138f984cc96211c4 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Thu, 9 Jun 2022 14:25:01 -0400 Subject: [PATCH 001/164] fix(auth): handle null SAML authnContext context --- server/modules/authentication/saml/authentication.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/modules/authentication/saml/authentication.js b/server/modules/authentication/saml/authentication.js index e1c75d154a..6eeef27a80 100644 --- a/server/modules/authentication/saml/authentication.js +++ b/server/modules/authentication/saml/authentication.js @@ -14,14 +14,14 @@ module.exports = { callbackUrl: conf.callbackURL, entryPoint: conf.entryPoint, issuer: conf.issuer, - cert: _.split(conf.cert || '', '|'), + cert: (conf.cert || '').split('|'), signatureAlgorithm: conf.signatureAlgorithm, digestAlgorithm: conf.digestAlgorithm, identifierFormat: conf.identifierFormat, wantAssertionsSigned: conf.wantAssertionsSigned, acceptedClockSkewMs: _.toSafeInteger(conf.acceptedClockSkewMs), disableRequestedAuthnContext: conf.disableRequestedAuthnContext, - authnContext: _.split(conf.authnContext, '|'), + authnContext: (conf.authnContext || '').split('|'), racComparison: conf.racComparison, forceAuthn: conf.forceAuthn, passive: conf.passive, From 97a744556b8afa8687f9fcf1efea410a74d70217 Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Sat, 11 Jun 2022 04:15:00 +0100 Subject: [PATCH 002/164] feat(mail): allow setting of mailer identifying name (#5363) --- client/components/admin/admin-mail.vue | 12 ++++++++++++ .../graph/admin/mail/mail-mutation-save-config.gql | 1 + client/graph/admin/mail/mail-query-config.gql | 1 + server/core/mail.js | 1 + server/graph/resolvers/mail.js | 1 + server/graph/schemas/mail.graphql | 2 ++ server/setup.js | 1 + 7 files changed, 19 insertions(+) diff --git a/client/components/admin/admin-mail.vue b/client/components/admin/admin-mail.vue index 660660f946..49b467899f 100644 --- a/client/components/admin/admin-mail.vue +++ b/client/components/admin/admin-mail.vue @@ -57,6 +57,16 @@ :hint='$t(`admin:mail.smtpPortHint`)' style='max-width: 300px;' ) + v-text-field( + outlined + v-model='config.name' + :label='$t(`admin:mail.smtpName`)' + required + :counter='255' + prepend-icon='mdi-server' + persistent-hint + :hint='$t(`admin:mail.smtpNameHint`)' + ) v-switch( v-model='config.secure' :label='$t(`admin:mail.smtpTLS`)' @@ -169,6 +179,7 @@ export default { senderEmail: '', host: '', port: 0, + name: '', secure: false, verifySSL: false, user: '', @@ -192,6 +203,7 @@ export default { senderEmail: this.config.senderEmail || '', host: this.config.host || '', port: _.toSafeInteger(this.config.port) || 0, + namer: this.config.name || '', secure: this.config.secure || false, verifySSL: this.config.verifySSL || false, user: this.config.user || '', diff --git a/client/graph/admin/mail/mail-mutation-save-config.gql b/client/graph/admin/mail/mail-mutation-save-config.gql index 3b8f699936..6b49ad2e33 100644 --- a/client/graph/admin/mail/mail-mutation-save-config.gql +++ b/client/graph/admin/mail/mail-mutation-save-config.gql @@ -18,6 +18,7 @@ mutation ( senderEmail: $senderEmail, host: $host, port: $port, + name: $name, secure: $secure, verifySSL: $verifySSL, user: $user, diff --git a/client/graph/admin/mail/mail-query-config.gql b/client/graph/admin/mail/mail-query-config.gql index 66232acbdd..5d7091aa6a 100644 --- a/client/graph/admin/mail/mail-query-config.gql +++ b/client/graph/admin/mail/mail-query-config.gql @@ -5,6 +5,7 @@ senderEmail host port + name secure verifySSL user diff --git a/server/core/mail.js b/server/core/mail.js index 9dad973a9d..4af28b6598 100644 --- a/server/core/mail.js +++ b/server/core/mail.js @@ -13,6 +13,7 @@ module.exports = { let conf = { host: WIKI.config.mail.host, port: WIKI.config.mail.port, + name: WIKI.config.mail.name, secure: WIKI.config.mail.secure, tls: { rejectUnauthorized: !(WIKI.config.mail.verifySSL === false) diff --git a/server/graph/resolvers/mail.js b/server/graph/resolvers/mail.js index d7e8739732..7305e68633 100644 --- a/server/graph/resolvers/mail.js +++ b/server/graph/resolvers/mail.js @@ -49,6 +49,7 @@ module.exports = { senderEmail: args.senderEmail, host: args.host, port: args.port, + name: args.name, secure: args.secure, verifySSL: args.verifySSL, user: args.user, diff --git a/server/graph/schemas/mail.graphql b/server/graph/schemas/mail.graphql index f935c5ac25..d9741d82bb 100644 --- a/server/graph/schemas/mail.graphql +++ b/server/graph/schemas/mail.graphql @@ -32,6 +32,7 @@ type MailMutation { senderEmail: String! host: String! port: Int! + name: String! secure: Boolean! verifySSL: Boolean! user: String! @@ -52,6 +53,7 @@ type MailConfig { senderEmail: String! host: String! port: Int! + name: String! secure: Boolean! verifySSL: Boolean! user: String! diff --git a/server/setup.js b/server/setup.js index 6d87a29f26..44da308b61 100644 --- a/server/setup.js +++ b/server/setup.js @@ -103,6 +103,7 @@ module.exports = () => { senderEmail: '', host: '', port: 465, + name: '', secure: true, verifySSL: true, user: '', From 046e4b98cb302d3d92974173e1e544d384eac7d7 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sat, 11 Jun 2022 17:24:53 -0400 Subject: [PATCH 003/164] fix(graphql): remove required flag on MailConfig schema --- server/graph/schemas/mail.graphql | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/server/graph/schemas/mail.graphql b/server/graph/schemas/mail.graphql index d9741d82bb..eed57c8868 100644 --- a/server/graph/schemas/mail.graphql +++ b/server/graph/schemas/mail.graphql @@ -49,17 +49,17 @@ type MailMutation { # ----------------------------------------------- type MailConfig { - senderName: String! - senderEmail: String! - host: String! - port: Int! - name: String! - secure: Boolean! - verifySSL: Boolean! - user: String! - pass: String! - useDKIM: Boolean! - dkimDomainName: String! - dkimKeySelector: String! - dkimPrivateKey: String! + senderName: String + senderEmail: String + host: String + port: Int + name: String + secure: Boolean + verifySSL: Boolean + user: String + pass: String + useDKIM: Boolean + dkimDomainName: String + dkimKeySelector: String + dkimPrivateKey: String } From 1e577735c4a87d12edf09093652e6ecf497905a2 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sat, 11 Jun 2022 17:40:48 -0400 Subject: [PATCH 004/164] fix(mail): typo in admin mail save mutation --- client/components/admin/admin-mail.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/admin/admin-mail.vue b/client/components/admin/admin-mail.vue index 49b467899f..4db028af80 100644 --- a/client/components/admin/admin-mail.vue +++ b/client/components/admin/admin-mail.vue @@ -203,7 +203,7 @@ export default { senderEmail: this.config.senderEmail || '', host: this.config.host || '', port: _.toSafeInteger(this.config.port) || 0, - namer: this.config.name || '', + name: this.config.name || '', secure: this.config.secure || false, verifySSL: this.config.verifySSL || false, user: this.config.user || '', From 18f91659454cba8ea6bf7c8332cd4fc54b233b35 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sat, 11 Jun 2022 17:55:16 -0400 Subject: [PATCH 005/164] fix(graphql): add missing admin mail name variable to save mutation --- .../admin/mail/mail-mutation-save-config.gql | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/client/graph/admin/mail/mail-mutation-save-config.gql b/client/graph/admin/mail/mail-mutation-save-config.gql index 6b49ad2e33..611a1c0a65 100644 --- a/client/graph/admin/mail/mail-mutation-save-config.gql +++ b/client/graph/admin/mail/mail-mutation-save-config.gql @@ -1,31 +1,32 @@ mutation ( - $senderName: String!, - $senderEmail: String!, - $host: String!, - $port: Int!, - $secure: Boolean!, - $verifySSL: Boolean!, - $user: String!, - $pass: String!, - $useDKIM: Boolean!, - $dkimDomainName: String!, - $dkimKeySelector: String!, + $senderName: String! + $senderEmail: String! + $host: String! + $port: Int! + $name: String! + $secure: Boolean! + $verifySSL: Boolean! + $user: String! + $pass: String! + $useDKIM: Boolean! + $dkimDomainName: String! + $dkimKeySelector: String! $dkimPrivateKey: String! ) { mail { updateConfig( - senderName: $senderName, - senderEmail: $senderEmail, - host: $host, - port: $port, - name: $name, - secure: $secure, - verifySSL: $verifySSL, - user: $user, - pass: $pass, - useDKIM: $useDKIM, - dkimDomainName: $dkimDomainName, - dkimKeySelector: $dkimKeySelector, + senderName: $senderName + senderEmail: $senderEmail + host: $host + port: $port + name: $name + secure: $secure + verifySSL: $verifySSL + user: $user + pass: $pass + useDKIM: $useDKIM + dkimDomainName: $dkimDomainName + dkimKeySelector: $dkimKeySelector dkimPrivateKey: $dkimPrivateKey ) { responseResult { From 0425b82c833aeaccd49532dd725602912b3c4346 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Fri, 17 Jun 2022 17:46:57 -0400 Subject: [PATCH 006/164] fix(kernel): handle SIGTERM graceful shutdown --- server/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/index.js b/server/index.js index 87eff16bfe..96f5e4a602 100644 --- a/server/index.js +++ b/server/index.js @@ -38,6 +38,9 @@ WIKI.kernel.init() // Register exit handler // ---------------------------------------- +process.on('SIGTERM', () => { + WIKI.kernel.shutdown() +}) process.on('SIGINT', () => { WIKI.kernel.shutdown() }) From 0a1bc707fb3bba3e10b3f11772e231b18ac77d70 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 19 Jun 2022 23:09:03 -0400 Subject: [PATCH 007/164] ci: add telegram notify to build release workflow --- .github/workflows/build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a5b6702ad2..a752e57491 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -358,6 +358,18 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + - name: Notify Telegram Channel + uses: appleboy/telegram-action@0.0.3 + with: + to: ${{ secrets.TELEGRAM_TO }} + token: ${{ secrets.TELEGRAM_TOKEN }} + format: markdown + message: | + Wiki.js **${{ github.ref_name }}** has been released! + + See [release notes](https://github.com/requarks/wiki/releases) for details. + build-do-image: name: Build DigitalOcean Image From 56457c858cc31b6cb13bb64bad2d56f83bba0fdd Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 19 Jun 2022 23:10:41 -0400 Subject: [PATCH 008/164] ci: add test telegram notify workflow --- .github/workflows/telegram.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/telegram.yml diff --git a/.github/workflows/telegram.yml b/.github/workflows/telegram.yml new file mode 100644 index 0000000000..e7463e5b36 --- /dev/null +++ b/.github/workflows/telegram.yml @@ -0,0 +1,18 @@ +name: Telegram Test +on: + workflow_dispatch: +jobs: + build: + runs-on: ubuntu-latest + steps: + + - name: Notify Telegram Channel + uses: appleboy/telegram-action@0.0.3 + with: + to: ${{ secrets.TELEGRAM_TO }} + token: ${{ secrets.TELEGRAM_TOKEN }} + format: markdown + message: | + Wiki.js **2.5.284** has been released! + + See [release notes](https://github.com/requarks/wiki/releases) for details. From 8609b3fc2fd716ec3ae1e911e2f1ab5fdecd7891 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 19 Jun 2022 23:15:52 -0400 Subject: [PATCH 009/164] ci: update test telegram workflow [skip ci] --- .github/workflows/telegram.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/telegram.yml b/.github/workflows/telegram.yml index e7463e5b36..86b87be393 100644 --- a/.github/workflows/telegram.yml +++ b/.github/workflows/telegram.yml @@ -7,7 +7,7 @@ jobs: steps: - name: Notify Telegram Channel - uses: appleboy/telegram-action@0.0.3 + uses: appleboy/telegram-action@v0.1.1 with: to: ${{ secrets.TELEGRAM_TO }} token: ${{ secrets.TELEGRAM_TOKEN }} From acf89cbcc27e0ee90adbf4e8a9cba02c9d68dc25 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 19 Jun 2022 23:21:16 -0400 Subject: [PATCH 010/164] ci: update test telegram workflow [skip ci] --- .github/workflows/telegram.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/telegram.yml b/.github/workflows/telegram.yml index 86b87be393..90dd771c5f 100644 --- a/.github/workflows/telegram.yml +++ b/.github/workflows/telegram.yml @@ -14,5 +14,4 @@ jobs: format: markdown message: | Wiki.js **2.5.284** has been released! - See [release notes](https://github.com/requarks/wiki/releases) for details. From c37c34ac129210103a1e1073fcf47b0b83d8b873 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 19 Jun 2022 23:27:35 -0400 Subject: [PATCH 011/164] ci: fix telegram notify on build release workflow --- .github/workflows/build.yml | 7 +++---- .github/workflows/telegram.yml | 17 ----------------- 2 files changed, 3 insertions(+), 21 deletions(-) delete mode 100644 .github/workflows/telegram.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a752e57491..ebb10de3c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -360,16 +360,15 @@ jobs: SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - name: Notify Telegram Channel - uses: appleboy/telegram-action@0.0.3 + uses: appleboy/telegram-action@v0.1.1 with: to: ${{ secrets.TELEGRAM_TO }} token: ${{ secrets.TELEGRAM_TOKEN }} format: markdown + disable_web_page_preview: true message: | - Wiki.js **${{ github.ref_name }}** has been released! - + Wiki.js *${{ github.ref_name }}* has been released! See [release notes](https://github.com/requarks/wiki/releases) for details. - build-do-image: name: Build DigitalOcean Image diff --git a/.github/workflows/telegram.yml b/.github/workflows/telegram.yml deleted file mode 100644 index 90dd771c5f..0000000000 --- a/.github/workflows/telegram.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Telegram Test -on: - workflow_dispatch: -jobs: - build: - runs-on: ubuntu-latest - steps: - - - name: Notify Telegram Channel - uses: appleboy/telegram-action@v0.1.1 - with: - to: ${{ secrets.TELEGRAM_TO }} - token: ${{ secrets.TELEGRAM_TOKEN }} - format: markdown - message: | - Wiki.js **2.5.284** has been released! - See [release notes](https://github.com/requarks/wiki/releases) for details. From a6d6deb2c91041e02a41b1305284c1c4b0e8827c Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 19 Jun 2022 23:34:54 -0400 Subject: [PATCH 012/164] docs: add telegram badge to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b1d5ac2448..4d4cb56df6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ [![GitHub Sponsors](https://img.shields.io/github/sponsors/ngpixel?logo=github&color=ea4aaa)](https://github.com/users/NGPixel/sponsorship) [![Open Collective backers and sponsors](https://img.shields.io/opencollective/all/wikijs?label=backers&color=218bff&logo=opencollective&logoColor=white)](https://opencollective.com/wikijs) [![Chat on Slack](https://img.shields.io/badge/slack-requarks-CC2B5E.svg?style=flat&logo=slack)](https://wiki.requarks.io/slack) -[![Twitter Follow](https://img.shields.io/badge/follow-%40requarks-blue.svg?style=flat&logo=twitter)](https://twitter.com/requarks) +[![Follow on Twitter](https://img.shields.io/badge/twitter-%40requarks-blue.svg?style=flat&logo=twitter)](https://twitter.com/requarks) +[![Follow on Telegram](https://img.shields.io/badge/telegram-%40wiki__js-blue.svg?style=flat&logo=telegram)](https://t.me/wiki_js) [![Reddit](https://img.shields.io/badge/reddit-%2Fr%2Fwikijs-orange?logo=reddit&logoColor=white)](https://www.reddit.com/r/wikijs/) [![Subscribe to Newsletter](https://img.shields.io/badge/newsletter-subscribe-yellow.svg?style=flat&logo=mailchimp)](https://blog.js.wiki/subscribe) From 81ad894ccdbf794598b0648fdc69acaf6e8630f6 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Thu, 23 Jun 2022 17:02:26 -0400 Subject: [PATCH 013/164] ci: add discord notification on release --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ebb10de3c7..d38dea8e6f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -369,6 +369,12 @@ jobs: message: | Wiki.js *${{ github.ref_name }}* has been released! See [release notes](https://github.com/requarks/wiki/releases) for details. + + - name: Notify Discord Channel + uses: sebastianpopp/discord-action@v1.0 + with: + webhook: ${{ secrets.DISCORD_WEBHOOK }} + message: Wiki.js ${{ github.ref_name }} has been released! See https://github.com/requarks/wiki/releases for details. build-do-image: name: Build DigitalOcean Image From e38b07067edabf82e403e2cc3a44e287a56523ab Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Fri, 24 Jun 2022 18:46:55 -0400 Subject: [PATCH 014/164] docs: update README with discord link --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4d4cb56df6..e04dc2d851 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,13 @@ [![Build + Publish](https://github.com/Requarks/wiki/actions/workflows/build.yml/badge.svg)](https://github.com/Requarks/wiki/actions/workflows/build.yml) [![Huntr](https://img.shields.io/badge/security%20bounty-disclose-brightgreen.svg?style=flat&logo=cachet&logoColor=white)](https://huntr.dev/bounties/disclose) [![GitHub Sponsors](https://img.shields.io/github/sponsors/ngpixel?logo=github&color=ea4aaa)](https://github.com/users/NGPixel/sponsorship) -[![Open Collective backers and sponsors](https://img.shields.io/opencollective/all/wikijs?label=backers&color=218bff&logo=opencollective&logoColor=white)](https://opencollective.com/wikijs) +[![Open Collective backers and sponsors](https://img.shields.io/opencollective/all/wikijs?label=backers&color=218bff&logo=opencollective&logoColor=white)](https://opencollective.com/wikijs) +[![Subscribe to Newsletter](https://img.shields.io/badge/newsletter-subscribe-yellow.svg?style=flat&logo=mailchimp&logoColor=white)](https://blog.js.wiki/subscribe) [![Chat on Slack](https://img.shields.io/badge/slack-requarks-CC2B5E.svg?style=flat&logo=slack)](https://wiki.requarks.io/slack) -[![Follow on Twitter](https://img.shields.io/badge/twitter-%40requarks-blue.svg?style=flat&logo=twitter)](https://twitter.com/requarks) +[![Follow on Twitter](https://img.shields.io/badge/twitter-%40requarks-blue.svg?style=flat&logo=twitter&logoColor=white)](https://twitter.com/requarks) [![Follow on Telegram](https://img.shields.io/badge/telegram-%40wiki__js-blue.svg?style=flat&logo=telegram)](https://t.me/wiki_js) +[![Chat on Discord](https://img.shields.io/badge/discord-join-8D96F6.svg?style=flat&logo=discord&logoColor=white)](https://discord.gg/rcxt9QS2jd) [![Reddit](https://img.shields.io/badge/reddit-%2Fr%2Fwikijs-orange?logo=reddit&logoColor=white)](https://www.reddit.com/r/wikijs/) -[![Subscribe to Newsletter](https://img.shields.io/badge/newsletter-subscribe-yellow.svg?style=flat&logo=mailchimp)](https://blog.js.wiki/subscribe) ##### A modern, lightweight and powerful wiki app built on NodeJS From 18ac9da4c7ccf27a21445ac3b2fb0cd576d3b726 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Fri, 24 Jun 2022 18:52:53 -0400 Subject: [PATCH 015/164] docs: update README --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e04dc2d851..fa649f9cf0 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@
-Wiki.js is an open source project that has been made possible due to the generous contributions by community [backers](https://wiki.js.org/about). If you are interested in supporting this project, please consider [becoming a sponsor](https://github.com/users/NGPixel/sponsorship), [becoming a patron](https://www.patreon.com/requarks), donating to our [OpenCollective](https://opencollective.com/wikijs), via [Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FLV5X255Z9CJU&source=url) or via Ethereum (`0xe1d55c19ae86f6bcbfb17e7f06ace96bdbb22cb5`). +Wiki.js is an open source project that has been made possible due to the generous contributions by community [backers](https://js.wiki/about). If you are interested in supporting this project, please consider [becoming a sponsor](https://github.com/users/NGPixel/sponsorship), [becoming a patron](https://www.patreon.com/requarks), donating to our [OpenCollective](https://opencollective.com/wikijs), via [Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FLV5X255Z9CJU&source=url) or via Ethereum (`0xe1d55c19ae86f6bcbfb17e7f06ace96bdbb22cb5`). [![Become a Sponsor](https://img.shields.io/badge/donate-github-ea4aaa.svg?style=popout&logo=github)](https://github.com/users/NGPixel/sponsorship) [![Become a Patron](https://img.shields.io/badge/donate-patreon-orange.svg?style=popout&logo=patreon)](https://www.patreon.com/requarks) @@ -409,9 +409,6 @@ This project exists thanks to all the people who contribute. [[Contribute]](http

Special Thanks

-![Algolia](https://js.wiki/legacy/logo_algolia.png) -[Algolia](https://www.algolia.com/) for providing access to their incredible search engine. - ![Browserstack](https://js.wiki/legacy/logo_browserstack.png) [Browserstack](https://www.browserstack.com/) for providing access to their great cross-browser testing tools. @@ -419,16 +416,16 @@ This project exists thanks to all the people who contribute. [[Contribute]](http [Cloudflare](https://www.cloudflare.com/) for providing their great CDN, SSL and advanced networking services. ![DigitalOcean](https://js.wiki/legacy/logo_digitalocean.png) -[DigitalOcean](https://m.do.co/c/5f7445bfa4d0) for providing hosting of the Wiki.js documentation site. +[DigitalOcean](https://m.do.co/c/5f7445bfa4d0) for providing hosting of the Wiki.js documentation site and APIs. ![Icons8](https://static.requarks.io/logo/icons8-text-h40.png) -[Icons8](https://icons8.com/) for providing beautiful icon sets. +[Icons8](https://icons8.com/) for providing access to their beautiful icon sets. ![Lokalise](https://static.requarks.io/logo/lokalise-text-h40.png) [Lokalise](https://lokalise.com/) for providing access to their great localization tool. ![Netlify](https://js.wiki/legacy/logo_netlify.png) -[Netlify](https://www.netlify.com) for providing hosting for landings and blog websites. +[Netlify](https://www.netlify.com) for providing hosting for our website. ![ngrok](https://static.requarks.io/logo/ngrok-h40.png) [ngrok](https://ngrok.com) for providing access to their great HTTP tunneling services. From 48077fc9e5702bc9bc633de7202d9bbf0420073d Mon Sep 17 00:00:00 2001 From: NGPixel Date: Fri, 24 Jun 2022 22:20:36 -0400 Subject: [PATCH 016/164] feat(admin): make page extensions configurable --- client/components/admin/admin-general.vue | 66 ++++++++++++++--------- server/app/data.yml | 8 +-- server/controllers/common.js | 2 +- server/graph/resolvers/site.js | 7 ++- server/graph/schemas/site.graphql | 2 + 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/client/components/admin/admin-general.vue b/client/components/admin/admin-general.vue index 24829c8c1e..85561381cc 100644 --- a/client/components/admin/admin-general.vue +++ b/client/components/admin/admin-general.vue @@ -164,6 +164,19 @@ //- disabled //- ) + v-card.mt-5.animated.fadeInUp.wait-p6s + v-toolbar(color='primary', dark, dense, flat) + v-toolbar-title.subtitle-1 URL Handling + v-card-text + v-text-field( + outlined + :label='$t(`admin:general.pageExtensions`)' + v-model='config.pageExtensions' + prepend-icon='mdi-format-text-wrapping-overflow' + :hint='$t(`admin:general.pageExtensionsHint`)' + persistent-hint + ) + component(:is='activeModal') @@ -202,7 +215,8 @@ export default { featurePageRatings: false, featurePageComments: false, featurePersonalWikis: false, - featureTinyPNG: false + featureTinyPNG: false, + pageExtensions: '' }, metaRobots: [ { text: 'Index', value: 'index' }, @@ -247,32 +261,34 @@ export default { await this.$apollo.mutate({ mutation: gql` mutation ( - $host: String! - $title: String! - $description: String! - $robots: [String]! - $analyticsService: String! - $analyticsId: String! - $company: String! - $contentLicense: String! - $logoUrl: String! - $featurePageRatings: Boolean! - $featurePageComments: Boolean! - $featurePersonalWikis: Boolean! + $host: String + $title: String + $description: String + $robots: [String] + $analyticsService: String + $analyticsId: String + $company: String + $contentLicense: String + $logoUrl: String + $pageExtensions: String + $featurePageRatings: Boolean + $featurePageComments: Boolean + $featurePersonalWikis: Boolean ) { site { updateConfig( - host: $host, - title: $title, - description: $description, - robots: $robots, - analyticsService: $analyticsService, - analyticsId: $analyticsId, - company: $company, - contentLicense: $contentLicense, - logoUrl: $logoUrl, - featurePageRatings: $featurePageRatings, - featurePageComments: $featurePageComments, + host: $host + title: $title + description: $description + robots: $robots + analyticsService: $analyticsService + analyticsId: $analyticsId + company: $company + contentLicense: $contentLicense + logoUrl: $logoUrl + pageExtensions: $pageExtensions + featurePageRatings: $featurePageRatings + featurePageComments: $featurePageComments featurePersonalWikis: $featurePersonalWikis ) { responseResult { @@ -295,6 +311,7 @@ export default { company: _.get(this.config, 'company', ''), contentLicense: _.get(this.config, 'contentLicense', ''), logoUrl: _.get(this.config, 'logoUrl', ''), + pageExtensions: _.get(this.config, 'pageExtensions', ''), featurePageRatings: _.get(this.config, 'featurePageRatings', false), featurePageComments: _.get(this.config, 'featurePageComments', false), featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false) @@ -347,6 +364,7 @@ export default { company contentLicense logoUrl + pageExtensions featurePageRatings featurePageComments featurePersonalWikis diff --git a/server/app/data.yml b/server/app/data.yml index ca48a5eae7..c122145e0a 100644 --- a/server/app/data.yml +++ b/server/app/data.yml @@ -45,6 +45,10 @@ defaults: company: '' contentLicense: '' logoUrl: https://static.requarks.io/logo/wikijs-butterfly.svg + pageExtensions: + - md + - html + - txt mail: host: '' secure: true @@ -152,8 +156,4 @@ reservedPaths: - img - js - svg -pageExtensions: - - md - - html - - txt # --------------------------------- diff --git a/server/controllers/common.js b/server/controllers/common.js index 052c375748..0cd47db22b 100644 --- a/server/controllers/common.js +++ b/server/controllers/common.js @@ -414,7 +414,7 @@ router.get('/_userav/:uid', async (req, res, next) => { * View document / asset */ router.get('/*', async (req, res, next) => { - const stripExt = _.some(WIKI.data.pageExtensions, ext => _.endsWith(req.path, `.${ext}`)) + const stripExt = _.some(WIKI.config.pageExtensions, ext => _.endsWith(req.path, `.${ext}`)) const pageArgs = pageHelper.parsePath(req.path, { stripExt }) const isPage = (stripExt || pageArgs.path.indexOf('.') === -1) diff --git a/server/graph/resolvers/site.js b/server/graph/resolvers/site.js index f36b2f7f46..255bef525d 100644 --- a/server/graph/resolvers/site.js +++ b/server/graph/resolvers/site.js @@ -18,6 +18,7 @@ module.exports = { company: WIKI.config.company, contentLicense: WIKI.config.contentLicense, logoUrl: WIKI.config.logoUrl, + pageExtensions: WIKI.config.pageExtensions.join(', '), ...WIKI.config.seo, ...WIKI.config.features, ...WIKI.config.security, @@ -62,6 +63,10 @@ module.exports = { WIKI.config.logoUrl = _.trim(args.logoUrl) } + if (args.hasOwnProperty('pageExtensions')) { + WIKI.config.pageExtensions = _.trim(args.pageExtensions).split(',').map(p => p.trim().toLowerCase()).filter(p => p !== '') + } + WIKI.config.seo = { description: _.get(args, 'description', WIKI.config.seo.description), robots: _.get(args, 'robots', WIKI.config.seo.robots), @@ -104,7 +109,7 @@ module.exports = { forceDownload: _.get(args, 'uploadForceDownload', WIKI.config.uploads.forceDownload) } - await WIKI.configSvc.saveToDb(['host', 'title', 'company', 'contentLicense', 'seo', 'logoUrl', 'auth', 'features', 'security', 'uploads']) + await WIKI.configSvc.saveToDb(['host', 'title', 'company', 'contentLicense', 'seo', 'logoUrl', 'pageExtensions', 'auth', 'features', 'security', 'uploads']) if (WIKI.config.security.securityTrustProxy) { WIKI.app.enable('trust proxy') diff --git a/server/graph/schemas/site.graphql b/server/graph/schemas/site.graphql index 5544fffe8c..9ff3663985 100644 --- a/server/graph/schemas/site.graphql +++ b/server/graph/schemas/site.graphql @@ -33,6 +33,7 @@ type SiteMutation { company: String contentLicense: String logoUrl: String + pageExtensions: String authAutoLogin: Boolean authEnforce2FA: Boolean authHideLocal: Boolean @@ -74,6 +75,7 @@ type SiteConfig { company: String contentLicense: String logoUrl: String + pageExtensions: String authAutoLogin: Boolean authEnforce2FA: Boolean authHideLocal: Boolean From 4f2dd36e33f8a4abb498147177630c193a8e7c00 Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Tue, 5 Jul 2022 18:26:50 -0400 Subject: [PATCH 017/164] feat(helm): expose DATABASE_URL (#5445) --- dev/helm/templates/NOTES.txt | 2 +- dev/helm/templates/deployment.yaml | 5 +++++ dev/helm/values.yaml | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/dev/helm/templates/NOTES.txt b/dev/helm/templates/NOTES.txt index 5199428e90..93c0d35656 100644 --- a/dev/helm/templates/NOTES.txt +++ b/dev/helm/templates/NOTES.txt @@ -2,7 +2,7 @@ {{- if .Values.ingress.enabled }} {{- range $host := .Values.ingress.hosts }} {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} {{- end }} {{- end }} {{- else if contains "NodePort" .Values.service.type }} diff --git a/dev/helm/templates/deployment.yaml b/dev/helm/templates/deployment.yaml index 24910f2b52..63b3d768af 100644 --- a/dev/helm/templates/deployment.yaml +++ b/dev/helm/templates/deployment.yaml @@ -41,6 +41,10 @@ spec: env: - name: DB_TYPE value: postgres + {{- if .Values.externalPostgresql.databaseURL }} + - name: DATABASE_URL + value: {{ .Values.externalPostgresql.databaseURL }} + {{- else }} - name: DB_HOST value: {{ template "wiki.postgresql.host" . }} - name: DB_PORT @@ -62,6 +66,7 @@ spec: name: {{ template "wiki.postgresql.secret" . }} {{- end }} key: {{ template "wiki.postgresql.secretKey" . }} + {{- end }} - name: HA_ACTIVE value: {{ .Values.replicaCount | int | le 2 | quote }} {{- with .Values.volumeMounts }} diff --git a/dev/helm/values.yaml b/dev/helm/values.yaml index 6b7296a7aa..ebe2260d0f 100644 --- a/dev/helm/values.yaml +++ b/dev/helm/values.yaml @@ -102,6 +102,10 @@ sideload: # - name: HTTPS_PROXY # value: http://my.proxy.com:3128 +## This will override the postgresql chart values +# externalPostgresql: +# databaseURL: postgresql://postgres:postgres@postgres:5432/wiki?sslmode=require + ## Configuration values for the postgresql dependency. ## ref: https://github.com/kubernetes/charts/blob/master/stable/postgresql/README.md ## From dffffd3a2ba2b2f17e4782d58ebca899be5b0caa Mon Sep 17 00:00:00 2001 From: Don Kendall Date: Wed, 6 Jul 2022 19:40:21 -0400 Subject: [PATCH 018/164] fix(helm): allow self-signed ssl (#5446) --- dev/helm/templates/deployment.yaml | 6 +++++- dev/helm/values.yaml | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/dev/helm/templates/deployment.yaml b/dev/helm/templates/deployment.yaml index 63b3d768af..62f02bc795 100644 --- a/dev/helm/templates/deployment.yaml +++ b/dev/helm/templates/deployment.yaml @@ -41,9 +41,11 @@ spec: env: - name: DB_TYPE value: postgres - {{- if .Values.externalPostgresql.databaseURL }} + {{- if (.Values.externalPostgresql).databaseURL }} - name: DATABASE_URL value: {{ .Values.externalPostgresql.databaseURL }} + - name: NODE_TLS_REJECT_UNAUTHORIZED + value: {{ default "1" .Values.externalPostgresql.NODE_TLS_REJECT_UNAUTHORIZED | quote }} {{- else }} - name: DB_HOST value: {{ template "wiki.postgresql.host" . }} @@ -81,6 +83,8 @@ spec: {{- toYaml .Values.livenessProbe | nindent 12 }} readinessProbe: {{- toYaml .Values.readinessProbe | nindent 12 }} + startupProbe: + {{- toYaml .Values.startupProbe | nindent 12 }} resources: {{- toYaml .Values.resources | nindent 12 }} {{- with .Values.nodeSelector }} diff --git a/dev/helm/values.yaml b/dev/helm/values.yaml index ebe2260d0f..1a450d6e30 100644 --- a/dev/helm/values.yaml +++ b/dev/helm/values.yaml @@ -32,6 +32,16 @@ readinessProbe: path: /healthz port: http +startupProbe: + initialDelaySeconds: 15 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 60 + httpGet: + path: /healthz + port: http + podSecurityContext: {} # fsGroup: 2000 @@ -104,7 +114,10 @@ sideload: ## This will override the postgresql chart values # externalPostgresql: -# databaseURL: postgresql://postgres:postgres@postgres:5432/wiki?sslmode=require +# # note: ?sslmode=require => ?ssl=true +# databaseURL: postgresql://postgres:postgres@postgres:5432/wiki?ssl=true +# # For self signed CAs, like DigitalOcean +# NODE_TLS_REJECT_UNAUTHORIZED: "0" ## Configuration values for the postgresql dependency. ## ref: https://github.com/kubernetes/charts/blob/master/stable/postgresql/README.md From 628c72ea169045e1f1dd2121cf32e761867dbf45 Mon Sep 17 00:00:00 2001 From: Mirco T Date: Sun, 17 Jul 2022 01:41:41 +0200 Subject: [PATCH 019/164] feat: CAS authentication module (#5452) Co-authored-by: SeaLife --- .../authentication/cas/authentication.js | 16 +++++++-- .../modules/authentication/cas/definition.yml | 35 +++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/server/modules/authentication/cas/authentication.js b/server/modules/authentication/cas/authentication.js index eae89affbe..9255d02e21 100644 --- a/server/modules/authentication/cas/authentication.js +++ b/server/modules/authentication/cas/authentication.js @@ -1,3 +1,4 @@ +const _ = require('lodash') /* global WIKI */ // ------------------------------------ @@ -10,15 +11,24 @@ module.exports = { init (passport, conf) { passport.use(conf.key, new CASStrategy({ - ssoBaseURL: conf.ssoBaseURL, - serverBaseURL: conf.serverBaseURL, + version: conf.casVersion, + ssoBaseURL: conf.casUrl, + serverBaseURL: conf.baseUrl, + serviceURL: conf.callbackURL, passReqToCallback: true }, async (req, profile, cb) => { try { const user = await WIKI.models.users.processProfile({ providerKey: req.params.strategy, - profile + profile: { + ...profile, + id: _.get(profile.attributes, conf.uniqueIdAttribute, profile.user), + email: _.get(profile.attributes, conf.emailAttribute), + name: _.get(profile.attributes, conf.displayNameAttribute, profile.user), + picture: '' + } }) + cb(null, user) } catch (err) { cb(err, null) diff --git a/server/modules/authentication/cas/definition.yml b/server/modules/authentication/cas/definition.yml index 912840eb93..a8c6e4fd70 100644 --- a/server/modules/authentication/cas/definition.yml +++ b/server/modules/authentication/cas/definition.yml @@ -6,6 +6,37 @@ logo: https://static.requarks.io/logo/cas.svg color: green darken-2 website: https://apereo.github.io/cas/ useForm: false +isAvailable: true props: - ssoBaseURL: String - serverBaseURL: String + baseUrl: + type: String + title: Base URL + hint: 'Base-URL of your WikiJS (for example: https://wiki.example.com)' + order: 1 + casUrl: + type: String + title: URL to the CAS Server + hint: 'Base-URL of the CAS server, including context path. (for example: https://login.company.com/cas)' + order: 2 + casVersion: + type: String + title: CAS Version + hint: 'The version of CAS to use' + order: 3 + enum: + - CAS3.0 + - CAS1.0 + default: 'CAS3.0' + emailAttribute: + type: String + title: Attribute key which contains the users email + default: email + order: 4 + displayNameAttribute: + type: String + title: Attribute key which contains the users display name (leave empty if there is none) + order: 5 + uniqueIdAttribute: + type: String + title: Attribute key which contains the unique identifier of a user. (if empty, username will be used) + order: 6 From e78953d01805e02ee6064698a6432b1843802207 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Tue, 19 Jul 2022 18:20:03 -0400 Subject: [PATCH 020/164] fix(admin): update admin groups page rules write:pages label to match actual permissions --- client/components/admin/admin-groups-edit-rules.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/components/admin/admin-groups-edit-rules.vue b/client/components/admin/admin-groups-edit-rules.vue index 89d97db487..f52d9265b4 100644 --- a/client/components/admin/admin-groups-edit-rules.vue +++ b/client/components/admin/admin-groups-edit-rules.vue @@ -214,8 +214,8 @@ export default { return { roles: [ { text: 'Read Pages', value: 'read:pages', icon: 'mdi-file-eye-outline' }, - { text: 'Create Pages', value: 'write:pages', icon: 'mdi-file-plus-outline' }, - { text: 'Edit + Move Pages', value: 'manage:pages', icon: 'mdi-file-document-edit-outline' }, + { text: 'Create + Edit Pages', value: 'write:pages', icon: 'mdi-file-plus-outline' }, + { text: 'Rename / Move Pages', value: 'manage:pages', icon: 'mdi-file-document-edit-outline' }, { text: 'Delete Pages', value: 'delete:pages', icon: 'mdi-file-remove-outline' }, { text: 'View Pages Source', value: 'read:source', icon: 'mdi-code-tags' }, { text: 'View Pages History', value: 'read:history', icon: 'mdi-history' }, From 85c920f965c8e9367689e5d1fd1c3434672020b7 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Thu, 21 Jul 2022 15:55:55 -0400 Subject: [PATCH 021/164] docs: update BACKERS [skip ci] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fa649f9cf0..3ca878233f 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - Akira Suenami ([@a-suenami](https://github.com/a-suenami)) +- Armin Reiter ([@arminreiter](https://github.com/arminreiter)) - Arnaud Marchand ([@snuids](https://github.com/snuids)) - Brian Douglass ([@bhdouglass](https://github.com/bhdouglass)) - Bryon Vandiver ([@asterick](https://github.com/asterick)) From 0e123a62f7ffc9ae2af8584a2bee3ba89dd9e885 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 1 Aug 2022 21:38:48 -0400 Subject: [PATCH 022/164] docs: update BACKERS [skip ci] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3ca878233f..b6263c4174 100644 --- a/README.md +++ b/README.md @@ -357,6 +357,7 @@ Thank you to all our patrons! 🙏 [[Become a patron](https://www.patreon.com/re - Alex Balabanov - Alex Zen - Arti Zirk +- Ave - Brandon Curtis - Dave 'Sri' Seah - djagoo From 6943524b3f4f7eb9136b36e9a9f2851e2af13881 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sat, 6 Aug 2022 01:18:44 -0400 Subject: [PATCH 023/164] docs: update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b6263c4174..99488b3750 100644 --- a/README.md +++ b/README.md @@ -164,11 +164,11 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - MaFarine ([@MaFarine](https://github.com/MaFarine)) - Marcilio Leite Neto ([@marclneto](https://github.com/marclneto)) - Mattias Johnson ([@mattiasJohnson](https://github.com/mattiasJohnson)) -- Max Ricketts-Uy ([@MaxRickettsUy](https://github.com/MaxRickettsUy)) +- Max Ricketts-Uy ([@MaxRickettsUy](https://github.com/MaxRickettsUy)) - Mickael Asseline ([@PAPAMICA](https://github.com/PAPAMICA)) - Mitchell Rowton ([@mrowton](https://github.com/mrowton)) - M. Scott Ford ([@mscottford](https://github.com/mscottford)) From 933293a997edc882eb42366e88fc7e8c110627a3 Mon Sep 17 00:00:00 2001 From: Hexaflexagon Date: Sat, 6 Aug 2022 23:27:25 +0200 Subject: [PATCH 024/164] feat: add elasticsearch ssl options (#5499) --- .../search/elasticsearch/definition.yml | 19 ++++++++++++----- server/modules/search/elasticsearch/engine.js | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/server/modules/search/elasticsearch/definition.yml b/server/modules/search/elasticsearch/definition.yml index 856f651b02..8475c0b5f8 100644 --- a/server/modules/search/elasticsearch/definition.yml +++ b/server/modules/search/elasticsearch/definition.yml @@ -20,28 +20,37 @@ props: title: Host(s) hint: Comma-separated list of Elasticsearch hosts to connect to, including the port, username and password if necessary. (e.g. http://localhost:9200, https://user:pass@es1.example.com:9200) order: 2 + verifyTLSCertificate: + title: Verify TLS Certificate + type: Boolean + default: true + order: 3 + tlsCertPath: + title: TLS Certificate Path + type: String + hint: Absolute path to the TLS certificate on the server. + order: 4 indexName: type: String title: Index Name hint: The index name to use during creation default: wiki - order: 3 + order: 5 analyzer: type: String title: Analyzer hint: 'The token analyzer in elasticsearch' default: simple - order: 4 + order: 6 sniffOnStart: type: Boolean title: Sniff on start hint: 'Should Wiki.js attempt to detect the rest of the cluster on first connect? (Default: off)' default: false - order: 5 + order: 7 sniffInterval: type: Number title: Sniff Interval hint: '0 = disabled, Interval in seconds to check for updated list of nodes in cluster. (Default: 0)' default: 0 - order: 6 - + order: 8 diff --git a/server/modules/search/elasticsearch/engine.js b/server/modules/search/elasticsearch/engine.js index 4a41df8861..4a96b2bbfe 100644 --- a/server/modules/search/elasticsearch/engine.js +++ b/server/modules/search/elasticsearch/engine.js @@ -1,6 +1,7 @@ const _ = require('lodash') const stream = require('stream') const Promise = require('bluebird') +const fs = require('fs') const pipeline = Promise.promisify(stream.pipeline) /* global WIKI */ @@ -24,6 +25,7 @@ module.exports = { nodes: this.config.hosts.split(',').map(_.trim), sniffOnStart: this.config.sniffOnStart, sniffInterval: (this.config.sniffInterval > 0) ? this.config.sniffInterval : false, + ssl: getTlsOptions(this.config), name: 'wiki-js' }) break @@ -33,6 +35,7 @@ module.exports = { nodes: this.config.hosts.split(',').map(_.trim), sniffOnStart: this.config.sniffOnStart, sniffInterval: (this.config.sniffInterval > 0) ? this.config.sniffInterval : false, + ssl: getTlsOptions(this.config), name: 'wiki-js' }) break @@ -351,3 +354,21 @@ module.exports = { WIKI.logger.info(`(SEARCH/ELASTICSEARCH) Index rebuilt successfully.`) } } + +function getTlsOptions(conf) { + if (!conf.tlsCertPath) { + return { + rejectUnauthorized: conf.verifyTLSCertificate + } + } + + const caList = [] + if (conf.verifyTLSCertificate) { + caList.push(fs.readFileSync(conf.tlsCertPath)) + } + + return { + rejectUnauthorized: conf.verifyTLSCertificate, + ca: caList + } +} From fdeb4a48472139996775336b372025afc907a41d Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sat, 13 Aug 2022 14:20:46 -0400 Subject: [PATCH 025/164] docs: update BACKERS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 99488b3750..91244f6640 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - Oleksandr Koltsov ([@crambo](https://github.com/crambo)) - Philipp Schmitt ([@pschmitt](https://github.com/pschmitt)) - Robert Lanzke ([@winkelement](https://github.com/winkelement)) +- Ruizhe Li ([@liruizhe1995](https://github.com/liruizhe1995)) - Sam Martin ([@ABitMoreDepth](https://github.com/ABitMoreDepth)) - Sean Coffey ([@seanecoffey](https://github.com/seanecoffey)) - Stephan Kristyn ([@stevek-pro](https://github.com/stevek-pro)) From 4e5da41d35a9dc00372bdf4a2ea5e89113d51f96 Mon Sep 17 00:00:00 2001 From: Sandhya Veludandi Date: Sun, 14 Aug 2022 19:07:09 -0400 Subject: [PATCH 026/164] fix: page cursor and pagination (#5541) * fix: search results not displaying on first page * fix: page cursor position stays the same between page selection --- client/components/common/search-results.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/components/common/search-results.vue b/client/components/common/search-results.vue index 64c57f41f5..ddc33208f1 100644 --- a/client/components/common/search-results.vue +++ b/client/components/common/search-results.vue @@ -105,6 +105,9 @@ export default { } else { this.searchIsLoading = true } + }, + results() { + this.cursor = 0 } }, mounted() { @@ -153,6 +156,9 @@ export default { skip() { return !this.search || this.search.length < 2 }, + result() { + this.pagination = 1 + }, update: (data) => _.get(data, 'pages.search', {}), watchLoading (isLoading) { this.searchIsLoading = isLoading From 8290e86aaf362d53cbc573abdc78e7740dd72a02 Mon Sep 17 00:00:00 2001 From: Pam S Date: Tue, 16 Aug 2022 16:37:19 -0400 Subject: [PATCH 027/164] feat: add logout for auth0 (#5545) Co-authored-by: Pam Selle --- server/modules/authentication/auth0/authentication.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/modules/authentication/auth0/authentication.js b/server/modules/authentication/auth0/authentication.js index 9eade81ab1..388139bc05 100644 --- a/server/modules/authentication/auth0/authentication.js +++ b/server/modules/authentication/auth0/authentication.js @@ -27,5 +27,8 @@ module.exports = { } } )) + }, + logout (conf) { + return `https://${conf.domain}/v2/logout?${new URLSearchParams({ client_id: conf.clientId, returnTo: WIKI.config.host }).toString()}` } } From fb9e37faad2d0afbbfa2bccb93be9e33c98f87a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Ple=C3=9F?= Date: Sun, 4 Sep 2022 04:56:05 +0200 Subject: [PATCH 028/164] docs: update CONTRIBUTING.md (#5603) --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6f8041d7a4..824c3e9d9d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -28,7 +28,7 @@ It is also always helpful to have some context for your pull request. What was t Use the feature request board to submit new ideas and vote on which ideas should be integrated first. -:triangular_flag_on_post: [https://wiki.js.org/feedback/](https://wiki.js.org/feedback/) +:triangular_flag_on_post: [https://js.wiki/feedback/](https://js.wiki/feedback/) *Do not use GitHub issues to submit new feature ideas, as it will closed and you'll be asked to use the feature request board above. GitHub Issues are limited to bugs / issues / help*. From 31bd3274871c317f416c2c56a399eaa0f3c28067 Mon Sep 17 00:00:00 2001 From: Jared Brogan <42228088+jaredbrogan@users.noreply.github.com> Date: Sat, 3 Sep 2022 21:57:21 -0500 Subject: [PATCH 029/164] fix: correct azure blob storage typo (#5591) --- server/modules/storage/azure/definition.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/storage/azure/definition.yml b/server/modules/storage/azure/definition.yml index 13eb92e09c..631bef37dd 100644 --- a/server/modules/storage/azure/definition.yml +++ b/server/modules/storage/azure/definition.yml @@ -41,4 +41,4 @@ props: actions: - handler: exportAll label: Export All - hint: Output all content from the DB to Azure Blog Storage, overwriting any existing data. If you enabled Azure Blog Storage after content was created or you temporarily disabled it, you'll want to execute this action to add the missing content. + hint: Output all content from the DB to Azure Blob Storage, overwriting any existing data. If you enabled Azure Blob Storage after content was created or you temporarily disabled it, you'll want to execute this action to add the missing content. From 91221e73eb94a1d75c20e0866e4d7057ff9cf4e8 Mon Sep 17 00:00:00 2001 From: Fionera Date: Tue, 6 Sep 2022 00:40:54 +0200 Subject: [PATCH 030/164] feat: set groups based on OIDC claim (#5568) Co-authored-by: Nicolas Giard --- .../modules/authentication/oidc/authentication.js | 11 +++++++++++ server/modules/authentication/oidc/definition.yml | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/server/modules/authentication/oidc/authentication.js b/server/modules/authentication/oidc/authentication.js index 6bd244fee8..5f9d026933 100644 --- a/server/modules/authentication/oidc/authentication.js +++ b/server/modules/authentication/oidc/authentication.js @@ -29,6 +29,17 @@ module.exports = { email: _.get(profile, '_json.' + conf.emailClaim) } }) + if (conf.mapGroups) { + const groups = _.get(profile, '_json.' + conf.groupsClaim) + if (groups) { + const groupIDs = Object.values(WIKI.auth.groups) + .filter(g => groups.includes(g.name)) + .map(g => g.id) + for (let groupID of groupIDs) { + await user.$relatedQuery('groups').relate(groupID) + } + } + } cb(null, user) } catch (err) { cb(err, null) diff --git a/server/modules/authentication/oidc/definition.yml b/server/modules/authentication/oidc/definition.yml index 02812c4f5b..ae1c636a28 100644 --- a/server/modules/authentication/oidc/definition.yml +++ b/server/modules/authentication/oidc/definition.yml @@ -49,8 +49,21 @@ props: default: email maxWidth: 500 order: 7 + mapGroups: + type: Boolean + title: Map Groups + hint: Map groups matching names from the groups claim value + default: false + order: 8 + groupsClaim: + type: String + title: Groups Claim + hint: Field containing the group names + default: groups + maxWidth: 500 + order: 9 logoutURL: type: String title: Logout URL hint: (optional) Logout URL on the OAuth2 provider where the user will be redirected to complete the logout process. - order: 8 + order: 10 From 665284bf90e4fa230469c09c697f42eaed76db10 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 5 Sep 2022 18:45:27 -0400 Subject: [PATCH 031/164] docs: update BACKERS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 91244f6640..6a9ab1e72e 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - Cameron Steele ([@ATechAdventurer](https://github.com/ATechAdventurer)) - Charlie Schliesser ([@charlie-s](https://github.com/charlie-s)) - Cloud Data Hosting LLC ([@CloudDataHostingLLC](https://github.com/CloudDataHostingLLC)) +- Cole Manning ([@RVRX](https://github.com/RVRX)) - CrazyMarvin ([@CrazyMarvin](https://github.com/CrazyMarvin)) - David Christian Holin ([@SirGibihm](https://github.com/SirGibihm)) - Dragan Espenschied ([@despens](https://github.com/despens)) From 4b3005057f99cd7008b4aff4ecd7cf90968eb072 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 17 Sep 2022 17:36:40 -0400 Subject: [PATCH 032/164] fix: prevent user enumeration using local login timings --- server/modules/authentication/local/authentication.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/modules/authentication/local/authentication.js b/server/modules/authentication/local/authentication.js index e6fa75d3c4..ea2bf1d0b1 100644 --- a/server/modules/authentication/local/authentication.js +++ b/server/modules/authentication/local/authentication.js @@ -1,3 +1,5 @@ +const bcrypt = require('bcryptjs-then') + /* global WIKI */ // ------------------------------------ @@ -28,6 +30,9 @@ module.exports = { done(null, user) } } else { + // Fake verify password to mask timing differences + await bcrypt.compare((Math.random() + 1).toString(36), '$2a$12$irXbAcQSY59pcQQfNQpY8uyhfSw48nzDikAmr60drI501nR.PuBx2') + done(new WIKI.Error.AuthLoginFailed(), null) } } catch (err) { From ebf4da9bea59590eaa6820c6b00b3a1cf1d8c083 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 17 Sep 2022 17:54:11 -0400 Subject: [PATCH 033/164] fix: oidc auth groups relate / unrelate --- .../modules/authentication/oidc/authentication.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/server/modules/authentication/oidc/authentication.js b/server/modules/authentication/oidc/authentication.js index 5f9d026933..ae3811116c 100644 --- a/server/modules/authentication/oidc/authentication.js +++ b/server/modules/authentication/oidc/authentication.js @@ -31,12 +31,14 @@ module.exports = { }) if (conf.mapGroups) { const groups = _.get(profile, '_json.' + conf.groupsClaim) - if (groups) { - const groupIDs = Object.values(WIKI.auth.groups) - .filter(g => groups.includes(g.name)) - .map(g => g.id) - for (let groupID of groupIDs) { - await user.$relatedQuery('groups').relate(groupID) + if (groups && _.isArray(groups)) { + const currentGroups = (await user.$relatedQuery('groups').select('groups.id')).groups.map(g => g.id) + const expectedGroups = Object.values(WIKI.auth.groups).filter(g => groups.includes(g.name)).map(g => g.id) + for (const groupId of _.difference(expectedGroups, currentGroups)) { + await user.$relatedQuery('groups').relate(groupId) + } + for (const groupId of _.difference(currentGroups, expectedGroups)) { + await user.$relatedQuery('groups').unrelate(groupId) } } } From fa35f3a2548f805a7db4d69935a76e9af03550ff Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 18 Sep 2022 20:24:22 -0400 Subject: [PATCH 034/164] fix: footer text overflow on smaller desktop screens --- client/scss/base/base.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/scss/base/base.scss b/client/scss/base/base.scss index f06afeea73..0322435431 100644 --- a/client/scss/base/base.scss +++ b/client/scss/base/base.scss @@ -30,6 +30,12 @@ html { } } +@media only screen and (min-width:960px) { + .v-application .v-footer { + padding-left: 272px + } +} + #root .v-application { .overline { line-height: 1rem; From 8715cd69b2da5bc4332a6eda07945fad8738c8ac Mon Sep 17 00:00:00 2001 From: NGPixel Date: Tue, 20 Sep 2022 16:55:05 -0400 Subject: [PATCH 035/164] feat: edit shortcuts --- client/components/admin/admin-general.vue | 111 +++++++++++++++++++++- client/store/page.js | 11 ++- client/themes/default/components/page.vue | 82 +++++++++++++++- client/themes/default/scss/app.scss | 4 + server/app/data.yml | 8 ++ server/controllers/common.js | 7 +- server/graph/resolvers/site.js | 13 ++- server/graph/schemas/site.graphql | 14 +++ server/models/pages.js | 4 +- server/views/page.pug | 2 + 10 files changed, 246 insertions(+), 10 deletions(-) diff --git a/client/components/admin/admin-general.vue b/client/components/admin/admin-general.vue index 85561381cc..8804ee3922 100644 --- a/client/components/admin/admin-general.vue +++ b/client/components/admin/admin-general.vue @@ -144,7 +144,7 @@ //- ) //- v-divider.mt-3 - v-switch( + v-switch.mt-0( inset label='Comments' color='indigo' @@ -177,6 +177,76 @@ persistent-hint ) + v-card.mt-5.animated.fadeInUp.wait-p7s + v-toolbar(color='primary', dark, dense, flat) + v-toolbar-title.subtitle-1 {{$t('admin:general.editShortcuts')}} + v-card-text + v-switch.mt-0( + inset + :label='$t(`admin:general.editFab`)' + color='primary' + v-model='config.editFab' + persistent-hint + :hint='$t(`admin:general.editFabHint`)' + ) + v-divider + .overline.grey--text.pa-4 {{$t('admin:general.editMenuBar')}} + .px-3.pb-3 + v-switch.mt-0.ml-1( + inset + :label='$t(`admin:general.displayEditMenuBar`)' + color='primary' + v-model='config.editMenuBar' + persistent-hint + :hint='$t(`admin:general.displayEditMenuBarHint`)' + ) + v-switch.mt-4.ml-1( + v-if='config.editMenuBar' + inset + :label='$t(`admin:general.displayEditMenuBtn`)' + color='primary' + v-model='config.editMenuBtn' + persistent-hint + :hint='$t(`admin:general.displayEditMenuBtnHint`)' + ) + v-switch.mt-4.ml-1( + v-if='config.editMenuBar' + inset + :label='$t(`admin:general.displayEditMenuExternalBtn`)' + color='primary' + v-model='config.editMenuExternalBtn' + persistent-hint + :hint='$t(`admin:general.displayEditMenuExternalBtnHint`)' + ) + template(v-if='config.editMenuBar && config.editMenuExternalBtn') + v-divider + .overline.grey--text.pa-4 External Edit Button + .px-3.pb-3 + v-text-field( + outlined + :label='$t(`admin:general.editMenuExternalName`)' + v-model='config.editMenuExternalName' + prepend-icon='mdi-format-title' + :hint='$t(`admin:general.editMenuExternalNameHint`)' + persistent-hint + ) + v-text-field.mt-3( + outlined + :label='$t(`admin:general.editMenuExternalIcon`)' + v-model='config.editMenuExternalIcon' + prepend-icon='mdi-dice-5' + :hint='$t(`admin:general.editMenuExternalIconHint`)' + persistent-hint + ) + v-text-field.mt-3( + outlined + :label='$t(`admin:general.editMenuExternalUrl`)' + v-model='config.editMenuExternalUrl' + prepend-icon='mdi-near-me' + :hint='$t(`admin:general.editMenuExternalUrlHint`)' + persistent-hint + ) + component(:is='activeModal') @@ -216,7 +286,14 @@ export default { featurePageComments: false, featurePersonalWikis: false, featureTinyPNG: false, - pageExtensions: '' + pageExtensions: '', + editFab: false, + editMenuBar: false, + editMenuBtn: false, + editMenuExternalBtn: false, + editMenuExternalName: '', + editMenuExternalIcon: '', + editMenuExternalUrl: '' }, metaRobots: [ { text: 'Index', value: 'index' }, @@ -274,6 +351,13 @@ export default { $featurePageRatings: Boolean $featurePageComments: Boolean $featurePersonalWikis: Boolean + $editFab: Boolean + $editMenuBar: Boolean + $editMenuBtn: Boolean + $editMenuExternalBtn: Boolean + $editMenuExternalName: String + $editMenuExternalIcon: String + $editMenuExternalUrl: String ) { site { updateConfig( @@ -290,6 +374,13 @@ export default { featurePageRatings: $featurePageRatings featurePageComments: $featurePageComments featurePersonalWikis: $featurePersonalWikis + editFab: $editFab + editMenuBar: $editMenuBar + editMenuBtn: $editMenuBtn + editMenuExternalBtn: $editMenuExternalBtn + editMenuExternalName: $editMenuExternalName + editMenuExternalIcon: $editMenuExternalIcon + editMenuExternalUrl: $editMenuExternalUrl ) { responseResult { succeeded @@ -314,7 +405,14 @@ export default { pageExtensions: _.get(this.config, 'pageExtensions', ''), featurePageRatings: _.get(this.config, 'featurePageRatings', false), featurePageComments: _.get(this.config, 'featurePageComments', false), - featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false) + featurePersonalWikis: _.get(this.config, 'featurePersonalWikis', false), + editFab: _.get(this.config, 'editFab', false), + editMenuBar: _.get(this.config, 'editMenuBar', false), + editMenuBtn: _.get(this.config, 'editMenuBtn', false), + editMenuExternalBtn: _.get(this.config, 'editMenuExternalBtn', false), + editMenuExternalName: _.get(this.config, 'editMenuExternalName', ''), + editMenuExternalIcon: _.get(this.config, 'editMenuExternalIcon', ''), + editMenuExternalUrl: _.get(this.config, 'editMenuExternalUrl', '') }, watchLoading (isLoading) { this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-update') @@ -368,6 +466,13 @@ export default { featurePageRatings featurePageComments featurePersonalWikis + editFab + editMenuBar + editMenuBtn + editMenuExternalBtn + editMenuExternalName + editMenuExternalIcon + editMenuExternalUrl } } } diff --git a/client/store/page.js b/client/store/page.js index 0a72798eee..92979647b8 100644 --- a/client/store/page.js +++ b/client/store/page.js @@ -41,7 +41,16 @@ const state = { manage: false } }, - commentsCount: 0 + commentsCount: 0, + editShortcuts: { + editFab: false, + editMenuBar: false, + editMenuBtn: false, + editMenuExternalBtn: false, + editMenuExternalName: '', + editMenuExternalIcon: '', + editMenuExternalUrl: '' + } } export default { diff --git a/client/themes/default/components/page.vue b/client/themes/default/components/page.vue index 42d0b2c502..0993c9ec43 100644 --- a/client/themes/default/components/page.vue +++ b/client/themes/default/components/page.vue @@ -49,10 +49,28 @@ status-indicator.ml-3(negative, pulse) v-divider v-container.grey.pa-0(fluid, :class='$vuetify.theme.dark ? `darken-4-l3` : `lighten-4`') - v-row(no-gutters, align-content='center', style='height: 90px;') + v-row.page-header-section(no-gutters, align-content='center', style='height: 90px;') v-col.page-col-content.is-page-header(offset-xl='2', offset-lg='3', style='margin-top: auto; margin-bottom: auto;', :class='$vuetify.rtl ? `pr-4` : `pl-4`') .headline.grey--text(:class='$vuetify.theme.dark ? `text--lighten-2` : `text--darken-3`') {{title}} .caption.grey--text.text--darken-1 {{description}} + .page-edit-shortcuts(v-if='editShortcutsObj.editMenuBar') + v-btn( + v-if='editShortcutsObj.editMenuBtn' + @click='pageEdit' + depressed + small + ) + v-icon.mr-2(small) mdi-pencil + span.text-none {{$t(`common:actions.edit`)}} + v-btn( + v-if='editShortcutsObj.editMenuExternalBtn' + :href='editMenuExternalUrl' + target='_blank' + depressed + small + ) + v-icon.mr-2(small) {{ editShortcutsObj.editMenuExternalIcon }} + span.text-none {{$t(`common:page.editExternal`, { name: editShortcutsObj.editMenuExternalName })}} v-divider v-container.pl-5.pt-4(fluid, grid-list-xl) v-layout(row) @@ -186,7 +204,7 @@ v-spacer v-flex.page-col-content(xs12, lg9, xl10) - v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasAnyPagePermissions') + v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasAnyPagePermissions && editShortcutsObj.editFab') template(v-slot:activator='{ on: onEditActivator }') v-speed-dial( v-model='pageEditFab' @@ -440,6 +458,14 @@ export default { commentsExternal: { type: Boolean, default: false + }, + editShortcuts: { + type: String, + default: '' + }, + filename: { + type: String, + default: '' } }, data() { @@ -478,6 +504,7 @@ export default { isAuthenticated: get('user/authenticated'), commentsCount: get('page/commentsCount'), commentsPerms: get('page/effectivePermissions@comments'), + editShortcutsObj: get('page/editShortcuts'), rating: { get () { return 3.5 @@ -519,7 +546,14 @@ export default { return this.hasAdminPermission || this.hasWritePagesPermission || this.hasManagePagesPermission || this.hasDeletePagesPermission || this.hasReadSourcePermission || this.hasReadHistoryPermission }, - printView: sync('site/printView') + printView: sync('site/printView'), + editMenuExternalUrl () { + if (this.editShortcutsObj.editMenuBar && this.editShortcutsObj.editMenuExternalBtn) { + return this.editShortcutsObj.editMenuExternalUrl.replace('{filename}', this.filename) + } else { + return '' + } + } }, created() { this.$store.set('page/authorId', this.authorId) @@ -537,6 +571,9 @@ export default { if (this.effectivePermissions) { this.$store.set('page/effectivePermissions', JSON.parse(Buffer.from(this.effectivePermissions, 'base64').toString())) } + if (this.editShortcuts) { + this.$store.set('page/editShortcuts', JSON.parse(Buffer.from(this.editShortcuts, 'base64').toString())) + } this.$store.set('page/mode', 'view') }, @@ -676,4 +713,43 @@ export default { display: none; } +.page-header-section { + position: relative; + + .page-edit-shortcuts { + position: absolute; + bottom: -14px; + right: 10px; + + .v-btn { + border-right: 1px solid #DDD !important; + border-bottom: 1px solid #DDD !important; + border-radius: 0; + color: #777; + background-color: #FFF !important; + + @at-root .theme--dark & { + background-color: #222 !important; + border-right-color: #444 !important; + border-bottom-color: #444 !important; + color: #CCC; + } + + .v-icon { + color: mc('blue', '700'); + } + + &:first-child { + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; + } + + &:last-child { + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + } + } + } +} + diff --git a/client/themes/default/scss/app.scss b/client/themes/default/scss/app.scss index 2b51ed7202..99f406db4a 100644 --- a/client/themes/default/scss/app.scss +++ b/client/themes/default/scss/app.scss @@ -1036,4 +1036,8 @@ .comments-container { display: none; } + + .page-edit-shortcuts { + display: none; + } } diff --git a/server/app/data.yml b/server/app/data.yml index c122145e0a..54482c99f1 100644 --- a/server/app/data.yml +++ b/server/app/data.yml @@ -67,6 +67,14 @@ defaults: audience: 'urn:wiki.js' tokenExpiration: '30m' tokenRenewal: '14d' + editShortcuts: + editFab: true + editMenuBar: false + editMenuBtn: true + editMenuExternalBtn: true + editMenuExternalName: 'GitHub' + editMenuExternalIcon: 'mdi-github' + editMenuExternalUrl: 'https://github.com/org/repo/blob/main/{filename}' features: featurePageRatings: true featurePageComments: true diff --git a/server/controllers/common.js b/server/controllers/common.js index 0cd47db22b..3bcfcd940f 100644 --- a/server/controllers/common.js +++ b/server/controllers/common.js @@ -542,13 +542,18 @@ router.get('/*', async (req, res, next) => { }) } + // -> Page Filename (for edit on external repo button) + let pageFilename = WIKI.config.lang.namespacing ? `${pageArgs.locale}/${page.path}` : page.path + pageFilename += page.contentType === 'markdown' ? '.md' : '.html' + // -> Render view res.render('page', { page, sidebar, injectCode, comments: commentTmpl, - effectivePermissions + effectivePermissions, + pageFilename }) } } else if (pageArgs.path === 'home') { diff --git a/server/graph/resolvers/site.js b/server/graph/resolvers/site.js index 255bef525d..db538a217f 100644 --- a/server/graph/resolvers/site.js +++ b/server/graph/resolvers/site.js @@ -20,6 +20,7 @@ module.exports = { logoUrl: WIKI.config.logoUrl, pageExtensions: WIKI.config.pageExtensions.join(', '), ...WIKI.config.seo, + ...WIKI.config.editShortcuts, ...WIKI.config.features, ...WIKI.config.security, authAutoLogin: WIKI.config.auth.autoLogin, @@ -84,6 +85,16 @@ module.exports = { tokenRenewal: _.get(args, 'authJwtRenewablePeriod', WIKI.config.auth.tokenRenewal) } + WIKI.config.editShortcuts = { + editFab: _.get(args, 'editFab', WIKI.config.editShortcuts.editFab), + editMenuBar: _.get(args, 'editMenuBar', WIKI.config.editShortcuts.editMenuBar), + editMenuBtn: _.get(args, 'editMenuBtn', WIKI.config.editShortcuts.editMenuBtn), + editMenuExternalBtn: _.get(args, 'editMenuExternalBtn', WIKI.config.editShortcuts.editMenuExternalBtn), + editMenuExternalName: _.get(args, 'editMenuExternalName', WIKI.config.editShortcuts.editMenuExternalName), + editMenuExternalIcon: _.get(args, 'editMenuExternalIcon', WIKI.config.editShortcuts.editMenuExternalIcon), + editMenuExternalUrl: _.get(args, 'editMenuExternalUrl', WIKI.config.editShortcuts.editMenuExternalUrl) + } + WIKI.config.features = { featurePageRatings: _.get(args, 'featurePageRatings', WIKI.config.features.featurePageRatings), featurePageComments: _.get(args, 'featurePageComments', WIKI.config.features.featurePageComments), @@ -109,7 +120,7 @@ module.exports = { forceDownload: _.get(args, 'uploadForceDownload', WIKI.config.uploads.forceDownload) } - await WIKI.configSvc.saveToDb(['host', 'title', 'company', 'contentLicense', 'seo', 'logoUrl', 'pageExtensions', 'auth', 'features', 'security', 'uploads']) + await WIKI.configSvc.saveToDb(['host', 'title', 'company', 'contentLicense', 'seo', 'logoUrl', 'pageExtensions', 'auth', 'editShortcuts', 'features', 'security', 'uploads']) if (WIKI.config.security.securityTrustProxy) { WIKI.app.enable('trust proxy') diff --git a/server/graph/schemas/site.graphql b/server/graph/schemas/site.graphql index 9ff3663985..4cd36d7643 100644 --- a/server/graph/schemas/site.graphql +++ b/server/graph/schemas/site.graphql @@ -41,6 +41,13 @@ type SiteMutation { authJwtAudience: String authJwtExpiration: String authJwtRenewablePeriod: String + editFab: Boolean + editMenuBar: Boolean + editMenuBtn: Boolean + editMenuExternalBtn: Boolean + editMenuExternalName: String + editMenuExternalIcon: String + editMenuExternalUrl: String featurePageRatings: Boolean featurePageComments: Boolean featurePersonalWikis: Boolean @@ -83,6 +90,13 @@ type SiteConfig { authJwtAudience: String authJwtExpiration: String authJwtRenewablePeriod: String + editFab: Boolean + editMenuBar: Boolean + editMenuBtn: Boolean + editMenuExternalBtn: Boolean + editMenuExternalName: String + editMenuExternalIcon: String + editMenuExternalUrl: String featurePageRatings: Boolean featurePageComments: Boolean featurePersonalWikis: Boolean diff --git a/server/models/pages.js b/server/models/pages.js index 44b3825fe3..9bb5d3975c 100644 --- a/server/models/pages.js +++ b/server/models/pages.js @@ -148,6 +148,7 @@ module.exports = class Page extends Model { isPublished: 'boolean', publishEndDate: 'string', publishStartDate: 'string', + contentType: 'string', render: 'string', tags: [ { @@ -787,7 +788,7 @@ module.exports = class Page extends Model { * @returns {Promise} Promise with no value */ static async deletePage(opts) { - const page = await WIKI.models.pages.getPageFromDb(_.has(opts, 'id') ? opts.id : opts); + const page = await WIKI.models.pages.getPageFromDb(_.has(opts, 'id') ? opts.id : opts) if (!page) { throw new WIKI.Error.PageNotFound() } @@ -1067,6 +1068,7 @@ module.exports = class Page extends Model { isPublished: page.isPublished === 1 || page.isPublished === true, publishEndDate: page.publishEndDate, publishStartDate: page.publishStartDate, + contentType: page.contentType, render: page.render, tags: page.tags.map(t => _.pick(t, ['tag', 'title'])), title: page.title, diff --git a/server/views/page.pug b/server/views/page.pug index cc19fbaef2..32649fbe74 100644 --- a/server/views/page.pug +++ b/server/views/page.pug @@ -29,6 +29,8 @@ block body comments-enabled=config.features.featurePageComments effective-permissions=Buffer.from(JSON.stringify(effectivePermissions)).toString('base64') comments-external=comments.codeTemplate + edit-shortcuts=Buffer.from(JSON.stringify(config.editShortcuts)).toString('base64') + filename=pageFilename ) template(slot='contents') div!= page.render From 574a18f97b05f49d27f87cbf2dd9b3975a231420 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Tue, 20 Sep 2022 23:21:06 -0400 Subject: [PATCH 036/164] docs: update BACKERS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6a9ab1e72e..177c836bd8 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - chaee ([@chaee](https://github.com/chaee)) - magicpotato ([@fortheday](https://github.com/fortheday)) - motoacs ([@motoacs](https://github.com/motoacs)) +- muzian666 ([@motoacs](https://github.com/muzian666)) - rburckner ([@rburckner](https://github.com/rburckner)) - scorpion ([@scorpion](https://github.com/scorpion)) - valantien ([@valantien](https://github.com/valantien)) From 26aa23c025c4125a9d14f008d3e788caed898812 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Tue, 20 Sep 2022 23:24:06 -0400 Subject: [PATCH 037/164] docs: update BACKERS --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 177c836bd8..9a9480cac2 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - chaee ([@chaee](https://github.com/chaee)) - magicpotato ([@fortheday](https://github.com/fortheday)) - motoacs ([@motoacs](https://github.com/motoacs)) -- muzian666 ([@motoacs](https://github.com/muzian666)) +- muzian666 ([@muzian666](https://github.com/muzian666)) - rburckner ([@rburckner](https://github.com/rburckner)) - scorpion ([@scorpion](https://github.com/scorpion)) - valantien ([@valantien](https://github.com/valantien)) From 1fcb946f561ceda8c01ff3651726a3c663f18de6 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Fri, 23 Sep 2022 18:07:18 -0400 Subject: [PATCH 038/164] docs: update README --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a9480cac2..96e34cabf5 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,18 @@ Support this project by becoming a sponsor. Your name will show up in the Contri Oleksii
(@idokka) - + From 274ecf4b20488ee267edb448f898d84646544dd0 Mon Sep 17 00:00:00 2001 From: Evandro Arruda Date: Fri, 30 Sep 2022 17:52:25 -0300 Subject: [PATCH 039/164] fix: America/Sao_Paulo timezone offset (#5690) --- client/components/admin/admin-users-edit.vue | 2 +- client/components/profile/profile.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/components/admin/admin-users-edit.vue b/client/components/admin/admin-users-edit.vue index 7b5acae65b..a9e200706d 100644 --- a/client/components/admin/admin-users-edit.vue +++ b/client/components/admin/admin-users-edit.vue @@ -499,9 +499,9 @@ export default { { text: '(GMT-03:00) Rothera', value: 'Antarctica/Rothera' }, { text: '(GMT-03:00) Salvador', value: 'America/Bahia' }, { text: '(GMT-03:00) Santiago', value: 'America/Santiago' }, + { text: '(GMT-03:00) Sao Paulo', value: 'America/Sao_Paulo' }, { text: '(GMT-03:00) Stanley', value: 'Atlantic/Stanley' }, { text: '(GMT-02:00) Noronha', value: 'America/Noronha' }, - { text: '(GMT-02:00) Sao Paulo', value: 'America/Sao_Paulo' }, { text: '(GMT-02:00) South Georgia', value: 'Atlantic/South_Georgia' }, { text: '(GMT-01:00) Azores', value: 'Atlantic/Azores' }, { text: '(GMT-01:00) Cape Verde', value: 'Atlantic/Cape_Verde' }, diff --git a/client/components/profile/profile.vue b/client/components/profile/profile.vue index 918cb6d307..345476d271 100644 --- a/client/components/profile/profile.vue +++ b/client/components/profile/profile.vue @@ -469,9 +469,9 @@ export default { { text: '(GMT-03:00) Rothera', value: 'Antarctica/Rothera' }, { text: '(GMT-03:00) Salvador', value: 'America/Bahia' }, { text: '(GMT-03:00) Santiago', value: 'America/Santiago' }, + { text: '(GMT-03:00) Sao Paulo', value: 'America/Sao_Paulo' }, { text: '(GMT-03:00) Stanley', value: 'Atlantic/Stanley' }, { text: '(GMT-02:00) Noronha', value: 'America/Noronha' }, - { text: '(GMT-02:00) Sao Paulo', value: 'America/Sao_Paulo' }, { text: '(GMT-02:00) South Georgia', value: 'Atlantic/South_Georgia' }, { text: '(GMT-01:00) Azores', value: 'Atlantic/Azores' }, { text: '(GMT-01:00) Cape Verde', value: 'Atlantic/Cape_Verde' }, From 15206efc57cb1cae49744a87e8b5b337a99df309 Mon Sep 17 00:00:00 2001 From: adroslice Date: Sun, 2 Oct 2022 21:52:39 +0200 Subject: [PATCH 040/164] fix: comment edit not updating original content (#5646) --- server/modules/comments/default/comment.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/modules/comments/default/comment.js b/server/modules/comments/default/comment.js index 53b05bf1d9..fa819c8bbe 100644 --- a/server/modules/comments/default/comment.js +++ b/server/modules/comments/default/comment.js @@ -126,6 +126,7 @@ module.exports = { async update ({ id, content, user }) { const renderedContent = DOMPurify.sanitize(mkdown.render(content)) await WIKI.models.comments.query().findById(id).patch({ + content, render: renderedContent }) return renderedContent From 485e99c7fd194e7201cc9ac1bcfc850775b3f608 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Sun, 2 Oct 2022 23:49:47 -0400 Subject: [PATCH 041/164] docs: update BACKERS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 96e34cabf5..b2cb4690cf 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - Florian Moss ([@florianmoss](https://github.com/florianmoss)) - GoodCorporateCitizen ([@GoodCorporateCitizen](https://github.com/GoodCorporateCitizen)) - HeavenBay ([@HeavenBay](https://github.com/heavenbay)) +- HikaruEgashira ([@HikaruEgashira](https://github.com/HikaruEgashira)) - Ian Hyzy ([@ianhyzy](https://github.com/ianhyzy)) - Jaimyn Mayer ([@jabelone](https://github.com/jabelone)) - Jay Lee ([@polyglotm](https://github.com/polyglotm)) From 17c11b3f4e2bad9c2fdbb9071c1aa5500713d6eb Mon Sep 17 00:00:00 2001 From: cleaverm Date: Tue, 4 Oct 2022 21:20:54 +0200 Subject: [PATCH 042/164] fix: typo in letsencrypt.js logging output (#5712) --- server/core/letsencrypt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/letsencrypt.js b/server/core/letsencrypt.js index bbad33da5a..246d0e473b 100644 --- a/server/core/letsencrypt.js +++ b/server/core/letsencrypt.js @@ -113,7 +113,7 @@ module.exports = { } } }) - WIKI.logger.info(`(LETSENCRYPT) New certifiate received successfully: [ COMPLETED ]`) + WIKI.logger.info(`(LETSENCRYPT) New certificate received successfully: [ COMPLETED ]`) WIKI.config.letsencrypt.payload = certResp WIKI.config.letsencrypt.domain = WIKI.config.ssl.domain await WIKI.configSvc.saveToDb(['letsencrypt']) From cf7abeaa9403cac1edb5b0995b51891ef7307bbe Mon Sep 17 00:00:00 2001 From: yuta <35091804+vampire-yuta@users.noreply.github.com> Date: Wed, 5 Oct 2022 04:26:09 +0900 Subject: [PATCH 043/164] chore(helm): add loadBalancerIP param (#5704) --- dev/helm/templates/service.yaml | 3 +++ dev/helm/values.yaml | 1 + 2 files changed, 4 insertions(+) diff --git a/dev/helm/templates/service.yaml b/dev/helm/templates/service.yaml index 5b27cb7ed3..62bcff25ba 100644 --- a/dev/helm/templates/service.yaml +++ b/dev/helm/templates/service.yaml @@ -11,6 +11,9 @@ metadata: {{- end }} spec: type: {{.Values.service.type}} + {{- if eq .Values.service.type "LoadBalancer" }} + loadBalancerIP: {{ default "" .Values.service.loadBalancerIP }} + {{- end }} ports: - port: {{ default "80" .Values.service.port}} targetPort: http diff --git a/dev/helm/values.yaml b/dev/helm/values.yaml index 1a450d6e30..a61d53e02e 100644 --- a/dev/helm/values.yaml +++ b/dev/helm/values.yaml @@ -61,6 +61,7 @@ service: # type: LoadBalancer # httpsPort: 443 # annotations: {} + # loadBalancerIP: 172.16.0.1 ingress: enabled: true From db0255cb7cd35c7cb8ad256f10723c69a9443478 Mon Sep 17 00:00:00 2001 From: Rodrigo Ribeiro Gomes Date: Mon, 17 Oct 2022 18:11:59 -0300 Subject: [PATCH 044/164] fix: add missing scriptJs and scriptCss to single page resolver (#5689) --- server/graph/resolvers/page.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/graph/resolvers/page.js b/server/graph/resolvers/page.js index e356ac0f35..15631a18a8 100644 --- a/server/graph/resolvers/page.js +++ b/server/graph/resolvers/page.js @@ -159,7 +159,9 @@ module.exports = { return { ...page, locale: page.localeCode, - editor: page.editorKey + editor: page.editorKey, + scriptJs: page.extra.js, + scriptCss: page.extra.css } } else { throw new WIKI.Error.PageViewForbidden() From 98e199a0095a2b520133844051bfb3bf150efe5e Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 17 Oct 2022 21:28:25 -0400 Subject: [PATCH 045/164] docs: update BACKERS --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index b2cb4690cf..d963606e0b 100644 --- a/README.md +++ b/README.md @@ -352,6 +352,23 @@ Support this project by becoming a sponsor. Your logo will show up in the Contri + + + + + + + + + + + + + + + + +
From e6bbf9d088def4b44a7f1d94bfa092c6f0ec5b8e Mon Sep 17 00:00:00 2001 From: Andrei Senchuk <169769+asenchuk@users.noreply.github.com> Date: Tue, 25 Oct 2022 03:04:25 +0300 Subject: [PATCH 046/164] fix: oidc module - map() call on undefined; fix unrelate() usage (#5781) --- server/modules/authentication/oidc/authentication.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/modules/authentication/oidc/authentication.js b/server/modules/authentication/oidc/authentication.js index ae3811116c..bea659f27a 100644 --- a/server/modules/authentication/oidc/authentication.js +++ b/server/modules/authentication/oidc/authentication.js @@ -32,13 +32,13 @@ module.exports = { if (conf.mapGroups) { const groups = _.get(profile, '_json.' + conf.groupsClaim) if (groups && _.isArray(groups)) { - const currentGroups = (await user.$relatedQuery('groups').select('groups.id')).groups.map(g => g.id) + const currentGroups = (await user.$relatedQuery('groups').select('groups.id')).map(g => g.id) const expectedGroups = Object.values(WIKI.auth.groups).filter(g => groups.includes(g.name)).map(g => g.id) for (const groupId of _.difference(expectedGroups, currentGroups)) { await user.$relatedQuery('groups').relate(groupId) } for (const groupId of _.difference(currentGroups, expectedGroups)) { - await user.$relatedQuery('groups').unrelate(groupId) + await user.$relatedQuery('groups').unrelate().where('groupId', groupId) } } } From bc6d1592b4ebde503dc131974efa57ca51624de1 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Wed, 26 Oct 2022 19:19:49 -0400 Subject: [PATCH 047/164] docs: update BACKERS --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d963606e0b..10226b20a1 100644 --- a/README.md +++ b/README.md @@ -400,22 +400,25 @@ Thank you to all our patrons! 🙏 [[Become a patron](https://www.patreon.com/re - Hope - Ian - Imari Childress +- Iskander Callos -- Iskander Callos - Josh Stewart - Justin Dunsworth - Keir - Loïc CRAMPON - Ludgeir Ibanez +- Lyn Matten +- Mads Rosendahl - Mark Mansur - Matt Gedigian - Nate Figz - Patryk - Philipp Schürch - Tracey Duffy +- Quaxim - Richeir - Shad Narcher - SmartNET.works From 1bb9be0e62a8ba866579d3571558dda956c8c731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=9D=E9=9B=B6?= <78294929+JiuLing-zhang@users.noreply.github.com> Date: Thu, 27 Oct 2022 22:41:20 +0800 Subject: [PATCH 048/164] fix: admin contribute link address. (#5791) --- client/components/admin/admin-contribute.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/admin/admin-contribute.vue b/client/components/admin/admin-contribute.vue index e13507faf9..e3d85851c2 100644 --- a/client/components/admin/admin-contribute.vue +++ b/client/components/admin/admin-contribute.vue @@ -184,7 +184,7 @@ v-list-item-title Netlify v-list-item-subtitle Deploy modern static websites with Netlify. Get CDN, Continuous deployment, 1-click HTTPS, and all the services you need. v-list-item-action - v-btn(icon, href='https://wwwnetlify.com', target='_blank') + v-btn(icon, href='https://www.netlify.com', target='_blank') v-icon(color='grey') mdi-earth From 6857937e19ebb9871372e630c53191175d5e0001 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Thu, 27 Oct 2022 16:24:52 -0400 Subject: [PATCH 049/164] docs: update BACKERS --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 10226b20a1..53136766f2 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,12 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - + + + + + + From 504f1725a2d497bf5a62416f0ae2cc890359c500 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sun, 30 Oct 2022 00:23:28 -0400 Subject: [PATCH 050/164] chore: update dependencies --- package.json | 36 ++--- yarn.lock | 371 ++++++++++++++++++++++++++++----------------------- 2 files changed, 222 insertions(+), 185 deletions(-) diff --git a/package.json b/package.json index b00007bc1b..78f3c91f9f 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,9 @@ "node": ">=10.12" }, "dependencies": { - "@azure/storage-blob": "12.9.0", + "@azure/storage-blob": "12.12.0", "@exlinc/keycloak-passport": "1.0.2", - "@joplin/turndown-plugin-gfm": "1.0.43", + "@joplin/turndown-plugin-gfm": "1.0.45", "@root/csr": "0.8.1", "@root/keypairs": "0.10.3", "@root/pem": "1.0.4", @@ -53,7 +53,7 @@ "azure-search-client": "3.1.5", "bcryptjs-then": "1.0.1", "bluebird": "3.7.2", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "chalk": "4.1.0", "cheerio": "1.0.0-rc.5", "chokidar": "3.5.3", @@ -74,10 +74,10 @@ "elasticsearch6": "npm:@elastic/elasticsearch@6", "elasticsearch7": "npm:@elastic/elasticsearch@7", "emoji-regex": "9.2.2", - "eventemitter2": "6.4.5", - "express": "4.18.1", + "eventemitter2": "6.4.9", + "express": "4.18.2", "express-brute": "1.0.1", - "express-session": "1.17.2", + "express-session": "1.17.3", "file-type": "15.0.1", "filesize": "6.1.0", "fs-extra": "9.0.1", @@ -119,8 +119,8 @@ "markdown-it-task-lists": "2.1.1", "mathjax": "3.1.2", "mime-types": "2.1.35", - "moment": "2.29.3", - "moment-timezone": "0.5.31", + "moment": "2.29.4", + "moment-timezone": "0.5.38", "mongodb": "3.6.5", "ms": "2.1.3", "mssql": "6.2.3", @@ -129,11 +129,11 @@ "nanoid": "3.2.0", "node-2fa": "1.1.2", "node-cache": "5.1.2", - "nodemailer": "6.7.4", + "nodemailer": "6.8.0", "objection": "2.2.18", "passport": "0.4.1", - "passport-auth0": "1.4.2", - "passport-azure-ad": "4.3.1", + "passport-auth0": "1.4.3", + "passport-azure-ad": "4.3.4", "passport-cas": "0.1.1", "passport-discord": "0.1.4", "passport-dropbox-oauth2": "1.1.0", @@ -147,12 +147,12 @@ "passport-microsoft": "0.1.0", "passport-oauth2": "1.6.1", "passport-okta-oauth": "0.0.1", - "passport-openidconnect": "0.0.2", - "passport-saml": "3.2.1", + "passport-openidconnect": "0.1.1", + "passport-saml": "3.2.4", "passport-slack-oauth2": "1.1.1", "passport-twitch-strategy": "2.2.0", "pem-jwk": "2.0.0", - "pg": "8.4.1", + "pg": "8.8.0", "pg-hstore": "2.3.4", "pg-pubsub": "0.5.0", "pg-query-stream": "3.3.1", @@ -167,13 +167,13 @@ "safe-regex": "2.1.1", "sanitize-filename": "1.6.3", "scim-query-filter-parser": "2.0.4", - "semver": "7.3.7", + "semver": "7.3.8", "serve-favicon": "2.5.0", "simple-git": "2.21.0", "solr-node": "1.2.1", "sqlite3": "5.0.6", "ssh2": "1.5.0", - "ssh2-promise": "1.0.2", + "ssh2-promise": "1.0.3", "striptags": "3.2.0", "subscriptions-transport-ws": "0.9.18", "tar-fs": "2.1.1", @@ -183,7 +183,7 @@ "uuid": "8.3.2", "validate.js": "0.13.1", "winston": "3.3.3", - "xss": "1.0.11", + "xss": "1.0.14", "yargs": "16.1.0" }, "devDependencies": { @@ -228,7 +228,7 @@ "cash-dom": "8.1.1", "chart.js": "2.9.4", "clean-webpack-plugin": "3.0.0", - "clipboard": "2.0.10", + "clipboard": "2.0.11", "codemirror": "5.58.2", "copy-webpack-plugin": "6.2.1", "core-js": "3.6.5", diff --git a/yarn.lock b/yarn.lock index c23b638b5e..ff2a8969d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -278,10 +278,10 @@ "@azure/ms-rest-js" "^1.8.7" adal-node "^0.1.28" -"@azure/storage-blob@12.9.0": - version "12.9.0" - resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.9.0.tgz#4cbd8b4c7a47dd064867430db892f4ef2d8f17ab" - integrity sha512-ank38FdCLfJ+EoeMzCz3hkYJuZAd63ARvDKkxZYRDb+beBYf+/+gx8jNTqkq/hfyUl4dJQ/a7tECU0Y0F98CHg== +"@azure/storage-blob@12.12.0": + version "12.12.0" + resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.12.0.tgz#25e277c885692d5adcd8c2a949789b2837a74c59" + integrity sha512-o/Mf6lkyYG/eBW4/hXB9864RxVNmAkcKHjsGR6Inlp5hupa3exjSyH2KjO3tLO//YGA+tS+17hM2bxRl9Sn16g== dependencies: "@azure/abort-controller" "^1.0.0" "@azure/core-http" "^2.0.0" @@ -3229,10 +3229,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@joplin/turndown-plugin-gfm@1.0.43": - version "1.0.43" - resolved "https://registry.yarnpkg.com/@joplin/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.43.tgz#a495708f7043af30c0d43ef34c6d60d3952ba36d" - integrity sha512-d0Qji9JT8vyCjPMfWCPgOCOA9naJlY9Yihumi2n3+FEnVJuu55gTpJzUNzA0TY5f1EDTbHtQYiFM56vkisjwgw== +"@joplin/turndown-plugin-gfm@1.0.45": + version "1.0.45" + resolved "https://registry.yarnpkg.com/@joplin/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.45.tgz#c37cb58ecad97a6385fc27350b7aead8236e30c6" + integrity sha512-RUQfMrFqFp2wB0mOZPGOTq6LVUVBOhQg87+ecv1+qF2gTHZm3jQd77iV5Eddbg2WjCj06eCG99et3kdPf0YwVw== "@josephg/resolvable@^1.0.0": version "1.0.1" @@ -4312,11 +4312,16 @@ dependencies: tslib "^1.9.3" -"@xmldom/xmldom@^0.7.0", "@xmldom/xmldom@^0.7.5": +"@xmldom/xmldom@^0.7.0": version "0.7.5" resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d" integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A== +"@xmldom/xmldom@^0.7.6": + version "0.7.7" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.7.tgz#16bd8a4e5c953018b8168e5d0a7d26b117cd7fa9" + integrity sha512-RwEdIYho2kjbSZ7fpvhkHy5wk1Y3x0O6e/EHL3/SoiAfFWH+yhV2/XZQvsBoAeGRNFwgScJS/gRZv+uIwoj7yA== + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -5240,10 +5245,10 @@ async-retry@^1.2.1: dependencies: retry "0.12.0" -async@1.5.2, async@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= +async@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" + integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== async@>=0.6.0: version "3.1.0" @@ -5255,6 +5260,11 @@ async@^3.1.0, async@^3.2.0: resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -5346,12 +5356,13 @@ axios@^0.19.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -axios@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.22.0.tgz#bf702c41fb50fbca4539589d839a077117b79b25" - integrity sha512-Z0U3uhqQeg1oNcihswf4ZD57O3NrR1+ZXhxaROaWpDmsDTx7T2HNBV2ulBtie2hwJptu8UvgnJoK+BIqdzh/1w== +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== dependencies: - follow-redirects "^1.14.4" + follow-redirects "^1.14.9" + form-data "^4.0.0" azure-search-client@3.1.5: version "3.1.5" @@ -5735,10 +5746,10 @@ body-parser@1.19.0, body-parser@^1.18.3: raw-body "2.4.0" type-is "~1.6.17" -body-parser@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== dependencies: bytes "3.1.2" content-type "~1.0.4" @@ -5748,7 +5759,7 @@ body-parser@1.20.0: http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.10.3" + qs "6.11.0" raw-body "2.5.1" type-is "~1.6.18" unpipe "1.0.0" @@ -5988,6 +5999,11 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "~3.7.0" +buildcheck@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.3.tgz#70451897a95d80f7807e68fc412eb2e7e35ff4d5" + integrity sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA== + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -6128,14 +6144,14 @@ cache-loader@4.1.0: neo-async "^2.6.1" schema-utils "^2.0.0" -cache-manager@2.10.2: - version "2.10.2" - resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-2.10.2.tgz#7ecabfb82db9e80290dc6705f3a555ded1c9cc8c" - integrity sha512-VueuJaWPfugreadk88pZ23g0nGVd4qqG4Y8X8y9LQePEN+EhaDlXbJM5pbJB0CdpuTmqVPCmcWgtEDxLqbT1zw== +cache-manager@^3.6.1: + version "3.6.3" + resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-3.6.3.tgz#48052f3cf9ee4bac1cbb6adeedd69faf9da4ec04" + integrity sha512-dS4DnV6c6cQcVH5OxzIU1XZaACXwvVIiUPkFytnRmLOACuBGv3GQgRQ1RJGRRw4/9DF14ZK2RFlZu1TUgDniMg== dependencies: - async "1.5.2" - lodash.clonedeep "4.5.0" - lru-cache "4.0.0" + async "3.2.3" + lodash.clonedeep "^4.5.0" + lru-cache "6.0.0" cachedir@^2.3.0: version "2.3.0" @@ -6564,10 +6580,10 @@ cli-truncate@^0.2.1: slice-ansi "0.0.4" string-width "^1.0.1" -clipboard@2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.10.tgz#e61f6f7139ac5044c58c0484dcac9fb2a918bfd6" - integrity sha512-cz3m2YVwFz95qSEbCDi2fzLN/epEN9zXBvfgAoGkvGOJZATMl9gtTDVOtBYkx2ODUJl2kvmud7n32sV2BpYR4g== +clipboard@2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5" + integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw== dependencies: good-listener "^1.2.2" select "^1.1.2" @@ -7024,6 +7040,11 @@ cookie@0.4.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== +cookie@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + cookie@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" @@ -7147,6 +7168,14 @@ cpu-features@0.0.2: dependencies: nan "^2.14.1" +cpu-features@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.4.tgz#0023475bb4f4c525869c162e4108099e35bf19d8" + integrity sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A== + dependencies: + buildcheck "0.0.3" + nan "^2.15.0" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -9228,10 +9257,10 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -eventemitter2@6.4.5: - version "6.4.5" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.5.tgz#97380f758ae24ac15df8353e0cc27f8b95644655" - integrity sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw== +eventemitter2@6.4.9: + version "6.4.9" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.9.tgz#41f2750781b4230ed58827bc119d293471ecb125" + integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg== eventemitter2@^6.4.2: version "6.4.3" @@ -9366,12 +9395,12 @@ express-brute@1.0.1: long-timeout "~0.1.1" underscore "~1.8.3" -express-session@1.17.2: - version "1.17.2" - resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.2.tgz#397020374f9bf7997f891b85ea338767b30d0efd" - integrity sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ== +express-session@1.17.3: + version "1.17.3" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.3.tgz#14b997a15ed43e5949cb1d073725675dd2777f36" + integrity sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw== dependencies: - cookie "0.4.1" + cookie "0.4.2" cookie-signature "1.0.6" debug "2.6.9" depd "~2.0.0" @@ -9380,14 +9409,14 @@ express-session@1.17.2: safe-buffer "5.2.1" uid-safe "~2.1.5" -express@4.18.1: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== +express@4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.0" + body-parser "1.20.1" content-disposition "0.5.4" content-type "~1.0.4" cookie "0.5.0" @@ -9406,7 +9435,7 @@ express@4.18.1: parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.10.3" + qs "6.11.0" range-parser "~1.2.1" safe-buffer "5.2.1" send "0.18.0" @@ -9876,10 +9905,10 @@ follow-redirects@1.5.10: dependencies: debug "=3.1.0" -follow-redirects@^1.14.4: - version "1.14.7" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" - integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== +follow-redirects@^1.14.9: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" @@ -12664,10 +12693,10 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= -lodash.clonedeep@4.5.0: +lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== lodash.includes@^4.3.0: version "4.3.0" @@ -12832,13 +12861,12 @@ lower-case@^2.0.1: dependencies: tslib "^1.10.0" -lru-cache@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.0.tgz#b5cbf01556c16966febe54ceec0fb4dc90df6c28" - integrity sha1-tcvwFVbBaWb+vlTO7A+03JDfbCg= +lru-cache@6.0.0, lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: - pseudomap "^1.0.1" - yallist "^2.0.0" + yallist "^4.0.0" lru-cache@^4.1.2, lru-cache@^4.1.3, lru-cache@^4.1.5: version "4.1.5" @@ -12855,13 +12883,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - luxon@1.25.0: version "1.25.0" resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.25.0.tgz#d86219e90bc0102c0eb299d65b2f5e95efe1fe72" @@ -13489,17 +13510,17 @@ moment-timezone-data-webpack-plugin@1.3.0: find-cache-dir "^3.0.0" make-dir "^3.0.0" -moment-timezone@0.5.31: - version "0.5.31" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.31.tgz#9c40d8c5026f0c7ab46eda3d63e49c155148de05" - integrity sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA== +moment-timezone@0.5.38: + version "0.5.38" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.38.tgz#9674a5397b8be7c13de820fd387d8afa0f725aad" + integrity sha512-nMIrzGah4+oYZPflDvLZUgoVUO4fvAqHstvG3xAUnMolWncuAiLDWNnJZj6EwJGMGfb1ZcuTFE6GI3hNOVWI/Q== dependencies: moment ">= 2.9.0" -moment@2.29.3: - version "2.29.3" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" - integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== +moment@2.29.4: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== "moment@>= 2.9.0", moment@^2.10.2, moment@^2.19.2, moment@^2.22.1: version "2.24.0" @@ -13619,6 +13640,11 @@ nan@^2.14.1, nan@^2.15.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== +nan@^2.16.0: + version "2.17.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" + integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== + nanoid@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" @@ -13901,10 +13927,10 @@ node-uuid@1.4.1: resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.1.tgz#39aef510e5889a3dca9c895b506c73aae1bac048" integrity sha1-Oa71EOWImj3KnIlbUGxzquG6wEg= -nodemailer@6.7.4: - version "6.7.4" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.4.tgz#28771bda3dda8f2dad1912aca0f8727ce7f09d89" - integrity sha512-TBSS3qS8WG45ycUwEvEA/3UM1o3sLz9jUl4TPUKPz4ImWWM6UgRCb5pLO+HOouDKEj57yNLOrzQlO8+9IjWZoA== +nodemailer@6.8.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.8.0.tgz#804bcc5256ee5523bc914506ee59f8de8f0b1cd5" + integrity sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ== nopt@1.0.10: version "1.0.10" @@ -14558,31 +14584,30 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -passport-auth0@1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/passport-auth0/-/passport-auth0-1.4.2.tgz#a4464f3ad1a44ea13cc688258babfdc9645205e9" - integrity sha512-cIPIhN0WbgXWxU0VrKXLT0eF/3jeZ6JJwkypUMpxjH4MOVDIUfU0qBeZBVZySd8WkkIzRNG/EY0lZqKflYJIFA== +passport-auth0@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/passport-auth0/-/passport-auth0-1.4.3.tgz#8034b5fbf75706e95b1b97627c4caa18af6f96c5" + integrity sha512-jTOY8xV0OZfhZ32gs74p64CCkOSdVohMFIqLE46/ji3qUkA5mBzfOr5FMGXnraLpVzl6Phkn0TbxYbUIll3dxA== dependencies: - axios "^0.22.0" + axios "^0.27.2" passport-oauth "^1.0.0" passport-oauth2 "^1.6.0" -passport-azure-ad@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/passport-azure-ad/-/passport-azure-ad-4.3.1.tgz#2935d0d65ca6c5d1cc73b7ba0685ea69d249e1f0" - integrity sha512-QM/GFbwpbIRO5MVLB4kkhCaskUkgKzeujYzcnxicqXh4c2M9m1M5sCvVtiJUVXaG6fMthX2Dqvl36Psn/ia84w== +passport-azure-ad@4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/passport-azure-ad/-/passport-azure-ad-4.3.4.tgz#2f1c3f64003df974b60390ece70d106336336f46" + integrity sha512-veG3IT/ovfFaMK3IREcVGLYa8nx/91s10eeMcfJmvofHG7Uv6FVElrnDA2E1CgQdE6hdWzG28UV8ITw6Qhocxg== dependencies: - async "^1.5.2" + async "^3.2.3" base64url "^3.0.0" bunyan "^1.8.14" - cache-manager "2.10.2" + cache-manager "^3.6.1" https-proxy-agent "^5.0.0" jws "^3.1.3" lodash "^4.11.2" node-jose "^2.0.0" oauth "0.9.15" - passport "^0.4.1" - request "^2.72.0" + passport "^0.6.0" valid-url "^1.0.6" passport-cas@0.1.1: @@ -14725,22 +14750,20 @@ passport-okta-oauth@0.0.1: pkginfo "0.2.x" uid2 "0.0.3" -passport-openidconnect@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/passport-openidconnect/-/passport-openidconnect-0.0.2.tgz#e488f8bdb386c9a9fd39c91d5ab8c880156e8153" - integrity sha1-5Ij4vbOGyan9OckdWrjIgBVugVM= +passport-openidconnect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/passport-openidconnect/-/passport-openidconnect-0.1.1.tgz#83921ff5f87f634079f65262dada834af1972244" + integrity sha512-r0QJiWEzwCg2MeCIXVP5G6YxVRqnEsZ2HpgKRthZ9AiQHJrgGUytXpsdcGF9BRwd3yMrEesb/uG/Yxb86rrY0g== dependencies: oauth "0.9.x" passport-strategy "1.x.x" - request "^2.75.0" - webfinger "0.4.x" -passport-saml@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/passport-saml/-/passport-saml-3.2.1.tgz#c489a61a4c2dd93ddec1d53952a595b9f33e15e8" - integrity sha512-Y8aD94B6MTLht57BlBrDauEgvtWjuSeINKk7NadXlpT/OBmsoGGYPpb0FJeBtdyGX4GEbZARAkxvBEqsL8E7XQ== +passport-saml@3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/passport-saml/-/passport-saml-3.2.4.tgz#e8e9523f954988a3a47d12e425d7fa0f20a74dc9" + integrity sha512-JSgkFXeaexLNQh1RrOvJAgjLnZzH/S3HbX/mWAk+i7aulnjqUe7WKnPl1NPnJWqP7Dqsv0I2Xm6KIFHkftk0HA== dependencies: - "@xmldom/xmldom" "^0.7.5" + "@xmldom/xmldom" "^0.7.6" debug "^4.3.2" passport-strategy "^1.0.0" xml-crypto "^2.1.3" @@ -14769,7 +14792,7 @@ passport-twitch-strategy@2.2.0: node-fetch "^2.6.1" passport-oauth2 "^1.5.0" -passport@0.4.1, passport@^0.4.1: +passport@0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== @@ -14777,6 +14800,15 @@ passport@0.4.1, passport@^0.4.1: passport-strategy "1.x.x" pause "0.0.1" +passport@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.6.0.tgz#e869579fab465b5c0b291e841e6cc95c005fac9d" + integrity sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + utils-merge "^1.0.1" + path-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" @@ -14930,10 +14962,10 @@ pg-connection-string@2.3.0: resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.3.0.tgz#c13fcb84c298d0bfa9ba12b40dd6c23d946f55d6" integrity sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w== -pg-connection-string@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10" - integrity sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ== +pg-connection-string@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" + integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== pg-cursor@^2.4.1: version "2.4.1" @@ -14967,15 +14999,15 @@ pg-pool@^2.0.10: resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.10.tgz#842ee23b04e86824ce9d786430f8365082d81c4a" integrity sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg== -pg-pool@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.2.1.tgz#5f4afc0f58063659aeefa952d36af49fa28b30e0" - integrity sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA== +pg-pool@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.5.2.tgz#ed1bed1fb8d79f1c6fd5fb1c99e990fbf9ddf178" + integrity sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w== -pg-protocol@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.3.0.tgz#3c8fb7ca34dbbfcc42776ce34ac5f537d6e34770" - integrity sha512-64/bYByMrhWULUaCd+6/72c9PMWhiVFs3EVxl9Ct6a3v/U8+rKgqP2w+kKg/BIGgMJyB+Bk/eNivT32Al+Jghw== +pg-protocol@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0" + integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ== pg-pubsub@0.5.0: version "0.5.0" @@ -15011,16 +15043,16 @@ pg-types@^2.1.0: postgres-date "~1.0.4" postgres-interval "^1.1.0" -pg@8.4.1: - version "8.4.1" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.4.1.tgz#06cfb6208ae787a869b2f0022da11b90d13d933e" - integrity sha512-NRsH0aGMXmX1z8Dd0iaPCxWUw4ffu+lIAmGm+sTCwuDDWkpEgRCAHZYDwqaNhC5hG5DRMOjSUFasMWhvcmLN1A== +pg@8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.8.0.tgz#a77f41f9d9ede7009abfca54667c775a240da686" + integrity sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw== dependencies: buffer-writer "2.0.0" packet-reader "1.0.0" - pg-connection-string "^2.4.0" - pg-pool "^3.2.1" - pg-protocol "^1.3.0" + pg-connection-string "^2.5.0" + pg-pool "^3.5.2" + pg-protocol "^1.5.0" pg-types "^2.1.0" pgpass "1.x" @@ -16283,7 +16315,7 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -pseudomap@^1.0.1, pseudomap@^1.0.2: +pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= @@ -16559,10 +16591,10 @@ qr-image@3.2.0: resolved "https://registry.yarnpkg.com/qr-image/-/qr-image-3.2.0.tgz#9fa8295beae50c4a149cf9f909a1db464a8672e8" integrity sha1-n6gpW+rlDEoUnPn5CaHbRkqGcug= -qs@6.10.3, qs@^6.10.3: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" @@ -16576,6 +16608,13 @@ qs@6.9.3: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== +qs@^6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + qs@^6.5.1: version "6.8.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.8.0.tgz#87b763f0d37ca54200334cd57bb2ef8f68a1d081" @@ -17164,7 +17203,7 @@ request@2.88.2, request@^2.88.2: tunnel-agent "^0.6.0" uuid "^3.3.2" -"request@>= 2.52.0", request@^2.72.0, request@^2.75.0: +"request@>= 2.52.0": version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -17555,7 +17594,7 @@ sax@1.2.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= -sax@>=0.1.1, sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: +sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -17658,10 +17697,10 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.7, semver@^7.3.5, semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== dependencies: lru-cache "^6.0.0" @@ -17675,6 +17714,13 @@ semver@^7.2.1, semver@^7.3.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== +semver@^7.3.5, semver@^7.3.7: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -18133,15 +18179,15 @@ sqlstring@^2.3.2: resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.2.tgz#cdae7169389a1375b18e885f2e60b3e460809514" integrity sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg== -ssh2-promise@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ssh2-promise/-/ssh2-promise-1.0.2.tgz#50f1dc18c9898a93a62c3c5873ae60a66fff1af1" - integrity sha512-W+nNjW/kGSZn/Ln2wrjo/hlC4ZlCDyLck2FAY7zv72IA4ULPyybVdjVB31SzGFuLY+zlauc4SFGEICDlpVdVAg== +ssh2-promise@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ssh2-promise/-/ssh2-promise-1.0.3.tgz#7c890e3f27536abf02b55337a307e49420004dda" + integrity sha512-842MuERRLuGdTneOZhc5HeogBtGFI/WeeJ9LH3Jp+eB57av8hHGDzxZqgWuQmuxVDniRf7B+agSfgc2wKfLY4w== dependencies: "@heroku/socksv5" "^0.0.9" - ssh2 "^1.4.0" + ssh2 "^1.10.0" -ssh2@1.5.0, ssh2@^1.4.0: +ssh2@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.5.0.tgz#4dc559ba98a1cbb420e8d42998dfe35d0eda92bc" integrity sha512-iUmRkhH9KGeszQwDW7YyyqjsMTf4z+0o48Cp4xOwlY5LjtbIAvyd3fwnsoUZW/hXmTCRA3yt7S/Jb9uVjErVlA== @@ -18152,6 +18198,17 @@ ssh2@1.5.0, ssh2@^1.4.0: cpu-features "0.0.2" nan "^2.15.0" +ssh2@^1.10.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.11.0.tgz#ce60186216971e12f6deb553dcf82322498fe2e4" + integrity sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw== + dependencies: + asn1 "^0.2.4" + bcrypt-pbkdf "^1.0.2" + optionalDependencies: + cpu-features "~0.0.4" + nan "^2.16.0" + sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -18235,11 +18292,6 @@ stealthy-require@^1.1.1: resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= -step@0.0.x: - version "0.0.6" - resolved "https://registry.yarnpkg.com/step/-/step-0.0.6.tgz#143e7849a5d7d3f4a088fe29af94915216eeede2" - integrity sha1-FD54SaXX0/SgiP4pr5SRUhbu7eI= - stoppable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" @@ -19471,7 +19523,7 @@ utila@^0.4.0, utila@~0.4: resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= -utils-merge@1.0.1, utils-merge@1.x.x: +utils-merge@1.0.1, utils-merge@1.x.x, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= @@ -19824,14 +19876,6 @@ watchpack@^1.7.4: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.0" -webfinger@0.4.x: - version "0.4.2" - resolved "https://registry.yarnpkg.com/webfinger/-/webfinger-0.4.2.tgz#3477a6d97799461896039fcffc650b73468ee76d" - integrity sha1-NHem2XeZRhiWA5/P/GULc0aO520= - dependencies: - step "0.0.x" - xml2js "0.1.x" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -20282,13 +20326,6 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xml2js@0.1.x: - version "0.1.14" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.1.14.tgz#5274e67f5a64c5f92974cd85139e0332adc6b90c" - integrity sha1-UnTmf1pkxfkpdM2FE54DMq3GuQw= - dependencies: - sax ">=0.1.1" - xml2js@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" @@ -20362,10 +20399,10 @@ xpath@0.0.32: resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.32.tgz#1b73d3351af736e17ec078d6da4b8175405c48af" integrity sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw== -xss@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.11.tgz#211cb82e95b5071d4c75d597283c021157ebe46a" - integrity sha512-EimjrjThZeK2MO7WKR9mN5ZC1CSqivSl55wvUK5EtU6acf0rzEE1pN+9ZDrFXJ82BRp3JL38pPE6S4o/rpp1zQ== +xss@1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.14.tgz#4f3efbde75ad0d82e9921cc3c95e6590dd336694" + integrity sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw== dependencies: commander "^2.20.3" cssfilter "0.0.10" @@ -20408,7 +20445,7 @@ yaeti@^0.0.6: resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= -yallist@^2.0.0, yallist@^2.1.2: +yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= From 1893fd499af00a226b7490b421d48313a1d2ac3a Mon Sep 17 00:00:00 2001 From: Simon Lichtinghagen <2264757+silicht@users.noreply.github.com> Date: Mon, 7 Nov 2022 14:41:31 +0100 Subject: [PATCH 051/164] fix: login with Keycloak 20 by explicit set OAuth scopes (#5808) * Fix login with Keycloak 20 by explicit set OAuth scopes * moved scopes to definition.yml Co-authored-by: Simon Lichtinghagen --- server/modules/authentication/keycloak/definition.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/modules/authentication/keycloak/definition.yml b/server/modules/authentication/keycloak/definition.yml index df8ca666c7..d4ab044cf3 100644 --- a/server/modules/authentication/keycloak/definition.yml +++ b/server/modules/authentication/keycloak/definition.yml @@ -7,6 +7,10 @@ color: blue-grey darken-2 website: https://www.keycloak.org/ useForm: false isAvailable: true +scopes: + - openid + - profile + - email props: host: type: String From 2cb304100c678df824399c682a801d338792873f Mon Sep 17 00:00:00 2001 From: natsutteatsuiyone Date: Tue, 8 Nov 2022 06:47:42 +0900 Subject: [PATCH 052/164] fix: Page Rules based on Tag Matches do not work for comment permissions (#5819) --- server/graph/resolvers/comment.js | 15 ++++++++++++--- server/models/comments.js | 9 ++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/server/graph/resolvers/comment.js b/server/graph/resolvers/comment.js index ff30b55c65..1c8949432d 100644 --- a/server/graph/resolvers/comment.js +++ b/server/graph/resolvers/comment.js @@ -40,9 +40,13 @@ module.exports = { * Fetch list of comments for a page */ async list (obj, args, context) { - const page = await WIKI.models.pages.query().select('id').findOne({ localeCode: args.locale, path: args.path }) + const page = await WIKI.models.pages.query().select('pages.id').findOne({ localeCode: args.locale, path: args.path }) + .withGraphJoined('tags') + .modifyGraph('tags', builder => { + builder.select('tag') + }) if (page) { - if (WIKI.auth.checkAccess(context.req.user, ['read:comments'], args)) { + if (WIKI.auth.checkAccess(context.req.user, ['read:comments'], { tags: page.tags, ...args })) { const comments = await WIKI.models.comments.query().where('pageId', page.id).orderBy('createdAt') return comments.map(c => ({ ...c, @@ -66,10 +70,15 @@ module.exports = { throw new WIKI.Error.CommentNotFound() } const page = await WIKI.models.pages.query().select('localeCode', 'path').findById(cm.pageId) + .withGraphJoined('tags') + .modifyGraph('tags', builder => { + builder.select('tag') + }) if (page) { if (WIKI.auth.checkAccess(context.req.user, ['read:comments'], { path: page.path, - locale: page.localeCode + locale: page.localeCode, + tags: page.tags })) { return { ...cm, diff --git a/server/models/comments.js b/server/models/comments.js index aeaa94db29..0ec5f5c90c 100644 --- a/server/models/comments.js +++ b/server/models/comments.js @@ -99,7 +99,8 @@ module.exports = class Comment extends Model { if (page) { if (!WIKI.auth.checkAccess(user, ['write:comments'], { path: page.path, - locale: page.localeCode + locale: page.localeCode, + tags: page.tags })) { throw new WIKI.Error.CommentPostForbidden() } @@ -136,7 +137,8 @@ module.exports = class Comment extends Model { if (page) { if (!WIKI.auth.checkAccess(user, ['manage:comments'], { path: page.path, - locale: page.localeCode + locale: page.localeCode, + tags: page.tags })) { throw new WIKI.Error.CommentManageForbidden() } @@ -169,7 +171,8 @@ module.exports = class Comment extends Model { if (page) { if (!WIKI.auth.checkAccess(user, ['manage:comments'], { path: page.path, - locale: page.localeCode + locale: page.localeCode, + tags: page.tags })) { throw new WIKI.Error.CommentManageForbidden() } From 445ad05a3d4dbc3278aa778f5602ad3e68862afb Mon Sep 17 00:00:00 2001 From: natsutteatsuiyone Date: Tue, 8 Nov 2022 06:50:47 +0900 Subject: [PATCH 053/164] fix: incompatibility issues with passport-openidconnect@0.1.1 (#5799) * fix: incompatibility issues with passport-openidconnect * fix: remove a trailing semicolon --- server/modules/authentication/oidc/authentication.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/modules/authentication/oidc/authentication.js b/server/modules/authentication/oidc/authentication.js index bea659f27a..de76da4173 100644 --- a/server/modules/authentication/oidc/authentication.js +++ b/server/modules/authentication/oidc/authentication.js @@ -20,7 +20,9 @@ module.exports = { userInfoURL: conf.userInfoURL, callbackURL: conf.callbackURL, passReqToCallback: true - }, async (req, iss, sub, profile, cb) => { + }, async (req, iss, uiProfile, idProfile, context, idToken, accessToken, refreshToken, params, cb) => { + const profile = Object.assign({}, idProfile, uiProfile) + try { const user = await WIKI.models.users.processProfile({ providerKey: req.params.strategy, From d98e0b3cd0774a28c96d77feb4af187b49ab5372 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Tue, 8 Nov 2022 17:56:37 -0500 Subject: [PATCH 054/164] chore: rollback azure blob module to 12.9 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 78f3c91f9f..dc62e85bd8 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "node": ">=10.12" }, "dependencies": { - "@azure/storage-blob": "12.12.0", + "@azure/storage-blob": "12.9.0", "@exlinc/keycloak-passport": "1.0.2", "@joplin/turndown-plugin-gfm": "1.0.45", "@root/csr": "0.8.1", diff --git a/yarn.lock b/yarn.lock index ff2a8969d2..e1b08805a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -278,10 +278,10 @@ "@azure/ms-rest-js" "^1.8.7" adal-node "^0.1.28" -"@azure/storage-blob@12.12.0": - version "12.12.0" - resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.12.0.tgz#25e277c885692d5adcd8c2a949789b2837a74c59" - integrity sha512-o/Mf6lkyYG/eBW4/hXB9864RxVNmAkcKHjsGR6Inlp5hupa3exjSyH2KjO3tLO//YGA+tS+17hM2bxRl9Sn16g== +"@azure/storage-blob@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.9.0.tgz#4cbd8b4c7a47dd064867430db892f4ef2d8f17ab" + integrity sha512-ank38FdCLfJ+EoeMzCz3hkYJuZAd63ARvDKkxZYRDb+beBYf+/+gx8jNTqkq/hfyUl4dJQ/a7tECU0Y0F98CHg== dependencies: "@azure/abort-controller" "^1.0.0" "@azure/core-http" "^2.0.0" From 9fbc25adb8acd1cb7699e8bbfd0fc072cef08312 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Tue, 8 Nov 2022 22:40:43 -0500 Subject: [PATCH 055/164] feat: improve table rendering + add markdown-it-decorate module --- client/components/editor/editor-markdown.vue | 2 + client/themes/default/scss/app.scss | 87 ++++++++++++++++++- package.json | 1 + server/models/pages.js | 5 +- .../modules/rendering/html-core/renderer.js | 10 +++ .../rendering/markdown-core/renderer.js | 2 + yarn.lock | 5 ++ 7 files changed, 107 insertions(+), 5 deletions(-) diff --git a/client/components/editor/editor-markdown.vue b/client/components/editor/editor-markdown.vue index 6134524d9d..38f0f353b6 100644 --- a/client/components/editor/editor-markdown.vue +++ b/client/components/editor/editor-markdown.vue @@ -225,6 +225,7 @@ import './markdown/fold' // Markdown-it import MarkdownIt from 'markdown-it' import mdAttrs from 'markdown-it-attrs' +import mdDecorate from 'markdown-it-decorate' import mdEmoji from 'markdown-it-emoji' import mdTaskLists from 'markdown-it-task-lists' import mdExpandTabs from 'markdown-it-expand-tabs' @@ -288,6 +289,7 @@ const md = new MarkdownIt({ .use(mdAttrs, { allowedAttributes: ['id', 'class', 'target'] }) + .use(mdDecorate) .use(underline) .use(mdEmoji) .use(mdTaskLists, { label: false, labelAfter: false }) diff --git a/client/themes/default/scss/app.scss b/client/themes/default/scss/app.scss index 99f406db4a..8bba5e7250 100644 --- a/client/themes/default/scss/app.scss +++ b/client/themes/default/scss/app.scss @@ -662,13 +662,40 @@ // --------------------------------- table { - margin: .5rem 1.75rem; + margin: .5rem 0; border-spacing: 0; + border-radius: 5px; + border: 1px solid mc('grey', '300'); + + @at-root .theme--dark & { + border-color: mc('grey', '600'); + } + + &.dense { + td, th { + font-size: .85rem; + padding: .5rem; + } + } th { padding: .75rem; border-bottom: 2px solid mc('grey', '500'); color: mc('grey', '600'); + background-color: mc('grey', '100'); + + @at-root .theme--dark & { + background-color: darken(mc('grey', '900'), 8%); + border-bottom-color: mc('grey', '600'); + color: mc('grey', '500'); + } + + &:first-child { + border-top-left-radius: 7px; + } + &:last-child { + border-top-right-radius: 7px; + } } td { @@ -677,7 +704,56 @@ tr { td { - border-bottom: 1px solid mc('grey', '200'); + border-bottom: 1px solid mc('grey', '300'); + border-right: 1px solid mc('grey', '100'); + + @at-root .theme--dark & { + border-bottom-color: mc('grey', '700'); + border-right-color: mc('grey', '800'); + } + + &:nth-child(even) { + background-color: mc('grey', '50'); + + @at-root .theme--dark & { + background-color: darken(mc('grey', '900'), 4%); + } + } + + &:last-child { + border-right: none; + } + } + + &:nth-child(even) { + td { + background-color: mc('grey', '50'); + + @at-root .theme--dark & { + background-color: darken(mc('grey', '800'), 8%); + } + + &:nth-child(even) { + background-color: mc('grey', '100'); + + @at-root .theme--dark & { + background-color: darken(mc('grey', '800'), 10%); + } + } + } + } + + &:last-child { + td { + border-bottom: none; + + &:first-child { + border-bottom-left-radius: 7px; + } + &:last-child { + border-bottom-right-radius: 7px; + } + } } } } @@ -699,6 +775,7 @@ border: 1px solid mc('blue-grey', '100'); box-shadow: inset -1px -1px 0 0 #FFF, inset 1px 0 0 #FFF; padding: .5rem .75rem; + border-radius: 0 !important; @at-root .theme--dark & { border-color: mc('grey', '700'); @@ -735,6 +812,12 @@ } } + // -> Add horizontal scrollbar when table is too wide + .table-container { + width: 100%; + overflow-x: auto; + } + // --------------------------------- // IMAGES // --------------------------------- diff --git a/package.json b/package.json index dc62e85bd8..209f19d021 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "markdown-it": "11.0.1", "markdown-it-abbr": "1.0.4", "markdown-it-attrs": "3.0.3", + "markdown-it-decorate": "1.2.2", "markdown-it-emoji": "1.4.0", "markdown-it-expand-tabs": "1.0.13", "markdown-it-external-links": "0.0.6", diff --git a/server/models/pages.js b/server/models/pages.js index 9bb5d3975c..dc54af9a06 100644 --- a/server/models/pages.js +++ b/server/models/pages.js @@ -959,9 +959,8 @@ module.exports = class Page extends Model { // -> Save render to cache await WIKI.models.pages.savePageToCache(page) } else { - // -> No render? Possible duplicate issue - /* TODO: Detect duplicate and delete */ - throw new Error('Error while fetching page. Duplicate entry detected. Reload the page to try again.') + // -> No render? Last page render failed... + throw new Error('Page has no rendered version. Looks like the Last page render failed. Try to edit the page and save it again.') } } } diff --git a/server/modules/rendering/html-core/renderer.js b/server/modules/rendering/html-core/renderer.js index d470053074..f0ffbec80e 100644 --- a/server/modules/rendering/html-core/renderer.js +++ b/server/modules/rendering/html-core/renderer.js @@ -243,6 +243,16 @@ module.exports = { } }) + // -------------------------------- + // Wrap root table nodes + // -------------------------------- + + $('body').contents().toArray().forEach(item => { + if (item && item.name === 'table' && item.parent.name === 'body') { + $(item).wrap('
') + } + }) + // -------------------------------- // Escape mustache expresions // -------------------------------- diff --git a/server/modules/rendering/markdown-core/renderer.js b/server/modules/rendering/markdown-core/renderer.js index 42bd12be24..5723214e77 100644 --- a/server/modules/rendering/markdown-core/renderer.js +++ b/server/modules/rendering/markdown-core/renderer.js @@ -1,5 +1,6 @@ const md = require('markdown-it') const mdAttrs = require('markdown-it-attrs') +const mdDecorate = require('markdown-it-decorate') const _ = require('lodash') const underline = require('./underline') @@ -42,6 +43,7 @@ module.exports = { mkdown.use(mdAttrs, { allowedAttributes: ['id', 'class', 'target'] }) + mkdown.use(mdDecorate) for (let child of this.children) { const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`) diff --git a/yarn.lock b/yarn.lock index e1b08805a5..825dd9151f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12968,6 +12968,11 @@ markdown-it-attrs@3.0.3: resolved "https://registry.yarnpkg.com/markdown-it-attrs/-/markdown-it-attrs-3.0.3.tgz#92acdb16fe551cb056c5eb9848413443cafb5231" integrity sha512-cLnICU2t61skNCr4Wih/sdza+UbQcqJGZwvqAypnbWA284nzDm+Gpc90iaRk/JjsIy4emag5v3s0rXFhFBWhCA== +markdown-it-decorate@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/markdown-it-decorate/-/markdown-it-decorate-1.2.2.tgz#f1e11d11d837ae78906198f8a2c974f0e646acb7" + integrity sha512-7BFWJ97KBXgkaPVjKHISQnhSW8RWQ7yRNXpr8pPUV2Rw4GHvGrgb6CelKCM+GSijP0uSLCAVfc/knWIz+2v/Sw== + markdown-it-emoji@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc" From f77c6953a1ec33a6bdc6ac9a8e5c6a98d94c04ca Mon Sep 17 00:00:00 2001 From: NGPixel Date: Tue, 8 Nov 2022 22:47:12 -0500 Subject: [PATCH 056/164] chore: set windows build node to 16.x --- .github/workflows/build.yml | 8 ++++---- package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d38dea8e6f..304f20e45d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -191,7 +191,7 @@ jobs: - name: Setup Node.js environment uses: actions/setup-node@v2.5.1 with: - node-version: 12.x + node-version: 16.x - name: Download a Build Artifact uses: actions/download-artifact@v2.1.0 @@ -347,7 +347,7 @@ jobs: body: ${{ steps.changelog.outputs.changes }} token: ${{ github.token }} artifacts: 'drop/wiki-js.tar.gz,drop-win/wiki-js-windows.tar.gz' - + - name: Notify Slack Releases Channel uses: slackapi/slack-github-action@v1.18.0 with: @@ -358,7 +358,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - + - name: Notify Telegram Channel uses: appleboy/telegram-action@v0.1.1 with: @@ -369,7 +369,7 @@ jobs: message: | Wiki.js *${{ github.ref_name }}* has been released! See [release notes](https://github.com/requarks/wiki/releases) for details. - + - name: Notify Discord Channel uses: sebastianpopp/discord-action@v1.0 with: diff --git a/package.json b/package.json index 209f19d021..d6edb3fbaa 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "node": ">=10.12" }, "dependencies": { - "@azure/storage-blob": "12.9.0", + "@azure/storage-blob": "12.12.0", "@exlinc/keycloak-passport": "1.0.2", "@joplin/turndown-plugin-gfm": "1.0.45", "@root/csr": "0.8.1", diff --git a/yarn.lock b/yarn.lock index 825dd9151f..37a5605830 100644 --- a/yarn.lock +++ b/yarn.lock @@ -278,10 +278,10 @@ "@azure/ms-rest-js" "^1.8.7" adal-node "^0.1.28" -"@azure/storage-blob@12.9.0": - version "12.9.0" - resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.9.0.tgz#4cbd8b4c7a47dd064867430db892f4ef2d8f17ab" - integrity sha512-ank38FdCLfJ+EoeMzCz3hkYJuZAd63ARvDKkxZYRDb+beBYf+/+gx8jNTqkq/hfyUl4dJQ/a7tECU0Y0F98CHg== +"@azure/storage-blob@12.12.0": + version "12.12.0" + resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.12.0.tgz#25e277c885692d5adcd8c2a949789b2837a74c59" + integrity sha512-o/Mf6lkyYG/eBW4/hXB9864RxVNmAkcKHjsGR6Inlp5hupa3exjSyH2KjO3tLO//YGA+tS+17hM2bxRl9Sn16g== dependencies: "@azure/abort-controller" "^1.0.0" "@azure/core-http" "^2.0.0" From fff7f10dd7d47acc22064e1cde049cf169e1c2ce Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Wed, 9 Nov 2022 17:04:07 -0500 Subject: [PATCH 057/164] ci: add purge droplet-agent to DO packer script --- dev/packer/scripts/900-cleanup.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dev/packer/scripts/900-cleanup.sh b/dev/packer/scripts/900-cleanup.sh index f6b0f526d5..60557f887c 100644 --- a/dev/packer/scripts/900-cleanup.sh +++ b/dev/packer/scripts/900-cleanup.sh @@ -8,14 +8,16 @@ if [[ ! -d /tmp ]]; then fi chmod 1777 /tmp +export DEBIAN_FRONTEND=noninteractive apt-get -y update -apt-get -y upgrade +apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes +apt-get purge droplet-agent +apt-get -y autoremove +apt-get -y autoclean rm -rf /tmp/* /var/tmp/* history -c cat /dev/null > /root/.bash_history unset HISTFILE -apt-get -y autoremove -apt-get -y autoclean find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-???????? rm -rf /var/lib/cloud/instances/* From 701567b53a58d0dcc84688e594a4dba24091b253 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Wed, 9 Nov 2022 17:09:32 -0500 Subject: [PATCH 058/164] ci: add DO img-check script to packer --- dev/packer/digitalocean.json | 3 +- dev/packer/scripts/999-img-check.sh | 628 ++++++++++++++++++++++++++++ 2 files changed, 630 insertions(+), 1 deletion(-) create mode 100644 dev/packer/scripts/999-img-check.sh diff --git a/dev/packer/digitalocean.json b/dev/packer/digitalocean.json index 0a33bd035f..0bd1523eb6 100644 --- a/dev/packer/digitalocean.json +++ b/dev/packer/digitalocean.json @@ -78,7 +78,8 @@ "scripts/013-docker-dns.sh", "scripts/014-ufw-docker.sh", "scripts/020-application-tag.sh", - "scripts/900-cleanup.sh" + "scripts/900-cleanup.sh", + "scripts/999-img-check.sh" ] } ] diff --git a/dev/packer/scripts/999-img-check.sh b/dev/packer/scripts/999-img-check.sh new file mode 100644 index 0000000000..6473b66284 --- /dev/null +++ b/dev/packer/scripts/999-img-check.sh @@ -0,0 +1,628 @@ +#!/bin/bash + +# DigitalOcean Marketplace Image Validation Tool +# © 2021-2022 DigitalOcean LLC. +# This code is licensed under Apache 2.0 license (see LICENSE.md for details) + +VERSION="v. 1.8" +RUNDATE=$( date ) + +# Script should be run with SUDO +if [ "$EUID" -ne 0 ] + then echo "[Error] - This script must be run with sudo or as the root user." + exit 1 +fi + +STATUS=0 +PASS=0 +WARN=0 +FAIL=0 + +# $1 == command to check for +# returns: 0 == true, 1 == false +cmdExists() { + if command -v "$1" > /dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +function getDistro { + if [ -f /etc/os-release ]; then + # freedesktop.org and systemd + # shellcheck disable=SC1091 + . /etc/os-release + OS=$NAME + VER=$VERSION_ID +elif type lsb_release >/dev/null 2>&1; then + # linuxbase.org + OS=$(lsb_release -si) + VER=$(lsb_release -sr) +elif [ -f /etc/lsb-release ]; then + # For some versions of Debian/Ubuntu without lsb_release command + # shellcheck disable=SC1091 + . /etc/lsb-release + OS=$DISTRIB_ID + VER=$DISTRIB_RELEASE +elif [ -f /etc/debian_version ]; then + # Older Debian/Ubuntu/etc. + OS=Debian + VER=$(cat /etc/debian_version) +elif [ -f /etc/SuSe-release ]; then + # Older SuSE/etc. + : +elif [ -f /etc/redhat-release ]; then + # Older Red Hat, CentOS, etc. + VER=$(cut -d" " -f3 < /etc/redhat-release | cut -d "." -f1) + d=$(cut -d" " -f1 < /etc/redhat-release | cut -d "." -f1) + if [[ $d == "CentOS" ]]; then + OS="CentOS Linux" + fi +else + # Fall back to uname, e.g. "Linux ", also works for BSD, etc. + OS=$(uname -s) + VER=$(uname -r) +fi +} +function loadPasswords { +SHADOW=$(cat /etc/shadow) +} + +function checkAgent { + # Check for the presence of the DO directory in the filesystem + if [ -d /opt/digitalocean ];then + echo -en "\e[41m[FAIL]\e[0m DigitalOcean directory detected.\n" + ((FAIL++)) + STATUS=2 + if [[ $OS == "CentOS Linux" ]] || [[ $OS == "CentOS Stream" ]] || [[ $OS == "Rocky Linux" ]]; then + echo "To uninstall the agent: 'sudo yum remove droplet-agent'" + echo "To remove the DO directory: 'find /opt/digitalocean/ -type d -empty -delete'" + elif [[ $OS == "Ubuntu" ]] || [[ $OS == "Debian" ]]; then + echo "To uninstall the agent and remove the DO directory: 'sudo apt-get purge droplet-agent'" + fi + else + echo -en "\e[32m[PASS]\e[0m DigitalOcean Monitoring agent was not found\n" + ((PASS++)) + fi +} + +function checkLogs { + cp_ignore="/var/log/cpanel-install.log" + echo -en "\nChecking for log files in /var/log\n\n" + # Check if there are log archives or log files that have not been recently cleared. + for f in /var/log/*-????????; do + [[ -e $f ]] || break + if [ "${f}" != "${cp_ignore}" ]; then + echo -en "\e[93m[WARN]\e[0m Log archive ${f} found; Contents:\n" + cat "${f}" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + fi + done + for f in /var/log/*.[0-9];do + [[ -e $f ]] || break + echo -en "\e[93m[WARN]\e[0m Log archive ${f} found; Contents:\n" + cat "${f}" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + done + for f in /var/log/*.log; do + [[ -e $f ]] || break + if [[ "${f}" = '/var/log/lfd.log' && "$(grep -E -v '/var/log/messages has been reset| Watching /var/log/messages' "${f}" | wc -c)" -gt 50 ]]; then + if [ "${f}" != "${cp_ignore}" ]; then + echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found; Contents:\n" + cat "${f}" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + fi + elif [[ "${f}" != '/var/log/lfd.log' && "$(wc -c < "${f}")" -gt 50 ]]; then + if [ "${f}" != "${cp_ignore}" ]; then + echo -en "\e[93m[WARN]\e[0m un-cleared log file, ${f} found; Contents:\n" + cat "${f}" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + fi + fi + done +} +function checkTMP { + # Check the /tmp directory to ensure it is empty. Warn on any files found. + return 1 +} +function checkRoot { + user="root" + uhome="/root" + for usr in $SHADOW + do + IFS=':' read -r -a u <<< "$usr" + if [[ "${u[0]}" == "${user}" ]]; then + if [[ ${u[1]} == "!" ]] || [[ ${u[1]} == "!!" ]] || [[ ${u[1]} == "*" ]]; then + echo -en "\e[32m[PASS]\e[0m User ${user} has no password set.\n" + ((PASS++)) + else + echo -en "\e[41m[FAIL]\e[0m User ${user} has a password set on their account.\n" + ((FAIL++)) + STATUS=2 + fi + fi + done + if [ -d ${uhome}/ ]; then + if [ -d ${uhome}/.ssh/ ]; then + if ls ${uhome}/.ssh/*> /dev/null 2>&1; then + for key in "${uhome}"/.ssh/* + do + if [ "${key}" == "${uhome}/.ssh/authorized_keys" ]; then + + if [ "$(wc -c < "${key}")" -gt 50 ]; then + echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a populated authorized_keys file in \e[93m${key}\e[0m\n" + akey=$(cat "${key}") + echo "File Contents:" + echo "$akey" + echo "--------------" + ((FAIL++)) + STATUS=2 + fi + elif [ "${key}" == "${uhome}/.ssh/id_rsa" ]; then + if [ "$(wc -c < "${key}")" -gt 0 ]; then + echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a private key file in \e[93m${key}\e[0m\n" + akey=$(cat "${key}") + echo "File Contents:" + echo "$akey" + echo "--------------" + ((FAIL++)) + STATUS=2 + else + echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has empty private key file in \e[93m${key}\e[0m\n" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + fi + elif [ "${key}" != "${uhome}/.ssh/known_hosts" ]; then + echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a file in their .ssh directory at \e[93m${key}\e[0m\n" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + else + if [ "$(wc -c < "${key}")" -gt 50 ]; then + echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a populated known_hosts file in \e[93m${key}\e[0m\n" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + fi + fi + done + else + echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m has no SSH keys present\n" + fi + else + echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have an .ssh directory\n" + fi + if [ -f /root/.bash_history ];then + + BH_S=$(wc -c < /root/.bash_history) + + if [[ $BH_S -lt 200 ]]; then + echo -en "\e[32m[PASS]\e[0m ${user}'s Bash History appears to have been cleared\n" + ((PASS++)) + else + echo -en "\e[41m[FAIL]\e[0m ${user}'s Bash History should be cleared to prevent sensitive information from leaking\n" + ((FAIL++)) + STATUS=2 + fi + + return 1; + else + echo -en "\e[32m[PASS]\e[0m The Root User's Bash History is not present\n" + ((PASS++)) + fi + else + echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have a directory in /home\n" + fi + echo -en "\n\n" + return 1 +} + +function checkUsers { + # Check each user-created account + awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' < /etc/passwd | while IFS= read -r user; + do + # Skip some other non-user system accounts + if [[ $user == "centos" ]]; then + : + elif [[ $user == "nfsnobody" ]]; then + : + else + echo -en "\nChecking user: ${user}...\n" + for usr in $SHADOW + do + IFS=':' read -r -a u <<< "$usr" + if [[ "${u[0]}" == "${user}" ]]; then + if [[ ${u[1]} == "!" ]] || [[ ${u[1]} == "!!" ]] || [[ ${u[1]} == "*" ]]; then + echo -en "\e[32m[PASS]\e[0m User ${user} has no password set.\n" + # shellcheck disable=SC2030 + ((PASS++)) + else + echo -en "\e[41m[FAIL]\e[0m User ${user} has a password set on their account. Only system users are allowed on the image.\n" + # shellcheck disable=SC2030 + ((FAIL++)) + STATUS=2 + fi + fi + done + #echo "User Found: ${user}" + uhome="/home/${user}" + if [ -d "${uhome}/" ]; then + if [ -d "${uhome}/.ssh/" ]; then + if ls "${uhome}/.ssh/*"> /dev/null 2>&1; then + for key in "${uhome}"/.ssh/* + do + if [ "${key}" == "${uhome}/.ssh/authorized_keys" ]; then + if [ "$(wc -c < "${key}")" -gt 50 ]; then + echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a populated authorized_keys file in \e[93m${key}\e[0m\n" + akey=$(cat "${key}") + echo "File Contents:" + echo "$akey" + echo "--------------" + ((FAIL++)) + STATUS=2 + fi + elif [ "${key}" == "${uhome}/.ssh/id_rsa" ]; then + if [ "$(wc -c < "${key}")" -gt 0 ]; then + echo -en "\e[41m[FAIL]\e[0m User \e[1m${user}\e[0m has a private key file in \e[93m${key}\e[0m\n" + akey=$(cat "${key}") + echo "File Contents:" + echo "$akey" + echo "--------------" + ((FAIL++)) + STATUS=2 + else + echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has empty private key file in \e[93m${key}\e[0m\n" + # shellcheck disable=SC2030 + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + fi + elif [ "${key}" != "${uhome}/.ssh/known_hosts" ]; then + + echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a file in their .ssh directory named \e[93m${key}\e[0m\n" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + + else + if [ "$(wc -c < "${key}")" -gt 50 ]; then + echo -en "\e[93m[WARN]\e[0m User \e[1m${user}\e[0m has a known_hosts file in \e[93m${key}\e[0m\n" + ((WARN++)) + if [[ $STATUS != 2 ]]; then + STATUS=1 + fi + fi + fi + + + done + else + echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m has no SSH keys present\n" + fi + else + echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have an .ssh directory\n" + fi + else + echo -en "\e[32m[ OK ]\e[0m User \e[1m${user}\e[0m does not have a directory in /home\n" + fi + + # Check for an uncleared .bash_history for this user + if [ -f "${uhome}/.bash_history" ]; then + BH_S=$(wc -c < "${uhome}/.bash_history") + + if [[ $BH_S -lt 200 ]]; then + echo -en "\e[32m[PASS]\e[0m ${user}'s Bash History appears to have been cleared\n" + ((PASS++)) + else + echo -en "\e[41m[FAIL]\e[0m ${user}'s Bash History should be cleared to prevent sensitive information from leaking\n" + ((FAIL++)) + STATUS=2 + + fi + echo -en "\n\n" + fi + fi + done +} +function checkFirewall { + + if [[ $OS == "Ubuntu" ]]; then + fw="ufw" + ufwa=$(ufw status |head -1| sed -e "s/^Status:\ //") + if [[ $ufwa == "active" ]]; then + FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + # shellcheck disable=SC2031 + ((PASS++)) + else + FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + # shellcheck disable=SC2031 + ((WARN++)) + fi + elif [[ $OS == "CentOS Linux" ]] || [[ $OS == "CentOS Stream" ]] || [[ $OS == "Rocky Linux" ]]; then + if [ -f /usr/lib/systemd/system/csf.service ]; then + fw="csf" + if [[ $(systemctl status $fw >/dev/null 2>&1) ]]; then + + FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + ((PASS++)) + elif cmdExists "firewall-cmd"; then + if [[ $(systemctl is-active firewalld >/dev/null 2>&1 && echo 1 || echo 0) ]]; then + FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + ((PASS++)) + else + FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + ((WARN++)) + fi + else + FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + ((WARN++)) + fi + else + fw="firewalld" + if [[ $(systemctl is-active firewalld >/dev/null 2>&1 && echo 1 || echo 0) ]]; then + FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + ((PASS++)) + else + FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + ((WARN++)) + fi + fi + elif [[ "$OS" =~ Debian.* ]]; then + # user could be using a number of different services for managing their firewall + # we will check some of the most common + if cmdExists 'ufw'; then + fw="ufw" + ufwa=$(ufw status |head -1| sed -e "s/^Status:\ //") + if [[ $ufwa == "active" ]]; then + FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + ((PASS++)) + else + FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + ((WARN++)) + fi + elif cmdExists "firewall-cmd"; then + fw="firewalld" + if [[ $(systemctl is-active --quiet $fw) ]]; then + FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + ((PASS++)) + else + FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + ((WARN++)) + fi + else + # user could be using vanilla iptables, check if kernel module is loaded + fw="iptables" + if lsmod | grep -q '^ip_tables' 2>/dev/null; then + FW_VER="\e[32m[PASS]\e[0m Firewall service (${fw}) is active\n" + ((PASS++)) + else + FW_VER="\e[93m[WARN]\e[0m No firewall is configured. Ensure ${fw} is installed and configured\n" + ((WARN++)) + fi + fi + fi + +} +function checkUpdates { + if [[ $OS == "Ubuntu" ]] || [[ "$OS" =~ Debian.* ]]; then + # Ensure /tmp exists and has the proper permissions before + # checking for security updates + # https://github.com/digitalocean/marketplace-partners/issues/94 + if [[ ! -d /tmp ]]; then + mkdir /tmp + fi + chmod 1777 /tmp + + echo -en "\nUpdating apt package database to check for security updates, this may take a minute...\n\n" + apt-get -y update > /dev/null + + uc=$(apt-get --just-print upgrade | grep -i "security" -c) + if [[ $uc -gt 0 ]]; then + update_count=$(( uc / 2 )) + else + update_count=0 + fi + + if [[ $update_count -gt 0 ]]; then + echo -en "\e[41m[FAIL]\e[0m There are ${update_count} security updates available for this image that have not been installed.\n" + echo -en + echo -en "Here is a list of the security updates that are not installed:\n" + sleep 2 + apt-get --just-print upgrade | grep -i security | awk '{print $2}' | awk '!seen[$0]++' + echo -en + # shellcheck disable=SC2031 + ((FAIL++)) + STATUS=2 + else + echo -en "\e[32m[PASS]\e[0m There are no pending security updates for this image.\n\n" + ((PASS++)) + fi + elif [[ $OS == "CentOS Linux" ]] || [[ $OS == "CentOS Stream" ]] || [[ $OS == "Rocky Linux" ]]; then + echo -en "\nChecking for available security updates, this may take a minute...\n\n" + + update_count=$(yum check-update --security --quiet | wc -l) + if [[ $update_count -gt 0 ]]; then + echo -en "\e[41m[FAIL]\e[0m There are ${update_count} security updates available for this image that have not been installed.\n" + ((FAIL++)) + STATUS=2 + else + echo -en "\e[32m[PASS]\e[0m There are no pending security updates for this image.\n" + ((PASS++)) + fi + else + echo "Error encountered" + exit 1 + fi + + return 1; +} +function checkCloudInit { + + if hash cloud-init 2>/dev/null; then + CI="\e[32m[PASS]\e[0m Cloud-init is installed.\n" + ((PASS++)) + else + CI="\e[41m[FAIL]\e[0m No valid verison of cloud-init was found.\n" + ((FAIL++)) + STATUS=2 + fi + return 1 +} + +function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } + + +clear +echo "DigitalOcean Marketplace Image Validation Tool ${VERSION}" +echo "Executed on: ${RUNDATE}" +echo "Checking local system for Marketplace compatibility..." + +getDistro + +echo -en "\n\e[1mDistribution:\e[0m ${OS}\n" +echo -en "\e[1mVersion:\e[0m ${VER}\n\n" + +ost=0 +osv=0 + +if [[ $OS == "Ubuntu" ]]; then + ost=1 + if [[ $VER == "22.04" ]] || [[ $VER == "20.04" ]] || [[ $VER == "18.04" ]] || [[ $VER == "16.04" ]]; then + osv=1 + fi + +elif [[ "$OS" =~ Debian.* ]]; then + ost=1 + case "$VER" in + 9) + osv=1 + ;; + 10) + osv=1 + ;; + 11) + osv=1 + ;; + *) + osv=2 + ;; + esac + +elif [[ $OS == "CentOS Linux" ]]; then + ost=1 + if [[ $VER == "8" ]]; then + osv=1 + elif [[ $VER == "7" ]]; then + osv=1 + elif [[ $VER == "6" ]]; then + osv=1 + else + osv=2 + fi +elif [[ $OS == "CentOS Stream" ]]; then + ost=1 + if [[ $VER == "8" ]]; then + osv=1 + else + osv=2 + fi +elif [[ $OS == "Rocky Linux" ]]; then + ost=1 + if [[ $VER =~ 8\. ]]; then + osv=1 + else + osv=2 + fi +else + ost=0 +fi + +if [[ $ost == 1 ]]; then + echo -en "\e[32m[PASS]\e[0m Supported Operating System Detected: ${OS}\n" + ((PASS++)) +else + echo -en "\e[41m[FAIL]\e[0m ${OS} is not a supported Operating System\n" + ((FAIL++)) + STATUS=2 +fi + +if [[ $osv == 1 ]]; then + echo -en "\e[32m[PASS]\e[0m Supported Release Detected: ${VER}\n" + ((PASS++)) +elif [[ $ost == 1 ]]; then + echo -en "\e[41m[FAIL]\e[0m ${OS} ${VER} is not a supported Operating System Version\n" + ((FAIL++)) + STATUS=2 +else + echo "Exiting..." + exit 1 +fi + +checkCloudInit + +echo -en "${CI}" + +checkFirewall + +echo -en "${FW_VER}" + +checkUpdates + +loadPasswords + +checkLogs + +echo -en "\n\nChecking all user-created accounts...\n" +checkUsers + +echo -en "\n\nChecking the root account...\n" +checkRoot + +checkAgent + + +# Summary +echo -en "\n\n---------------------------------------------------------------------------------------------------\n" + +if [[ $STATUS == 0 ]]; then + echo -en "Scan Complete.\n\e[32mAll Tests Passed!\e[0m\n" +elif [[ $STATUS == 1 ]]; then + echo -en "Scan Complete. \n\e[93mSome non-critical tests failed. Please review these items.\e[0m\e[0m\n" +else + echo -en "Scan Complete. \n\e[41mOne or more tests failed. Please review these items and re-test.\e[0m\n" +fi +echo "---------------------------------------------------------------------------------------------------" +echo -en "\e[1m${PASS} Tests PASSED\e[0m\n" +echo -en "\e[1m${WARN} WARNINGS\e[0m\n" +echo -en "\e[1m${FAIL} Tests FAILED\e[0m\n" +echo -en "---------------------------------------------------------------------------------------------------\n" + +if [[ $STATUS == 0 ]]; then + echo -en "We did not detect any issues with this image. Please be sure to manually ensure that all software installed on the base system is functional, secure and properly configured (or facilities for configuration on first-boot have been created).\n\n" + exit 0 +elif [[ $STATUS == 1 ]]; then + echo -en "Please review all [WARN] items above and ensure they are intended or resolved. If you do not have a specific requirement, we recommend resolving these items before image submission\n\n" + exit 0 +else + echo -en "Some critical tests failed. These items must be resolved and this scan re-run before you submit your image to the DigitalOcean Marketplace.\n\n" + exit 1 +fi \ No newline at end of file From 3579f9e7256bf5d4fa872df8ff1c8918acf37a9e Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Wed, 9 Nov 2022 17:26:04 -0500 Subject: [PATCH 059/164] ci: purge do agent directory from do packer image --- dev/packer/scripts/900-cleanup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/packer/scripts/900-cleanup.sh b/dev/packer/scripts/900-cleanup.sh index 60557f887c..dbf5b9e5ed 100644 --- a/dev/packer/scripts/900-cleanup.sh +++ b/dev/packer/scripts/900-cleanup.sh @@ -12,6 +12,7 @@ export DEBIAN_FRONTEND=noninteractive apt-get -y update apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes apt-get purge droplet-agent +rm -rf /opt/digitalocean apt-get -y autoremove apt-get -y autoclean rm -rf /tmp/* /var/tmp/* From dc90e0b5a7437caac1bd68f899ca10b5080f4778 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Thu, 10 Nov 2022 13:48:13 -0500 Subject: [PATCH 060/164] docs: add MacStadium sponsor mention [skip ci] --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 53136766f2..3b79715687 100644 --- a/README.md +++ b/README.md @@ -462,6 +462,9 @@ This project exists thanks to all the people who contribute. [[Contribute]](http ![Lokalise](https://static.requarks.io/logo/lokalise-text-h40.png) [Lokalise](https://lokalise.com/) for providing access to their great localization tool. +![MacStadium](https://static.requarks.io/logo/macstadium-h40.png) +[MacStadium](https://www.macstadium.com) for providing access to their Mac hardware in the cloud. + ![Netlify](https://js.wiki/legacy/logo_netlify.png) [Netlify](https://www.netlify.com) for providing hosting for our website. From db2ad81a1fb1840f6ef9fa353ffefb92c6a9180a Mon Sep 17 00:00:00 2001 From: cannorin <13620400+cannorin@users.noreply.github.com> Date: Sun, 13 Nov 2022 15:43:48 +0900 Subject: [PATCH 061/164] feat: katex persistent macro support (#5838) Co-authored-by: cannorin --- client/components/editor/editor-markdown.vue | 5 +++-- server/modules/rendering/markdown-katex/renderer.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client/components/editor/editor-markdown.vue b/client/components/editor/editor-markdown.vue index 38f0f353b6..6fc2e5815d 100644 --- a/client/components/editor/editor-markdown.vue +++ b/client/components/editor/editor-markdown.vue @@ -348,11 +348,12 @@ plantuml.init(md, {}) // KATEX // ======================================== +const macros = {} md.inline.ruler.after('escape', 'katex_inline', katexHelper.katexInline) md.renderer.rules.katex_inline = (tokens, idx) => { try { return katex.renderToString(tokens[idx].content, { - displayMode: false + displayMode: false, macros }) } catch (err) { console.warn(err) @@ -365,7 +366,7 @@ md.block.ruler.after('blockquote', 'katex_block', katexHelper.katexBlock, { md.renderer.rules.katex_block = (tokens, idx) => { try { return `

` + katex.renderToString(tokens[idx].content, { - displayMode: true + displayMode: true, macros }) + `

` } catch (err) { console.warn(err) diff --git a/server/modules/rendering/markdown-katex/renderer.js b/server/modules/rendering/markdown-katex/renderer.js index 2321ad127d..fbb673937a 100644 --- a/server/modules/rendering/markdown-katex/renderer.js +++ b/server/modules/rendering/markdown-katex/renderer.js @@ -24,12 +24,13 @@ katex.__defineMacro('\\tripledash', '{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2m module.exports = { init (mdinst, conf) { + const macros = {} if (conf.useInline) { mdinst.inline.ruler.after('escape', 'katex_inline', katexInline) mdinst.renderer.rules.katex_inline = (tokens, idx) => { try { return katex.renderToString(tokens[idx].content, { - displayMode: false + displayMode: false, macros }) } catch (err) { WIKI.logger.warn(err) @@ -44,7 +45,7 @@ module.exports = { mdinst.renderer.rules.katex_block = (tokens, idx) => { try { return `

` + katex.renderToString(tokens[idx].content, { - displayMode: true + displayMode: true, macros }) + `

` } catch (err) { WIKI.logger.warn(err) From d10f2a1966a050c326e8de2432204ed691d73bea Mon Sep 17 00:00:00 2001 From: NGPixel Date: Fri, 18 Nov 2022 16:24:23 -0500 Subject: [PATCH 062/164] feat: send UPGRADE_COMPANION_REF in automated upgrade call --- server/graph/resolvers/system.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/graph/resolvers/system.js b/server/graph/resolvers/system.js index 103a704189..51e57637b5 100644 --- a/server/graph/resolvers/system.js +++ b/server/graph/resolvers/system.js @@ -90,7 +90,10 @@ module.exports = { if (process.env.UPGRADE_COMPANION) { await request({ method: 'POST', - uri: 'http://wiki-update-companion/upgrade' + uri: 'http://wiki-update-companion/upgrade', + qs: { + ...process.env.UPGRADE_COMPANION_REF && { container: process.env.UPGRADE_COMPANION_REF } + } }) return { responseResult: graphHelper.generateSuccess('Upgrade has started.') From 86c940705789d986da52d180a108e9664ea9aca7 Mon Sep 17 00:00:00 2001 From: CDN Date: Sat, 19 Nov 2022 05:40:18 +0800 Subject: [PATCH 063/164] feat: add umami analytics module (#5869) Co-authored-by: Nicolas Giard --- server/modules/analytics/umami/code.yml | 2 ++ server/modules/analytics/umami/definition.yml | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 server/modules/analytics/umami/code.yml create mode 100644 server/modules/analytics/umami/definition.yml diff --git a/server/modules/analytics/umami/code.yml b/server/modules/analytics/umami/code.yml new file mode 100644 index 0000000000..b16662b394 --- /dev/null +++ b/server/modules/analytics/umami/code.yml @@ -0,0 +1,2 @@ +head: | + diff --git a/server/modules/analytics/umami/definition.yml b/server/modules/analytics/umami/definition.yml new file mode 100644 index 0000000000..8afec209d1 --- /dev/null +++ b/server/modules/analytics/umami/definition.yml @@ -0,0 +1,17 @@ +key: umami +title: Umami Analytics +description: Umami is a simple, fast, privacy-focused alternative to Google Analytics. +author: CDN18 +logo: https://static.requarks.io/logo/umami.svg +website: https://umami.is +isAvailable: true +props: + websiteID: + type: String + title: Website ID + order: 1 + url: + type: String + title: Umami Server URL + hint: The URL of your Umami instance. It should start with http/https and omit the trailing slash. (e.g. https://umami.example.com) + order: 2 From 0a2a32db47273836d820a3ff0788dfaa0505d4b6 Mon Sep 17 00:00:00 2001 From: CDN Date: Sat, 19 Nov 2022 05:56:15 +0800 Subject: [PATCH 064/164] feat: add artalk comment module (#5868) Co-authored-by: Nicolas Giard --- server/modules/comments/artalk/code.yml | 17 ++++++++++++++ server/modules/comments/artalk/definition.yml | 23 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 server/modules/comments/artalk/code.yml create mode 100644 server/modules/comments/artalk/definition.yml diff --git a/server/modules/comments/artalk/code.yml b/server/modules/comments/artalk/code.yml new file mode 100644 index 0000000000..dc61bd79d3 --- /dev/null +++ b/server/modules/comments/artalk/code.yml @@ -0,0 +1,17 @@ +main: | +
+head: | + + +body: | + diff --git a/server/modules/comments/artalk/definition.yml b/server/modules/comments/artalk/definition.yml new file mode 100644 index 0000000000..8c59fc0c93 --- /dev/null +++ b/server/modules/comments/artalk/definition.yml @@ -0,0 +1,23 @@ +key: artalk +title: Artalk +description: A light-weight self-hosted comment system. +author: CDN18 +logo: https://static.requarks.io/logo/artalk.png +website: https://artalk.js.org +codeTemplate: true +isAvailable: true +props: + server: + type: String + title: Artalk Backend URL + default: '' + hint: 'Publicly accessible URL of your Artalk instance. It should start with http/https and omit the trailing slash. (e.g. https://artalk.example.com)' + maxWidth: 650 + order: 1 + siteName: + type: String + title: Site Name + default: '' + hint: 'The name of this site configured in the artalk backend. Leave empty to use default site.' + maxWidth: 450 + order: 2 From ca2f7aaf73760ebbe4ac4a00794f1cdf70ede49b Mon Sep 17 00:00:00 2001 From: NGPixel Date: Fri, 18 Nov 2022 19:27:35 -0500 Subject: [PATCH 065/164] chore: add css classes on page sidebar cards --- client/themes/default/components/page.vue | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/themes/default/components/page.vue b/client/themes/default/components/page.vue index 0993c9ec43..83712c5f16 100644 --- a/client/themes/default/components/page.vue +++ b/client/themes/default/components/page.vue @@ -75,7 +75,7 @@ v-container.pl-5.pt-4(fluid, grid-list-xl) v-layout(row) v-flex.page-col-sd(lg3, xl2, v-if='$vuetify.breakpoint.lgAndUp') - v-card.mb-5(v-if='tocDecoded.length') + v-card.page-toc-card.mb-5(v-if='tocDecoded.length') .overline.pa-5.pb-0(:class='$vuetify.theme.dark ? `blue--text text--lighten-2` : `primary--text`') {{$t('common:page.toc')}} v-list.pb-3(dense, nav, :class='$vuetify.theme.dark ? `darken-3-d3` : ``') template(v-for='(tocItem, tocIdx) in tocDecoded') @@ -89,7 +89,7 @@ v-list-item-title.px-3.caption.grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-1`') {{tocSubItem.title}} //- v-divider(inset, v-if='tocIdx < toc.length - 1') - v-card.mb-5(v-if='tags.length > 0') + v-card.page-tags-card.mb-5(v-if='tags.length > 0') .pa-5 .overline.teal--text.pb-2(:class='$vuetify.theme.dark ? `text--lighten-3` : ``') {{$t('common:page.tags')}} v-chip.mr-1.mb-1( @@ -109,7 +109,7 @@ ) v-icon(:color='$vuetify.theme.dark ? `teal lighten-3` : `teal`', size='20') mdi-tag-multiple - v-card.mb-5(v-if='commentsEnabled && commentsPerms.read') + v-card.page-comments-card.mb-5(v-if='commentsEnabled && commentsPerms.read') .pa-5 .overline.pb-2.blue-grey--text.d-flex.align-center(:class='$vuetify.theme.dark ? `text--lighten-3` : `text--darken-2`') span {{$t('common:comments.sdTitle')}} @@ -145,7 +145,7 @@ v-icon(:color='$vuetify.theme.dark ? `blue-grey lighten-1` : `blue-grey darken-2`', dense) mdi-comment-plus span {{$t('common:comments.newComment')}} - v-card.mb-5 + v-card.page-author-card.mb-5 .pa-5 .overline.indigo--text.d-flex(:class='$vuetify.theme.dark ? `text--lighten-3` : ``') span {{$t('common:page.lastEditedBy')}} @@ -162,8 +162,8 @@ ) v-icon(color='indigo', dense) mdi-history span {{$t('common:header.history')}} - .body-2.grey--text(:class='$vuetify.theme.dark ? `` : `text--darken-3`') {{ authorName }} - .caption.grey--text.text--darken-1 {{ updatedAt | moment('calendar') }} + .page-author-card-name.body-2.grey--text(:class='$vuetify.theme.dark ? `` : `text--darken-3`') {{ authorName }} + .page-author-card-date.caption.grey--text.text--darken-1 {{ updatedAt | moment('calendar') }} //- v-card.mb-5 //- .pa-5 @@ -178,7 +178,7 @@ //- ) //- .caption.grey--text 5 votes - v-card(flat) + v-card.page-shortcuts-card(flat) v-toolbar(:color='$vuetify.theme.dark ? `grey darken-4-d3` : `grey lighten-3`', flat, dense) v-spacer v-tooltip(bottom) From 037dc3ce5961c1691307f19dad7d28a2260149bb Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Mon, 21 Nov 2022 22:31:41 -0500 Subject: [PATCH 066/164] docs: update BACKERS --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b79715687..1ef5a9604c 100644 --- a/README.md +++ b/README.md @@ -406,11 +406,11 @@ Thank you to all our patrons! 🙏 [[Become a patron](https://www.patreon.com/re - Ian - Imari Childress - Iskander Callos +- Josh Stewart -- Josh Stewart - Justin Dunsworth - Keir - Loïc CRAMPON @@ -428,6 +428,7 @@ Thank you to all our patrons! 🙏 [[Become a patron](https://www.patreon.com/re - Shad Narcher - SmartNET.works - Stepan Sokolovskyi +- Zach Crawford - Zach Maynard - 张白驹 From 143c6db0f0583d43027b1752fb2b8ba20a5e9e47 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Wed, 23 Nov 2022 23:20:00 -0500 Subject: [PATCH 067/164] docs: update BACKERS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1ef5a9604c..bfae1d0009 100644 --- a/README.md +++ b/README.md @@ -425,6 +425,7 @@ Thank you to all our patrons! 🙏 [[Become a patron](https://www.patreon.com/re - Tracey Duffy - Quaxim - Richeir +- Sergio Navarro Fernández - Shad Narcher - SmartNET.works - Stepan Sokolovskyi From 73af37b81baac1df75fc343deb82d818cb1eaee8 Mon Sep 17 00:00:00 2001 From: CDN Date: Fri, 2 Dec 2022 15:33:24 +0800 Subject: [PATCH 068/164] fix: git log should explicitly separate branch from paths (#5911) --- server/modules/storage/git/storage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/modules/storage/git/storage.js b/server/modules/storage/git/storage.js index b047233b7b..cd69f3e720 100644 --- a/server/modules/storage/git/storage.js +++ b/server/modules/storage/git/storage.js @@ -118,7 +118,7 @@ module.exports = { * SYNC */ async sync() { - const currentCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch]), 'latest', {}) + const currentCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch, '--']), 'latest', {}) const rootUser = await WIKI.models.users.getRootUser() @@ -140,7 +140,7 @@ module.exports = { // Process Changes if (_.includes(['sync', 'pull'], this.mode)) { - const latestCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch]), 'latest', {}) + const latestCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch, '--']), 'latest', {}) const diff = await this.git.diffSummary(['-M', currentCommitLog.hash, latestCommitLog.hash]) if (_.get(diff, 'files', []).length > 0) { From 9ac80c1a8f3cb57f9a6095463b38a593830089f3 Mon Sep 17 00:00:00 2001 From: Nicolas Giard Date: Thu, 8 Dec 2022 02:59:57 -0500 Subject: [PATCH 069/164] docs: update BACKERS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bfae1d0009..bccf16fcf2 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,7 @@ Support this project by becoming a sponsor. Your name will show up in the Contri - Tyler Denman ([@tylerguy](https://github.com/tylerguy)) - Victor Bilgin ([@vbilgin](https://github.com/vbilgin)) - VMO Solutions ([@vmosolutions](https://github.com/vmosolutions)) +- ameyrakheja ([@ameyrakheja](https://github.com/ameyrakheja)) - aniketpanjwani ([@aniketpanjwani](https://github.com/aniketpanjwani)) - aytaa ([@aytaa](https://github.com/aytaa)) - chaee ([@chaee](https://github.com/chaee)) From f3133a72ec40e49a5115e9cfd543cdd1a9e2e378 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 10 Dec 2022 17:03:40 -0500 Subject: [PATCH 070/164] feat: toc sidebar position --- client/components/admin/admin-theme.vue | 17 ++++++---- .../graph/admin/theme/theme-mutation-save.gql | 4 +-- .../graph/admin/theme/theme-query-config.gql | 1 + client/store/site.js | 1 + client/themes/default/components/page.vue | 34 +++++++++++++++---- server/app/data.yml | 1 + server/graph/resolvers/theming.js | 2 ++ server/graph/schemas/theming.graphql | 2 ++ server/master.js | 1 + 9 files changed, 48 insertions(+), 15 deletions(-) diff --git a/client/components/admin/admin-theme.vue b/client/components/admin/admin-theme.vue index 83ec5fac8f..b5cd0e59d1 100644 --- a/client/components/admin/admin-theme.vue +++ b/client/components/admin/admin-theme.vue @@ -55,20 +55,16 @@ v-card.mt-3.animated.fadeInUp.wait-p1s v-toolbar(color='primary', dark, dense, flat) v-toolbar-title.subtitle-1 {{$t(`admin:theme.options`)}} - v-spacer - v-chip(label, color='white', small).primary--text coming soon v-card-text v-select( - :items='[]' + :items='tocPositions' outlined prepend-icon='mdi-border-vertical' - v-model='config.iconset' + v-model='config.tocPosition' label='Table of Contents Position' persistent-hint hint='Select whether the table of contents is shown on the left, right or not at all.' - disabled ) - v-flex(lg6 xs12) //- v-card.animated.fadeInUp.wait-p2s //- v-toolbar(color='teal', dark, dense, flat) @@ -155,6 +151,7 @@ export default { theme: 'default', darkMode: false, iconset: '', + tocPosition: 'left', injectCSS: '', injectHead: '', injectBody: '' @@ -184,6 +181,13 @@ export default { width: 100 } ] + }, + tocPositions () { + return [ + { text: 'Left (default)', value: 'left' }, + { text: 'Right', value: 'right' }, + { text: 'Hidden', value: 'off' } + ] } }, watch: { @@ -209,6 +213,7 @@ export default { theme: this.config.theme, iconset: this.config.iconset, darkMode: this.darkMode, + tocPosition: this.config.tocPosition, injectCSS: this.config.injectCSS, injectHead: this.config.injectHead, injectBody: this.config.injectBody diff --git a/client/graph/admin/theme/theme-mutation-save.gql b/client/graph/admin/theme/theme-mutation-save.gql index 856442ce90..86853ebade 100644 --- a/client/graph/admin/theme/theme-mutation-save.gql +++ b/client/graph/admin/theme/theme-mutation-save.gql @@ -1,6 +1,6 @@ -mutation($theme: String!, $iconset: String!, $darkMode: Boolean!, $injectCSS: String, $injectHead: String, $injectBody: String) { +mutation($theme: String!, $iconset: String!, $darkMode: Boolean!, $tocPosition: String, $injectCSS: String, $injectHead: String, $injectBody: String) { theming { - setConfig(theme: $theme, iconset: $iconset, darkMode: $darkMode, injectCSS: $injectCSS, injectHead: $injectHead, injectBody: $injectBody) { + setConfig(theme: $theme, iconset: $iconset, darkMode: $darkMode, tocPosition: $tocPosition, injectCSS: $injectCSS, injectHead: $injectHead, injectBody: $injectBody) { responseResult { succeeded errorCode diff --git a/client/graph/admin/theme/theme-query-config.gql b/client/graph/admin/theme/theme-query-config.gql index 360cb2fa57..5009fe06af 100644 --- a/client/graph/admin/theme/theme-query-config.gql +++ b/client/graph/admin/theme/theme-query-config.gql @@ -4,6 +4,7 @@ query { theme iconset darkMode + tocPosition injectCSS injectHead injectBody diff --git a/client/store/site.js b/client/store/site.js index e26830e335..979468c7e6 100644 --- a/client/store/site.js +++ b/client/store/site.js @@ -6,6 +6,7 @@ const state = { company: siteConfig.company, contentLicense: siteConfig.contentLicense, dark: siteConfig.darkMode, + tocPosition: siteConfig.tocPosition, mascot: true, title: siteConfig.title, logoUrl: siteConfig.logoUrl, diff --git a/client/themes/default/components/page.vue b/client/themes/default/components/page.vue index 83712c5f16..15015b8825 100644 --- a/client/themes/default/components/page.vue +++ b/client/themes/default/components/page.vue @@ -50,7 +50,14 @@ v-divider v-container.grey.pa-0(fluid, :class='$vuetify.theme.dark ? `darken-4-l3` : `lighten-4`') v-row.page-header-section(no-gutters, align-content='center', style='height: 90px;') - v-col.page-col-content.is-page-header(offset-xl='2', offset-lg='3', style='margin-top: auto; margin-bottom: auto;', :class='$vuetify.rtl ? `pr-4` : `pl-4`') + v-col.page-col-content.is-page-header( + :offset-xl='tocPosition === `left` ? 2 : 0' + :offset-lg='tocPosition === `left` ? 3 : 0' + :xl10='tocPosition === `right`' + :lg9='tocPosition === `right`' + style='margin-top: auto; margin-bottom: auto;' + :class='$vuetify.rtl ? `pr-4` : `pl-4`' + ) .headline.grey--text(:class='$vuetify.theme.dark ? `text--lighten-2` : `text--darken-3`') {{title}} .caption.grey--text.text--darken-1 {{description}} .page-edit-shortcuts(v-if='editShortcutsObj.editMenuBar') @@ -74,7 +81,13 @@ v-divider v-container.pl-5.pt-4(fluid, grid-list-xl) v-layout(row) - v-flex.page-col-sd(lg3, xl2, v-if='$vuetify.breakpoint.lgAndUp') + v-flex.page-col-sd( + v-if='tocPosition !== `off` && $vuetify.breakpoint.lgAndUp' + :order-xs1='tocPosition !== `right`' + :order-xs2='tocPosition === `right`' + lg3 + xl2 + ) v-card.page-toc-card.mb-5(v-if='tocDecoded.length') .overline.pa-5.pb-0(:class='$vuetify.theme.dark ? `blue--text text--lighten-2` : `primary--text`') {{$t('common:page.toc')}} v-list.pb-3(dense, nav, :class='$vuetify.theme.dark ? `darken-3-d3` : ``') @@ -181,10 +194,10 @@ v-card.page-shortcuts-card(flat) v-toolbar(:color='$vuetify.theme.dark ? `grey darken-4-d3` : `grey lighten-3`', flat, dense) v-spacer - v-tooltip(bottom) - template(v-slot:activator='{ on }') - v-btn(icon, tile, v-on='on', :aria-label='$t(`common:page.bookmark`)'): v-icon(color='grey') mdi-bookmark - span {{$t('common:page.bookmark')}} + //- v-tooltip(bottom) + //- template(v-slot:activator='{ on }') + //- v-btn(icon, tile, v-on='on', :aria-label='$t(`common:page.bookmark`)'): v-icon(color='grey') mdi-bookmark + //- span {{$t('common:page.bookmark')}} v-menu(offset-y, bottom, min-width='300') template(v-slot:activator='{ on: menu }') v-tooltip(bottom) @@ -203,7 +216,13 @@ span {{$t('common:page.printFormat')}} v-spacer - v-flex.page-col-content(xs12, lg9, xl10) + v-flex.page-col-content( + xs12 + :lg9='tocPosition !== `off`' + :xl10='tocPosition !== `off`' + :order-xs1='tocPosition === `right`' + :order-xs2='tocPosition !== `right`' + ) v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasAnyPagePermissions && editShortcutsObj.editFab') template(v-slot:activator='{ on: onEditActivator }') v-speed-dial( @@ -536,6 +555,7 @@ export default { tocDecoded () { return JSON.parse(Buffer.from(this.toc, 'base64').toString()) }, + tocPosition: get('site/tocPosition'), hasAdminPermission: get('page/effectivePermissions@system.manage'), hasWritePagesPermission: get('page/effectivePermissions@pages.write'), hasManagePagesPermission: get('page/effectivePermissions@pages.manage'), diff --git a/server/app/data.yml b/server/app/data.yml index 54482c99f1..a7fb78aee7 100644 --- a/server/app/data.yml +++ b/server/app/data.yml @@ -59,6 +59,7 @@ defaults: theme: 'default' iconset: 'md' darkMode: false + tocPosition: 'left' auth: autoLogin: false enforce2FA: false diff --git a/server/graph/resolvers/theming.js b/server/graph/resolvers/theming.js index cfd6367038..3a175c0fa9 100644 --- a/server/graph/resolvers/theming.js +++ b/server/graph/resolvers/theming.js @@ -24,6 +24,7 @@ module.exports = { theme: WIKI.config.theming.theme, iconset: WIKI.config.theming.iconset, darkMode: WIKI.config.theming.darkMode, + tocPosition: WIKI.config.theming.tocPosition || 'left', injectCSS: new CleanCSS({ format: 'beautify' }).minify(WIKI.config.theming.injectCSS).styles, injectHead: WIKI.config.theming.injectHead, injectBody: WIKI.config.theming.injectBody @@ -44,6 +45,7 @@ module.exports = { theme: args.theme, iconset: args.iconset, darkMode: args.darkMode, + tocPosition: args.tocPosition || 'left', injectCSS: args.injectCSS || '', injectHead: args.injectHead || '', injectBody: args.injectBody || '' diff --git a/server/graph/schemas/theming.graphql b/server/graph/schemas/theming.graphql index eddebad42e..2c7b2fb662 100644 --- a/server/graph/schemas/theming.graphql +++ b/server/graph/schemas/theming.graphql @@ -28,6 +28,7 @@ type ThemingMutation { theme: String! iconset: String! darkMode: Boolean! + tocPosition: String injectCSS: String injectHead: String injectBody: String @@ -42,6 +43,7 @@ type ThemingConfig { theme: String! iconset: String! darkMode: Boolean! + tocPosition: String injectCSS: String injectHead: String injectBody: String diff --git a/server/master.js b/server/master.js index 8274a2edbc..0037e0d6a6 100644 --- a/server/master.js +++ b/server/master.js @@ -149,6 +149,7 @@ module.exports = async () => { title: WIKI.config.title, theme: WIKI.config.theming.theme, darkMode: WIKI.config.theming.darkMode, + tocPosition: WIKI.config.theming.tocPosition, lang: WIKI.config.lang.code, rtl: WIKI.config.lang.rtl, company: WIKI.config.company, From eb99f828b1304064b7ca93183b2c857d43b2e0df Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 10 Dec 2022 18:05:53 -0500 Subject: [PATCH 071/164] fix: edit buttons hidden when toc sidebar is on the right --- client/themes/default/components/page.vue | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/themes/default/components/page.vue b/client/themes/default/components/page.vue index 15015b8825..bd7d8b8eaf 100644 --- a/client/themes/default/components/page.vue +++ b/client/themes/default/components/page.vue @@ -53,8 +53,8 @@ v-col.page-col-content.is-page-header( :offset-xl='tocPosition === `left` ? 2 : 0' :offset-lg='tocPosition === `left` ? 3 : 0' - :xl10='tocPosition === `right`' - :lg9='tocPosition === `right`' + :xl='tocPosition === `right` ? 10 : false' + :lg='tocPosition === `right` ? 9 : false' style='margin-top: auto; margin-bottom: auto;' :class='$vuetify.rtl ? `pr-4` : `pl-4`' ) @@ -736,9 +736,13 @@ export default { .page-header-section { position: relative; + > .is-page-header { + position: relative; + } + .page-edit-shortcuts { position: absolute; - bottom: -14px; + bottom: -43px; right: 10px; .v-btn { From c91ff2da7eae98d10a6b02ba0c5e521c39cb8d06 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 10 Dec 2022 18:12:04 -0500 Subject: [PATCH 072/164] feat: add page-ready client boot event --- client/themes/default/components/page.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/themes/default/components/page.vue b/client/themes/default/components/page.vue index bd7d8b8eaf..a4c8178794 100644 --- a/client/themes/default/components/page.vue +++ b/client/themes/default/components/page.vue @@ -639,6 +639,8 @@ export default { this.$vuetify.goTo(decodeURIComponent(ev.currentTarget.hash), this.scrollOpts) } }) + + window.boot.notify('page-ready') }) }, methods: { From d6d88ed9765e6a0748b2e13767b8f2388fde8054 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 10 Dec 2022 19:38:26 -0500 Subject: [PATCH 073/164] fix: edit buttons header alignment when toc sidebar is on the right --- client/themes/default/components/page.vue | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/client/themes/default/components/page.vue b/client/themes/default/components/page.vue index a4c8178794..0d1f6473fa 100644 --- a/client/themes/default/components/page.vue +++ b/client/themes/default/components/page.vue @@ -58,9 +58,13 @@ style='margin-top: auto; margin-bottom: auto;' :class='$vuetify.rtl ? `pr-4` : `pl-4`' ) - .headline.grey--text(:class='$vuetify.theme.dark ? `text--lighten-2` : `text--darken-3`') {{title}} - .caption.grey--text.text--darken-1 {{description}} - .page-edit-shortcuts(v-if='editShortcutsObj.editMenuBar') + .page-header-headings + .headline.grey--text(:class='$vuetify.theme.dark ? `text--lighten-2` : `text--darken-3`') {{title}} + .caption.grey--text.text--darken-1 {{description}} + .page-edit-shortcuts( + v-if='editShortcutsObj.editMenuBar' + :class='tocPosition === `right` ? `is-right` : ``' + ) v-btn( v-if='editShortcutsObj.editMenuBtn' @click='pageEdit' @@ -742,9 +746,16 @@ export default { position: relative; } + .page-header-headings { + min-height: 52px; + display: flex; + justify-content: center; + flex-direction: column; + } + .page-edit-shortcuts { position: absolute; - bottom: -43px; + bottom: -33px; right: 10px; .v-btn { From eadefb88278608cfe4c65923e3213cb5306b8b6d Mon Sep 17 00:00:00 2001 From: topdev-spetermann <121106551+topdev-spetermann@users.noreply.github.com> Date: Thu, 22 Dec 2022 00:37:41 +0100 Subject: [PATCH 074/164] fix: sideloading locales should import availabilities (#5973) --- server/core/sideloader.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/core/sideloader.js b/server/core/sideloader.js index 40d80966de..cbdb58c7d0 100644 --- a/server/core/sideloader.js +++ b/server/core/sideloader.js @@ -52,7 +52,8 @@ module.exports = { strings: lcObj, isRTL: locale.isRTL, name: locale.name, - nativeName: locale.nativeName + nativeName: locale.nativeName, + availability: locale.availability || 0 }).where('code', locale.code) } else { await WIKI.models.locales.query().insert({ @@ -60,7 +61,8 @@ module.exports = { strings: lcObj, isRTL: locale.isRTL, name: locale.name, - nativeName: locale.nativeName + nativeName: locale.nativeName, + availability: locale.availability || 0 }) } importedLocales++ From 54dbf9ad00e7405e22fee77239854acaf185a24e Mon Sep 17 00:00:00 2001 From: Boris Date: Sat, 24 Dec 2022 04:19:16 +0300 Subject: [PATCH 075/164] feat: add asciidoc editor module (#5954) * feat: add asciidoc editor module * fix storage file extension for asciidoc pages * fix: asciidoc editor + rendering improvements * fix: description list css improvements Co-authored-by: NGPixel --- client/components/admin.vue | 12 - client/components/editor.vue | 1 + .../{markdown/fold.js => common/cmFold.js} | 10 +- client/components/editor/editor-asciidoc.vue | 707 ++++++++++++++++++ client/components/editor/editor-markdown.vue | 34 +- .../editor/editor-modal-editorselect.vue | 179 +---- client/static/svg/editor-icon-asciidoc.svg | 1 + client/themes/default/scss/app.scss | 159 ++++ package.json | 2 + server/helpers/page.js | 1 + server/models/editors.js | 2 + server/modules/editor/asciidoc/definition.yml | 6 + .../rendering/asciidoc-core/definition.yml | 20 + .../rendering/asciidoc-core/renderer.js | 26 + yarn.lock | 71 ++ 15 files changed, 1039 insertions(+), 192 deletions(-) rename client/components/editor/{markdown/fold.js => common/cmFold.js} (92%) create mode 100644 client/components/editor/editor-asciidoc.vue create mode 100644 client/static/svg/editor-icon-asciidoc.svg create mode 100644 server/modules/editor/asciidoc/definition.yml create mode 100644 server/modules/rendering/asciidoc-core/definition.yml create mode 100644 server/modules/rendering/asciidoc-core/renderer.js diff --git a/client/components/admin.vue b/client/components/admin.vue index f6e3722a07..1d0762f300 100644 --- a/client/components/admin.vue +++ b/client/components/admin.vue @@ -65,15 +65,6 @@ v-list-item(to='/comments') v-list-item-avatar(size='24', tile): v-icon mdi-comment-text-outline v-list-item-title {{ $t('admin:comments.title') }} - v-list-item(to='/editor', disabled) - v-list-item-avatar(size='24', tile): v-icon(color='grey lighten-2') mdi-playlist-edit - v-list-item-title {{ $t('admin:editor.title') }} - v-list-item(to='/extensions') - v-list-item-avatar(size='24', tile): v-icon mdi-chip - v-list-item-title {{ $t('admin:extensions.title') }} - v-list-item(to='/logging', disabled) - v-list-item-avatar(size='24', tile): v-icon(color='grey lighten-2') mdi-script-text-outline - v-list-item-title {{ $t('admin:logging.title') }} v-list-item(to='/rendering', color='primary') v-list-item-avatar(size='24', tile): v-icon mdi-cogs v-list-item-title {{ $t('admin:rendering.title') }} @@ -104,9 +95,6 @@ v-list-item(to='/utilities', color='primary', v-if='hasPermission(`manage:system`)') v-list-item-avatar(size='24', tile): v-icon mdi-wrench-outline v-list-item-title {{ $t('admin:utilities.title') }} - v-list-item(to='/webhooks', v-if='hasPermission(`manage:system`)', disabled) - v-list-item-avatar(size='24', tile): v-icon(color='grey lighten-2') mdi-webhook - v-list-item-title {{ $t('admin:webhooks.title') }} v-list-group( to='/dev' no-action diff --git a/client/components/editor.vue b/client/components/editor.vue index 15311e9bed..7cd577b112 100644 --- a/client/components/editor.vue +++ b/client/components/editor.vue @@ -77,6 +77,7 @@ export default { editorApi: () => import(/* webpackChunkName: "editor-api", webpackMode: "lazy" */ './editor/editor-api.vue'), editorCode: () => import(/* webpackChunkName: "editor-code", webpackMode: "lazy" */ './editor/editor-code.vue'), editorCkeditor: () => import(/* webpackChunkName: "editor-ckeditor", webpackMode: "lazy" */ './editor/editor-ckeditor.vue'), + editorAsciidoc: () => import(/* webpackChunkName: "editor-asciidoc", webpackMode: "lazy" */ './editor/editor-asciidoc.vue'), editorMarkdown: () => import(/* webpackChunkName: "editor-markdown", webpackMode: "lazy" */ './editor/editor-markdown.vue'), editorRedirect: () => import(/* webpackChunkName: "editor-redirect", webpackMode: "lazy" */ './editor/editor-redirect.vue'), editorModalEditorselect: () => import(/* webpackChunkName: "editor", webpackMode: "eager" */ './editor/editor-modal-editorselect.vue'), diff --git a/client/components/editor/markdown/fold.js b/client/components/editor/common/cmFold.js similarity index 92% rename from client/components/editor/markdown/fold.js rename to client/components/editor/common/cmFold.js index 1bc56ef5ba..5226730374 100644 --- a/client/components/editor/markdown/fold.js +++ b/client/components/editor/common/cmFold.js @@ -7,7 +7,13 @@ const maxDepth = 100 const codeBlockStartMatch = /^`{3}[a-zA-Z0-9]+$/ const codeBlockEndMatch = /^`{3}$/ -CodeMirror.registerHelper('fold', 'markdown', function (cm, start) { +export default { + register(lang) { + CodeMirror.registerHelper('fold', lang, foldHandler) + } +} + +function foldHandler (cm, start) { const firstLine = cm.getLine(start.line) const lastLineNo = cm.lastLine() let end @@ -59,4 +65,4 @@ CodeMirror.registerHelper('fold', 'markdown', function (cm, start) { from: CodeMirror.Pos(start.line, firstLine.length), to: CodeMirror.Pos(end, cm.getLine(end).length) } -}) +} diff --git a/client/components/editor/editor-asciidoc.vue b/client/components/editor/editor-asciidoc.vue new file mode 100644 index 0000000000..296b2414b9 --- /dev/null +++ b/client/components/editor/editor-asciidoc.vue @@ -0,0 +1,707 @@ + + + + + diff --git a/client/components/editor/editor-markdown.vue b/client/components/editor/editor-markdown.vue index 6fc2e5815d..04b5c6aa83 100644 --- a/client/components/editor/editor-markdown.vue +++ b/client/components/editor/editor-markdown.vue @@ -124,44 +124,19 @@ span {{$t('editor:markup.insertAssets')}} v-tooltip(right, color='teal') template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p2s(icon, tile, v-on='on', dark, disabled, @click='toggleModal(`editorModalBlocks`)').mx-0 - v-icon(:color='activeModal === `editorModalBlocks` ? `teal` : ``') mdi-view-dashboard-outline - span {{$t('editor:markup.insertBlock')}} - v-tooltip(right, color='teal') - template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p3s(icon, tile, v-on='on', dark, disabled).mx-0 - v-icon mdi-code-braces - span {{$t('editor:markup.insertCodeBlock')}} - v-tooltip(right, color='teal') - template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p4s(icon, tile, v-on='on', dark, disabled).mx-0 - v-icon mdi-movie - span {{$t('editor:markup.insertVideoAudio')}} - v-tooltip(right, color='teal') - template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p5s(icon, tile, v-on='on', dark, @click='toggleModal(`editorModalDrawio`)').mx-0 + v-btn.mt-3.animated.fadeInLeft.wait-p2s(icon, tile, v-on='on', dark, @click='toggleModal(`editorModalDrawio`)').mx-0 v-icon mdi-chart-multiline span {{$t('editor:markup.insertDiagram')}} - v-tooltip(right, color='teal') - template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p6s(icon, tile, v-on='on', dark, disabled).mx-0 - v-icon mdi-function-variant - span {{$t('editor:markup.insertMathExpression')}} - v-tooltip(right, color='teal') - template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p7s(icon, tile, v-on='on', dark, disabled).mx-0 - v-icon mdi-table-plus - span {{$t('editor:markup.tableHelper')}} template(v-if='$vuetify.breakpoint.mdAndUp') v-spacer v-tooltip(right, color='teal') template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p8s(icon, tile, v-on='on', dark, @click='toggleFullscreen').mx-0 + v-btn.mt-3.animated.fadeInLeft.wait-p3s(icon, tile, v-on='on', dark, @click='toggleFullscreen').mx-0 v-icon mdi-arrow-expand-all span {{$t('editor:markup.distractionFreeMode')}} v-tooltip(right, color='teal') template(v-slot:activator='{ on }') - v-btn.mt-3.animated.fadeInLeft.wait-p9s(icon, tile, v-on='on', dark, @click='toggleHelp').mx-0 + v-btn.mt-3.animated.fadeInLeft.wait-p4s(icon, tile, v-on='on', dark, @click='toggleHelp').mx-0 v-icon(:color='helpShown ? `teal` : ``') mdi-help-circle span {{$t('editor:markup.markdownFormattingHelp')}} .editor-markdown-editor @@ -220,7 +195,6 @@ import 'codemirror/addon/hint/show-hint.js' import 'codemirror/addon/fold/foldcode.js' import 'codemirror/addon/fold/foldgutter.js' import 'codemirror/addon/fold/foldgutter.css' -import './markdown/fold' // Markdown-it import MarkdownIt from 'markdown-it' @@ -251,6 +225,7 @@ import mermaid from 'mermaid' // Helpers import katexHelper from './common/katex' import tabsetHelper from './markdown/tabset' +import cmFold from './common/cmFold' // ======================================== // INIT @@ -337,6 +312,7 @@ md.renderer.rules.paragraph_open = injectLineNumbers md.renderer.rules.heading_open = injectLineNumbers md.renderer.rules.blockquote_open = injectLineNumbers +cmFold.register('markdown') // ======================================== // PLANTUML // ======================================== diff --git a/client/components/editor/editor-modal-editorselect.vue b/client/components/editor/editor-modal-editorselect.vue index b5ce35f5c1..df2adf96a0 100644 --- a/client/components/editor/editor-modal-editorselect.vue +++ b/client/components/editor/editor-modal-editorselect.vue @@ -6,57 +6,7 @@ .subtitle-1.white--text {{$t('editor:select.title')}} v-container(grid-list-lg, fluid) v-layout(row, wrap, justify-center) - v-flex(xs4) - v-hover - template(v-slot:default='{ hover }') - v-card.radius-7.primary.animated.fadeInUp( - hover - light - ripple - ) - v-card-text.text-center(@click='') - img(src='/_assets/svg/editor-icon-api.svg', alt='API', style='width: 36px; opacity: .5;') - .body-2.blue--text.mt-2.text--lighten-2 API Docs - .caption.blue--text.text--lighten-1 REST / GraphQL - v-fade-transition - v-overlay( - v-if='hover' - absolute - color='primary' - opacity='.8' - ) - .body-2.mt-7 Coming Soon - v-flex(xs4) - v-hover - template(v-slot:default='{ hover }') - v-card.radius-7.primary.animated.fadeInUp.wait-p1s( - hover - light - ripple - ) - v-card-text.text-center(@click='') - img(src='/_assets/svg/editor-icon-wikitext.svg', alt='WikiText', style='width: 36px; opacity: .5;') - .body-2.blue--text.mt-2.text--lighten-2 Blog - .caption.blue--text.text--lighten-1 Timeline of Posts - v-fade-transition - v-overlay( - v-if='hover' - absolute - color='primary' - opacity='.8' - ) - .body-2.mt-7 Coming Soon - v-flex(xs4) - v-card.radius-7.animated.fadeInUp.wait-p2s( - hover - light - ripple - ) - v-card-text.text-center(@click='selectEditor("code")') - img(src='/_assets/svg/editor-icon-code.svg', alt='Code', style='width: 36px;') - .body-2.primary--text.mt-2 Code - .caption.grey--text Raw HTML - v-flex(xs4) + v-flex(xs6) v-card.radius-7.animated.fadeInUp.wait-p1s( hover light @@ -66,28 +16,8 @@ img(src='/_assets/svg/editor-icon-markdown.svg', alt='Markdown', style='width: 36px;') .body-2.primary--text.mt-2 Markdown .caption.grey--text Plain Text Formatting - v-flex(xs4) - v-hover - template(v-slot:default='{ hover }') - v-card.radius-7.primary.animated.fadeInUp.wait-p2s( - hover - light - ripple - ) - v-card-text.text-center(@click='') - img(src='/_assets/svg/editor-icon-tabular.svg', alt='Tabular', style='width: 36px; opacity: .5;') - .body-2.blue--text.mt-2.text--lighten-2 Tabular - .caption.blue--text.text--lighten-1 Excel-like - v-fade-transition - v-overlay( - v-if='hover' - absolute - color='primary' - opacity='.8' - ) - .body-2.mt-7 Coming Soon - v-flex(xs4) - v-card.radius-7.animated.fadeInUp.wait-p3s( + v-flex(xs6) + v-card.radius-7.animated.fadeInUp.wait-p2s( hover light ripple @@ -96,85 +26,36 @@ img(src='/_assets/svg/editor-icon-ckeditor.svg', alt='Visual Editor', style='width: 36px;') .body-2.mt-2.primary--text Visual Editor .caption.grey--text Rich-text WYSIWYG - //- .caption.blue--text.text--lighten-2 {{$t('editor:select.cannotChange')}} - - v-card.radius-7.mt-2(color='teal darken-3', dark) - v-card-text.text-center.py-4 - .subtitle-1.white--text {{$t('editor:select.customView')}} - v-container(grid-list-lg, fluid) - v-layout(row, wrap, justify-center) v-flex(xs4) - v-hover - template(v-slot:default='{ hover }') - v-card.radius-7.animated.fadeInUp( - hover - light - ripple - ) - v-card-text.text-center(@click='fromTemplate') - img(src='/_assets/svg/icon-cube.svg', alt='From Template', style='width: 42px; opacity: .5;') - .body-2.mt-1.teal--text From Template - .caption.grey--text Use an existing page... + v-card.radius-7.animated.fadeInUp.wait-p3s( + hover + light + ripple + ) + v-card-text.text-center(@click='selectEditor("asciidoc")') + img(src='/_assets/svg/editor-icon-asciidoc.svg', alt='AsciiDoc', style='width: 36px;') + .body-2.primary--text.mt-2 AsciiDoc + .caption.grey--text Plain Text Formatting v-flex(xs4) - v-hover - template(v-slot:default='{ hover }') - v-card.radius-7.teal.animated.fadeInUp.wait-p1s( - hover - light - ripple - ) - //- v-card-text.text-center(@click='selectEditor("redirect")') - v-card-text.text-center(@click='') - img(src='/_assets/svg/icon-route.svg', alt='Redirection', style='width: 42px; opacity: .5;') - .body-2.mt-1.teal--text.text--lighten-2 Redirection - .caption.teal--text.text--lighten-1 Redirect the user to... + v-card.radius-7.animated.fadeInUp.wait-p4s( + hover + light + ripple + ) + v-card-text.text-center(@click='selectEditor("code")') + img(src='/_assets/svg/editor-icon-code.svg', alt='Code', style='width: 36px;') + .body-2.primary--text.mt-2 Code + .caption.grey--text Raw HTML v-flex(xs4) - v-hover - template(v-slot:default='{ hover }') - v-card.radius-7.teal.animated.fadeInUp.wait-p2s( - hover - light - ripple - ) - v-card-text.text-center(@click='') - img(src='/_assets/svg/icon-sewing-patch.svg', alt='Code', style='width: 42px; opacity: .5;') - .body-2.mt-1.teal--text.text--lighten-2 Embed - .caption.teal--text.text--lighten-1 Include external pages - v-fade-transition - v-overlay( - v-if='hover' - absolute - color='teal' - opacity='.8' - ) - .body-2.mt-7 Coming Soon - v-hover - template(v-slot:default='{ hover }') - v-card.radius-7.mt-2(color='indigo darken-3', dark) - v-toolbar(dense, flat, color='light-green darken-3') - v-spacer - .caption.mr-1 or convert from - v-btn.mx-1.animated.fadeInUp(depressed, color='light-green darken-2', @click='', disabled) - v-icon(left) mdi-alpha-a-circle - .body-2.text-none AsciiDoc - v-btn.mx-1.animated.fadeInUp.wait-p1s(depressed, color='light-green darken-2', @click='', disabled) - v-icon(left) mdi-alpha-c-circle - .body-2.text-none CREOLE - v-btn.mx-1.animated.fadeInUp.wait-p2s(depressed, color='light-green darken-2', @click='', disabled) - v-icon(left) mdi-alpha-t-circle - .body-2.text-none Textile - v-btn.mx-1.animated.fadeInUp.wait-p3s(depressed, color='light-green darken-2', @click='', disabled) - v-icon(left) mdi-alpha-w-circle - .body-2.text-none WikiText - v-spacer - v-fade-transition - v-overlay( - v-if='hover' - absolute - color='light-green darken-3' - opacity='.8' - ) - .body-2 Coming Soon + v-card.radius-7.animated.fadeInUp.wait-p5s( + hover + light + ripple + ) + v-card-text.text-center(@click='fromTemplate') + img(src='/_assets/svg/icon-cube.svg', alt='From Template', style='width: 42px; opacity: .5;') + .body-2.mt-1.teal--text From Template + .caption.grey--text Use an existing page... page-selector(mode='select', v-model='templateDialogIsShown', :open-handler='fromTemplateHandle', :path='path', :locale='locale', must-exist) diff --git a/client/static/svg/editor-icon-asciidoc.svg b/client/static/svg/editor-icon-asciidoc.svg new file mode 100644 index 0000000000..d0c954b184 --- /dev/null +++ b/client/static/svg/editor-icon-asciidoc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/themes/default/scss/app.scss b/client/themes/default/scss/app.scss index 8bba5e7250..5e7f0a958c 100644 --- a/client/themes/default/scss/app.scss +++ b/client/themes/default/scss/app.scss @@ -356,6 +356,148 @@ } } + // --------------------------------- + // ASCIIDOC SPECIFIC + // --------------------------------- + + .admonitionblock { + margin: 1rem 0; + position: relative; + + table { + border: none; + background-color: transparent; + width: 100%; + } + + td.icon { + border-bottom-left-radius: 7px; + border-top-left-radius: 7px; + text-align: center; + width: 56px; + + &::before { + display: inline-block; + font: normal normal normal 24px/1 "Material Design Icons", sans-serif !important; + } + } + + td.content { + border-bottom-right-radius: 7px; + border-top-right-radius: 7px; + } + + &.note { + td.icon { + background-color: mc('blue', '300'); + color: mc('blue', '50'); + &::before { + content: "\F02FC"; + } + } + td.content { + color: darken(mc('blue', '900'), 10%); + background-color: mc('blue', '50'); + + @at-root .theme--dark & { + background-color: mc('blue', '900'); + color: mc('blue', '50'); + } + } + } + &.tip { + td.icon { + background-color: mc('green', '300'); + color: mc('green', '50'); + &::before { + content: "\F0335"; + } + } + td.content { + color: darken(mc('green', '900'), 10%); + background-color: mc('green', '50'); + + @at-root .theme--dark & { + background-color: mc('green', '900'); + color: mc('green', '50'); + } + } + } + &.warning { + background-color: transparent !important; + + td.icon { + background-color: mc('orange', '300'); + color: #FFF; + &::before { + content: "\F0026"; + } + } + td.content { + color: darken(mc('orange', '900'), 10%); + background-color: mc('orange', '50'); + + @at-root .theme--dark & { + background-color: darken(mc('orange', '900'), 5%); + color: mc('orange', '100'); + } + } + } + &.caution { + td.icon { + background-color: mc('purple', '300'); + color: mc('purple', '50'); + &::before { + content: "\f0238"; + } + } + td.content { + color: darken(mc('purple', '900'), 10%); + background-color: mc('purple', '50'); + + @at-root .theme--dark & { + background-color: mc('purple', '900'); + color: mc('purple', '100'); + } + } + } + &.important { + td.icon { + background-color: mc('red', '300'); + color: mc('red', '50'); + &::before { + content: "\F0159"; + } + } + td.content { + color: darken(mc('red', '900'), 10%); + background-color: mc('red', '50'); + + @at-root .theme--dark & { + background-color: mc('red', '900'); + color: mc('red', '100'); + } + } + } + } + + .exampleblock { + > .title { + font-style: italic; + font-size: 1rem !important; + color: #7a2717; + + @at-root .theme--dark & { + color: mc('brown', '300'); + } + } + > .content { + border: 1px solid mc('grey', '200'); + border-radius: 7px; + margin-bottom: 12px; + padding: 16px; + } + } // --------------------------------- // LISTS // --------------------------------- @@ -547,6 +689,23 @@ } } + dl { + dt { + margin-top: 0.3em; + margin-bottom: 0.3em; + font-weight: bold; + } + + dd { + margin-left: 1.125em; + margin-bottom: 0.75em; + + > p { + padding: 0; + } + } + } + // --------------------------------- // CODE // --------------------------------- diff --git a/package.json b/package.json index d6edb3fbaa..32d4ecd64b 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "node": ">=10.12" }, "dependencies": { + "asciidoctor": "2.2.6", "@azure/storage-blob": "12.12.0", "@exlinc/keycloak-passport": "1.0.2", "@joplin/turndown-plugin-gfm": "1.0.45", @@ -231,6 +232,7 @@ "clean-webpack-plugin": "3.0.0", "clipboard": "2.0.11", "codemirror": "5.58.2", + "codemirror-asciidoc": "1.0.4", "copy-webpack-plugin": "6.2.1", "core-js": "3.6.5", "css-loader": "4.3.0", diff --git a/server/helpers/page.js b/server/helpers/page.js index 8049edc103..8bea0aa3b2 100644 --- a/server/helpers/page.js +++ b/server/helpers/page.js @@ -10,6 +10,7 @@ const unsafeCharsRegex = /[\x00-\x1f\x80-\x9f\\"|<>:*?]/ const contentToExt = { markdown: 'md', + asciidoc: 'adoc', html: 'html' } const extToContent = _.invert(contentToExt) diff --git a/server/models/editors.js b/server/models/editors.js index 8a05ba9879..f4d091af81 100644 --- a/server/models/editors.js +++ b/server/models/editors.js @@ -101,6 +101,8 @@ module.exports = class Editor extends Model { return 'markdown' case 'html': return 'ckeditor' + case 'asciidoc': + return 'asciidoc' default: return 'code' } diff --git a/server/modules/editor/asciidoc/definition.yml b/server/modules/editor/asciidoc/definition.yml new file mode 100644 index 0000000000..378b60da67 --- /dev/null +++ b/server/modules/editor/asciidoc/definition.yml @@ -0,0 +1,6 @@ +key: asciidoc +title: Asciidoc +description: Basic Asciidoc editor +contentType: asciidoc +author: dzruyk +props: {} diff --git a/server/modules/rendering/asciidoc-core/definition.yml b/server/modules/rendering/asciidoc-core/definition.yml new file mode 100644 index 0000000000..8a11eb14d9 --- /dev/null +++ b/server/modules/rendering/asciidoc-core/definition.yml @@ -0,0 +1,20 @@ +key: asciidocCore +title: Core +description: Basic Asciidoc Parser +author: dzruyk (Based on asciidoctor.js renderer) +input: asciidoc +output: html +icon: mdi-sitemap +enabledDefault: true +props: + safeMode: + type: String + default: server + title: Safe Mode + hint: Sets the safe mode to use when parsing content to HTML. + order: 1 + enum: + - unsafe + - safe + - server + - secure diff --git a/server/modules/rendering/asciidoc-core/renderer.js b/server/modules/rendering/asciidoc-core/renderer.js new file mode 100644 index 0000000000..e37217d875 --- /dev/null +++ b/server/modules/rendering/asciidoc-core/renderer.js @@ -0,0 +1,26 @@ +const asciidoctor = require('asciidoctor')() +const cheerio = require('cheerio') + +module.exports = { + async render() { + const html = asciidoctor.convert(this.input, { + standalone: false, + safe: this.config.safeMode, + attributes: { + showtitle: true, + icons: 'font' + } + }) + + const $ = cheerio.load(html, { + decodeEntities: true + }) + + $('pre.highlight > code.language-diagram').each((i, elm) => { + const diagramContent = Buffer.from($(elm).html(), 'base64').toString() + $(elm).parent().replaceWith(`
${diagramContent}`)
+    })
+
+    return $.html()
+  }
+}
diff --git a/yarn.lock b/yarn.lock
index 37a5605830..92107b1cd6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -177,6 +177,21 @@
   dependencies:
     tslib "~2.0.1"
 
+"@asciidoctor/cli@3.5.0":
+  version "3.5.0"
+  resolved "https://registry.yarnpkg.com/@asciidoctor/cli/-/cli-3.5.0.tgz#0b0a0204880b325971fb2af33bf490ab67672d8f"
+  integrity sha512-/VMHXcZBnZ9vgWfmqk9Hu0x0gMjPLup0YGq/xA8qCQuk11kUIZNMVQwgSsIUzOEwJqIUD7CgncJdtfwv1Ndxuw==
+  dependencies:
+    yargs "16.2.0"
+
+"@asciidoctor/core@2.2.6":
+  version "2.2.6"
+  resolved "https://registry.yarnpkg.com/@asciidoctor/core/-/core-2.2.6.tgz#a59a9e8ab48ac0a615d5a3200214d3071291c5d5"
+  integrity sha512-TmB2K5UfpDpSbCNBBntXzKHcAk2EA3/P68jmWvmJvglVUdkO9V6kTAuXVe12+h6C4GK0ndwuCrHHtEVcL5t6pQ==
+  dependencies:
+    asciidoctor-opal-runtime "0.3.3"
+    unxhr "1.0.1"
+
 "@azure/abort-controller@^1.0.0":
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.1.tgz#8510935b25ac051e58920300e9d7b511ca6e656a"
@@ -5168,6 +5183,22 @@ asap@^2.0.0, asap@~2.0.3:
   resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
   integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
 
+asciidoctor-opal-runtime@0.3.3:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/asciidoctor-opal-runtime/-/asciidoctor-opal-runtime-0.3.3.tgz#2667635f858d3eb3fdfcf6795cf68138e2040174"
+  integrity sha512-/CEVNiOia8E5BMO9FLooo+Kv18K4+4JBFRJp8vUy/N5dMRAg+fRNV4HA+o6aoSC79jVU/aT5XvUpxSxSsTS8FQ==
+  dependencies:
+    glob "7.1.3"
+    unxhr "1.0.1"
+
+asciidoctor@2.2.6:
+  version "2.2.6"
+  resolved "https://registry.yarnpkg.com/asciidoctor/-/asciidoctor-2.2.6.tgz#43b5fec8ab91ed2d8d1815c75067cfa29da2e568"
+  integrity sha512-EXG3+F2pO21B+COfQmV/WgEgGiy7nG/mJiS/o5DXpaT2q82FRZWPVkbMZrpDvpu4pjXe5c754RbZR9Vz0L0Vtw==
+  dependencies:
+    "@asciidoctor/cli" "3.5.0"
+    "@asciidoctor/core" "2.2.6"
+
 asn1.js@^4.0.0:
   version "4.10.1"
   resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
@@ -6681,6 +6712,11 @@ code-point-at@^1.0.0:
   resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
   integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
 
+codemirror-asciidoc@1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/codemirror-asciidoc/-/codemirror-asciidoc-1.0.4.tgz#7439fcc38f30f1408ab144d156bf398ed35b2cc0"
+  integrity sha512-U+G8+ToPONYFGkwTprxpFzV6EV1bCA9zChAA8uT2YAnKFn357JMWL2VkdIPy2yP5N/X13GzslMOGaAk1UNE3rA==
+
 codemirror@5.58.2:
   version "5.58.2"
   resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.58.2.tgz#ed54a1796de1498688bea1cdd4e9eeb187565d1b"
@@ -10252,6 +10288,18 @@ glob-parent@~5.1.2:
   dependencies:
     is-glob "^4.0.1"
 
+glob@7.1.3:
+  version "7.1.3"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
+  integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.4"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
 glob@^6.0.1:
   version "6.0.4"
   resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
@@ -19425,6 +19473,11 @@ untildify@^4.0.0:
   resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
   integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
 
+unxhr@1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/unxhr/-/unxhr-1.0.1.tgz#92200322d66c728993de771f9e01eeb21f41bc7b"
+  integrity sha512-MAhukhVHyaLGDjyDYhy8gVjWJyhTECCdNsLwlMoGFoNJ3o79fpQhtQuzmAE4IxCMDwraF4cW8ZjpAV0m9CRQbg==
+
 upath@^1.1.1:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
@@ -20445,6 +20498,11 @@ y18n@^5.0.2:
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
   integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
 
+y18n@^5.0.5:
+  version "5.0.8"
+  resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
+  integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+
 yaeti@^0.0.6:
   version "0.0.6"
   resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577"
@@ -20514,6 +20572,19 @@ yargs@16.1.0:
     y18n "^5.0.2"
     yargs-parser "^20.2.2"
 
+yargs@16.2.0:
+  version "16.2.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
+  integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+  dependencies:
+    cliui "^7.0.2"
+    escalade "^3.1.1"
+    get-caller-file "^2.0.5"
+    require-directory "^2.1.1"
+    string-width "^4.2.0"
+    y18n "^5.0.5"
+    yargs-parser "^20.2.2"
+
 yargs@^13.3.2:
   version "13.3.2"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"

From 41454cfd30cbdbbcc4dfb53f1c29aecfcce470b2 Mon Sep 17 00:00:00 2001
From: Eric Knibbe 
Date: Fri, 13 Jan 2023 17:54:15 -0500
Subject: [PATCH 076/164] fix(git): disable color.ui in git storage (#6014)

---
 server/modules/storage/git/storage.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/server/modules/storage/git/storage.js b/server/modules/storage/git/storage.js
index cd69f3e720..0995445abc 100644
--- a/server/modules/storage/git/storage.js
+++ b/server/modules/storage/git/storage.js
@@ -45,9 +45,10 @@ module.exports = {
       await this.git.init()
     }
 
-    // Disable quotePath
+    // Disable quotePath, color output
     // Link https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath
     await this.git.raw(['config', '--local', 'core.quotepath', false])
+    await this.git.raw(['config', '--local', 'color.ui', false])
 
     // Set default author
     await this.git.raw(['config', '--local', 'user.email', this.config.defaultEmail])

From a906f2e7820273ef25bbad5dcf1cc6dc15525544 Mon Sep 17 00:00:00 2001
From: Nicolas Giard 
Date: Fri, 13 Jan 2023 18:07:01 -0500
Subject: [PATCH 077/164] docs: update issue template

---
 .github/ISSUE_TEMPLATE/config.yml | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 680ec362d3..90c15174fa 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -3,9 +3,6 @@ contact_links:
   - name: Help / Questions
     url: https://github.com/Requarks/wiki/discussions/categories/help-questions
     about: Ask the community for help on using or setting up Wiki.js
-  - name: Report a Security Issue
-    url: https://github.com/Requarks/wiki/security/policy
-    about: Privately report security issues so they can be addressed quickly.
   - name: Errors / Bug Reports
     url: https://github.com/Requarks/wiki/discussions/categories/error-bug-report
     about: Create a discussion around the bug / error you're getting. If validated, a proper GitHub issue will be created so that it can be worked on.

From 9dddef3a3fceac5134a261ee8a0f937568585cf6 Mon Sep 17 00:00:00 2001
From: Nicolas Giard 
Date: Fri, 13 Jan 2023 18:09:20 -0500
Subject: [PATCH 078/164] docs: remove old issue template

---
 .github/ISSUE_TEMPLATE.md | 12 ------------
 1 file changed, 12 deletions(-)
 delete mode 100644 .github/ISSUE_TEMPLATE.md

diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 3b4b7ae9fc..0000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-### Actual behavior
-
-### Expected behavior
-
-### Steps to reproduce the behavior
-
-
-
-

From 12233c476d6b8addd17b1ea3d1428c1605d18458 Mon Sep 17 00:00:00 2001
From: Sleuth56 <34520077+Sleuth56@users.noreply.github.com>
Date: Sun, 29 Jan 2023 16:51:40 -0500
Subject: [PATCH 079/164] feat: enable state key on generic oauth2 (#6104)

---
 server/modules/authentication/oauth2/authentication.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/server/modules/authentication/oauth2/authentication.js b/server/modules/authentication/oauth2/authentication.js
index a2285cfff8..f40fb395e5 100644
--- a/server/modules/authentication/oauth2/authentication.js
+++ b/server/modules/authentication/oauth2/authentication.js
@@ -18,7 +18,8 @@ module.exports = {
       userInfoURL: conf.userInfoURL,
       callbackURL: conf.callbackURL,
       passReqToCallback: true,
-      scope: conf.scope
+      scope: conf.scope,
+      state: true
     }, async (req, accessToken, refreshToken, profile, cb) => {
       try {
         const user = await WIKI.models.users.processProfile({

From 5f876ced20279c7561f1c2227ae9600a1f7ddfc5 Mon Sep 17 00:00:00 2001
From: NGPixel 
Date: Sun, 29 Jan 2023 17:14:34 -0500
Subject: [PATCH 080/164] feat: optional oauth2 module nonce toggle

---
 server/modules/authentication/oauth2/authentication.js | 2 +-
 server/modules/authentication/oauth2/definition.yml    | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/server/modules/authentication/oauth2/authentication.js b/server/modules/authentication/oauth2/authentication.js
index f40fb395e5..7be57f7463 100644
--- a/server/modules/authentication/oauth2/authentication.js
+++ b/server/modules/authentication/oauth2/authentication.js
@@ -19,7 +19,7 @@ module.exports = {
       callbackURL: conf.callbackURL,
       passReqToCallback: true,
       scope: conf.scope,
-      state: true
+      state: conf.enableCSRFProtection
     }, async (req, accessToken, refreshToken, profile, cb) => {
       try {
         const user = await WIKI.models.users.processProfile({
diff --git a/server/modules/authentication/oauth2/definition.yml b/server/modules/authentication/oauth2/definition.yml
index 0621aa3922..45c1918383 100644
--- a/server/modules/authentication/oauth2/definition.yml
+++ b/server/modules/authentication/oauth2/definition.yml
@@ -70,3 +70,9 @@ props:
     title: Pass access token via GET query string to User Info Endpoint
     hint: (optional) Pass the access token in an `access_token` parameter attached to the GET query string of the User Info Endpoint URL. Otherwise the access token will be passed in the Authorization header.
     order: 11
+  enableCSRFProtection:
+    type: Boolean
+    default: true
+    title: Enable CSRF protection
+    hint: Pass a nonce state parameter during authentication to protect against CSRF attacks.
+    order: 12

From 43a797d32276449f3568d58bb53419d3171afc82 Mon Sep 17 00:00:00 2001
From: gueldi <45048474+gueldenstone@users.noreply.github.com>
Date: Sun, 29 Jan 2023 23:55:47 +0100
Subject: [PATCH 081/164] feat: adds displayName property to OIDC
 authentication module (#6096)

* Adds displayName property to oidc authentication method
* fix: update displayName prop
* fix: use blank display name in oidc auth

---------

Co-authored-by: Nicolas Giard 
---
 .../modules/authentication/oidc/authentication.js   |  3 ++-
 server/modules/authentication/oidc/definition.yml   | 13 ++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/server/modules/authentication/oidc/authentication.js b/server/modules/authentication/oidc/authentication.js
index de76da4173..22a3f2c53d 100644
--- a/server/modules/authentication/oidc/authentication.js
+++ b/server/modules/authentication/oidc/authentication.js
@@ -28,7 +28,8 @@ module.exports = {
             providerKey: req.params.strategy,
             profile: {
               ...profile,
-              email: _.get(profile, '_json.' + conf.emailClaim)
+              email: _.get(profile, '_json.' + conf.emailClaim),
+              displayName: _.get(profile, conf.displayNameClaim, ''),
             }
           })
           if (conf.mapGroups) {
diff --git a/server/modules/authentication/oidc/definition.yml b/server/modules/authentication/oidc/definition.yml
index ae1c636a28..4ec22e797f 100644
--- a/server/modules/authentication/oidc/definition.yml
+++ b/server/modules/authentication/oidc/definition.yml
@@ -49,21 +49,28 @@ props:
     default: email
     maxWidth: 500
     order: 7
+  displayNameClaim:
+    type: String
+    title: Display Name Claim
+    hint: Field containing the user display name
+    default: displayName
+    maxWidth: 500
+    order: 8
   mapGroups:
     type: Boolean
     title: Map Groups
     hint: Map groups matching names from the groups claim value
     default: false
-    order: 8
+    order: 9
   groupsClaim:
     type: String
     title: Groups Claim
     hint: Field containing the group names
     default: groups
     maxWidth: 500
-    order: 9
+    order: 10
   logoutURL:
     type: String
     title: Logout URL
     hint: (optional) Logout URL on the OAuth2 provider where the user will be redirected to complete the logout process.
-    order: 10
+    order: 11

From 1da80eaab8367a67a38b5603693022c146d35f66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Lajoie?= 
Date: Mon, 30 Jan 2023 00:08:13 +0100
Subject: [PATCH 082/164] feat: oauth2 add groups mapping (#6053)

Co-authored-by: Nicolas Giard 
---
 .../authentication/oauth2/authentication.js   | 13 ++++++++++++
 .../authentication/oauth2/definition.yml      | 21 +++++++++++++++----
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/server/modules/authentication/oauth2/authentication.js b/server/modules/authentication/oauth2/authentication.js
index 7be57f7463..ce66c3db0d 100644
--- a/server/modules/authentication/oauth2/authentication.js
+++ b/server/modules/authentication/oauth2/authentication.js
@@ -31,6 +31,19 @@ module.exports = {
             email: _.get(profile, conf.emailClaim)
           }
         })
+        if (conf.mapGroups) {
+          const groups = _.get(profile, conf.groupsClaim)
+          if (groups && _.isArray(groups)) {
+            const currentGroups = (await user.$relatedQuery('groups').select('groups.id')).map(g => g.id)
+            const expectedGroups = Object.values(WIKI.auth.groups).filter(g => groups.includes(g.name)).map(g => g.id)
+            for (const groupId of _.difference(expectedGroups, currentGroups)) {
+              await user.$relatedQuery('groups').relate(groupId)
+            }
+            for (const groupId of _.difference(currentGroups, expectedGroups)) {
+              await user.$relatedQuery('groups').unrelate().where('groupId', groupId)
+            }
+          }
+        }
         cb(null, user)
       } catch (err) {
         cb(err, null)
diff --git a/server/modules/authentication/oauth2/definition.yml b/server/modules/authentication/oauth2/definition.yml
index 45c1918383..0e59962944 100644
--- a/server/modules/authentication/oauth2/definition.yml
+++ b/server/modules/authentication/oauth2/definition.yml
@@ -54,25 +54,38 @@ props:
     default: email
     maxWidth: 500
     order: 8
+  mapGroups:
+    type: Boolean
+    title: Map Groups
+    hint: Map groups matching names from the groups claim value
+    default: false
+    order: 9
+  groupsClaim:
+    type: String
+    title: Groups Claim
+    hint: Field containing the group names
+    default: groups
+    maxWidth: 500
+    order: 10
   logoutURL:
     type: String
     title: Logout URL
     hint: (optional) Logout URL on the OAuth2 provider where the user will be redirected to complete the logout process.
-    order: 9
+    order: 11
   scope:
     type: String
     title: Scope
     hint: (optional) Application Client permission scopes.
-    order: 10
+    order: 12
   useQueryStringForAccessToken:
     type: Boolean
     default: false
     title: Pass access token via GET query string to User Info Endpoint
     hint: (optional) Pass the access token in an `access_token` parameter attached to the GET query string of the User Info Endpoint URL. Otherwise the access token will be passed in the Authorization header.
-    order: 11
+    order: 13
   enableCSRFProtection:
     type: Boolean
     default: true
     title: Enable CSRF protection
     hint: Pass a nonce state parameter during authentication to protect against CSRF attacks.
-    order: 12
+    order: 14

From 0d914b061e62443f600e1392cbbe0a483e99adf0 Mon Sep 17 00:00:00 2001
From: Leangseu Kim 
Date: Sun, 29 Jan 2023 21:43:55 -0500
Subject: [PATCH 083/164] feat: add singleByPath GraphQL resolver (#6011)

Co-authored-by: k k 
---
 server/graph/resolvers/page.js    | 24 ++++++++++++++++++++++++
 server/graph/schemas/page.graphql |  5 +++++
 2 files changed, 29 insertions(+)

diff --git a/server/graph/resolvers/page.js b/server/graph/resolvers/page.js
index 15631a18a8..9e99686ad6 100644
--- a/server/graph/resolvers/page.js
+++ b/server/graph/resolvers/page.js
@@ -170,6 +170,30 @@ module.exports = {
         throw new WIKI.Error.PageNotFound()
       }
     },
+    async singleByPath(obj, args, context, info) {
+      let page = await WIKI.models.pages.getPageFromDb({
+        path: args.path,
+        locale: args.locale,
+      });
+      if (page) {
+        if (WIKI.auth.checkAccess(context.req.user, ['manage:pages', 'delete:pages'], {
+          path: page.path,
+          locale: page.localeCode
+        })) {
+          return {
+            ...page,
+            locale: page.localeCode,
+            editor: page.editorKey,
+            scriptJs: page.extra.js,
+            scriptCss: page.extra.css
+          }
+        } else {
+          throw new WIKI.Error.PageViewForbidden()
+        }
+      } else {
+        throw new WIKI.Error.PageNotFound()
+      }
+    },
     /**
      * FETCH TAGS
      */
diff --git a/server/graph/schemas/page.graphql b/server/graph/schemas/page.graphql
index 10eebc8560..552ad32586 100644
--- a/server/graph/schemas/page.graphql
+++ b/server/graph/schemas/page.graphql
@@ -46,6 +46,11 @@ type PageQuery {
     id: Int!
   ): Page @auth(requires: ["read:pages", "manage:system"])
 
+  singleByPath(
+    path: String!
+    locale: String!
+  ): Page @auth(requires: ["read:pages", "manage:system"])
+
   tags: [PageTag]! @auth(requires: ["manage:system", "read:pages"])
 
   searchTags(

From 8fa771c4ce6b667d5c2b1de6b343977af4351644 Mon Sep 17 00:00:00 2001
From: Charlotte County Public Schools
 <119430841+icsinfo@users.noreply.github.com>
Date: Sun, 29 Jan 2023 22:52:21 -0500
Subject: [PATCH 084/164] feat: set groups based on LDAP groups (#5903)

* Add mapping ldap groups to wiki groups
---------

Co-authored-by: Nicolas Giard 
---
 .../authentication/ldap/authentication.js     | 24 ++++++++++++-
 .../authentication/ldap/definition.yml        | 36 +++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/server/modules/authentication/ldap/authentication.js b/server/modules/authentication/ldap/authentication.js
index 8f5a9817ab..29d2148220 100644
--- a/server/modules/authentication/ldap/authentication.js
+++ b/server/modules/authentication/ldap/authentication.js
@@ -19,6 +19,13 @@ module.exports = {
           searchBase: conf.searchBase,
           searchFilter: conf.searchFilter,
           tlsOptions: getTlsOptions(conf),
+          ...conf.mapGroups && {
+            groupSearchBase: conf.groupSearchBase,
+            groupSearchFilter: conf.groupSearchFilter,
+            groupSearchScope: conf.groupSearchScope,
+            groupDnProperty: conf.groupDnProperty,
+            groupSearchAttributes: [conf.groupNameField]
+          },
           includeRaw: true
         },
         usernameField: 'email',
@@ -40,6 +47,21 @@ module.exports = {
               picture: _.get(profile, `_raw.${conf.mappingPicture}`, '')
             }
           })
+          // map users LDAP groups to wiki groups with the same name, and remove any groups that don't match LDAP
+          if (conf.mapGroups) {
+            const ldapGroups = _.get(profile, '_groups')
+            if (ldapGroups && _.isArray(ldapGroups)) {
+              const groups = ldapGroups.map(g => g[conf.groupNameField])
+              const currentGroups = (await user.$relatedQuery('groups').select('groups.id')).map(g => g.id)
+              const expectedGroups = Object.values(WIKI.auth.groups).filter(g => groups.includes(g.name)).map(g => g.id)
+              for (const groupId of _.difference(expectedGroups, currentGroups)) {
+                await user.$relatedQuery('groups').relate(groupId)
+              }
+              for (const groupId of _.difference(currentGroups, expectedGroups)) {
+                await user.$relatedQuery('groups').unrelate().where('groupId', groupId)
+              }
+            }
+          }
           cb(null, user)
         } catch (err) {
           if (WIKI.config.flags.ldapdebug) {
@@ -59,7 +81,7 @@ function getTlsOptions(conf) {
 
   if (!conf.tlsCertPath) {
     return {
-      rejectUnauthorized: conf.verifyTLSCertificate,
+      rejectUnauthorized: conf.verifyTLSCertificate
     }
   }
 
diff --git a/server/modules/authentication/ldap/definition.yml b/server/modules/authentication/ldap/definition.yml
index 8b0b1b2d05..193a9fc00f 100644
--- a/server/modules/authentication/ldap/definition.yml
+++ b/server/modules/authentication/ldap/definition.yml
@@ -83,3 +83,39 @@ props:
     hint: The field storing the user avatar picture. Usually "jpegPhoto" or "thumbnailPhoto".
     maxWidth: 500
     order: 23
+  mapGroups:
+    type: Boolean
+    title: Map Groups
+    hint: Map groups matching names from the users LDAP/Active Directory groups. Group Search Base must also be defined for this to work. Note this will remove any groups the user has that doesn't match an LDAP/Active Directory group.
+    default: false
+    order: 24
+  groupSearchBase:
+    type: String
+    title: Group Search Base
+    hint: The base DN from which to search for groups.
+    default: OU=groups,dc=example,dc=com
+    order: 25
+  groupSearchFilter:
+    type: String
+    title: Group Search Filter
+    hint: LDAP search filter for groups. (member={{dn}}) will use the distinguished name of the user and will work in most cases.
+    default: (member={{dn}})
+    order: 26
+  groupSearchScope:
+    type: String
+    title: Group Search Scope
+    hint: How far from the Group Search Base to search for groups. sub (default) will search the entire subtree. base, will only search the Group Search Base dn. one, will search the Group Search Base dn and one additional level.
+    default: sub
+    order: 27
+  groupDnProperty:
+    type: String
+    title: Group DN Property
+    hint: The property of user object to use in {{dn}} interpolation of Group Search Filter.
+    default: dn
+    order: 28
+  groupNameField:
+    type: String
+    title: Group Name Field
+    hint: The field that contains the name of the LDAP group to match on, usually "name" or "cn".
+    default: name
+    order: 29

From 2e8585478f40dda27ec1092e23656da695a94fb0 Mon Sep 17 00:00:00 2001
From: Eric Knibbe 
Date: Sun, 29 Jan 2023 23:09:33 -0500
Subject: [PATCH 085/164] fix(git): handle file renames between folders (#6020)

* git storage: handle file renames between folders

---------

Co-authored-by: Nicolas Giard 
---
 server/core/db.js                      |  2 +-
 server/models/pages.js                 |  3 ++-
 server/modules/storage/disk/storage.js |  2 +-
 server/modules/storage/git/storage.js  | 24 +++++++++++++++++++-----
 4 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/server/core/db.js b/server/core/db.js
index 2d614c55fd..25f21ad34c 100644
--- a/server/core/db.js
+++ b/server/core/db.js
@@ -138,7 +138,7 @@ module.exports = {
           switch (WIKI.config.db.type) {
             case 'postgres':
               await conn.query(`set application_name = 'Wiki.js'`)
-              // -> Set schema if it's not public             
+              // -> Set schema if it's not public
               if (WIKI.config.db.schema && WIKI.config.db.schema !== 'public') {
                 await conn.query(`set search_path TO ${WIKI.config.db.schema}, public;`)
               }
diff --git a/server/models/pages.js b/server/models/pages.js
index dc54af9a06..bb5b658512 100644
--- a/server/models/pages.js
+++ b/server/models/pages.js
@@ -725,7 +725,7 @@ module.exports = class Page extends Model {
     const destinationHash = pageHelper.generateHash({ path: opts.destinationPath, locale: opts.destinationLocale, privateNS: opts.isPrivate ? 'TODO' : '' })
 
     // -> Move page
-    const destinationTitle = (page.title === page.path ? opts.destinationPath : page.title)
+    const destinationTitle = (page.title === _.last(page.path.split('/')) ? _.last(opts.destinationPath.split('/')) : page.title)
     await WIKI.models.pages.query().patch({
       path: opts.destinationPath,
       localeCode: opts.destinationLocale,
@@ -745,6 +745,7 @@ module.exports = class Page extends Model {
       ...page,
       destinationPath: opts.destinationPath,
       destinationLocaleCode: opts.destinationLocale,
+      title: destinationTitle,
       destinationHash
     })
 
diff --git a/server/modules/storage/disk/storage.js b/server/modules/storage/disk/storage.js
index 1c3a7c40db..8e4e466162 100644
--- a/server/modules/storage/disk/storage.js
+++ b/server/modules/storage/disk/storage.js
@@ -135,7 +135,7 @@ module.exports = {
         transform: async (page, enc, cb) => {
           const pageObject = await WIKI.models.pages.query().findById(page.id)
           page.tags = await pageObject.$relatedQuery('tags')
-          
+
           let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}`
           if (WIKI.config.lang.code !== page.localeCode) {
             fileName = `${page.localeCode}/${fileName}`
diff --git a/server/modules/storage/git/storage.js b/server/modules/storage/git/storage.js
index 0995445abc..14b805ce91 100644
--- a/server/modules/storage/git/storage.js
+++ b/server/modules/storage/git/storage.js
@@ -146,10 +146,24 @@ module.exports = {
       const diff = await this.git.diffSummary(['-M', currentCommitLog.hash, latestCommitLog.hash])
       if (_.get(diff, 'files', []).length > 0) {
         let filesToProcess = []
+        const filePattern = /(.*?)(?:{(.*?))? => (?:(.*?)})?(.*)/
         for (const f of diff.files) {
-          const fMoved = f.file.split(' => ')
-          const fName = fMoved.length === 2 ? fMoved[1] : fMoved[0]
-          const fPath = path.join(this.repoPath, fName)
+          const fMatch = f.file.match(filePattern)
+          const fNames = {
+            old: null,
+            new: null
+          }
+          if (!fMatch) {
+            fNames.old = f.file
+            fNames.new = f.file
+          } else if (!fMatch[2] && !fMatch[3]) {
+            fNames.old = fMatch[1]
+            fNames.new = fMatch[4]
+          } else {
+            fNames.old = (fMatch[1]+fMatch[2]+fMatch[4]).replace('//', '/'),
+            fNames.new = (fMatch[1]+fMatch[3]+fMatch[4]).replace('//', '/')
+          }
+          const fPath = path.join(this.repoPath, fNames.new)
           let fStats = { size: 0 }
           try {
             fStats = await fs.stat(fPath)
@@ -166,8 +180,8 @@ module.exports = {
               path: fPath,
               stats: fStats
             },
-            oldPath: fMoved[0],
-            relPath: fName
+            oldPath: fNames.old,
+            relPath: fNames.new
           })
         }
         await this.processFiles(filesToProcess, rootUser)

From cc96b1fbcc72a1b0f7dd926cf95107dede1018a3 Mon Sep 17 00:00:00 2001
From: NGPixel 
Date: Sat, 4 Feb 2023 04:01:37 -0500
Subject: [PATCH 086/164] chore: update dependencies

---
 package.json |  60 +++---
 yarn.lock    | 596 ++++++++++++++++++++++++++++-----------------------
 2 files changed, 362 insertions(+), 294 deletions(-)

diff --git a/package.json b/package.json
index 32d4ecd64b..6717e922ff 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,6 @@
     "node": ">=10.12"
   },
   "dependencies": {
-    "asciidoctor": "2.2.6",
     "@azure/storage-blob": "12.12.0",
     "@exlinc/keycloak-passport": "1.0.2",
     "@joplin/turndown-plugin-gfm": "1.0.45",
@@ -49,8 +48,9 @@
     "apollo-fetch": "0.7.0",
     "apollo-server": "2.25.2",
     "apollo-server-express": "2.25.2",
+    "asciidoctor": "2.2.6",
     "auto-load": "3.0.4",
-    "aws-sdk": "2.1125.0",
+    "aws-sdk": "2.1309.0",
     "azure-search-client": "3.1.5",
     "bcryptjs-then": "1.0.1",
     "bluebird": "3.7.2",
@@ -59,7 +59,7 @@
     "cheerio": "1.0.0-rc.5",
     "chokidar": "3.5.3",
     "chromium-pickle-js": "0.2.0",
-    "clean-css": "4.2.3",
+    "clean-css": "5.3.2",
     "command-exists": "1.2.9",
     "compression": "1.7.4",
     "connect-session-knex": "2.0.0",
@@ -67,14 +67,14 @@
     "cors": "2.8.5",
     "cuint": "0.2.2",
     "custom-error-instance": "2.1.2",
-    "dependency-graph": "0.9.0",
+    "dependency-graph": "0.11.0",
     "diff": "4.0.2",
     "diff2html": "3.1.14",
-    "dompurify": "2.2.7",
+    "dompurify": "2.4.3",
     "dotize": "0.3.0",
     "elasticsearch6": "npm:@elastic/elasticsearch@6",
     "elasticsearch7": "npm:@elastic/elasticsearch@7",
-    "emoji-regex": "9.2.2",
+    "emoji-regex": "10.2.1",
     "eventemitter2": "6.4.9",
     "express": "4.18.2",
     "express-brute": "1.0.1",
@@ -94,11 +94,11 @@
     "i18next-express-middleware": "2.0.0",
     "i18next-node-fs-backend": "2.1.3",
     "image-size": "0.9.2",
-    "js-base64": "3.7.2",
+    "js-base64": "3.7.4",
     "js-binary": "1.2.0",
     "js-yaml": "3.14.0",
     "jsdom": "16.4.0",
-    "jsonwebtoken": "8.5.1",
+    "jsonwebtoken": "9.0.0",
     "katex": "0.12.0",
     "klaw": "3.0.0",
     "knex": "0.21.7",
@@ -119,19 +119,19 @@
     "markdown-it-sub": "1.0.0",
     "markdown-it-sup": "1.0.0",
     "markdown-it-task-lists": "2.1.1",
-    "mathjax": "3.1.2",
+    "mathjax": "3.2.2",
     "mime-types": "2.1.35",
     "moment": "2.29.4",
-    "moment-timezone": "0.5.38",
+    "moment-timezone": "0.5.40",
     "mongodb": "3.6.5",
     "ms": "2.1.3",
     "mssql": "6.2.3",
     "multer": "1.4.4",
-    "mysql2": "2.3.3",
+    "mysql2": "3.1.0",
     "nanoid": "3.2.0",
     "node-2fa": "1.1.2",
     "node-cache": "5.1.2",
-    "nodemailer": "6.8.0",
+    "nodemailer": "6.9.1",
     "objection": "2.2.18",
     "passport": "0.4.1",
     "passport-auth0": "1.4.3",
@@ -143,7 +143,7 @@
     "passport-github2": "0.1.12",
     "passport-gitlab2": "5.0.0",
     "passport-google-oauth20": "2.0.0",
-    "passport-jwt": "4.0.0",
+    "passport-jwt": "4.0.1",
     "passport-ldapauth": "3.0.1",
     "passport-local": "1.0.0",
     "passport-microsoft": "0.1.0",
@@ -154,16 +154,16 @@
     "passport-slack-oauth2": "1.1.1",
     "passport-twitch-strategy": "2.2.0",
     "pem-jwk": "2.0.0",
-    "pg": "8.8.0",
+    "pg": "8.9.0",
     "pg-hstore": "2.3.4",
     "pg-pubsub": "0.5.0",
-    "pg-query-stream": "3.3.1",
-    "pg-tsquery": "8.1.0",
+    "pg-query-stream": "4.3.0",
+    "pg-tsquery": "8.4.1",
     "pug": "3.0.2",
-    "punycode": "2.1.1",
+    "punycode": "2.3.0",
     "qr-image": "3.2.0",
     "raven": "2.6.4",
-    "remove-markdown": "0.3.0",
+    "remove-markdown": "0.5.0",
     "request": "2.88.2",
     "request-promise": "4.2.6",
     "safe-regex": "2.1.1",
@@ -171,22 +171,22 @@
     "scim-query-filter-parser": "2.0.4",
     "semver": "7.3.8",
     "serve-favicon": "2.5.0",
-    "simple-git": "2.21.0",
+    "simple-git": "3.16.0",
     "solr-node": "1.2.1",
-    "sqlite3": "5.0.6",
-    "ssh2": "1.5.0",
+    "sqlite3": "5.1.4",
+    "ssh2": "1.11.0",
     "ssh2-promise": "1.0.3",
     "striptags": "3.2.0",
     "subscriptions-transport-ws": "0.9.18",
     "tar-fs": "2.1.1",
     "turndown": "7.1.1",
-    "twemoji": "13.1.0",
+    "twemoji": "14.0.2",
     "uslug": "1.0.4",
-    "uuid": "8.3.2",
+    "uuid": "9.0.0",
     "validate.js": "0.13.1",
-    "winston": "3.3.3",
+    "winston": "3.8.2",
     "xss": "1.0.14",
-    "yargs": "16.1.0"
+    "yargs": "17.6.2"
   },
   "devDependencies": {
     "@babel/cli": "^7.12.1",
@@ -214,7 +214,7 @@
     "apollo-link-batch-http": "1.2.14",
     "apollo-link-error": "1.1.13",
     "apollo-link-http": "1.5.17",
-    "apollo-link-persisted-queries": "0.2.2",
+    "apollo-link-persisted-queries": "0.2.5",
     "apollo-link-ws": "1.0.20",
     "apollo-utilities": "1.3.4",
     "autoprefixer": "9.8.6",
@@ -227,7 +227,7 @@
     "babel-plugin-transform-imports": "2.0.0",
     "cache-loader": "4.1.0",
     "canvas-confetti": "1.3.1",
-    "cash-dom": "8.1.1",
+    "cash-dom": "8.1.3",
     "chart.js": "2.9.4",
     "clean-webpack-plugin": "3.0.0",
     "clipboard": "2.0.11",
@@ -252,7 +252,7 @@
     "eslint-plugin-vue": "7.1.0",
     "file-loader": "6.1.1",
     "filepond": "4.21.1",
-    "filepond-plugin-file-validate-type": "1.2.7",
+    "filepond-plugin-file-validate-type": "1.2.8",
     "filesize.js": "2.0.0",
     "graphql-persisted-document-loader": "2.0.0",
     "graphql-tag": "2.11.0",
@@ -279,7 +279,7 @@
     "postcss-import": "12.0.1",
     "postcss-loader": "3.0.0",
     "postcss-preset-env": "6.7.0",
-    "postcss-selector-parser": "6.0.10",
+    "postcss-selector-parser": "6.0.11",
     "prismjs": "1.22.0",
     "pug-lint": "2.6.0",
     "pug-loader": "2.4.0",
@@ -320,7 +320,7 @@
     "webpack-bundle-analyzer": "3.9.0",
     "webpack-cli": "3.3.12",
     "webpack-dev-middleware": "3.7.2",
-    "webpack-hot-middleware": "2.25.1",
+    "webpack-hot-middleware": "2.25.3",
     "webpack-merge": "5.2.0",
     "webpack-modernizr-loader": "5.0.0",
     "webpack-subresource-integrity": "1.5.1",
diff --git a/yarn.lock b/yarn.lock
index 92107b1cd6..19181d2bdd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2719,6 +2719,11 @@
     exec-sh "^0.3.2"
     minimist "^1.2.0"
 
+"@colors/colors@1.5.0":
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
+  integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
+
 "@csstools/convert-colors@^1.4.0":
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
@@ -4848,13 +4853,13 @@ apollo-link-http@1.5.17:
     apollo-link-http-common "^0.2.16"
     tslib "^1.9.3"
 
-apollo-link-persisted-queries@0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/apollo-link-persisted-queries/-/apollo-link-persisted-queries-0.2.2.tgz#156597cb259b7bb56cf4e967a7be0312954f4591"
-  integrity sha512-YL7XBu/5QsSbbYaWUXgm87T2Hn/2AQZk5Wr8CLXGDr3Wl3E/TRhBhKgQQTly9xhaTi7jgBO+AeIyTH5wCBHA9w==
+apollo-link-persisted-queries@0.2.5:
+  version "0.2.5"
+  resolved "https://registry.yarnpkg.com/apollo-link-persisted-queries/-/apollo-link-persisted-queries-0.2.5.tgz#76deabf68dac218d83f2fa23eebc3b25772fd914"
+  integrity sha512-PYWsMFcRGT9NZ6e6EK5rlhNDtcK6FR76JDy1RIngEfR6RdM5a2Z0IhZdn9RTTNB3V/+s7iWviQmoCfQrTVXu0A==
   dependencies:
     apollo-link "^1.2.1"
-    hash.js "^1.1.3"
+    hash.js "^1.1.7"
 
 apollo-link-ws@1.0.20:
   version "1.0.20"
@@ -5286,7 +5291,7 @@ async@>=0.6.0:
   resolved "https://registry.yarnpkg.com/async/-/async-3.1.0.tgz#42b3b12ae1b74927b5217d8c0016baaf62463772"
   integrity sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==
 
-async@^3.1.0, async@^3.2.0:
+async@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
   integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
@@ -5354,10 +5359,15 @@ autoprefixer@^9.6.1:
     postcss "^7.0.17"
     postcss-value-parser "^4.0.0"
 
-aws-sdk@2.1125.0:
-  version "2.1125.0"
-  resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1125.0.tgz#2a73f5bf1e5e8f8dbc873ef87cfe14925721ba2e"
-  integrity sha512-2syNkKDqDcDmB/chc61a5xx+KYzaarLs1/KshE0b1Opp2oSq2FARyUBbk59HgwKaDUB61uPF33ZG9sHiIVx2hQ==
+available-typed-arrays@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
+  integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
+
+aws-sdk@2.1309.0:
+  version "2.1309.0"
+  resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1309.0.tgz#2bc6e25af6da39a6c9c48080a43b35596a58a2c5"
+  integrity sha512-EC/EtDDWDoJnovvmNlJqvojNJMbFZ78HESzgFiond5vzPS+FIWnWgGJ1ZVvIWU9O4X5I8cEMckwHCTfVYNcZxA==
   dependencies:
     buffer "4.9.2"
     events "1.1.1"
@@ -5366,7 +5376,8 @@ aws-sdk@2.1125.0:
     querystring "0.2.0"
     sax "1.2.1"
     url "0.10.3"
-    uuid "3.3.2"
+    util "^0.12.4"
+    uuid "8.0.0"
     xml2js "0.4.19"
 
 aws-sign2@~0.7.0:
@@ -6189,7 +6200,7 @@ cachedir@^2.3.0:
   resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8"
   integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==
 
-call-bind@^1.0.0:
+call-bind@^1.0.0, call-bind@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
   integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
@@ -6294,10 +6305,10 @@ caseless@~0.12.0:
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
   integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
 
-cash-dom@8.1.1:
-  version "8.1.1"
-  resolved "https://registry.yarnpkg.com/cash-dom/-/cash-dom-8.1.1.tgz#37f6ba46fc470a1efad5215eefc2515271949c60"
-  integrity sha512-aMESow+8m7EuifAeNhpnRHQHN8O24gGeiR53lebD5ShBCisBCoB4y5BBe9pGXtTPP6b1qCp90W9HaaUARyc16Q==
+cash-dom@8.1.3:
+  version "8.1.3"
+  resolved "https://registry.yarnpkg.com/cash-dom/-/cash-dom-8.1.3.tgz#58920fd61d85235121682dac09c6b01f8671e550"
+  integrity sha512-+W6A9GrgH6do57T/2QLlobr8Q3nwvRoLf74HQRu8zFsyP8hBAjg0RJsubIP+uoV7MYknnugrEdEW5HHH0hJB7Q==
 
 chalk@2.3.x:
   version "2.3.2"
@@ -6552,7 +6563,14 @@ class-utils@^0.3.5:
     isobject "^3.0.0"
     static-extend "^0.1.1"
 
-clean-css@4.2.3, clean-css@^4.1.6, clean-css@^4.2.3:
+clean-css@5.3.2:
+  version "5.3.2"
+  resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224"
+  integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==
+  dependencies:
+    source-map "~0.6.0"
+
+clean-css@^4.1.6, clean-css@^4.2.3:
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
   integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==
@@ -6674,6 +6692,15 @@ cliui@^7.0.2:
     strip-ansi "^6.0.0"
     wrap-ansi "^7.0.0"
 
+cliui@^8.0.1:
+  version "8.0.1"
+  resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
+  integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
+  dependencies:
+    string-width "^4.2.0"
+    strip-ansi "^6.0.1"
+    wrap-ansi "^7.0.0"
+
 clone-deep@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
@@ -6835,11 +6862,6 @@ colors@^1.1.2:
   resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
   integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
 
-colors@^1.2.1:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
-  integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==
-
 colorspace@1.1.x:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5"
@@ -7197,13 +7219,6 @@ cosmiconfig@^5.0.0:
     js-yaml "^3.13.1"
     parse-json "^4.0.0"
 
-cpu-features@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.2.tgz#9f636156f1155fd04bdbaa028bb3c2fbef3cea7a"
-  integrity sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==
-  dependencies:
-    nan "^2.14.1"
-
 cpu-features@~0.0.4:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.4.tgz#0023475bb4f4c525869c162e4108099e35bf19d8"
@@ -8353,10 +8368,10 @@ denque@^1.4.1:
   resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf"
   integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==
 
-denque@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/denque/-/denque-2.0.1.tgz#bcef4c1b80dc32efe97515744f21a4229ab8934a"
-  integrity sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==
+denque@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1"
+  integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==
 
 depd@2.0.0, depd@^2.0.0, depd@~2.0.0:
   version "2.0.0"
@@ -8368,10 +8383,10 @@ depd@^1.1.2, depd@~1.1.1, depd@~1.1.2:
   resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
   integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
 
-dependency-graph@0.9.0:
-  version "0.9.0"
-  resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.9.0.tgz#11aed7e203bc8b00f48356d92db27b265c445318"
-  integrity sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==
+dependency-graph@0.11.0:
+  version "0.11.0"
+  resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27"
+  integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==
 
 deprecated-decorator@^0.1.6:
   version "0.1.6"
@@ -8565,10 +8580,10 @@ domino@^2.1.6:
   resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.6.tgz#fe4ace4310526e5e7b9d12c7de01b7f485a57ffe"
   integrity sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==
 
-dompurify@2.2.7:
-  version "2.2.7"
-  resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.7.tgz#a5f055a2a471638680e779bd08fc334962d11fd8"
-  integrity sha512-jdtDffdGNY+C76jvodNTu9jt5yYj59vuTUyx+wXdzcSwAGTYZDAQkQ7Iwx9zcGrA4ixC1syU4H3RZROqRxokxg==
+dompurify@2.4.3:
+  version "2.4.3"
+  resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.3.tgz#f4133af0e6a50297fc8874e2eaedc13a3c308c03"
+  integrity sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==
 
 domutils@1.5.1:
   version "1.5.1"
@@ -8754,10 +8769,10 @@ emittery@^0.7.1:
   resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.1.tgz#c02375a927a40948c0345cc903072597f5270451"
   integrity sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==
 
-emoji-regex@9.2.2:
-  version "9.2.2"
-  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
-  integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+emoji-regex@10.2.1:
+  version "10.2.1"
+  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.2.1.tgz#a41c330d957191efd3d9dfe6e1e8e1e9ab048b3f"
+  integrity sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==
 
 emoji-regex@^7.0.1:
   version "7.0.3"
@@ -9621,11 +9636,6 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4:
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
   integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
 
-fast-safe-stringify@^2.0.4:
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2"
-  integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==
-
 fast-safe-stringify@^2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
@@ -9741,10 +9751,10 @@ file@^0.2.2:
   resolved "https://registry.yarnpkg.com/file/-/file-0.2.2.tgz#c3dfd8f8cf3535ae455c2b423c2e52635d76b4d3"
   integrity sha1-w9/Y+M81Na5FXCtCPC5SY112tNM=
 
-filepond-plugin-file-validate-type@1.2.7:
-  version "1.2.7"
-  resolved "https://registry.yarnpkg.com/filepond-plugin-file-validate-type/-/filepond-plugin-file-validate-type-1.2.7.tgz#34bd2585cc51a3e13d9fc46c0be9c3caec59e13d"
-  integrity sha512-HMOoS7BrpMt3YLWMylqshV7V0fJyTLZlibF4Y/Q7XFFFkzHKR+KSFiCRGZqXbFWw6hgtcl5wBC9kVwMB9AOPTg==
+filepond-plugin-file-validate-type@1.2.8:
+  version "1.2.8"
+  resolved "https://registry.yarnpkg.com/filepond-plugin-file-validate-type/-/filepond-plugin-file-validate-type-1.2.8.tgz#58ab1815a3f505f2189e6943263ae3b6cb314bd1"
+  integrity sha512-UBTqIWbk5+5R0GBELI8svu01MHWjFSLfc9DfCMvFtHKXLdJMxY1p37ChC4YKQjhfODaTuvLnNVRsukMGMFZBBg==
 
 filepond@4.21.1:
   version "4.21.1"
@@ -9946,6 +9956,13 @@ follow-redirects@^1.14.9:
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
   integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
 
+for-each@^0.3.3:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
+  integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
+  dependencies:
+    is-callable "^1.1.3"
+
 for-in@^1.0.1, for-in@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -10214,6 +10231,15 @@ get-intrinsic@^1.0.2:
     has "^1.0.3"
     has-symbols "^1.0.1"
 
+get-intrinsic@^1.1.3:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f"
+  integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==
+  dependencies:
+    function-bind "^1.1.1"
+    has "^1.0.3"
+    has-symbols "^1.0.3"
+
 get-stream@^4.0.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
@@ -10420,6 +10446,13 @@ good-listener@^1.2.2:
   dependencies:
     delegate "^3.1.2"
 
+gopd@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
+  integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+  dependencies:
+    get-intrinsic "^1.1.3"
+
 graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0:
   version "4.2.2"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
@@ -10611,6 +10644,18 @@ has-symbols@^1.0.1:
   resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
   integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
 
+has-symbols@^1.0.2, has-symbols@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
+  integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+
+has-tostringtag@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
+  integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==
+  dependencies:
+    has-symbols "^1.0.2"
+
 has-unicode@^2.0.0, has-unicode@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -10667,7 +10712,7 @@ hash-sum@^1.0.2:
   resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04"
   integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=
 
-hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.3:
+hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7:
   version "1.1.7"
   resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
   integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
@@ -11268,6 +11313,14 @@ is-accessor-descriptor@^1.0.0:
   dependencies:
     kind-of "^6.0.0"
 
+is-arguments@^1.0.4:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
+  integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
+  dependencies:
+    call-bind "^1.0.2"
+    has-tostringtag "^1.0.0"
+
 is-arrayish@^0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@@ -11302,6 +11355,11 @@ is-buffer@^2.0.2:
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
   integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
 
+is-callable@^1.1.3:
+  version "1.2.7"
+  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
+  integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
+
 is-callable@^1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
@@ -11445,6 +11503,13 @@ is-generator-fn@^2.0.0:
   resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
   integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
 
+is-generator-function@^1.0.7:
+  version "1.0.10"
+  resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
+  integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
+  dependencies:
+    has-tostringtag "^1.0.0"
+
 is-glob@4.0.1, is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
@@ -11621,6 +11686,17 @@ is-symbol@^1.0.2:
   dependencies:
     has-symbols "^1.0.0"
 
+is-typed-array@^1.1.10, is-typed-array@^1.1.3:
+  version "1.1.10"
+  resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f"
+  integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==
+  dependencies:
+    available-typed-arrays "^1.0.5"
+    call-bind "^1.0.2"
+    for-each "^0.3.3"
+    gopd "^1.0.1"
+    has-tostringtag "^1.0.0"
+
 is-typedarray@^1.0.0, is-typedarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@@ -12143,10 +12219,10 @@ jmespath@0.16.0:
   resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076"
   integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==
 
-js-base64@3.7.2:
-  version "3.7.2"
-  resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.2.tgz#816d11d81a8aff241603d19ce5761e13e41d7745"
-  integrity sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==
+js-base64@3.7.4:
+  version "3.7.4"
+  resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.4.tgz#af95b20f23efc8034afd2d1cc5b9d0adf7419037"
+  integrity sha512-wpM/wi20Tl+3ifTyi0RdDckS4YTD4Lf953mBRrpG8547T7hInHNPEj8+ck4gB8VDcGyeAWFK++Wb/fU1BeavKQ==
 
 js-beautify@1.13.5:
   version "1.13.5"
@@ -12335,21 +12411,15 @@ jsonfile@^6.0.1:
   optionalDependencies:
     graceful-fs "^4.1.6"
 
-jsonwebtoken@8.5.1, jsonwebtoken@^8.2.0:
-  version "8.5.1"
-  resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
-  integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
+jsonwebtoken@9.0.0, jsonwebtoken@^9.0.0:
+  version "9.0.0"
+  resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz#d0faf9ba1cc3a56255fe49c0961a67e520c1926d"
+  integrity sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==
   dependencies:
     jws "^3.2.2"
-    lodash.includes "^4.3.0"
-    lodash.isboolean "^3.0.3"
-    lodash.isinteger "^4.0.4"
-    lodash.isnumber "^3.0.3"
-    lodash.isplainobject "^4.0.6"
-    lodash.isstring "^4.0.1"
-    lodash.once "^4.0.0"
+    lodash "^4.17.21"
     ms "^2.1.1"
-    semver "^5.6.0"
+    semver "^7.3.8"
 
 jsprim@^1.2.2:
   version "1.4.1"
@@ -12595,9 +12665,9 @@ linkify-it@^2.0.0:
     uc.micro "^1.0.1"
 
 linkify-it@^3.0.1:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8"
-  integrity sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ==
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e"
+  integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==
   dependencies:
     uc.micro "^1.0.1"
 
@@ -12746,36 +12816,6 @@ lodash.clonedeep@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
   integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
 
-lodash.includes@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
-  integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
-
-lodash.isboolean@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
-  integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
-
-lodash.isinteger@^4.0.4:
-  version "4.0.4"
-  resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
-  integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
-
-lodash.isnumber@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
-  integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
-
-lodash.isplainobject@^4.0.6:
-  version "4.0.6"
-  resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
-  integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
-
-lodash.isstring@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
-  integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
-
 lodash.kebabcase@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
@@ -12786,7 +12826,7 @@ lodash.memoize@^4.1.2:
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
   integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
 
-lodash.once@^4.0.0, lodash.once@^4.1.1:
+lodash.once@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
   integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
@@ -12826,7 +12866,7 @@ lodash@4.17.20, lodash@^4.17.20:
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
   integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
 
-lodash@4.17.21:
+lodash@4.17.21, lodash@^4.17.21:
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -12864,15 +12904,15 @@ log-update@2.3.x, log-update@^2.3.0:
     cli-cursor "^2.0.0"
     wrap-ansi "^3.0.1"
 
-logform@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2"
-  integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==
+logform@^2.3.2, logform@^2.4.0:
+  version "2.4.2"
+  resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.2.tgz#a617983ac0334d0c3b942c34945380062795b47c"
+  integrity sha512-W4c9himeAwXEdZ05dQNerhFz2XG80P9Oj0loPUMV23VC2it0orMHQhJm4hdnnor3rd1HsGf6a2lPwBM1zeXHGw==
   dependencies:
-    colors "^1.2.1"
-    fast-safe-stringify "^2.0.4"
+    "@colors/colors" "1.5.0"
     fecha "^4.2.0"
     ms "^2.1.1"
+    safe-stable-stringify "^2.3.1"
     triple-beam "^1.3.0"
 
 loglevel@^1.6.7:
@@ -12890,6 +12930,11 @@ long@^4.0.0:
   resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
   integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
 
+long@^5.2.1:
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f"
+  integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==
+
 loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -12916,7 +12961,7 @@ lru-cache@6.0.0, lru-cache@^6.0.0:
   dependencies:
     yallist "^4.0.0"
 
-lru-cache@^4.1.2, lru-cache@^4.1.3, lru-cache@^4.1.5:
+lru-cache@^4.1.2, lru-cache@^4.1.5:
   version "4.1.5"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
   integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
@@ -12931,6 +12976,11 @@ lru-cache@^5.1.1:
   dependencies:
     yallist "^3.0.2"
 
+lru-cache@^7.14.1:
+  version "7.14.1"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.14.1.tgz#8da8d2f5f59827edb388e63e459ac23d6d408fea"
+  integrity sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==
+
 luxon@1.25.0:
   version "1.25.0"
   resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.25.0.tgz#d86219e90bc0102c0eb299d65b2f5e95efe1fe72"
@@ -13024,7 +13074,7 @@ markdown-it-decorate@1.2.2:
 markdown-it-emoji@1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz#9bee0e9a990a963ba96df6980c4fddb05dfb4dcc"
-  integrity sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=
+  integrity sha512-QCz3Hkd+r5gDYtS2xsFXmBYrgw6KuWcJZLCEkdfAuwzZbShCmCfta+hwAMq4NX/4xPzkSHduMKgMkkPUJxSXNg==
 
 markdown-it-expand-tabs@1.0.13:
   version "1.0.13"
@@ -13080,7 +13130,7 @@ markdown-it-task-lists@2.1.1:
   resolved "https://registry.yarnpkg.com/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz#f68f4d2ac2bad5a2c373ba93081a1a6848417088"
   integrity sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==
 
-markdown-it@11.0.1:
+markdown-it@11.0.1, markdown-it@^11.0.0:
   version "11.0.1"
   resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-11.0.1.tgz#b54f15ec2a2193efa66dda1eb4173baea08993d6"
   integrity sha512-aU1TzmBKcWNNYvH9pjq6u92BML+Hz3h5S/QpfTFwiQF852pLT+9qHsrhM9JYipkOXZxGn+sGH8oyJE9FD9WezQ==
@@ -13102,26 +13152,15 @@ markdown-it@^10.0.0:
     mdurl "^1.0.1"
     uc.micro "^1.0.5"
 
-markdown-it@^11.0.0:
-  version "11.0.0"
-  resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-11.0.0.tgz#dbfc30363e43d756ebc52c38586b91b90046b876"
-  integrity sha512-+CvOnmbSubmQFSA9dKz1BRiaSMV7rhexl3sngKqFyXSagoA3fBdJQ8oZWtRy2knXdpDXaBw44euz37DeJQ9asg==
-  dependencies:
-    argparse "^1.0.7"
-    entities "~2.0.0"
-    linkify-it "^3.0.1"
-    mdurl "^1.0.1"
-    uc.micro "^1.0.5"
-
 math-expression-evaluator@^1.2.14:
   version "1.2.17"
   resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
   integrity sha1-3oGf282E3M2PrlnGrreWFbnSZqw=
 
-mathjax@3.1.2:
-  version "3.1.2"
-  resolved "https://registry.yarnpkg.com/mathjax/-/mathjax-3.1.2.tgz#95c0d45ce2330ef7b6a815cebe7d61ecc26bbabd"
-  integrity sha512-BojKspBv4nNWzO1wC6VEI+g9gHDOhkaGHGgLxXkasdU4pwjdO5AXD5M/wcLPkXYPjZ/N+6sU8rjQTlyvN2cWiQ==
+mathjax@3.2.2:
+  version "3.2.2"
+  resolved "https://registry.yarnpkg.com/mathjax/-/mathjax-3.2.2.tgz#c754d7b46a679d7f3fa03543d6b8bf124ddf9f6b"
+  integrity sha512-Bt+SSVU8eBG27zChVewOicYs7Xsdt40qm4+UpHyX7k0/O9NliPc+x77k1/FEsPsjKPZGJvtRZM1vO+geW0OhGw==
 
 md5.js@^1.3.4:
   version "1.3.5"
@@ -13563,10 +13602,10 @@ moment-timezone-data-webpack-plugin@1.3.0:
     find-cache-dir "^3.0.0"
     make-dir "^3.0.0"
 
-moment-timezone@0.5.38:
-  version "0.5.38"
-  resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.38.tgz#9674a5397b8be7c13de820fd387d8afa0f725aad"
-  integrity sha512-nMIrzGah4+oYZPflDvLZUgoVUO4fvAqHstvG3xAUnMolWncuAiLDWNnJZj6EwJGMGfb1ZcuTFE6GI3hNOVWI/Q==
+moment-timezone@0.5.40:
+  version "0.5.40"
+  resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.40.tgz#c148f5149fd91dd3e29bf481abc8830ecba16b89"
+  integrity sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==
   dependencies:
     moment ">= 2.9.0"
 
@@ -13662,33 +13701,33 @@ mv@~2:
     ncp "~2.0.0"
     rimraf "~2.4.0"
 
-mysql2@2.3.3:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-2.3.3.tgz#944f3deca4b16629052ff8614fbf89d5552545a0"
-  integrity sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==
+mysql2@3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.1.0.tgz#7d7b6c9e368bd5f74a82ce150edc32401a05d756"
+  integrity sha512-woMeIog21X72RcFLhE/xajhUdnwRMd6Oq16S7/O2qJ5lPUDfFwgSW+xhx7TjzcM8PU3q+dVsryIaDi+HyQR/0A==
   dependencies:
-    denque "^2.0.1"
+    denque "^2.1.0"
     generate-function "^2.3.1"
     iconv-lite "^0.6.3"
-    long "^4.0.0"
-    lru-cache "^6.0.0"
-    named-placeholders "^1.1.2"
+    long "^5.2.1"
+    lru-cache "^7.14.1"
+    named-placeholders "^1.1.3"
     seq-queue "^0.0.5"
     sqlstring "^2.3.2"
 
-named-placeholders@^1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.2.tgz#ceb1fbff50b6b33492b5cf214ccf5e39cef3d0e8"
-  integrity sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==
+named-placeholders@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.3.tgz#df595799a36654da55dda6152ba7a137ad1d9351"
+  integrity sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==
   dependencies:
-    lru-cache "^4.1.3"
+    lru-cache "^7.14.1"
 
 nan@^2.12.1, nan@^2.14.0:
   version "2.14.0"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
   integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
 
-nan@^2.14.1, nan@^2.15.0:
+nan@^2.15.0:
   version "2.15.0"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
   integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
@@ -13980,10 +14019,10 @@ node-uuid@1.4.1:
   resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.1.tgz#39aef510e5889a3dca9c895b506c73aae1bac048"
   integrity sha1-Oa71EOWImj3KnIlbUGxzquG6wEg=
 
-nodemailer@6.8.0:
-  version "6.8.0"
-  resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.8.0.tgz#804bcc5256ee5523bc914506ee59f8de8f0b1cd5"
-  integrity sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==
+nodemailer@6.9.1:
+  version "6.9.1"
+  resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.1.tgz#8249d928a43ed85fec17b13d2870c8f758a126ed"
+  integrity sha512-qHw7dOiU5UKNnQpXktdgQ1d3OFgRAekuvbJLcdG5dnEo/GtcTHRYM7+UfJARdOFU9WUQO8OiIamgWPmiSFHYAA==
 
 nopt@1.0.10:
   version "1.0.10"
@@ -14715,12 +14754,12 @@ passport-google-oauth20@2.0.0:
   dependencies:
     passport-oauth2 "1.x.x"
 
-passport-jwt@4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065"
-  integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==
+passport-jwt@4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.1.tgz#c443795eff322c38d173faa0a3c481479646ec3d"
+  integrity sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ==
   dependencies:
-    jsonwebtoken "^8.2.0"
+    jsonwebtoken "^9.0.0"
     passport-strategy "^1.0.0"
 
 passport-ldapauth@3.0.1:
@@ -15020,10 +15059,10 @@ pg-connection-string@^2.5.0:
   resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34"
   integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==
 
-pg-cursor@^2.4.1:
-  version "2.4.1"
-  resolved "https://registry.yarnpkg.com/pg-cursor/-/pg-cursor-2.4.1.tgz#4bedd74817c27e078c381550a5b392dcdb86ea83"
-  integrity sha512-3ffxaoFFTedeBx72pKg/BwuSH26UelvUhlibIO/zxMYkroNIXt1uFOYLRvatozpi79GMpPe+kHVeIfcCIK7/Sg==
+pg-cursor@^2.8.0:
+  version "2.8.0"
+  resolved "https://registry.yarnpkg.com/pg-cursor/-/pg-cursor-2.8.0.tgz#7cb0929ad33ea68fe15d25b0de34acd611e189d5"
+  integrity sha512-LrOaEHK+R1C40e+xeri3FTRY/VKp9uTOCVsKtGB7LJ57qbeaphYvWjbVly8AesdT1GfHXYcAnVdExKhW7DKOvA==
 
 pg-format@^1.0.2:
   version "1.0.4"
@@ -15057,10 +15096,10 @@ pg-pool@^3.5.2:
   resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.5.2.tgz#ed1bed1fb8d79f1c6fd5fb1c99e990fbf9ddf178"
   integrity sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==
 
-pg-protocol@^1.5.0:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0"
-  integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==
+pg-protocol@^1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833"
+  integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==
 
 pg-pubsub@0.5.0:
   version "0.5.0"
@@ -15073,17 +15112,17 @@ pg-pubsub@0.5.0:
     promised-retry "^0.3.0"
     verror "^1.10.0"
 
-pg-query-stream@3.3.1:
-  version "3.3.1"
-  resolved "https://registry.yarnpkg.com/pg-query-stream/-/pg-query-stream-3.3.1.tgz#b5d4e5134ca651493a2d9a6a849b7cfb25d30b15"
-  integrity sha512-T8gWhDqBevDz8IYguxYQ5eZZ7p50BJXeoXo/uGLyH0fpXS6v0GnvoX/Pavb8A/t/iF0SQNd59/eIJgt+FV6aoA==
+pg-query-stream@4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/pg-query-stream/-/pg-query-stream-4.3.0.tgz#93deb1732b655d328496abe191ca33fdc1e144e6"
+  integrity sha512-+Eer4Y1e43rAaphFNu9/VJKn9nKTApFKCSwVtDjXYnuO4QYqWHOEkApmGJv8gvaU5T6fcuEtjsN24gk+Rx7X9A==
   dependencies:
-    pg-cursor "^2.4.1"
+    pg-cursor "^2.8.0"
 
-pg-tsquery@8.1.0:
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/pg-tsquery/-/pg-tsquery-8.1.0.tgz#de30d5f3d6721adbf9c0dc33f4e79d8fcb9071a8"
-  integrity sha512-CXTK0HNFA9H1nk12HKHBWaER+c9yhNq/En8u0FtQTjM/KQ6llyCnEAios6TZ+fz8QI2w0qJ8y3HE3Uc/pHXrFg==
+pg-tsquery@8.4.1:
+  version "8.4.1"
+  resolved "https://registry.yarnpkg.com/pg-tsquery/-/pg-tsquery-8.4.1.tgz#7346aefd90983f321c59382e1468f192b1b10894"
+  integrity sha512-GoeRhw6o4Bpt7awdUwHq6ITOw40IWSrb5IC2qR6dF9ZECtHFGdSpnjHOl9Rumd8Rx12kLI2T9TGV0gvxD5pFgA==
 
 pg-types@^2.1.0:
   version "2.2.0"
@@ -15096,16 +15135,16 @@ pg-types@^2.1.0:
     postgres-date "~1.0.4"
     postgres-interval "^1.1.0"
 
-pg@8.8.0:
-  version "8.8.0"
-  resolved "https://registry.yarnpkg.com/pg/-/pg-8.8.0.tgz#a77f41f9d9ede7009abfca54667c775a240da686"
-  integrity sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==
+pg@8.9.0:
+  version "8.9.0"
+  resolved "https://registry.yarnpkg.com/pg/-/pg-8.9.0.tgz#73c5d77a854d36b0e185450dacb8b90c669e040b"
+  integrity sha512-ZJM+qkEbtOHRuXjmvBtOgNOXOtLSbxiMiUVMgE4rV6Zwocy03RicCVvDXgx8l4Biwo8/qORUnEqn2fdQzV7KCg==
   dependencies:
     buffer-writer "2.0.0"
     packet-reader "1.0.0"
     pg-connection-string "^2.5.0"
     pg-pool "^3.5.2"
-    pg-protocol "^1.5.0"
+    pg-protocol "^1.6.0"
     pg-types "^2.1.0"
     pgpass "1.x"
 
@@ -16057,10 +16096,10 @@ postcss-selector-not@^4.0.0:
     balanced-match "^1.0.0"
     postcss "^7.0.2"
 
-postcss-selector-parser@6.0.10:
-  version "6.0.10"
-  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
-  integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
+postcss-selector-parser@6.0.11:
+  version "6.0.11"
+  resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc"
+  integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==
   dependencies:
     cssesc "^3.0.0"
     util-deprecate "^1.0.2"
@@ -16624,16 +16663,21 @@ punycode@1.3.2:
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
   integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
 
-punycode@2.1.1, punycode@^2.1.0, punycode@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
-  integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+punycode@2.3.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
+  integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
 
 punycode@^1.2.4, punycode@^1.4.1:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
   integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
 
+punycode@^2.1.0, punycode@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
+  integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+
 q@^1.1.2:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -16691,7 +16735,7 @@ querystring-es3@^0.2.0:
   resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
   integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
 
-querystring@0.2.0, querystring@^0.2.0:
+querystring@0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
   integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
@@ -16880,7 +16924,7 @@ readable-stream@1.1.x:
     isarray "0.0.1"
     string_decoder "~0.10.x"
 
-readable-stream@^2.0.0, readable-stream@^2.3.7:
+readable-stream@^2.0.0:
   version "2.3.7"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
   integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -17159,10 +17203,10 @@ relay-runtime@10.0.1:
     "@babel/runtime" "^7.0.0"
     fbjs "^1.0.0"
 
-remove-markdown@0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/remove-markdown/-/remove-markdown-0.3.0.tgz#5e4b667493a93579728f3d52ecc1db9ca505dc98"
-  integrity sha1-XktmdJOpNXlyjz1S7MHbnKUF3Jg=
+remove-markdown@0.5.0:
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/remove-markdown/-/remove-markdown-0.5.0.tgz#a596264bbd60b9ceab2e2ae86e5789eee91aee32"
+  integrity sha512-x917M80K97K5IN1L8lUvFehsfhR8cYjGQ/yAMRI9E7JIKivtl5Emo5iD13DhMr+VojzMCiYk8V2byNPwT/oapg==
 
 remove-trailing-separator@^1.0.1:
   version "1.1.0"
@@ -17575,6 +17619,11 @@ safe-regex@^1.1.0:
   dependencies:
     ret "~0.1.10"
 
+safe-stable-stringify@^2.3.1:
+  version "2.4.2"
+  resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz#ec7b037768098bf65310d1d64370de0dc02353aa"
+  integrity sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==
+
 "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
   version "2.1.2"
   resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -17750,7 +17799,7 @@ semver@7.0.0:
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
   integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
 
-semver@7.3.8:
+semver@7.3.8, semver@^7.3.8:
   version "7.3.8"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
   integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
@@ -17975,14 +18024,14 @@ signedsource@^1.0.0:
   resolved "https://registry.yarnpkg.com/signedsource/-/signedsource-1.0.0.tgz#1ddace4981798f93bd833973803d80d52e93ad6a"
   integrity sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo=
 
-simple-git@2.21.0:
-  version "2.21.0"
-  resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.21.0.tgz#d25d3fdc6a139cd7f80f197541a6f9f6e9d4cbc8"
-  integrity sha512-rohCHmEjD/ESXFLxF4bVeqgdb4Awc65ZyyuCKl3f7BvgMbZOBa/Ye3HN/GFnvruiUOAWWNupxhz3Rz5/3vJLTg==
+simple-git@3.16.0:
+  version "3.16.0"
+  resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.16.0.tgz#421773e24680f5716999cc4a1d60127b4b6a9dec"
+  integrity sha512-zuWYsOLEhbJRWVxpjdiXl6eyAyGo/KzVW+KFhhw9MqEEJttcq+32jTWSGyxTdf9e/YCohxRE+9xpWFj9FdiJNw==
   dependencies:
     "@kwsites/file-exists" "^1.1.1"
     "@kwsites/promise-deferred" "^1.1.1"
-    debug "^4.1.1"
+    debug "^4.3.4"
 
 simple-progress-webpack-plugin@1.1.2:
   version "1.1.2"
@@ -18216,10 +18265,10 @@ sprintf-js@~1.0.2:
   resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
   integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
 
-sqlite3@5.0.6:
-  version "5.0.6"
-  resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.6.tgz#1b50a36e528fe650f79da9ed7adde6468d597aa9"
-  integrity sha512-uT1dC6N3ReF+jchY01zvl1wVFFJ5xO86wSnCpK39uA/zmAHBDm6TiAq1v876QKv8JgiijxQ7/fb5C2LPm7ZAJA==
+sqlite3@5.1.4:
+  version "5.1.4"
+  resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.1.4.tgz#35f83d368963168b324ad2f0fffce09f3b8723a7"
+  integrity sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==
   dependencies:
     "@mapbox/node-pre-gyp" "^1.0.0"
     node-addon-api "^4.2.0"
@@ -18240,18 +18289,7 @@ ssh2-promise@1.0.3:
     "@heroku/socksv5" "^0.0.9"
     ssh2 "^1.10.0"
 
-ssh2@1.5.0:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.5.0.tgz#4dc559ba98a1cbb420e8d42998dfe35d0eda92bc"
-  integrity sha512-iUmRkhH9KGeszQwDW7YyyqjsMTf4z+0o48Cp4xOwlY5LjtbIAvyd3fwnsoUZW/hXmTCRA3yt7S/Jb9uVjErVlA==
-  dependencies:
-    asn1 "^0.2.4"
-    bcrypt-pbkdf "^1.0.2"
-  optionalDependencies:
-    cpu-features "0.0.2"
-    nan "^2.15.0"
-
-ssh2@^1.10.0:
+ssh2@1.11.0, ssh2@^1.10.0:
   version "1.11.0"
   resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.11.0.tgz#ce60186216971e12f6deb553dcf82322498fe2e4"
   integrity sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==
@@ -19136,7 +19174,7 @@ trim-right@^1.0.1:
   resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
   integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
 
-triple-beam@^1.2.0, triple-beam@^1.3.0:
+triple-beam@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
   integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
@@ -19229,19 +19267,19 @@ twemoji-awesome@1.0.6:
   resolved "https://registry.yarnpkg.com/twemoji-awesome/-/twemoji-awesome-1.0.6.tgz#3167c3abb95753da997291f8f1c53cbac61852a5"
   integrity sha1-MWfDq7lXU9qZcpH48cU8usYYUqU=
 
-twemoji-parser@13.1.0:
-  version "13.1.0"
-  resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-13.1.0.tgz#65e7e449c59258791b22ac0b37077349127e3ea4"
-  integrity sha512-AQOzLJpYlpWMy8n+0ATyKKZzWlZBJN+G0C+5lhX7Ftc2PeEVdUU/7ns2Pn2vVje26AIZ/OHwFoUbdv6YYD/wGg==
+twemoji-parser@14.0.0:
+  version "14.0.0"
+  resolved "https://registry.yarnpkg.com/twemoji-parser/-/twemoji-parser-14.0.0.tgz#13dabcb6d3a261d9efbf58a1666b182033bf2b62"
+  integrity sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==
 
-twemoji@13.1.0:
-  version "13.1.0"
-  resolved "https://registry.yarnpkg.com/twemoji/-/twemoji-13.1.0.tgz#65bb71e966dae56f0d42c30176f04cbdae109913"
-  integrity sha512-e3fZRl2S9UQQdBFLYXtTBT6o4vidJMnpWUAhJA+yLGR+kaUTZAt3PixC0cGvvxWSuq2MSz/o0rJraOXrWw/4Ew==
+twemoji@14.0.2:
+  version "14.0.2"
+  resolved "https://registry.yarnpkg.com/twemoji/-/twemoji-14.0.2.tgz#c53adb01dab22bf4870f648ca8cc347ce99ee37e"
+  integrity sha512-BzOoXIe1QVdmsUmZ54xbEH+8AgtOKUiG53zO5vVP2iUu6h5u9lN15NcuS6te4OY96qx0H7JK9vjjl9WQbkTRuA==
   dependencies:
     fs-extra "^8.0.1"
     jsonfile "^5.0.0"
-    twemoji-parser "13.1.0"
+    twemoji-parser "14.0.0"
     universalify "^0.1.2"
 
 type-check@^0.4.0, type-check@~0.4.0:
@@ -19576,6 +19614,17 @@ util@^0.11.0:
   dependencies:
     inherits "2.0.3"
 
+util@^0.12.4:
+  version "0.12.5"
+  resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc"
+  integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==
+  dependencies:
+    inherits "^2.0.3"
+    is-arguments "^1.0.4"
+    is-generator-function "^1.0.7"
+    is-typed-array "^1.1.3"
+    which-typed-array "^1.1.2"
+
 utila@^0.4.0, utila@~0.4:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
@@ -19591,10 +19640,15 @@ uuid@3.3.2:
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
   integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
 
-uuid@8.3.2:
-  version "8.3.2"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
-  integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+uuid@8.0.0:
+  version "8.0.0"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c"
+  integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==
+
+uuid@9.0.0:
+  version "9.0.0"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
+  integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
 
 uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2:
   version "3.3.3"
@@ -19996,14 +20050,13 @@ webpack-dev-middleware@3.7.2:
     range-parser "^1.2.1"
     webpack-log "^2.0.0"
 
-webpack-hot-middleware@2.25.1:
-  version "2.25.1"
-  resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.1.tgz#581f59edf0781743f4ca4c200fd32c9266c6cf7c"
-  integrity sha512-Koh0KyU/RPYwel/khxbsDz9ibDivmUbrRuKSSQvW42KSDdO4w23WI3SkHpSUKHE76LrFnnM/L7JCrpBwu8AXYw==
+webpack-hot-middleware@2.25.3:
+  version "2.25.3"
+  resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz#be343ce2848022cfd854dd82820cd730998c6794"
+  integrity sha512-IK/0WAHs7MTu1tzLTjio73LjS3Ov+VvBKQmE8WPlJutgG5zT6Urgq/BbAdRrHTRpyzK0dvAvFh1Qg98akxgZpA==
   dependencies:
     ansi-html-community "0.0.8"
     html-entities "^2.1.0"
-    querystring "^0.2.0"
     strip-ansi "^6.0.0"
 
 webpack-log@^2.0.0:
@@ -20159,6 +20212,18 @@ which-module@^2.0.0:
   resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
   integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
 
+which-typed-array@^1.1.2:
+  version "1.1.9"
+  resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6"
+  integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==
+  dependencies:
+    available-typed-arrays "^1.0.5"
+    call-bind "^1.0.2"
+    for-each "^0.3.3"
+    gopd "^1.0.1"
+    has-tostringtag "^1.0.0"
+    is-typed-array "^1.1.10"
+
 which@^1.2.14, which@^1.2.9, which@^1.3.1:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
@@ -20192,28 +20257,31 @@ wildcard@^2.0.0:
   resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec"
   integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
 
-winston-transport@^4.4.0:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59"
-  integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==
+winston-transport@^4.5.0:
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa"
+  integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==
   dependencies:
-    readable-stream "^2.3.7"
-    triple-beam "^1.2.0"
+    logform "^2.3.2"
+    readable-stream "^3.6.0"
+    triple-beam "^1.3.0"
 
-winston@3.3.3:
-  version "3.3.3"
-  resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170"
-  integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==
+winston@3.8.2:
+  version "3.8.2"
+  resolved "https://registry.yarnpkg.com/winston/-/winston-3.8.2.tgz#56e16b34022eb4cff2638196d9646d7430fdad50"
+  integrity sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==
   dependencies:
+    "@colors/colors" "1.5.0"
     "@dabh/diagnostics" "^2.0.2"
-    async "^3.1.0"
+    async "^3.2.3"
     is-stream "^2.0.0"
-    logform "^2.2.0"
+    logform "^2.4.0"
     one-time "^1.0.0"
     readable-stream "^3.4.0"
+    safe-stable-stringify "^2.3.1"
     stack-trace "0.0.x"
     triple-beam "^1.3.0"
-    winston-transport "^4.4.0"
+    winston-transport "^4.5.0"
 
 with@^7.0.0:
   version "7.0.2"
@@ -20493,11 +20561,6 @@ y18n@^4.0.0:
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
   integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
 
-y18n@^5.0.2:
-  version "5.0.5"
-  resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
-  integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
-
 y18n@^5.0.5:
   version "5.0.8"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
@@ -20552,6 +20615,11 @@ yargs-parser@^20.2.2:
   resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.3.tgz#92419ba867b858c868acf8bae9bf74af0dd0ce26"
   integrity sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==
 
+yargs-parser@^21.1.1:
+  version "21.1.1"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
+  integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
+
 yargs-parser@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
@@ -20559,31 +20627,31 @@ yargs-parser@^5.0.0:
   dependencies:
     camelcase "^3.0.0"
 
-yargs@16.1.0:
-  version "16.1.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.1.0.tgz#fc333fe4791660eace5a894b39d42f851cd48f2a"
-  integrity sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==
+yargs@16.2.0:
+  version "16.2.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
+  integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
   dependencies:
     cliui "^7.0.2"
     escalade "^3.1.1"
     get-caller-file "^2.0.5"
     require-directory "^2.1.1"
     string-width "^4.2.0"
-    y18n "^5.0.2"
+    y18n "^5.0.5"
     yargs-parser "^20.2.2"
 
-yargs@16.2.0:
-  version "16.2.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
-  integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+yargs@17.6.2:
+  version "17.6.2"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541"
+  integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==
   dependencies:
-    cliui "^7.0.2"
+    cliui "^8.0.1"
     escalade "^3.1.1"
     get-caller-file "^2.0.5"
     require-directory "^2.1.1"
-    string-width "^4.2.0"
+    string-width "^4.2.3"
     y18n "^5.0.5"
-    yargs-parser "^20.2.2"
+    yargs-parser "^21.1.1"
 
 yargs@^13.3.2:
   version "13.3.2"

From 30b66b1623c13b9ae6c0fde285cd8f7a7c57f59b Mon Sep 17 00:00:00 2001
From: Nicolas Giard 
Date: Sat, 4 Feb 2023 12:05:17 -0500
Subject: [PATCH 087/164] ci: disable provenance in docker build action

---
 .github/workflows/build.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 304f20e45d..f1499fa524 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -60,6 +60,7 @@ jobs:
         context: .
         file: dev/build/Dockerfile
         push: true
+        provenance: false
         tags: |
           requarks/wiki:canary
           requarks/wiki:canary-${{ env.REL_VERSION_STRICT }}
@@ -178,6 +179,7 @@ jobs:
         file: dev/build-arm/Dockerfile
         platforms: ${{ matrix.platform }}
         push: true
+        provenance: false
         tags: |
           requarks/wiki:canary-${{ matrix.docker }}-${{ env.REL_VERSION_STRICT }}
           ghcr.io/requarks/wiki:canary-${{ matrix.docker }}-${{ env.REL_VERSION_STRICT }}

From 30576149d387df243dff5233feea4ca4d5af1c70 Mon Sep 17 00:00:00 2001
From: Nicolas Giard 
Date: Sat, 4 Feb 2023 12:29:25 -0500
Subject: [PATCH 088/164] ci: update build workflow actions

---
 .github/workflows/build.yml | 44 ++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f1499fa524..069d241b21 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -19,7 +19,7 @@ jobs:
       packages: write
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
 
     - name: Set Build Variables
       run: |
@@ -42,20 +42,20 @@ jobs:
         cat package.json
 
     - name: Login to DockerHub
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         username: ${{ secrets.DOCKERHUB_USERNAME }}
         password: ${{ secrets.DOCKERHUB_TOKEN }}
 
     - name: Login to GitHub Container Registry
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         registry: ghcr.io
         username: ${{ github.repository_owner }}
         password: ${{ secrets.GITHUB_TOKEN }}
 
     - name: Build and push Docker images
-      uses: docker/build-push-action@v2.9.0
+      uses: docker/build-push-action@v4.0.0
       with:
         context: .
         file: dev/build/Dockerfile
@@ -78,7 +78,7 @@ jobs:
         find _dist/wiki/ -printf "%P\n" | tar -czf wiki-js.tar.gz --no-recursion -C _dist/wiki/ -T -
 
     - name: Upload a Build Artifact
-      uses: actions/upload-artifact@v2.3.1
+      uses: actions/upload-artifact@v3.1.2
       with:
         name: drop
         path: wiki-js.tar.gz
@@ -93,7 +93,7 @@ jobs:
         dbtype: [postgres, mysql, mariadb, mssql, sqlite]
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
 
     - name: Set Test Variables
       run: |
@@ -130,7 +130,7 @@ jobs:
             docker: armv7
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
 
     - name: Set Version Variables
       run: |
@@ -143,19 +143,19 @@ jobs:
         fi
 
     - name: Set up QEMU
-      uses: docker/setup-qemu-action@v1
+      uses: docker/setup-qemu-action@v2.1.0
 
     - name: Set up Docker Buildx
-      uses: docker/setup-buildx-action@v1
+      uses: docker/setup-buildx-action@v2.4.0
 
     - name: Login to DockerHub
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         username: ${{ secrets.DOCKERHUB_USERNAME }}
         password: ${{ secrets.DOCKERHUB_TOKEN }}
 
     - name: Login to GitHub Container Registry
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         registry: ghcr.io
         username: ${{ github.repository_owner }}
@@ -173,7 +173,7 @@ jobs:
         tar -xzf $GITHUB_WORKSPACE/drop/wiki-js.tar.gz -C $GITHUB_WORKSPACE/build --exclude=node_modules
 
     - name: Build and push Docker images
-      uses: docker/build-push-action@v2.9.0
+      uses: docker/build-push-action@v4.0.0
       with:
         context: .
         file: dev/build-arm/Dockerfile
@@ -191,12 +191,12 @@ jobs:
 
     steps:
     - name: Setup Node.js environment
-      uses: actions/setup-node@v2.5.1
+      uses: actions/setup-node@v3.6.0
       with:
         node-version: 16.x
 
     - name: Download a Build Artifact
-      uses: actions/download-artifact@v2.1.0
+      uses: actions/download-artifact@v3.0.2
       with:
         name: drop
         path: drop
@@ -214,7 +214,7 @@ jobs:
       run: tar -czf wiki-js-windows.tar.gz -C $env:GITHUB_WORKSPACE\win .
 
     - name: Upload a Build Artifact
-      uses: actions/upload-artifact@v2.3.1
+      uses: actions/upload-artifact@v3.1.2
       with:
         name: drop-win
         path: wiki-js-windows.tar.gz
@@ -234,13 +234,13 @@ jobs:
         echo "REL_VERSION_STRICT=${GITHUB_REF_NAME#?}" >> $GITHUB_ENV
 
     - name: Login to DockerHub
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         username: ${{ secrets.DOCKERHUB_USERNAME }}
         password: ${{ secrets.DOCKERHUB_TOKEN }}
 
     - name: Login to GitHub Container Registry
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         registry: ghcr.io
         username: ${{ github.repository_owner }}
@@ -275,13 +275,13 @@ jobs:
         echo "REL_VERSION_STRICT=${GITHUB_REF_NAME#?}" >> $GITHUB_ENV
 
     - name: Login to DockerHub
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         username: ${{ secrets.DOCKERHUB_USERNAME }}
         password: ${{ secrets.DOCKERHUB_TOKEN }}
 
     - name: Login to GitHub Container Registry
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2.1.0
       with:
         registry: ghcr.io
         username: ${{ github.repository_owner }}
@@ -321,13 +321,13 @@ jobs:
         docker manifest push -p ghcr.io/requarks/wiki:latest
 
     - name: Download Linux Build
-      uses: actions/download-artifact@v2.1.0
+      uses: actions/download-artifact@v3.0.2
       with:
         name: drop
         path: drop
 
     - name: Download Windows Build
-      uses: actions/download-artifact@v2.1.0
+      uses: actions/download-artifact@v3.0.2
       with:
         name: drop-win
         path: drop-win
@@ -384,7 +384,7 @@ jobs:
     needs: [release]
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
 
     - name: Set Version Variables
       run: |

From 9b99ebb187dd059ed6e9b88e5f56d84f612a4606 Mon Sep 17 00:00:00 2001
From: Nicolas Giard 
Date: Sat, 4 Feb 2023 12:37:38 -0500
Subject: [PATCH 089/164] ci: disable provenance in build workflow

---
 .github/workflows/build.yml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 069d241b21..9aa1d32e86 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -60,7 +60,6 @@ jobs:
         context: .
         file: dev/build/Dockerfile
         push: true
-        provenance: false
         tags: |
           requarks/wiki:canary
           requarks/wiki:canary-${{ env.REL_VERSION_STRICT }}
@@ -179,7 +178,6 @@ jobs:
         file: dev/build-arm/Dockerfile
         platforms: ${{ matrix.platform }}
         push: true
-        provenance: false
         tags: |
           requarks/wiki:canary-${{ matrix.docker }}-${{ env.REL_VERSION_STRICT }}
           ghcr.io/requarks/wiki:canary-${{ matrix.docker }}-${{ env.REL_VERSION_STRICT }}
@@ -341,10 +339,11 @@ jobs:
         writeToFile: false
 
     - name: Update GitHub Release
-      uses: ncipollo/release-action@v1
+      uses: ncipollo/release-action@v1.12.0
       with:
         allowUpdates: true
         draft: false
+        makeLatest: true
         name: ${{ github.ref_name }}
         body: ${{ steps.changelog.outputs.changes }}
         token: ${{ github.token }}

From 2e3bdb6630ae095bacf27d228374a944cde1bdb3 Mon Sep 17 00:00:00 2001
From: Nicolas Giard 
Date: Sat, 4 Feb 2023 15:21:10 -0500
Subject: [PATCH 090/164] ci: fix build arm64 action

---
 .github/workflows/build.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9aa1d32e86..0ab452e1e8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -161,7 +161,7 @@ jobs:
         password: ${{ secrets.GITHUB_TOKEN }}
 
     - name: Download a Build Artifact
-      uses: actions/download-artifact@v2.1.0
+      uses: actions/download-artifact@v3.0.2
       with:
         name: drop
         path: drop
@@ -177,6 +177,7 @@ jobs:
         context: .
         file: dev/build-arm/Dockerfile
         platforms: ${{ matrix.platform }}
+        provenance: false
         push: true
         tags: |
           requarks/wiki:canary-${{ matrix.docker }}-${{ env.REL_VERSION_STRICT }}

From ac930fc23e8192d9405306056e05957bb3b76e26 Mon Sep 17 00:00:00 2001
From: NGPixel 
Date: Sat, 4 Feb 2023 16:09:41 -0500
Subject: [PATCH 091/164] fix: change simple-git import

---
 server/modules/storage/git/storage.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/server/modules/storage/git/storage.js b/server/modules/storage/git/storage.js
index 14b805ce91..59194b4101 100644
--- a/server/modules/storage/git/storage.js
+++ b/server/modules/storage/git/storage.js
@@ -1,5 +1,5 @@
 const path = require('path')
-const sgit = require('simple-git/promise')
+const sgit = require('simple-git')
 const fs = require('fs-extra')
 const _ = require('lodash')
 const stream = require('stream')
@@ -160,8 +160,8 @@ module.exports = {
             fNames.old = fMatch[1]
             fNames.new = fMatch[4]
           } else {
-            fNames.old = (fMatch[1]+fMatch[2]+fMatch[4]).replace('//', '/'),
-            fNames.new = (fMatch[1]+fMatch[3]+fMatch[4]).replace('//', '/')
+            fNames.old = (fMatch[1] + fMatch[2] + fMatch[4]).replace('//', '/'),
+            fNames.new = (fMatch[1] + fMatch[3] + fMatch[4]).replace('//', '/')
           }
           const fPath = path.join(this.repoPath, fNames.new)
           let fStats = { size: 0 }

From bba1d1b57418ce5c528d3985f0f4c62df1b20b5a Mon Sep 17 00:00:00 2001
From: gueldi <45048474+gueldenstone@users.noreply.github.com>
Date: Wed, 8 Feb 2023 04:00:26 +0100
Subject: [PATCH 092/164] fix(oidc): use _json prop when setting displayName
 (#6135)

* Fixes setting displayName from OIDC

Relates to: https://github.com/requarks/wiki/pull/6096

* Update authentication.js

---------

Co-authored-by: Nicolas Giard 
---
 server/modules/authentication/oidc/authentication.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/modules/authentication/oidc/authentication.js b/server/modules/authentication/oidc/authentication.js
index 22a3f2c53d..11b7aac996 100644
--- a/server/modules/authentication/oidc/authentication.js
+++ b/server/modules/authentication/oidc/authentication.js
@@ -29,7 +29,7 @@ module.exports = {
             profile: {
               ...profile,
               email: _.get(profile, '_json.' + conf.emailClaim),
-              displayName: _.get(profile, conf.displayNameClaim, ''),
+              displayName: _.get(profile, '_json.' + conf.displayNameClaim, '')
             }
           })
           if (conf.mapGroups) {

From 26dcc007e77d7a90701650423501fa8cff951269 Mon Sep 17 00:00:00 2001
From: Leangseu Kim 
Date: Tue, 7 Feb 2023 22:02:12 -0500
Subject: [PATCH 093/164] fix: sort visualize tree (#6110)

Co-authored-by: k k 
---
 client/components/admin/admin-pages-visualize.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/components/admin/admin-pages-visualize.vue b/client/components/admin/admin-pages-visualize.vue
index 116b38a970..3c9b20eb65 100644
--- a/client/components/admin/admin-pages-visualize.vue
+++ b/client/components/admin/admin-pages-visualize.vue
@@ -104,7 +104,7 @@ export default {
         const truncatePath = path => _.take(path.split('/'), depth).join('/')
         const descendantsByChild =
           Object.entries(_.groupBy(descendants, page => truncatePath(page.path)))
-            .map(([childPath, descendantsGroup]) => [getPage(childPath), descendantsGroup])
+            .map(([childPath, descendantsGroup]) => [getPage(childPath), _.sortBy(descendantsGroup, child => child.path)])
             .map(([child, descendantsGroup]) =>
               [child, _.filter(descendantsGroup, d => d.path !== child.path)])
         return {

From 78a35c377c216ea6031a9aef9a0a2ca4c35d8dea Mon Sep 17 00:00:00 2001
From: Dan Nicholson 
Date: Thu, 16 Feb 2023 17:04:19 -0700
Subject: [PATCH 094/164] feat: include query parameters in locale redirect
 (#6132)

* feat: include query parameters in locale redirect

* refactor: code cleanup

---------

Co-authored-by: Nicolas Giard 
---
 server/controllers/common.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/server/controllers/common.js b/server/controllers/common.js
index 3bcfcd940f..55cc4d333f 100644
--- a/server/controllers/common.js
+++ b/server/controllers/common.js
@@ -4,6 +4,7 @@ const pageHelper = require('../helpers/page')
 const _ = require('lodash')
 const CleanCSS = require('clean-css')
 const moment = require('moment')
+const qs = require('querystring')
 
 /* global WIKI */
 
@@ -420,7 +421,8 @@ router.get('/*', async (req, res, next) => {
 
   if (isPage) {
     if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) {
-      return res.redirect(`/${pageArgs.locale}/${pageArgs.path}`)
+      const query = !_.isEmpty(req.query) ? `?${qs.stringify(req.query)}` : ''
+      return res.redirect(`/${pageArgs.locale}/${pageArgs.path}${query}`)
     }
 
     req.i18n.changeLanguage(pageArgs.locale)

From f972a9c7dee934d1c1ed35986424d162bedd6211 Mon Sep 17 00:00:00 2001
From: Nyxtorm 
Date: Fri, 17 Feb 2023 01:10:19 +0100
Subject: [PATCH 095/164] fix: code block styling in blockquotes (#6108)

---
 client/themes/default/scss/app.scss | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/client/themes/default/scss/app.scss b/client/themes/default/scss/app.scss
index 5e7f0a958c..72866a0110 100644
--- a/client/themes/default/scss/app.scss
+++ b/client/themes/default/scss/app.scss
@@ -282,7 +282,7 @@
         content: "\F02FC";
       }
 
-      code {
+      code:not([class^="language-"]) {
         background-color: mc('blue', '50');
         color: mc('blue', '800');
       }
@@ -302,7 +302,7 @@
         content: "\F0026";
       }
 
-      code {
+      code:not([class^="language-"]) {
         background-color: mc('orange', '50');
         color: mc('orange', '800');
       }
@@ -323,7 +323,7 @@
         content: "\F0159";
       }
 
-      code {
+      code:not([class^="language-"]) {
         background-color: mc('red', '50');
         color: mc('red', '800');
       }
@@ -343,7 +343,7 @@
         content: "\F0E1E";
       }
 
-      code {
+      code:not([class^="language-"]) {
         background-color: mc('green', '50');
         color: mc('green', '800');
       }

From e954b50a7ac9669bc515493ce621b23a7bd93e54 Mon Sep 17 00:00:00 2001
From: NGPixel 
Date: Thu, 16 Feb 2023 20:45:55 -0500
Subject: [PATCH 096/164] feat: footer text override option

---
 client/components/admin/admin-general.vue       | 15 +++++++++++++++
 client/store/site.js                            |  1 +
 client/themes/default/components/nav-footer.vue |  5 ++++-
 server/app/data.yml                             |  1 +
 server/graph/resolvers/site.js                  |  7 ++++++-
 server/graph/schemas/site.graphql               |  2 ++
 server/master.js                                |  1 +
 server/modules/storage/git/storage.js           |  2 +-
 8 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/client/components/admin/admin-general.vue b/client/components/admin/admin-general.vue
index 8804ee3922..3ac524a85a 100644
--- a/client/components/admin/admin-general.vue
+++ b/client/components/admin/admin-general.vue
@@ -82,6 +82,14 @@
                       :return-object='false'
                       :hint='$t(`admin:general.contentLicenseHint`)'
                       persistent-hint
+                    )
+                    v-text-field.mt-3(
+                      outlined
+                      :label='$t(`admin:general.footerOverride`)'
+                      v-model='config.footerOverride'
+                      prepend-icon='mdi-page-layout-footer'
+                      persistent-hint
+                      :hint='$t(`admin:general.footerOverrideHint`)'
                       )
                   v-divider
                   .overline.grey--text.pa-4 SEO
@@ -280,6 +288,7 @@ export default {
         analyticsId: '',
         company: '',
         contentLicense: '',
+        footerOverride: '',
         logoUrl: '',
         featureAnalytics: false,
         featurePageRatings: false,
@@ -308,6 +317,7 @@ export default {
     logoUrl: sync('site/logoUrl'),
     company: sync('site/company'),
     contentLicense: sync('site/contentLicense'),
+    footerOverride: sync('site/footerOverride'),
     activeModal: sync('editor/activeModal'),
     contentLicenses () {
       return [
@@ -346,6 +356,7 @@ export default {
               $analyticsId: String
               $company: String
               $contentLicense: String
+              $footerOverride: String
               $logoUrl: String
               $pageExtensions: String
               $featurePageRatings: Boolean
@@ -369,6 +380,7 @@ export default {
                   analyticsId: $analyticsId
                   company: $company
                   contentLicense: $contentLicense
+                  footerOverride: $footerOverride
                   logoUrl: $logoUrl
                   pageExtensions: $pageExtensions
                   featurePageRatings: $featurePageRatings
@@ -401,6 +413,7 @@ export default {
             analyticsId: _.get(this.config, 'analyticsId', ''),
             company: _.get(this.config, 'company', ''),
             contentLicense: _.get(this.config, 'contentLicense', ''),
+            footerOverride: _.get(this.config, 'footerOverride', ''),
             logoUrl: _.get(this.config, 'logoUrl', ''),
             pageExtensions: _.get(this.config, 'pageExtensions', ''),
             featurePageRatings: _.get(this.config, 'featurePageRatings', false),
@@ -426,6 +439,7 @@ export default {
         this.siteTitle = this.config.title
         this.company = this.config.company
         this.contentLicense = this.config.contentLicense
+        this.footerOverride = this.config.footerOverride
         this.logoUrl = this.config.logoUrl
       } catch (err) {
         this.$store.commit('pushGraphError', err)
@@ -461,6 +475,7 @@ export default {
               analyticsId
               company
               contentLicense
+              footerOverride
               logoUrl
               pageExtensions
               featurePageRatings
diff --git a/client/store/site.js b/client/store/site.js
index 979468c7e6..0e3369de9c 100644
--- a/client/store/site.js
+++ b/client/store/site.js
@@ -5,6 +5,7 @@ import { make } from 'vuex-pathify'
 const state = {
   company: siteConfig.company,
   contentLicense: siteConfig.contentLicense,
+  footerOverride: siteConfig.footerOverride,
   dark: siteConfig.darkMode,
   tocPosition: siteConfig.tocPosition,
   mascot: true,
diff --git a/client/themes/default/components/nav-footer.vue b/client/themes/default/components/nav-footer.vue
index 08e44fcd9c..a43428d6b1 100644
--- a/client/themes/default/components/nav-footer.vue
+++ b/client/themes/default/components/nav-footer.vue
@@ -1,7 +1,9 @@