Explorar el Código

WIP: refactor IGrowiInfo interface

Yuki Takei hace 1 año
padre
commit
71550f19fc
Se han modificado 28 ficheros con 103 adiciones y 81 borrados
  1. 2 1
      apps/app/src/client/components/Admin/Users/ExternalAccountTable.tsx
  2. 2 1
      apps/app/src/client/components/LoginForm/ExternalAuthButton.tsx
  3. 1 1
      apps/app/src/client/components/LoginForm/LoginForm.tsx
  4. 3 2
      apps/app/src/client/components/Me/DisassociateModal.tsx
  5. 2 1
      apps/app/src/features/external-user-group/server/service/external-user-group-sync.ts
  6. 1 2
      apps/app/src/features/questionnaire/interfaces/condition.ts
  7. 9 0
      apps/app/src/features/questionnaire/interfaces/growi-app-additional-info.ts
  8. 5 3
      apps/app/src/features/questionnaire/interfaces/proactive-questionnaire-answer.ts
  9. 6 4
      apps/app/src/features/questionnaire/interfaces/questionnaire-answer.ts
  10. 1 2
      apps/app/src/features/questionnaire/server/models/schema/condition.ts
  11. 27 12
      apps/app/src/features/questionnaire/server/models/schema/growi-info.ts
  12. 4 6
      apps/app/src/features/questionnaire/server/service/questionnaire.ts
  13. 9 0
      apps/app/src/interfaces/external-auth-provider.ts
  14. 1 1
      apps/app/src/pages/login/index.page.tsx
  15. 4 5
      apps/app/src/server/models/external-account.ts
  16. 2 1
      apps/app/src/server/routes/apiv3/security-settings/checkSetupStrategiesHasAdmin.ts
  17. 1 1
      apps/app/src/server/service/config-manager/config-definition.ts
  18. 1 1
      apps/app/src/server/service/config-manager/config-manager.integ.ts
  19. 1 1
      apps/app/src/server/service/config-manager/legacy/config-loader.ts
  20. 1 1
      apps/app/src/server/service/external-account.ts
  21. 1 1
      apps/app/src/server/service/passport.ts
  22. 3 2
      apps/app/src/stores/personal-settings.tsx
  23. 1 0
      packages/core/src/consts/index.ts
  24. 0 0
      packages/core/src/consts/system.ts
  25. 2 15
      packages/core/src/interfaces/external-account.ts
  26. 10 14
      packages/core/src/interfaces/growi-app-info.ts
  27. 1 0
      packages/core/src/interfaces/index.ts
  28. 2 3
      packages/core/src/interfaces/user.ts

+ 2 - 1
apps/app/src/client/components/Admin/Users/ExternalAccountTable.tsx

@@ -6,6 +6,7 @@ import { useTranslation } from 'next-i18next';
 
 
 import AdminExternalAccountsContainer from '~/client/services/AdminExternalAccountsContainer';
 import AdminExternalAccountsContainer from '~/client/services/AdminExternalAccountsContainer';
 import { toastSuccess, toastError } from '~/client/util/toastr';
 import { toastSuccess, toastError } from '~/client/util/toastr';
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 
 
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 
 
@@ -76,7 +77,7 @@ const ExternalAccountTable = (props: ExternalAccountTableProps): JSX.Element =>
           </tr>
           </tr>
         </thead>
         </thead>
         <tbody>
         <tbody>
