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

Merge branch 'master' into feat/158232-prevent-inline-mime-type-sniffing-vulnerabilities

arvid-e 3 недель назад
Родитель
Сommit
8994875eb3

+ 0 - 1
apps/app/package.json

@@ -109,7 +109,6 @@
     "browser-bunyan": "^1.8.0",
     "bson-objectid": "^2.0.4",
     "bunyan": "^1.8.15",
-    "check-node-version": "^4.2.1",
     "compression": "^1.7.4",
     "connect-flash": "~0.1.1",
     "connect-mongo": "^4.6.0",

+ 2 - 2
apps/app/src/client/components/Admin/Notification/ManageGlobalNotification.tsx

@@ -303,7 +303,7 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
                 onChange={() => onChangeTriggerEvents(TriggerEventType.EDIT)}
               >
                 <span className="badge rounded-pill bg-warning text-dark">
-                  <span className="imaterial-symbols-outlined">edit</span> EDIT
+                  <span className="material-symbols-outlined">edit</span> EDIT
                 </span>
               </TriggerEventCheckBox>
             </div>
@@ -314,7 +314,7 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
                 checked={triggerEvents.has(TriggerEventType.MOVE)}
                 onChange={() => onChangeTriggerEvents(TriggerEventType.MOVE)}
               >
-                <span className="badge rounded-pill bg-pink">
+                <span className="badge rounded-pill bg-secondary">
                   <span className="material-symbols-outlined">redo</span>MOVE
                 </span>
               </TriggerEventCheckBox>

+ 14 - 10
apps/app/src/client/components/PageHeader/PageHeader.tsx

@@ -1,6 +1,7 @@
 import { type JSX, useCallback, useEffect, useRef, useState } from 'react';
 
 import { useCurrentPageData } from '~/states/page';
+import { useDeviceLargerThanSm } from '~/states/ui/device';
 import { usePageControlsX } from '~/states/ui/page';
 
 import { PagePathHeader } from './PagePathHeader';
