Просмотр исходного кода

Merge branch 'master' into feat/g2g-nextjs

Haku Mizuki 3 лет назад
Родитель
Сommit
6b1e48b94f
27 измененных файлов с 133 добавлено и 737 удалено
  1. 1 0
      .github/workflows/release.yml
  2. 8 0
      packages/app/docker/codebuild/main.tf
  3. 0 663
      packages/app/docker/codebuild/terraform.tfstate
  4. 1 1
      packages/app/package.json
  5. 6 8
      packages/app/src/components/Admin/MarkdownSetting/WhiteListInput.jsx
  6. 1 4
      packages/app/src/components/Admin/MarkdownSetting/XssForm.jsx
  7. 4 5
      packages/app/src/pages/[[...path]].page.tsx
  8. 3 2
      packages/app/src/pages/_private-legacy-pages.page.tsx
  9. 3 2
      packages/app/src/pages/_search.page.tsx
  10. 3 2
      packages/app/src/pages/me/[[...path]].page.tsx
  11. 5 3
      packages/app/src/pages/share/[[...path]].page.tsx
  12. 3 2
      packages/app/src/pages/tags.page.tsx
  13. 3 2
      packages/app/src/pages/trash.page.tsx
  14. 1 1
      packages/app/src/pages/utils/commons.ts
  15. 2 1
      packages/app/src/server/routes/apiv3/index.js
  16. 12 1
      packages/app/src/server/routes/login-passport.js
  17. 27 3
      packages/app/src/services/renderer/renderer.tsx
  18. 9 2
      packages/app/src/services/xss/xssOption.ts
  19. 16 6
      packages/app/src/styles/theme/_apply-colors-dark.scss
  20. 2 2
      packages/app/src/styles/theme/_apply-colors-light.scss
  21. 10 8
      packages/app/src/styles/theme/_apply-colors.scss
  22. 0 6
      packages/app/src/styles/theme/_hsl-reboot-bootstrap-theme-colors.scss
  23. 1 1
      packages/core/src/models/vo/error-apiv3.ts
  24. 2 1
      packages/preset-themes/package.json
  25. 3 6
      packages/preset-themes/src/styles/future.scss
  26. 0 5
      packages/preset-themes/src/styles/halloween.scss
  27. 7 0
      packages/preset-themes/vite.themes.config.ts

+ 1 - 0
.github/workflows/release.yml

@@ -177,6 +177,7 @@ jobs:
     needs: [determine-tags, build-image]
 
     uses: weseek/growi/.github/workflows/reusable-app-create-manifests.yml@master
+    with:
       tags: ${{ needs.determine-tags.outputs.TAGS }}
       registry: docker.io
       image-name: weseek/growi

+ 8 - 0
packages/app/docker/codebuild/main.tf

