Parcourir la source

Merge pull request #10526 from growilabs/fix/174481-accessing-admin-customize-error

fix: Accessing admin customize error
Yuki Takei il y a 4 mois
Parent
commit
72f6724938

+ 11 - 10
apps/app/src/pages/_document.page.tsx

@@ -42,10 +42,10 @@ const HeadersForGrowiPlugin = (
 };
 
 interface GrowiDocumentProps {
-  themeHref: string;
-  customScript: string | null;
-  customCss: string | null;
-  customNoscript: string | null;
+  themeHref: string | undefined;
+  customScript: string | undefined;
+  customCss: string | undefined;
+  customNoscript: string | undefined;
   pluginResourceEntries: GrowiPluginResourceEntries;
   locale: Locale;
 }
@@ -63,9 +63,10 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
     const { customizeService } = crowi;
 
     const { themeHref } = customizeService;
-    const customScript: string | null = customizeService.getCustomScript();
-    const customCss: string | null = customizeService.getCustomCss();
-    const customNoscript: string | null = customizeService.getCustomNoscript();
+    const customScript: string | undefined = customizeService.getCustomScript();
+    const customCss: string | undefined = customizeService.getCustomCss();
+    const customNoscript: string | undefined =
+      customizeService.getCustomNoscript();
 
     // retrieve plugin manifests
     const growiPluginService = await import(
@@ -87,7 +88,7 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
     };
   }
 
-  renderCustomScript(customScript: string | null): JSX.Element {
+  renderCustomScript(customScript: string | undefined): JSX.Element {
     if (customScript == null || customScript.length === 0) {
       return <></>;
     }
@@ -100,7 +101,7 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
     );
   }
 