@@ -13,23 +14,26 @@ const moduleClass = styles['page-header'] ?? '';
 export const PageHeader = (): JSX.Element => {
   const currentPage = useCurrentPageData();
   const pageControlsX = usePageControlsX();
+  const [isLargerThanSm] = useDeviceLargerThanSm();
   const pageHeaderRef = useRef<HTMLDivElement>(null);
 
-  const [maxWidth, setMaxWidth] = useState<number>();
+  const [maxWidth, setMaxWidth] = useState<number>(300);
 
   const calcMaxWidth = useCallback(() => {
-    if (pageControlsX == null || pageHeaderRef.current == null) {
-      // Length that allows users to use PageHeader functionality.
-      setMaxWidth(300);
+    if (pageHeaderRef.current == null) {
       return;
     }
 
-    // PageControls.x - PageHeader.x
-    const maxWidth =
-      pageControlsX - pageHeaderRef.current.getBoundingClientRect().x;
-
-    setMaxWidth(maxWidth);
-  }, [pageControlsX]);
+    const pageHeaderX = pageHeaderRef.current.getBoundingClientRect().x;
+    setMaxWidth(
+      !isLargerThanSm
+        ? window.innerWidth - pageHeaderX
+        : pageControlsX != null
+          ? pageControlsX - pageHeaderX
+          : // Length that allows users to use PageHeader functionality.
+            300,
+    );
+  }, [isLargerThanSm, pageControlsX]);
 
   useEffect(() => {
     calcMaxWidth();

+ 1 - 1
apps/app/src/server/routes/apiv3/admin-home.ts

@@ -96,7 +96,7 @@ module.exports = (crowi: Crowi) => {
       const { getRuntimeVersions } = await import(
         '~/server/util/runtime-versions'
       );
-      const runtimeVersions = await getRuntimeVersions();
+      const runtimeVersions = getRuntimeVersions();
 
       const adminHomeParams: IResAdminHome = {
         growiVersion: getGrowiVersion(),

+ 12 - 50
apps/app/src/server/util/runtime-versions.ts

@@ -1,4 +1,4 @@
-import checkNodeVersion from 'check-node-version';
+import { execSync } from 'node:child_process';
 
 type RuntimeVersions = {
   node: string | undefined;
@@ -6,56 +6,18 @@ type RuntimeVersions = {
   pnpm: string | undefined;
 };
 
-// define original types because the object returned is not according to the official type definition
-type SatisfiedVersionInfo = {
-  isSatisfied: true;
-  version: {
-    version: string;
-  };
-};
-
-type NotfoundVersionInfo = {
-  isSatisfied: true;
-  notfound: true;
-};
-
-type VersionInfo = SatisfiedVersionInfo | NotfoundVersionInfo;
-
-function isNotfoundVersionInfo(info: VersionInfo): info is NotfoundVersionInfo {
-  return 'notfound' in info;
-}
-
-function isSatisfiedVersionInfo(
-  info: VersionInfo,
-): info is SatisfiedVersionInfo {
-  return 'version' in info;
-}
-
-const getVersion = (versionInfo: VersionInfo): string | undefined => {
-  if (isNotfoundVersionInfo(versionInfo)) {
+function getCommandVersion(command: string): string | undefined {
+  try {
+    return execSync(command, { encoding: 'utf8' }).trim();
+  } catch {
     return undefined;
   }
+}
 
-  if (isSatisfiedVersionInfo(versionInfo)) {
-    return versionInfo.version.version;
-  }
-
-  return undefined;
-};
-
-export function getRuntimeVersions(): Promise<RuntimeVersions> {
-  return new Promise((resolve, reject) => {
-    checkNodeVersion({}, (error, result) => {
-      if (error) {
-        reject(error);
-        return;
-      }
-
-      resolve({
-        node: getVersion(result.versions.node as unknown as VersionInfo),
-        npm: getVersion(result.versions.npm as unknown as VersionInfo),
-        pnpm: getVersion(result.versions.pnpm as unknown as VersionInfo),
-      });
-    });
-  });
+export function getRuntimeVersions(): RuntimeVersions {
+  return {
+    node: process.versions.node,
+    npm: getCommandVersion('npm --version'),
+    pnpm: getCommandVersion('pnpm --version'),
+  };
 }

+ 23 - 0
apps/app/src/states/ui/device.ts

@@ -10,6 +10,7 @@ import { atom, useAtom } from 'jotai';
 export const isDeviceLargerThanXlAtom = atom(false);
 export const isDeviceLargerThanLgAtom = atom(false);
 export const isDeviceLargerThanMdAtom = atom(false);
+export const isDeviceLargerThanSmAtom = atom(false);
 export const isMobileAtom = atom(false);
 
 export const useDeviceLargerThanXl = () => {
@@ -78,6 +79,28 @@ export const useDeviceLargerThanMd = () => {
   return [isLargerThanMd, setIsLargerThanMd] as const;
 };
 
+export const useDeviceLargerThanSm = () => {
+  const [isLargerThanSm, setIsLargerThanSm] = useAtom(isDeviceLargerThanSmAtom);
+
+  useEffect(() => {
+    const smOrAboveHandler = function (this: MediaQueryList): void {
+      // xs -> sm: matches will be true
+      // sm -> xs: matches will be false
+      setIsLargerThanSm(this.matches);
+    };
+    const mql = addBreakpointListener(Breakpoint.SM, smOrAboveHandler);
+
+    // initialize
+    setIsLargerThanSm(mql.matches);
+
+    return () => {
+      cleanupBreakpointListener(mql, smOrAboveHandler);
+    };
+  }, [setIsLargerThanSm]);
+
+  return [isLargerThanSm, setIsLargerThanSm] as const;
+};
+
 export const useIsMobile = () => {
   const [isMobile, setIsMobile] = useAtom(isMobileAtom);
 

+ 1 - 27
pnpm-lock.yaml

@@ -310,9 +310,6 @@ importers:
       bunyan:
         specifier: ^1.8.15
         version: 1.8.15
-      check-node-version:
-        specifier: ^4.2.1
-        version: 4.2.1
       compression:
         specifier: ^1.7.4
         version: 1.7.4
@@ -6584,11 +6581,6 @@ packages:
     resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
     engines: {node: '>= 16'}
 
-  check-node-version@4.2.1:
-    resolution: {integrity: sha512-YYmFYHV/X7kSJhuN/QYHUu998n/TRuDe8UenM3+m5NrkiH670lb9ILqHIvBencvJc4SDh+XcbXMR4b+TtubJiw==}
-    engines: {node: '>=8.3.0'}
-    hasBin: true
-
   cheerio-select@2.1.0:
     resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
 
@@ -9707,6 +9699,7 @@ packages:
     resolution: {integrity: sha512-Quz3MvAwHxVYNXsOByL7xI5EB2WYOeFswqaHIA3qOK3isRWTxiplBEocmmru6XmxDB2L7jDNYtYA4FyimoAFEw==}
     engines: {node: '>=8.17.0'}
     hasBin: true
+    bundledDependencies: []
 
   jsonfile@3.0.1:
     resolution: {integrity: sha512-oBko6ZHlubVB5mRFkur5vgYR1UyqX+S6Y/oCfLhqNdcc2fYFlDpIoNc7AfKS1KOGcnNAkvsr0grLck9ANM815w==}
@@ -10225,9 +10218,6 @@ packages:
     resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==}
     engines: {node: '>=8'}
 
-  map-values@1.0.1:
-    resolution: {integrity: sha512-BbShUnr5OartXJe1GeccAWtfro11hhgNJg6G9/UtWKjVGvV5U4C09cg5nk8JUevhXODaXY+hQ3xxMUKSs62ONQ==}
-
   markdown-it-front-matter@0.2.4:
     resolution: {integrity: sha512-25GUs0yjS2hLl8zAemVndeEzThB1p42yxuDEKbd4JlL3jiz+jsm6e56Ya8B0VREOkNxLYB4TTwaoPJ3ElMmW+w==}
 
@@ -11097,9 +11087,6 @@ packages:
     resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
     engines: {node: '>=0.10.0'}
 
-  object-filter@1.0.2:
-    resolution: {integrity: sha512-NahvP2vZcy1ZiiYah30CEPw0FpDcSkSePJBMpzl5EQgCmISijiGuJm3SPYp7U+Lf2TljyaIw3E5EgkEx/TNEVA==}
-
   object-hash@2.2.0:
     resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
     engines: {node: '>= 6'}
@@ -21516,15 +21503,6 @@ snapshots:
 
   check-error@2.1.1: {}
 
-  check-node-version@4.2.1:
-    dependencies:
-      chalk: 3.0.0
-      map-values: 1.0.1
-      minimist: 1.2.8
-      object-filter: 1.0.2
-      run-parallel: 1.2.0
-      semver: 6.3.1
-
   cheerio-select@2.1.0:
     dependencies:
       boolbase: 1.0.0
@@ -25239,8 +25217,6 @@ snapshots:
 
   map-obj@4.3.0: {}
 
-  map-values@1.0.1: {}
-
   markdown-it-front-matter@0.2.4: {}
 
   markdown-it@13.0.2:
@@ -26478,8 +26454,6 @@ snapshots:
 
   object-assign@4.1.1: {}
 
-  object-filter@1.0.2: {}
-
   object-hash@2.2.0: {}
 
   object-inspect@1.13.4: {}