@@ -1,4 +1,12 @@
 terraform {
+  backend "remote" {
+    organization = "weseek"
+
+    workspaces {
+      name = "growi-official-image-builder"
+    }
+  }
+
   required_providers {
     aws = {
       source  = "hashicorp/aws"

Разница между файлами не показана из-за своего большого размера
+ 0 - 663
packages/app/docker/codebuild/terraform.tfstate


+ 1 - 1
packages/app/package.json

@@ -46,7 +46,7 @@
     "openapi:v3": "yarn cross-env API_VERSION=3 yarn swagger-jsdoc -- \"src/server/routes/apiv3/**/*.js\" \"src/server/models/**/*.js\"",
     "openapi:v1": "yarn cross-env API_VERSION=1 yarn swagger-jsdoc -- \"src/server/*/*.js\" \"src/server/models/**/*.js\"",
     "resources:hackmd": "yarn lerna run build --scope=@growi/hackmd",
-    "resources:preset-themes": "yarn lerna run build --scope=@growi/preset-themes",
+    "resources:preset-themes": "yarn lerna run dev:nowatch --scope=@growi/preset-themes",
     "// resources:dl-resources": "yarn ts-node bin/download-cdn-resources.ts",
     "ts-node": "node -r ts-node/register -r tsconfig-paths/register -r dotenv-flow/config"
   },

+ 6 - 8
packages/app/src/components/Admin/MarkdownSetting/WhiteListInput.jsx

@@ -24,13 +24,13 @@ class WhiteListInput extends React.Component {
   }
 
   onClickRecommendTagButton() {
-    // this.tagWhiteList.current.value = this.tags;
-    // this.props.adminMarkDownContainer.setState({ tagWhiteList: this.tags });
+    this.tagWhiteList.current.value = this.tags;
+    this.props.adminMarkDownContainer.setState({ tagWhiteList: this.tags });
   }
 
   onClickRecommendAttrButton() {
-    // this.attrWhiteList.current.value = this.attrs;
-    // this.props.adminMarkDownContainer.setState({ attrWhiteList: this.attrs });
+    this.attrWhiteList.current.value = this.attrs;
+    this.props.adminMarkDownContainer.setState({ attrWhiteList: this.attrs });
   }
 
   render() {
@@ -41,12 +41,11 @@ class WhiteListInput extends React.Component {
         <div className="mt-4">
           <div className="d-flex justify-content-between">
             {t('markdown_settings.xss_options.tag_names')}
-            <p id="btn-import-tags" className="btn btn-sm btn-primary mb-0 disabled" onClick={this.onClickRecommendTagButton}>
+            <p id="btn-import-tags" className="btn btn-sm btn-primary mb-0" onClick={this.onClickRecommendTagButton}>
               {t('markdown_settings.xss_options.import_recommended', { target: 'Tags' })}
             </p>
           </div>
           <textarea
-            disabled
             className="form-control xss-list"
             name="recommendedTags"
             rows="6"
@@ -59,12 +58,11 @@ class WhiteListInput extends React.Component {
         <div className="mt-4">
           <div className="d-flex justify-content-between">
             {t('markdown_settings.xss_options.tag_attributes')}
-            <p id="btn-import-tags" className="btn btn-sm btn-primary mb-0 disabled" onClick={this.onClickRecommendAttrButton}>
+            <p id="btn-import-tags" className="btn btn-sm btn-primary mb-0" onClick={this.onClickRecommendAttrButton}>
               {t('markdown_settings.xss_options.import_recommended', { target: 'Attrs' })}
             </p>
           </div>
           <textarea
-            disabled
             className="form-control xss-list"
             name="recommendedAttrs"
             rows="6"

+ 1 - 4
packages/app/src/components/Admin/MarkdownSetting/XssForm.jsx

@@ -93,7 +93,6 @@ class XssForm extends React.Component {
           <div className="col-md-6 col-sm-12 align-self-start mb-4">
             <div className="custom-control custom-radio">
               <input
-                disabled
                 type="radio"
                 className="custom-control-input"
                 id="xssOption2"
@@ -102,9 +101,7 @@ class XssForm extends React.Component {
                 onChange={() => { adminMarkDownContainer.setState({ xssOption: RehypeSanitizeOption.CUSTOM }) }}
               />
               <label className="custom-control-label w-100" htmlFor="xssOption2">
-                <p className="font-weight-bold">{t('markdown_settings.xss_options.custom_whitelist')}
-                  <span className='text-warning'> (TBD: Currently unavailable)</span>
-                </p>
+                <p className="font-weight-bold">{t('markdown_settings.xss_options.custom_whitelist')}</p>
                 <WhiteListInput customizable />
               </label>
             </div>

+ 4 - 5
packages/app/src/pages/[[...path]].page.tsx

@@ -604,12 +604,11 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
     blockdiagUri: process.env.BLOCKDIAG_URI ?? null,
 
     // XSS Options
-    attrWhiteList: crowi.xssService.getAttrWhiteList(),
-    tagWhiteList: crowi.xssService.getTagWhiteList(),
-    highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
-
-    // XSS: rehype-sanitize options
     isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
+    attrWhiteList: JSON.parse(crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes')),
+    tagWhiteList: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
+    highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
   };
 
   props.sidebarConfig = {

+ 3 - 2
packages/app/src/pages/_private-legacy-pages.page.tsx

@@ -136,8 +136,9 @@ async function injectServerConfigurations(context: GetServerSidePropsContext, pr
 
     // XSS Options
     isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    attrWhiteList: crowi.xssService.getAttrWhiteList(),
-    tagWhiteList: crowi.xssService.getTagWhiteList(),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
+    attrWhiteList: JSON.parse(crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes')),
+    tagWhiteList: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
     highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
   };
 }

+ 3 - 2
packages/app/src/pages/_search.page.tsx

@@ -158,8 +158,9 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
 
     // XSS Options
     isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    attrWhiteList: crowi.xssService.getAttrWhiteList(),
-    tagWhiteList: crowi.xssService.getTagWhiteList(),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
+    attrWhiteList: JSON.parse(crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes')),
+    tagWhiteList: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
     highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
   };
 

+ 3 - 2
packages/app/src/pages/me/[[...path]].page.tsx

@@ -186,8 +186,9 @@ async function injectServerConfigurations(context: GetServerSidePropsContext, pr
 
     // XSS Options
     isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    attrWhiteList: crowi.xssService.getAttrWhiteList(),
-    tagWhiteList: crowi.xssService.getTagWhiteList(),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
+    attrWhiteList: JSON.parse(crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes')),
+    tagWhiteList: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
     highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
   };
 }

+ 5 - 3
packages/app/src/pages/share/[[...path]].page.tsx

@@ -22,7 +22,7 @@ import { RendererConfig } from '~/interfaces/services/renderer';
 import { IShareLinkHasId } from '~/interfaces/share-link';
 import type { PageDocument } from '~/server/models/page';
 import {
-  useCurrentUser, useCurrentPageId, useRendererConfig, useIsSearchPage,
+  useCurrentUser, useCurrentPageId, useRendererConfig, useIsSearchPage, useCurrentPathname,
   useShareLinkId, useIsSearchServiceConfigured, useIsSearchServiceReachable, useIsSearchScopeChildrenAsDefault, useDrawioUri, useIsContainerFluid,
 } from '~/stores/context';
 import loggerFactory from '~/utils/logger';
@@ -86,6 +86,7 @@ const GrowiContextualSubNavigationForSharedPage = (props: GrowiContextualSubNavi
 };
 
 const SharedPage: NextPageWithLayout<Props> = (props: Props) => {
+  useCurrentPathname(props.shareLink?.relatedPage.path);
   useIsSearchPage(false);
   useShareLinkId(props.shareLink?._id);
   useCurrentPageId(props.shareLink?.relatedPage._id);
@@ -208,8 +209,9 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
 
     // XSS Options
     isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    attrWhiteList: xssService.getAttrWhiteList(),
-    tagWhiteList: xssService.getTagWhiteList(),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
+    attrWhiteList: JSON.parse(crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes')),
+    tagWhiteList: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
     highlightJsStyleBorder: configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
   };
 }

+ 3 - 2
packages/app/src/pages/tags.page.tsx

@@ -165,8 +165,9 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
 
     // XSS Options
     isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    attrWhiteList: crowi.xssService.getAttrWhiteList(),
-    tagWhiteList: crowi.xssService.getTagWhiteList(),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
+    attrWhiteList: JSON.parse(crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes')),
+    tagWhiteList: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
     highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
   };
 }

+ 3 - 2
packages/app/src/pages/trash.page.tsx

@@ -160,8 +160,9 @@ function injectServerConfigurations(context: GetServerSidePropsContext, props: P
 
     // XSS Options
     isEnabledXssPrevention: configManager.getConfig('markdown', 'markdown:rehypeSanitize:isEnabledPrevention'),
-    attrWhiteList: crowi.xssService.getAttrWhiteList(),
-    tagWhiteList: crowi.xssService.getTagWhiteList(),
+    xssOption: configManager.getConfig('markdown', 'markdown:rehypeSanitize:option'),
+    attrWhiteList: JSON.parse(crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:attributes')),
+    tagWhiteList: crowi.configManager.getConfig('markdown', 'markdown:rehypeSanitize:tagNames'),
     highlightJsStyleBorder: crowi.configManager.getConfig('crowi', 'customize:highlightJsStyleBorder'),
   };
 }

+ 1 - 1
packages/app/src/pages/utils/commons.ts

@@ -36,7 +36,7 @@ export const getServerSideCommonProps: GetServerSideProps<CommonProps> = async(c
   } = crowi;
 
   const url = new URL(context.resolvedUrl, 'http://example.com');
-  const currentPathname = decodeURI(url.pathname);
+  const currentPathname = decodeURIComponent(url.pathname);
 
   const isMaintenanceMode = appService.isMaintenanceMode();
 

+ 2 - 1
packages/app/src/server/routes/apiv3/index.js

@@ -51,7 +51,8 @@ module.exports = (crowi, app) => {
   const loginPassport = require('../login-passport')(crowi, app);
 
   routerForAuth.post('/login', applicationInstalled, loginFormValidator.loginRules(), loginFormValidator.loginValidation,
-    addActivity, loginPassport.loginWithLocal, loginPassport.loginWithLdap, loginPassport.cannotLoginErrorHadnler, loginPassport.loginFailure);
+    addActivity, loginPassport.isEnableLoginWithLocalOrLdap, loginPassport.loginWithLocal, loginPassport.loginWithLdap,
+    loginPassport.cannotLoginErrorHadnler, loginPassport.loginFailure);
 
   routerForAuth.use('/invited', require('./invited')(crowi));
   routerForAuth.use('/logout', require('./logout')(crowi));

+ 12 - 1
packages/app/src/server/routes/login-passport.js

@@ -133,6 +133,16 @@ module.exports = function(crowi, app) {
     return res.apiv3({ redirectTo, userStatus: req.user.status });
   };
 
+  const isEnableLoginWithLocalOrLdap = (req, res, next) => {
+    if (!passportService.isLocalStrategySetup && !passportService.isLdapStrategySetup) {
+      logger.error('LocalStrategy and LdapStrategy has not been set up');
+      const error = new ErrorV3('message.strategy_has_not_been_set_up', '', undefined, { strategy: 'LocalStrategy and LdapStrategy' });
+      return next(error);
+    }
+
+    return next();
+  };
+
   const cannotLoginErrorHadnler = (req, res, next) => {
     // this is called when all login method is somehow failed without invoking 'return next(<any Error>)'
     const err = new ErrorV3('message.sign_in_failure');
@@ -328,7 +338,7 @@ module.exports = function(crowi, app) {
   const loginWithLocal = (req, res, next) => {
     if (!passportService.isLocalStrategySetup) {
       debug('LocalStrategy has not been set up');
-      return res.apiv3Err(new ErrorV3('message.strategy_has_not_been_set_up', '', undefined, { strategy: 'LocalStrategy' }), 405);
+      return next();
     }
 
     if (!req.form.isValid) {
@@ -585,6 +595,7 @@ module.exports = function(crowi, app) {
 
   return {
     cannotLoginErrorHadnler,
+    isEnableLoginWithLocalOrLdap,
     loginFailure,
     loginFailureForExternalAccount,
     loginWithLdap,

+ 27 - 3
packages/app/src/services/renderer/renderer.tsx

@@ -29,6 +29,7 @@ import { Header } from '~/components/ReactMarkdownComponents/Header';
 import { NextLink } from '~/components/ReactMarkdownComponents/NextLink';
 import { Table } from '~/components/ReactMarkdownComponents/Table';
 import { TableWithEditButton } from '~/components/ReactMarkdownComponents/TableWithEditButton';
+import { RehypeSanitizeOption } from '~/interfaces/rehype';
 import { RendererConfig } from '~/interfaces/services/renderer';
 import { registerGrowiFacade } from '~/utils/growi-facade';
 import loggerFactory from '~/utils/logger';
@@ -66,16 +67,21 @@ export type RendererOptions = Omit<ReactMarkdownOptions, 'remarkPlugins' | 'rehy
     | undefined
 };
 
+const commonSanitizeAttributes = { '*': ['class', 'className', 'style'] };
+
 const commonSanitizeOption: SanitizeOption = deepmerge(
   sanitizeDefaultSchema,
   {
     clobberPrefix: 'mdcont-',
-    attributes: {
-      '*': ['class', 'className', 'style'],
-    },
+    attributes: commonSanitizeAttributes,
   },
 );
 
+const injectCustomSanitizeOption = (config: RendererConfig) => {
+  commonSanitizeOption.tagNames = config.tagWhiteList;
+  commonSanitizeOption.attributes = deepmerge(commonSanitizeAttributes, config.attrWhiteList ?? {});
+};
+
 const isSanitizePlugin = (pluggable: Pluggable): pluggable is SanitizePlugin => {
   if (!Array.isArray(pluggable) || pluggable.length < 2) {
     return false;
@@ -148,6 +154,10 @@ export const generateViewOptions = (
     remarkPlugins.push(breaks);
   }
 
+  if (config.xssOption === RehypeSanitizeOption.CUSTOM) {
+    injectCustomSanitizeOption(config);
+  }
+
   const rehypeSanitizePlugin: Pluggable<any[]> | (() => void) = config.isEnabledXssPrevention
     ? [sanitize, deepmerge(
       commonSanitizeOption,
@@ -190,6 +200,11 @@ export const generateTocOptions = (config: RendererConfig, tocNode: HtmlElementN
   // add remark plugins
   // remarkPlugins.push();
 
+  if (config.xssOption === RehypeSanitizeOption.CUSTOM) {
+    injectCustomSanitizeOption(config);
+  }
+
+
   const rehypeSanitizePlugin: Pluggable<any[]> | (() => void) = config.isEnabledXssPrevention
     ? [sanitize, deepmerge(
       commonSanitizeOption,
@@ -234,6 +249,11 @@ export const generateSimpleViewOptions = (
     remarkPlugins.push(breaks);
   }
 
+  if (config.xssOption === RehypeSanitizeOption.CUSTOM) {
+    injectCustomSanitizeOption(config);
+  }
+
+
   const rehypeSanitizePlugin: Pluggable<any[]> | (() => void) = config.isEnabledXssPrevention
     ? [sanitize, deepmerge(
       commonSanitizeOption,
@@ -281,6 +301,10 @@ export const generatePreviewOptions = (config: RendererConfig, pagePath: string)
     remarkPlugins.push(breaks);
   }
 
+  if (config.xssOption === RehypeSanitizeOption.CUSTOM) {
+    injectCustomSanitizeOption(config);
+  }
+
   const rehypeSanitizePlugin: Pluggable<any[]> | (() => void) = config.isEnabledXssPrevention
     ? [sanitize, deepmerge(
       commonSanitizeOption,

+ 9 - 2
packages/app/src/services/xss/xssOption.ts

@@ -1,7 +1,14 @@
+import { defaultSchema as sanitizeDefaultSchema } from 'rehype-sanitize';
+import type { RehypeSanitizeOption } from '~/interfaces/rehype';
+
+type tagWhiteList = typeof sanitizeDefaultSchema.tagNames;
+type attrWhiteList = typeof sanitizeDefaultSchema.attributes;
+
 export type XssOptionConfig = {
   isEnabledXssPrevention: boolean,
-  tagWhiteList: any[],
-  attrWhiteList: any[],
+  xssOption: RehypeSanitizeOption,
+  tagWhiteList: tagWhiteList,
+  attrWhiteList: attrWhiteList,
 }
 
 export default class XssOption {

+ 16 - 6
packages/app/src/styles/theme/_apply-colors-dark.scss

@@ -13,12 +13,11 @@
   $color-list-active: var(--color-list-active,var(--color-reversal));
   $bgcolor-list-hover: var(--bgcolor-list-hover,var(--bgcolor-global));
   $bgcolor-list-active: var(--bgcolor-list-active,var(--primary));
-  $bgcolor-subnav: var(--bgcolor-subnav);
   $color-table: var(--color-table,white);
   $bgcolor-table: var(--bgcolor-table,#343a40);
-  $border-color-table: var(--border-color-table,hsl.lighten(var(--bgcolor-table),7.5%),lighten(#343a40, 7.5%));
+  $border-color-table: var(--border-color-table,lighten(#343a40, 7.5%));
   $color-table-hover: var(--color-table-hover,rgba(white, 0.075));
-  $bgcolor-table-hover: var(--bgcolor-table-hover,hsl.lighten(var(--bgcolor-table),7.5%),lighten(#343a40, 7.5%));
+  $bgcolor-table-hover: var(--bgcolor-table-hover,lighten(#343a40, 7.5%));
   $bgcolor-sidebar-list-group: var(--bgcolor-sidebar-list-group,var(--bgcolor-list));
   $color-tags: var(--color-tags,#949494);
   $bgcolor-tags: var(--bgcolor-tags,var(--dark));
@@ -28,7 +27,7 @@
   $bgcolor-dropdown: var(--bgcolor-dropdown,var(--bgcolor-global));
   $color-dropdown-link: var(--color-dropdown-link,var(--color-global));
   $color-dropdown-link-hover: var(--color-dropdown-link-hover,var(--light));
-  $bgcolor-dropdown-link-hover: var(--bgcolor-dropdown-link-hover,var(--primary));
+  $bgcolor-dropdown-link-hover: var(--bgcolor-dropdown-link-hover,hsl.lighten(var(--bgcolor-global), 15%));
   $color-dropdown-link-active: var(--color-dropdown-link-active,var(--light));
   $bgcolor-dropdown-link-active: var(--bgcolor-dropdown-link-active,var(--primary));
 
@@ -106,17 +105,24 @@
     background-color: hsl.darken(var(--bgcolor-global),5%);
   }
 
+  .rbt-input-multi .rbt-input-main {
+    color: black;
+  }
   /*
   * Table
   */
   .table {
     @extend .table-dark;
+    thead th {
+      vertical-align: bottom;
+      border-bottom: 2px solid #d6dadf;
+    }
   }
 
   /*
   * Card
   */
-  .card:not([class*=‘bg-’]):not(.well):not(.card-disabled) {
+  .card:not([class*='bg-']):not(.well):not(.card-disabled) {
     @extend .bg-dark;
   }
 
@@ -247,7 +253,6 @@
     @include mixins-buttons.button-svg-icon-variant($dark, $dark);
     color: $gray-400;
     box-shadow: none !important;
-
   }
 
   /*
@@ -522,6 +527,10 @@
     }
   }
 
+  mark.rbt-highlight-text {
+    color: var(--color-global);
+  }
+
   /*
   * GROWI popular tags
   */
@@ -574,5 +583,6 @@
   * skeleton
   */
   .grw-skeleton {
+    background-color: hsl.lighten(var(--bgcolor-subnav),10%);
   }
 }

+ 2 - 2
packages/app/src/styles/theme/_apply-colors-light.scss

@@ -84,7 +84,7 @@
   * card
   */
   .card.card-disabled {
-    background-color: var(--background-color);
+    background-color: var(--bgcolor-global);
     border-color: $gray-200;
   }
 
@@ -459,6 +459,6 @@
   * skeleton
   */
   .grw-skeleton {
-    background-color: hsl.lighten(var(--bgcolor-navbar),10%);
+    background-color: hsl.darken(var(--bgcolor-subnav),10%);
   }
 }

+ 10 - 8
packages/app/src/styles/theme/_apply-colors.scss

@@ -187,6 +187,9 @@ ul.pagination {
   .search-typeahead {
     background-color: hsl.alpha(var(--bgcolor-global),10%);
   }
+  input.form-control {
+    border: none;
+  }
 }
 
 .grw-sidebar {
@@ -375,14 +378,6 @@ ul.pagination {
   }
 }
 
-.grw-page-accessories-modal {
-  .modal-header {
-    .close {
-      color: var(--secondary);
-    }
-  }
-}
-
 /*
  * cards
  */
@@ -693,3 +688,10 @@ Emoji picker modal
 .emoji-picker-modal {
   background-color: transparent !important;
 }
+
+/*
+* revision-history-diff
+*/
+.revision-history-diff {
+  background-color: white;
+}

+ 0 - 6
packages/app/src/styles/theme/_hsl-reboot-bootstrap-theme-colors.scss

@@ -12,12 +12,6 @@ $hsl-colors: (
 @each $color, $value in $hsl-colors {
   .bg-#{$color} {
     background-color: $value !important;
-    a,
-    button {
-      @include hover-focus() {
-        background-color: hsl.darken($value, 10%) !important;
-      }
-    }
   }
 }
 

+ 1 - 1
packages/core/src/models/vo/error-apiv3.ts

@@ -4,7 +4,7 @@ export class ErrorV3 extends Error {
 
   args?: any;
 
-  constructor(message = '', code = '', stack = undefined, args = undefined) {
+  constructor(message = '', code = '', stack = undefined, args: any = undefined) {
     super(); // do not provide message to the super constructor
     this.message = message;
     this.code = code;

+ 2 - 1
packages/preset-themes/package.json

@@ -9,9 +9,10 @@
   ],
   "scripts": {
     "build": "yarn build:libs & yarn build:themes",
-    "build:w": "yarn build:libs -w & yarn build:themes -w",
     "build:libs": "vite -c vite.libs.config.ts build",
     "build:themes": "vite -c vite.themes.config.ts build",
+    "dev": "yarn build:libs --mode dev -w & yarn build:themes --mode dev -w",
+    "dev:nowatch": "yarn build:libs --mode dev & yarn build:themes --mode dev",
     "lint:eslint": "eslint --quiet \"**/*.{js,jsx,ts,tsx}\"",
     "lint:styles": "stylelint src/**/*.scss",
     "lint": "run-p lint:*",

+ 3 - 6
packages/preset-themes/src/styles/future.scss

@@ -19,6 +19,8 @@
 
   // Background colors
   --bgcolor-global: var(--themecolor);
+  --bgcolor-global-hs: var(--themecolor-hs);
+  --bgcolor-global-l: var(--themecolor-l);
   --bgcolor-inline-code: #1f1f22; //optional
   --bgcolor-card: #{hsl.darken(var(--themecolor), 5%)};
   --bgcolor-blinked-section: #{hsl.alpha(var(--primary), 60%)};
@@ -49,7 +51,7 @@
   // Table colors
   // --color-table: #; // optional
   --bgcolor-table: #{hsl.darken(var(--themecolor), 3%)}; // optional
-  // --border-color-table: #; // optional
+  --border-color-table: #{hsl.lighten(var(--themecolor), 10%)};; // optional
   // --color-table-hover: #; // optional
   // --bgcolor-table-hover: #; // optional
 
@@ -133,9 +135,4 @@
       color: white;
     }
   }
-
-  pre {
-    color: #95abba;
-    background-color: #1f1f22;
-  }
 }

+ 0 - 5
packages/preset-themes/src/styles/halloween.scss

@@ -134,9 +134,4 @@ $bordercolor: #7e0d7e;
   .table {
     color: var(--color-global);
   }
-
-  pre {
-    color: #edba4a;
-    background: black;
-  }
 }

+ 7 - 0
packages/preset-themes/vite.themes.config.ts

@@ -1,5 +1,7 @@
 import { defineConfig } from 'vite';
 
+const isProd = process.env.NODE_ENV === 'production';
+
 // https://vitejs.dev/config/
 export default defineConfig({
   build: {
@@ -23,6 +25,11 @@ export default defineConfig({
         '/src/styles/spring.scss',
         '/src/styles/wood.scss',
       ],
+      output: {
+        assetFileNames: isProd
+          ? undefined
+          : 'assets/[name].[ext]', // not attach hash
+      },
     },
   },
 });

Некоторые файлы не были показаны из-за большого количества измененных файлов