-  renderCustomCss(customCss: string | null): JSX.Element {
+  renderCustomCss(customCss: string | undefined): JSX.Element {
     if (customCss == null || customCss.length === 0) {
       return <></>;
     }
@@ -108,7 +109,7 @@ class GrowiDocument extends Document<GrowiDocumentInitialProps> {
     return <style dangerouslySetInnerHTML={{ __html: customCss }} />;
   }
 
-  renderCustomNoscript(customNoscript: string | null): JSX.Element {
+  renderCustomNoscript(customNoscript: string | undefined): JSX.Element {
     if (customNoscript == null || customNoscript.length === 0) {
       return <></>;
     }

+ 1 - 10
apps/app/src/pages/admin/customize.page.tsx

@@ -3,7 +3,6 @@ import dynamic from 'next/dynamic';
 import { useHydrateAtoms } from 'jotai/utils';
 
 import type { CrowiRequest } from '~/interfaces/crowi-request';
-import { _atomsForAdminPagesHydration as atoms } from '~/states/global';
 import { isCustomizedLogoUploadedAtom } from '~/states/server-configurations';
 
 import type { NextPageWithLayout } from '../_app.page';
@@ -21,7 +20,6 @@ const CustomizeSettingContents = dynamic(
 );
 
 type PageProps = {
-  isDefaultBrandLogoUsed: boolean;
   isCustomizedLogoUploaded: boolean;
   customTitleTemplate?: string;
 };
@@ -33,11 +31,7 @@ const AdminCustomizeSettingsPage: NextPageWithLayout<Props> = (
   props: Props,
 ) => {
   useHydrateAtoms(
-    [
-      [atoms.isDefaultLogoAtom, props.isDefaultBrandLogoUsed],
-      [atoms.customTitleTemplateAtom, props.customTitleTemplate],
-      [isCustomizedLogoUploadedAtom, props.isCustomizedLogoUploaded],
-    ],
+    [[isCustomizedLogoUploadedAtom, props.isCustomizedLogoUploaded]],
     { dangerouslyForceHydrate: true },
   );
 
@@ -66,11 +60,8 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
 
   const customizePropsFragment = {
     props: {
-      isDefaultBrandLogoUsed:
-        await crowi.attachmentService.isDefaultBrandLogoUsed(),
       isCustomizedLogoUploaded:
         await crowi.attachmentService.isBrandLogoExist(),
-      customTitleTemplate: crowi.configManager.getConfig('customize:title'),
     },
   } satisfies { props: PageProps };
 

+ 8 - 2
apps/app/src/server/crowi/index.js

@@ -26,7 +26,7 @@ import UserEvent from '../events/user';
 import { accessTokenParser } from '../middlewares/access-token-parser';
 import { aclService as aclServiceSingletonInstance } from '../service/acl';
 import AppService from '../service/app';
-import AttachmentService from '../service/attachment';
+import { AttachmentService } from '../service/attachment';
 import { configManager as configManagerSingletonInstance } from '../service/config-manager';
 import instanciateExportService from '../service/export';
 import instanciateExternalAccountService from '../service/external-account';
@@ -74,6 +74,9 @@ class Crowi {
   /** @type {import('../service/config-manager').IConfigManagerForApp} */
   configManager;
 
+  /** @type {AttachmentService} */
+  attachmentService;
+
   /** @type {import('../service/acl').AclService} */
   aclService;
 
@@ -98,6 +101,9 @@ class Crowi {
   /** @type {import('../service/page-operation').IPageOperationService} */
   pageOperationService;
 
+  /** @type {import('../service/customize').CustomizeService} */
+  customizeService;
+
   /** @type {PassportService} */
   passportService;
 
@@ -632,7 +638,7 @@ Crowi.prototype.setUpAcl = async function () {
  * setup CustomizeService
  */
 Crowi.prototype.setUpCustomize = async function () {
-  const CustomizeService = require('../service/customize');
+  const { CustomizeService } = await import('../service/customize');
   if (this.customizeService == null) {
     this.customizeService = new CustomizeService(this);
     this.customizeService.initCustomCss();

+ 25 - 12
apps/app/src/server/service/attachment.ts

@@ -1,9 +1,11 @@
-import type { IAttachment } from '@growi/core/dist/interfaces';
+import type { IAttachment, Ref } from '@growi/core/dist/interfaces';
+import type { HydratedDocument } from 'mongoose';
 
 import loggerFactory from '~/utils/logger';
 
 import type Crowi from '../crowi';
 import { AttachmentType } from '../interfaces/attachment';
+import type { IAttachmentDocument } from '../models/attachment';
 import { Attachment } from '../models/attachment';
 
 const fs = require('fs');
@@ -19,15 +21,28 @@ const createReadStream = (filePath) => {
   });
 };
 
-type AttachHandler = (pageId: string | null, attachment: IAttachment, file: Express.Multer.File) => Promise<void>;
+type AttachHandler = (pageId: string | null, attachment: IAttachmentDocument, file: Express.Multer.File) => Promise<void>;
 
 type DetachHandler = (attachmentId: string) => Promise<void>;
 
 
+type IAttachmentService = {
+  createAttachment(
+    file: Express.Multer.File, user: any, pageId: string | null, attachmentType: AttachmentType,
+    disposeTmpFileCallback?: (file: Express.Multer.File) => void,
+  ): Promise<IAttachmentDocument>;
+  removeAllAttachments(attachments: IAttachmentDocument[]): Promise<void>;
+  removeAttachment(attachmentId: Ref<IAttachment> | undefined): Promise<void>;
+  isBrandLogoExist(): Promise<boolean>;
+  addAttachHandler(handler: AttachHandler): void;
+  addDetachHandler(handler: DetachHandler): void;
+};
+
+
 /**
  * the service class for Attachment and file-uploader
  */
-class AttachmentService {
+export class AttachmentService implements IAttachmentService {
 
   attachHandlers: AttachHandler[] = [];
 
@@ -39,7 +54,7 @@ class AttachmentService {
     this.crowi = crowi;
   }
 
-  async createAttachment(file, user, pageId = null, attachmentType, disposeTmpFileCallback) {
+  async createAttachment(file, user, pageId: string | null | undefined = null, attachmentType, disposeTmpFileCallback): Promise<IAttachmentDocument> {
     const { fileUploadService } = this.crowi;
 
     // check limit
@@ -82,7 +97,7 @@ class AttachmentService {
     return attachment;
   }
 
-  async removeAllAttachments(attachments) {
+  async removeAllAttachments(attachments: HydratedDocument<IAttachmentDocument>[]): Promise<void> {
     const { fileUploadService } = this.crowi;
     const attachmentsCollection = mongoose.connection.collection('attachments');
     const unorderAttachmentsBulkOp = attachmentsCollection.initializeUnorderedBulkOp();
@@ -96,12 +111,12 @@ class AttachmentService {
     });
     await unorderAttachmentsBulkOp.execute();
 
-    await fileUploadService.deleteFiles(attachments);
+    fileUploadService.deleteFiles(attachments);
 
     return;
   }
 
-  async removeAttachment(attachmentId) {
+  async removeAttachment(attachmentId: Ref<IAttachment> | undefined): Promise<void> {
     const { fileUploadService } = this.crowi;
     const attachment = await Attachment.findById(attachmentId);
 
@@ -125,7 +140,7 @@ class AttachmentService {
     return;
   }
 
-  async isBrandLogoExist() {
+  async isBrandLogoExist(): Promise<boolean> {
     const query = { attachmentType: AttachmentType.BRAND_LOGO };
     const count = await Attachment.countDocuments(query);
 
@@ -136,7 +151,7 @@ class AttachmentService {
    * Register a handler that will be called after attachment creation
    * @param {(pageId: string, attachment: Attachment, file: Express.Multer.File) => Promise<void>} handler
    */
-  addAttachHandler(handler) {
+  addAttachHandler(handler: AttachHandler): void {
     this.attachHandlers.push(handler);
   }
 
@@ -144,10 +159,8 @@ class AttachmentService {
    * Register a handler that will be called before attachment deletion
    * @param {(attachmentId: string) => Promise<void>} handler
    */
-  addDetachHandler(handler) {
+  addDetachHandler(handler: DetachHandler): void {
     this.detachHandlers.push(handler);
   }
 
 }
-
-module.exports = AttachmentService;

+ 1 - 3
apps/app/src/server/service/customize.ts

@@ -22,7 +22,7 @@ const logger = loggerFactory('growi:service:CustomizeService');
 /**
  * the service class of CustomizeService
  */
-class CustomizeService implements S2sMessageHandlable {
+export class CustomizeService implements S2sMessageHandlable {
 
   s2sMessagingService: any;
 
@@ -148,5 +148,3 @@ class CustomizeService implements S2sMessageHandlable {
   }
 
 }
-
-module.exports = CustomizeService;