-          { adminExternalAccountsContainer.state.externalAccounts.map((ea: IAdminExternalAccount) => {
+          { adminExternalAccountsContainer.state.externalAccounts.map((ea: IAdminExternalAccount<IExternalAuthProviderType>) => {
             return (
             return (
               <tr key={ea._id}>
               <tr key={ea._id}>
                 <td><span>{ea.providerType}</span></td>
                 <td><span>{ea.providerType}</span></td>

+ 2 - 1
apps/app/src/client/components/LoginForm/ExternalAuthButton.tsx

@@ -1,8 +1,9 @@
 import { useCallback } from 'react';
 import { useCallback } from 'react';
 
 
-import { IExternalAuthProviderType } from '@growi/core';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 
 
+import { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
+
 const authIcon = {
 const authIcon = {
   [IExternalAuthProviderType.google]: <span className="growi-custom-icons align-bottom">google</span>,
   [IExternalAuthProviderType.google]: <span className="growi-custom-icons align-bottom">google</span>,
   [IExternalAuthProviderType.github]: <span className="growi-custom-icons align-bottom">github</span>,
   [IExternalAuthProviderType.github]: <span className="growi-custom-icons align-bottom">github</span>,

+ 1 - 1
apps/app/src/client/components/LoginForm/LoginForm.tsx

@@ -2,7 +2,6 @@ import React, {
   useState, useEffect, useCallback,
   useState, useEffect, useCallback,
 } from 'react';
 } from 'react';
 
 
-import type { IExternalAuthProviderType } from '@growi/core';
 import { LoadingSpinner } from '@growi/ui/dist/components';
 import { LoadingSpinner } from '@growi/ui/dist/components';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import { useRouter } from 'next/router';
 import { useRouter } from 'next/router';
@@ -13,6 +12,7 @@ import { useTWithOpt } from '~/client/util/t-with-opt';
 import type { IExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
 import type { IExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
 import { LoginErrorCode } from '~/interfaces/errors/login-error';
 import { LoginErrorCode } from '~/interfaces/errors/login-error';
 import type { IErrorV3 } from '~/interfaces/errors/v3-error';
 import type { IErrorV3 } from '~/interfaces/errors/v3-error';
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 import { RegistrationMode } from '~/interfaces/registration-mode';
 import { RegistrationMode } from '~/interfaces/registration-mode';
 import { toArrayIfNot } from '~/utils/array-utils';
 import { toArrayIfNot } from '~/utils/array-utils';
 
 

+ 3 - 2
apps/app/src/client/components/Me/DisassociateModal.tsx

@@ -1,6 +1,6 @@
 import React, { useCallback } from 'react';
 import React, { useCallback } from 'react';
 
 
-import type { IExternalAccountHasId } from '@growi/core';
+import type { HasObjectId, IExternalAccount } from '@growi/core';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import {
 import {
   Modal,
   Modal,
@@ -10,12 +10,13 @@ import {
 } from 'reactstrap';
 } from 'reactstrap';
 
 
 import { toastSuccess, toastError } from '~/client/util/toastr';
 import { toastSuccess, toastError } from '~/client/util/toastr';
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 import { usePersonalSettings, useSWRxPersonalExternalAccounts } from '~/stores/personal-settings';
 import { usePersonalSettings, useSWRxPersonalExternalAccounts } from '~/stores/personal-settings';
 
 
 type Props = {
 type Props = {
   isOpen: boolean,
   isOpen: boolean,
   onClose: () => void,
   onClose: () => void,
-  accountForDisassociate: IExternalAccountHasId,
+  accountForDisassociate: IExternalAccount<IExternalAuthProviderType> & HasObjectId,
 }
 }
 
 
 
 

+ 2 - 1
apps/app/src/features/external-user-group/server/service/external-user-group-sync.ts

@@ -1,4 +1,4 @@
-import type { IExternalAuthProviderType, IUserHasId } from '@growi/core';
+import type { IUserHasId } from '@growi/core';
 
 
 import { SocketEventName } from '~/interfaces/websocket';
 import { SocketEventName } from '~/interfaces/websocket';
 import ExternalAccount from '~/server/models/external-account';
 import ExternalAccount from '~/server/models/external-account';
@@ -16,6 +16,7 @@ import type {
 } from '../../interfaces/external-user-group';
 } from '../../interfaces/external-user-group';
 import ExternalUserGroup from '../models/external-user-group';
 import ExternalUserGroup from '../models/external-user-group';
 import ExternalUserGroupRelation from '../models/external-user-group-relation';
 import ExternalUserGroupRelation from '../models/external-user-group-relation';
+import { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 
 
 const logger = loggerFactory('growi:service:external-user-group-sync-service');
 const logger = loggerFactory('growi:service:external-user-group-sync-service');
 
 

+ 1 - 2
apps/app/src/features/questionnaire/interfaces/condition.ts

@@ -1,6 +1,5 @@
 import type { HasObjectId } from '@growi/core';
 import type { HasObjectId } from '@growi/core';
-
-import type { GrowiServiceType } from '~/interfaces/system';
+import type { GrowiServiceType } from '@growi/core/dist/consts';
 
 
 import type { UserType } from './user-info';
 import type { UserType } from './user-info';
 
 

+ 9 - 0
apps/app/src/features/questionnaire/interfaces/growi-app-additional-info.ts

@@ -0,0 +1,9 @@
+import type { IGrowiAdditionalInfo } from '@growi/core/dist/interfaces';
+
+import type { AttachmentMethodType } from '~/interfaces/attachment';
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
+
+export type IGrowiAppAdditionalInfo = IGrowiAdditionalInfo & {
+  attachmentType: AttachmentMethodType
+  activeExternalAccountTypes?: IExternalAuthProviderType[]
+}

+ 5 - 3
apps/app/src/features/questionnaire/interfaces/proactive-questionnaire-answer.ts

@@ -1,11 +1,13 @@
-import { IGrowiInfo } from './growi-info';
-import { IUserInfo } from './user-info';
+import type { IGrowiInfo } from '@growi/core/dist/interfaces';
+
+import type { IGrowiAppAdditionalInfo } from './growi-app-additional-info';
+import type { IUserInfo } from './user-info';
 
 
 
 
 export interface IProactiveQuestionnaireAnswer {
 export interface IProactiveQuestionnaireAnswer {
   satisfaction: number,
   satisfaction: number,
   commentText: string,
   commentText: string,
-  growiInfo: IGrowiInfo,
+  growiInfo: IGrowiInfo<IGrowiAppAdditionalInfo>,
   userInfo: IUserInfo,
   userInfo: IUserInfo,
   answeredAt: Date,
   answeredAt: Date,
   lengthOfExperience?: string,
   lengthOfExperience?: string,

+ 6 - 4
apps/app/src/features/questionnaire/interfaces/questionnaire-answer.ts

@@ -1,11 +1,13 @@
-import { IAnswer } from './answer';
-import { IGrowiInfo } from './growi-info';
-import { IUserInfo } from './user-info';
+import type { IGrowiInfo } from '@growi/core/dist/interfaces';
+
+import type { IAnswer } from './answer';
+import type { IGrowiAppAdditionalInfo } from './growi-app-additional-info';
+import type { IUserInfo } from './user-info';
 
 
 export interface IQuestionnaireAnswer<ID = string> {
 export interface IQuestionnaireAnswer<ID = string> {
   answers: IAnswer[]
   answers: IAnswer[]
   answeredAt: Date
   answeredAt: Date
-  growiInfo: IGrowiInfo
+  growiInfo: IGrowiInfo<IGrowiAppAdditionalInfo>
   userInfo: IUserInfo
   userInfo: IUserInfo
   questionnaireOrder: ID
   questionnaireOrder: ID
 }
 }

+ 1 - 2
apps/app/src/features/questionnaire/server/models/schema/condition.ts

@@ -1,7 +1,6 @@
+import { GrowiServiceType } from '@growi/core/dist/consts';
 import { Schema } from 'mongoose';
 import { Schema } from 'mongoose';
 
 
-import { GrowiServiceType } from '~/interfaces/system';
-
 import type { ICondition } from '../../../interfaces/condition';
 import type { ICondition } from '../../../interfaces/condition';
 import { UserType } from '../../../interfaces/user-info';
 import { UserType } from '../../../interfaces/user-info';
 
 

+ 27 - 12
apps/app/src/features/questionnaire/server/models/schema/growi-info.ts

@@ -1,26 +1,31 @@
+import { GrowiDeploymentType, GrowiServiceType } from '@growi/core/dist/consts';
+import type { IGrowiInfo } from '@growi/core/dist/interfaces';
+import { GrowiWikiType } from '@growi/core/dist/interfaces';
 import { Schema } from 'mongoose';
 import { Schema } from 'mongoose';
 
 
+import type { IGrowiAppAdditionalInfo } from '~/features/questionnaire/interfaces/growi-app-additional-info';
 import { AttachmentMethodType } from '~/interfaces/attachment';
 import { AttachmentMethodType } from '~/interfaces/attachment';
-import { GrowiDeploymentType, GrowiServiceType } from '~/interfaces/system';
+import { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 
 
-import type { IGrowiInfo } from '../../../interfaces/growi-info';
-import {
-  GrowiExternalAuthProviderType, GrowiWikiType,
-} from '../../../interfaces/growi-info';
+// legacy properties (extracted from additionalInfo for growi-questionnaire)
+// see: https://gitlab.weseek.co.jp/tech/growi/growi-questionnaire
+type IGrowiInfoLegacy = IGrowiInfo<IGrowiAppAdditionalInfo> & IGrowiAppAdditionalInfo;
 
 
+const growiAdditionalInfoSchema = new Schema<IGrowiAppAdditionalInfo>({
+  installedAt: { type: Date, required: true },
+  installedAtByOldestUser: { type: Date, required: true },
+  currentUsersCount: { type: Number, required: true },
+  currentActiveUsersCount: { type: Number, required: true },
+  attachmentType: { type: String, required: true, enum: Object.values(AttachmentMethodType) },
+  activeExternalAccountTypes: [{ type: String, enum: Object.values(IExternalAuthProviderType) }],
+});
 
 
-export const growiInfoSchema = new Schema<IGrowiInfo>({
+export const growiInfoSchema = new Schema<IGrowiInfoLegacy>({
   version: { type: String, required: true },
   version: { type: String, required: true },
   appSiteUrl: { type: String },
   appSiteUrl: { type: String },
   appSiteUrlHashed: { type: String, required: true },
   appSiteUrlHashed: { type: String, required: true },
-  installedAt: { type: Date, required: true },
-  installedAtByOldestUser: { type: Date, required: true },
   type: { type: String, required: true, enum: Object.values(GrowiServiceType) },
   type: { type: String, required: true, enum: Object.values(GrowiServiceType) },
-  currentUsersCount: { type: Number, required: true },
-  currentActiveUsersCount: { type: Number, required: true },
   wikiType: { type: String, required: true, enum: Object.values(GrowiWikiType) },
   wikiType: { type: String, required: true, enum: Object.values(GrowiWikiType) },
-  attachmentType: { type: String, required: true, enum: Object.values(AttachmentMethodType) },
-  activeExternalAccountTypes: [{ type: String, enum: Object.values(GrowiExternalAuthProviderType) }],
   osInfo: {
   osInfo: {
     type: { type: String },
     type: { type: String },
     platform: String,
     platform: String,
@@ -28,4 +33,14 @@ export const growiInfoSchema = new Schema<IGrowiInfo>({
     totalmem: Number,
     totalmem: Number,
   },
   },
   deploymentType: { type: String, enum: (<(string | null)[]>Object.values(GrowiDeploymentType)).concat([null]) },
   deploymentType: { type: String, enum: (<(string | null)[]>Object.values(GrowiDeploymentType)).concat([null]) },
+  additionalInfo: growiAdditionalInfoSchema,
+
+  // legacy properties (extracted from additionalInfo for growi-questionnaire)
+  // see: https://gitlab.weseek.co.jp/tech/growi/growi-questionnaire
+  installedAt: { type: Date, required: true },
+  installedAtByOldestUser: { type: Date, required: true },
+  currentUsersCount: { type: Number, required: true },
+  currentActiveUsersCount: { type: Number, required: true },
+  attachmentType: { type: String, required: true, enum: Object.values(AttachmentMethodType) },
+  activeExternalAccountTypes: [{ type: String, enum: Object.values(IExternalAuthProviderType) }],
 });
 });

+ 4 - 6
apps/app/src/features/questionnaire/server/service/questionnaire.ts

@@ -2,25 +2,23 @@ import crypto from 'crypto';
 import * as os from 'node:os';
 import * as os from 'node:os';
 
 
 import type { IUserHasId } from '@growi/core';
 import type { IUserHasId } from '@growi/core';
+import { IGrowiInfo } from '@growi/core/dist/interfaces';
+import { GrowiDeploymentType, GrowiServiceType } from '@growi/core/dist/consts';
 
 
 import { AttachmentMethodType } from '~/interfaces/attachment';
 import { AttachmentMethodType } from '~/interfaces/attachment';
-import { GrowiDeploymentType, GrowiServiceType } from '~/interfaces/system';
 import type { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
 import type { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
 // eslint-disable-next-line import/no-named-as-default
 // eslint-disable-next-line import/no-named-as-default
 import { Config } from '~/server/models/config';
 import { Config } from '~/server/models/config';
 import { aclService } from '~/server/service/acl';
 import { aclService } from '~/server/service/acl';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
-import type { IGrowiInfo } from '../../interfaces/growi-info';
-import {
-  GrowiWikiType, GrowiExternalAuthProviderType,
-} from '../../interfaces/growi-info';
 import { StatusType } from '../../interfaces/questionnaire-answer-status';
 import { StatusType } from '../../interfaces/questionnaire-answer-status';
 import { type IUserInfo, UserType } from '../../interfaces/user-info';
 import { type IUserInfo, UserType } from '../../interfaces/user-info';
 import QuestionnaireAnswerStatus from '../models/questionnaire-answer-status';
 import QuestionnaireAnswerStatus from '../models/questionnaire-answer-status';
 import type { QuestionnaireOrderDocument } from '../models/questionnaire-order';
 import type { QuestionnaireOrderDocument } from '../models/questionnaire-order';
 import QuestionnaireOrder from '../models/questionnaire-order';
 import QuestionnaireOrder from '../models/questionnaire-order';
 import { isShowableCondition } from '../util/condition';
 import { isShowableCondition } from '../util/condition';
+import { IGrowiAppAdditionalInfo } from '../../interfaces/growi-app-additional-info';
 
 
 
 
 const logger = loggerFactory('growi:service:questionnaire');
 const logger = loggerFactory('growi:service:questionnaire');
@@ -34,7 +32,7 @@ class QuestionnaireService {
     this.crowi = crowi;
     this.crowi = crowi;
   }
   }
 
 
-  async getGrowiInfo(): Promise<IGrowiInfo> {
+  async getGrowiInfo(): Promise<IGrowiInfo<IGrowiAppAdditionalInfo>> {
     const User = this.crowi.model('User');
     const User = this.crowi.model('User');
 
 
     const appSiteUrl = this.crowi.appService.getSiteUrl();
     const appSiteUrl = this.crowi.appService.getSiteUrl();

+ 9 - 0
apps/app/src/interfaces/external-auth-provider.ts

@@ -0,0 +1,9 @@
+export const IExternalAuthProviderType = {
+  ldap: 'ldap',
+  saml: 'saml',
+  oidc: 'oidc',
+  google: 'google',
+  github: 'github',
+} as const;
+
+export type IExternalAuthProviderType = typeof IExternalAuthProviderType[keyof typeof IExternalAuthProviderType]

+ 1 - 1
apps/app/src/pages/login/index.page.tsx

@@ -1,6 +1,5 @@
 import React from 'react';
 import React from 'react';
 
 
-import { IExternalAuthProviderType } from '@growi/core';
 import type {
 import type {
   NextPage, GetServerSideProps, GetServerSidePropsContext,
   NextPage, GetServerSideProps, GetServerSidePropsContext,
 } from 'next';
 } from 'next';
@@ -13,6 +12,7 @@ import { NoLoginLayout } from '~/components/Layout/NoLoginLayout';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
 import type { CrowiRequest } from '~/interfaces/crowi-request';
 import type { IExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
 import type { IExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
 import { isExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
 import { isExternalAccountLoginError } from '~/interfaces/errors/external-account-login-error';
+import { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 import type { RegistrationMode } from '~/interfaces/registration-mode';
 import type { RegistrationMode } from '~/interfaces/registration-mode';
 import type { CommonProps } from '~/pages/utils/commons';
 import type { CommonProps } from '~/pages/utils/commons';
 import { getServerSideCommonProps, generateCustomTitle, getNextI18NextConfig } from '~/pages/utils/commons';
 import { getServerSideCommonProps, generateCustomTitle, getNextI18NextConfig } from '~/pages/utils/commons';

+ 4 - 5
apps/app/src/server/models/external-account.ts

@@ -1,12 +1,12 @@
 // disable no-return-await for model functions
 // disable no-return-await for model functions
 /* eslint-disable no-return-await */
 /* eslint-disable no-return-await */
-import type { IUser } from '@growi/core/dist/interfaces';
-import { type IExternalAccount, type IExternalAccountHasId, type IUserHasId } from '@growi/core/dist/interfaces';
+import type { IUser, IUserHasId, IExternalAccount } from '@growi/core/dist/interfaces';
 import type { Model, Document, HydratedDocument } from 'mongoose';
 import type { Model, Document, HydratedDocument } from 'mongoose';
 import mongoose, { Schema } from 'mongoose';
 import mongoose, { Schema } from 'mongoose';
 import mongoosePaginate from 'mongoose-paginate-v2';
 import mongoosePaginate from 'mongoose-paginate-v2';
 import uniqueValidator from 'mongoose-unique-validator';
 import uniqueValidator from 'mongoose-unique-validator';
 
 
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 import { NullUsernameToBeRegisteredError } from '~/server/models/errors';
 import { NullUsernameToBeRegisteredError } from '~/server/models/errors';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
@@ -14,8 +14,7 @@ import { getOrCreateModel } from '../util/mongoose-utils';
 
 
 const logger = loggerFactory('growi:models:external-account');
 const logger = loggerFactory('growi:models:external-account');
 
 
-
-export interface ExternalAccountDocument extends IExternalAccount, Document {}
+export interface ExternalAccountDocument extends IExternalAccount<IExternalAuthProviderType>, Document {}
 
 
 export interface ExternalAccountModel extends Model<ExternalAccountDocument> {
 export interface ExternalAccountModel extends Model<ExternalAccountDocument> {
   [x:string]: any, // for old methods
   [x:string]: any, // for old methods
@@ -71,7 +70,7 @@ schema.statics.findOrRegister = function(
     usernameToBeRegistered?: string,
     usernameToBeRegistered?: string,
     nameToBeRegistered?: string,
     nameToBeRegistered?: string,
     mailToBeRegistered?: string,
     mailToBeRegistered?: string,
-): Promise<IExternalAccountHasId> {
+): Promise<HydratedDocument<IExternalAccount<IExternalAuthProviderType>>> {
   return this.findOne({ providerType, accountId })
   return this.findOne({ providerType, accountId })
     .then((account) => {
     .then((account) => {
     // ExternalAccount is found
     // ExternalAccount is found

+ 2 - 1
apps/app/src/server/routes/apiv3/security-settings/checkSetupStrategiesHasAdmin.ts

@@ -1,6 +1,7 @@
-import type { IExternalAuthProviderType } from '@growi/core';
 import mongoose from 'mongoose';
 import mongoose from 'mongoose';
 
 
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
+
 interface AggregateResult {
 interface AggregateResult {
   count: number;
   count: number;
 }
 }

+ 1 - 1
apps/app/src/server/service/config-manager/config-definition.ts

@@ -1,3 +1,4 @@
+import { GrowiServiceType } from '@growi/core/dist/consts';
 import type { ConfigDefinition, Lang } from '@growi/core/dist/interfaces';
 import type { ConfigDefinition, Lang } from '@growi/core/dist/interfaces';
 import { defineConfig } from '@growi/core/dist/interfaces';
 import { defineConfig } from '@growi/core/dist/interfaces';
 import type OpenAI from 'openai';
 import type OpenAI from 'openai';
@@ -7,7 +8,6 @@ import { AttachmentMethodType } from '~/interfaces/attachment';
 import type { IPageDeleteConfigValue, IPageDeleteConfigValueToProcessValidation } from '~/interfaces/page-delete-config';
 import type { IPageDeleteConfigValue, IPageDeleteConfigValueToProcessValidation } from '~/interfaces/page-delete-config';
 import type { RegistrationMode } from '~/interfaces/registration-mode';
 import type { RegistrationMode } from '~/interfaces/registration-mode';
 import { RehypeSanitizeType } from '~/interfaces/services/rehype-sanitize';
 import { RehypeSanitizeType } from '~/interfaces/services/rehype-sanitize';
-import { GrowiServiceType } from '~/interfaces/system';
 
 
 /*
 /*
  * Sort order for top level keys:
  * Sort order for top level keys:

+ 1 - 1
apps/app/src/server/service/config-manager/config-manager.integ.ts

@@ -1,6 +1,6 @@
 import { mock } from 'vitest-mock-extended';
 import { mock } from 'vitest-mock-extended';
 
 
-import { GrowiDeploymentType, GrowiServiceType } from '~/interfaces/system';
+import { GrowiDeploymentType, GrowiServiceType } from '@growi/core/dist/consts';
 
 
 import { Config } from '../../models/config';
 import { Config } from '../../models/config';
 import type { S2sMessagingService } from '../s2s-messaging/base';
 import type { S2sMessagingService } from '../s2s-messaging/base';

+ 1 - 1
apps/app/src/server/service/config-manager/legacy/config-loader.ts

@@ -1,7 +1,7 @@
+import { GrowiServiceType } from '@growi/core/dist/consts';
 import { envUtils } from '@growi/core/dist/utils';
 import { envUtils } from '@growi/core/dist/utils';
 import { parseISO } from 'date-fns/parseISO';
 import { parseISO } from 'date-fns/parseISO';
 
 
-import { GrowiServiceType } from '~/interfaces/system';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import {
 import {

+ 1 - 1
apps/app/src/server/service/external-account.ts

@@ -1,7 +1,7 @@
-import type { IExternalAuthProviderType } from '@growi/core';
 import { ErrorV3 } from '@growi/core/dist/models';
 import { ErrorV3 } from '@growi/core/dist/models';
 
 
 import { LoginErrorCode } from '~/interfaces/errors/login-error';
 import { LoginErrorCode } from '~/interfaces/errors/login-error';
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import { NullUsernameToBeRegisteredError } from '../models/errors';
 import { NullUsernameToBeRegisteredError } from '../models/errors';

+ 1 - 1
apps/app/src/server/service/passport.ts

@@ -1,6 +1,5 @@
 import type { IncomingMessage } from 'http';
 import type { IncomingMessage } from 'http';
 
 
-import type { IExternalAuthProviderType } from '@growi/core';
 import axiosRetry from 'axios-retry';
 import axiosRetry from 'axios-retry';
 import luceneQueryParser from 'lucene-query-parser';
 import luceneQueryParser from 'lucene-query-parser';
 import { Strategy as OidcStrategy, Issuer as OIDCIssuer, custom } from 'openid-client';
 import { Strategy as OidcStrategy, Issuer as OIDCIssuer, custom } from 'openid-client';
@@ -14,6 +13,7 @@ import type { Profile, VerifiedCallback } from 'passport-saml';
 import { Strategy as SamlStrategy } from 'passport-saml';
 import { Strategy as SamlStrategy } from 'passport-saml';
 import urljoin from 'url-join';
 import urljoin from 'url-join';
 
 
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import S2sMessage from '../models/vo/s2s-message';
 import S2sMessage from '../models/vo/s2s-message';

+ 3 - 2
apps/app/src/stores/personal-settings.tsx

@@ -1,8 +1,9 @@
-import type { IExternalAccountHasId, IExternalAuthProviderType, IUser } from '@growi/core';
+import type { HasObjectId, IExternalAccount, IUser } from '@growi/core/dist/interfaces';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import type { SWRConfiguration, SWRResponse } from 'swr';
 import type { SWRConfiguration, SWRResponse } from 'swr';
 import useSWR from 'swr';
 import useSWR from 'swr';
 
 
+import type { IExternalAuthProviderType } from '~/interfaces/external-auth-provider';
 import { useIsGuestUser } from '~/stores-universal/context';
 import { useIsGuestUser } from '~/stores-universal/context';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
@@ -103,7 +104,7 @@ export const usePersonalSettings = (config?: SWRConfiguration): SWRResponse<IUse
   };
   };
 };
 };
 
 
-export const useSWRxPersonalExternalAccounts = (): SWRResponse<IExternalAccountHasId[], Error> => {
+export const useSWRxPersonalExternalAccounts = (): SWRResponse<(IExternalAccount<IExternalAuthProviderType> & HasObjectId)[], Error> => {
   return useSWR(
   return useSWR(
     '/personal-setting/external-accounts',
     '/personal-setting/external-accounts',
     endpoint => apiv3Get(endpoint).then(response => response.data.externalAccounts),
     endpoint => apiv3Get(endpoint).then(response => response.data.externalAccounts),

+ 1 - 0
packages/core/src/consts/index.ts

@@ -1,3 +1,4 @@
 export * from './accepted-upload-file-type';
 export * from './accepted-upload-file-type';
 export * from './growi-plugin';
 export * from './growi-plugin';
+export * from './system';
 export * from './ydoc-status';
 export * from './ydoc-status';

+ 0 - 0
apps/app/src/interfaces/system.ts → packages/core/src/consts/system.ts


+ 2 - 15
packages/core/src/interfaces/external-account.ts

@@ -1,21 +1,8 @@
 import type { Ref } from './common';
 import type { Ref } from './common';
-import type { HasObjectId } from './has-object-id';
 import type { IUser } from './user';
 import type { IUser } from './user';
 
 
-export const IExternalAuthProviderType = {
-  ldap: 'ldap',
-  saml: 'saml',
-  oidc: 'oidc',
-  google: 'google',
-  github: 'github',
-} as const;
-
-export type IExternalAuthProviderType = typeof IExternalAuthProviderType[keyof typeof IExternalAuthProviderType]
-
-export type IExternalAccount = {
-  providerType: IExternalAuthProviderType,
+export type IExternalAccount<P> = {
+  providerType: P,
   accountId: string,
   accountId: string,
   user: Ref<IUser>,
   user: Ref<IUser>,
 }
 }
-
-export type IExternalAccountHasId = IExternalAccount & HasObjectId

+ 10 - 14
apps/app/src/features/questionnaire/interfaces/growi-info.ts → packages/core/src/interfaces/growi-app-info.ts

@@ -1,16 +1,10 @@
 import type * as os from 'node:os';
 import type * as os from 'node:os';
 
 
-import { IExternalAuthProviderType } from '@growi/core';
-
-import type { AttachmentMethodType } from '~/interfaces/attachment';
-import type { GrowiDeploymentType, GrowiServiceType } from '~/interfaces/system';
+import type { GrowiDeploymentType, GrowiServiceType } from '../consts/system';
 
 
 export const GrowiWikiType = { open: 'open', closed: 'closed' } as const;
 export const GrowiWikiType = { open: 'open', closed: 'closed' } as const;
 type GrowiWikiType = typeof GrowiWikiType[keyof typeof GrowiWikiType]
 type GrowiWikiType = typeof GrowiWikiType[keyof typeof GrowiWikiType]
 
 
-export const GrowiExternalAuthProviderType = IExternalAuthProviderType;
-export type GrowiExternalAuthProviderType = typeof GrowiExternalAuthProviderType[keyof typeof GrowiExternalAuthProviderType]
-
 interface IGrowiOSInfo {
 interface IGrowiOSInfo {
   type?: ReturnType<typeof os.type>
   type?: ReturnType<typeof os.type>
   platform?: ReturnType<typeof os.platform>
   platform?: ReturnType<typeof os.platform>
@@ -18,18 +12,20 @@ interface IGrowiOSInfo {
   totalmem?: ReturnType<typeof os.totalmem>
   totalmem?: ReturnType<typeof os.totalmem>
 }
 }
 
 
-export interface IGrowiInfo {
-  version: string
-  appSiteUrl?: string
-  appSiteUrlHashed: string
+export interface IGrowiAdditionalInfo {
   installedAt: Date
   installedAt: Date
   installedAtByOldestUser: Date
   installedAtByOldestUser: Date
-  type: GrowiServiceType
   currentUsersCount: number
   currentUsersCount: number
   currentActiveUsersCount: number
   currentActiveUsersCount: number
+}
+
+export interface IGrowiInfo<A extends IGrowiAdditionalInfo> {
+  version: string
+  appSiteUrl?: string
+  appSiteUrlHashed: string
+  type: GrowiServiceType
   wikiType: GrowiWikiType
   wikiType: GrowiWikiType
-  attachmentType: AttachmentMethodType
-  activeExternalAccountTypes?: GrowiExternalAuthProviderType[]
   osInfo?: IGrowiOSInfo
   osInfo?: IGrowiOSInfo
   deploymentType?: GrowiDeploymentType
   deploymentType?: GrowiDeploymentType
+  additionalInfo?: A
 }
 }

+ 1 - 0
packages/core/src/interfaces/index.ts

@@ -4,6 +4,7 @@ export * from './color-scheme';
 export * from './config-manager';
 export * from './config-manager';
 export * from './common';
 export * from './common';
 export * from './external-account';
 export * from './external-account';
+export * from './growi-app-info';
 export * from './growi-facade';
 export * from './growi-facade';
 export * from './growi-theme-metadata';
 export * from './growi-theme-metadata';
 export * from './has-object-id';
 export * from './has-object-id';

+ 2 - 3
packages/core/src/interfaces/user.ts

@@ -1,6 +1,5 @@
 import type { IAttachment } from './attachment';
 import type { IAttachment } from './attachment';
 import type { Ref } from './common';
 import type { Ref } from './common';
-import type { IExternalAuthProviderType } from './external-account';
 import type { HasObjectId } from './has-object-id';
 import type { HasObjectId } from './has-object-id';
 import type { Lang } from './lang';
 import type { Lang } from './lang';
 
 
@@ -53,9 +52,9 @@ export type IUserHasId = IUser & HasObjectId;
 export type IUserGroupHasId = IUserGroup & HasObjectId;
 export type IUserGroupHasId = IUserGroup & HasObjectId;
 export type IUserGroupRelationHasId = IUserGroupRelation & HasObjectId;
 export type IUserGroupRelationHasId = IUserGroupRelation & HasObjectId;
 
 
-export type IAdminExternalAccount = {
+export type IAdminExternalAccount<P> = {
   _id: string,
   _id: string,
-  providerType: IExternalAuthProviderType,
+  providerType: P,
   accountId: string,
   accountId: string,
   user: IUser,
   user: IUser,
   createdAt: Date,
   createdAt: Date,