Yuki Takei 1 سال پیش
والد
کامیت
93ab2f824a

+ 31 - 17
apps/app/src/features/questionnaire/server/service/questionnaire.ts

@@ -1,31 +1,37 @@
 import crypto from 'crypto';
 import * as os from 'node:os';
 
+
 import type { IUserHasId } from '@growi/core';
-import { IGrowiInfo } from '@growi/core/dist/interfaces';
 import { GrowiDeploymentType, GrowiServiceType } from '@growi/core/dist/consts';
+import type { IGrowiInfo, IUser } from '@growi/core/dist/interfaces';
+import { GrowiWikiType } from '@growi/core/dist/interfaces';
+import type { Model } from 'mongoose';
+import mongoose from 'mongoose';
 
 import { AttachmentMethodType } from '~/interfaces/attachment';
+import { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
+import type Crowi from '~/server/crowi';
 import type { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
-// eslint-disable-next-line import/no-named-as-default
 import { Config } from '~/server/models/config';
 import { aclService } from '~/server/service/acl';
+import { configManager } from '~/server/service/config-manager';
 import loggerFactory from '~/utils/logger';
 
+import type { IGrowiAppAdditionalInfo } from '../../interfaces/growi-app-additional-info';
 import { StatusType } from '../../interfaces/questionnaire-answer-status';
 import { type IUserInfo, UserType } from '../../interfaces/user-info';
 import QuestionnaireAnswerStatus from '../models/questionnaire-answer-status';
 import type { QuestionnaireOrderDocument } from '../models/questionnaire-order';
 import QuestionnaireOrder from '../models/questionnaire-order';
 import { isShowableCondition } from '../util/condition';
-import { IGrowiAppAdditionalInfo } from '../../interfaces/growi-app-additional-info';
 
 
 const logger = loggerFactory('growi:service:questionnaire');
 
 class QuestionnaireService {
 
-  crowi: any;
+  crowi: Crowi;
 
   // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
   constructor(crowi) {
@@ -33,7 +39,8 @@ class QuestionnaireService {
   }
 
   async getGrowiInfo(): Promise<IGrowiInfo<IGrowiAppAdditionalInfo>> {
-    const User = this.crowi.model('User');
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    const User = mongoose.model<IUser, Model<IUser>>('User');
 
     const appSiteUrl = this.crowi.appService.getSiteUrl();
     const hasher = crypto.createHash('sha256');
@@ -48,25 +55,30 @@ class QuestionnaireService {
     const installedAtByOldestUser = user ? user.createdAt : null;
 
     const appInstalledConfig = await Config.findOne({ key: 'app:installed' });
-    const installedAt = appInstalledConfig != null && appInstalledConfig.createdAt != null ? appInstalledConfig.createdAt : installedAtByOldestUser;
+    const oldestConfig = await Config.findOne().sort({ createdAt: 1 });
+
+    // oldestConfig must not be null because there is at least one config
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    const installedAt = installedAtByOldestUser ?? appInstalledConfig?.createdAt ?? oldestConfig!.createdAt ?? null;
 
     const currentUsersCount = await User.countDocuments();
-    const currentActiveUsersCount = await User.countActiveUsers();
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    const currentActiveUsersCount = await (User as any).countActiveUsers();
 
     const isGuestAllowedToRead = aclService.isGuestAllowedToRead();
     const wikiType = isGuestAllowedToRead ? GrowiWikiType.open : GrowiWikiType.closed;
 
-    const activeExternalAccountTypes: GrowiExternalAuthProviderType[] = Object.values(GrowiExternalAuthProviderType).filter((type) => {
-      return this.crowi.configManager.getConfig(`security:passport-${type}:isEnabled`);
+    const activeExternalAccountTypes: IExternalAuthProviderType[] = Object.values(IExternalAuthProviderType).filter((type) => {
+      return configManager.getConfig(`security:passport-${type}:isEnabled`);
     });
 
-    const typeStr = this.crowi.configManager.getConfig('app:serviceType');
+    const typeStr = configManager.getConfig('app:serviceType');
     const type = Object.values(GrowiServiceType).includes(typeStr) ? typeStr : null;
 
-    const attachmentTypeStr = this.crowi.configManager.getConfig('app:fileUploadType');
+    const attachmentTypeStr = configManager.getConfig('app:fileUploadType');
     const attachmentType = Object.values(AttachmentMethodType).includes(attachmentTypeStr) ? attachmentTypeStr : null;
 
-    const deploymentTypeStr = this.crowi.configManager.getConfig('app:deploymentType');
+    const deploymentTypeStr = configManager.getConfig('app:deploymentType');
     const deploymentType = Object.values(GrowiDeploymentType).includes(deploymentTypeStr) ? deploymentTypeStr : null;
 
     return {
@@ -77,17 +89,19 @@ class QuestionnaireService {
         arch: os.arch(),
         totalmem: os.totalmem(),
       },
-      appSiteUrl: this.crowi.configManager.getConfig('questionnaire:isAppSiteUrlHashed') ? null : appSiteUrl,
+      appSiteUrl: configManager.getConfig('questionnaire:isAppSiteUrlHashed') ? null : appSiteUrl,
       appSiteUrlHashed,
-      installedAt,
-      installedAtByOldestUser,
       type,
-      currentUsersCount,
-      currentActiveUsersCount,
       wikiType,
       attachmentType,
       activeExternalAccountTypes,
       deploymentType,
+      additionalInfo: {
+        installedAt,
+        installedAtByOldestUser,
+        currentUsersCount,
+        currentActiveUsersCount,
+      },
     };
   }
 

+ 1 - 1
packages/core/src/interfaces/growi-app-info.ts

@@ -14,7 +14,7 @@ interface IGrowiOSInfo {
 
 export interface IGrowiAdditionalInfo {
   installedAt: Date
-  installedAtByOldestUser: Date
+  installedAtByOldestUser: Date | null
   currentUsersCount: number
   currentActiveUsersCount: number
 }